import { customElement, type TemplateResult, state, html, property, css, cssManager, } from '@design.estate/dees-element'; import * as domtools from '@design.estate/dees-domtools'; import { DeesInputBase } from './dees-input-base.js'; import { demoFunc } from './dees-input-typelist.demo.js'; @customElement('dees-input-typelist') export class DeesInputTypelist extends DeesInputBase { public static demo = demoFunc; // INSTANCE @property({ type: Array }) public value: string[] = []; @state() private inputValue: string = ''; public static styles = [ ...DeesInputBase.baseStyles, cssManager.defaultStyles, css` :host { color: ${cssManager.bdTheme('#333', '#fff')}; } .mainbox { border-radius: 3px; background: ${cssManager.bdTheme('#fafafa', '#222222')}; overflow: hidden; border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #ffffff10')}; border-bottom: ${cssManager.bdTheme('1px solid #CCC', '1px solid #222')}; border-right: ${cssManager.bdTheme('1px solid #CCC', '1px solid #ffffff10')}; border-left: ${cssManager.bdTheme('1px solid #CCC', '1px solid #ffffff10')}; box-shadow: ${cssManager.bdTheme('0px 1px 4px rgba(0,0,0,0.3)', 'none')}; transition: all 0.2s; position: relative; } .mainbox:hover { filter: ${cssManager.bdTheme('brightness(0.98)', 'brightness(1.05)')}; } .mainbox:focus-within { outline: 2px solid ${cssManager.bdTheme('#0069f2', '#0084ff')}; outline-offset: -2px; } .tags { padding: 16px; cursor: default; } .notags { text-align: center; color: ${cssManager.bdTheme('#999', '#666')}; font-size: 13px; font-style: italic; } input { display: block; box-sizing: border-box; background: ${cssManager.bdTheme('#f5f5f5', '#181818')}; width: 100%; outline: none; border: none; color: inherit; padding: 0px 16px; overflow: hidden; line-height: 32px; height: 0px; transition: height 0.2s; border-top: 1px solid ${cssManager.bdTheme('#e0e0e0', '#333')}; } input:focus { height: 32px; background: ${cssManager.bdTheme('#fafafa', '#1a1a1a')}; } input::placeholder { color: ${cssManager.bdTheme('#999', '#666')}; } .tag { display: inline-block; background: ${cssManager.bdTheme('#e8f5e9', '#2d3a2d')}; color: ${cssManager.bdTheme('#2e7d32', '#81c784')}; padding: 4px 10px; border-radius: 4px; margin: 3px; font-size: 13px; font-weight: 500; transition: all 0.2s; border: 1px solid ${cssManager.bdTheme('#c8e6c9', '#1b5e20')}; } .tag:hover { background: ${cssManager.bdTheme('#c8e6c9', '#3d4f3d')}; transform: translateY(-1px); } .tag .remove { margin-left: 8px; cursor: pointer; opacity: 0.7; font-weight: 700; font-size: 16px; line-height: 1; transition: opacity 0.2s; } .tag .remove:hover { opacity: 1; color: ${cssManager.bdTheme('#c62828', '#ef5350')}; } /* Disabled state */ :host([disabled]) .mainbox { opacity: 0.6; cursor: not-allowed; } :host([disabled]) .tags { cursor: not-allowed; } :host([disabled]) .tag { pointer-events: none; } :host([disabled]) input { cursor: not-allowed; background: ${cssManager.bdTheme('#f0f0f0', '#1a1a1a')}; } `, ]; public render(): TemplateResult { return html`
{ this.shadowRoot.querySelector('input').focus(); }}> ${this.value.length === 0 ? html`
No tags yet
` : this.value.map( (tag) => html` ${tag} { e.stopPropagation(); this.removeTag(tag); }}>× ` )}
{ this.inputValue = (e.target as HTMLInputElement).value; }} @keydown=${(e: KeyboardEvent) => { if (e.key === 'Enter' && this.inputValue.trim()) { e.preventDefault(); this.addTag(this.inputValue.trim()); } }} .disabled=${this.disabled} />
`; } private addTag(tag: string) { if (!this.value.includes(tag)) { this.value = [...this.value, tag]; this.inputValue = ''; this.changeSubject.next(this); } } private removeTag(tag: string) { this.value = this.value.filter((t) => t !== tag); this.changeSubject.next(this); } public getValue(): string[] { return this.value; } public setValue(value: string[]): void { this.value = value; } }