import { customElement, DeesElement, html, css, cssManager, property, type TemplateResult, } from '@design.estate/dees-element'; import { demoFunc } from './dees-settings.demo.js'; import { cssGeistFontFamily } from '../../00fonts.js'; import { themeDefaultStyles } from '../../00theme.js'; import '../../00group-layout/dees-tile/dees-tile.js'; declare global { interface HTMLElementTagNameMap { 'dees-settings': DeesSettings; } } export interface ISettingsField { key: string; label: string; value: string | TemplateResult; } export interface ISettingsAction { name: string; action: () => void | Promise; } /** * dees-settings — a read-only settings display tile with modal-style footer actions. * * Renders a dees-tile with a heading, a grid of label/value fields, * and a footer action bar. When an action is clicked the component * dispatches a `settings-action` CustomEvent with the action name. */ @customElement('dees-settings') export class DeesSettings extends DeesElement { public static demo = demoFunc; public static demoGroups = ['Layout']; @property({ type: String }) accessor heading: string = ''; @property({ type: String }) accessor description: string = ''; @property({ attribute: false }) accessor settingsFields: ISettingsField[] = []; @property({ attribute: false }) accessor actions: ISettingsAction[] = []; public static styles = [ themeDefaultStyles, cssManager.defaultStyles, css` :host { display: block; font-family: ${cssGeistFontFamily}; } .settingsGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px 24px; padding: 16px; } .settingsField { display: flex; flex-direction: column; gap: 2px; } .fieldLabel { font-size: 11px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--dees-color-text-muted); } .fieldValue { font-size: 13px; color: var(--dees-color-text-primary); } .settingsDescription { padding: 16px; font-size: 13px; line-height: 1.5; color: var(--dees-color-text-muted); } .bottomButtons { display: flex; flex-direction: row; justify-content: flex-end; align-items: center; gap: 0; height: 36px; width: 100%; box-sizing: border-box; } .bottomButtons .bottomButton { padding: 0 16px; height: 100%; text-align: center; font-size: 12px; font-weight: 500; cursor: pointer; user-select: none; transition: all 0.15s ease; background: transparent; border: none; border-left: 1px solid var(--dees-color-border-subtle); color: var(--dees-color-text-muted); white-space: nowrap; display: flex; align-items: center; } .bottomButtons .bottomButton:first-child { border-left: none; } .bottomButtons .bottomButton:hover { background: var(--dees-color-hover); color: var(--dees-color-text-primary); } .bottomButtons .bottomButton:active { background: ${cssManager.bdTheme('hsl(0 0% 92%)', 'hsl(0 0% 13%)')}; } .bottomButtons .bottomButton.primary { color: ${cssManager.bdTheme('hsl(217.2 91.2% 59.8%)', 'hsl(213.1 93.9% 67.8%)')}; font-weight: 600; } .bottomButtons .bottomButton.primary:hover { background: ${cssManager.bdTheme('hsl(217.2 91.2% 59.8% / 0.08)', 'hsl(213.1 93.9% 67.8% / 0.08)')}; color: ${cssManager.bdTheme('hsl(217.2 91.2% 50%)', 'hsl(213.1 93.9% 75%)')}; } .bottomButtons .bottomButton.primary:active { background: ${cssManager.bdTheme('hsl(217.2 91.2% 59.8% / 0.15)', 'hsl(213.1 93.9% 67.8% / 0.15)')}; } `, ]; public render(): TemplateResult { const hasFields = this.settingsFields.length > 0; const hasActions = this.actions.length > 0; return html` ${hasFields ? html`
${this.settingsFields.map( (field) => html`
${field.label} ${field.value}
`, )}
` : html`
${this.description}
`} ${hasActions ? html`
${this.actions.map( (actionArg, index) => html`
actionArg.action()} > ${actionArg.name}
`, )}
` : ''}
`; } }