From c1e8f8c2a6196edd82a090b096750d61f7874a91 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 17 Jun 2025 10:00:50 +0000 Subject: [PATCH] feat: Enhance selection options with icons and dividers for improved UI --- ts_web/elements/dees-appui-base.demo.ts | 13 +- ts_web/elements/dees-appui-base.ts | 2 +- ts_web/elements/dees-appui-mainselector.ts | 111 ++++++++++++------ ts_web/elements/dees-appui-tabs.ts | 2 +- ts_web/elements/interfaces/selectionoption.ts | 1 + 5 files changed, 84 insertions(+), 45 deletions(-) diff --git a/ts_web/elements/dees-appui-base.demo.ts b/ts_web/elements/dees-appui-base.demo.ts index 27a2210..e5b17f1 100644 --- a/ts_web/elements/dees-appui-base.demo.ts +++ b/ts_web/elements/dees-appui-base.demo.ts @@ -72,12 +72,13 @@ export const demoFunc = () => { ]; // Selector options (second sidebar) - const selectorOptions: ISelectionOption[] = [ - { key: 'Overview', action: () => console.log('Overview selected') }, - { key: 'Components', action: () => console.log('Components selected') }, - { key: 'Services', action: () => console.log('Services selected') }, - { key: 'Database', action: () => console.log('Database selected') }, - { key: 'Settings', action: () => console.log('Settings selected') }, + const selectorOptions: (ISelectionOption | { divider: true })[] = [ + { key: 'Overview', iconName: 'home', action: () => console.log('Overview selected') }, + { key: 'Components', iconName: 'package', action: () => console.log('Components selected') }, + { key: 'Services', iconName: 'server', action: () => console.log('Services selected') }, + { divider: true }, + { key: 'Database', iconName: 'database', action: () => console.log('Database selected') }, + { key: 'Settings', iconName: 'settings', action: () => console.log('Settings selected') }, ]; // Main content tabs diff --git a/ts_web/elements/dees-appui-base.ts b/ts_web/elements/dees-appui-base.ts index 7d514f0..ad3a569 100644 --- a/ts_web/elements/dees-appui-base.ts +++ b/ts_web/elements/dees-appui-base.ts @@ -65,7 +65,7 @@ export class DeesAppuiBase extends DeesElement { // Properties for mainselector @property({ type: Array }) - public mainselectorOptions: interfaces.ISelectionOption[] = []; + public mainselectorOptions: (interfaces.ISelectionOption | { divider: true })[] = []; @property({ type: Object }) public mainselectorSelectedOption?: interfaces.ISelectionOption; diff --git a/ts_web/elements/dees-appui-mainselector.ts b/ts_web/elements/dees-appui-mainselector.ts index 3d8d639..258a975 100644 --- a/ts_web/elements/dees-appui-mainselector.ts +++ b/ts_web/elements/dees-appui-mainselector.ts @@ -2,6 +2,7 @@ import * as plugins from './00plugins.js'; import * as interfaces from './interfaces/index.js'; import { DeesContextmenu } from './dees-contextmenu.js'; +import './dees-icon.js'; import { DeesElement, @@ -22,18 +23,18 @@ export class DeesAppuiMainselector extends DeesElement { public static demo = () => html` console.log('Overview') }, - { key: 'Components', action: () => console.log('Components') }, - { key: 'Services', action: () => console.log('Services') }, - { key: 'Database', action: () => console.log('Database') }, - { key: 'Settings', action: () => console.log('Settings') }, + { key: 'Overview', iconName: 'home', action: () => console.log('Overview') }, + { key: 'Components', iconName: 'package', action: () => console.log('Components') }, + { key: 'Services', iconName: 'server', action: () => console.log('Services') }, + { key: 'Database', iconName: 'database', action: () => console.log('Database') }, + { key: 'Settings', iconName: 'settings', action: () => console.log('Settings') }, ]} > `; // INSTANCE @property({ type: Array }) - public selectionOptions: interfaces.ISelectionOption[] = [ + public selectionOptions: (interfaces.ISelectionOption | { divider: true })[] = [ { key: '⚠️ Please set selection options', action: () => console.warn('No selection options configured for mainselector') }, ]; @@ -51,7 +52,7 @@ export class DeesAppuiMainselector extends DeesElement { max-width: 300px; height: 100%; background: ${cssManager.bdTheme('#fafafa', '#000000')}; - border-right: 1px solid ${cssManager.bdTheme('#e0e0e0', '#222222')}; + border-right: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')}; } .maincontainer { position: absolute; @@ -63,55 +64,79 @@ export class DeesAppuiMainselector extends DeesElement { .topbar { position: absolute; - height: 32px; + height: 40px; width: 100%; + display: flex; + align-items: center; + border-bottom: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')}; } .topbar .heading { - padding-left: 16px; - padding-top: 8px; - line-height: 24px; + padding-left: 12px; font-family: 'Geist Sans', sans-serif; font-weight: 600; - font-size: 14px; - color: ${cssManager.bdTheme('#666', '#ccc')}; + font-size: 12px; + color: ${cssManager.bdTheme('#666', '#999')}; + text-transform: uppercase; + letter-spacing: 0.5px; } .selectionOptions { position: absolute; - top: 32px; - padding-top: 8px; + top: 40px; left: 0px; - width: 100%; + right: 0px; + bottom: 0px; + overflow-y: auto; font-family: 'Geist Sans', sans-serif; - font-size: 14px; + font-size: 12px; + padding: 4px 0; } .selectionOptions .selectionOption { cursor: default; - margin-left: 16px; - margin-right: 16px; - padding-top: 8px; - padding-bottom: 8px; - border-top: 1px dotted ${cssManager.bdTheme('#e0e0e0', '#303030')}; - border-left: 0px solid rgba(0, 0, 0, 0); - transition: all 0.1s; + padding: 8px 12px; + margin: 0; + transition: background 0.1s; + display: flex; + align-items: center; + gap: 8px; + color: ${cssManager.bdTheme('#333', '#ccc')}; + user-select: none; } .selectionOptions .selectionOption:hover { - border-left: 2px solid #26a69a50; - padding-left: 8px; - background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.02)', 'rgba(255, 255, 255, 0.02)')}; + background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.04)', 'rgba(255, 255, 255, 0.08)')}; } - .selectionOptions .selectionOption:first-child { - border-top: 1px solid rgba(0, 0, 0, 0); + .selectionOptions .selectionOption:active { + background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.08)', 'rgba(255, 255, 255, 0.12)')}; } .selectionOptions .selectionOption.selectedOption { - border-left: 4px solid #26a69a; - padding-left: 10px; - background: ${cssManager.bdTheme('rgba(38, 166, 154, 0.05)', 'rgba(38, 166, 154, 0.1)')}; + background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.08)', 'rgba(255, 255, 255, 0.12)')}; + color: ${cssManager.bdTheme('#000', '#fff')}; + font-weight: 500; + } + + .selectionOptions .selectionOption.selectedOption::before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 3px; + background: ${cssManager.bdTheme('#26a69a', '#26a69a')}; + } + + .selectionOption { + position: relative; + } + + .selection-divider { + height: 1px; + background: ${cssManager.bdTheme('#e0e0e0', '#202020')}; + margin: 4px 0; } `, ]; @@ -121,17 +146,22 @@ export class DeesAppuiMainselector extends DeesElement {
-
Properties
+
Selector
${this.selectionOptions.map((selectionOptionArg) => { + if ('divider' in selectionOptionArg && selectionOptionArg.divider) { + return html`
`; + } + + const option = selectionOptionArg as interfaces.ISelectionOption; return html`
- ${selectionOptionArg.key} + ${option.iconName ? html` + + ` : ''} + ${option.key}
`; })} @@ -168,7 +201,11 @@ export class DeesAppuiMainselector extends DeesElement { await super.firstUpdated(_changedProperties); if (this.selectionOptions && this.selectionOptions.length > 0) { await this.updateComplete; - this.selectOption(this.selectionOptions[0]); + // Find first non-divider option + const firstOption = this.selectionOptions.find(option => !('divider' in option)) as interfaces.ISelectionOption; + if (firstOption) { + this.selectOption(firstOption); + } } } } diff --git a/ts_web/elements/dees-appui-tabs.ts b/ts_web/elements/dees-appui-tabs.ts index 97c92d8..4951da5 100644 --- a/ts_web/elements/dees-appui-tabs.ts +++ b/ts_web/elements/dees-appui-tabs.ts @@ -51,7 +51,7 @@ export class DeesAppuiTabs extends DeesElement { .tabs-wrapper { position: relative; background: ${cssManager.bdTheme('#f5f5f5', '#000000')}; - height: 56px; + height: 52px; } .tabsContainer { diff --git a/ts_web/elements/interfaces/selectionoption.ts b/ts_web/elements/interfaces/selectionoption.ts index 32f8c6b..3987671 100644 --- a/ts_web/elements/interfaces/selectionoption.ts +++ b/ts_web/elements/interfaces/selectionoption.ts @@ -1,4 +1,5 @@ export interface ISelectionOption { key: string; + iconName?: string; action: () => void; } \ No newline at end of file