import { LitElement, html, css } from 'lit'; import { customElement, property, queryAssignedNodes } from 'lit/decorators.js'; @customElement('iu-select') export class Select extends LitElement { static override styles = css` :host { display: block; } .select-group{ margin-bottom: var(--iu-spacing-4); } label { font-weight: bold; display: block; margin-bottom: var(--iu-spacing-0); } .select{ width: 100%; border-top: 1px solid var(--iu-color-grey-200); border-bottom: 1px solid var(--iu-color-grey-200); position: relative; } .select.has-value select { color: var(--iu-color-black); } select { width: 100%; height: 2.25rem; appearance: none; border: 0; background: transparent; padding: 8px 0; color: var(--iu-color-grey-300); font-size: 1rem; cursor: pointer; } .select:has(select:focus){ border-top: 1px solid var(--iu-color-black); border-bottom: 1px solid var(--iu-color-black); } select:focus { outline: 0; color: var(--iu-color-black); } svg{ width: 36px; height: 36px; position: absolute; right: 0; top: 0; pointer-events: none; } `; @property({ type: String }) selected = ''; @property({ type: String }) name: string = ''; @property({ type: String }) label?: string; @property({ type: String }) placeholder?: string; @property({ type: Array }) options: Array<{ value: string; label: string }> = []; @queryAssignedNodes() private slottedOptions?: NodeList; private handleChange(event: Event) { const target = event.target as HTMLSelectElement; this.selected = target.value; // Add class when an option is selected const selectWrapper = this.shadowRoot?.querySelector('.select'); if (selectWrapper) { selectWrapper.classList.toggle('has-value', this.selected !== ''); } this.dispatchEvent(new CustomEvent('select-change', { detail: { value: this.selected }, bubbles: true, composed: true, })); } override render() { return html` <div class="select-group"> <label for="${this.name}">${this.label}</label> <div class="select"> <select @change="${this.handleChange}"> ${this.placeholder ? html `<option selected disabled>${this.placeholder}</option>` : ''} ${this.options.map( option => html`<option value="${option.value}">${option.label}</option>` )} </select> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37 37"><path fill-rule="evenodd" clip-rule="evenodd" d="m18.502 21.319 5.66-5.241.68.733-6.34 5.87-6.34-5.87.68-.733 5.66 5.24Z" fill="#000"/></svg> </div> </div> `; } } declare global { interface HTMLElementTagNameMap { 'iu-select': Select; } }