import { DeesElement, html, property, customElement, css, type TemplateResult } from '@design.estate/dees-element'; import { idpElementStyles } from './tokens.js'; declare global { interface HTMLElementTagNameMap { 'idp-input': IdpInput; } } @customElement('idp-input') export class IdpInput extends DeesElement { public static demo = () => html``; public static demoGroups = ['idp.global v3 primitives']; @property({ type: String }) public accessor label = ''; @property({ type: String }) public accessor name = ''; @property({ type: String }) public accessor key = ''; @property({ type: String }) public accessor hint = ''; @property({ type: String }) public accessor value = ''; @property({ type: String }) public accessor placeholder = ''; @property({ type: String }) public accessor type = 'text'; @property({ type: String }) public accessor autocomplete = ''; @property({ type: String }) public accessor error = ''; @property({ type: Boolean, reflect: true }) public accessor required = false; @property({ type: Boolean, reflect: true }) public accessor disabled = false; public static styles = [ ...idpElementStyles, css` :host { display: block; } label { display: grid; gap: 6px; } .label { color: var(--idp-fg); font-size: 13px; font-weight: 500; } input { width: 100%; height: 36px; box-sizing: border-box; padding: 0 10px; border: 1px solid var(--idp-border); border-radius: 8px; outline: none; background: var(--idp-card); color: var(--idp-fg); font-family: var(--idp-font); font-size: 13px; transition: border-color 120ms ease, box-shadow 120ms ease; } input:focus { border-color: var(--idp-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--idp-accent), transparent 86%); } input:disabled { opacity: 0.5; } input[aria-invalid='true'] { border-color: var(--idp-destructive); box-shadow: 0 0 0 3px color-mix(in srgb, var(--idp-destructive), transparent 86%); } .hint, .error { color: var(--idp-muted-fg); font-size: 12px; line-height: 1.4; } .error { color: var(--idp-destructive); } `, ]; public focus() { this.shadowRoot?.querySelector('input')?.focus(); } public validate() { const input = this.shadowRoot?.querySelector('input'); if (this.required && !this.value.trim()) { this.error = `${this.label || this.name || 'This field'} is required.`; return false; } if (input && !input.checkValidity()) { this.error = input.validationMessage; return false; } this.error = ''; return true; } private handleInput(eventArg: Event) { this.value = (eventArg.target as HTMLInputElement).value; if (this.error) { this.validate(); } this.dispatchEvent(new CustomEvent('idp-input-change', { detail: { name: this.name || this.key, key: this.key || this.name, value: this.value }, bubbles: true, composed: true, })); } public render(): TemplateResult { return html` `; } }