import { ZuiBaseElement } from '@zywave/zui-base'; import { html } from 'lit'; import { property } from 'lit/decorators.js'; import type { PropertyValues, LitElement } from 'lit'; /** * Use to create a selectable option that can be used within `` or ``. * @element zui-option * * @slot - Default, unnamed slot; for inserting label text into ``; optionally, you can use the `label` attribute/property instead * * @event {CustomEvent} selectedchange - Event is dispatched when `` is selected or deselected; contains details regarding the `selected` state * @event {CustomEvent} updated - Event is dispatched when `` is updated; contains details regarding what properties changed */ export class ZuiOptionElement extends ZuiBaseElement { /** * Sets a `value` for the option */ @property({ type: String, reflect: true }) value: string | null | undefined = undefined; /** * The label users will see as a choice, in a select dropdown */ @property({ type: String }) label = ''; /** * Options `disabled` state */ @property({ type: Boolean, reflect: true }) disabled = false; /** * Whether to hide the option from the list or not */ @property({ type: Boolean }) hidden = false; /** * Determines if the `zui-option` is selected */ @property({ type: Boolean, reflect: true }) selected = false; private updateObserver: MutationObserver; connectedCallback() { super.connectedCallback(); this.updateObserver = new MutationObserver(() => { // TODO(pat): we should tell zui-select that this option was updated; we shouldn't reach out directly to zui-select (this.parentNode as LitElement).requestUpdate(); }); this.updateObserver.observe(this, { attributes: true, attributeFilter: ['disabled', 'hidden'], childList: true }); } updated(changedProperties: PropertyValues) { this.dispatchEvent(new CustomEvent('updated', { detail: changedProperties, bubbles: true })); } render() { return html`${this.label}`; } } window.customElements.define('zui-option', ZuiOptionElement); export interface IZuiOptionObject { label: string; value?: string; disabled: boolean; group?: string; selected: boolean; } export class ZuiOptionObject extends EventTarget implements IZuiOptionObject { #selected = false; label: string; value?: string; disabled: boolean; group?: string; get selected(): boolean { return this.#selected; } set selected(val: boolean) { this.#selected = val; this.dispatchEvent(new CustomEvent('selectedchange', { bubbles: true, detail: { selected: val } })); } constructor(label: string, value?: string, disabled?: boolean, group?: string | undefined, selected?: boolean) { super(); this.label = label; this.value = value || label; this.disabled = disabled ?? false; this.group = group; this.#selected = selected ?? false; } } declare global { interface HTMLElementTagNameMap { 'zui-option': ZuiOptionElement; } }