From e38d3cd42a019752b0de46687dbf827ede3eff72 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Mon, 29 Dec 2025 01:20:24 +0000 Subject: [PATCH] feat(theme,interfaces): Introduce a global theming system and unify menu/tab interfaces; migrate components to use themeDefaultStyles and update APIs accordingly --- changelog.md | 10 + package.json | 2 +- pnpm-lock.yaml | 13 +- readme.md | 588 ++++++++---------- ts_web/00_commitinfo_data.ts | 2 +- .../dees-appui-activitylog.demo.ts | 45 ++ .../dees-appui-activitylog.ts | 47 +- .../dees-appui-base/dees-appui-base.ts | 53 +- .../dees-appui-maincontent.ts | 7 +- .../dees-appui-mainmenu.ts | 19 +- .../dees-appui-profiledropdown.ts | 3 + .../dees-appui-secondarymenu.demo.ts | 2 +- .../dees-appui-secondarymenu.ts | 19 +- .../dees-appui-tabs/dees-appui-tabs.demo.ts | 91 +++ .../dees-appui-tabs/dees-appui-tabs.ts | 103 +-- .../dees-appui-view/dees-appui-view.demo.ts | 30 + .../dees-appui-view/dees-appui-view.ts | 60 +- .../dees-button-group/dees-button-group.ts | 3 + .../00group-button/dees-button/dees-button.ts | 3 + .../dees-chart-log/dees-chart-log.ts | 3 + .../dees-dataview-statusobject.ts | 3 + .../dees-editor-markdown.ts | 3 + .../00group-editor/dees-editor/dees-editor.ts | 3 + .../dees-form-submit/dees-form-submit.ts | 5 +- .../dees-input-checkbox.ts | 3 + .../dees-input-dropdown.ts | 3 + .../dees-input-iban/dees-input-iban.ts | 3 + .../dees-input-list/dees-input-list.ts | 3 + .../dees-input-multitoggle.ts | 3 + .../dees-input-phone/dees-input-phone.ts | 3 + .../dees-input-quantityselector.ts | 5 +- .../dees-input-radiogroup.ts | 3 + .../dees-input-tags/dees-input-tags.ts | 3 + .../dees-input-text/dees-input-text.ts | 3 + .../dees-input-typelist.ts | 3 + .../dees-formatting-menu.ts | 3 + .../dees-input-wysiwyg/dees-input-wysiwyg.ts | 2 + .../dees-input-wysiwyg/dees-slash-menu.ts | 3 + .../dees-input-wysiwyg/dees-wysiwyg-block.ts | 3 + .../dees-input-profilepicture.ts | 3 + .../profilepicture/profilepicture.modal.ts | 3 + .../dees-simple-appdash.ts | 3 + .../dees-simple-login/dees-simple-login.ts | 3 + ts_web/elements/00theme.ts | 218 +++++++ ts_web/elements/dees-badge/dees-badge.ts | 3 + ts_web/elements/dees-chips/dees-chips.ts | 3 + .../dees-contextmenu/dees-contextmenu.ts | 3 + ts_web/elements/dees-heading/dees-heading.ts | 3 + ts_web/elements/dees-hint/dees-hint.ts | 5 +- ts_web/elements/dees-icon/dees-icon.ts | 5 +- ts_web/elements/dees-label/dees-label.ts | 3 + .../dees-mobilenavigation.ts | 3 + ts_web/elements/dees-modal/dees-modal.ts | 3 + .../dees-pagination/dees-pagination.ts | 3 + ts_web/elements/dees-panel/dees-panel.ts | 3 + .../dees-progressbar/dees-progressbar.ts | 3 + .../elements/dees-searchbar/dees-searchbar.ts | 3 + .../dees-shopping-productcard.ts | 3 + .../dees-speechbubble/dees-speechbubble.ts | 3 + ts_web/elements/dees-spinner/dees-spinner.ts | 3 + .../elements/dees-statsgrid/dees-statsgrid.ts | 3 + ts_web/elements/dees-stepper/dees-stepper.ts | 3 + ts_web/elements/dees-table/dees-table.ts | 1 + ts_web/elements/dees-table/styles.ts | 3 + .../elements/dees-terminal/dees-terminal.ts | 3 + ts_web/elements/dees-theme/dees-theme.demo.ts | 275 ++++++++ ts_web/elements/dees-theme/dees-theme.ts | 224 +++++++ ts_web/elements/dees-theme/index.ts | 1 + ts_web/elements/dees-toast/dees-toast.ts | 3 + ts_web/elements/dees-updater/dees-updater.ts | 3 + .../dees-windowcontrols.ts | 3 + ts_web/elements/index.ts | 2 + ts_web/elements/interfaces/appconfig.ts | 23 +- ts_web/elements/interfaces/index.ts | 2 - ts_web/elements/interfaces/menugroup.ts | 8 +- ts_web/elements/interfaces/secondarymenu.ts | 20 - ts_web/elements/interfaces/selectionoption.ts | 5 - ts_web/elements/interfaces/tab.ts | 2 +- 78 files changed, 1413 insertions(+), 616 deletions(-) create mode 100644 ts_web/elements/00group-appui/dees-appui-activitylog/dees-appui-activitylog.demo.ts create mode 100644 ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.demo.ts create mode 100644 ts_web/elements/00group-appui/dees-appui-view/dees-appui-view.demo.ts create mode 100644 ts_web/elements/00theme.ts create mode 100644 ts_web/elements/dees-theme/dees-theme.demo.ts create mode 100644 ts_web/elements/dees-theme/dees-theme.ts create mode 100644 ts_web/elements/dees-theme/index.ts delete mode 100644 ts_web/elements/interfaces/secondarymenu.ts delete mode 100644 ts_web/elements/interfaces/selectionoption.ts diff --git a/changelog.md b/changelog.md index 48503d2..ee61a77 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,15 @@ # Changelog +## 2025-12-29 - 3.5.0 - feat(theme,interfaces) +Introduce a global theming system and unify menu/tab interfaces; migrate components to use themeDefaultStyles and update APIs accordingly + +- Add a new theme module and component (00theme.ts + dees-theme) that provides CSS tokens and themeDefaultStyles to import into components +- Migrate many components to include themeDefaultStyles in their static styles and add TODOs to replace hardcoded values with CSS variables +- Rename ITab -> IMenuItem and replace group.tabs with group.items across interfaces and components (IMenuGroup shape changed) — this is a breaking API change +- Remove legacy interfaces (ISecondaryMenuGroup, ISelectionOption) and update method and property types in DeesAppui* components and app config to use IMenuItem/IMenuGroup +- Move @design.estate/dees-wcctools from dependencies to devDependencies and bump its version to ^3.3.0 +- Add numerous demo files and expand README with usage, examples and theme documentation + ## 2025-12-19 - 3.4.0 - feat(dees-appui-base) overhaul AppUI core: replace simple view rendering with a full-featured ViewRegistry (caching, hide/show lifecycle, async lazy-loading), introduce view lifecycle hooks and activation context, add activity log API/component, remove built-in router and state manager, and update configuration interfaces and demos diff --git a/package.json b/package.json index fd3354b..40a1564 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "dependencies": { "@design.estate/dees-domtools": "^2.3.6", "@design.estate/dees-element": "^2.1.3", - "@design.estate/dees-wcctools": "^3.1.0", "@fortawesome/fontawesome-svg-core": "^7.1.0", "@fortawesome/free-brands-svg-icons": "^7.1.0", "@fortawesome/free-regular-svg-icons": "^7.1.0", @@ -45,6 +44,7 @@ "xterm-addon-fit": "^0.8.0" }, "devDependencies": { + "@design.estate/dees-wcctools": "^3.3.0", "@git.zone/tsbuild": "^4.0.2", "@git.zone/tsbundle": "^2.6.3", "@git.zone/tstest": "^3.1.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 221c6a7..8d20e56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: ^2.1.3 version: 2.1.3 '@design.estate/dees-wcctools': - specifier: ^3.1.0 - version: 3.1.0 + specifier: ^3.3.0 + version: 3.3.0 '@fortawesome/fontawesome-svg-core': specifier: ^7.1.0 version: 7.1.0 @@ -350,8 +350,8 @@ packages: '@design.estate/dees-wcctools@1.3.0': resolution: {integrity: sha512-+yd8c1gTIKNRQYCvG0xu6Am8dHsRm7ymluX2gnoBQN4aFOpZgIBi/v9CvGyPhTD1p/VRouIBz1wsUCejnwrFCA==} - '@design.estate/dees-wcctools@3.1.0': - resolution: {integrity: sha512-EZsgvZZ736PORt8FkHvzKzsmsHDkYOngcWfL1eBEutT3HBQq4PW5X6PVWSHXFzbhI6rt3O07GJHEIa+xU2mSkQ==} + '@design.estate/dees-wcctools@3.3.0': + resolution: {integrity: sha512-ZOxG5LkbLLsqDQWO+JCOjFkL77l9FuLDa7LBuZRkTSX0jRoYG6ICI1UoI9i6twxm4JKSzQ4iHjL/F5mHbQiKTg==} '@emnapi/core@1.7.1': resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} @@ -5409,7 +5409,7 @@ snapshots: - supports-color - vue - '@design.estate/dees-wcctools@3.1.0': + '@design.estate/dees-wcctools@3.3.0': dependencies: '@design.estate/dees-domtools': 2.3.6 '@design.estate/dees-element': 2.1.3 @@ -6805,20 +6805,17 @@ snapshots: transitivePeerDependencies: - '@aws-sdk/credential-providers' - '@mongodb-js/zstd' - - '@nuxt/kit' - aws-crt - bare-abort-controller - bufferutil - gcp-metadata - kerberos - mongodb-client-encryption - - react - react-native-b4a - snappy - socks - supports-color - utf-8-validate - - vue '@push.rocks/taskbuffer@3.5.0': dependencies: diff --git a/readme.md b/readme.md index 0f2be48..467d9fd 100644 --- a/readme.md +++ b/readme.md @@ -1,32 +1,71 @@ # @design.estate/dees-catalog -A comprehensive web components library built with TypeScript and LitElement, providing 75+ UI components for building modern web applications with consistent design and behavior. -## Development Guide -For developers working on this library, please refer to the [UI Components Playbook](readme.playbook.md) for comprehensive patterns, best practices, and architectural guidelines. +A comprehensive web components library built with TypeScript and LitElement, providing **75+ UI components** for building modern web applications with consistent design and behavior. 🚀 -## Install -To install the `@design.estate/dees-catalog` library, you can use npm or any other compatible JavaScript package manager: +[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/) +[![LitElement](https://img.shields.io/badge/LitElement-4.0+-orange.svg)](https://lit.dev/) + +## Issue Reporting and Security + +For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly. + +## ✨ Features + +- 🎨 **Consistent Design System** - Beautiful, cohesive components following modern UI/UX principles +- 🌙 **Dark/Light Theme Support** - All components automatically adapt to your theme +- ⌨️ **Keyboard Accessible** - Full keyboard navigation and ARIA support +- 📱 **Responsive** - Mobile-first design that works across all screen sizes +- 🔧 **TypeScript-First** - Fully typed APIs with excellent IDE support +- 🧩 **Modular** - Use only what you need, tree-shakeable architecture + +## 📦 Installation ```bash npm install @design.estate/dees-catalog +# or +pnpm add @design.estate/dees-catalog ``` -## Components Overview +## 🚀 Quick Start + +```typescript +import { html, DeesElement, customElement } from '@design.estate/dees-element'; +import '@design.estate/dees-catalog'; + +@customElement('my-app') +class MyApp extends DeesElement { + render() { + return html` + alert('Hello!')}> + Click me! + + `; + } +} +``` + +## 📖 Development Guide + +For developers working on this library, please refer to the [UI Components Playbook](readme.playbook.md) for comprehensive patterns, best practices, and architectural guidelines. + +## 📚 Components Overview | Category | Components | |----------|------------| -| Core UI | [`DeesButton`](#deesbutton), [`DeesButtonExit`](#deesbuttonexit), [`DeesButtonGroup`](#deesbuttongroup), [`DeesBadge`](#deesbadge), [`DeesChips`](#deeschips), [`DeesHeading`](#deesheading), [`DeesHint`](#deeshint), [`DeesIcon`](#deesicon), [`DeesLabel`](#deeslabel), [`DeesPanel`](#deespanel), [`DeesSearchbar`](#deessearchbar), [`DeesSpinner`](#deesspinner), [`DeesToast`](#deestoast), [`DeesWindowcontrols`](#deeswindowcontrols) | -| Forms | [`DeesForm`](#deesform), [`DeesInputText`](#deesinputtext), [`DeesInputCheckbox`](#deesinputcheckbox), [`DeesInputDropdown`](#deesinputdropdown), [`DeesInputRadiogroup`](#deesinputradiogroup), [`DeesInputFileupload`](#deesinputfileupload), [`DeesInputIban`](#deesinputiban), [`DeesInputPhone`](#deesinputphone), [`DeesInputQuantitySelector`](#deesinputquantityselector), [`DeesInputMultitoggle`](#deesinputmultitoggle), [`DeesInputTags`](#deesinputtags), [`DeesInputTypelist`](#deesinputtypelist), [`DeesInputRichtext`](#deesinputrichtext), [`DeesInputWysiwyg`](#deesinputwysiwyg), [`DeesInputDatepicker`](#deesinputdatepicker), [`DeesInputSearchselect`](#deesinputsearchselect), [`DeesFormSubmit`](#deesformsubmit) | -| Layout | [`DeesAppuiBase`](#deesappuibase), [`DeesAppuiMainmenu`](#deesappuimainmenu), [`DeesAppuiMainselector`](#deesappuimainselector), [`DeesAppuiMaincontent`](#deesappuimaincontent), [`DeesAppuiAppbar`](#deesappuiappbar), [`DeesAppuiActivitylog`](#deesappuiactivitylog), [`DeesAppuiProfiledropdown`](#deesappuiprofiledropdown), [`DeesAppuiTabs`](#deesappuitabs), [`DeesAppuiView`](#deesappuiview), [`DeesMobileNavigation`](#deesmobilenavigation), [`DeesDashboardGrid`](#deesdashboardgrid) | -| Data Display | [`DeesTable`](#deestable), [`DeesDataviewCodebox`](#deesdataviewcodebox), [`DeesDataviewStatusobject`](#deesdataviewstatusobject), [`DeesPdf`](#deespdf), [`DeesStatsGrid`](#deesstatsgrid), [`DeesPagination`](#deespagination) | -| Visualization | [`DeesChartArea`](#deeschartarea), [`DeesChartLog`](#deeschartlog) | -| Dialogs & Overlays | [`DeesModal`](#deesmodal), [`DeesContextmenu`](#deescontextmenu), [`DeesSpeechbubble`](#deesspeechbubble), [`DeesWindowlayer`](#deeswindowlayer) | -| Navigation | [`DeesStepper`](#deesstepper), [`DeesProgressbar`](#deesprogressbar) | -| Development | [`DeesEditor`](#deeseditor), [`DeesEditorMarkdown`](#deeseditormarkdown), [`DeesEditorMarkdownoutlet`](#deeseditormarkdownoutlet), [`DeesTerminal`](#deesterminal), [`DeesUpdater`](#deesupdater) | -| Auth & Utilities | [`DeesSimpleAppdash`](#deessimpleappdash), [`DeesSimpleLogin`](#deessimplelogin) | -| Shopping | [`DeesShoppingProductcard`](#deesshoppingproductcard) | +| **Core UI** | [`DeesButton`](#deesbutton), [`DeesButtonExit`](#deesbuttonexit), [`DeesButtonGroup`](#deesbuttongroup), [`DeesBadge`](#deesbadge), [`DeesChips`](#deeschips), [`DeesHeading`](#deesheading), [`DeesHint`](#deeshint), [`DeesIcon`](#deesicon), [`DeesLabel`](#deeslabel), [`DeesPanel`](#deespanel), [`DeesSearchbar`](#deessearchbar), [`DeesSpinner`](#deesspinner), [`DeesToast`](#deestoast), [`DeesWindowcontrols`](#deeswindowcontrols) | +| **Forms** | [`DeesForm`](#deesform), [`DeesInputText`](#deesinputtext), [`DeesInputCheckbox`](#deesinputcheckbox), [`DeesInputDropdown`](#deesinputdropdown), [`DeesInputRadiogroup`](#deesinputradiogroup), [`DeesInputFileupload`](#deesinputfileupload), [`DeesInputIban`](#deesinputiban), [`DeesInputPhone`](#deesinputphone), [`DeesInputQuantitySelector`](#deesinputquantityselector), [`DeesInputMultitoggle`](#deesinputmultitoggle), [`DeesInputTags`](#deesinputtags), [`DeesInputTypelist`](#deesinputtypelist), [`DeesInputRichtext`](#deesinputrichtext), [`DeesInputWysiwyg`](#deesinputwysiwyg), [`DeesInputDatepicker`](#deesinputdatepicker), [`DeesInputSearchselect`](#deesinputsearchselect), [`DeesFormSubmit`](#deesformsubmit) | +| **Layout** | [`DeesAppuiBase`](#deesappuibase), [`DeesAppuiMainmenu`](#deesappuimainmenu), [`DeesAppuiSecondarymenu`](#deesappuisecondarymenu), [`DeesAppuiMaincontent`](#deesappuimaincontent), [`DeesAppuiAppbar`](#deesappuiappbar), [`DeesAppuiActivitylog`](#deesappuiactivitylog), [`DeesAppuiProfiledropdown`](#deesappuiprofiledropdown), [`DeesAppuiTabs`](#deesappuitabs), [`DeesAppuiView`](#deesappuiview), [`DeesMobileNavigation`](#deesmobilenavigation), [`DeesDashboardGrid`](#deesdashboardgrid) | +| **Data Display** | [`DeesTable`](#deestable), [`DeesDataviewCodebox`](#deesdataviewcodebox), [`DeesDataviewStatusobject`](#deesdataviewstatusobject), [`DeesPdf`](#deespdf), [`DeesStatsGrid`](#deesstatsgrid), [`DeesPagination`](#deespagination) | +| **Visualization** | [`DeesChartArea`](#deeschartarea), [`DeesChartLog`](#deeschartlog) | +| **Dialogs & Overlays** | [`DeesModal`](#deesmodal), [`DeesContextmenu`](#deescontextmenu), [`DeesSpeechbubble`](#deesspeechbubble), [`DeesWindowlayer`](#deeswindowlayer) | +| **Navigation** | [`DeesStepper`](#deesstepper), [`DeesProgressbar`](#deesprogressbar) | +| **Development** | [`DeesEditor`](#deeseditor), [`DeesEditorMarkdown`](#deeseditormarkdown), [`DeesEditorMarkdownoutlet`](#deeseditormarkdownoutlet), [`DeesTerminal`](#deesterminal), [`DeesUpdater`](#deesupdater) | +| **Auth & Utilities** | [`DeesSimpleAppdash`](#deessimpleappdash), [`DeesSimpleLogin`](#deessimplelogin) | +| **Shopping** | [`DeesShoppingProductcard`](#deesshoppingproductcard) | -## Detailed Component Documentation +--- + +## 🎯 Detailed Component Documentation ### Core UI Components @@ -84,7 +123,7 @@ Display icons from FontAwesome and Lucide icon libraries with library prefixes. color="#22c55e" // Optional: custom color > -// Lucide icons - use 'lucide:' prefix +// Lucide icons - use 'lucide:' prefix ``` -Key Features: +**Key Features:** - Multiple toast types with distinct icons and colors - 6 position options for flexible placement - Auto-dismiss with visual progress indicator @@ -254,6 +286,8 @@ Window control buttons (minimize, maximize, close) for desktop-like applications > ``` +--- + ### Form Components #### `DeesForm` @@ -427,7 +461,7 @@ Tag input component for managing lists of tags with auto-complete and validation > ``` -Key Features: +**Key Features:** - Add tags by pressing Enter or typing comma/semicolon - Remove tags with click or backspace - Auto-complete suggestions with keyboard navigation @@ -464,7 +498,7 @@ Date and time picker component with calendar interface and manual typing support minDate="2025-01-01" // Minimum selectable date maxDate="2025-12-31" // Maximum selectable date .disabledDates=${[ // Array of disabled dates - '2025-01-10', + '2025-01-10', '2025-01-11' ]} weekStartsOn={1} // 0 = Sunday, 1 = Monday @@ -473,7 +507,7 @@ Date and time picker component with calendar interface and manual typing support > ``` -Key Features: +**Key Features:** - Interactive calendar popup - Manual date typing with multiple formats - Optional time selection @@ -487,7 +521,7 @@ Key Features: - Theme-aware styling - Live parsing and validation -Manual Input Formats: +**Manual Input Formats:** ```typescript // Date formats supported "2023-12-20" // ISO format (YYYY-MM-DD) @@ -500,8 +534,6 @@ Manual Input Formats: "12/20/2023 16:00" ``` -The component automatically parses and validates input as you type, updating the internal date value when a valid date is recognized. - #### `DeesInputSearchselect` Search-enabled dropdown selection component. @@ -535,7 +567,7 @@ Rich text editor with formatting toolbar powered by TipTap. > ``` -Key Features: +**Key Features:** - Full formatting toolbar (bold, italic, underline, strike, etc.) - Heading levels (H1-H6) - Lists (bullet, ordered) @@ -560,7 +592,7 @@ Advanced block-based editor with slash commands and rich content blocks. > ``` -Key Features: +**Key Features:** - Slash commands for quick formatting - Block-based editing (paragraphs, headings, lists, etc.) - Drag and drop block reordering @@ -579,6 +611,8 @@ Submit button component specifically designed for `DeesForm`. >Submit Form ``` +--- + ### Layout Components #### `DeesAppuiBase` @@ -640,41 +674,37 @@ Main navigation menu component for application-wide navigation. ```typescript handleNavigation('dashboard') - }, - { - key: 'settings', - label: 'Settings', - icon: 'cog', - action: () => handleNavigation('settings') + name: 'Main', + items: [ + { key: 'dashboard', iconName: 'lucide:home', action: () => navigate('dashboard') }, + { key: 'settings', iconName: 'lucide:settings', action: () => navigate('settings') } + ] } ]} collapsed // Optional: show collapsed version - position="left" // Options: left, right > ``` -#### `DeesAppuiMainselector` -Secondary navigation component for sub-section selection. +#### `DeesAppuiSecondarymenu` +Secondary navigation component for sub-section selection with collapsible groups and badges. ```typescript - selectSection('section1') + name: 'Active', + iconName: 'lucide:folder', + items: [ + { key: 'Frontend App', iconName: 'lucide:code', action: () => select('frontend'), badge: 3, badgeVariant: 'warning' }, + { key: 'API Server', iconName: 'lucide:server', action: () => select('api') } + ] } ]} - selectedKey="section1" // Currently selected section - @selection-change=${handleSectionChange} -> + @item-select=${handleSectionChange} +> ``` #### `DeesAppuiMaincontent` @@ -683,16 +713,13 @@ Main content area with tab management support. ```typescript Tab 1 Content`, - action: () => handleTabAction('tab1') - } + { key: 'Overview', iconName: 'lucide:home', action: () => selectTab('overview') }, + { key: 'Details', iconName: 'lucide:info', action: () => selectTab('details') } ]} - selectedTab="tab1" // Currently active tab - @tab-change=${handleTabChange} -> + @tab-select=${handleTabChange} +> + + ``` #### `DeesAppuiAppbar` @@ -705,91 +732,82 @@ Professional application bar component with hierarchical menus, breadcrumb navig name: 'File', action: async () => {}, // No-op for parent menu items submenu: [ - { - name: 'New File', - shortcut: 'Cmd+N', - iconName: 'file-plus', - action: async () => handleNewFile() + { + name: 'New File', + shortcut: 'Cmd+N', + iconName: 'file-plus', + action: async () => handleNewFile() }, - { - name: 'Open...', - shortcut: 'Cmd+O', - iconName: 'folder-open', - action: async () => handleOpen() + { + name: 'Open...', + shortcut: 'Cmd+O', + iconName: 'folder-open', + action: async () => handleOpen() }, { divider: true }, // Menu separator - { - name: 'Save', - shortcut: 'Cmd+S', - iconName: 'save', + { + name: 'Save', + shortcut: 'Cmd+S', + iconName: 'save', action: async () => handleSave(), disabled: true // Disabled state } ] - }, - { - name: 'Edit', - action: async () => {}, - submenu: [ - { name: 'Undo', shortcut: 'Cmd+Z', iconName: 'undo', action: async () => handleUndo() }, - { name: 'Redo', shortcut: 'Cmd+Shift+Z', iconName: 'redo', action: async () => handleRedo() } - ] } ]} - .breadcrumbs=${'Project > src > components > AppBar.ts'} - .breadcrumbSeparator=${' > '} + .breadcrumbs=${'Project > src > components'} .showWindowControls=${true} .showSearch=${true} - .theme=${'dark'} // Options: 'light' | 'dark' .user=${{ name: 'John Doe', - avatar: '/path/to/avatar.jpg', // Optional + avatar: '/path/to/avatar.jpg', status: 'online' // Options: 'online' | 'offline' | 'busy' | 'away' }} @menu-select=${(e) => handleMenuSelect(e.detail.item)} @breadcrumb-navigate=${(e) => handleBreadcrumbClick(e.detail)} - @search-click=${() => handleSearchClick()} - @user-menu-open=${() => handleUserMenuOpen()} > ``` -Key Features: -- **Hierarchical Menu System** - - Top-level text-only menus (following desktop UI standards) - - Dropdown submenus with icons and keyboard shortcuts - - Support for nested submenus - - Menu dividers for visual grouping - - Disabled state support - -- **Keyboard Navigation** - - Tab navigation between top-level items - - Arrow keys for dropdown navigation (Up/Down in dropdowns, Left/Right between top items) - - Enter to select items - - Escape to close dropdowns - - Home/End keys for first/last item - -- **Breadcrumb Navigation** - - Customizable breadcrumb trail - - Configurable separator - - Click events for navigation - -- **User Account Section** - - User avatar with fallback to initials - - Status indicator (online, offline, busy, away) - - Click handler for user menu - -- **Visual Features** - - Light and dark theme support - - Smooth animations and transitions - - Window controls integration - - Search icon with click handler - - Responsive layout using CSS Grid - -- **Accessibility** - - Full ARIA support (menubar, menuitem roles) - - Keyboard navigation - - Focus management - - Screen reader compatible +**Key Features:** +- **Hierarchical Menu System** - Top-level menus with dropdown submenus, icons, and keyboard shortcuts +- **Keyboard Navigation** - Full keyboard support (Tab, Arrow keys, Enter, Escape) +- **Breadcrumb Navigation** - Customizable breadcrumb trail with click events +- **User Account Section** - Avatar with status indicator +- **Accessibility** - Full ARIA support with menubar roles + +#### `DeesAppuiView` +View wrapper component for single-view layouts with internal tabs. + +```typescript + {}, content: html`
General settings
` }, + { key: 'Security', iconName: 'lucide:shield', action: () => {}, content: html`
Security settings
` } + ] + }} + .paddingPx=${16} // Default padding for tab content +>
+``` + +#### `DeesAppuiTabs` +Reusable tab component with horizontal/vertical layout support. + +```typescript + console.log('Home') }, + { key: 'Settings', iconName: 'lucide:settings', action: () => console.log('Settings') } + ]} + tabStyle="horizontal" // Options: horizontal, vertical + showTabIndicator={true} + @tab-select=${handleTabSelect} +> +``` + +--- ### Data Display Components @@ -825,9 +843,7 @@ Advanced table component with sorting, filtering, and action support. > ``` -##### DeesTable (Updated) - -Newer features available in `dees-table`: +**Advanced Features:** - Schema-first columns or `displayFunction` rendering - Sorting via header clicks with `aria-sort` + `sortChange` - Global search with Lucene-like syntax; modes: `table`, `data`, `server` @@ -846,9 +862,9 @@ Code display component with syntax highlighting and line numbers. progLang="typescript" // Programming language for syntax highlighting .codeToDisplay=${` import { html } from '@design.estate/dees-element'; - + export const myComponent = () => { - return html`
Hello World
`; + return html\`
Hello World
\`; }; `} > @@ -865,18 +881,8 @@ Status display component for complex objects with nested status indicators. combinedStatus: 'partly_ok', combinedStatusText: 'Partially OK', details: [ - { - name: 'Database', - value: 'Connected', - status: 'ok', - statusText: 'OK' - }, - { - name: 'API Service', - value: 'Degraded', - status: 'partly_ok', - statusText: 'Partially OK' - } + { name: 'Database', value: 'Connected', status: 'ok', statusText: 'OK' }, + { name: 'API Service', value: 'Degraded', status: 'partly_ok', statusText: 'Partially OK' } ] }} > @@ -890,19 +896,13 @@ PDF viewer component with navigation and zoom controls. source="path/to/document.pdf" // URL or base64 encoded PDF page={1} // Current page number scale={1.0} // Zoom level - .controls=${[ // Optional: customize available controls - 'zoom', - 'download', - 'print', - 'navigation' - ]} + .controls=${['zoom', 'download', 'print', 'navigation']} @page-change=${handlePageChange} - @document-loaded=${handleDocumentLoaded} > ``` #### `DeesStatsGrid` -A responsive grid component for displaying statistical data with various visualization types including numbers, gauges, percentages, and trends. +A responsive grid component for displaying statistical data with various visualization types. ```typescript { - console.log('Viewing revenue details'); - } - }, - { - name: 'Export Data', - iconName: 'faFileExport', - action: async () => { - console.log('Exporting revenue data'); - } - } - ] + color: '#22c55e' }, { id: 'cpu', @@ -940,8 +924,7 @@ A responsive grid component for displaying statistical data with various visuali type: 'gauge', icon: 'faMicrochip', gaugeOptions: { - min: 0, - max: 100, + min: 0, max: 100, thresholds: [ { value: 0, color: '#22c55e' }, { value: 60, color: '#f59e0b' }, @@ -949,15 +932,6 @@ A responsive grid component for displaying statistical data with various visuali ] } }, - { - id: 'storage', - title: 'Storage Used', - value: 65, - type: 'percentage', - icon: 'faHardDrive', - description: '650 GB of 1 TB', - color: '#3b82f6' - }, { id: 'requests', title: 'API Requests', @@ -966,35 +940,10 @@ A responsive grid component for displaying statistical data with various visuali type: 'trend', icon: 'faServer', trendData: [45, 52, 38, 65, 72, 68, 75, 82, 79, 85, 88, 92] - }, - { - id: 'uptime', - title: 'System Uptime', - value: '99.95%', - type: 'text', - icon: 'faCheckCircle', - color: '#22c55e', - description: 'Last 30 days' } ]} - .gridActions=${[ - { - name: 'Refresh', - iconName: 'faSync', - action: async () => { - console.log('Refreshing stats...'); - } - }, - { - name: 'Export Report', - iconName: 'faFileExport', - action: async () => { - console.log('Exporting stats report...'); - } - } - ]} - .minTileWidth=${250} // Minimum tile width in pixels - .gap=${16} // Gap between tiles in pixels + .minTileWidth=${250} + .gap=${16} > ``` @@ -1006,11 +955,13 @@ Pagination component for navigating through large datasets. totalItems={500} itemsPerPage={20} currentPage={1} - maxVisiblePages={7} // Maximum page numbers to display + maxVisiblePages={7} @page-change=${handlePageChange} > ``` +--- + ### Visualization Components #### `DeesChartArea` @@ -1018,7 +969,7 @@ Area chart component built on ApexCharts for visualizing time-series data. ```typescript @@ -1047,22 +990,16 @@ Specialized chart component for visualizing log data and events. ``` +--- + ### Dialogs & Overlays Components #### `DeesModal` @@ -1074,36 +1011,14 @@ DeesModal.createAndShow({ heading: 'Confirm Action', content: html` - + `, menuOptions: [ - { - name: 'Cancel', - action: async (modal) => { - modal.destroy(); - return null; - } - }, - { - name: 'Confirm', - action: async (modal) => { - // Handle confirmation - modal.destroy(); - return null; - } - } + { name: 'Cancel', action: async (modal) => { modal.destroy(); return null; } }, + { name: 'Confirm', action: async (modal) => { /* handle */ modal.destroy(); return null; } } ] }); - -// Component usage - ``` #### `DeesContextmenu` @@ -1112,19 +1027,10 @@ Context menu component for right-click actions. ```typescript handleEdit() - }, - { - label: 'Delete', - icon: 'trash', - action: () => handleDelete() - } + { label: 'Edit', icon: 'edit', action: () => handleEdit() }, + { label: 'Delete', icon: 'trash', action: () => handleDelete() } ]} - position="right" // Options: right, left, auto - @item-click=${handleMenuItemClick} + position="right" > ``` @@ -1134,39 +1040,22 @@ Tooltip-style speech bubble component for contextual information. ```typescript // Programmatic usage const bubble = await DeesSpeechbubble.createAndShow( - referenceElement, // Element to attach to + referenceElement, 'Helpful information about this feature' ); - -// Component usage - ``` #### `DeesWindowlayer` Base overlay component used by modal dialogs and other overlay components. ```typescript -// Programmatic usage const layer = await DeesWindowLayer.createAndShow({ - blur: true, // Enable backdrop blur + blur: true, }); - -// Component usage - -
- -
-
``` +--- + ### Navigation Components #### `DeesStepper` @@ -1175,23 +1064,9 @@ Multi-step navigation component for guided user flows. ```typescript Personal Information Form`, - validation: () => validatePersonalInfo() - }, - { - key: 'address', - label: 'Address', - content: html`
Address Form
`, - validation: () => validateAddress() - }, - { - key: 'confirm', - label: 'Confirmation', - content: html`
Review and Confirm
` - } + { key: 'personal', label: 'Personal Info', content: html`
Form 1
` }, + { key: 'address', label: 'Address', content: html`
Form 2
` }, + { key: 'confirm', label: 'Confirmation', content: html`
Review
` } ]} currentStep="personal" @step-change=${handleStepChange} @@ -1204,15 +1079,16 @@ Progress indicator component for tracking completion status. ```typescript ``` +--- + ### Development Components #### `DeesEditor` @@ -1239,12 +1115,7 @@ Markdown editor component with live preview. ``` @@ -1254,9 +1125,8 @@ Markdown preview component for rendering markdown content. ```typescript ``` @@ -1271,8 +1141,6 @@ Terminal emulator component for command-line interface. }} .prompt=${'$'} .welcomeMessage=${'Welcome! Type "help" for available commands.'} - .historySize=${100} - .autoFocus={true} > ``` @@ -1282,13 +1150,14 @@ Component for managing application updates and version control. ```typescript ``` +--- + ### Auth & Utilities Components #### `DeesSimpleAppdash` @@ -1301,10 +1170,7 @@ Simple application dashboard component for quick prototyping. { name: 'Dashboard', icon: 'home', route: '/dashboard' }, { name: 'Settings', icon: 'settings', route: '/settings' } ]} - .user=${{ - name: 'John Doe', - role: 'Administrator' - }} + .user=${{ name: 'John Doe', role: 'Administrator' }} @menu-select=${handleMenuSelect} > @@ -1319,7 +1185,7 @@ Simple login form component with validation and customization. .appName=${'My Application'} .logo=${'./assets/logo.png'} .backgroundImage=${'./assets/background.jpg'} - .fields=${['username', 'password']} // Options: username, email, password + .fields=${['username', 'password']} showForgotPassword showRememberMe @login=${handleLogin} @@ -1327,6 +1193,8 @@ Simple login form component with validation and customization. > ``` +--- + ### Shopping Components #### `DeesShoppingProductcard` @@ -1339,37 +1207,69 @@ Product card component for e-commerce applications. category: 'Electronics', description: 'High-quality wireless headphones with noise cancellation', price: 199.99, - originalPrice: 249.99, // Shows strikethrough price + originalPrice: 249.99, currency: '$', inStock: true, - stockText: 'In Stock', // Custom stock text - imageUrl: '/images/headphones.jpg', - iconName: 'lucide:headphones' // Fallback icon if no image + imageUrl: '/images/headphones.jpg' }} - quantity={1} // Current quantity - showQuantitySelector={true} // Show quantity selector - selectable={false} // Enable selection mode - selected={false} // Selection state - @quantityChange=${(e) => handleQuantityChange(e.detail)} - @selectionChange=${(e) => handleSelectionChange(e.detail)} + quantity={1} + showQuantitySelector={true} + @quantityChange=${handleQuantityChange} > ``` +--- + +## 🔧 TypeScript Interfaces + +The library exports unified interfaces for consistent API patterns: + +```typescript +// Base menu item interface (used by tabs, menus, etc.) +interface IMenuItem { + key: string; + iconName?: string; + action: () => void; + badge?: string | number; + badgeVariant?: 'default' | 'success' | 'warning' | 'error'; +} + +// Extended tab interface for views with content +interface IViewTab extends IMenuItem { + content?: TemplateResult | (() => TemplateResult); + useSlotName?: boolean; + slotName?: string; + paddingPx?: number; +} + +// Menu group interface for organized menus +interface IMenuGroup { + name: string; + items: IMenuItem[]; + collapsed?: boolean; + iconName?: string; +} +``` + +--- + ## License and Legal Information -This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the license file within this repository. +This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file. -Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file. +**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file. ### Trademarks -This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH. +This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein. + +Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar. ### Company Information Task Venture Capital GmbH -Registered at District court Bremen HRB 35230 HB, Germany +Registered at District Court Bremen HRB 35230 HB, Germany -For any legal inquiries or if you require further information, please contact us via email at hello@task.vc. +For any legal inquiries or further information, please contact us via email at hello@task.vc. By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works. diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 7b94d92..fe72340 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@design.estate/dees-catalog', - version: '3.4.0', + version: '3.5.0', description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.' } diff --git a/ts_web/elements/00group-appui/dees-appui-activitylog/dees-appui-activitylog.demo.ts b/ts_web/elements/00group-appui/dees-appui-activitylog/dees-appui-activitylog.demo.ts new file mode 100644 index 0000000..2c3c321 --- /dev/null +++ b/ts_web/elements/00group-appui/dees-appui-activitylog/dees-appui-activitylog.demo.ts @@ -0,0 +1,45 @@ +import { html, cssManager } from '@design.estate/dees-element'; +import '@design.estate/dees-wcctools/demotools'; +import type { DeesAppuiActivitylog } from './dees-appui-activitylog.js'; + +export const demoFunc = () => { + // Create the activity log element + const activityLog = document.createElement('dees-appui-activitylog') as DeesAppuiActivitylog; + + // Add demo entries after the element is connected + setTimeout(() => { + activityLog.addMany([ + { type: 'login', user: 'John Doe', message: 'logged in from Chrome on macOS' }, + { type: 'create', user: 'John Doe', message: 'created a new project "Frontend App"' }, + { type: 'update', user: 'Jane Smith', message: 'updated API documentation' }, + { type: 'view', user: 'John Doe', message: 'viewed dashboard analytics' }, + { type: 'delete', user: 'Admin', message: 'removed deprecated endpoint' }, + { type: 'custom', user: 'System', message: 'scheduled backup completed', iconName: 'lucide:database' }, + { type: 'logout', user: 'Alice Brown', message: 'logged out' }, + { type: 'create', user: 'Jane Smith', message: 'created invoice #1234' }, + ]); + + // Subscribe to updates + activityLog.entries$.subscribe((entries) => { + console.log('Activity log updated:', entries.length, 'entries'); + }); + }, 100); + + return html` + + +
+ ${activityLog} +
+
+ `; +}; diff --git a/ts_web/elements/00group-appui/dees-appui-activitylog/dees-appui-activitylog.ts b/ts_web/elements/00group-appui/dees-appui-activitylog/dees-appui-activitylog.ts index bf04386..0e4e679 100644 --- a/ts_web/elements/00group-appui/dees-appui-activitylog/dees-appui-activitylog.ts +++ b/ts_web/elements/00group-appui/dees-appui-activitylog/dees-appui-activitylog.ts @@ -12,53 +12,14 @@ import { import * as domtools from '@design.estate/dees-domtools'; import { DeesContextmenu } from '../../dees-contextmenu/dees-contextmenu.js'; import '../../dees-icon/dees-icon.js'; -import '@design.estate/dees-wcctools/demotools'; import type { IActivityEntry, IActivityLogAPI } from '../../interfaces/appconfig.js'; +import { demoFunc } from './dees-appui-activitylog.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; @customElement('dees-appui-activitylog') export class DeesAppuiActivitylog extends DeesElement implements IActivityLogAPI { // STATIC - public static demo = () => { - // Create the activity log element - const activityLog = document.createElement('dees-appui-activitylog') as DeesAppuiActivitylog; - - // Add demo entries after the element is connected - setTimeout(() => { - activityLog.addMany([ - { type: 'login', user: 'John Doe', message: 'logged in from Chrome on macOS' }, - { type: 'create', user: 'John Doe', message: 'created a new project "Frontend App"' }, - { type: 'update', user: 'Jane Smith', message: 'updated API documentation' }, - { type: 'view', user: 'John Doe', message: 'viewed dashboard analytics' }, - { type: 'delete', user: 'Admin', message: 'removed deprecated endpoint' }, - { type: 'custom', user: 'System', message: 'scheduled backup completed', iconName: 'lucide:database' }, - { type: 'logout', user: 'Alice Brown', message: 'logged out' }, - { type: 'create', user: 'Jane Smith', message: 'created invoice #1234' }, - ]); - - // Subscribe to updates - activityLog.entries$.subscribe((entries) => { - console.log('Activity log updated:', entries.length, 'entries'); - }); - }, 100); - - return html` - - -
- ${activityLog} -
-
- `; - }; + public static demo = demoFunc; // INSTANCE PROPERTIES @state() @@ -75,8 +36,10 @@ export class DeesAppuiActivitylog extends DeesElement implements IActivityLogAPI // STYLES public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { color: ${cssManager.bdTheme('#09090b', '#fafafa')}; position: relative; diff --git a/ts_web/elements/00group-appui/dees-appui-base/dees-appui-base.ts b/ts_web/elements/00group-appui/dees-appui-base/dees-appui-base.ts index 0d788c4..18a1f86 100644 --- a/ts_web/elements/00group-appui/dees-appui-base/dees-appui-base.ts +++ b/ts_web/elements/00group-appui/dees-appui-base/dees-appui-base.ts @@ -16,6 +16,7 @@ import type { DeesAppuiSecondarymenu } from '../dees-appui-secondarymenu/dees-ap import type { DeesAppuiMaincontent } from '../dees-appui-maincontent/dees-appui-maincontent.js'; import type { DeesAppuiActivitylog } from '../dees-appui-activitylog/dees-appui-activitylog.js'; import { demoFunc } from './dees-appui-base.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; // View registry for managing views import { ViewRegistry } from './view.registry.js'; @@ -84,23 +85,23 @@ export class DeesAppuiBase extends DeesElement { accessor mainmenuGroups: interfaces.IMenuGroup[] = []; @property({ type: Array }) - accessor mainmenuBottomTabs: interfaces.ITab[] = []; + accessor mainmenuBottomTabs: interfaces.IMenuItem[] = []; @property({ type: Array }) - accessor mainmenuTabs: interfaces.ITab[] = []; + accessor mainmenuTabs: interfaces.IMenuItem[] = []; @property({ type: Object }) - accessor mainmenuSelectedTab: interfaces.ITab | undefined = undefined; + accessor mainmenuSelectedTab: interfaces.IMenuItem | undefined = undefined; // Properties for secondarymenu @property({ type: String }) accessor secondarymenuHeading: string = ''; @property({ type: Array }) - accessor secondarymenuGroups: interfaces.ISecondaryMenuGroup[] = []; + accessor secondarymenuGroups: interfaces.IMenuGroup[] = []; @property({ type: Object }) - accessor secondarymenuSelectedItem: interfaces.ISecondaryMenuItem | undefined = undefined; + accessor secondarymenuSelectedItem: interfaces.IMenuItem | undefined = undefined; // Collapse states @property({ type: Boolean }) @@ -111,10 +112,10 @@ export class DeesAppuiBase extends DeesElement { // Properties for maincontent @property({ type: Array }) - accessor maincontentTabs: interfaces.ITab[] = []; + accessor maincontentTabs: interfaces.IMenuItem[] = []; @property({ type: Object }) - accessor maincontentSelectedTab: interfaces.ITab | undefined = undefined; + accessor maincontentSelectedTab: interfaces.IMenuItem | undefined = undefined; // References to child components @state() @@ -142,8 +143,10 @@ export class DeesAppuiBase extends DeesElement { private searchCallback: ((query: string) => void) | null = null; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { position: absolute; height: 100%; @@ -370,12 +373,12 @@ export class DeesAppuiBase extends DeesElement { /** * Add a menu item to a specific group */ - public addMainMenuItem(groupName: string, tab: interfaces.ITab): void { + public addMainMenuItem(groupName: string, tab: interfaces.IMenuItem): void { this.mainmenuGroups = this.mainmenuGroups.map(group => { if (group.name === groupName) { return { ...group, - tabs: [...(group.tabs || []), tab], + items: [...(group.items || []), tab], }; } return group; @@ -390,7 +393,7 @@ export class DeesAppuiBase extends DeesElement { if (group.name === groupName) { return { ...group, - tabs: (group.tabs || []).filter(t => t.key !== tabKey), + items: (group.items || []).filter(t => t.key !== tabKey), }; } return group; @@ -402,7 +405,7 @@ export class DeesAppuiBase extends DeesElement { */ public setMainMenuSelection(tabKey: string): void { for (const group of this.mainmenuGroups) { - const tab = group.tabs?.find(t => t.key === tabKey); + const tab = group.items?.find(t => t.key === tabKey); if (tab) { this.mainmenuSelectedTab = tab; return; @@ -428,7 +431,7 @@ export class DeesAppuiBase extends DeesElement { public setMainMenuBadge(tabKey: string, badge: string | number): void { this.mainmenuGroups = this.mainmenuGroups.map(group => ({ ...group, - tabs: (group.tabs || []).map(tab => + items: (group.items || []).map(tab => tab.key === tabKey ? { ...tab, badge } : tab ), })); @@ -444,7 +447,7 @@ export class DeesAppuiBase extends DeesElement { public clearMainMenuBadge(tabKey: string): void { this.mainmenuGroups = this.mainmenuGroups.map(group => ({ ...group, - tabs: (group.tabs || []).map(tab => { + items: (group.items || []).map(tab => { if (tab.key === tabKey) { const { badge, ...rest } = tab; return rest; @@ -469,7 +472,7 @@ export class DeesAppuiBase extends DeesElement { /** * Set the secondary menu configuration */ - public setSecondaryMenu(config: { heading?: string; groups: interfaces.ISecondaryMenuGroup[] }): void { + public setSecondaryMenu(config: { heading?: string; groups: interfaces.IMenuGroup[] }): void { if (config.heading !== undefined) { this.secondarymenuHeading = config.heading; } @@ -479,7 +482,7 @@ export class DeesAppuiBase extends DeesElement { /** * Update a specific secondary menu group */ - public updateSecondaryMenuGroup(groupName: string, update: Partial): void { + public updateSecondaryMenuGroup(groupName: string, update: Partial): void { this.secondarymenuGroups = this.secondarymenuGroups.map(group => group.name === groupName ? { ...group, ...update } : group ); @@ -490,7 +493,7 @@ export class DeesAppuiBase extends DeesElement { */ public addSecondaryMenuItem( groupName: string, - item: interfaces.ISecondaryMenuGroup['items'][0] + item: interfaces.IMenuGroup['items'][0] ): void { this.secondarymenuGroups = this.secondarymenuGroups.map(group => { if (group.name === groupName) { @@ -532,7 +535,7 @@ export class DeesAppuiBase extends DeesElement { /** * Set the content tabs */ - public setContentTabs(tabs: interfaces.ITab[]): void { + public setContentTabs(tabs: interfaces.IMenuItem[]): void { this.maincontentTabs = [...tabs]; if (tabs.length > 0 && !this.maincontentSelectedTab) { this.maincontentSelectedTab = tabs[0]; @@ -542,7 +545,7 @@ export class DeesAppuiBase extends DeesElement { /** * Add a content tab */ - public addContentTab(tab: interfaces.ITab): void { + public addContentTab(tab: interfaces.IMenuItem): void { this.maincontentTabs = [...this.maincontentTabs, tab]; } @@ -569,7 +572,7 @@ export class DeesAppuiBase extends DeesElement { /** * Get the currently selected content tab */ - public getSelectedContentTab(): interfaces.ITab | undefined { + public getSelectedContentTab(): interfaces.IMenuItem | undefined { return this.maincontentSelectedTab; } @@ -779,7 +782,7 @@ export class DeesAppuiBase extends DeesElement { return config.mainMenu.sections.map((section) => ({ name: section.name, - tabs: section.views + items: section.views .map((viewId) => { const view = this.viewRegistry.get(viewId); if (!view) { @@ -791,13 +794,13 @@ export class DeesAppuiBase extends DeesElement { iconName: view.iconName, action: () => this.navigateToView(viewId), badge: view.badge, - } as interfaces.ITab; + } as interfaces.IMenuItem; }) - .filter(Boolean) as interfaces.ITab[], + .filter(Boolean) as interfaces.IMenuItem[], })); } - private buildBottomTabsFromItems(items: string[]): interfaces.ITab[] { + private buildBottomTabsFromItems(items: string[]): interfaces.IMenuItem[] { return items .map((viewId) => { const view = this.viewRegistry.get(viewId); @@ -809,9 +812,9 @@ export class DeesAppuiBase extends DeesElement { key: view.id, iconName: view.iconName, action: () => this.navigateToView(viewId), - } as interfaces.ITab; + } as interfaces.IMenuItem; }) - .filter(Boolean) as interfaces.ITab[]; + .filter(Boolean) as interfaces.IMenuItem[]; } private async loadView( diff --git a/ts_web/elements/00group-appui/dees-appui-maincontent/dees-appui-maincontent.ts b/ts_web/elements/00group-appui/dees-appui-maincontent/dees-appui-maincontent.ts index 3ab1f4f..a9d76a7 100644 --- a/ts_web/elements/00group-appui/dees-appui-maincontent/dees-appui-maincontent.ts +++ b/ts_web/elements/00group-appui/dees-appui-maincontent/dees-appui-maincontent.ts @@ -13,6 +13,7 @@ import { import * as domtools from '@design.estate/dees-domtools'; import '../dees-appui-tabs/dees-appui-tabs.js'; import type { DeesAppuiTabs } from '../dees-appui-tabs/dees-appui-tabs.js'; +import { themeDefaultStyles } from '../../00theme.js'; @customElement('dees-appui-maincontent') export class DeesAppuiMaincontent extends DeesElement { @@ -35,16 +36,18 @@ export class DeesAppuiMaincontent extends DeesElement { @property({ type: Array, }) - accessor tabs: interfaces.ITab[] = [ + accessor tabs: interfaces.IMenuItem[] = [ { key: '⚠️ Please set tabs', action: () => console.warn('No tabs configured for maincontent') }, ]; @property({ type: Object }) - accessor selectedTab: interfaces.ITab | null = null; + accessor selectedTab: interfaces.IMenuItem | null = null; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { color: ${cssManager.bdTheme('#333', '#fff')}; display: block; diff --git a/ts_web/elements/00group-appui/dees-appui-mainmenu/dees-appui-mainmenu.ts b/ts_web/elements/00group-appui/dees-appui-mainmenu/dees-appui-mainmenu.ts index 54be09b..5e75a95 100644 --- a/ts_web/elements/00group-appui/dees-appui-mainmenu/dees-appui-mainmenu.ts +++ b/ts_web/elements/00group-appui/dees-appui-mainmenu/dees-appui-mainmenu.ts @@ -13,6 +13,7 @@ import { } from '@design.estate/dees-element'; import { DeesContextmenu } from '../../dees-contextmenu/dees-contextmenu.js'; import { demoFunc } from './dees-appui-mainmenu.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; /** * the most left menu @@ -37,21 +38,23 @@ export class DeesAppuiMainmenu extends DeesElement { // Bottom tabs (pinned to bottom) @property({ type: Array }) - accessor bottomTabs: interfaces.ITab[] = []; + accessor bottomTabs: interfaces.IMenuItem[] = []; // Legacy tabs property (for backward compatibility) @property({ type: Array }) - accessor tabs: interfaces.ITab[] = []; + accessor tabs: interfaces.IMenuItem[] = []; @property() - accessor selectedTab: interfaces.ITab; + accessor selectedTab: interfaces.IMenuItem; @property({ type: Boolean, reflect: true }) accessor collapsed: boolean = false; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { --menu-width-expanded: 200px; --menu-width-collapsed: 56px; @@ -390,7 +393,7 @@ export class DeesAppuiMainmenu extends DeesElement { `)} @@ -407,7 +410,7 @@ export class DeesAppuiMainmenu extends DeesElement { `; } - private renderTab(tabArg: interfaces.ITab): TemplateResult { + private renderTab(tabArg: interfaces.IMenuItem): TemplateResult { return html`
0) { - const groupTabs = this.menuGroups.flatMap(group => group.tabs); + const groupTabs = this.menuGroups.flatMap(group => group.items); return [...groupTabs, ...this.bottomTabs]; } return [...this.tabs, ...this.bottomTabs]; } - updateTab(tabArg: interfaces.ITab) { + updateTab(tabArg: interfaces.IMenuItem) { this.selectedTab = tabArg; this.selectedTab.action(); diff --git a/ts_web/elements/00group-appui/dees-appui-profiledropdown/dees-appui-profiledropdown.ts b/ts_web/elements/00group-appui/dees-appui-profiledropdown/dees-appui-profiledropdown.ts index 611ae68..22e177e 100644 --- a/ts_web/elements/00group-appui/dees-appui-profiledropdown/dees-appui-profiledropdown.ts +++ b/ts_web/elements/00group-appui/dees-appui-profiledropdown/dees-appui-profiledropdown.ts @@ -11,6 +11,7 @@ import { cssManager, state, } from '@design.estate/dees-element'; +import { themeDefaultStyles } from '../../00theme.js'; @customElement('dees-appui-profiledropdown') export class DeesAppuiProfileDropdown extends DeesElement { @@ -53,8 +54,10 @@ export class DeesAppuiProfileDropdown extends DeesElement { accessor position: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' = 'top-right'; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; position: absolute; diff --git a/ts_web/elements/00group-appui/dees-appui-secondarymenu/dees-appui-secondarymenu.demo.ts b/ts_web/elements/00group-appui/dees-appui-secondarymenu/dees-appui-secondarymenu.demo.ts index c6efdb1..8206ddc 100644 --- a/ts_web/elements/00group-appui/dees-appui-secondarymenu/dees-appui-secondarymenu.demo.ts +++ b/ts_web/elements/00group-appui/dees-appui-secondarymenu/dees-appui-secondarymenu.demo.ts @@ -44,7 +44,7 @@ export const demoFunc = () => html` { key: 'Integrations', iconName: 'plug', action: () => console.log('Integrations'), badge: 5, badgeVariant: 'error' }, ] } - ] as interfaces.ISecondaryMenuGroup[]} + ] as interfaces.IMenuGroup[]} @item-select=${(e: CustomEvent) => console.log('Selected:', e.detail)} >
diff --git a/ts_web/elements/00group-appui/dees-appui-secondarymenu/dees-appui-secondarymenu.ts b/ts_web/elements/00group-appui/dees-appui-secondarymenu/dees-appui-secondarymenu.ts index 6ba8d32..1122b3e 100644 --- a/ts_web/elements/00group-appui/dees-appui-secondarymenu/dees-appui-secondarymenu.ts +++ b/ts_web/elements/00group-appui/dees-appui-secondarymenu/dees-appui-secondarymenu.ts @@ -15,6 +15,7 @@ import { cssManager, } from '@design.estate/dees-element'; import { demoFunc } from './dees-appui-secondarymenu.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; /** * Secondary navigation menu for sub-navigation within MainMenu views @@ -32,15 +33,15 @@ export class DeesAppuiSecondarymenu extends DeesElement { /** Grouped items with collapse support */ @property({ type: Array }) - accessor groups: interfaces.ISecondaryMenuGroup[] = []; + accessor groups: interfaces.IMenuGroup[] = []; /** Legacy flat list support for backward compatibility */ @property({ type: Array }) - accessor selectionOptions: (interfaces.ISelectionOption | { divider: true })[] = []; + accessor selectionOptions: (interfaces.IMenuItem | { divider: true })[] = []; /** Currently selected item */ @property({ type: Object }) - accessor selectedItem: interfaces.ISecondaryMenuItem | null = null; + accessor selectedItem: interfaces.IMenuItem | null = null; /** Internal state for collapsed groups */ @state() @@ -51,8 +52,10 @@ export class DeesAppuiSecondarymenu extends DeesElement { accessor collapsed: boolean = false; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { --sidebar-width-expanded: 240px; --sidebar-width-collapsed: 56px; @@ -482,7 +485,7 @@ export class DeesAppuiSecondarymenu extends DeesElement { `; } - private renderMenuItem(item: interfaces.ISecondaryMenuItem, group?: interfaces.ISecondaryMenuGroup): TemplateResult { + private renderMenuItem(item: interfaces.IMenuItem, group?: interfaces.IMenuGroup): TemplateResult { const isSelected = this.selectedItem?.key === item.key; return html`
`; } - const item = option as interfaces.ISelectionOption; + const item = option as interfaces.IMenuItem; return this.renderMenuItem({ key: item.key, iconName: item.iconName, @@ -537,7 +540,7 @@ export class DeesAppuiSecondarymenu extends DeesElement { })); } - private selectItem(item: interfaces.ISecondaryMenuItem, group?: interfaces.ISecondaryMenuGroup): void { + private selectItem(item: interfaces.IMenuItem, group?: interfaces.IMenuGroup): void { this.selectedItem = item; item.action(); @@ -548,7 +551,7 @@ export class DeesAppuiSecondarymenu extends DeesElement { })); } - private handleContextMenu(event: MouseEvent, item: interfaces.ISecondaryMenuItem): void { + private handleContextMenu(event: MouseEvent, item: interfaces.IMenuItem): void { DeesContextmenu.openContextMenuWithOptions(event, [ { name: 'View details', @@ -582,7 +585,7 @@ export class DeesAppuiSecondarymenu extends DeesElement { } } else if (this.selectionOptions.length > 0) { // Legacy mode: select first non-divider option - const firstOption = this.selectionOptions.find(opt => !('divider' in opt)) as interfaces.ISelectionOption; + const firstOption = this.selectionOptions.find(opt => !('divider' in opt)) as interfaces.IMenuItem; if (firstOption && !this.selectedItem) { this.selectItem({ key: firstOption.key, diff --git a/ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.demo.ts b/ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.demo.ts new file mode 100644 index 0000000..43fa509 --- /dev/null +++ b/ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.demo.ts @@ -0,0 +1,91 @@ +import { html, cssManager } from '@design.estate/dees-element'; +import * as interfaces from '../../interfaces/index.js'; + +export const demoFunc = () => { + const horizontalTabs: interfaces.IMenuItem[] = [ + { key: 'Home', iconName: 'lucide:home', action: () => console.log('Home clicked') }, + { key: 'Analytics Dashboard', iconName: 'lucide:lineChart', action: () => console.log('Analytics clicked') }, + { key: 'Reports', iconName: 'lucide:fileText', action: () => console.log('Reports clicked') }, + { key: 'User Settings', iconName: 'lucide:settings', action: () => console.log('Settings clicked') }, + { key: 'Help', iconName: 'lucide:helpCircle', action: () => console.log('Help clicked') }, + ]; + + const verticalTabs: interfaces.IMenuItem[] = [ + { key: 'Profile', iconName: 'lucide:user', action: () => console.log('Profile clicked') }, + { key: 'Security', iconName: 'lucide:shield', action: () => console.log('Security clicked') }, + { key: 'Notifications', iconName: 'lucide:bell', action: () => console.log('Notifications clicked') }, + { key: 'Integrations', iconName: 'lucide:link', action: () => console.log('Integrations clicked') }, + { key: 'Advanced', iconName: 'lucide:code', action: () => console.log('Advanced clicked') }, + ]; + + const noIndicatorTabs: interfaces.IMenuItem[] = [ + { key: 'All', action: () => console.log('All clicked') }, + { key: 'Active', action: () => console.log('Active clicked') }, + { key: 'Completed', action: () => console.log('Completed clicked') }, + { key: 'Archived', action: () => console.log('Archived clicked') }, + ]; + + const demoContent = (text: string) => html` +
+ ${text} +
+ `; + + return html` + +
+
+
Horizontal Tabs with Animated Indicator
+ + ${demoContent('Select a tab to see the smooth sliding animation of the indicator. The indicator automatically adjusts its width to match the tab content with minimal padding.')} + +
+ +
+
Vertical Tabs Layout
+
+ + ${demoContent('Vertical tabs work great for settings pages and navigation menus. The animated indicator smoothly transitions between selections.')} +
+
+ +
+
Without Indicator
+ + ${demoContent('Tabs can also be used without the animated indicator by setting showTabIndicator to false.')} + +
+
+ `; +}; diff --git a/ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.ts b/ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.ts index 9d9fd2c..ae21719 100644 --- a/ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.ts +++ b/ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.ts @@ -11,106 +11,21 @@ import { } from '@design.estate/dees-element'; import * as domtools from '@design.estate/dees-domtools'; +import { demoFunc } from './dees-appui-tabs.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; @customElement('dees-appui-tabs') export class DeesAppuiTabs extends DeesElement { - public static demo = () => { - const horizontalTabs: interfaces.ITab[] = [ - { key: 'Home', iconName: 'lucide:home', action: () => console.log('Home clicked') }, - { key: 'Analytics Dashboard', iconName: 'lucide:lineChart', action: () => console.log('Analytics clicked') }, - { key: 'Reports', iconName: 'lucide:fileText', action: () => console.log('Reports clicked') }, - { key: 'User Settings', iconName: 'lucide:settings', action: () => console.log('Settings clicked') }, - { key: 'Help', iconName: 'lucide:helpCircle', action: () => console.log('Help clicked') }, - ]; - - const verticalTabs: interfaces.ITab[] = [ - { key: 'Profile', iconName: 'lucide:user', action: () => console.log('Profile clicked') }, - { key: 'Security', iconName: 'lucide:shield', action: () => console.log('Security clicked') }, - { key: 'Notifications', iconName: 'lucide:bell', action: () => console.log('Notifications clicked') }, - { key: 'Integrations', iconName: 'lucide:link', action: () => console.log('Integrations clicked') }, - { key: 'Advanced', iconName: 'lucide:code', action: () => console.log('Advanced clicked') }, - ]; - - const noIndicatorTabs: interfaces.ITab[] = [ - { key: 'All', action: () => console.log('All clicked') }, - { key: 'Active', action: () => console.log('Active clicked') }, - { key: 'Completed', action: () => console.log('Completed clicked') }, - { key: 'Archived', action: () => console.log('Archived clicked') }, - ]; - - const demoContent = (text: string) => html` -
- ${text} -
- `; - - return html` - -
-
-
Horizontal Tabs with Animated Indicator
- - ${demoContent('Select a tab to see the smooth sliding animation of the indicator. The indicator automatically adjusts its width to match the tab content with minimal padding.')} - -
- -
-
Vertical Tabs Layout
-
- - ${demoContent('Vertical tabs work great for settings pages and navigation menus. The animated indicator smoothly transitions between selections.')} -
-
- -
-
Without Indicator
- - ${demoContent('Tabs can also be used without the animated indicator by setting showTabIndicator to false.')} - -
-
- `; - }; + public static demo = demoFunc; // INSTANCE @property({ type: Array, }) - accessor tabs: interfaces.ITab[] = []; + accessor tabs: interfaces.IMenuItem[] = []; @property({ type: Object }) - accessor selectedTab: interfaces.ITab | null = null; + accessor selectedTab: interfaces.IMenuItem | null = null; @property({ type: Boolean }) accessor showTabIndicator: boolean = true; @@ -119,8 +34,10 @@ export class DeesAppuiTabs extends DeesElement { accessor tabStyle: 'horizontal' | 'vertical' = 'horizontal'; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; position: relative; @@ -312,7 +229,7 @@ export class DeesAppuiTabs extends DeesElement { `; } - private renderTab(tab: interfaces.ITab, isHorizontal: boolean): TemplateResult { + private renderTab(tab: interfaces.IMenuItem, isHorizontal: boolean): TemplateResult { const isSelected = tab === this.selectedTab; const classes = `tab ${isSelected ? 'selectedTab' : ''}`; @@ -336,11 +253,11 @@ export class DeesAppuiTabs extends DeesElement { `; } - private renderTabIcon(tab: interfaces.ITab): TemplateResult | '' { + private renderTabIcon(tab: interfaces.IMenuItem): TemplateResult | '' { return tab.iconName ? html`` : ''; } - private selectTab(tabArg: interfaces.ITab) { + private selectTab(tabArg: interfaces.IMenuItem) { this.selectedTab = tabArg; tabArg.action(); diff --git a/ts_web/elements/00group-appui/dees-appui-view/dees-appui-view.demo.ts b/ts_web/elements/00group-appui/dees-appui-view/dees-appui-view.demo.ts new file mode 100644 index 0000000..b68349b --- /dev/null +++ b/ts_web/elements/00group-appui/dees-appui-view/dees-appui-view.demo.ts @@ -0,0 +1,30 @@ +import { html } from '@design.estate/dees-element'; + +export const demoFunc = () => html` + console.log('Overview tab'), + content: html`
Overview Content
` + }, + { + key: 'details', + iconName: 'lucide:fileText', + action: () => console.log('Details tab'), + content: html`
Details Content
` + } + ], + menuItems: [ + { key: 'General', action: () => console.log('General') }, + { key: 'Advanced', action: () => console.log('Advanced') }, + ] + }} + >
+`; diff --git a/ts_web/elements/00group-appui/dees-appui-view/dees-appui-view.ts b/ts_web/elements/00group-appui/dees-appui-view/dees-appui-view.ts index c63b367..52f203a 100644 --- a/ts_web/elements/00group-appui/dees-appui-view/dees-appui-view.ts +++ b/ts_web/elements/00group-appui/dees-appui-view/dees-appui-view.ts @@ -13,9 +13,14 @@ import { import '../dees-appui-tabs/dees-appui-tabs.js'; import type { DeesAppuiTabs } from '../dees-appui-tabs/dees-appui-tabs.js'; +import { demoFunc } from './dees-appui-view.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; -export interface IAppViewTab extends interfaces.ITab { +export interface IViewTab extends interfaces.IMenuItem { content?: TemplateResult | (() => TemplateResult); + useSlotName?: boolean; + slotName?: string; + paddingPx?: number; } export interface IAppView { @@ -23,54 +28,32 @@ export interface IAppView { name: string; description?: string; iconName?: string; - tabs: IAppViewTab[]; - menuItems?: interfaces.ISelectionOption[]; + tabs: IViewTab[]; + menuItems?: interfaces.IMenuItem[]; } @customElement('dees-appui-view') export class DeesAppuiView extends DeesElement { - public static demo = () => html` - console.log('Overview tab'), - content: html`
Overview Content
` - }, - { - key: 'details', - iconName: 'lucide:fileText', - action: () => console.log('Details tab'), - content: html`
Details Content
` - } - ], - menuItems: [ - { key: 'General', action: () => console.log('General') }, - { key: 'Advanced', action: () => console.log('Advanced') }, - ] - }} - >
- `; + public static demo = demoFunc; // INSTANCE @property({ type: Object }) accessor viewConfig: IAppView; @state() - accessor selectedTab: IAppViewTab | null = null; + accessor selectedTab: IViewTab | null = null; @state() accessor tabs: DeesAppuiTabs; + @property({ type: Number }) + accessor paddingPx: number = 16; + public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; position: relative; @@ -138,9 +121,14 @@ export class DeesAppuiView extends DeesElement { ${this.viewConfig.tabs.map((tab) => { const isActive = tab === this.selectedTab; const content = typeof tab.content === 'function' ? tab.content() : tab.content; + const padding = tab.paddingPx ?? this.paddingPx; return html` -
- ${content || html``} +
+ ${content + ? content + : tab.useSlotName + ? html`` + : ''}
`; })} @@ -182,11 +170,11 @@ export class DeesAppuiView extends DeesElement { } } - public getMenuItems(): interfaces.ISelectionOption[] { + public getMenuItems(): interfaces.IMenuItem[] { return this.viewConfig?.menuItems || []; } - public getTabs(): IAppViewTab[] { + public getTabs(): IViewTab[] { return this.viewConfig?.tabs || []; } } \ No newline at end of file diff --git a/ts_web/elements/00group-button/dees-button-group/dees-button-group.ts b/ts_web/elements/00group-button/dees-button-group/dees-button-group.ts index 78acdd0..3f27487 100644 --- a/ts_web/elements/00group-button/dees-button-group/dees-button-group.ts +++ b/ts_web/elements/00group-button/dees-button-group/dees-button-group.ts @@ -10,6 +10,7 @@ import { import * as domtools from '@design.estate/dees-domtools'; import { demoFunc } from './dees-button-group.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -33,8 +34,10 @@ export class DeesButtonGroup extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: inline-block; } diff --git a/ts_web/elements/00group-button/dees-button/dees-button.ts b/ts_web/elements/00group-button/dees-button/dees-button.ts index 5847cb0..e176f94 100644 --- a/ts_web/elements/00group-button/dees-button/dees-button.ts +++ b/ts_web/elements/00group-button/dees-button/dees-button.ts @@ -12,6 +12,7 @@ import { import * as domtools from '@design.estate/dees-domtools'; import { demoFunc } from './dees-button.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -79,8 +80,10 @@ export class DeesButton extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: inline-block; box-sizing: border-box; diff --git a/ts_web/elements/00group-chart/dees-chart-log/dees-chart-log.ts b/ts_web/elements/00group-chart/dees-chart-log/dees-chart-log.ts index 65263f0..06c4f85 100644 --- a/ts_web/elements/00group-chart/dees-chart-log/dees-chart-log.ts +++ b/ts_web/elements/00group-chart/dees-chart-log/dees-chart-log.ts @@ -10,6 +10,7 @@ import { import * as domtools from '@design.estate/dees-domtools'; import { demoFunc } from './dees-chart-log.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { @@ -50,8 +51,10 @@ export class DeesChartLog extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { font-family: 'SF Mono', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', monospace; color: ${cssManager.bdTheme('hsl(0 0% 3.9%)', 'hsl(0 0% 98%)')}; diff --git a/ts_web/elements/00group-dataview/dees-dataview-statusobject/dees-dataview-statusobject.ts b/ts_web/elements/00group-dataview/dees-dataview-statusobject/dees-dataview-statusobject.ts index 6265997..6d43db3 100644 --- a/ts_web/elements/00group-dataview/dees-dataview-statusobject/dees-dataview-statusobject.ts +++ b/ts_web/elements/00group-dataview/dees-dataview-statusobject/dees-dataview-statusobject.ts @@ -16,6 +16,7 @@ import { import * as tsclass from '@tsclass/tsclass'; import { DeesContextmenu } from '../../dees-contextmenu/dees-contextmenu.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -30,8 +31,10 @@ export class DeesDataviewStatusobject extends DeesElement { @property({ type: Object }) accessor statusObject: tsclass.code.IStatusObject; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; } diff --git a/ts_web/elements/00group-editor/dees-editor-markdown/dees-editor-markdown.ts b/ts_web/elements/00group-editor/dees-editor-markdown/dees-editor-markdown.ts index 5445c51..dc1b0a2 100644 --- a/ts_web/elements/00group-editor/dees-editor-markdown/dees-editor-markdown.ts +++ b/ts_web/elements/00group-editor/dees-editor-markdown/dees-editor-markdown.ts @@ -8,6 +8,7 @@ import { cssManager, domtools } from '@design.estate/dees-element'; +import { themeDefaultStyles } from '../../00theme.js'; const deferred = domtools.plugins.smartpromise.defer(); @@ -22,8 +23,10 @@ export class DeesEditorMarkdown extends DeesElement { public static demo = () => html``; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ .gridcontainer { position: absolute; height: 100%; diff --git a/ts_web/elements/00group-editor/dees-editor/dees-editor.ts b/ts_web/elements/00group-editor/dees-editor/dees-editor.ts index e8ff152..9b72e96 100644 --- a/ts_web/elements/00group-editor/dees-editor/dees-editor.ts +++ b/ts_web/elements/00group-editor/dees-editor/dees-editor.ts @@ -9,6 +9,7 @@ import { } from '@design.estate/dees-element'; import * as domtools from '@design.estate/dees-domtools'; import { MONACO_VERSION } from './version.js'; +import { themeDefaultStyles } from '../../00theme.js'; import type * as monaco from 'monaco-editor'; @@ -51,8 +52,10 @@ export class DeesEditor extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { } diff --git a/ts_web/elements/00group-form/dees-form-submit/dees-form-submit.ts b/ts_web/elements/00group-form/dees-form-submit/dees-form-submit.ts index fc792be..7c07068 100644 --- a/ts_web/elements/00group-form/dees-form-submit/dees-form-submit.ts +++ b/ts_web/elements/00group-form/dees-form-submit/dees-form-submit.ts @@ -8,6 +8,7 @@ import { property, } from '@design.estate/dees-element'; import type { DeesForm } from '../dees-form/dees-form.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -39,7 +40,9 @@ export class DeesFormSubmit extends DeesElement { super(); } - public static styles = [cssManager.defaultStyles, css``]; + public static styles = [themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ + `]; public render() { return html` diff --git a/ts_web/elements/00group-input/dees-input-checkbox/dees-input-checkbox.ts b/ts_web/elements/00group-input/dees-input-checkbox/dees-input-checkbox.ts index 715ac0e..0b415c9 100644 --- a/ts_web/elements/00group-input/dees-input-checkbox/dees-input-checkbox.ts +++ b/ts_web/elements/00group-input/dees-input-checkbox/dees-input-checkbox.ts @@ -9,6 +9,7 @@ import { import { DeesInputBase } from '../dees-input-base/dees-input-base.js'; import { demoFunc } from './dees-input-checkbox.demo.js'; import { cssGeistFontFamily } from '../../00fonts.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -38,9 +39,11 @@ export class DeesInputCheckbox extends DeesInputBase { } public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ * { box-sizing: border-box; } diff --git a/ts_web/elements/00group-input/dees-input-dropdown/dees-input-dropdown.ts b/ts_web/elements/00group-input/dees-input-dropdown/dees-input-dropdown.ts index 6aaee63..43cbc84 100644 --- a/ts_web/elements/00group-input/dees-input-dropdown/dees-input-dropdown.ts +++ b/ts_web/elements/00group-input/dees-input-dropdown/dees-input-dropdown.ts @@ -11,6 +11,7 @@ import * as domtools from '@design.estate/dees-domtools'; import { demoFunc } from './dees-input-dropdown.demo.js'; import { DeesInputBase } from '../dees-input-base/dees-input-base.js'; import { cssGeistFontFamily } from '../../00fonts.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -60,9 +61,11 @@ export class DeesInputDropdown extends DeesInputBase { accessor searchValue: string = ''; public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ * { box-sizing: border-box; } diff --git a/ts_web/elements/00group-input/dees-input-iban/dees-input-iban.ts b/ts_web/elements/00group-input/dees-input-iban/dees-input-iban.ts index 85b36bd..99d3c69 100644 --- a/ts_web/elements/00group-input/dees-input-iban/dees-input-iban.ts +++ b/ts_web/elements/00group-input/dees-input-iban/dees-input-iban.ts @@ -11,6 +11,7 @@ import * as domtools from '@design.estate/dees-domtools'; import { DeesInputBase } from '../dees-input-base/dees-input-base.js'; import * as ibantools from 'ibantools'; import { demoFunc } from './dees-input-iban.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; @customElement('dees-input-iban') export class DeesInputIban extends DeesInputBase { @@ -30,9 +31,11 @@ export class DeesInputIban extends DeesInputBase { accessor value = ''; public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ /* IBAN input specific styles can go here */ `, ]; diff --git a/ts_web/elements/00group-input/dees-input-list/dees-input-list.ts b/ts_web/elements/00group-input/dees-input-list/dees-input-list.ts index 6592d20..2df4113 100644 --- a/ts_web/elements/00group-input/dees-input-list/dees-input-list.ts +++ b/ts_web/elements/00group-input/dees-input-list/dees-input-list.ts @@ -11,6 +11,7 @@ import { DeesInputBase } from '../dees-input-base/dees-input-base.js'; import '../../dees-icon/dees-icon.js'; import '../../00group-button/dees-button/dees-button.js'; import { demoFunc } from './dees-input-list.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -64,9 +65,11 @@ export class DeesInputList extends DeesInputBase { accessor dragOverIndex: number = -1; public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; diff --git a/ts_web/elements/00group-input/dees-input-multitoggle/dees-input-multitoggle.ts b/ts_web/elements/00group-input/dees-input-multitoggle/dees-input-multitoggle.ts index 981932d..d666f7f 100644 --- a/ts_web/elements/00group-input/dees-input-multitoggle/dees-input-multitoggle.ts +++ b/ts_web/elements/00group-input/dees-input-multitoggle/dees-input-multitoggle.ts @@ -11,6 +11,7 @@ import { DeesInputBase } from '../dees-input-base/dees-input-base.js'; import * as colors from '../../00colors.js' import { demoFunc } from './dees-input-multitoggle.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -67,9 +68,11 @@ export class DeesInputMultitoggle extends DeesInputBase { } public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { color: ${cssManager.bdTheme('#09090b', '#fafafa')}; user-select: none; diff --git a/ts_web/elements/00group-input/dees-input-phone/dees-input-phone.ts b/ts_web/elements/00group-input/dees-input-phone/dees-input-phone.ts index f1bca35..709c77e 100644 --- a/ts_web/elements/00group-input/dees-input-phone/dees-input-phone.ts +++ b/ts_web/elements/00group-input/dees-input-phone/dees-input-phone.ts @@ -10,6 +10,7 @@ import { import * as domtools from '@design.estate/dees-domtools'; import { DeesInputBase } from '../dees-input-base/dees-input-base.js'; import { demoFunc } from './dees-input-phone.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -33,9 +34,11 @@ export class DeesInputPhone extends DeesInputBase { accessor placeholder: string = '+1 (555) 123-4567'; public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ /* Phone input specific styles can go here */ `, ]; diff --git a/ts_web/elements/00group-input/dees-input-quantityselector/dees-input-quantityselector.ts b/ts_web/elements/00group-input/dees-input-quantityselector/dees-input-quantityselector.ts index 15555db..3b8b2e6 100644 --- a/ts_web/elements/00group-input/dees-input-quantityselector/dees-input-quantityselector.ts +++ b/ts_web/elements/00group-input/dees-input-quantityselector/dees-input-quantityselector.ts @@ -2,6 +2,7 @@ import { customElement, property, html, type TemplateResult, css, cssManager } f import * as domtools from '@design.estate/dees-domtools'; import { DeesInputBase } from '../dees-input-base/dees-input-base.js'; import { demoFunc } from './dees-input-quantityselector.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -23,14 +24,16 @@ export class DeesInputQuantitySelector extends DeesInputBase { } public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ * { box-sizing: border-box; } diff --git a/ts_web/elements/00group-input/dees-input-tags/dees-input-tags.ts b/ts_web/elements/00group-input/dees-input-tags/dees-input-tags.ts index 2e8aa25..3ffee6a 100644 --- a/ts_web/elements/00group-input/dees-input-tags/dees-input-tags.ts +++ b/ts_web/elements/00group-input/dees-input-tags/dees-input-tags.ts @@ -10,6 +10,7 @@ import { import { DeesInputBase } from '../dees-input-base/dees-input-base.js'; import '../../dees-icon/dees-icon.js'; import { demoFunc } from './dees-input-tags.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -48,9 +49,11 @@ export class DeesInputTags extends DeesInputBase { accessor validationText: string = ''; public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; diff --git a/ts_web/elements/00group-input/dees-input-text/dees-input-text.ts b/ts_web/elements/00group-input/dees-input-text/dees-input-text.ts index 93280d0..b91d2d2 100644 --- a/ts_web/elements/00group-input/dees-input-text/dees-input-text.ts +++ b/ts_web/elements/00group-input/dees-input-text/dees-input-text.ts @@ -11,6 +11,7 @@ import { cssManager, css, } from '@design.estate/dees-element'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -56,9 +57,11 @@ export class DeesInputText extends DeesInputBase { accessor validationFunction: (value: string) => boolean; public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ * { box-sizing: border-box; } diff --git a/ts_web/elements/00group-input/dees-input-typelist/dees-input-typelist.ts b/ts_web/elements/00group-input/dees-input-typelist/dees-input-typelist.ts index 9369227..8806580 100644 --- a/ts_web/elements/00group-input/dees-input-typelist/dees-input-typelist.ts +++ b/ts_web/elements/00group-input/dees-input-typelist/dees-input-typelist.ts @@ -11,6 +11,7 @@ import * as domtools from '@design.estate/dees-domtools'; import { DeesInputBase } from '../dees-input-base/dees-input-base.js'; import { demoFunc } from './dees-input-typelist.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; @customElement('dees-input-typelist') export class DeesInputTypelist extends DeesInputBase { @@ -27,9 +28,11 @@ export class DeesInputTypelist extends DeesInputBase { public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { color: ${cssManager.bdTheme('#333', '#fff')}; } diff --git a/ts_web/elements/00group-input/dees-input-wysiwyg/dees-formatting-menu.ts b/ts_web/elements/00group-input/dees-input-wysiwyg/dees-formatting-menu.ts index fbc1595..b15f7c8 100644 --- a/ts_web/elements/00group-input/dees-input-wysiwyg/dees-formatting-menu.ts +++ b/ts_web/elements/00group-input/dees-input-wysiwyg/dees-formatting-menu.ts @@ -10,6 +10,7 @@ import { import { zIndexRegistry } from '../../00zindex.js'; import { WysiwygFormatting } from './wysiwyg.formatting.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -41,8 +42,10 @@ export class DeesFormattingMenu extends DeesElement { private callback: ((command: string) => void | Promise) | null = null; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { position: fixed; pointer-events: none; diff --git a/ts_web/elements/00group-input/dees-input-wysiwyg/dees-input-wysiwyg.ts b/ts_web/elements/00group-input/dees-input-wysiwyg/dees-input-wysiwyg.ts index 70ad1bf..146c802 100644 --- a/ts_web/elements/00group-input/dees-input-wysiwyg/dees-input-wysiwyg.ts +++ b/ts_web/elements/00group-input/dees-input-wysiwyg/dees-input-wysiwyg.ts @@ -28,6 +28,7 @@ import { DeesSlashMenu, DeesFormattingMenu } from './index.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -86,6 +87,7 @@ export class DeesInputWysiwyg extends DeesInputBase { private history: WysiwygHistory; public static styles = [ + themeDefaultStyles, ...DeesInputBase.baseStyles, cssManager.defaultStyles, wysiwygStyles diff --git a/ts_web/elements/00group-input/dees-input-wysiwyg/dees-slash-menu.ts b/ts_web/elements/00group-input/dees-input-wysiwyg/dees-slash-menu.ts index afb7cd2..4c9712b 100644 --- a/ts_web/elements/00group-input/dees-input-wysiwyg/dees-slash-menu.ts +++ b/ts_web/elements/00group-input/dees-input-wysiwyg/dees-slash-menu.ts @@ -12,6 +12,7 @@ import '../../dees-icon/dees-icon.js'; import { type ISlashMenuItem } from './wysiwyg.types.js'; import { WysiwygShortcuts } from './wysiwyg.shortcuts.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -49,8 +50,10 @@ export class DeesSlashMenu extends DeesElement { private callback: ((type: string) => void) | null = null; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { position: fixed; pointer-events: none; diff --git a/ts_web/elements/00group-input/dees-input-wysiwyg/dees-wysiwyg-block.ts b/ts_web/elements/00group-input/dees-input-wysiwyg/dees-wysiwyg-block.ts index 3f2f9cd..4050843 100644 --- a/ts_web/elements/00group-input/dees-input-wysiwyg/dees-wysiwyg-block.ts +++ b/ts_web/elements/00group-input/dees-input-wysiwyg/dees-wysiwyg-block.ts @@ -15,6 +15,7 @@ import { BlockRegistry, type IBlockEventHandlers } from './blocks/index.js'; import './wysiwyg.blockregistration.js'; import { WysiwygShortcuts } from './wysiwyg.shortcuts.js'; import '../../dees-contextmenu/dees-contextmenu.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -82,8 +83,10 @@ export class DeesWysiwygBlock extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; } diff --git a/ts_web/elements/00group-input/profilepicture/dees-input-profilepicture.ts b/ts_web/elements/00group-input/profilepicture/dees-input-profilepicture.ts index d1a07af..c982f54 100644 --- a/ts_web/elements/00group-input/profilepicture/dees-input-profilepicture.ts +++ b/ts_web/elements/00group-input/profilepicture/dees-input-profilepicture.ts @@ -12,6 +12,7 @@ import '../../dees-icon/dees-icon.js'; import '../../dees-label/dees-label.js'; import { ProfilePictureModal } from './profilepicture.modal.js'; import { demoFunc } from './dees-input-profilepicture.demo.js'; +import { themeDefaultStyles } from '../../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -67,9 +68,11 @@ export class DeesInputProfilePicture extends DeesInputBase
`; diff --git a/ts_web/elements/dees-icon/dees-icon.ts b/ts_web/elements/dees-icon/dees-icon.ts index a25e662..9990720 100644 --- a/ts_web/elements/dees-icon/dees-icon.ts +++ b/ts_web/elements/dees-icon/dees-icon.ts @@ -9,6 +9,7 @@ import { } from '@design.estate/dees-element'; import * as domtools from '@design.estate/dees-domtools'; +import { themeDefaultStyles } from '../00theme.js'; import { icon, type IconDefinition } from '@fortawesome/fontawesome-svg-core'; import { @@ -325,8 +326,10 @@ export class DeesIcon extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: inline-flex; align-items: center; @@ -334,7 +337,7 @@ export class DeesIcon extends DeesElement { line-height: 1; vertical-align: middle; } - + /* Improve rendering performance */ #iconContainer svg { display: block; diff --git a/ts_web/elements/dees-label/dees-label.ts b/ts_web/elements/dees-label/dees-label.ts index 41fa8ce..c85a0b5 100644 --- a/ts_web/elements/dees-label/dees-label.ts +++ b/ts_web/elements/dees-label/dees-label.ts @@ -13,6 +13,7 @@ import { } from '@design.estate/dees-element'; import { demoFunc } from './dees-label.demo.js'; +import { themeDefaultStyles } from '../00theme.js'; @customElement('dees-label') export class DeesLabel extends DeesElement { @@ -39,8 +40,10 @@ export class DeesLabel extends DeesElement { accessor required: boolean = false; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; } diff --git a/ts_web/elements/dees-mobilenavigation/dees-mobilenavigation.ts b/ts_web/elements/dees-mobilenavigation/dees-mobilenavigation.ts index e1f8ad1..15eb0f4 100644 --- a/ts_web/elements/dees-mobilenavigation/dees-mobilenavigation.ts +++ b/ts_web/elements/dees-mobilenavigation/dees-mobilenavigation.ts @@ -14,6 +14,7 @@ import { } from '@design.estate/dees-element'; import { DeesWindowLayer } from '../dees-windowlayer/dees-windowlayer.js'; import '../dees-icon/dees-icon.js'; +import { themeDefaultStyles } from '../00theme.js'; @customElement('dees-mobilenavigation') export class DeesMobilenavigation extends DeesElement { @@ -111,8 +112,10 @@ export class DeesMobilenavigation extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { font-family: ${cssGeistFontFamily}; } diff --git a/ts_web/elements/dees-modal/dees-modal.ts b/ts_web/elements/dees-modal/dees-modal.ts index 7b2b3f2..6d88d3d 100644 --- a/ts_web/elements/dees-modal/dees-modal.ts +++ b/ts_web/elements/dees-modal/dees-modal.ts @@ -21,6 +21,7 @@ import { import * as domtools from '@design.estate/dees-domtools'; import { DeesWindowLayer } from '../dees-windowlayer/dees-windowlayer.js'; import '../dees-icon/dees-icon.js'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -115,8 +116,10 @@ export class DeesModal extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { font-family: ${cssGeistFontFamily}; color: ${cssManager.bdTheme('#333', '#fff')}; diff --git a/ts_web/elements/dees-pagination/dees-pagination.ts b/ts_web/elements/dees-pagination/dees-pagination.ts index caef12b..75685ef 100644 --- a/ts_web/elements/dees-pagination/dees-pagination.ts +++ b/ts_web/elements/dees-pagination/dees-pagination.ts @@ -1,5 +1,6 @@ import { customElement, html, DeesElement, property, css, cssManager, type TemplateResult } from '@design.estate/dees-element'; import { demoFunc } from './dees-pagination.demo.js'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -23,8 +24,10 @@ export class DeesPagination extends DeesElement { accessor total = 1; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: inline-flex; align-items: center; diff --git a/ts_web/elements/dees-panel/dees-panel.ts b/ts_web/elements/dees-panel/dees-panel.ts index 6bd8bce..f59c687 100644 --- a/ts_web/elements/dees-panel/dees-panel.ts +++ b/ts_web/elements/dees-panel/dees-panel.ts @@ -9,6 +9,7 @@ import { } from '@design.estate/dees-element'; import { demoFunc } from './dees-panel.demo.js'; import { cssGeistFontFamily } from '../00fonts.js'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -36,8 +37,10 @@ export class DeesPanel extends DeesElement { accessor runAfterRender: ((elementArg: HTMLElement) => void | Promise) | undefined = undefined; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; font-family: ${cssGeistFontFamily}; diff --git a/ts_web/elements/dees-progressbar/dees-progressbar.ts b/ts_web/elements/dees-progressbar/dees-progressbar.ts index 88f675b..1958835 100644 --- a/ts_web/elements/dees-progressbar/dees-progressbar.ts +++ b/ts_web/elements/dees-progressbar/dees-progressbar.ts @@ -16,6 +16,7 @@ import { } from '@design.estate/dees-element'; import * as domtools from '@design.estate/dees-domtools'; +import { themeDefaultStyles } from '../00theme.js'; @customElement('dees-progressbar') export class DeesProgressbar extends DeesElement { @@ -29,8 +30,10 @@ export class DeesProgressbar extends DeesElement { accessor percentage = 0; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { color: ${cssManager.bdTheme(colors.bright.text, colors.dark.text)}; } diff --git a/ts_web/elements/dees-searchbar/dees-searchbar.ts b/ts_web/elements/dees-searchbar/dees-searchbar.ts index 06e0d04..6a51178 100644 --- a/ts_web/elements/dees-searchbar/dees-searchbar.ts +++ b/ts_web/elements/dees-searchbar/dees-searchbar.ts @@ -13,6 +13,7 @@ import { import * as colors from '../00colors.js'; import { demoFunc } from './dees-searchbar.demo.js'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -27,8 +28,10 @@ export class DeesSearchbar extends DeesElement { // STATIC public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { padding: 40px; font-family: Dees Sans; diff --git a/ts_web/elements/dees-shopping-productcard/dees-shopping-productcard.ts b/ts_web/elements/dees-shopping-productcard/dees-shopping-productcard.ts index 37d35a2..a0dc127 100644 --- a/ts_web/elements/dees-shopping-productcard/dees-shopping-productcard.ts +++ b/ts_web/elements/dees-shopping-productcard/dees-shopping-productcard.ts @@ -8,6 +8,7 @@ import { DeesElement, } from '@design.estate/dees-element'; import { demoFunc } from './dees-shopping-productcard.demo.js'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -51,8 +52,10 @@ export class DeesShoppingProductcard extends DeesElement { accessor selected: boolean = false; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; } diff --git a/ts_web/elements/dees-speechbubble/dees-speechbubble.ts b/ts_web/elements/dees-speechbubble/dees-speechbubble.ts index ee57687..61b0901 100644 --- a/ts_web/elements/dees-speechbubble/dees-speechbubble.ts +++ b/ts_web/elements/dees-speechbubble/dees-speechbubble.ts @@ -17,6 +17,7 @@ import { unsafeHTML, } from '@design.estate/dees-element'; import { DeesWindowLayer } from '../dees-windowlayer/dees-windowlayer.js'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -78,8 +79,10 @@ export class DeesSpeechbubble extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { box-sizing: border-box; color: ${cssManager.bdTheme('#333', '#fff')}; diff --git a/ts_web/elements/dees-spinner/dees-spinner.ts b/ts_web/elements/dees-spinner/dees-spinner.ts index 08ec8f2..2aaf51d 100644 --- a/ts_web/elements/dees-spinner/dees-spinner.ts +++ b/ts_web/elements/dees-spinner/dees-spinner.ts @@ -11,6 +11,7 @@ import { } from '@design.estate/dees-element'; import * as domtools from '@design.estate/dees-domtools'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -46,8 +47,10 @@ export class DeesSpinner extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; } diff --git a/ts_web/elements/dees-statsgrid/dees-statsgrid.ts b/ts_web/elements/dees-statsgrid/dees-statsgrid.ts index 21d242f..f76d8ca 100644 --- a/ts_web/elements/dees-statsgrid/dees-statsgrid.ts +++ b/ts_web/elements/dees-statsgrid/dees-statsgrid.ts @@ -16,6 +16,7 @@ import type { TemplateResult } from '@design.estate/dees-element'; import '../dees-icon/dees-icon.js'; import '../dees-contextmenu/dees-contextmenu.js'; import '../00group-button/dees-button/dees-button.js'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -75,8 +76,10 @@ export class DeesStatsGrid extends DeesElement { accessor contextMenuActions: plugins.tsclass.website.IMenuItem[] = []; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; width: 100%; diff --git a/ts_web/elements/dees-stepper/dees-stepper.ts b/ts_web/elements/dees-stepper/dees-stepper.ts index c1dca8f..a2cbcf8 100644 --- a/ts_web/elements/dees-stepper/dees-stepper.ts +++ b/ts_web/elements/dees-stepper/dees-stepper.ts @@ -15,6 +15,7 @@ import { import * as domtools from '@design.estate/dees-domtools'; import { stepperDemo } from './dees-stepper.demo.js'; +import { themeDefaultStyles } from '../00theme.js'; export interface IStep { title: string; @@ -50,8 +51,10 @@ export class DeesStepper extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { position: absolute; width: 100%; diff --git a/ts_web/elements/dees-table/dees-table.ts b/ts_web/elements/dees-table/dees-table.ts index a3805be..d5ba7ae 100644 --- a/ts_web/elements/dees-table/dees-table.ts +++ b/ts_web/elements/dees-table/dees-table.ts @@ -14,6 +14,7 @@ import { getViewData as getViewDataFn, } from './data.js'; import { compileLucenePredicate } from './lucene.js'; +import { themeDefaultStyles } from '../00theme.js'; export type { Column, ITableAction, ITableActionDataArg, TDisplayFunction } from './types.js'; diff --git a/ts_web/elements/dees-table/styles.ts b/ts_web/elements/dees-table/styles.ts index 6b07c17..fd00544 100644 --- a/ts_web/elements/dees-table/styles.ts +++ b/ts_web/elements/dees-table/styles.ts @@ -1,9 +1,12 @@ import { cssManager, css, type CSSResult } from '@design.estate/dees-element'; import { cssGeistFontFamily } from '../00fonts.js'; +import { themeDefaultStyles } from '../00theme.js'; export const tableStyles: CSSResult[] = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; width: 100%; diff --git a/ts_web/elements/dees-terminal/dees-terminal.ts b/ts_web/elements/dees-terminal/dees-terminal.ts index 40e3e80..27b4e13 100644 --- a/ts_web/elements/dees-terminal/dees-terminal.ts +++ b/ts_web/elements/dees-terminal/dees-terminal.ts @@ -13,6 +13,7 @@ import * as webcontainer from '@webcontainer/api'; import { Terminal } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -57,8 +58,10 @@ export class DeesTerminal extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { padding: 20px; background: var(--dees-terminal-background, #000000); diff --git a/ts_web/elements/dees-theme/dees-theme.demo.ts b/ts_web/elements/dees-theme/dees-theme.demo.ts new file mode 100644 index 0000000..7271272 --- /dev/null +++ b/ts_web/elements/dees-theme/dees-theme.demo.ts @@ -0,0 +1,275 @@ +import { html, css, cssManager } from '@design.estate/dees-element'; + +export const demoFunc = () => html` + +
+ +
+
Spacing Scale
+
+ CSS variables: --dees-spacing-xs through --dees-spacing-3xl +
+
+
+
+
xs (4px)
+
+
+
+
sm (8px)
+
+
+
+
md (12px)
+
+
+
+
lg (16px)
+
+
+
+
xl (24px)
+
+
+
+
2xl (32px)
+
+
+
+
3xl (48px)
+
+
+
+ +
+
Border Radius Scale
+
+ CSS variables: --dees-radius-xs through --dees-radius-full +
+
+
+
xs
+
2px
+
+
+
sm
+
4px
+
+
+
md
+
6px
+
+
+
lg
+
8px
+
+
+
xl
+
12px
+
+
+
full
+
999px
+
+
+
+ +
+
Shadow Elevation Scale
+
+ CSS variables: --dees-shadow-xs through --dees-shadow-lg +
+
+
+
xs
+
minimal
+
+
+
sm
+
subtle
+
+
+
md
+
medium
+
+
+
lg
+
prominent
+
+
+
+ +
+
Control Height Scale
+
+ CSS variables: --dees-control-height-sm through --dees-control-height-xl +
+
+
+
sm
+
32px
+
+
+
md
+
36px
+
+
+
lg
+
40px
+
+
+
xl
+
48px
+
+
+
+ +
+
Transition Durations
+
+ CSS variables: --dees-transition-fast through --dees-transition-slower +
+
+
+
--dees-transition-fast
+
0.1s
+
+
+
--dees-transition-default
+
0.15s
+
+
+
--dees-transition-slow
+
0.2s
+
+
+
--dees-transition-slower
+
0.3s
+
+
+
+
+
+`; diff --git a/ts_web/elements/dees-theme/dees-theme.ts b/ts_web/elements/dees-theme/dees-theme.ts new file mode 100644 index 0000000..a1b9a9c --- /dev/null +++ b/ts_web/elements/dees-theme/dees-theme.ts @@ -0,0 +1,224 @@ +import { + DeesElement, + type TemplateResult, + property, + customElement, + html, + css, + cssManager, +} from '@design.estate/dees-element'; + +import { + type ITheme, + type IThemeColors, + type IThemeSpacing, + type IThemeRadius, + type IThemeShadows, + type IThemeTransitions, + type IThemeControlHeights, + themeDefaults, + themeDefaultStyles, +} from '../00theme.js'; + +import { demoFunc } from './dees-theme.demo.js'; + +/** + * A theme provider component that wraps children and provides CSS custom properties. + * Can be used at the app root or around specific sections to customize theming. + * + * Usage: + * ```html + * + * + * + * ``` + * + * With custom overrides: + * ```html + * + * + * + * ``` + */ +@customElement('dees-theme') +export class DeesTheme extends DeesElement { + public static demo = demoFunc; + + // ============================================ + // Properties for theme overrides + // ============================================ + + @property({ type: Object }) + accessor customSpacing: Partial | null = null; + + @property({ type: Object }) + accessor customRadius: Partial | null = null; + + @property({ type: Object }) + accessor customShadows: Partial | null = null; + + @property({ type: Object }) + accessor customTransitions: Partial | null = null; + + @property({ type: Object }) + accessor customControlHeights: Partial | null = null; + + // ============================================ + // Styles + // ============================================ + + public static styles = [ + themeDefaultStyles, + cssManager.defaultStyles, + css` + :host { + display: contents; + } + `, + ]; + + // ============================================ + // Render + // ============================================ + + public render(): TemplateResult { + return html` + + + `; + } + + // ============================================ + // Private Methods + // ============================================ + + private generateCustomStyles(): string { + const styles: string[] = [':host {']; + + // Custom spacing + if (this.customSpacing) { + for (const [key, value] of Object.entries(this.customSpacing)) { + if (value) { + styles.push(` --dees-spacing-${key}: ${value};`); + } + } + } + + // Custom radius + if (this.customRadius) { + for (const [key, value] of Object.entries(this.customRadius)) { + if (value) { + styles.push(` --dees-radius-${key}: ${value};`); + } + } + } + + // Custom shadows + if (this.customShadows) { + for (const [key, value] of Object.entries(this.customShadows)) { + if (value) { + styles.push(` --dees-shadow-${key}: ${value};`); + } + } + } + + // Custom transitions + if (this.customTransitions) { + for (const [key, value] of Object.entries(this.customTransitions)) { + if (value) { + const cssKey = key === 'default' ? 'default' : key; + styles.push(` --dees-transition-${cssKey}: ${value};`); + } + } + } + + // Custom control heights + if (this.customControlHeights) { + for (const [key, value] of Object.entries(this.customControlHeights)) { + if (value) { + styles.push(` --dees-control-height-${key}: ${value};`); + } + } + } + + styles.push('}'); + return styles.join('\n'); + } + + // ============================================ + // Public API Methods + // ============================================ + + /** + * Set a spacing value dynamically + */ + public setSpacing(key: keyof IThemeSpacing, value: string): void { + this.customSpacing = { ...this.customSpacing, [key]: value }; + } + + /** + * Set a radius value dynamically + */ + public setRadius(key: keyof IThemeRadius, value: string): void { + this.customRadius = { ...this.customRadius, [key]: value }; + } + + /** + * Set a shadow value dynamically + */ + public setShadow(key: keyof IThemeShadows, value: string): void { + this.customShadows = { ...this.customShadows, [key]: value }; + } + + /** + * Set a transition value dynamically + */ + public setTransition(key: keyof IThemeTransitions, value: string): void { + this.customTransitions = { ...this.customTransitions, [key]: value }; + } + + /** + * Set a control height value dynamically + */ + public setControlHeight(key: keyof IThemeControlHeights, value: string): void { + this.customControlHeights = { ...this.customControlHeights, [key]: value }; + } + + /** + * Get the current theme configuration (defaults + overrides) + */ + public getTheme(): ITheme { + return { + colors: themeDefaults.colors, + spacing: { ...themeDefaults.spacing, ...this.customSpacing }, + radius: { ...themeDefaults.radius, ...this.customRadius }, + shadows: { ...themeDefaults.shadows, ...this.customShadows }, + transitions: { ...themeDefaults.transitions, ...this.customTransitions }, + controlHeights: { ...themeDefaults.controlHeights, ...this.customControlHeights }, + }; + } + + /** + * Reset all custom overrides to defaults + */ + public resetToDefaults(): void { + this.customSpacing = null; + this.customRadius = null; + this.customShadows = null; + this.customTransitions = null; + this.customControlHeights = null; + } + + /** + * Apply a complete theme object + */ + public applyTheme(theme: Partial): void { + if (theme.spacing) this.customSpacing = theme.spacing; + if (theme.radius) this.customRadius = theme.radius; + if (theme.shadows) this.customShadows = theme.shadows; + if (theme.transitions) this.customTransitions = theme.transitions; + if (theme.controlHeights) this.customControlHeights = theme.controlHeights; + } +} diff --git a/ts_web/elements/dees-theme/index.ts b/ts_web/elements/dees-theme/index.ts new file mode 100644 index 0000000..5e16fbb --- /dev/null +++ b/ts_web/elements/dees-theme/index.ts @@ -0,0 +1 @@ +export * from './dees-theme.js'; diff --git a/ts_web/elements/dees-toast/dees-toast.ts b/ts_web/elements/dees-toast/dees-toast.ts index 9fcb143..61bea7a 100644 --- a/ts_web/elements/dees-toast/dees-toast.ts +++ b/ts_web/elements/dees-toast/dees-toast.ts @@ -4,6 +4,7 @@ import * as domtools from '@design.estate/dees-domtools'; import { zIndexLayers } from '../00zindex.js'; import { demoFunc } from './dees-toast.demo.js'; import { cssGeistFontFamily } from '../00fonts.js'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -148,8 +149,10 @@ export class DeesToast extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; pointer-events: auto; diff --git a/ts_web/elements/dees-updater/dees-updater.ts b/ts_web/elements/dees-updater/dees-updater.ts index 45b3b94..56ffe43 100644 --- a/ts_web/elements/dees-updater/dees-updater.ts +++ b/ts_web/elements/dees-updater/dees-updater.ts @@ -11,6 +11,7 @@ import { demoFunc } from './dees-updater.demo.js'; import '../dees-windowlayer/dees-windowlayer.js'; import { css, cssManager } from '@design.estate/dees-element'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -44,8 +45,10 @@ export class DeesUpdater extends DeesElement { } public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ .modalContainer { will-change: transform; position: relative; diff --git a/ts_web/elements/dees-windowcontrols/dees-windowcontrols.ts b/ts_web/elements/dees-windowcontrols/dees-windowcontrols.ts index 7e2aa38..daf7525 100644 --- a/ts_web/elements/dees-windowcontrols/dees-windowcontrols.ts +++ b/ts_web/elements/dees-windowcontrols/dees-windowcontrols.ts @@ -10,6 +10,7 @@ import { css, cssManager, } from '@design.estate/dees-element'; +import { themeDefaultStyles } from '../00theme.js'; declare global { interface HTMLElementTagNameMap { @@ -34,8 +35,10 @@ export class DeesWindowControls extends DeesElement { accessor position: 'left' | 'right' = 'left'; public static styles = [ + themeDefaultStyles, cssManager.defaultStyles, css` + /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { position: relative; display: block; diff --git a/ts_web/elements/index.ts b/ts_web/elements/index.ts index 1820675..3bbcc2f 100644 --- a/ts_web/elements/index.ts +++ b/ts_web/elements/index.ts @@ -1,4 +1,5 @@ export * from './00zindex.js'; +export * from './00theme.js'; // Component Groups export * from './00group-appui/index.js'; @@ -37,3 +38,4 @@ export * from './dees-toast/index.js'; export * from './dees-updater/index.js'; export * from './dees-windowcontrols/index.js'; export * from './dees-windowlayer/index.js'; +export * from './dees-theme/index.js'; diff --git a/ts_web/elements/interfaces/appconfig.ts b/ts_web/elements/interfaces/appconfig.ts index 8d376ae..de336f5 100644 --- a/ts_web/elements/interfaces/appconfig.ts +++ b/ts_web/elements/interfaces/appconfig.ts @@ -1,7 +1,6 @@ import type { TemplateResult } from '@design.estate/dees-element'; import type { IAppBarMenuItem } from './appbarmenuitem.js'; -import type { ITab } from './tab.js'; -import type { ISecondaryMenuGroup } from './secondarymenu.js'; +import type { IMenuItem } from './tab.js'; import type { IMenuGroup } from './menugroup.js'; // Forward declaration for circular reference @@ -15,22 +14,22 @@ export type TDeesAppuiBase = HTMLElement & { setWindowControlsVisible: (visible: boolean) => void; setMainMenu: (config: IMainMenuConfig) => void; updateMainMenuGroup: (groupName: string, update: Partial) => void; - addMainMenuItem: (groupName: string, tab: ITab) => void; + addMainMenuItem: (groupName: string, tab: IMenuItem) => void; removeMainMenuItem: (groupName: string, tabKey: string) => void; setMainMenuSelection: (tabKey: string) => void; setMainMenuCollapsed: (collapsed: boolean) => void; setMainMenuBadge: (tabKey: string, badge: string | number) => void; clearMainMenuBadge: (tabKey: string) => void; - setSecondaryMenu: (config: { heading?: string; groups: ISecondaryMenuGroup[] }) => void; - updateSecondaryMenuGroup: (groupName: string, update: Partial) => void; - addSecondaryMenuItem: (groupName: string, item: ISecondaryMenuGroup['items'][0]) => void; + setSecondaryMenu: (config: { heading?: string; groups: IMenuGroup[] }) => void; + updateSecondaryMenuGroup: (groupName: string, update: Partial) => void; + addSecondaryMenuItem: (groupName: string, item: IMenuGroup['items'][0]) => void; setSecondaryMenuSelection: (itemKey: string) => void; clearSecondaryMenu: () => void; - setContentTabs: (tabs: ITab[]) => void; - addContentTab: (tab: ITab) => void; + setContentTabs: (tabs: IMenuItem[]) => void; + addContentTab: (tab: IMenuItem) => void; removeContentTab: (tabKey: string) => void; selectContentTab: (tabKey: string) => void; - getSelectedContentTab: () => ITab | undefined; + getSelectedContentTab: () => IMenuItem | undefined; activityLog: IActivityLogAPI; navigateToView: (viewId: string, params?: Record) => Promise; getCurrentView: () => IViewDefinition | undefined; @@ -132,9 +131,9 @@ export interface IViewDefinition { | (() => TemplateResult) | (() => Promise HTMLElement) | (() => TemplateResult)>); /** Secondary menu items specific to this view */ - secondaryMenu?: ISecondaryMenuGroup[]; + secondaryMenu?: IMenuGroup[]; /** Content tabs specific to this view */ - contentTabs?: ITab[]; + contentTabs?: IMenuItem[]; /** Optional route path (defaults to id). Supports params like 'settings/:section' */ route?: string; /** Badge to show on menu item */ @@ -169,7 +168,7 @@ export interface IMainMenuConfig { /** Bottom pinned items (view IDs or tabs) */ bottomItems?: string[]; /** Bottom tabs */ - bottomTabs?: ITab[]; + bottomTabs?: IMenuItem[]; } /** diff --git a/ts_web/elements/interfaces/index.ts b/ts_web/elements/interfaces/index.ts index 1536930..99dd6f1 100644 --- a/ts_web/elements/interfaces/index.ts +++ b/ts_web/elements/interfaces/index.ts @@ -1,6 +1,4 @@ export * from './tab.js'; -export * from './selectionoption.js'; export * from './appbarmenuitem.js'; export * from './menugroup.js'; -export * from './secondarymenu.js'; export * from './appconfig.js'; diff --git a/ts_web/elements/interfaces/menugroup.ts b/ts_web/elements/interfaces/menugroup.ts index 4ce3582..a2a30e9 100644 --- a/ts_web/elements/interfaces/menugroup.ts +++ b/ts_web/elements/interfaces/menugroup.ts @@ -1,6 +1,8 @@ -import type { ITab } from './tab.js'; +import type { IMenuItem } from './tab.js'; export interface IMenuGroup { - name?: string; - tabs: ITab[]; + name: string; + items: IMenuItem[]; + collapsed?: boolean; + iconName?: string; } diff --git a/ts_web/elements/interfaces/secondarymenu.ts b/ts_web/elements/interfaces/secondarymenu.ts deleted file mode 100644 index 898879f..0000000 --- a/ts_web/elements/interfaces/secondarymenu.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Interface for individual menu items in the secondary menu - */ -export interface ISecondaryMenuItem { - key: string; - iconName?: string; - action: () => void; - badge?: string | number; - badgeVariant?: 'default' | 'success' | 'warning' | 'error'; -} - -/** - * Interface for collapsible groups in the secondary menu - */ -export interface ISecondaryMenuGroup { - name: string; - items: ISecondaryMenuItem[]; - collapsed?: boolean; - iconName?: string; -} diff --git a/ts_web/elements/interfaces/selectionoption.ts b/ts_web/elements/interfaces/selectionoption.ts deleted file mode 100644 index 3987671..0000000 --- a/ts_web/elements/interfaces/selectionoption.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface ISelectionOption { - key: string; - iconName?: string; - action: () => void; -} \ No newline at end of file diff --git a/ts_web/elements/interfaces/tab.ts b/ts_web/elements/interfaces/tab.ts index 08c43b2..fc1fcf6 100644 --- a/ts_web/elements/interfaces/tab.ts +++ b/ts_web/elements/interfaces/tab.ts @@ -1,4 +1,4 @@ -export interface ITab { +export interface IMenuItem { key: string; iconName?: string; action: () => void;