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, type TemplateResult, property, customElement, html, css, cssManager, } from '@design.estate/dees-element'; /** * the property selector menu * mainly used to select assets within in an organization */ @customElement('dees-appui-mainselector') export class DeesAppuiMainselector extends DeesElement { public static demo = () => html` 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 | { divider: true })[] = [ { key: '⚠️ Please set selection options', action: () => console.warn('No selection options configured for mainselector') }, ]; @property() public selectedOption: interfaces.ISelectionOption = null; public static styles = [ cssManager.defaultStyles, css` :host { color: ${cssManager.bdTheme('#333', '#fff')}; position: relative; display: block; width: 100%; max-width: 300px; height: 100%; background: ${cssManager.bdTheme('#fafafa', '#000000')}; border-right: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')}; } .maincontainer { position: absolute; top: 0px; left: 0px; height: 100%; width: 100%; } .topbar { position: absolute; height: 40px; width: 100%; display: flex; align-items: center; border-bottom: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')}; } .topbar .heading { padding-left: 12px; font-family: 'Geist Sans', sans-serif; font-weight: 600; font-size: 12px; color: ${cssManager.bdTheme('#666', '#999')}; text-transform: uppercase; letter-spacing: 0.5px; } .selectionOptions { position: absolute; top: 40px; left: 0px; right: 0px; bottom: 0px; overflow-y: auto; font-family: 'Geist Sans', sans-serif; font-size: 12px; padding: 4px 0; } .selectionOptions .selectionOption { cursor: default; 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 { background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.04)', 'rgba(255, 255, 255, 0.08)')}; } .selectionOptions .selectionOption:active { background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.08)', 'rgba(255, 255, 255, 0.12)')}; } .selectionOptions .selectionOption.selectedOption { 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; } `, ]; public render(): TemplateResult { return html`
Selector
${this.selectionOptions.map((selectionOptionArg) => { if ('divider' in selectionOptionArg && selectionOptionArg.divider) { return html`
`; } const option = selectionOptionArg as interfaces.ISelectionOption; return html`
${option.iconName ? html` ` : ''} ${option.key}
`; })}
`; } private selectOption(optionArg: interfaces.ISelectionOption) { this.selectedOption = optionArg; this.selectedOption.action(); // Emit option-select event this.dispatchEvent(new CustomEvent('option-select', { detail: { option: optionArg }, bubbles: true, composed: true })); } async firstUpdated(_changedProperties: Map) { await super.firstUpdated(_changedProperties); if (this.selectionOptions && this.selectionOptions.length > 0) { await this.updateComplete; // Find first non-divider option const firstOption = this.selectionOptions.find(option => !('divider' in option)) as interfaces.ISelectionOption; if (firstOption) { this.selectOption(firstOption); } } } }