diff --git a/ts_web/elements/dees-input-multitoggle.demo.ts b/ts_web/elements/dees-input-multitoggle.demo.ts index cbfd563..f032a37 100644 --- a/ts_web/elements/dees-input-multitoggle.demo.ts +++ b/ts_web/elements/dees-input-multitoggle.demo.ts @@ -1,4 +1,4 @@ -import { html, css } from '@design.estate/dees-element'; +import { html, css, cssManager } from '@design.estate/dees-element'; export const demoFunc = () => html` @@ -7,10 +7,31 @@ export const demoFunc = () => html` .demo-container { display: flex; flex-direction: column; - gap: 24px; + gap: 32px; + padding: 48px; + background: ${cssManager.bdTheme('#f8f9fa', '#0a0a0a')}; + min-height: 100vh; + } + + .section { + background: ${cssManager.bdTheme('#ffffff', '#18181b')}; + border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; + border-radius: 8px; padding: 24px; - max-width: 1200px; - margin: 0 auto; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + } + + .section-title { + font-size: 18px; + font-weight: 600; + margin-bottom: 8px; + color: ${cssManager.bdTheme('#09090b', '#fafafa')}; + } + + .section-description { + font-size: 14px; + color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; + margin-bottom: 24px; } .settings-grid { @@ -28,7 +49,10 @@ export const demoFunc = () => html` - + + Multi-Option Toggle + Select from multiple options with a smooth sliding indicator animation. + html` .selectedOption=${'Grid View'} > + + - + - + + Boolean Toggle + Simple on/off switches with customizable labels for clearer context. + html` .selectedOption=${'true'} > + + html` .booleanFalseName=${'Light'} .selectedOption=${'Dark'} > - + - + + Settings Grid + Configuration options arranged in a responsive grid layout. + html` - + - + + States & Form Integration + Examples of disabled states and integration within forms. + html` .disabled=${true} > + + html` .selectedOption=${'MIT'} > - + `; \ No newline at end of file diff --git a/ts_web/elements/dees-input-multitoggle.ts b/ts_web/elements/dees-input-multitoggle.ts index d8c9c01..bfb6794 100644 --- a/ts_web/elements/dees-input-multitoggle.ts +++ b/ts_web/elements/dees-input-multitoggle.ts @@ -57,9 +57,12 @@ export class DeesInputMultitoggle extends DeesInputBase { } else { this.selectedOption = val as string; } + this.requestUpdate(); // Defer indicator update to next frame if component not yet updated if (this.hasUpdated) { - this.setIndicator(); + requestAnimationFrame(() => { + this.setIndicator(); + }); } } @@ -68,59 +71,71 @@ export class DeesInputMultitoggle extends DeesInputBase { cssManager.defaultStyles, css` :host { - color: ${cssManager.bdTheme('#333', '#ccc')}; + color: ${cssManager.bdTheme('#09090b', '#fafafa')}; user-select: none; } - .selections { position: relative; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - background: ${cssManager.bdTheme('#fff', '#222')}; - width: min-content; - border-radius: 20px; - height: 32px; - border-top: 1px solid ${cssManager.bdTheme('rgba(0,0,0,0.1)', 'rgba(255,255,255,0.1)')}; + display: inline-flex; + align-items: center; + background: ${cssManager.bdTheme('#ffffff', '#18181b')}; + border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; + padding: 4px; + border-radius: 8px; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); } .option { - color: ${cssManager.bdTheme('#666', '#999')}; position: relative; - padding: 0px 16px; - line-height: 32px; - cursor: default; - width: min-content; /* Make the width as per the content */ - white-space: nowrap; /* Prevent text wrapping */ - transition: all 0.1s; + padding: 8px 20px; + border-radius: 6px; + cursor: pointer; + white-space: nowrap; + transition: color 0.2s ease; font-size: 14px; - transform: translateY(-1px); + font-weight: 500; + color: ${cssManager.bdTheme('#71717a', '#71717a')}; + line-height: 1; + z-index: 2; } .option:hover { - color: ${cssManager.bdTheme('#333', '#fff')}; + color: ${cssManager.bdTheme('#18181b', '#e4e4e7')}; } .option.selected { - color: ${cssManager.bdTheme('#fff', '#fff')}; + color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')}; } .indicator { opacity: 0; position: absolute; - height: 24px; - left: 4px; - top: 3px; - border-radius: 16px; - background: ${cssManager.bdTheme(colors.bright.blueActive, colors.dark.blueActive)}; - min-width: 24px; - transition: all 0.1s ease-in-out; + height: calc(100% - 8px); + top: 4px; + border-radius: 6px; + background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.15)', 'rgba(59, 130, 246, 0.15)')}; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); + z-index: 1; } .indicator.no-transition { transition: none; } + + :host([disabled]) .selections { + opacity: 0.5; + cursor: not-allowed; + } + + :host([disabled]) .option { + cursor: not-allowed; + pointer-events: none; + } + + :host([disabled]) .indicator { + background: ${cssManager.bdTheme('rgba(113, 113, 122, 0.15)', 'rgba(113, 113, 122, 0.15)')}; + } `, ]; @@ -165,10 +180,14 @@ export class DeesInputMultitoggle extends DeesInputBase { } public async handleSelection(optionArg: string) { + if (this.disabled) return; this.selectedOption = optionArg; + this.requestUpdate(); + this.changeSubject.next(this); + await this.updateComplete; this.setIndicator(); } - + private indicatorInitialized = false; public async setIndicator() { @@ -199,8 +218,8 @@ export class DeesInputMultitoggle extends DeesInputBase { }, 50); } - indicator.style.width = `${option.clientWidth - 8}px`; - indicator.style.left = `${option.offsetLeft + 4}px`; + indicator.style.width = `${option.clientWidth}px`; + indicator.style.left = `${option.offsetLeft}px`; indicator.style.opacity = '1'; } } @@ -218,8 +237,11 @@ export class DeesInputMultitoggle extends DeesInputBase { } else { this.selectedOption = value as string; } + this.requestUpdate(); if (this.hasUpdated) { - this.setIndicator(); + requestAnimationFrame(() => { + this.setIndicator(); + }); } } }