@sky.ui/core 0.0.53 → 0.0.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/custom-elements.json +3785 -3679
- package/dist/helper/controllers/popover-controller.js +1 -1
- package/dist/helper/controllers/popover-controller.js.map +1 -1
- package/dist/helper/index.js +1 -1
- package/dist/helper/utils/index.d.ts +1 -0
- package/dist/helper/utils/index.js +1 -1
- package/dist/helper/utils/stable-array.d.ts +6 -0
- package/dist/helper/utils/stable-array.js +2 -0
- package/dist/helper/utils/stable-array.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/sky-avatar/sky-avatar.js +5 -5
- package/dist/sky-avatar/sky-avatar.js.map +1 -1
- package/dist/sky-chip/sky-chip.d.ts +8 -2
- package/dist/sky-chip/sky-chip.js +10 -10
- package/dist/sky-chip/sky-chip.js.map +1 -1
- package/dist/sky-combobox/sky-combobox.d.ts +2 -0
- package/dist/sky-combobox/sky-combobox.js +16 -16
- package/dist/sky-combobox/sky-combobox.js.map +1 -1
- package/dist/sky-flexbox/sky-flexbox.d.ts +2 -0
- package/dist/sky-flexbox/sky-flexbox.js +3 -3
- package/dist/sky-flexbox/sky-flexbox.js.map +1 -1
- package/dist/sky-form/sky-form.js +7 -7
- package/dist/sky-form/sky-form.js.map +1 -1
- package/dist/sky-image/sky-image.js +5 -5
- package/dist/sky-image/sky-image.js.map +1 -1
- package/dist/sky-input/sky-input.js +6 -6
- package/dist/sky-input/sky-input.js.map +1 -1
- package/dist/sky-list/sky-list.js +3 -3
- package/dist/sky-list/sky-list.js.map +1 -1
- package/dist/sky-listitem/sky-listitem.d.ts +1 -0
- package/dist/sky-listitem/sky-listitem.js +4 -2
- package/dist/sky-listitem/sky-listitem.js.map +1 -1
- package/dist/sky-radio/sky-radio.js +1 -1
- package/dist/sky-radio/sky-radio.js.map +1 -1
- package/dist/sky-simple-table/sky-simple-table.d.ts +7 -2
- package/dist/sky-simple-table/sky-simple-table.js +9 -9
- package/dist/sky-simple-table/sky-simple-table.js.map +1 -1
- package/dist/sky-theme-provider/sky-theme-provider.js +2 -2
- package/dist/sky-theme-provider/sky-theme-provider.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sky-combobox.js","sources":["../../src/sky-combobox/sky-combobox.ts"],"sourcesContent":["import { LitElement, html, css, nothing, PropertyValues, unsafeCSS } from \"lit\";\r\nimport { property, customElement, query, queryAll, queryAssignedElements, state } from \"lit/decorators.js\";\r\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\r\nimport { when } from \"lit/directives/when.js\";\r\nimport { repeat } from \"lit/directives/repeat.js\";\r\nimport { classMap } from \"lit/directives/class-map.js\";\r\nimport { resolveColor } from \"../helper/utils/color-resolver\";\r\nimport { cssOnFillEnhance } from \"../helper/utils/contrast-color\";\r\nimport { PopoverController } from \"../helper/controllers/popover-controller\";\r\nimport {\r\n FormControlBase,\r\n FormState,\r\n} from \"../helper/internals/form-control-base\";\r\nimport { SkyIcon } from \"../sky-icon/sky-icon.js\";\r\nimport { SkyCheckbox } from \"../sky-checkbox/sky-checkbox.js\";\r\nimport { SkyInput } from \"../sky-input/sky-input.js\";\r\nimport { PresetController } from \"../helper/controllers/preset-controller\";\r\n\r\nexport type SkyComboboxJustify =\r\n | \"flex-start\"\r\n | \"center\"\r\n | \"flex-end\"\r\n | \"space-between\"\r\n | \"space-around\"\r\n | \"space-evenly\";\r\nexport type SkyComboboxErrorDisplayMode = \"single\" | \"all\" | \"none\";\r\nexport type SkyComboboxIconPosition = \"left\" | \"right\";\r\n/** How multi-select values render in the field (single-select always uses plain text). */\r\nexport type SkyComboboxMultiDisplay = \"chips\" | \"text\" | \"count\";\r\nexport type SkyComboboxValueChangedDetail = {\r\n value: any | any[];\r\n selectedItems: any[];\r\n emittedValues?: any | any[];\r\n isFilteredSelection?: boolean;\r\n};\r\nexport type SkyComboboxSearchQueryChangedDetail = { searchQuery: string };\r\nexport type SkyComboboxValidationErrorDetail = { errors: string[] };\r\nexport type SkyComboboxValidationSuccessDetail = { value: any };\r\nexport type SkyComboboxIconClickDetail = {\r\n position: SkyComboboxIconPosition;\r\n event: MouseEvent;\r\n};\r\nexport type SkyComboboxAddNewOptionDetail = { value: string };\r\n\r\n/** Reserved key on `customRenderers` for renderer UI state (not an option renderer). */\r\nexport const COMBOBOX_RENDERERS_STATE_KEY = \"$rendererState\";\r\n\r\nexport type SkyComboboxRendererStateApi = {\r\n rendererState: Readonly<Record<string, unknown>>;\r\n patchRendererState: (patch: Record<string, unknown>) => void;\r\n};\r\n\r\nexport type SkyComboboxOptionRenderContext = SkyComboboxRendererStateApi & {\r\n /** Index within the currently filtered dropdown list. */\r\n index: number;\r\n /** Index in the original `options` array. */\r\n sourceIndex: number;\r\n /** Plain display label (no highlight markup). */\r\n label: string;\r\n /** Search-highlighted label HTML string (same as default option text). */\r\n highlightedLabel: string;\r\n selected: boolean;\r\n /** Keyboard / pointer active row. */\r\n active: boolean;\r\n multiSelect: boolean;\r\n};\r\n\r\nexport type SkyComboboxSelectedRenderContext = SkyComboboxRendererStateApi & {\r\n selectedItems: any[];\r\n /** Index within `selectedItems`. */\r\n index: number;\r\n multiSelect: boolean;\r\n multiDisplay: SkyComboboxMultiDisplay;\r\n /** Default plain label for this option. */\r\n label: string;\r\n};\r\n\r\nexport type SkyComboboxOptionRenderer = (\r\n option: unknown,\r\n ctx: SkyComboboxOptionRenderContext,\r\n) => unknown;\r\n\r\nexport type SkyComboboxSelectedRenderer = (\r\n option: unknown,\r\n ctx: SkyComboboxSelectedRenderContext,\r\n) => unknown;\r\n\r\nexport type SkyComboboxCustomRenderers = {\r\n /** Custom dropdown option row content (host keeps checkbox / selected chrome). */\r\n option?: SkyComboboxOptionRenderer;\r\n /** Custom selected-value / chip label content. */\r\n selected?: SkyComboboxSelectedRenderer;\r\n [COMBOBOX_RENDERERS_STATE_KEY]?: Record<string, unknown>;\r\n};\r\n\r\nfunction isComboboxRendererStateBag(\r\n value: unknown,\r\n): value is Record<string, unknown> {\r\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) {\r\n return false;\r\n }\r\n const o = value as Record<string, unknown>;\r\n return typeof o.option !== \"function\" && typeof o.selected !== \"function\";\r\n}\r\n\r\nfunction extractComboboxRendererState(\r\n customRenderers: SkyComboboxCustomRenderers | null | undefined,\r\n): Record<string, unknown> {\r\n const bag = customRenderers?.[COMBOBOX_RENDERERS_STATE_KEY];\r\n return isComboboxRendererStateBag(bag) ? { ...bag } : {};\r\n}\r\n\r\n/**\r\n * @element sky-combobox\r\n *\r\n * @summary Interactive combobox with single/multi select, search, chips, validation, and popover-based option selection.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/combobox\r\n * @dependency sky-icon\r\n * @dependency sky-checkbox\r\n * @dependency sky-input\r\n *\r\n * @uiVModel value value-changed\r\n * @uiVModel searchQuery search-query-changed\r\n *\r\n * @slot icon-left - Slot for the left icon in the combobox (e.g., search icon).\r\n * @slot icon-right - Slot for the right icon in the combobox (e.g., dropdown icon).\r\n * @slot - Default slot for adding custom options or content.\r\n *\r\n * @csspart combo-box-container - The main container element wrapping the entire component\r\n * @csspart input-wrapper - The input field wrapper that contains chips, icons, and dropdown button\r\n * @csspart icon-slot - Both left and right icon containers\r\n * @csspart placeholder-label - The placeholder text label\r\n * @csspart clear-button - The clear (×) button\r\n * @csspart field-trailing - Trailing actions rail (clear, right icon, chevron)\r\n * @csspart dropdown-button - The dropdown toggle arrow button\r\n * @csspart chip-container - Container for the chips in multi-select mode\r\n * @csspart value-summary - Multi-select text/count summary (when `multi-display` is `text` or `count`)\r\n * @csspart chip - Individual chip element\r\n * @csspart single-select-chip - Chip shown in single-select mode\r\n * @csspart overflow-chip - The \"+N\" chip that shows hidden chips count\r\n * @csspart remove-chip-icon - The remove icon within chips\r\n * @csspart hidden-chips-dropdown - Dropdown that appears when clicking overflow chip\r\n * @csspart hidden-chip-inner - Individual chip in the hidden chips dropdown\r\n * @csspart hidden-chip-label - Label text in hidden chips dropdown\r\n * @csspart dropdown - The main dropdown container\r\n * @csspart search-container - Container for the search input in the dropdown\r\n * @csspart search-input - The search input field\r\n * @csspart add-option-icon - The \"+\" icon for adding new options\r\n * @csspart select-all - The \"Select All\" row in the dropdown\r\n * @csspart checkbox - Checkbox elements in multi-select mode\r\n * @csspart option - Individual option row in the dropdown\r\n * @csspart highlighted-text - Highlighted text in search results\r\n * @csspart no-options - \"No options found\" message\r\n * @csspart error-list - Container for validation error messages\r\n * @csspart error-item - Individual validation error message\r\n * @csspart dropdown-scroller - Scrollable container for dropdown options\r\n * @csspart chip-label - Label text within chips\r\n *\r\n * @fires {CustomEvent<SkyComboboxValueChangedDetail>} value-changed - Fired whenever selection changes.\r\n * @fires {CustomEvent<SkyComboboxSearchQueryChangedDetail>} search-query-changed - Fired when search query changes.\r\n * @fires {CustomEvent<SkyComboboxValidationErrorDetail>} validation-error - Fired when validation fails.\r\n * @fires {CustomEvent<SkyComboboxValidationSuccessDetail>} validation-success - Fired when validation passes.\r\n * @fires {CustomEvent<SkyComboboxIconClickDetail>} icon-click - Fired when icon slot is clicked.\r\n * @fires {CustomEvent<SkyComboboxAddNewOptionDetail>} add-new-option - Fired when user confirms adding a new option.\r\n *\r\n * @property {any} value - Current selection value (single) or value array (multi).\r\n * @property {string} placeholder - Main placeholder text.\r\n * @property {string} searchPlaceholder - Search input placeholder text.\r\n * @property {string} searchQuery - Current search filter text when `searchable` is enabled. Default: `\"\"`.\r\n * @property {any[]} options - Available options list.\r\n * @property {boolean} searchable - Enables search input and filtering.\r\n * @property {boolean} addOption - Enables ad-hoc option creation from search query.\r\n * @property {boolean} multiSelect - Enables multi-select chip behavior.\r\n * @property {boolean} selectAll - Shows select-all row in eligible modes.\r\n * @property {boolean} clearable - Shows clear button when value exists.\r\n * @property {boolean} loading - Shows loading affordance.\r\n * @property {boolean} compact - Enables compact sizing.\r\n * @property {boolean} disabled - Disables interaction.\r\n * @property {boolean} required - Enables required validation.\r\n * @property {boolean} readonly - Enables read-only mode.\r\n * @property {boolean} emitFullObject - Emits full option objects in events.\r\n * @property {string} emittedKey - Key emitted from object options when `emitFullObject` is false.\r\n * @property {string} displayKey - Key used for visual labels in object options.\r\n * @property {SkyComboboxCustomRenderers} customRenderers - Named renderers: `option` (dropdown row), `selected` (value/chip label), optional `$rendererState`.\r\n * @property {number} visibleChips - Number of visible chips before `+N` overflow chip.\r\n * @property {number} chipSize - Maximum label length for each chip.\r\n * @property {string} color - Accent color token/CSS color.\r\n * @property {number} zIndex - Dropdown overlay z-index.\r\n * @property {string} height - Max dropdown scroll height.\r\n * @property {boolean} openAbove - Opens dropdown above when true.\r\n * @property {SkyComboboxJustify} justify - Option-row content justification.\r\n * @property {boolean} showErrors - Renders validation errors below control.\r\n * @property {SkyComboboxErrorDisplayMode} errorDisplayMode - Validation error rendering strategy.\r\n * @property {(value:any)=>true|string} validations - External validator callbacks.\r\n * @property {boolean} validationArrayFormat - Sends selected array into validators when true.\r\n * @property {string} prefix - Optional inline prefix text.\r\n * @property {string} suffix - Optional inline suffix text.\r\n * @property {string} prefixColor - Prefix color value.\r\n * @property {string} suffixColor - Suffix color value.\r\n * @property {string} requiredMessage - Required validation failure text.\r\n * @property {boolean} enforceMinOneSelection - Prevents clearing all selections in multi-select mode.\r\n * @property {boolean} validationActive - Enables validation UI state.\r\n * @property {boolean} invalid - Reflects invalid state.\r\n * @property {string} variant - Visual style: `default`, `highlight`, `fieldset`, or `inside`.\r\n * @property {string} label - Label text. Above the field by default; on the border for `fieldset`; inside the field for `inside`.\r\n * @property {SkyComboboxMultiDisplay} multiDisplay - Multi-select value UI: `chips` (default), `text` (comma-joined), or `count` (“N selected”).\r\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\r\n *\r\n * @method openDropdown Opens the combobox dropdown.\r\n * @method closeDropdown Closes the combobox dropdown.\r\n * @method clearSelection Clears current selection if allowed.\r\n * @method reset Resets combobox state and clears validation UI.\r\n * @method patchRendererState Merges keys into `customRenderers.$rendererState` and re-renders.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-combobox label=\"Assignee\" searchable clearable placeholder=\"Select user\"></sky-combobox>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-combobox label=\"Assignee\" searchable clearable placeholder=\"Select user\"></sky-combobox>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return <sky-combobox label=\"Assignee\" searchable clearable placeholder=\"Select user\"></sky-combobox>;\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-combobox\")\r\nexport class SkyCombobox extends FormControlBase {\r\n\r\n static dependencies: Record<string, CustomElementConstructor> = {\r\n \"sky-icon\": SkyIcon,\r\n \"sky-checkbox\": SkyCheckbox,\r\n \"sky-input\": SkyInput,\r\n };\r\n\r\n /** Current value. Set via attribute in HTML (e.g. value=\"option-1\") or via JS (string or array when multiSelect). Not reflected when set to array from JS. */\r\n @property() value: any = \"\";\r\n @property({ type: String }) placeholder: string = \"Select An Option\";\r\n @property({ type: String }) searchPlaceholder: string = \"Search...\";\r\n @property({ type: String }) label: string = \"\";\r\n private _options: any[] = [];\r\n @property({ type: Array })\r\n get options(): any[] {\r\n return this._options;\r\n }\r\n set options(value: any[] | null | undefined) {\r\n const old = this._options;\r\n this._options = Array.isArray(value) ? value : [];\r\n this.requestUpdate(\"options\", old);\r\n }\r\n @property({ type: Number }) chipSize: number = 20;\r\n @property({ type: String }) color: string = \"primary\";\r\n @property({ type: Boolean, reflect: true }) clearable: boolean = false;\r\n @property({ type: Boolean, reflect: true }) loading: boolean = false;\r\n @property({ type: Boolean, reflect: true }) compact: boolean = false;\r\n @property({ type: Boolean, reflect: true }) override disabled: boolean = false;\r\n @property({ type: Boolean, reflect: true }) searchable: boolean = false;\r\n @property({ type: Boolean, reflect: true }) multiSelect: boolean = false;\r\n @property({ type: Number, reflect: true }) visibleChips: number = 2;\r\n @property({ type: Boolean, reflect: true }) selectAll: boolean = false;\r\n private _validations: ((value: any) => true | string)[] = [];\r\n @property({ type: Array })\r\n get validations(): ((value: any) => true | string)[] {\r\n return this._validations;\r\n }\r\n set validations(value: ((value: any) => true | string)[] | null | undefined) {\r\n const old = this._validations;\r\n this._validations = Array.isArray(value) ? value : [];\r\n this.requestUpdate(\"validations\", old);\r\n }\r\n @property({ type: Boolean }) showErrors: boolean = false;\r\n @property({ type: String }) errorDisplayMode: SkyComboboxErrorDisplayMode = \"single\";\r\n @property({ type: Boolean, reflect: true }) override required: boolean = false;\r\n @property({ type: Boolean, reflect: true }) emitFullObject: boolean = false;\r\n @property({ type: String }) emittedKey: string = \"value\";\r\n @property({ type: String }) displayKey: string = \"\";\r\n private _customRenderers: SkyComboboxCustomRenderers = {};\r\n /**\r\n * Named custom renderers for option rows and selected-value labels.\r\n * Coerces null/undefined to `{}` for safe framework binding.\r\n */\r\n @property({ type: Object })\r\n get customRenderers(): SkyComboboxCustomRenderers {\r\n return this._customRenderers;\r\n }\r\n set customRenderers(value: SkyComboboxCustomRenderers | null | undefined) {\r\n const old = this._customRenderers;\r\n this._customRenderers =\r\n value != null && typeof value === \"object\" && !Array.isArray(value)\r\n ? value\r\n : {};\r\n this.requestUpdate(\"customRenderers\", old);\r\n }\r\n @property({ type: Boolean }) addOption: boolean = false;\r\n @property({ type: Boolean }) validationArrayFormat: boolean = false;\r\n @property({ type: String }) override prefix: string = \"\";\r\n @property({ type: String }) suffix: string = \"\";\r\n @property({ type: String }) prefixColor: string = \"\";\r\n @property({ type: String }) suffixColor: string = \"\";\r\n @property({ type: String }) justify: SkyComboboxJustify = \"flex-start\";\r\n @property({ type: Number }) zIndex: number = 11;\r\n @property({ type: String }) height: string = \"200px\";\r\n @property({ type: String }) override requiredMessage: string = \"Selection is required.\";\r\n @property({ type: Boolean, reflect: true }) override readonly: boolean = false;\r\n @property({ type: Boolean }) enforceMinOneSelection: boolean = false;\r\n @property({ type: Boolean }) openAbove: boolean = false;\r\n @property({ type: Boolean, reflect: true }) validationActive: boolean = false;\r\n @property({ type: Boolean, reflect: true }) invalid = false;\r\n @property({ type: String, reflect: true }) variant:\r\n | \"default\"\r\n | \"highlight\"\r\n | \"fieldset\"\r\n | \"inside\" = \"default\";\r\n /** Multi-select field presentation. Ignored for single-select. */\r\n @property({ type: String, reflect: true, attribute: \"multi-display\" })\r\n multiDisplay: SkyComboboxMultiDisplay = \"chips\";\r\n\r\n /** Current search filter when `searchable`; exposed for controlled search / `v-model:search-query`. */\r\n @property({ type: String, attribute: false }) searchQuery = \"\";\r\n @state() filteredOptions: any[] = [];\r\n @state() focused: boolean = false;\r\n @state() open: boolean = false;\r\n @state() selectedItems: any[] = [];\r\n @state() hiddenChipsOpen: boolean = false;\r\n @state() activeIndex: number = -1;\r\n @state() validationErrors: string[] = [];\r\n @state() validationStatus: any[] = [];\r\n @state() private hasLeftIcon = false;\r\n @state() private hasRightIcon = false;\r\n @state() private optionSlotSet = new Set<string>();\r\n private _rendererRuntimeState: Record<string, unknown> = {};\r\n\r\n @query(\".input-wrapper\") private inputWrapperEl!: HTMLElement;\r\n @query(\".dropdown\") private dropdownEl!: HTMLElement;\r\n @query(\".hidden-chips-dropdown\") private hiddenDropdownEl!: HTMLElement;\r\n @query(\".search-container sky-input\") private searchInputEl!: SkyInput;\r\n @query(\".overflow-chip\") private overflowChipEl!: HTMLElement;\r\n @query(\".combo-box-container\") private comboContainerEl!: HTMLElement;\r\n @queryAll(\"[data-row-index]\") private rowEls!: NodeListOf<HTMLElement>;\r\n @queryAssignedElements({ slot: \"icon-left\" }) private iconLeftEls!: HTMLElement[];\r\n @queryAssignedElements({ slot: \"icon-right\" }) private iconRightEls!: HTMLElement[];\r\n\r\n private _searchDebounceId: ReturnType<typeof setTimeout> | null = null;\r\n private _closeResetId: ReturnType<typeof setTimeout> | null = null;\r\n private static readonly _SEARCH_DEBOUNCE_MS = 150;\r\n private static readonly _SEARCH_DEBOUNCE_OPTIONS_THRESHOLD = 30;\r\n /** Matches PopoverController exit animation so list stays visible while closing. */\r\n private static readonly _CLOSE_RESET_MS = 250;\r\n\r\n private dropdownPopover = new PopoverController(this, {\r\n getAnchor: () => this.inputWrapperEl,\r\n getPopover: () => this.dropdownEl,\r\n cssVarLeft: \"--sky-dd-left\",\r\n cssVarTop: \"--sky-dd-top\",\r\n cssVarWidth: \"--sky-dd-width\",\r\n getPlacement: () => 'bottom' as any,\r\n getAlign: () => \"start\" as any,\r\n getGap: () => 6,\r\n getPadding: () => 8,\r\n getMatchAnchorWidth: () => true,\r\n getMaxWidthToViewport: () => true,\r\n getMaxWidthMode: () => \"cap\" as any,\r\n getFlip: () => true,\r\n getFlipOrder: () => [],\r\n getAnimateReposition: () => true,\r\n getRepositionMs: () => 160,\r\n getCloseOnEscape: () => true,\r\n getCloseOnOutside: () => true,\r\n getRestoreFocusOnClose: () => true,\r\n onOpenChange: (open, meta) => {\r\n this.open = open;\r\n\r\n if (open) {\r\n this.focused = true;\r\n if (this._closeResetId != null) {\r\n clearTimeout(this._closeResetId);\r\n this._closeResetId = null;\r\n }\r\n this.validationActive = true;\r\n this.filterOptions();\r\n requestAnimationFrame(() => this.focusOnOpen());\r\n } else {\r\n this.activeIndex = -1;\r\n // Defer search reset so options stay populated during the close animation.\r\n if (this._closeResetId != null) clearTimeout(this._closeResetId);\r\n this._closeResetId = setTimeout(() => {\r\n this._closeResetId = null;\r\n if (this.open) return;\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.filterOptions();\r\n }, SkyCombobox._CLOSE_RESET_MS);\r\n\r\n // close hidden chips too\r\n this.hiddenChipsOpen = false;\r\n this.hiddenPopover.closePopover(\"api\");\r\n }\r\n },\r\n });\r\n\r\n private hiddenPopover = new PopoverController(this, {\r\n getAnchor: () => this.overflowChipEl,\r\n getPopover: () => this.hiddenDropdownEl,\r\n cssVarLeft: \"--sky-hc-left\",\r\n cssVarTop: \"--sky-hc-top\",\r\n cssVarWidth: \"--sky-hc-width\",\r\n getPlacement: () => \"bottom\" as any,\r\n getAlign: () => \"center\" as any,\r\n getGap: () => 4,\r\n getPadding: () => 8,\r\n getMatchAnchorWidth: () => false,\r\n getMaxWidthToViewport: () => true,\r\n getMaxWidthMode: () => \"cap\" as any,\r\n getFlip: () => true,\r\n getFlipOrder: () => [],\r\n getAnimateReposition: () => true,\r\n getRepositionMs: () => 120,\r\n getCloseOnEscape: () => true,\r\n getCloseOnOutside: () => true,\r\n getRestoreFocusOnClose: () => false,\r\n onOpenChange: (open) => {\r\n this.hiddenChipsOpen = open;\r\n\r\n // if opening hidden chips, close main dropdown\r\n if (open && this.open) {\r\n this.dropdownPopover.closePopover(\"api\");\r\n }\r\n },\r\n });\r\n\r\n\r\n /** Named prop preset from nearest `sky-config-provider`. */\r\n @property({ type: String, reflect: true }) preset = \"\";\r\n\r\n private _presets = new PresetController(this);\r\n\r\n static override styles = css`\r\n :host {\r\n display: block;\r\n font-family: var(--sky-font);\r\n width: 100%;\r\n --sky-input-height: 36px;\r\n --sky-input-height-compact: 28px;\r\n --sky-input-border-width: 1px;\r\n --sky-input-pad-x: var(--sky-space-3, 12px);\r\n --sky-input-pad-x-sm: var(--sky-space-1, 4px);\r\n --sky-input-pad-x-xs: 0px;\r\n --sky-input-pad-y: var(--sky-space-1, 4px);\r\n --sky-input-pad-y-sm: 0px;\r\n --sky-input-gap: var(--sky-space-1, 4px);\r\n --sky-input-icon-width: 2rem;\r\n }\r\n\r\n :host([compact]) {\r\n --sky-input-pad-x: var(--sky-space-2, 8px);\r\n --sky-input-pad-x-sm: var(--sky-space-1, 4px);\r\n --sky-input-icon-width: 1.75rem;\r\n }\r\n\r\n :host([compact]) .combo-box-container > .label {\r\n font-size: var(--sky-font-size-xs);\r\n margin-bottom: var(--sky-space-1, 4px);\r\n line-height: 1.2;\r\n }\r\n\r\n :host([compact]) .placeholder-label,\r\n :host([compact]) .chip[single-select] {\r\n font-size: var(--sky-font-size-sm);\r\n }\r\n\r\n :host([compact]) .icon-slot {\r\n font-size: var(--sky-font-size-lg);\r\n }\r\n\r\n :host([compact]) .clear-button,\r\n :host([compact]) .dropdown-button {\r\n font-size: var(--sky-font-size-md);\r\n }\r\n\r\n :host([disabled]) {\r\n pointer-events: none;\r\n opacity: var(--sky-opacity-disabled, 0.6);\r\n }\r\n\r\n :host([readonly]) .input-wrapper {\r\n cursor: default;\r\n }\r\n\r\n :host([variant=\"highlight\"]) .label {\r\n color: var(--sky-dropdown-color);\r\n }\r\n\r\n /* Fieldset / legend */\r\n :host([variant=\"fieldset\"]) {\r\n overflow: visible;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .combo-box-container {\r\n overflow: visible;\r\n /* Room for legend text sitting on the top border — keep off :host */\r\n padding-block-start: 0.65em;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) fieldset.input-wrapper {\r\n display: block;\r\n height: auto;\r\n margin: 0;\r\n min-inline-size: 0;\r\n min-width: 0;\r\n padding: 0;\r\n overflow: visible;\r\n background: var(--sky-glass-solid);\r\n box-shadow: none;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) fieldset.input-wrapper[compact] {\r\n height: auto;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .input-fieldset-body {\r\n display: flex;\r\n width: 100%;\r\n align-items: center;\r\n box-sizing: border-box;\r\n height: calc(\r\n var(--sky-input-height) - 2 * var(--sky-input-border-width)\r\n );\r\n min-height: calc(\r\n var(--sky-input-height) - 2 * var(--sky-input-border-width)\r\n );\r\n background: transparent;\r\n border-radius: inherit;\r\n flex-wrap: nowrap;\r\n min-width: 0;\r\n overflow: hidden;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) fieldset.input-wrapper[compact] .input-fieldset-body {\r\n height: calc(\r\n var(--sky-input-height-compact) - 2 * var(--sky-input-border-width)\r\n );\r\n min-height: calc(\r\n var(--sky-input-height-compact) - 2 * var(--sky-input-border-width)\r\n );\r\n }\r\n\r\n /* Multi chips: keep fieldset at input height; center chips in the body */\r\n :host([variant=\"fieldset\"]) .input-fieldset-body:has(.chip:not([single-select])) {\r\n height: calc(\r\n var(--sky-input-height) - 2 * var(--sky-input-border-width)\r\n );\r\n min-height: calc(\r\n var(--sky-input-height) - 2 * var(--sky-input-border-width)\r\n );\r\n align-items: center;\r\n padding-block: 0;\r\n }\r\n\r\n :host([variant=\"fieldset\"][compact])\r\n .input-fieldset-body:has(.chip:not([single-select])) {\r\n height: calc(\r\n var(--sky-input-height-compact) - 2 * var(--sky-input-border-width)\r\n );\r\n min-height: calc(\r\n var(--sky-input-height-compact) - 2 * var(--sky-input-border-width)\r\n );\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .input-fieldset-body:has(.chip:not([single-select])) .field-main,\r\n :host([variant=\"fieldset\"]) .input-fieldset-body:has(.chip:not([single-select])) .chip-container {\r\n align-self: stretch;\r\n height: 100%;\r\n min-height: 0;\r\n align-items: center;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) legend.label {\r\n float: unset;\r\n width: auto;\r\n max-width: calc(100% - 2 * var(--sky-input-pad-x));\r\n margin-inline-start: var(--sky-input-pad-x);\r\n margin-block: 0;\r\n padding-inline: var(--sky-input-pad-x-sm);\r\n padding-block: 0;\r\n border: none;\r\n background: transparent;\r\n background-color: transparent;\r\n color: var(--sky-text-secondary);\r\n font-size: var(--sky-font-size-xs);\r\n /* Take no in-flow space; inner text is centered on the border notch */\r\n height: 0;\r\n line-height: 0;\r\n overflow: visible;\r\n white-space: nowrap;\r\n pointer-events: none;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) legend.label .legend-text {\r\n display: inline-block;\r\n max-width: 100%;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n line-height: 1.2;\r\n transform: translateY(-50%);\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .combo-box-container:focus-within legend.label,\r\n :host([variant=\"fieldset\"]) .input-wrapper[open] legend.label {\r\n color: var(--sky-dropdown-color);\r\n font-size: var(--sky-font-size-xs);\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .input-wrapper::after {\r\n content: none;\r\n display: none;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .input-wrapper[open],\r\n :host([variant=\"fieldset\"]) .input-wrapper:focus-visible {\r\n border-color: var(--sky-dropdown-color);\r\n }\r\n\r\n :host([variant=\"fieldset\"][validationActive]:invalid) .input-wrapper {\r\n border-color: var(--sky-danger-primary);\r\n }\r\n\r\n :host([variant=\"fieldset\"][validationActive]:invalid) legend.label {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n :host([variant=\"fieldset\"][compact]) legend.label,\r\n :host([variant=\"fieldset\"][compact]) .combo-box-container:focus-within legend.label,\r\n :host([variant=\"fieldset\"][compact]) .input-wrapper[open] legend.label {\r\n font-size: var(--sky-font-size-xs);\r\n }\r\n\r\n /* Inside: label in the wrapper above value row — keep tokens in sync with sky-input */\r\n :host([variant=\"inside\"]) {\r\n --sky-input-height-inside: 40px;\r\n --sky-input-height-inside-compact: 36px;\r\n --sky-input-inside-label-block: 2px;\r\n --sky-input-inside-value-min: 1.15em;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-wrapper {\r\n height: auto;\r\n min-height: var(--sky-input-height-inside);\r\n align-items: center;\r\n padding-block: var(--sky-input-pad-y-sm, 0px);\r\n overflow: hidden;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-wrapper[compact] {\r\n height: auto;\r\n min-height: var(--sky-input-height-inside-compact);\r\n padding-block: var(--sky-input-pad-y-sm, 0px);\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-inside-main {\r\n flex: 1 1 0%;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n gap: 0;\r\n padding-block: var(--sky-input-inside-label-block);\r\n padding-inline: 0;\r\n overflow: hidden;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-inside-main > .label {\r\n margin: 0;\r\n padding-inline: var(--sky-input-pad-x);\r\n font-size: var(--sky-font-size-xs);\r\n line-height: 1.15;\r\n min-height: 0;\r\n color: var(--sky-text-secondary);\r\n pointer-events: none;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n flex: 0 0 auto;\r\n }\r\n\r\n :host([variant=\"inside\"][compact]) .input-inside-main > .label {\r\n font-size: 0.6875rem;\r\n line-height: 1.15;\r\n min-height: 0;\r\n }\r\n\r\n :host([variant=\"inside\"]) .combo-box-container:focus-within .input-inside-main > .label,\r\n :host([variant=\"inside\"]) .input-wrapper[open] .input-inside-main > .label {\r\n color: var(--sky-dropdown-color);\r\n font-size: var(--sky-font-size-xs);\r\n }\r\n\r\n :host([variant=\"inside\"][compact]) .combo-box-container:focus-within .input-inside-main > .label,\r\n :host([variant=\"inside\"][compact]) .input-wrapper[open] .input-inside-main > .label {\r\n font-size: 0.6875rem;\r\n }\r\n\r\n :host([variant=\"inside\"][validationActive]:invalid) .input-inside-main > .label {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-inside-row {\r\n display: flex;\r\n align-items: center;\r\n min-width: 0;\r\n width: 100%;\r\n min-height: var(--sky-input-inside-value-min);\r\n gap: 0;\r\n overflow: hidden;\r\n flex: 0 0 auto;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-inside-main:has(.chip:not([single-select])) {\r\n justify-content: center;\r\n align-self: center;\r\n padding-block: 0;\r\n gap: 2px;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-inside-row:has(.chip:not([single-select])) {\r\n min-height: 0;\r\n height: auto;\r\n align-items: center;\r\n }\r\n\r\n :host([variant=\"inside\"]) .field-main:has(.chip:not([single-select])) {\r\n align-self: center;\r\n height: auto;\r\n min-height: 0;\r\n }\r\n\r\n /* Match sky-input: label + value share pad-x; zero start when left icon present */\r\n :host([variant=\"inside\"]) .input-inside-main > .label,\r\n :host([variant=\"inside\"]) .chip-container,\r\n :host([variant=\"inside\"]) .value-summary,\r\n :host([variant=\"inside\"]) .placeholder-label {\r\n padding-inline-start: var(--sky-input-pad-x);\r\n padding-inline-end: var(--sky-input-pad-x);\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-wrapper:has(.icon-slot[filled].left) .input-inside-main > .label,\r\n :host([variant=\"inside\"]) .input-wrapper:has(.icon-slot[filled].left) .chip-container,\r\n :host([variant=\"inside\"]) .input-wrapper:has(.icon-slot[filled].left) .value-summary,\r\n :host([variant=\"inside\"]) .input-wrapper:has(.icon-slot[filled].left) .placeholder-label {\r\n padding-inline-start: 0;\r\n }\r\n\r\n /* Left icon / trailing chrome centered to label+value column (like sky-input) */\r\n :host([variant=\"inside\"]) .icon-slot,\r\n :host([variant=\"inside\"]) .icon-slot[filled] {\r\n align-self: center;\r\n height: auto;\r\n max-height: none;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n :host([variant=\"inside\"]) .field-trailing {\r\n align-self: center;\r\n padding-inline-start: 0;\r\n }\r\n\r\n /* Outside labels — keep accent while dropdown is open (focus may leave into popover) */\r\n .combo-box-container:focus-within > .label,\r\n .combo-box-container:has(.input-wrapper[open]) > .label {\r\n color: var(--sky-dropdown-color);\r\n transition: color 0.3s ease;\r\n }\r\n\r\n :host([compact]) .combo-box-container:focus-within > .label,\r\n :host([compact]) .combo-box-container:has(.input-wrapper[open]) > .label {\r\n font-size: var(--sky-font-size-xs);\r\n }\r\n\r\n .label {\r\n font-size: var(--sky-font-size-sm);\r\n margin-bottom: var(--sky-space-1, 4px);\r\n text-align: start;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n font-family: var(--sky-font);\r\n line-height: 1.35;\r\n }\r\n\r\n .combo-box-container {\r\n position: relative;\r\n display: flex;\r\n flex-direction: column;\r\n max-width: 100%;\r\n overflow: visible;\r\n width: 100%;\r\n }\r\n\r\n .combo-box-container.shake {\r\n animation: shake 0.3s ease-in-out;\r\n animation-iteration-count: 1;\r\n }\r\n\r\n @keyframes shake {\r\n 0% {\r\n transform: translateX(0);\r\n }\r\n 25% {\r\n transform: translateX(-3px);\r\n }\r\n 50% {\r\n transform: translateX(3px);\r\n }\r\n 75% {\r\n transform: translateX(-3px);\r\n }\r\n 100% {\r\n transform: translateX(0);\r\n }\r\n }\r\n\r\n .search-container {\r\n display: flex;\r\n align-items: center;\r\n padding: 8px 10px;\r\n gap: var(--sky-input-gap, 4px);\r\n border-bottom: 1px solid var(--sky-border-light);\r\n margin-bottom: 5px;\r\n }\r\n\r\n .search-container .dropdown-search-input {\r\n flex: 1 1 auto;\r\n min-width: 0;\r\n width: 100%;\r\n }\r\n\r\n .new-option-btn {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 22px;\r\n height: 22px;\r\n border-radius: var(--sky-radius-primary);\r\n margin-left: 6px;\r\n cursor: pointer;\r\n background: var(--sky-hover-primary);\r\n border: var(--sky-border-primary);\r\n color: var(--sky-dropdown-color);\r\n flex-shrink: 0;\r\n transition: color 0.15s ease;\r\n }\r\n .new-option-btn:hover {\r\n color: var(--sky-active-primary);\r\n }\r\n .new-option-btn[disabled] {\r\n opacity: 0.6;\r\n pointer-events: none;\r\n }\r\n\r\n .input-wrapper {\r\n display: flex;\r\n align-items: center;\r\n background: var(--sky-glass-solid);\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n box-sizing: border-box;\r\n border-radius: var(--sky-radius-secondary);\r\n height: var(--sky-input-height);\r\n min-height: var(--sky-input-height);\r\n width: 100%;\r\n flex-wrap: nowrap;\r\n position: relative;\r\n overflow: hidden;\r\n border: var(--sky-border-primary);\r\n box-shadow: var(--sky-box-shadow-primary);\r\n transition:\r\n border-color var(--sky-transition-normal, 200ms ease),\r\n box-shadow var(--sky-transition-normal, 200ms ease);\r\n flex: 1 1 auto;\r\n min-width: 0;\r\n }\r\n\r\n .input-wrapper:focus-visible {\r\n border-bottom: 1px solid var(--sky-dropdown-color);\r\n outline: none;\r\n }\r\n\r\n .input-wrapper::after {\r\n content: \"\";\r\n position: absolute;\r\n top: -1px;\r\n left: -1px;\r\n right: -1px;\r\n bottom: -1px;\r\n border-radius: inherit;\r\n border: 1px solid transparent;\r\n border-bottom-color: transparent;\r\n opacity: 0;\r\n transition:\r\n opacity 0.3s ease,\r\n border-color 0.3s ease;\r\n pointer-events: none;\r\n }\r\n\r\n .input-wrapper[open]::after {\r\n opacity: 1;\r\n border-bottom-color: var(--sky-dropdown-color);\r\n }\r\n\r\n :host([validationActive]:invalid) .input-wrapper::after {\r\n opacity: 1;\r\n border-bottom-color: var(--sky-danger-primary);\r\n }\r\n\r\n :host([validationActive]:invalid) .label {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n :host([validationActive]:invalid) .icon-slot {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n .placeholder-label.active[compact] {\r\n top: 10px;\r\n background-color: var(--sky-dropdown-color);\r\n color: var(--sky-on-color-fallback-light, var(--sky-text-white));\r\n font-size: var(--sky-font-size-xs);\r\n padding: 0 5px;\r\n border-radius: 4px;\r\n }\r\n\r\n .input-wrapper[compact] {\r\n height: var(--sky-input-height-compact);\r\n min-height: var(--sky-input-height-compact);\r\n border-radius: var(--sky-radius-primary);\r\n }\r\n\r\n /* Multi chips stay single-line; do not grow taller than sky-input.\r\n Exempt inside variant — it needs two rows (label + value). */\r\n .input-wrapper:has(.chip:not([single-select])) {\r\n height: var(--sky-input-height);\r\n min-height: var(--sky-input-height);\r\n padding-block: 0;\r\n }\r\n\r\n .input-wrapper[compact]:has(.chip:not([single-select])) {\r\n height: var(--sky-input-height-compact);\r\n min-height: var(--sky-input-height-compact);\r\n padding-block: 0;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-wrapper,\r\n :host([variant=\"inside\"]) .input-wrapper:has(.chip),\r\n :host([variant=\"inside\"]) .input-wrapper[compact]:has(.chip) {\r\n height: auto;\r\n min-height: var(--sky-input-height-inside);\r\n padding-block: var(--sky-input-pad-y-sm, 0px);\r\n align-items: center;\r\n }\r\n\r\n :host([variant=\"inside\"][compact]) .input-wrapper,\r\n :host([variant=\"inside\"][compact]) .input-wrapper:has(.chip) {\r\n min-height: var(--sky-input-height-inside-compact);\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-wrapper:has(.chip:not([single-select])) {\r\n padding-block: 4px;\r\n }\r\n\r\n :host([variant=\"inside\"][compact]) .input-wrapper:has(.chip:not([single-select])) {\r\n padding-block: 2px;\r\n }\r\n\r\n :host([compact]) .placeholder-label {\r\n font-size: var(--sky-font-size-sm);\r\n }\r\n\r\n sky-icon {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 1em;\r\n height: 1em;\r\n flex-shrink: 0;\r\n }\r\n\r\n /* Value column: takes remaining width; never paints under trailing actions */\r\n .field-main {\r\n flex: 1 1 0%;\r\n min-width: 0;\r\n max-width: 100%;\r\n overflow: hidden;\r\n display: flex;\r\n align-items: center;\r\n align-self: stretch;\r\n position: relative;\r\n z-index: 0;\r\n }\r\n\r\n .chip-container {\r\n display: flex;\r\n gap: var(--sky-input-gap);\r\n flex: 1 1 0%;\r\n width: 100%;\r\n min-width: 0;\r\n max-width: 100%;\r\n min-height: 0;\r\n height: 100%;\r\n flex-wrap: nowrap;\r\n align-items: center;\r\n align-self: stretch;\r\n overflow: hidden;\r\n box-sizing: border-box;\r\n margin: 0;\r\n line-height: 1;\r\n padding-block: 4px;\r\n padding-inline: var(--sky-input-pad-x) var(--sky-input-pad-x-sm);\r\n }\r\n\r\n :host([compact]) .chip-container,\r\n .chip-container[compact] {\r\n gap: 4px;\r\n padding-block: 2px;\r\n }\r\n\r\n :host([variant=\"inside\"]) .chip-container {\r\n height: auto;\r\n align-self: center;\r\n padding-block: 0;\r\n }\r\n\r\n .input-wrapper:has(.icon-slot[filled].left) .chip-container {\r\n padding-inline-start: var(--sky-input-pad-x-sm);\r\n }\r\n\r\n .value-summary {\r\n display: block;\r\n flex: 1 1 0%;\r\n width: 100%;\r\n min-width: 0;\r\n max-width: 100%;\r\n box-sizing: border-box;\r\n margin: 0;\r\n padding-inline: var(--sky-input-pad-x) var(--sky-input-pad-x-sm);\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n font-size: var(--sky-font-size-md);\r\n color: var(--sky-text-primary);\r\n font-family: var(--sky-font);\r\n line-height: 1.25;\r\n text-align: start;\r\n }\r\n\r\n .input-wrapper:has(.icon-slot[filled].left) .value-summary {\r\n padding-inline-start: var(--sky-input-pad-x-sm);\r\n }\r\n\r\n :host([compact]) .value-summary {\r\n font-size: var(--sky-font-size-sm);\r\n }\r\n\r\n .chip-container::-webkit-scrollbar {\r\n display: none;\r\n }\r\n\r\n .chip {\r\n background-color: var(--sky-glass-primary);\r\n border-radius: var(--sky-radius-primary);\r\n padding: 0 6px;\r\n height: 1.25rem;\r\n max-height: calc(var(--sky-input-height) - 10px);\r\n font-size: var(--sky-font-size-sm);\r\n line-height: 1;\r\n display: inline-flex;\r\n align-items: center;\r\n align-self: center;\r\n gap: 4px;\r\n flex: 0 1 auto;\r\n max-width: 100%;\r\n min-width: 0;\r\n border: var(--sky-border-primary);\r\n font-family: var(--sky-font);\r\n text-align: start;\r\n box-sizing: border-box;\r\n white-space: nowrap;\r\n }\r\n\r\n .chip .chip-label {\r\n min-width: 0;\r\n flex: 1 1 auto;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n line-height: 1;\r\n }\r\n\r\n .chip.overflow-chip {\r\n flex: 0 0 auto;\r\n white-space: nowrap;\r\n max-width: none;\r\n }\r\n\r\n :host([compact]) .chip {\r\n height: 1.125rem;\r\n max-height: calc(var(--sky-input-height-compact) - 8px);\r\n padding: 0 4px;\r\n font-size: var(--sky-font-size-xs);\r\n }\r\n\r\n .chip .remove-chip[compact] {\r\n flex-shrink: 0;\r\n }\r\n .remove-chip-inner {\r\n font-size: var(--sky-font-size-md);\r\n color: var(--sky-dropdown-color);\r\n background-color: var(--sky-hover-primary);\r\n border-radius: var(--sky-radius-full);\r\n border: none;\r\n cursor: pointer;\r\n transition: color 0.2s ease, background-color 0.2s ease;\r\n }\r\n .remove-chip-inner:hover {\r\n color: var(--sky-danger-primary);\r\n }\r\n .remove-chip:hover {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n .chip .remove-chip {\r\n position: static;\r\n flex-shrink: 0;\r\n align-self: center;\r\n font-size: var(--sky-font-size-sm);\r\n color: var(--sky-dropdown-color);\r\n background-color: var(--sky-hover-primary);\r\n border-radius: var(--sky-radius-full);\r\n cursor: pointer;\r\n border: none;\r\n transition: color 0.2s ease, background-color 0.2s ease;\r\n }\r\n\r\n .input-wrapper[disabled] {\r\n opacity: 0.6;\r\n pointer-events: none;\r\n }\r\n\r\n .dropdown {\r\n position: fixed;\r\n padding: 5px;\r\n background: var(--sky-glass-tertiary);\r\n background-image: var(--sky-glass-surface);\r\n backdrop-filter: var(--sky-blur-tertiary) var(--sky-brightness-tertiary)\r\n var(--sky-saturation-tertiary);\r\n -webkit-backdrop-filter: var(--sky-blur-tertiary)\r\n var(--sky-brightness-tertiary) var(--sky-saturation-tertiary);\r\n border-radius: var(--sky-radius-secondary);\r\n box-shadow:\r\n var(--sky-box-shadow-inset),\r\n var(--sky-box-shadow-tertiary);\r\n box-sizing: border-box;\r\n pointer-events: auto;\r\n margin: 0;\r\n border: var(--sky-border-tertiary);\r\n }\r\n\r\n .dropdown-scroller {\r\n max-height: var(--sky-scroll-height);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n scrollbar-color: var(--sky-scrollbar-thumb) var(--sky-scrollbar-track);\r\n }\r\n\r\n .dropdown-scroller::-webkit-scrollbar {\r\n width: 6px;\r\n height: 6px;\r\n }\r\n\r\n .dropdown-scroller::-webkit-scrollbar-thumb {\r\n background-color: var(--sky-scrollbar-thumb);\r\n border-radius: var(--sky-radius-full, 9999px);\r\n transition: background-color var(--sky-duration-normal, 200ms)\r\n var(--sky-ease-default, ease);\r\n cursor: grab;\r\n }\r\n\r\n .dropdown-scroller::-webkit-scrollbar-thumb:hover {\r\n background-color: var(--sky-scrollbar-thumb-hover);\r\n }\r\n\r\n .dropdown-scroller::-webkit-scrollbar-track {\r\n background: var(--sky-scrollbar-track);\r\n }\r\n\r\n .dropdown-scroller::-webkit-scrollbar-button {\r\n background-color: transparent;\r\n }\r\n\r\n .dropdown-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 8px 10px;\r\n border-radius: var(--sky-radius-secondary);\r\n cursor: pointer;\r\n text-align: left;\r\n font-size: var(--sky-font-size-sm);\r\n color: var(--sky-text-primary);\r\n transition:\r\n background-color 0.15s ease,\r\n color 0.15s ease;\r\n box-sizing: border-box;\r\n margin: 2px 0;\r\n font-family: var(--sky-font);\r\n }\r\n\r\n .dropdown-item:hover {\r\n background-color: var(--sky-hover-primary);\r\n }\r\n\r\n .dropdown-item.active {\r\n background-color: var(--sky-hover-primary);\r\n }\r\n\r\n .dropdown-item.selected {\r\n color: var(--sky-dropdown-color, var(--sky-active-primary));\r\n background-color: var(--sky-active-g0, var(--sky-hover-primary));\r\n font-weight: var(--sky-font-weight-medium, 500);\r\n }\r\n\r\n .dropdown-item.active.selected,\r\n .dropdown-item.selected:hover {\r\n background-color: var(--sky-active-g0, var(--sky-hover-primary));\r\n color: var(--sky-dropdown-color, var(--sky-active-primary));\r\n }\r\n\r\n :host([compact]) .dropdown-item {\r\n font-size: var(--sky-font-size-sm);\r\n padding: 5px 8px;\r\n margin: 1px 0;\r\n }\r\n\r\n .icon-slot {\r\n display: none;\r\n justify-content: center;\r\n font-size: var(--sky-font-size-xl);\r\n align-items: center;\r\n align-self: center;\r\n color: var(--sky-text-primary);\r\n height: 100%;\r\n max-height: 100%;\r\n box-sizing: border-box;\r\n flex: 0 0 var(--sky-input-icon-width);\r\n width: var(--sky-input-icon-width);\r\n min-width: var(--sky-input-icon-width);\r\n padding: 0;\r\n background: none;\r\n border: none;\r\n transition: color var(--sky-transition-normal, 200ms ease);\r\n }\r\n\r\n .hidden-chips-dropdown {\r\n position: fixed; /* important: popover top layer */\r\n background: var(--sky-glass-tertiary);\r\n background-image: var(--sky-glass-surface);\r\n backdrop-filter: var(--sky-blur-tertiary) var(--sky-brightness-tertiary)\r\n var(--sky-saturation-tertiary);\r\n -webkit-backdrop-filter: var(--sky-blur-tertiary)\r\n var(--sky-brightness-tertiary) var(--sky-saturation-tertiary);\r\n box-shadow:\r\n var(--sky-box-shadow-inset),\r\n var(--sky-box-shadow-tertiary);\r\n border-radius: var(--sky-radius-secondary);\r\n border: var(--sky-border-tertiary);\r\n width: max-content;\r\n opacity: 0;\r\n transform: scale(0.98);\r\n transition: opacity 0.15s ease, transform 0.15s ease;\r\n margin: 0;\r\n }\r\n\r\n .hidden-chips-dropdown:popover-open {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n\r\n .hidden-chip-inner {\r\n padding: 4px 8px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n cursor: pointer;\r\n gap: 5px;\r\n font-size: var(--sky-font-size-sm);\r\n border-bottom: var(--sky-border-primary);\r\n font-family: var(--sky-font);\r\n }\r\n\r\n .hidden-chip-inner:last-child {\r\n border-bottom: none;\r\n }\r\n\r\n .icon-slot[filled] {\r\n display: flex;\r\n flex-shrink: 0;\r\n cursor: pointer;\r\n }\r\n\r\n .icon-slot[filled]:hover,\r\n .icon-slot[filled]:active,\r\n .icon-slot.focused,\r\n .input-wrapper[open] .icon-slot[filled] {\r\n color: var(--sky-dropdown-color);\r\n }\r\n\r\n .placeholder-label {\r\n white-space: nowrap;\r\n box-sizing: border-box;\r\n padding-inline: var(--sky-input-pad-x);\r\n flex: 1 1 0%;\r\n width: 100%;\r\n min-width: 0;\r\n text-align: start;\r\n font-size: var(--sky-font-size-md);\r\n line-height: 1.25;\r\n color: var(--sky-text-tertiary);\r\n transition: color var(--sky-transition-normal, 200ms ease);\r\n pointer-events: none;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n font-family: var(--sky-font);\r\n display: flex;\r\n align-items: center;\r\n align-self: stretch;\r\n }\r\n\r\n .input-wrapper:has(.icon-slot[filled].left) .placeholder-label {\r\n padding-inline-start: var(--sky-input-pad-x-sm);\r\n }\r\n\r\n .placeholder-label.active {\r\n display: none;\r\n }\r\n\r\n .field-trailing {\r\n display: flex;\r\n flex: 0 0 auto;\r\n flex-shrink: 0;\r\n align-items: center;\r\n justify-content: flex-end;\r\n align-self: stretch;\r\n gap: var(--sky-input-pad-x-sm);\r\n padding-inline-end: var(--sky-input-pad-x-sm);\r\n padding-inline-start: var(--sky-input-pad-x-sm);\r\n box-sizing: border-box;\r\n }\r\n\r\n sky-icon.clear-button {\r\n box-sizing: border-box;\r\n flex: 0 0 auto;\r\n width: 1.125rem;\r\n height: 1.125rem;\r\n min-width: 1.125rem;\r\n min-height: 1.125rem;\r\n margin: 0;\r\n padding: 0;\r\n border: none;\r\n font-size: 0.75rem;\r\n line-height: 1;\r\n color: var(--sky-dropdown-color);\r\n background-color: var(--sky-hover-primary);\r\n border-radius: var(--sky-radius-full);\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n cursor: pointer;\r\n transition: color var(--sky-transition-normal, 200ms ease);\r\n }\r\n\r\n sky-icon.clear-button[compact] {\r\n width: 1rem;\r\n height: 1rem;\r\n min-width: 1rem;\r\n min-height: 1rem;\r\n font-size: 0.6875rem;\r\n }\r\n\r\n sky-icon.clear-button:hover {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n sky-icon.dropdown-button {\r\n box-sizing: border-box;\r\n flex: 0 0 auto;\r\n width: var(--sky-input-icon-width);\r\n height: auto;\r\n min-width: calc(var(--sky-input-icon-width) - 0.25rem);\r\n margin: 0;\r\n padding: 0;\r\n border: none;\r\n font-size: var(--sky-font-size-sm);\r\n color: var(--sky-text-primary);\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: color var(--sky-transition-normal, 200ms ease);\r\n background: none;\r\n }\r\n\r\n sky-icon.dropdown-button:hover,\r\n .input-wrapper[open] sky-icon.dropdown-button {\r\n color: var(--sky-dropdown-color);\r\n }\r\n\r\n sky-icon.dropdown-button[compact] {\r\n font-size: var(--sky-font-size-md);\r\n }\r\n\r\n .loading-indicator {\r\n flex-shrink: 0;\r\n margin-inline-end: var(--sky-input-pad-x-sm);\r\n width: 16px;\r\n height: 16px;\r\n border: 2px solid var(--sky-border-light, var(--sky-text-tertiary));\r\n border-top: 2px solid var(--sky-dropdown-color, var(--sky-active-primary));\r\n border-radius: var(--sky-radius-full);\r\n animation: spin 1s linear infinite;\r\n }\r\n\r\n ::slotted(.icon-slot) {\r\n display: block;\r\n }\r\n\r\n @keyframes spin {\r\n 0% {\r\n transform: rotate(0deg);\r\n }\r\n 100% {\r\n transform: rotate(360deg);\r\n }\r\n }\r\n\r\n .highlight {\r\n color: var(--sky-dropdown-color);\r\n font-weight: var(--sky-font-weight-semibold);\r\n }\r\n\r\n .progress-container {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: flex-start;\r\n align-items: flex-start;\r\n position: absolute;\r\n width: 100%;\r\n top: 100%;\r\n }\r\n\r\n .progress-message {\r\n pointer-events: none;\r\n width: 100%;\r\n overflow: hidden;\r\n white-space: nowrap;\r\n text-overflow: ellipsis;\r\n font-size: var(--sky-font-size-sm);\r\n margin-inline-start: var(--sky-input-pad-x-sm);\r\n font-family: var(--sky-font);\r\n }\r\n\r\n :dir(rtl) .progress-message {\r\n margin-inline-start: unset;\r\n margin-inline-end: var(--sky-input-pad-x-sm);\r\n }\r\n\r\n .error-list {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0;\r\n width: 100%;\r\n }\r\n\r\n .error {\r\n font-size: var(--sky-font-size-xs);\r\n color: var(--sky-danger-primary);\r\n text-align: start;\r\n white-space: nowrap;\r\n text-overflow: ellipsis;\r\n font-family: var(--sky-font);\r\n }\r\n .sky-checkbox {\r\n appearance: none;\r\n flex-shrink: 0;\r\n width: 16px;\r\n height: 16px;\r\n border-radius: 6px;\r\n margin-right: 5px;\r\n border: 1px solid var(--sky-text-tertiary);\r\n background-color: transparent;\r\n box-shadow: none;\r\n cursor: pointer;\r\n position: relative;\r\n transition:\r\n background-color 0.3s ease,\r\n border-color 0.3s ease,\r\n box-shadow 0.3s ease;\r\n }\r\n\r\n .sky-checkbox:hover {\r\n background-color: var(--sky-text-tertiary);\r\n border-color: var(--sky-text-tertiary);\r\n }\r\n\r\n .sky-checkbox:focus-visible {\r\n background-color: var(--sky-text-tertiary);\r\n border-color: var(--sky-text-tertiary);\r\n outline: none;\r\n }\r\n\r\n .sky-checkbox:checked {\r\n background-color: var(--sky-active-primary);\r\n border-color: var(--sky-active-primary);\r\n }\r\n\r\n .sky-checkbox::after {\r\n content: \"\";\r\n width: 8px;\r\n height: 4px;\r\n border: 2px solid var(--sky-on-color-fallback-light, var(--sky-text-white));\r\n border-top: none;\r\n border-right: none;\r\n position: absolute;\r\n top: 6px;\r\n left: 50%;\r\n transform: translate(-50%, -50%) rotate(-90deg) scale(0.8);\r\n opacity: 0;\r\n transition:\r\n opacity 0.2s ease-in-out,\r\n transform 0.2s ease-in-out;\r\n }\r\n\r\n .sky-checkbox.indeterminate {\r\n background-color: var(--sky-active-primary);\r\n border-color: var(--sky-active-primary);\r\n }\r\n\r\n .sky-checkbox.indeterminate::after {\r\n width: 8px;\r\n height: 2px;\r\n background-color: var(--sky-on-color-fallback-light, var(--sky-text-white));\r\n border: none;\r\n top: 50%;\r\n left: 50%;\r\n opacity: 1;\r\n transform: translate(-50%, -50%) scale(1);\r\n }\r\n\r\n .sky-checkbox:checked::after {\r\n opacity: 1;\r\n transform: translate(-50%, -50%) rotate(-45deg) scale(1);\r\n }\r\n\r\n .sky-checkbox:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n }\r\n\r\n ${unsafeCSS(\r\n cssOnFillEnhance([\r\n {\r\n selector: \".placeholder-label.active[compact]\",\r\n fillVar: \"--sky-dropdown-color\",\r\n },\r\n {\r\n selector: \".sky-checkbox:checked::after\",\r\n fillVar: \"--sky-active-primary\",\r\n property: \"border-color\",\r\n },\r\n {\r\n selector: \".sky-checkbox.indeterminate::after\",\r\n fillVar: \"--sky-active-primary\",\r\n property: \"background-color\",\r\n },\r\n ]),\r\n )}\r\n `;\r\n\r\n constructor() {\r\n super();\r\n this.captureDefaultValue(\"\");\r\n }\r\n\r\n static override shadowRootOptions = {\r\n ...LitElement.shadowRootOptions,\r\n delegatesFocus: true,\r\n };\r\n\r\n override connectedCallback() {\r\n super.connectedCallback();\r\n\r\n if (!this.hasAttribute(\"tabindex\")) {\r\n this.tabIndex = this.disabled ? -1 : 0;\r\n }\r\n this.refreshOptionSlots();\r\n\r\n }\r\n\r\n override firstUpdated() {\r\n this.dropdownPopover.refreshTargets();\r\n this.hiddenPopover.refreshTargets();\r\n }\r\n\r\n private refreshOptionSlots = () => {\r\n const set = new Set<string>();\r\n this.querySelectorAll<HTMLElement>('[slot^=\"option-\"]').forEach((el) => {\r\n const slotName = (el as HTMLElement).slot;\r\n if (slotName) set.add(slotName);\r\n });\r\n this.optionSlotSet = set;\r\n };\r\n\r\n /** Get the current value for form submission */\r\n protected override getFormValue(): FormState {\r\n if (this.disabled || !this.name) return null;\r\n\r\n if (this.multiSelect) {\r\n const formData = new FormData();\r\n this.selectedItems.forEach((item) => {\r\n const value = this.emitFullObject\r\n ? JSON.stringify(item)\r\n : String(this.getOptionValue(item));\r\n formData.append(this.name, value);\r\n });\r\n // Add a dummy input when nothing is selected (for form validation)\r\n if (this.selectedItems.length === 0 && this.required) {\r\n formData.append(this.name, \"\");\r\n }\r\n return formData;\r\n } else {\r\n if (this.selectedItems.length === 0) return \"\";\r\n const item = this.selectedItems[0];\r\n return this.emitFullObject\r\n ? JSON.stringify(item)\r\n : String(this.getOptionValue(item));\r\n }\r\n }\r\n\r\n /** Set value from form state (e.g., form reset) */\r\n protected override setValueFromFormState(state: FormState): void {\r\n if (state === null || state === \"\") {\r\n this.value = this.multiSelect ? [] : \"\";\r\n this.selectedItems = [];\r\n return;\r\n }\r\n\r\n if (this.multiSelect) {\r\n let values: any[] = [];\r\n\r\n if (state instanceof FormData) {\r\n values = state.getAll(this.name);\r\n } else if (Array.isArray(state)) {\r\n values = state;\r\n } else if (typeof state === \"string\") {\r\n try {\r\n const parsed = JSON.parse(state);\r\n if (Array.isArray(parsed)) {\r\n values = parsed;\r\n } else {\r\n values = [state];\r\n }\r\n } catch {\r\n values = [state];\r\n }\r\n }\r\n\r\n this.setValueFromArray(values);\r\n } else {\r\n let stringValue = \"\";\r\n if (typeof state === \"string\") {\r\n stringValue = state;\r\n } else if (state instanceof FormData) {\r\n stringValue = state.get(this.name)?.toString() || \"\";\r\n } else if (Array.isArray(state) && state.length > 0) {\r\n stringValue = state[0].toString();\r\n }\r\n\r\n this.value = stringValue;\r\n this.syncSelectedItemsWithValue();\r\n }\r\n }\r\n protected override syncFormValue(): void {\r\n if (!this.name || this.disabled) {\r\n this.internals.setFormValue(null);\r\n return;\r\n }\r\n\r\n const v = this.getFormValue();\r\n\r\n if (v === null) {\r\n this.internals.setFormValue(null);\r\n return;\r\n }\r\n\r\n if (this.multiSelect && Array.isArray(v)) {\r\n // Matches native <select multiple> form value shape.\r\n const formData = new FormData();\r\n v.forEach((value) => {\r\n if (value !== null && value !== undefined && value !== \"\") {\r\n formData.append(this.name, String(value));\r\n }\r\n });\r\n this.internals.setFormValue(formData);\r\n } else {\r\n this.internals.setFormValue(v as string | File | null);\r\n }\r\n }\r\n private setValueFromArray(values: any[]) {\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n this.selectedItems = optionsArray.filter((option) => {\r\n const optionValue = this.getOptionValue(option);\r\n const optionValueString = this.emitFullObject\r\n ? JSON.stringify(option)\r\n : String(optionValue);\r\n\r\n return values.some((value) => {\r\n const stringValue = String(value);\r\n\r\n if (this.emitFullObject) {\r\n try {\r\n const parsedValue = JSON.parse(stringValue);\r\n return JSON.stringify(parsedValue) === optionValueString;\r\n } catch {\r\n return stringValue === optionValueString;\r\n }\r\n } else {\r\n return stringValue === optionValueString;\r\n }\r\n });\r\n });\r\n\r\n this.value = this.selectedItems.map((item) =>\r\n this.emitFullObject ? item : this.getOptionValue(item),\r\n );\r\n }\r\n\r\n /** Get the validity anchor (for validation messages) */\r\n protected override getValidityAnchor(): HTMLElement | undefined {\r\n return this;\r\n }\r\n\r\n /** Check if empty (for required validation) */\r\n protected override isEmpty(): boolean {\r\n if (this.multiSelect) {\r\n return this.selectedItems.length === 0;\r\n } else {\r\n return this.selectedItems.length === 0 || !this.value;\r\n }\r\n }\r\n\r\n protected override getNativeControl(): HTMLElement | null {\r\n return this.inputWrapperEl || null;\r\n }\r\n /** Override to provide custom error messages */\r\n protected override getCustomErrorMessage(): string {\r\n return this.validationErrors?.[0] || \"\";\r\n }\r\n\r\n /** Override form reset callback */\r\n protected override onFormReset(): void {\r\n super.onFormReset();\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.open = false;\r\n this.invalid = false;\r\n this.validationErrors = [];\r\n this.validationActive = false;\r\n }\r\n\r\n /** Override form disabled callback */\r\n protected override onFormDisabled(disabled: boolean): void {\r\n this.disabled = disabled;\r\n }\r\n\r\n /** Override form state restore callback */\r\n protected override onFormStateRestore(state: FormState): void {\r\n this.setValueFromFormState(state);\r\n }\r\n\r\n\r\n private toggleSelectAll(): void {\r\n if (this.disabled || this.readonly) return;\r\n\r\n if (this.isAllFilteredSelected()) {\r\n const filteredKeys = new Set(\r\n this.filteredOptions.map((opt) => this.optionKey(opt.original)),\r\n );\r\n\r\n const nextSelected = this.selectedItems.filter(\r\n (item) => !filteredKeys.has(this.optionKey(item)),\r\n );\r\n\r\n // 🚫 prevent going below 1 selection when enforced\r\n if (this.enforceMinOneSelection && nextSelected.length === 0) {\r\n return;\r\n }\r\n\r\n this.selectedItems = nextSelected;\r\n } else {\r\n const selectedKeys = new Set(\r\n this.selectedItems.map((item) => this.optionKey(item)),\r\n );\r\n const additions = this.filteredOptions\r\n .map((o) => o.original)\r\n .filter((opt) => !selectedKeys.has(this.optionKey(opt)));\r\n this.selectedItems = [...this.selectedItems, ...additions];\r\n }\r\n\r\n const valuesArray = this.selectedItems.map((opt) =>\r\n this.emitFullObject ? opt : this.getOptionValue(opt),\r\n );\r\n this.value = valuesArray;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent<SkyComboboxValueChangedDetail>(\"value-changed\", {\r\n detail: {\r\n value: valuesArray,\r\n selectedItems: [...this.selectedItems],\r\n emittedValues: valuesArray,\r\n isFilteredSelection: !!this.searchQuery.trim(),\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n\r\n this.syncFormValue();\r\n this.syncValidity();\r\n this.requestUpdate();\r\n }\r\n\r\n private isAllFilteredSelected(): boolean {\r\n if (this.filteredOptions.length === 0) return false;\r\n\r\n const selectedKeys = new Set(\r\n this.selectedItems.map((item) => this.optionKey(item)),\r\n );\r\n return this.filteredOptions.every((opt) =>\r\n selectedKeys.has(this.optionKey(opt.original)),\r\n );\r\n }\r\n\r\n private truncateText(text: string, maxLength: number): string {\r\n if (text.length > maxLength) {\r\n return text.slice(0, maxLength) + \"...\";\r\n }\r\n return text;\r\n }\r\n\r\n private validateInput(): void {\r\n if (!this.validationActive) return;\r\n\r\n this.validationErrors = [];\r\n\r\n const target = this.validationArrayFormat ? this.selectedItems : this.value;\r\n\r\n // 1) required first (single source of truth inside component UI)\r\n if (this.required && this.isEmpty()) {\r\n this.validationErrors.push(\r\n this.requiredMessage || \"Selection is required.\",\r\n );\r\n } else {\r\n // 2) run external validations only when not empty (optional but cleaner)\r\n if (Array.isArray(this.validations) && this.validations.length) {\r\n for (const v of this.validations) {\r\n const res = v(target);\r\n if (res !== true)\r\n this.validationErrors.push(String(res || \"Invalid value.\"));\r\n }\r\n }\r\n }\r\n\r\n this.invalid = this.validationErrors.length > 0;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent<SkyComboboxValidationErrorDetail | SkyComboboxValidationSuccessDetail>(\r\n this.invalid ? \"validation-error\" : \"validation-success\",\r\n {\r\n detail: this.invalid\r\n ? { errors: this.validationErrors }\r\n : { value: this.selectedItems },\r\n bubbles: true,\r\n composed: true,\r\n },\r\n ),\r\n );\r\n\r\n this.syncValidity();\r\n this.requestUpdate();\r\n }\r\n\r\n // Blocks form submit when invalid, even if validationActive is false.\r\n protected override validateForForm(): string {\r\n if (this.disabled) return \"\";\r\n\r\n // What should validators receive?\r\n const target = this.validationArrayFormat ? this.selectedItems : this.value;\r\n\r\n // 1) external validations first\r\n if (Array.isArray(this.validations) && this.validations.length) {\r\n for (const v of this.validations) {\r\n const res = v(target);\r\n if (res !== true) return String(res || \"Invalid value.\");\r\n }\r\n }\r\n\r\n // 2) enforceMinOneSelection as a hard rule (optional but makes form correct)\r\n if (this.enforceMinOneSelection && this.isEmpty()) {\r\n return this.requiredMessage || \"At least one selection is required.\";\r\n }\r\n\r\n // 3) required rule\r\n if (this.required && this.isEmpty()) {\r\n return this.requiredMessage || \"Selection is required.\";\r\n }\r\n\r\n return \"\";\r\n }\r\n\r\n override focus(options?: FocusOptions) {\r\n super.focus(options);\r\n if (this.searchInputEl) {\r\n this.searchInputEl.focus(options);\r\n } else if (this.inputWrapperEl) {\r\n this.inputWrapperEl.focus(options);\r\n }\r\n }\r\n\r\n override blur() {\r\n if (this.open) {\r\n this.dropdownPopover.closePopover(\"light-dismiss\");\r\n }\r\n super.blur();\r\n }\r\n\r\n private handleFocus(): void {\r\n this.focused = true;\r\n\r\n if (!this.validationActive) {\r\n this.validationActive = true;\r\n }\r\n }\r\n\r\n /**\r\n * Resets combobox state and clears validation UI.\r\n *\r\n * @returns {void}\r\n */\r\n public reset(): void {\r\n this.value = this.multiSelect ? [] : \"\";\r\n this.selectedItems = [];\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.filterOptions();\r\n this.validationErrors = [];\r\n this.validationActive = false;\r\n this.open = false;\r\n this.invalid = false;\r\n this.syncFormValue();\r\n this.syncValidity();\r\n this.requestUpdate();\r\n }\r\n\r\n /**\r\n * Opens the combobox dropdown.\r\n *\r\n * @returns {void}\r\n */\r\n public openDropdown(): void {\r\n if (this.disabled || this.readonly) return;\r\n this.dropdownPopover.openPopover();\r\n }\r\n\r\n /**\r\n * Closes the combobox dropdown.\r\n *\r\n * @returns {void}\r\n */\r\n public closeDropdown(): void {\r\n this.dropdownPopover.closePopover(\"api\");\r\n }\r\n\r\n /**\r\n * Clears current selection when allowed by component settings.\r\n *\r\n * @returns {void}\r\n */\r\n public clearSelection(): void {\r\n this.handleClear();\r\n }\r\n\r\n private handleBlur(): void {\r\n // Focus often moves into the popover top-layer; keep open chrome while open.\r\n if (this.open) return;\r\n this.focused = false;\r\n\r\n if (this.validationActive) {\r\n this.validateInput();\r\n }\r\n }\r\n\r\n override updated(changedProperties: Map<string, unknown>) {\r\n if (changedProperties.has(\"color\")) {\r\n this.style.setProperty(\"--sky-dropdown-color\", resolveColor(this.color));\r\n }\r\n if (changedProperties.has(\"height\")) {\r\n this.style.setProperty(\"--sky-scroll-height\", this.height);\r\n }\r\n }\r\n override willUpdate(changedProperties: Map<string, unknown>) {\r\n if (changedProperties.has(\"customRenderers\")) {\r\n this.syncRendererStateFromProp();\r\n }\r\n\r\n if (changedProperties.has(\"value\")) {\r\n this.syncSelectedItemsWithValue();\r\n this.syncFormValue();\r\n this.syncValidity();\r\n }\r\n\r\n if (changedProperties.has(\"options\")) {\r\n if (!Array.isArray(this.options)) {\r\n this.options = [];\r\n }\r\n this.syncSelectedItemsWithValue();\r\n this.filterOptions();\r\n this.syncFormValue();\r\n this.syncValidity();\r\n }\r\n\r\n if (changedProperties.has(\"searchable\")) {\r\n this.filterOptions();\r\n }\r\n\r\n if (changedProperties.has(\"searchQuery\")) {\r\n this.filterOptions();\r\n }\r\n\r\n if (changedProperties.has(\"validationErrors\")) {\r\n this.requestUpdate();\r\n }\r\n }\r\n\r\n /** Merges runtime renderer state (from `customRenderers.$rendererState`) and re-renders. */\r\n patchRendererState(patch: Record<string, unknown>): void {\r\n this._rendererRuntimeState = { ...this._rendererRuntimeState, ...patch };\r\n this.requestUpdate();\r\n }\r\n\r\n private syncRendererStateFromProp(): void {\r\n const fromProp = extractComboboxRendererState(this.customRenderers);\r\n this._rendererRuntimeState = {\r\n ...this._rendererRuntimeState,\r\n ...fromProp,\r\n };\r\n }\r\n\r\n private rendererStateApi(): SkyComboboxRendererStateApi {\r\n return {\r\n rendererState: this._rendererRuntimeState,\r\n patchRendererState: (patch: Record<string, unknown>) =>\r\n this.patchRendererState(patch),\r\n };\r\n }\r\n\r\n private buildOptionRenderContext(args: {\r\n option: unknown;\r\n index: number;\r\n sourceIndex: number;\r\n highlightedLabel: string;\r\n selected: boolean;\r\n active: boolean;\r\n }): SkyComboboxOptionRenderContext {\r\n return {\r\n index: args.index,\r\n sourceIndex: args.sourceIndex,\r\n label: String(this.getOptionLabel(args.option)),\r\n highlightedLabel: args.highlightedLabel,\r\n selected: args.selected,\r\n active: args.active,\r\n multiSelect: this.multiSelect,\r\n ...this.rendererStateApi(),\r\n };\r\n }\r\n\r\n private buildSelectedRenderContext(\r\n option: unknown,\r\n index: number,\r\n ): SkyComboboxSelectedRenderContext {\r\n return {\r\n selectedItems: [...this.selectedItems],\r\n index,\r\n multiSelect: this.multiSelect,\r\n multiDisplay: this.resolveMultiDisplay(),\r\n label: String(this.getOptionLabel(option)),\r\n ...this.rendererStateApi(),\r\n };\r\n }\r\n\r\n private renderOptionContent(args: {\r\n option: unknown;\r\n index: number;\r\n sourceIndex: number;\r\n highlighted: string;\r\n selected: boolean;\r\n active: boolean;\r\n hasSlot: boolean;\r\n slotName: string;\r\n }) {\r\n const defaultLabel = html`<span\r\n class=\"highlighted-text\"\r\n part=\"highlighted-text\"\r\n >${unsafeHTML(args.highlighted)}</span\r\n >`;\r\n\r\n // Named slots win over customRenderers (DOM composition).\r\n if (args.hasSlot) {\r\n return html`\r\n <div style=\"display: flex; gap: 8px;width:100%\">\r\n <slot name=${args.slotName}> ${defaultLabel} </slot>\r\n </div>\r\n `;\r\n }\r\n\r\n const customRenderer = this.customRenderers?.option;\r\n if (customRenderer) {\r\n const content = customRenderer(\r\n args.option,\r\n this.buildOptionRenderContext({\r\n option: args.option,\r\n index: args.index,\r\n sourceIndex: args.sourceIndex,\r\n highlightedLabel: args.highlighted,\r\n selected: args.selected,\r\n active: args.active,\r\n }),\r\n );\r\n return html`<div style=\"display: flex; gap: 8px;width:100%\">\r\n ${content}\r\n </div>`;\r\n }\r\n\r\n return defaultLabel;\r\n }\r\n\r\n private renderSelectedLabel(option: unknown, index: number) {\r\n const customRenderer = this.customRenderers?.selected;\r\n if (customRenderer) {\r\n return customRenderer(option, this.buildSelectedRenderContext(option, index));\r\n }\r\n return this.truncateText(String(this.getOptionLabel(option)), this.chipSize);\r\n }\r\n\r\n private renderSelectedSummaryLabel(option: unknown, index: number) {\r\n const customRenderer = this.customRenderers?.selected;\r\n if (customRenderer) {\r\n return customRenderer(option, this.buildSelectedRenderContext(option, index));\r\n }\r\n return String(this.getOptionLabel(option));\r\n }\r\n\r\n private syncSelectedItemsWithValue(): void {\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n // Treat null/undefined or [] (when multi) as empty\r\n const isEmptyMulti =\r\n this.multiSelect && Array.isArray(this.value) && this.value.length === 0;\r\n\r\n if (this.value == null || this.value === \"\" || isEmptyMulti) {\r\n this.selectedItems = [];\r\n this.value = this.multiSelect ? [] : \"\";\r\n return;\r\n }\r\n\r\n // Back-compat: if someone still passes a JSON stringified array\r\n if (this.multiSelect && typeof this.value === \"string\") {\r\n try {\r\n const parsed = JSON.parse(this.value);\r\n if (Array.isArray(parsed)) this.value = parsed;\r\n } catch (_) {\r\n // ignore non-JSON strings\r\n }\r\n }\r\n\r\n if (this.multiSelect) {\r\n // Normalize incoming to an array\r\n const raw = Array.isArray(this.value) ? this.value : [this.value];\r\n\r\n // Build a comparable key set from provided values\r\n const providedKeys = new Set(raw.map((v) => this.optionKey(v)));\r\n\r\n this.selectedItems = optionsArray.filter((opt) =>\r\n providedKeys.has(this.optionKey(opt)),\r\n );\r\n\r\n // Normalize this.value to the canonical emitted values\r\n this.value = this.selectedItems.map((opt) =>\r\n this.emitFullObject ? opt : this.getOptionValue(opt),\r\n );\r\n } else {\r\n const targetValue = this.optionKey(this.value);\r\n\r\n const selectedOption = optionsArray.find(\r\n (opt) => this.optionKey(opt) === targetValue,\r\n );\r\n\r\n this.selectedItems = selectedOption ? [selectedOption] : [];\r\n this.value = selectedOption\r\n ? this.emitFullObject\r\n ? selectedOption\r\n : this.getOptionValue(selectedOption)\r\n : \"\";\r\n }\r\n }\r\n\r\n private filterOptions(): void {\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n const makeRow = (option: any, idx: number) => {\r\n const label = this.getOptionLabel(option);\r\n return {\r\n original: option,\r\n _idx: idx,\r\n label,\r\n highlighted: label,\r\n };\r\n };\r\n\r\n if (!this.searchable || !this.searchQuery.trim()) {\r\n this.filteredOptions = optionsArray.map(makeRow);\r\n return;\r\n }\r\n\r\n const query = this.searchQuery.toLowerCase();\r\n\r\n this.filteredOptions = optionsArray\r\n .map(makeRow)\r\n .filter((row) => String(row.label).toLowerCase().includes(query))\r\n .map((row) => {\r\n const regex = new RegExp(`(${query})`, \"gi\");\r\n return {\r\n ...row,\r\n highlighted: String(row.label).replace(\r\n regex,\r\n (m: string) => `<span class=\"highlight\">${m}</span>`,\r\n ),\r\n };\r\n });\r\n }\r\n\r\n\r\n /** Emit search query for hosts / `v-model:search-query` when `searchQuery` changes outside the search input handler. */\r\n private emitSearchQueryChanged(): void {\r\n this.dispatchEvent(\r\n new CustomEvent<SkyComboboxSearchQueryChangedDetail>(\"search-query-changed\", {\r\n detail: { searchQuery: this.searchQuery },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n\r\n private handleSearchValueChanged(\r\n event: CustomEvent<{ value: string | number }>,\r\n ): void {\r\n event.stopPropagation();\r\n if (this.disabled || this.readonly) return;\r\n this.applySearchQuery(String(event.detail?.value ?? \"\"));\r\n }\r\n\r\n private handleSearchValueCleared(event: Event): void {\r\n event.stopPropagation();\r\n if (this.disabled || this.readonly) return;\r\n this.applySearchQuery(\"\");\r\n }\r\n\r\n private applySearchQuery(raw: string): void {\r\n this.searchQuery = raw;\r\n const optionsLength = Array.isArray(this.options) ? this.options.length : 0;\r\n const shouldDebounce =\r\n this.searchable &&\r\n optionsLength > SkyCombobox._SEARCH_DEBOUNCE_OPTIONS_THRESHOLD;\r\n\r\n const applyFilter = () => {\r\n this.filterOptions();\r\n this.emitSearchQueryChanged();\r\n };\r\n\r\n if (shouldDebounce) {\r\n if (this._searchDebounceId != null) clearTimeout(this._searchDebounceId);\r\n this._searchDebounceId = setTimeout(() => {\r\n this._searchDebounceId = null;\r\n applyFilter();\r\n }, SkyCombobox._SEARCH_DEBOUNCE_MS);\r\n } else {\r\n applyFilter();\r\n }\r\n }\r\n\r\n override disconnectedCallback() {\r\n super.disconnectedCallback();\r\n if (this._searchDebounceId != null) {\r\n clearTimeout(this._searchDebounceId);\r\n this._searchDebounceId = null;\r\n }\r\n if (this._closeResetId != null) {\r\n clearTimeout(this._closeResetId);\r\n this._closeResetId = null;\r\n }\r\n }\r\n\r\n private handleClear(): void {\r\n if (this.disabled || this.readonly) return;\r\n\r\n const hasSelection = this.multiSelect\r\n ? this.selectedItems.length > 0\r\n : !!this.value;\r\n\r\n if (this.enforceMinOneSelection && hasSelection) {\r\n return;\r\n }\r\n this.value = this.multiSelect ? [] : \"\";\r\n this.selectedItems = [];\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.open = false;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent<SkyComboboxValueChangedDetail>(\"value-changed\", {\r\n detail: {\r\n value: this.value,\r\n selectedItems: [],\r\n isFilteredSelection: false,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n\r\n this.syncFormValue();\r\n this.syncValidity();\r\n }\r\n\r\n selectOption(option: any) {\r\n if (this.disabled || this.readonly) return;\r\n\r\n const getEmittedValue = (item: any) => {\r\n return this.emitFullObject ? item : this.getOptionValue(item);\r\n };\r\n\r\n const wasFiltered = this.searchQuery.trim() !== \"\";\r\n\r\n if (!this.multiSelect) {\r\n const alreadySelected =\r\n this.selectedItems.length &&\r\n this.optionKey(this.selectedItems[0]) === this.optionKey(option);\r\n\r\n if (alreadySelected && this.enforceMinOneSelection) {\r\n this.open = false;\r\n return;\r\n }\r\n\r\n if (alreadySelected) {\r\n this.selectedItems = [];\r\n this.value = \"\";\r\n } else {\r\n this.selectedItems = [option];\r\n this.value = getEmittedValue(option);\r\n }\r\n\r\n this.validateInput();\r\n\r\n this.dispatchEvent(\r\n new CustomEvent(\"value-changed\", {\r\n detail: {\r\n value: this.value,\r\n selectedItems: this.selectedItems,\r\n emittedValues: this.selectedItems.map(getEmittedValue),\r\n isFilteredSelection: wasFiltered,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n\r\n // Search reset is deferred in onOpenChange so options stay visible during close animation.\r\n this.dropdownPopover.closePopover(\"api\");\r\n this.syncFormValue();\r\n this.syncValidity();\r\n this.requestUpdate();\r\n return;\r\n }\r\n\r\n const index = this.selectedItems.findIndex(\r\n (item) => this.optionKey(item) === this.optionKey(option),\r\n );\r\n\r\n let nextSelected: any[];\r\n\r\n if (index > -1) {\r\n nextSelected = [\r\n ...this.selectedItems.slice(0, index),\r\n ...this.selectedItems.slice(index + 1),\r\n ];\r\n } else {\r\n nextSelected = [...this.selectedItems, option];\r\n }\r\n\r\n if (this.enforceMinOneSelection && nextSelected.length === 0) {\r\n return;\r\n }\r\n\r\n this.selectedItems = nextSelected;\r\n this.value = nextSelected.map(getEmittedValue);\r\n\r\n this.validateInput();\r\n\r\n this.dispatchEvent(\r\n new CustomEvent(\"value-changed\", {\r\n detail: {\r\n value: this.value,\r\n selectedItems: this.selectedItems,\r\n emittedValues: this.value,\r\n isFilteredSelection: wasFiltered,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n\r\n this.syncFormValue();\r\n this.syncValidity();\r\n this.open = true;\r\n this.requestUpdate();\r\n }\r\n\r\n toggleHiddenChips(e: Event) {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n if (this.disabled || this.readonly) return;\r\n\r\n // close main dropdown if open\r\n if (this.open) {\r\n this.dropdownPopover.closePopover(\"api\");\r\n }\r\n\r\n this.hiddenPopover.toggle();\r\n }\r\n\r\n\r\n renderHiddenChipsDropdown() {\r\n return html`\r\n <div\r\n class=\"hidden-chips-dropdown\"\r\n part=\"hidden-chips-dropdown\"\r\n popover=\"manual\"\r\n @toggle=${this.hiddenPopover.onToggle}\r\n @click=${(e: MouseEvent) => e.stopPropagation()}\r\n style=\"\r\n left: var(--sky-hc-left, 0px);\r\n top: var(--sky-hc-top, 0px);\r\n width: var(--sky-hc-width, max-content);\r\n z-index: ${this.zIndex};\r\n \"\r\n >\r\n ${repeat(\r\n this.selectedItems.slice(this.visibleChips),\r\n (item) => this.optionKey(item),\r\n (item) => html`\r\n <div class=\"hidden-chip-inner\" part=\"hidden-chip-inner\">\r\n <span part=\"hidden-chip-label\">\r\n ${this.renderSelectedLabel(\r\n item,\r\n this.selectedItems.indexOf(item),\r\n )}\r\n </span>\r\n <sky-icon\r\n part=\"remove-chip-icon\"\r\n class=\"remove-chip-inner\"\r\n icon=\"ion:close\"\r\n @click=${(e: MouseEvent) => {\r\n e.stopPropagation();\r\n this.removeChip(item);\r\n }}\r\n ></sky-icon>\r\n </div>\r\n `,\r\n )}\r\n </div>\r\n `;\r\n }\r\n\r\n removeChip(option: any) {\r\n if (this.disabled || this.readonly) return;\r\n\r\n const next = this.selectedItems.filter(\r\n (item) => this.optionKey(item) !== this.optionKey(option),\r\n );\r\n\r\n // 🚫 prevent going below 1 selection when enforced\r\n if (this.enforceMinOneSelection && next.length === 0) {\r\n return;\r\n }\r\n\r\n this.selectedItems = next;\r\n if (this.selectedItems.length <= this.visibleChips) {\r\n this.hiddenPopover.closePopover(\"api\");\r\n }\r\n\r\n if (this.multiSelect) {\r\n const valuesArray = this.selectedItems.map((opt) =>\r\n this.emitFullObject ? opt : this.getOptionValue(opt),\r\n );\r\n this.value = valuesArray;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent(\"value-changed\", {\r\n detail: {\r\n value: valuesArray,\r\n selectedItems: [...this.selectedItems],\r\n emittedValues: valuesArray,\r\n isFilteredSelection: false,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n } else {\r\n this.value = \"\";\r\n this.dispatchEvent(\r\n new CustomEvent(\"value-changed\", {\r\n detail: {\r\n value: this.value,\r\n selectedItems: [],\r\n isFilteredSelection: false,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n\r\n this.syncFormValue();\r\n this.syncValidity();\r\n this.validateInput();\r\n this.requestUpdate();\r\n }\r\n\r\n renderChips() {\r\n // Multi-select chips only — single-select uses value-summary (no chip padding)\r\n const visible = Array.isArray(this.selectedItems)\r\n ? this.selectedItems.slice(0, this.visibleChips)\r\n : [];\r\n const overflow = this.selectedItems.length - this.visibleChips;\r\n return html`\r\n ${repeat(\r\n visible,\r\n (item) => this.optionKey(item),\r\n (item, index) => html`\r\n <span class=\"chip\" ?compact=${this.compact} part=\"chip\">\r\n <span class=\"chip-label\" part=\"chip-label\"\r\n >${this.renderSelectedLabel(item, index)}</span\r\n >\r\n ${when(\r\n this.multiSelect,\r\n () => html`\r\n <sky-icon\r\n class=\"remove-chip\"\r\n part=\"remove-chip-icon\"\r\n ?compact=${this.compact}\r\n @click=${(e: MouseEvent) => {\r\n e.stopPropagation();\r\n this.removeChip(item);\r\n }}\r\n icon=\"ion:close\"\r\n ></sky-icon>\r\n `,\r\n )}\r\n </span>\r\n `,\r\n )}\r\n ${when(\r\n overflow > 0,\r\n () => html`\r\n <span\r\n class=\"chip overflow-chip\"\r\n part=\"overflow-chip\"\r\n style=\"cursor:pointer\"\r\n ?compact=${this.compact}\r\n @click=${this.toggleHiddenChips}\r\n >\r\n + ${overflow}\r\n </span>\r\n `,\r\n )}\r\n `;\r\n }\r\n\r\n private resolveMultiDisplay(): SkyComboboxMultiDisplay {\r\n const mode = this.multiDisplay;\r\n if (mode === \"text\" || mode === \"count\" || mode === \"chips\") return mode;\r\n return \"chips\";\r\n }\r\n\r\n /** Selected value area: chips, joined text, or count summary. */\r\n private renderSelectedValue() {\r\n if (!this.selectedItems.length) return null;\r\n\r\n // Single-select: plain text (no chip chrome / padding)\r\n if (!this.multiSelect) {\r\n const item = this.selectedItems[0];\r\n const label = String(this.getOptionLabel(item));\r\n return html`\r\n <span\r\n class=\"value-summary\"\r\n part=\"value-summary single-select-chip\"\r\n title=${label}\r\n >${this.renderSelectedSummaryLabel(item, 0)}</span\r\n >\r\n `;\r\n }\r\n\r\n const mode = this.resolveMultiDisplay();\r\n\r\n if (mode === \"text\") {\r\n const customRenderer = this.customRenderers?.selected;\r\n if (customRenderer) {\r\n return html`\r\n <span class=\"value-summary\" part=\"value-summary\">\r\n ${this.selectedItems.map(\r\n (item, index) => html`${index > 0 ? \", \" : \"\"}${customRenderer(\r\n item,\r\n this.buildSelectedRenderContext(item, index),\r\n )}`,\r\n )}\r\n </span>\r\n `;\r\n }\r\n const joined = this.selectedItems\r\n .map((item) => String(this.getOptionLabel(item)))\r\n .join(\", \");\r\n return html`\r\n <span class=\"value-summary\" part=\"value-summary\" title=${joined}\r\n >${joined}</span\r\n >\r\n `;\r\n }\r\n\r\n if (mode === \"count\") {\r\n const n = this.selectedItems.length;\r\n const first = String(this.getOptionLabel(this.selectedItems[0]));\r\n const summary = n === 1 ? first : `${first} +${n - 1}`;\r\n const title = this.selectedItems\r\n .map((item) => String(this.getOptionLabel(item)))\r\n .join(\", \");\r\n const customRenderer = this.customRenderers?.selected;\r\n if (customRenderer) {\r\n return html`\r\n <span class=\"value-summary\" part=\"value-summary\" title=${title}>\r\n ${customRenderer(\r\n this.selectedItems[0],\r\n this.buildSelectedRenderContext(this.selectedItems[0], 0),\r\n )}${n > 1 ? ` +${n - 1}` : nothing}\r\n </span>\r\n `;\r\n }\r\n return html`\r\n <span class=\"value-summary\" part=\"value-summary\" title=${title}\r\n >${summary}</span\r\n >\r\n `;\r\n }\r\n\r\n return html`\r\n <div class=\"chip-container\" part=\"chip-container\" ?compact=${this.compact}>\r\n ${this.renderChips()}\r\n </div>\r\n `;\r\n }\r\n\r\n handleKeydown(event: KeyboardEvent) {\r\n if ((event.target as HTMLElement)?.closest(\".search-container\")) return;\r\n const { key, shiftKey } = event;\r\n\r\n if (!this.open && (key === \"ArrowDown\" || key === \"ArrowUp\" || key === \"Enter\")) {\r\n this.dropdownPopover.openPopover();\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (!this.open) return;\r\n\r\n const hasSearchRow = this.searchable || this.addOption;\r\n const firstSelectableIndex =\r\n this.multiSelect && this.selectAll\r\n ? hasSearchRow\r\n ? 1\r\n : 0\r\n : this.headerRows;\r\n\r\n const minIndex = firstSelectableIndex;\r\n const maxIndex =\r\n this.headerRows + Math.max(0, this.filteredOptions.length) - 1;\r\n\r\n if (this.activeIndex < minIndex) this.activeIndex = minIndex;\r\n\r\n if (key === \"ArrowDown\") {\r\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\r\n this.activeIndex = was >= maxIndex ? minIndex : was + 1;\r\n this.scrollActiveItemIntoView();\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (key === \"ArrowUp\") {\r\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\r\n this.activeIndex = was <= minIndex ? maxIndex : was - 1;\r\n this.scrollActiveItemIntoView();\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (key === \"Tab\") {\r\n if (shiftKey) {\r\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\r\n this.activeIndex = was <= minIndex ? maxIndex : was - 1;\r\n } else {\r\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\r\n this.activeIndex = was >= maxIndex ? minIndex : was + 1;\r\n }\r\n this.scrollActiveItemIntoView();\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (key === \"Enter\") {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.commitDropdownEnter();\r\n return;\r\n }\r\n\r\n if (this.readonly) {\r\n if (key === \"Escape\") {\r\n this.open = false;\r\n event.preventDefault();\r\n }\r\n return;\r\n }\r\n\r\n if (key === \"Home\") {\r\n this.activeIndex = minIndex;\r\n this.scrollActiveItemIntoView();\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (key === \"End\") {\r\n this.activeIndex = Math.max(minIndex, maxIndex);\r\n this.scrollActiveItemIntoView();\r\n event.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n private onSearchKeydown = (e: KeyboardEvent) => {\r\n const { key, shiftKey } = e;\r\n\r\n if (key === \"Enter\") {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.commitDropdownEnter();\r\n return;\r\n }\r\n\r\n if (key === \"ArrowDown\" || key === \"ArrowUp\" || key === \"Tab\") {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n const hasSearchRow = this.searchable || this.addOption;\r\n const firstSelectableIndex =\r\n this.multiSelect && this.selectAll\r\n ? hasSearchRow\r\n ? 1\r\n : 0\r\n : this.headerRows;\r\n\r\n const minIndex = firstSelectableIndex;\r\n const maxIndex =\r\n this.headerRows + Math.max(0, this.filteredOptions.length) - 1;\r\n\r\n const dir = key === \"ArrowUp\" || (key === \"Tab\" && e.shiftKey) ? -1 : 1;\r\n if (this.activeIndex < minIndex) this.activeIndex = minIndex;\r\n else\r\n this.activeIndex =\r\n this.activeIndex + dir < minIndex\r\n ? maxIndex\r\n : this.activeIndex + dir > maxIndex\r\n ? minIndex\r\n : this.activeIndex + dir;\r\n\r\n this.scrollActiveItemIntoView();\r\n }\r\n\r\n if (key === \"Escape\") {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.dropdownPopover.closePopover(\"escape\");\r\n return;\r\n }\r\n };\r\n\r\n /** Number of non-option rows before the first option (search + select-all). */\r\n private get headerRows(): number {\r\n let n = 0;\r\n if (this.searchable || this.addOption) n += 1;\r\n if (this.multiSelect && this.selectAll) n += 1;\r\n return n;\r\n }\r\n\r\n\r\n private getOptionByActiveIndex(): {\r\n kind: \"search\" | \"select-all\" | \"option\";\r\n optionIndex?: number;\r\n } | null {\r\n if (!this.open) return null;\r\n const idx = this.activeIndex;\r\n if (idx < 0) return null;\r\n\r\n if (this.searchable || this.addOption) {\r\n if (idx === 0) return { kind: \"search\" };\r\n }\r\n\r\n const selectAllBase = this.searchable || this.addOption ? 1 : 0;\r\n if (this.multiSelect && this.selectAll && idx === selectAllBase) {\r\n return { kind: \"select-all\" };\r\n }\r\n\r\n const optionIndex = idx - this.headerRows;\r\n if (optionIndex >= 0 && optionIndex < this.filteredOptions.length) {\r\n return { kind: \"option\", optionIndex };\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Commits the current keyboard highlight on Enter (search row vs select-all vs option).\r\n * Shared by {@link handleKeydown} and {@link onSearchKeydown} so focus in the search\r\n * field matches the same semantics as the input wrapper.\r\n */\r\n private commitDropdownEnter(): void {\r\n const target = this.getOptionByActiveIndex();\r\n if (!target) return;\r\n\r\n if (target.kind === \"search\") {\r\n if (this.addOption && this.canAddaddOption()) {\r\n this.dispatchEvent(\r\n new CustomEvent(\"add-new-option\", {\r\n detail: { value: this.searchQuery.trim() },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.filterOptions();\r\n } else if (this.filteredOptions.length > 0) {\r\n this.selectOption(this.filteredOptions[0].original);\r\n }\r\n return;\r\n }\r\n if (target.kind === \"select-all\") {\r\n this.toggleSelectAll();\r\n return;\r\n }\r\n if (target.kind === \"option\" && typeof target.optionIndex === \"number\") {\r\n const selectedOption =\r\n this.filteredOptions[target.optionIndex].original;\r\n this.selectOption(selectedOption);\r\n }\r\n }\r\n\r\n /** Focus logic when opening the dropdown. */\r\n private focusOnOpen() {\r\n const search = this.searchInputEl;\r\n if (search && document.activeElement !== search) {\r\n requestAnimationFrame(() => search.focus());\r\n }\r\n\r\n // Highlight first selected option (or first option), not the search row —\r\n // so selected/active chrome is visible as soon as the list opens.\r\n if (this.filteredOptions.length > 0) {\r\n let optionIdx = 0;\r\n if (this.selectedItems.length > 0) {\r\n const firstSelKey = this.optionKey(this.selectedItems[0]);\r\n const idxInFiltered = this.filteredOptions.findIndex(\r\n (o) => this.optionKey(o.original) === firstSelKey,\r\n );\r\n if (idxInFiltered >= 0) optionIdx = idxInFiltered;\r\n }\r\n this.activeIndex = this.headerRows + optionIdx;\r\n this.scrollActiveItemIntoView();\r\n return;\r\n }\r\n\r\n this.activeIndex = this.searchable || this.addOption ? 0 : -1;\r\n }\r\n\r\n private canAddaddOption(): boolean {\r\n if (!this.addOption) return false;\r\n const q = this.searchQuery.trim();\r\n if (!q) return false;\r\n\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n const dup = optionsArray.some((opt) => {\r\n const label = String(this.getOptionLabel(opt) || \"\").toLowerCase();\r\n const val = (this.getOptionValue(opt) ?? \"\").toString().toLowerCase();\r\n return label === q.toLowerCase() || val === q.toLowerCase();\r\n });\r\n return !dup;\r\n }\r\n private handleAddaddOption = (e: MouseEvent) => {\r\n e.stopPropagation();\r\n if (this.disabled || this.readonly) return;\r\n if (!this.canAddaddOption()) return;\r\n\r\n const value = this.searchQuery.trim();\r\n\r\n this.dispatchEvent(\r\n new CustomEvent(\"add-new-option\", {\r\n detail: { value },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.filterOptions();\r\n };\r\n\r\n scrollActiveItemIntoView() {\r\n const rows = Array.from(this.rowEls);\r\n const active = rows.find(\r\n (r) => Number(r.dataset.rowIndex) === this.activeIndex,\r\n );\r\n active?.scrollIntoView({ block: \"nearest\", behavior: \"smooth\" });\r\n }\r\n\r\n toggleDropdown(event: MouseEvent) {\r\n event.stopPropagation();\r\n if (this.disabled || this.readonly) return;\r\n\r\n // close hidden chips if open\r\n if (this.hiddenChipsOpen) {\r\n this.hiddenPopover.closePopover(\"api\");\r\n }\r\n\r\n this.validationActive = true;\r\n this.dropdownPopover.toggle();\r\n }\r\n\r\n\r\n\r\n renderDropdown() {\r\n return html`\r\n <div\r\n class=\"dropdown\"\r\n part=\"dropdown\"\r\n popover=\"manual\"\r\n @toggle=${this.dropdownPopover.onToggle}\r\n @click=${(e: MouseEvent) => e.stopPropagation()}\r\n style=\"\r\n left: var(--sky-dd-left, 0px);\r\n top: var(--sky-dd-top, 0px);\r\n min-width: var(--sky-dd-width, 100%);\r\n \"\r\n >\r\n ${when(\r\n this.searchable || this.addOption,\r\n () => html`\r\n <div\r\n class=\"search-container\"\r\n data-row-index=\"0\"\r\n part=\"search-container\"\r\n >\r\n <sky-input\r\n class=\"dropdown-search-input\"\r\n compact\r\n clearable\r\n part=\"search-input\"\r\n tabindex=\"0\"\r\n ?readonly=${this.readonly ||\r\n (!this.searchable && !this.addOption)}\r\n ?disabled=${this.disabled}\r\n placeholder=${this.searchPlaceholder}\r\n .value=${this.searchQuery}\r\n @value-changed=${this.searchable || this.addOption\r\n ? this.handleSearchValueChanged\r\n : null}\r\n @value-cleared=${this.searchable || this.addOption\r\n ? this.handleSearchValueCleared\r\n : null}\r\n @keydown=${this.onSearchKeydown}\r\n @focus=${this.searchable || this.addOption\r\n ? this.handleFocus\r\n : null}\r\n @blur=${this.searchable || this.addOption\r\n ? this.handleBlur\r\n : null}\r\n >\r\n <sky-icon slot=\"icon-left\" icon=\"ion:search\"></sky-icon>\r\n </sky-input>\r\n\r\n ${when(\r\n this.addOption,\r\n () => html`\r\n <sky-icon\r\n class=\"new-option-btn\"\r\n icon=\"ion:add\"\r\n part=\"add-option-icon\"\r\n title=\"Add as new option\"\r\n aria-label=\"Add as new option\"\r\n @click=${this.handleAddaddOption}\r\n ></sky-icon>\r\n `,\r\n )}\r\n </div>\r\n `,\r\n )}\r\n\r\n<div class=\"dropdown-scroller\">\r\n ${when(\r\n this.multiSelect && this.selectAll && this.filteredOptions.length,\r\n () => {\r\n const selectAllRowIndex = this.searchable || this.addOption ? 1 : 0;\r\n const selectAllClasses = classMap({\r\n \"dropdown-item\": true,\r\n active: this.activeIndex === selectAllRowIndex,\r\n selected: this.isAllFilteredSelected(),\r\n });\r\n return html`\r\n <div\r\n class=${selectAllClasses}\r\n data-row-index=${selectAllRowIndex}\r\n style=\"justify-content: ${this.justify};\"\r\n part=\"select-all\"\r\n @click=${this.toggleSelectAll}\r\n >\r\n <sky-checkbox\r\n .checked=${this.isAllFilteredSelected()}\r\n readonly\r\n ></sky-checkbox>\r\n Select All\r\n </div>\r\n `;\r\n },\r\n )}\r\n ${when(\r\n this.filteredOptions.length > 0,\r\n () => repeat(\r\n this.filteredOptions,\r\n ({ original, _idx }) => `${_idx}-${this.optionKey(original)}`,\r\n ({ original, highlighted, _idx }, index) => {\r\n const slotName = `option-${_idx}`;\r\n const hasSlot = this.optionSlotSet.has(slotName);\r\n\r\n const isSelected =\r\n Array.isArray(this.selectedItems) &&\r\n this.selectedItems.some(\r\n (item) => this.optionKey(item) === this.optionKey(original),\r\n );\r\n const rowIndex = this.headerRows + index;\r\n const isActive = rowIndex === this.activeIndex;\r\n const itemClasses = classMap({\r\n \"dropdown-item\": true,\r\n active: isActive,\r\n selected: isSelected,\r\n });\r\n\r\n return html`\r\n <div\r\n class=${itemClasses}\r\n data-row-index=${rowIndex}\r\n style=\"justify-content: ${this.justify};\"\r\n part=\"option\"\r\n @click=${() => this.selectOption(original)}\r\n @pointerenter=${() => {\r\n this.activeIndex = rowIndex;\r\n }}\r\n ?compact=${this.compact}\r\n >\r\n ${when(\r\n this.multiSelect,\r\n () => html` <sky-checkbox\r\n .checked=${isSelected}\r\n readonly\r\n ></sky-checkbox>`,\r\n )}\r\n ${this.renderOptionContent({\r\n option: original,\r\n index,\r\n sourceIndex: _idx,\r\n highlighted,\r\n selected: isSelected,\r\n active: isActive,\r\n hasSlot,\r\n slotName,\r\n })}\r\n </div>\r\n `;\r\n },\r\n ),\r\n () => html`<div\r\n class=\"dropdown-item\"\r\n part=\"no-options\"\r\n data-row-index=${this.headerRows}\r\n >\r\n No options found\r\n </div>`,\r\n )}\r\n </div>\r\n </div>\r\n `;\r\n }\r\n\r\n\r\n getOptionValue(option: any): any {\r\n if (this.emitFullObject) {\r\n return option; // Return the full object\r\n }\r\n\r\n // When emitFullObject is false, return the emittedKey value\r\n if (typeof option === \"object\" && option !== null) {\r\n // First try the emittedKey\r\n if (this.emittedKey in option) {\r\n return option[this.emittedKey];\r\n }\r\n // Fallback to any value property\r\n if (\"value\" in option) {\r\n return option.value;\r\n }\r\n // Fallback to the object itself\r\n return option;\r\n }\r\n\r\n return option;\r\n }\r\n\r\n /**\r\n * Stable string key for comparing options / selection identity.\r\n * Prefer `emittedKey` when present on object options; for other objects use\r\n * JSON.stringify — never String(object) (\"[object Object]\"), which makes every\r\n * option look selected when `emitFullObject` is true.\r\n */\r\n private optionKey(option: any): string {\r\n if (option == null) return String(option);\r\n\r\n if (typeof option === \"object\") {\r\n if (this.emittedKey && this.emittedKey in option) {\r\n const keyVal = option[this.emittedKey];\r\n return typeof keyVal === \"object\" && keyVal !== null\r\n ? JSON.stringify(keyVal)\r\n : String(keyVal);\r\n }\r\n\r\n const val = this.getOptionValue(option);\r\n if (typeof val === \"object\" && val !== null) {\r\n return JSON.stringify(val);\r\n }\r\n return String(val ?? \"\");\r\n }\r\n\r\n return String(option);\r\n }\r\n\r\n getOptionLabel(option: any): string {\r\n if (!option) return \"\";\r\n\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n if (\r\n this.displayKey &&\r\n typeof option === \"object\" &&\r\n option[this.displayKey]\r\n ) {\r\n return String(option[this.displayKey]);\r\n }\r\n\r\n if (typeof option === \"object\") {\r\n const stringValues = Object.values(option).filter(\r\n (value) => typeof value === \"string\",\r\n ) as string[];\r\n return stringValues.length > 0 ? stringValues[0]! : JSON.stringify(option);\r\n }\r\n\r\n return String(option);\r\n }\r\n\r\n renderValidationErrors() {\r\n if (!this.showErrors || !this.validationActive) return null;\r\n\r\n const msgs = this.getErrorMessages();\r\n\r\n if (!msgs.length) return null;\r\n\r\n const errId = `${this.id || \"sky-combobox\"}-errors`;\r\n\r\n return html`\r\n <div class=\"progress-message\">\r\n <ul id=${errId} class=\"error-list\" part=\"error-list\">\r\n ${repeat(msgs, (m) => m, (m) => html`<li class=\"error\" part=\"error-item\">${m}</li>`)}\r\n </ul>\r\n </div>\r\n `;\r\n }\r\n\r\n getErrorMessages() {\r\n const errs = Array.isArray(this.validationErrors)\r\n ? this.validationErrors\r\n : [];\r\n switch (this.errorDisplayMode) {\r\n case \"single\":\r\n return errs.slice(0, 1);\r\n case \"all\":\r\n return errs;\r\n case \"none\":\r\n default:\r\n return [];\r\n }\r\n }\r\n\r\n handleIconClick(position: \"left\" | \"right\", event: MouseEvent) {\r\n this.dispatchEvent(\r\n new CustomEvent(\"icon-click\", {\r\n detail: { position, event },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n\r\n private onIconSlotChange = () => {\r\n this.hasLeftIcon = (this.iconLeftEls?.length ?? 0) > 0;\r\n this.hasRightIcon = (this.iconRightEls?.length ?? 0) > 0;\r\n };\r\n\r\n override render() {\r\n const leftIconClasses = classMap({ \"icon-slot\": true, left: true, focused: this.focused });\r\n const rightIconClasses = classMap({ \"icon-slot\": true, right: true, focused: this.focused });\r\n const placeholderClasses = classMap({\r\n \"placeholder-label\": true,\r\n active: this.selectedItems.length > 0,\r\n });\r\n\r\n const isFieldset = this.variant === \"fieldset\";\r\n const isInside = this.variant === \"inside\";\r\n const labelEl = this.label\r\n ? isFieldset\r\n ? html`<legend class=\"label\" part=\"label\"><span class=\"legend-text\">${this.label}</span></legend>`\r\n : html`<div class=\"label\" part=\"label\">${this.label}</div>`\r\n : null;\r\n\r\n const leftIcon = html`\r\n <div\r\n class=${leftIconClasses}\r\n part=\"icon-slot\"\r\n ?filled=${this.hasLeftIcon}\r\n @click=${(e: MouseEvent) => this.handleIconClick(\"left\", e)}\r\n >\r\n <slot name=\"icon-left\" @slotchange=${this.onIconSlotChange}></slot>\r\n </div>\r\n `;\r\n\r\n const valueArea = when(\r\n this.selectedItems.length > 0,\r\n () => this.renderSelectedValue(),\r\n () => html`<label\r\n class=${placeholderClasses}\r\n part=\"placeholder-label\"\r\n ?compact=${this.compact}\r\n >\r\n <span style=\"color:${this.prefixColor}\">${this.prefix}</span\r\n >${this.placeholder}<span style=\"color:${this.suffixColor}\"\r\n >${this.suffix}</span\r\n >\r\n </label>`,\r\n );\r\n\r\n const trailingActions = html`\r\n <div class=\"field-trailing\" part=\"field-trailing\">\r\n ${when(\r\n this.clearable &&\r\n !this.enforceMinOneSelection &&\r\n (this.value || this.selectedItems.length),\r\n () => html`<sky-icon\r\n class=\"clear-button\"\r\n part=\"clear-button\"\r\n ?compact=${this.compact}\r\n @click=${(e: MouseEvent) => {\r\n e.stopPropagation();\r\n this.handleClear();\r\n }}\r\n ?loading=${this.loading}\r\n icon=\"ion:close\"\r\n ></sky-icon>`,\r\n )}\r\n ${when(\r\n this.loading,\r\n () => html`<div class=\"loading-indicator right\"></div>`,\r\n () =>\r\n this.hasRightIcon\r\n ? html`<div\r\n part=\"icon-slot\"\r\n class=${rightIconClasses}\r\n ?filled=${true}\r\n @click=${(e: MouseEvent) => this.handleIconClick(\"right\", e)}\r\n >\r\n <slot\r\n name=\"icon-right\"\r\n @slotchange=${this.onIconSlotChange}\r\n ></slot>\r\n </div>`\r\n : html`<slot\r\n name=\"icon-right\"\r\n style=\"display:none\"\r\n @slotchange=${this.onIconSlotChange}\r\n ></slot>`,\r\n )}\r\n <sky-icon\r\n class=\"dropdown-button\"\r\n part=\"dropdown-button\"\r\n ?compact=${this.compact}\r\n @click=${(e: MouseEvent) => {\r\n e.stopPropagation();\r\n if (!this.disabled && !this.readonly) {\r\n this.toggleDropdown(e);\r\n }\r\n }}\r\n icon=${this.open ? \"ion:ios-arrow-up\" : \"ion:chevron-down\"}\r\n >\r\n </sky-icon>\r\n </div>\r\n `;\r\n\r\n const defaultFieldContent = html`\r\n ${leftIcon}\r\n <div class=\"field-main\" part=\"field-main\">${valueArea}</div>\r\n ${this.readonly ? nothing : trailingActions}\r\n `;\r\n\r\n const insideFieldContent = html`\r\n ${leftIcon}\r\n <div class=\"input-inside-main\">\r\n ${labelEl}\r\n <div class=\"input-inside-row\">\r\n <div class=\"field-main\" part=\"field-main\">${valueArea}</div>\r\n </div>\r\n </div>\r\n ${this.readonly ? nothing : trailingActions}\r\n `;\r\n\r\n const fieldBody = isInside ? insideFieldContent : defaultFieldContent;\r\n\r\n const wrapperHandlers = {\r\n click: (e: MouseEvent) => {\r\n if (!this.disabled && !this.readonly) {\r\n this.toggleDropdown(e);\r\n }\r\n },\r\n keydown: this.handleKeydown,\r\n };\r\n\r\n const fieldWrapper = isFieldset\r\n ? html`\r\n <fieldset\r\n class=\"input-wrapper\"\r\n tabindex=\"0\"\r\n part=\"input-wrapper\"\r\n ?disabled=${this.disabled}\r\n ?compact=${this.compact}\r\n ?loading=${this.loading}\r\n ?open=${this.open}\r\n ?invalid=${this.invalid}\r\n @click=${wrapperHandlers.click}\r\n @keydown=${wrapperHandlers.keydown}\r\n >\r\n ${labelEl}\r\n <div class=\"input-fieldset-body\">${fieldBody}</div>\r\n </fieldset>\r\n `\r\n : html`\r\n <div\r\n class=\"input-wrapper\"\r\n tabindex=\"0\"\r\n part=\"input-wrapper\"\r\n ?disabled=${this.disabled}\r\n ?compact=${this.compact}\r\n ?loading=${this.loading}\r\n ?open=${this.open}\r\n ?invalid=${this.invalid}\r\n @click=${wrapperHandlers.click}\r\n @keydown=${wrapperHandlers.keydown}\r\n >\r\n ${fieldBody}\r\n </div>\r\n `;\r\n\r\n return html`\r\n <div class=\"combo-box-container\" part=\"combo-box-container\">\r\n ${!isFieldset && !isInside ? labelEl : nothing}\r\n ${fieldWrapper}\r\n ${this.renderHiddenChipsDropdown()} ${this.renderDropdown()}\r\n ${this.renderValidationErrors()}\r\n <slot style=\"display:none\" @slotchange=${this.refreshOptionSlots}></slot>\r\n </div>\r\n `;\r\n }\r\n}\r\n"],"names":["COMBOBOX_RENDERERS_STATE_KEY","extractComboboxRendererState","customRenderers","bag","value","Array","isArray","o","option","selected","isComboboxRendererStateBag","SkyCombobox","FormControlBase","constructor","super","this","placeholder","searchPlaceholder","label","_options","chipSize","color","clearable","loading","compact","disabled","searchable","multiSelect","visibleChips","selectAll","_validations","showErrors","errorDisplayMode","required","emitFullObject","emittedKey","displayKey","_customRenderers","addOption","validationArrayFormat","prefix","suffix","prefixColor","suffixColor","justify","zIndex","height","requiredMessage","readonly","enforceMinOneSelection","openAbove","validationActive","invalid","variant","multiDisplay","searchQuery","filteredOptions","focused","open","selectedItems","hiddenChipsOpen","activeIndex","validationErrors","validationStatus","hasLeftIcon","hasRightIcon","optionSlotSet","Set","_rendererRuntimeState","_searchDebounceId","_closeResetId","dropdownPopover","PopoverController","getAnchor","inputWrapperEl","getPopover","dropdownEl","cssVarLeft","cssVarTop","cssVarWidth","getPlacement","getAlign","getGap","getPadding","getMatchAnchorWidth","getMaxWidthToViewport","getMaxWidthMode","getFlip","getFlipOrder","getAnimateReposition","getRepositionMs","getCloseOnEscape","getCloseOnOutside","getRestoreFocusOnClose","onOpenChange","meta","clearTimeout","filterOptions","requestAnimationFrame","focusOnOpen","setTimeout","emitSearchQueryChanged","_CLOSE_RESET_MS","hiddenPopover","closePopover","overflowChipEl","hiddenDropdownEl","preset","_presets","PresetController","refreshOptionSlots","set","querySelectorAll","forEach","el","slotName","slot","add","onSearchKeydown","e","key","shiftKey","preventDefault","stopPropagation","commitDropdownEnter","hasSearchRow","minIndex","headerRows","maxIndex","Math","max","length","dir","scrollActiveItemIntoView","handleAddaddOption","canAddaddOption","trim","dispatchEvent","CustomEvent","detail","bubbles","composed","onIconSlotChange","iconLeftEls","iconRightEls","captureDefaultValue","options","old","requestUpdate","validations","connectedCallback","hasAttribute","tabIndex","firstUpdated","refreshTargets","getFormValue","name","formData","FormData","item","JSON","stringify","String","getOptionValue","append","setValueFromFormState","state","values","getAll","parsed","parse","setValueFromArray","stringValue","get","toString","syncSelectedItemsWithValue","syncFormValue","internals","setFormValue","v","optionsArray","filter","optionValue","optionValueString","some","parsedValue","map","getValidityAnchor","isEmpty","getNativeControl","getCustomErrorMessage","onFormReset","onFormDisabled","onFormStateRestore","toggleSelectAll","isAllFilteredSelected","filteredKeys","opt","optionKey","original","nextSelected","has","selectedKeys","additions","valuesArray","emittedValues","isFilteredSelection","syncValidity","every","truncateText","text","maxLength","slice","validateInput","target","push","res","errors","validateForForm","focus","searchInputEl","blur","handleFocus","reset","openDropdown","openPopover","closeDropdown","clearSelection","handleClear","handleBlur","updated","changedProperties","style","setProperty","resolveColor","willUpdate","syncRendererStateFromProp","patchRendererState","patch","fromProp","rendererStateApi","rendererState","buildOptionRenderContext","args","index","sourceIndex","getOptionLabel","highlightedLabel","active","buildSelectedRenderContext","resolveMultiDisplay","renderOptionContent","defaultLabel","html","unsafeHTML","highlighted","hasSlot","customRenderer","content","renderSelectedLabel","renderSelectedSummaryLabel","isEmptyMulti","_","raw","providedKeys","targetValue","selectedOption","find","makeRow","idx","_idx","query","toLowerCase","row","includes","regex","RegExp","replace","m","handleSearchValueChanged","event","applySearchQuery","handleSearchValueCleared","optionsLength","shouldDebounce","_SEARCH_DEBOUNCE_OPTIONS_THRESHOLD","applyFilter","_SEARCH_DEBOUNCE_MS","disconnectedCallback","hasSelection","selectOption","getEmittedValue","wasFiltered","alreadySelected","findIndex","toggleHiddenChips","toggle","renderHiddenChipsDropdown","onToggle","repeat","indexOf","removeChip","next","renderChips","visible","overflow","when","mode","renderSelectedValue","joined","join","n","first","summary","title","nothing","handleKeydown","closest","was","getOptionByActiveIndex","kind","selectAllBase","optionIndex","search","document","activeElement","optionIdx","firstSelKey","idxInFiltered","q","val","from","rowEls","r","Number","dataset","rowIndex","scrollIntoView","block","behavior","toggleDropdown","renderDropdown","selectAllRowIndex","selectAllClasses","classMap","isSelected","isActive","itemClasses","keyVal","stringValues","Object","renderValidationErrors","msgs","getErrorMessages","errId","id","errs","handleIconClick","position","render","leftIconClasses","left","rightIconClasses","right","placeholderClasses","isFieldset","isInside","labelEl","leftIcon","valueArea","trailingActions","defaultFieldContent","insideFieldContent","fieldBody","wrapperHandlers","fieldWrapper","dependencies","SkyIcon","SkyCheckbox","SkyInput","styles","css","unsafeCSS","cssOnFillEnhance","selector","fillVar","property","shadowRootOptions","LitElement","delegatesFocus","__decorateClass","prototype","type","Boolean","reflect","attribute","queryAll","queryAssignedElements","customElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sky-combobox.js","sources":["../../src/sky-combobox/sky-combobox.ts"],"sourcesContent":["import { LitElement, html, css, nothing, PropertyValues, unsafeCSS } from \"lit\";\r\nimport { property, customElement, query, queryAll, queryAssignedElements, state } from \"lit/decorators.js\";\r\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\r\nimport { when } from \"lit/directives/when.js\";\r\nimport { repeat } from \"lit/directives/repeat.js\";\r\nimport { classMap } from \"lit/directives/class-map.js\";\r\nimport { resolveColor } from \"../helper/utils/color-resolver\";\r\nimport { cssOnFillEnhance } from \"../helper/utils/contrast-color\";\r\nimport { PopoverController } from \"../helper/controllers/popover-controller\";\r\nimport {\r\n FormControlBase,\r\n FormState,\r\n} from \"../helper/internals/form-control-base\";\r\nimport { SkyIcon } from \"../sky-icon/sky-icon.js\";\r\nimport { SkyCheckbox } from \"../sky-checkbox/sky-checkbox.js\";\r\nimport { SkyInput } from \"../sky-input/sky-input.js\";\r\nimport { PresetController } from \"../helper/controllers/preset-controller\";\r\nimport {\r\n arrayPropHasChanged,\r\n coerceArray,\r\n EMPTY_ARRAY,\r\n} from \"../helper/utils/stable-array\";\r\n\r\nexport type SkyComboboxJustify =\r\n | \"flex-start\"\r\n | \"center\"\r\n | \"flex-end\"\r\n | \"space-between\"\r\n | \"space-around\"\r\n | \"space-evenly\";\r\nexport type SkyComboboxErrorDisplayMode = \"single\" | \"all\" | \"none\";\r\nexport type SkyComboboxIconPosition = \"left\" | \"right\";\r\n/** How multi-select values render in the field (single-select always uses plain text). */\r\nexport type SkyComboboxMultiDisplay = \"chips\" | \"text\" | \"count\";\r\nexport type SkyComboboxValueChangedDetail = {\r\n value: any | any[];\r\n selectedItems: any[];\r\n emittedValues?: any | any[];\r\n isFilteredSelection?: boolean;\r\n};\r\nexport type SkyComboboxSearchQueryChangedDetail = { searchQuery: string };\r\nexport type SkyComboboxValidationErrorDetail = { errors: string[] };\r\nexport type SkyComboboxValidationSuccessDetail = { value: any };\r\nexport type SkyComboboxIconClickDetail = {\r\n position: SkyComboboxIconPosition;\r\n event: MouseEvent;\r\n};\r\nexport type SkyComboboxAddNewOptionDetail = { value: string };\r\n\r\n/** Reserved key on `customRenderers` for renderer UI state (not an option renderer). */\r\nexport const COMBOBOX_RENDERERS_STATE_KEY = \"$rendererState\";\r\n\r\nexport type SkyComboboxRendererStateApi = {\r\n rendererState: Readonly<Record<string, unknown>>;\r\n patchRendererState: (patch: Record<string, unknown>) => void;\r\n};\r\n\r\nexport type SkyComboboxOptionRenderContext = SkyComboboxRendererStateApi & {\r\n /** Index within the currently filtered dropdown list. */\r\n index: number;\r\n /** Index in the original `options` array. */\r\n sourceIndex: number;\r\n /** Plain display label (no highlight markup). */\r\n label: string;\r\n /** Search-highlighted label HTML string (same as default option text). */\r\n highlightedLabel: string;\r\n selected: boolean;\r\n /** Keyboard / pointer active row. */\r\n active: boolean;\r\n multiSelect: boolean;\r\n};\r\n\r\nexport type SkyComboboxSelectedRenderContext = SkyComboboxRendererStateApi & {\r\n selectedItems: any[];\r\n /** Index within `selectedItems`. */\r\n index: number;\r\n multiSelect: boolean;\r\n multiDisplay: SkyComboboxMultiDisplay;\r\n /** Default plain label for this option. */\r\n label: string;\r\n};\r\n\r\nexport type SkyComboboxOptionRenderer = (\r\n option: unknown,\r\n ctx: SkyComboboxOptionRenderContext,\r\n) => unknown;\r\n\r\nexport type SkyComboboxSelectedRenderer = (\r\n option: unknown,\r\n ctx: SkyComboboxSelectedRenderContext,\r\n) => unknown;\r\n\r\nexport type SkyComboboxCustomRenderers = {\r\n /** Custom dropdown option row content (host keeps checkbox / selected chrome). */\r\n option?: SkyComboboxOptionRenderer;\r\n /** Custom selected-value / chip label content. */\r\n selected?: SkyComboboxSelectedRenderer;\r\n [COMBOBOX_RENDERERS_STATE_KEY]?: Record<string, unknown>;\r\n};\r\n\r\n/** Shared empty sentinel so null/undefined rebinds do not look like a new value. */\r\nconst EMPTY_RENDERERS: SkyComboboxCustomRenderers = Object.freeze({});\r\n\r\nfunction samePrimitiveArray(a: unknown[], b: unknown[]): boolean {\r\n if (a === b) return true;\r\n if (a.length !== b.length) return false;\r\n for (let i = 0; i < a.length; i++) {\r\n if (a[i] !== b[i]) return false;\r\n }\r\n return true;\r\n}\r\n\r\nfunction isComboboxRendererStateBag(\r\n value: unknown,\r\n): value is Record<string, unknown> {\r\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) {\r\n return false;\r\n }\r\n const o = value as Record<string, unknown>;\r\n return typeof o.option !== \"function\" && typeof o.selected !== \"function\";\r\n}\r\n\r\nfunction extractComboboxRendererState(\r\n customRenderers: SkyComboboxCustomRenderers | null | undefined,\r\n): Record<string, unknown> {\r\n const bag = customRenderers?.[COMBOBOX_RENDERERS_STATE_KEY];\r\n return isComboboxRendererStateBag(bag) ? { ...bag } : {};\r\n}\r\n\r\n/**\r\n * @element sky-combobox\r\n *\r\n * @summary Interactive combobox with single/multi select, search, chips, validation, and popover-based option selection.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/combobox\r\n * @dependency sky-icon\r\n * @dependency sky-checkbox\r\n * @dependency sky-input\r\n *\r\n * @uiVModel value value-changed\r\n * @uiVModel searchQuery search-query-changed\r\n *\r\n * @slot icon-left - Slot for the left icon in the combobox (e.g., search icon).\r\n * @slot icon-right - Slot for the right icon in the combobox (e.g., dropdown icon).\r\n * @slot - Default slot for adding custom options or content.\r\n *\r\n * @csspart combo-box-container - The main container element wrapping the entire component\r\n * @csspart input-wrapper - The input field wrapper that contains chips, icons, and dropdown button\r\n * @csspart icon-slot - Both left and right icon containers\r\n * @csspart placeholder-label - The placeholder text label\r\n * @csspart clear-button - The clear (×) button\r\n * @csspart field-trailing - Trailing actions rail (clear, right icon, chevron)\r\n * @csspart dropdown-button - The dropdown toggle arrow button\r\n * @csspart chip-container - Container for the chips in multi-select mode\r\n * @csspart value-summary - Multi-select text/count summary (when `multi-display` is `text` or `count`)\r\n * @csspart chip - Individual chip element\r\n * @csspart single-select-chip - Chip shown in single-select mode\r\n * @csspart overflow-chip - The \"+N\" chip that shows hidden chips count\r\n * @csspart remove-chip-icon - The remove icon within chips\r\n * @csspart hidden-chips-dropdown - Dropdown that appears when clicking overflow chip\r\n * @csspart hidden-chip-inner - Individual chip in the hidden chips dropdown\r\n * @csspart hidden-chip-label - Label text in hidden chips dropdown\r\n * @csspart dropdown - The main dropdown container\r\n * @csspart search-container - Container for the search input in the dropdown\r\n * @csspart search-input - The search input field\r\n * @csspart add-option-icon - The \"+\" icon for adding new options\r\n * @csspart select-all - The \"Select All\" row in the dropdown\r\n * @csspart checkbox - Checkbox elements in multi-select mode\r\n * @csspart option - Individual option row in the dropdown\r\n * @csspart highlighted-text - Highlighted text in search results\r\n * @csspart no-options - \"No options found\" message\r\n * @csspart error-list - Container for validation error messages\r\n * @csspart error-item - Individual validation error message\r\n * @csspart dropdown-scroller - Scrollable container for dropdown options\r\n * @csspart chip-label - Label text within chips\r\n *\r\n * @fires {CustomEvent<SkyComboboxValueChangedDetail>} value-changed - Fired whenever selection changes.\r\n * @fires {CustomEvent<SkyComboboxSearchQueryChangedDetail>} search-query-changed - Fired when search query changes.\r\n * @fires {CustomEvent<SkyComboboxValidationErrorDetail>} validation-error - Fired when validation fails.\r\n * @fires {CustomEvent<SkyComboboxValidationSuccessDetail>} validation-success - Fired when validation passes.\r\n * @fires {CustomEvent<SkyComboboxIconClickDetail>} icon-click - Fired when icon slot is clicked.\r\n * @fires {CustomEvent<SkyComboboxAddNewOptionDetail>} add-new-option - Fired when user confirms adding a new option.\r\n *\r\n * @property {any} value - Current selection value (single) or value array (multi).\r\n * @property {string} placeholder - Main placeholder text.\r\n * @property {string} searchPlaceholder - Search input placeholder text.\r\n * @property {string} searchQuery - Current search filter text when `searchable` is enabled. Default: `\"\"`.\r\n * @property {any[]} options - Available options list.\r\n * @property {boolean} searchable - Enables search input and filtering.\r\n * @property {boolean} addOption - Enables ad-hoc option creation from search query.\r\n * @property {boolean} multiSelect - Enables multi-select chip behavior.\r\n * @property {boolean} selectAll - Shows select-all row in eligible modes.\r\n * @property {boolean} clearable - Shows clear button when value exists.\r\n * @property {boolean} loading - Shows loading affordance.\r\n * @property {boolean} compact - Enables compact sizing.\r\n * @property {boolean} disabled - Disables interaction.\r\n * @property {boolean} required - Enables required validation.\r\n * @property {boolean} readonly - Enables read-only mode.\r\n * @property {boolean} emitFullObject - Emits full option objects in events.\r\n * @property {string} emittedKey - Key emitted from object options when `emitFullObject` is false.\r\n * @property {string} displayKey - Key used for visual labels in object options.\r\n * @property {SkyComboboxCustomRenderers} customRenderers - Named renderers: `option` (dropdown row), `selected` (value/chip label), optional `$rendererState`.\r\n * @property {number} visibleChips - Number of visible chips before `+N` overflow chip.\r\n * @property {number} chipSize - Maximum label length for each chip.\r\n * @property {string} color - Accent color token/CSS color.\r\n * @property {number} zIndex - Dropdown overlay z-index.\r\n * @property {string} height - Max dropdown scroll height.\r\n * @property {boolean} openAbove - Opens dropdown above when true.\r\n * @property {SkyComboboxJustify} justify - Option-row content justification.\r\n * @property {boolean} showErrors - Renders validation errors below control.\r\n * @property {SkyComboboxErrorDisplayMode} errorDisplayMode - Validation error rendering strategy.\r\n * @property {(value:any)=>true|string} validations - External validator callbacks.\r\n * @property {boolean} validationArrayFormat - Sends selected array into validators when true.\r\n * @property {string} prefix - Optional inline prefix text.\r\n * @property {string} suffix - Optional inline suffix text.\r\n * @property {string} prefixColor - Prefix color value.\r\n * @property {string} suffixColor - Suffix color value.\r\n * @property {string} requiredMessage - Required validation failure text.\r\n * @property {boolean} enforceMinOneSelection - Prevents clearing all selections in multi-select mode.\r\n * @property {boolean} validationActive - Enables validation UI state.\r\n * @property {boolean} invalid - Reflects invalid state.\r\n * @property {string} variant - Visual style: `default`, `highlight`, `fieldset`, or `inside`.\r\n * @property {string} label - Label text. Above the field by default; on the border for `fieldset`; inside the field for `inside`.\r\n * @property {SkyComboboxMultiDisplay} multiDisplay - Multi-select value UI: `chips` (default), `text` (comma-joined), or `count` (“N selected”).\r\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\r\n *\r\n * @method openDropdown Opens the combobox dropdown.\r\n * @method closeDropdown Closes the combobox dropdown.\r\n * @method clearSelection Clears current selection if allowed.\r\n * @method reset Resets combobox state and clears validation UI.\r\n * @method patchRendererState Merges keys into `customRenderers.$rendererState` and re-renders.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-combobox label=\"Assignee\" searchable clearable placeholder=\"Select user\"></sky-combobox>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-combobox label=\"Assignee\" searchable clearable placeholder=\"Select user\"></sky-combobox>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return <sky-combobox label=\"Assignee\" searchable clearable placeholder=\"Select user\"></sky-combobox>;\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-combobox\")\r\nexport class SkyCombobox extends FormControlBase {\r\n\r\n static dependencies: Record<string, CustomElementConstructor> = {\r\n \"sky-icon\": SkyIcon,\r\n \"sky-checkbox\": SkyCheckbox,\r\n \"sky-input\": SkyInput,\r\n };\r\n\r\n /** Current value. Set via attribute in HTML (e.g. value=\"option-1\") or via JS (string or array when multiSelect). Not reflected when set to array from JS. */\r\n @property() value: any = \"\";\r\n @property({ type: String }) placeholder: string = \"Select An Option\";\r\n @property({ type: String }) searchPlaceholder: string = \"Search...\";\r\n @property({ type: String }) label: string = \"\";\r\n private _options: any[] = EMPTY_ARRAY;\r\n @property({ type: Array, hasChanged: arrayPropHasChanged })\r\n get options(): any[] {\r\n return this._options;\r\n }\r\n set options(value: any[] | null | undefined) {\r\n this._options = coerceArray(value);\r\n }\r\n @property({ type: Number }) chipSize: number = 20;\r\n @property({ type: String }) color: string = \"primary\";\r\n @property({ type: Boolean, reflect: true }) clearable: boolean = false;\r\n @property({ type: Boolean, reflect: true }) loading: boolean = false;\r\n @property({ type: Boolean, reflect: true }) compact: boolean = false;\r\n @property({ type: Boolean, reflect: true }) override disabled: boolean = false;\r\n @property({ type: Boolean, reflect: true }) searchable: boolean = false;\r\n @property({ type: Boolean, reflect: true }) multiSelect: boolean = false;\r\n @property({ type: Number, reflect: true }) visibleChips: number = 2;\r\n @property({ type: Boolean, reflect: true }) selectAll: boolean = false;\r\n private _validations: ((value: any) => true | string)[] = EMPTY_ARRAY;\r\n @property({ type: Array, hasChanged: arrayPropHasChanged })\r\n get validations(): ((value: any) => true | string)[] {\r\n return this._validations;\r\n }\r\n set validations(value: ((value: any) => true | string)[] | null | undefined) {\r\n this._validations = coerceArray(value);\r\n }\r\n @property({ type: Boolean }) showErrors: boolean = false;\r\n @property({ type: String }) errorDisplayMode: SkyComboboxErrorDisplayMode = \"single\";\r\n @property({ type: Boolean, reflect: true }) override required: boolean = false;\r\n @property({ type: Boolean, reflect: true }) emitFullObject: boolean = false;\r\n @property({ type: String }) emittedKey: string = \"value\";\r\n @property({ type: String }) displayKey: string = \"\";\r\n private _customRenderers: SkyComboboxCustomRenderers = EMPTY_RENDERERS;\r\n /**\r\n * Named custom renderers for option rows and selected-value labels.\r\n * Coerces null/undefined to `{}` for safe framework binding.\r\n */\r\n @property({ type: Object })\r\n get customRenderers(): SkyComboboxCustomRenderers {\r\n return this._customRenderers;\r\n }\r\n set customRenderers(value: SkyComboboxCustomRenderers | null | undefined) {\r\n this._customRenderers =\r\n value != null && typeof value === \"object\" && !Array.isArray(value)\r\n ? value\r\n : EMPTY_RENDERERS;\r\n }\r\n @property({ type: Boolean }) addOption: boolean = false;\r\n @property({ type: Boolean }) validationArrayFormat: boolean = false;\r\n @property({ type: String }) override prefix: string = \"\";\r\n @property({ type: String }) suffix: string = \"\";\r\n @property({ type: String }) prefixColor: string = \"\";\r\n @property({ type: String }) suffixColor: string = \"\";\r\n @property({ type: String }) justify: SkyComboboxJustify = \"flex-start\";\r\n @property({ type: Number }) zIndex: number = 11;\r\n @property({ type: String }) height: string = \"200px\";\r\n @property({ type: String }) override requiredMessage: string = \"Selection is required.\";\r\n @property({ type: Boolean, reflect: true }) override readonly: boolean = false;\r\n @property({ type: Boolean }) enforceMinOneSelection: boolean = false;\r\n @property({ type: Boolean }) openAbove: boolean = false;\r\n @property({ type: Boolean, reflect: true }) validationActive: boolean = false;\r\n @property({ type: Boolean, reflect: true }) invalid = false;\r\n @property({ type: String, reflect: true }) variant:\r\n | \"default\"\r\n | \"highlight\"\r\n | \"fieldset\"\r\n | \"inside\" = \"default\";\r\n /** Multi-select field presentation. Ignored for single-select. */\r\n @property({ type: String, reflect: true, attribute: \"multi-display\" })\r\n multiDisplay: SkyComboboxMultiDisplay = \"chips\";\r\n\r\n /** Current search filter when `searchable`; exposed for controlled search / `v-model:search-query`. */\r\n @property({ type: String, attribute: false }) searchQuery = \"\";\r\n @state() filteredOptions: any[] = [];\r\n @state() focused: boolean = false;\r\n @state() open: boolean = false;\r\n @state() selectedItems: any[] = [];\r\n @state() hiddenChipsOpen: boolean = false;\r\n @state() activeIndex: number = -1;\r\n @state() validationErrors: string[] = [];\r\n @state() validationStatus: any[] = [];\r\n @state() private hasLeftIcon = false;\r\n @state() private hasRightIcon = false;\r\n @state() private optionSlotSet = new Set<string>();\r\n private _rendererRuntimeState: Record<string, unknown> = {};\r\n\r\n @query(\".input-wrapper\") private inputWrapperEl!: HTMLElement;\r\n @query(\".dropdown\") private dropdownEl!: HTMLElement;\r\n @query(\".hidden-chips-dropdown\") private hiddenDropdownEl!: HTMLElement;\r\n @query(\".search-container sky-input\") private searchInputEl!: SkyInput;\r\n @query(\".overflow-chip\") private overflowChipEl!: HTMLElement;\r\n @query(\".combo-box-container\") private comboContainerEl!: HTMLElement;\r\n @queryAll(\"[data-row-index]\") private rowEls!: NodeListOf<HTMLElement>;\r\n @queryAssignedElements({ slot: \"icon-left\" }) private iconLeftEls!: HTMLElement[];\r\n @queryAssignedElements({ slot: \"icon-right\" }) private iconRightEls!: HTMLElement[];\r\n\r\n private _searchDebounceId: ReturnType<typeof setTimeout> | null = null;\r\n /** When true, skip willUpdate filtering so typing debounce can delay list work. */\r\n private _deferSearchFilter = false;\r\n private _closeResetId: ReturnType<typeof setTimeout> | null = null;\r\n private static readonly _SEARCH_DEBOUNCE_MS = 150;\r\n private static readonly _SEARCH_DEBOUNCE_OPTIONS_THRESHOLD = 30;\r\n /** Matches PopoverController exit animation so list stays visible while closing. */\r\n private static readonly _CLOSE_RESET_MS = 250;\r\n\r\n private dropdownPopover = new PopoverController(this, {\r\n getAnchor: () => this.inputWrapperEl,\r\n getPopover: () => this.dropdownEl,\r\n cssVarLeft: \"--sky-dd-left\",\r\n cssVarTop: \"--sky-dd-top\",\r\n cssVarWidth: \"--sky-dd-width\",\r\n getPlacement: () => 'bottom' as any,\r\n getAlign: () => \"start\" as any,\r\n getGap: () => 6,\r\n getPadding: () => 8,\r\n getMatchAnchorWidth: () => true,\r\n getMaxWidthToViewport: () => true,\r\n getMaxWidthMode: () => \"cap\" as any,\r\n getFlip: () => true,\r\n getFlipOrder: () => [],\r\n getAnimateReposition: () => true,\r\n getRepositionMs: () => 160,\r\n getCloseOnEscape: () => true,\r\n getCloseOnOutside: () => true,\r\n getRestoreFocusOnClose: () => true,\r\n onOpenChange: (open, meta) => {\r\n this.open = open;\r\n\r\n if (open) {\r\n this.focused = true;\r\n if (this._closeResetId != null) {\r\n clearTimeout(this._closeResetId);\r\n this._closeResetId = null;\r\n }\r\n this.validationActive = true;\r\n this.filterOptions();\r\n requestAnimationFrame(() => this.focusOnOpen());\r\n } else {\r\n this.activeIndex = -1;\r\n // Defer search reset so options stay populated during the close animation.\r\n if (this._closeResetId != null) clearTimeout(this._closeResetId);\r\n this._closeResetId = setTimeout(() => {\r\n this._closeResetId = null;\r\n if (this.open) return;\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.filterOptions();\r\n }, SkyCombobox._CLOSE_RESET_MS);\r\n\r\n // close hidden chips too\r\n this.hiddenChipsOpen = false;\r\n this.hiddenPopover.closePopover(\"api\");\r\n }\r\n },\r\n });\r\n\r\n private hiddenPopover = new PopoverController(this, {\r\n getAnchor: () => this.overflowChipEl,\r\n getPopover: () => this.hiddenDropdownEl,\r\n cssVarLeft: \"--sky-hc-left\",\r\n cssVarTop: \"--sky-hc-top\",\r\n cssVarWidth: \"--sky-hc-width\",\r\n getPlacement: () => \"bottom\" as any,\r\n getAlign: () => \"center\" as any,\r\n getGap: () => 4,\r\n getPadding: () => 8,\r\n getMatchAnchorWidth: () => false,\r\n getMaxWidthToViewport: () => true,\r\n getMaxWidthMode: () => \"cap\" as any,\r\n getFlip: () => true,\r\n getFlipOrder: () => [],\r\n getAnimateReposition: () => true,\r\n getRepositionMs: () => 120,\r\n getCloseOnEscape: () => true,\r\n getCloseOnOutside: () => true,\r\n getRestoreFocusOnClose: () => false,\r\n onOpenChange: (open) => {\r\n this.hiddenChipsOpen = open;\r\n\r\n // if opening hidden chips, close main dropdown\r\n if (open && this.open) {\r\n this.dropdownPopover.closePopover(\"api\");\r\n }\r\n },\r\n });\r\n\r\n\r\n /** Named prop preset from nearest `sky-config-provider`. */\r\n @property({ type: String, reflect: true }) preset = \"\";\r\n\r\n private _presets = new PresetController(this);\r\n\r\n static override styles = css`\r\n :host {\r\n display: block;\r\n font-family: var(--sky-font);\r\n width: 100%;\r\n --sky-input-height: 36px;\r\n --sky-input-height-compact: 28px;\r\n --sky-input-border-width: 1px;\r\n --sky-input-pad-x: var(--sky-space-3, 12px);\r\n --sky-input-pad-x-sm: var(--sky-space-1, 4px);\r\n --sky-input-pad-x-xs: 0px;\r\n --sky-input-pad-y: var(--sky-space-1, 4px);\r\n --sky-input-pad-y-sm: 0px;\r\n --sky-input-gap: var(--sky-space-1, 4px);\r\n --sky-input-icon-width: 2rem;\r\n }\r\n\r\n :host([compact]) {\r\n --sky-input-pad-x: var(--sky-space-2, 8px);\r\n --sky-input-pad-x-sm: var(--sky-space-1, 4px);\r\n --sky-input-icon-width: 1.75rem;\r\n }\r\n\r\n :host([compact]) .combo-box-container > .label {\r\n font-size: var(--sky-font-size-xs);\r\n margin-bottom: var(--sky-space-1, 4px);\r\n line-height: 1.2;\r\n }\r\n\r\n :host([compact]) .placeholder-label,\r\n :host([compact]) .chip[single-select] {\r\n font-size: var(--sky-font-size-sm);\r\n }\r\n\r\n :host([compact]) .icon-slot {\r\n font-size: var(--sky-font-size-lg);\r\n }\r\n\r\n :host([compact]) .clear-button,\r\n :host([compact]) .dropdown-button {\r\n font-size: var(--sky-font-size-md);\r\n }\r\n\r\n :host([disabled]) {\r\n pointer-events: none;\r\n opacity: var(--sky-opacity-disabled, 0.6);\r\n }\r\n\r\n :host([readonly]) .input-wrapper {\r\n cursor: default;\r\n }\r\n\r\n :host([variant=\"highlight\"]) .label {\r\n color: var(--sky-dropdown-color);\r\n }\r\n\r\n /* Fieldset / legend */\r\n :host([variant=\"fieldset\"]) {\r\n overflow: visible;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .combo-box-container {\r\n overflow: visible;\r\n /* Room for legend text sitting on the top border — keep off :host */\r\n padding-block-start: 0.65em;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) fieldset.input-wrapper {\r\n display: block;\r\n height: auto;\r\n margin: 0;\r\n min-inline-size: 0;\r\n min-width: 0;\r\n padding: 0;\r\n overflow: visible;\r\n background: var(--sky-glass-solid);\r\n box-shadow: none;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) fieldset.input-wrapper[compact] {\r\n height: auto;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .input-fieldset-body {\r\n display: flex;\r\n width: 100%;\r\n align-items: center;\r\n box-sizing: border-box;\r\n height: calc(\r\n var(--sky-input-height) - 2 * var(--sky-input-border-width)\r\n );\r\n min-height: calc(\r\n var(--sky-input-height) - 2 * var(--sky-input-border-width)\r\n );\r\n background: transparent;\r\n border-radius: inherit;\r\n flex-wrap: nowrap;\r\n min-width: 0;\r\n overflow: hidden;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) fieldset.input-wrapper[compact] .input-fieldset-body {\r\n height: calc(\r\n var(--sky-input-height-compact) - 2 * var(--sky-input-border-width)\r\n );\r\n min-height: calc(\r\n var(--sky-input-height-compact) - 2 * var(--sky-input-border-width)\r\n );\r\n }\r\n\r\n /* Multi chips: keep fieldset at input height; center chips in the body */\r\n :host([variant=\"fieldset\"]) .input-fieldset-body:has(.chip:not([single-select])) {\r\n height: calc(\r\n var(--sky-input-height) - 2 * var(--sky-input-border-width)\r\n );\r\n min-height: calc(\r\n var(--sky-input-height) - 2 * var(--sky-input-border-width)\r\n );\r\n align-items: center;\r\n padding-block: 0;\r\n }\r\n\r\n :host([variant=\"fieldset\"][compact])\r\n .input-fieldset-body:has(.chip:not([single-select])) {\r\n height: calc(\r\n var(--sky-input-height-compact) - 2 * var(--sky-input-border-width)\r\n );\r\n min-height: calc(\r\n var(--sky-input-height-compact) - 2 * var(--sky-input-border-width)\r\n );\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .input-fieldset-body:has(.chip:not([single-select])) .field-main,\r\n :host([variant=\"fieldset\"]) .input-fieldset-body:has(.chip:not([single-select])) .chip-container {\r\n align-self: stretch;\r\n height: 100%;\r\n min-height: 0;\r\n align-items: center;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) legend.label {\r\n float: unset;\r\n width: auto;\r\n max-width: calc(100% - 2 * var(--sky-input-pad-x));\r\n margin-inline-start: var(--sky-input-pad-x);\r\n margin-block: 0;\r\n padding-inline: var(--sky-input-pad-x-sm);\r\n padding-block: 0;\r\n border: none;\r\n background: transparent;\r\n background-color: transparent;\r\n color: var(--sky-text-secondary);\r\n font-size: var(--sky-font-size-xs);\r\n /* Take no in-flow space; inner text is centered on the border notch */\r\n height: 0;\r\n line-height: 0;\r\n overflow: visible;\r\n white-space: nowrap;\r\n pointer-events: none;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) legend.label .legend-text {\r\n display: inline-block;\r\n max-width: 100%;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n line-height: 1.2;\r\n transform: translateY(-50%);\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .combo-box-container:focus-within legend.label,\r\n :host([variant=\"fieldset\"]) .input-wrapper[open] legend.label {\r\n color: var(--sky-dropdown-color);\r\n font-size: var(--sky-font-size-xs);\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .input-wrapper::after {\r\n content: none;\r\n display: none;\r\n }\r\n\r\n :host([variant=\"fieldset\"]) .input-wrapper[open],\r\n :host([variant=\"fieldset\"]) .input-wrapper:focus-visible {\r\n border-color: var(--sky-dropdown-color);\r\n }\r\n\r\n :host([variant=\"fieldset\"][validationActive]:invalid) .input-wrapper {\r\n border-color: var(--sky-danger-primary);\r\n }\r\n\r\n :host([variant=\"fieldset\"][validationActive]:invalid) legend.label {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n :host([variant=\"fieldset\"][compact]) legend.label,\r\n :host([variant=\"fieldset\"][compact]) .combo-box-container:focus-within legend.label,\r\n :host([variant=\"fieldset\"][compact]) .input-wrapper[open] legend.label {\r\n font-size: var(--sky-font-size-xs);\r\n }\r\n\r\n /* Inside: label in the wrapper above value row — keep tokens in sync with sky-input */\r\n :host([variant=\"inside\"]) {\r\n --sky-input-height-inside: 40px;\r\n --sky-input-height-inside-compact: 36px;\r\n --sky-input-inside-label-block: 2px;\r\n --sky-input-inside-value-min: 1.15em;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-wrapper {\r\n height: auto;\r\n min-height: var(--sky-input-height-inside);\r\n align-items: center;\r\n padding-block: var(--sky-input-pad-y-sm, 0px);\r\n overflow: hidden;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-wrapper[compact] {\r\n height: auto;\r\n min-height: var(--sky-input-height-inside-compact);\r\n padding-block: var(--sky-input-pad-y-sm, 0px);\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-inside-main {\r\n flex: 1 1 0%;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n gap: 0;\r\n padding-block: var(--sky-input-inside-label-block);\r\n padding-inline: 0;\r\n overflow: hidden;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-inside-main > .label {\r\n margin: 0;\r\n padding-inline: var(--sky-input-pad-x);\r\n font-size: var(--sky-font-size-xs);\r\n line-height: 1.15;\r\n min-height: 0;\r\n color: var(--sky-text-secondary);\r\n pointer-events: none;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n flex: 0 0 auto;\r\n }\r\n\r\n :host([variant=\"inside\"][compact]) .input-inside-main > .label {\r\n font-size: 0.6875rem;\r\n line-height: 1.15;\r\n min-height: 0;\r\n }\r\n\r\n :host([variant=\"inside\"]) .combo-box-container:focus-within .input-inside-main > .label,\r\n :host([variant=\"inside\"]) .input-wrapper[open] .input-inside-main > .label {\r\n color: var(--sky-dropdown-color);\r\n font-size: var(--sky-font-size-xs);\r\n }\r\n\r\n :host([variant=\"inside\"][compact]) .combo-box-container:focus-within .input-inside-main > .label,\r\n :host([variant=\"inside\"][compact]) .input-wrapper[open] .input-inside-main > .label {\r\n font-size: 0.6875rem;\r\n }\r\n\r\n :host([variant=\"inside\"][validationActive]:invalid) .input-inside-main > .label {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-inside-row {\r\n display: flex;\r\n align-items: center;\r\n min-width: 0;\r\n width: 100%;\r\n min-height: var(--sky-input-inside-value-min);\r\n gap: 0;\r\n overflow: hidden;\r\n flex: 0 0 auto;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-inside-main:has(.chip:not([single-select])) {\r\n justify-content: center;\r\n align-self: center;\r\n padding-block: 0;\r\n gap: 2px;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-inside-row:has(.chip:not([single-select])) {\r\n min-height: 0;\r\n height: auto;\r\n align-items: center;\r\n }\r\n\r\n :host([variant=\"inside\"]) .field-main:has(.chip:not([single-select])) {\r\n align-self: center;\r\n height: auto;\r\n min-height: 0;\r\n }\r\n\r\n /* Match sky-input: label + value share pad-x; zero start when left icon present */\r\n :host([variant=\"inside\"]) .input-inside-main > .label,\r\n :host([variant=\"inside\"]) .chip-container,\r\n :host([variant=\"inside\"]) .value-summary,\r\n :host([variant=\"inside\"]) .placeholder-label {\r\n padding-inline-start: var(--sky-input-pad-x);\r\n padding-inline-end: var(--sky-input-pad-x);\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-wrapper:has(.icon-slot[filled].left) .input-inside-main > .label,\r\n :host([variant=\"inside\"]) .input-wrapper:has(.icon-slot[filled].left) .chip-container,\r\n :host([variant=\"inside\"]) .input-wrapper:has(.icon-slot[filled].left) .value-summary,\r\n :host([variant=\"inside\"]) .input-wrapper:has(.icon-slot[filled].left) .placeholder-label {\r\n padding-inline-start: 0;\r\n }\r\n\r\n /* Left icon / trailing chrome centered to label+value column (like sky-input) */\r\n :host([variant=\"inside\"]) .icon-slot,\r\n :host([variant=\"inside\"]) .icon-slot[filled] {\r\n align-self: center;\r\n height: auto;\r\n max-height: none;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n :host([variant=\"inside\"]) .field-trailing {\r\n align-self: center;\r\n padding-inline-start: 0;\r\n }\r\n\r\n /* Outside labels — keep accent while dropdown is open (focus may leave into popover) */\r\n .combo-box-container:focus-within > .label,\r\n .combo-box-container:has(.input-wrapper[open]) > .label {\r\n color: var(--sky-dropdown-color);\r\n transition: color 0.3s ease;\r\n }\r\n\r\n :host([compact]) .combo-box-container:focus-within > .label,\r\n :host([compact]) .combo-box-container:has(.input-wrapper[open]) > .label {\r\n font-size: var(--sky-font-size-xs);\r\n }\r\n\r\n .label {\r\n font-size: var(--sky-font-size-sm);\r\n margin-bottom: var(--sky-space-1, 4px);\r\n text-align: start;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n font-family: var(--sky-font);\r\n line-height: 1.35;\r\n }\r\n\r\n .combo-box-container {\r\n position: relative;\r\n display: flex;\r\n flex-direction: column;\r\n max-width: 100%;\r\n overflow: visible;\r\n width: 100%;\r\n }\r\n\r\n .combo-box-container.shake {\r\n animation: shake 0.3s ease-in-out;\r\n animation-iteration-count: 1;\r\n }\r\n\r\n @keyframes shake {\r\n 0% {\r\n transform: translateX(0);\r\n }\r\n 25% {\r\n transform: translateX(-3px);\r\n }\r\n 50% {\r\n transform: translateX(3px);\r\n }\r\n 75% {\r\n transform: translateX(-3px);\r\n }\r\n 100% {\r\n transform: translateX(0);\r\n }\r\n }\r\n\r\n .search-container {\r\n display: flex;\r\n align-items: center;\r\n padding: 8px 10px;\r\n gap: var(--sky-input-gap, 4px);\r\n border-bottom: 1px solid var(--sky-border-light);\r\n margin-bottom: 5px;\r\n }\r\n\r\n .search-container .dropdown-search-input {\r\n flex: 1 1 auto;\r\n min-width: 0;\r\n width: 100%;\r\n }\r\n\r\n .new-option-btn {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 22px;\r\n height: 22px;\r\n border-radius: var(--sky-radius-primary);\r\n margin-left: 6px;\r\n cursor: pointer;\r\n background: var(--sky-hover-primary);\r\n border: var(--sky-border-primary);\r\n color: var(--sky-dropdown-color);\r\n flex-shrink: 0;\r\n transition: color 0.15s ease;\r\n }\r\n .new-option-btn:hover {\r\n color: var(--sky-active-primary);\r\n }\r\n .new-option-btn[disabled] {\r\n opacity: 0.6;\r\n pointer-events: none;\r\n }\r\n\r\n .input-wrapper {\r\n display: flex;\r\n align-items: center;\r\n background: var(--sky-glass-solid);\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n box-sizing: border-box;\r\n border-radius: var(--sky-radius-secondary);\r\n height: var(--sky-input-height);\r\n min-height: var(--sky-input-height);\r\n width: 100%;\r\n flex-wrap: nowrap;\r\n position: relative;\r\n overflow: hidden;\r\n border: var(--sky-border-primary);\r\n box-shadow: var(--sky-box-shadow-primary);\r\n transition:\r\n border-color var(--sky-transition-normal, 200ms ease),\r\n box-shadow var(--sky-transition-normal, 200ms ease);\r\n flex: 1 1 auto;\r\n min-width: 0;\r\n }\r\n\r\n .input-wrapper:focus-visible {\r\n border-bottom: 1px solid var(--sky-dropdown-color);\r\n outline: none;\r\n }\r\n\r\n .input-wrapper::after {\r\n content: \"\";\r\n position: absolute;\r\n top: -1px;\r\n left: -1px;\r\n right: -1px;\r\n bottom: -1px;\r\n border-radius: inherit;\r\n border: 1px solid transparent;\r\n border-bottom-color: transparent;\r\n opacity: 0;\r\n transition:\r\n opacity 0.3s ease,\r\n border-color 0.3s ease;\r\n pointer-events: none;\r\n }\r\n\r\n .input-wrapper[open]::after {\r\n opacity: 1;\r\n border-bottom-color: var(--sky-dropdown-color);\r\n }\r\n\r\n :host([validationActive]:invalid) .input-wrapper::after {\r\n opacity: 1;\r\n border-bottom-color: var(--sky-danger-primary);\r\n }\r\n\r\n :host([validationActive]:invalid) .label {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n :host([validationActive]:invalid) .icon-slot {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n .placeholder-label.active[compact] {\r\n top: 10px;\r\n background-color: var(--sky-dropdown-color);\r\n color: var(--sky-on-color-fallback-light, var(--sky-text-white));\r\n font-size: var(--sky-font-size-xs);\r\n padding: 0 5px;\r\n border-radius: 4px;\r\n }\r\n\r\n .input-wrapper[compact] {\r\n height: var(--sky-input-height-compact);\r\n min-height: var(--sky-input-height-compact);\r\n border-radius: var(--sky-radius-primary);\r\n }\r\n\r\n /* Multi chips stay single-line; do not grow taller than sky-input.\r\n Exempt inside variant — it needs two rows (label + value). */\r\n .input-wrapper:has(.chip:not([single-select])) {\r\n height: var(--sky-input-height);\r\n min-height: var(--sky-input-height);\r\n padding-block: 0;\r\n }\r\n\r\n .input-wrapper[compact]:has(.chip:not([single-select])) {\r\n height: var(--sky-input-height-compact);\r\n min-height: var(--sky-input-height-compact);\r\n padding-block: 0;\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-wrapper,\r\n :host([variant=\"inside\"]) .input-wrapper:has(.chip),\r\n :host([variant=\"inside\"]) .input-wrapper[compact]:has(.chip) {\r\n height: auto;\r\n min-height: var(--sky-input-height-inside);\r\n padding-block: var(--sky-input-pad-y-sm, 0px);\r\n align-items: center;\r\n }\r\n\r\n :host([variant=\"inside\"][compact]) .input-wrapper,\r\n :host([variant=\"inside\"][compact]) .input-wrapper:has(.chip) {\r\n min-height: var(--sky-input-height-inside-compact);\r\n }\r\n\r\n :host([variant=\"inside\"]) .input-wrapper:has(.chip:not([single-select])) {\r\n padding-block: 4px;\r\n }\r\n\r\n :host([variant=\"inside\"][compact]) .input-wrapper:has(.chip:not([single-select])) {\r\n padding-block: 2px;\r\n }\r\n\r\n :host([compact]) .placeholder-label {\r\n font-size: var(--sky-font-size-sm);\r\n }\r\n\r\n sky-icon {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 1em;\r\n height: 1em;\r\n flex-shrink: 0;\r\n }\r\n\r\n /* Value column: takes remaining width; never paints under trailing actions */\r\n .field-main {\r\n flex: 1 1 0%;\r\n min-width: 0;\r\n max-width: 100%;\r\n overflow: hidden;\r\n display: flex;\r\n align-items: center;\r\n align-self: stretch;\r\n position: relative;\r\n z-index: 0;\r\n }\r\n\r\n .chip-container {\r\n display: flex;\r\n gap: var(--sky-input-gap);\r\n flex: 1 1 0%;\r\n width: 100%;\r\n min-width: 0;\r\n max-width: 100%;\r\n min-height: 0;\r\n height: 100%;\r\n flex-wrap: nowrap;\r\n align-items: center;\r\n align-self: stretch;\r\n overflow: hidden;\r\n box-sizing: border-box;\r\n margin: 0;\r\n line-height: 1;\r\n padding-block: 4px;\r\n padding-inline: var(--sky-input-pad-x) var(--sky-input-pad-x-sm);\r\n }\r\n\r\n :host([compact]) .chip-container,\r\n .chip-container[compact] {\r\n gap: 4px;\r\n padding-block: 2px;\r\n }\r\n\r\n :host([variant=\"inside\"]) .chip-container {\r\n height: auto;\r\n align-self: center;\r\n padding-block: 0;\r\n }\r\n\r\n .input-wrapper:has(.icon-slot[filled].left) .chip-container {\r\n padding-inline-start: var(--sky-input-pad-x-sm);\r\n }\r\n\r\n .value-summary {\r\n display: block;\r\n flex: 1 1 0%;\r\n width: 100%;\r\n min-width: 0;\r\n max-width: 100%;\r\n box-sizing: border-box;\r\n margin: 0;\r\n padding-inline: var(--sky-input-pad-x) var(--sky-input-pad-x-sm);\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n font-size: var(--sky-font-size-md);\r\n color: var(--sky-text-primary);\r\n font-family: var(--sky-font);\r\n line-height: 1.25;\r\n text-align: start;\r\n }\r\n\r\n .input-wrapper:has(.icon-slot[filled].left) .value-summary {\r\n padding-inline-start: var(--sky-input-pad-x-sm);\r\n }\r\n\r\n :host([compact]) .value-summary {\r\n font-size: var(--sky-font-size-sm);\r\n }\r\n\r\n .chip-container::-webkit-scrollbar {\r\n display: none;\r\n }\r\n\r\n .chip {\r\n background-color: var(--sky-glass-primary);\r\n border-radius: var(--sky-radius-primary);\r\n padding: 0 6px;\r\n height: 1.25rem;\r\n max-height: calc(var(--sky-input-height) - 10px);\r\n font-size: var(--sky-font-size-sm);\r\n line-height: 1;\r\n display: inline-flex;\r\n align-items: center;\r\n align-self: center;\r\n gap: 4px;\r\n flex: 0 1 auto;\r\n max-width: 100%;\r\n min-width: 0;\r\n border: var(--sky-border-primary);\r\n font-family: var(--sky-font);\r\n text-align: start;\r\n box-sizing: border-box;\r\n white-space: nowrap;\r\n }\r\n\r\n .chip .chip-label {\r\n min-width: 0;\r\n flex: 1 1 auto;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n line-height: 1;\r\n }\r\n\r\n .chip.overflow-chip {\r\n flex: 0 0 auto;\r\n white-space: nowrap;\r\n max-width: none;\r\n }\r\n\r\n :host([compact]) .chip {\r\n height: 1.125rem;\r\n max-height: calc(var(--sky-input-height-compact) - 8px);\r\n padding: 0 4px;\r\n font-size: var(--sky-font-size-xs);\r\n }\r\n\r\n .chip .remove-chip[compact] {\r\n flex-shrink: 0;\r\n }\r\n .remove-chip-inner {\r\n font-size: var(--sky-font-size-md);\r\n color: var(--sky-dropdown-color);\r\n background-color: var(--sky-hover-primary);\r\n border-radius: var(--sky-radius-full);\r\n border: none;\r\n cursor: pointer;\r\n transition: color 0.2s ease, background-color 0.2s ease;\r\n }\r\n .remove-chip-inner:hover {\r\n color: var(--sky-danger-primary);\r\n }\r\n .remove-chip:hover {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n .chip .remove-chip {\r\n position: static;\r\n flex-shrink: 0;\r\n align-self: center;\r\n font-size: var(--sky-font-size-sm);\r\n color: var(--sky-dropdown-color);\r\n background-color: var(--sky-hover-primary);\r\n border-radius: var(--sky-radius-full);\r\n cursor: pointer;\r\n border: none;\r\n transition: color 0.2s ease, background-color 0.2s ease;\r\n }\r\n\r\n .input-wrapper[disabled] {\r\n opacity: 0.6;\r\n pointer-events: none;\r\n }\r\n\r\n .dropdown {\r\n position: fixed;\r\n padding: 5px;\r\n background: var(--sky-glass-tertiary);\r\n background-image: var(--sky-glass-surface);\r\n backdrop-filter: var(--sky-blur-tertiary) var(--sky-brightness-tertiary)\r\n var(--sky-saturation-tertiary);\r\n -webkit-backdrop-filter: var(--sky-blur-tertiary)\r\n var(--sky-brightness-tertiary) var(--sky-saturation-tertiary);\r\n border-radius: var(--sky-radius-secondary);\r\n box-shadow:\r\n var(--sky-box-shadow-inset),\r\n var(--sky-box-shadow-tertiary);\r\n box-sizing: border-box;\r\n pointer-events: auto;\r\n margin: 0;\r\n border: var(--sky-border-tertiary);\r\n }\r\n\r\n .dropdown-scroller {\r\n max-height: var(--sky-scroll-height);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n scrollbar-color: var(--sky-scrollbar-thumb) var(--sky-scrollbar-track);\r\n }\r\n\r\n .dropdown-scroller::-webkit-scrollbar {\r\n width: 6px;\r\n height: 6px;\r\n }\r\n\r\n .dropdown-scroller::-webkit-scrollbar-thumb {\r\n background-color: var(--sky-scrollbar-thumb);\r\n border-radius: var(--sky-radius-full, 9999px);\r\n transition: background-color var(--sky-duration-normal, 200ms)\r\n var(--sky-ease-default, ease);\r\n cursor: grab;\r\n }\r\n\r\n .dropdown-scroller::-webkit-scrollbar-thumb:hover {\r\n background-color: var(--sky-scrollbar-thumb-hover);\r\n }\r\n\r\n .dropdown-scroller::-webkit-scrollbar-track {\r\n background: var(--sky-scrollbar-track);\r\n }\r\n\r\n .dropdown-scroller::-webkit-scrollbar-button {\r\n background-color: transparent;\r\n }\r\n\r\n .dropdown-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 8px 10px;\r\n border-radius: var(--sky-radius-secondary);\r\n cursor: pointer;\r\n text-align: left;\r\n font-size: var(--sky-font-size-sm);\r\n color: var(--sky-text-primary);\r\n transition:\r\n background-color 0.15s ease,\r\n color 0.15s ease;\r\n box-sizing: border-box;\r\n margin: 2px 0;\r\n font-family: var(--sky-font);\r\n }\r\n\r\n .dropdown-item:hover {\r\n background-color: var(--sky-hover-primary);\r\n }\r\n\r\n .dropdown-item.active {\r\n background-color: var(--sky-hover-primary);\r\n }\r\n\r\n .dropdown-item.selected {\r\n color: var(--sky-dropdown-color, var(--sky-active-primary));\r\n background-color: var(--sky-active-g0, var(--sky-hover-primary));\r\n font-weight: var(--sky-font-weight-medium, 500);\r\n }\r\n\r\n .dropdown-item.active.selected,\r\n .dropdown-item.selected:hover {\r\n background-color: var(--sky-active-g0, var(--sky-hover-primary));\r\n color: var(--sky-dropdown-color, var(--sky-active-primary));\r\n }\r\n\r\n :host([compact]) .dropdown-item {\r\n font-size: var(--sky-font-size-sm);\r\n padding: 5px 8px;\r\n margin: 1px 0;\r\n }\r\n\r\n .icon-slot {\r\n display: none;\r\n justify-content: center;\r\n font-size: var(--sky-font-size-xl);\r\n align-items: center;\r\n align-self: center;\r\n color: var(--sky-text-primary);\r\n height: 100%;\r\n max-height: 100%;\r\n box-sizing: border-box;\r\n flex: 0 0 var(--sky-input-icon-width);\r\n width: var(--sky-input-icon-width);\r\n min-width: var(--sky-input-icon-width);\r\n padding: 0;\r\n background: none;\r\n border: none;\r\n transition: color var(--sky-transition-normal, 200ms ease);\r\n }\r\n\r\n .hidden-chips-dropdown {\r\n position: fixed; /* important: popover top layer */\r\n background: var(--sky-glass-tertiary);\r\n background-image: var(--sky-glass-surface);\r\n backdrop-filter: var(--sky-blur-tertiary) var(--sky-brightness-tertiary)\r\n var(--sky-saturation-tertiary);\r\n -webkit-backdrop-filter: var(--sky-blur-tertiary)\r\n var(--sky-brightness-tertiary) var(--sky-saturation-tertiary);\r\n box-shadow:\r\n var(--sky-box-shadow-inset),\r\n var(--sky-box-shadow-tertiary);\r\n border-radius: var(--sky-radius-secondary);\r\n border: var(--sky-border-tertiary);\r\n width: max-content;\r\n opacity: 0;\r\n transform: scale(0.98);\r\n transition: opacity 0.15s ease, transform 0.15s ease;\r\n margin: 0;\r\n }\r\n\r\n .hidden-chips-dropdown:popover-open {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n\r\n .hidden-chip-inner {\r\n padding: 4px 8px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n cursor: pointer;\r\n gap: 5px;\r\n font-size: var(--sky-font-size-sm);\r\n border-bottom: var(--sky-border-primary);\r\n font-family: var(--sky-font);\r\n }\r\n\r\n .hidden-chip-inner:last-child {\r\n border-bottom: none;\r\n }\r\n\r\n .icon-slot[filled] {\r\n display: flex;\r\n flex-shrink: 0;\r\n cursor: pointer;\r\n }\r\n\r\n .icon-slot[filled]:hover,\r\n .icon-slot[filled]:active,\r\n .icon-slot.focused,\r\n .input-wrapper[open] .icon-slot[filled] {\r\n color: var(--sky-dropdown-color);\r\n }\r\n\r\n .placeholder-label {\r\n white-space: nowrap;\r\n box-sizing: border-box;\r\n padding-inline: var(--sky-input-pad-x);\r\n flex: 1 1 0%;\r\n width: 100%;\r\n min-width: 0;\r\n text-align: start;\r\n font-size: var(--sky-font-size-md);\r\n line-height: 1.25;\r\n color: var(--sky-text-tertiary);\r\n transition: color var(--sky-transition-normal, 200ms ease);\r\n pointer-events: none;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n font-family: var(--sky-font);\r\n display: flex;\r\n align-items: center;\r\n align-self: stretch;\r\n }\r\n\r\n .input-wrapper:has(.icon-slot[filled].left) .placeholder-label {\r\n padding-inline-start: var(--sky-input-pad-x-sm);\r\n }\r\n\r\n .placeholder-label.active {\r\n display: none;\r\n }\r\n\r\n .field-trailing {\r\n display: flex;\r\n flex: 0 0 auto;\r\n flex-shrink: 0;\r\n align-items: center;\r\n justify-content: flex-end;\r\n align-self: stretch;\r\n gap: var(--sky-input-pad-x-sm);\r\n padding-inline-end: var(--sky-input-pad-x-sm);\r\n padding-inline-start: var(--sky-input-pad-x-sm);\r\n box-sizing: border-box;\r\n }\r\n\r\n sky-icon.clear-button {\r\n box-sizing: border-box;\r\n flex: 0 0 auto;\r\n width: 1.125rem;\r\n height: 1.125rem;\r\n min-width: 1.125rem;\r\n min-height: 1.125rem;\r\n margin: 0;\r\n padding: 0;\r\n border: none;\r\n font-size: 0.75rem;\r\n line-height: 1;\r\n color: var(--sky-dropdown-color);\r\n background-color: var(--sky-hover-primary);\r\n border-radius: var(--sky-radius-full);\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n cursor: pointer;\r\n transition: color var(--sky-transition-normal, 200ms ease);\r\n }\r\n\r\n sky-icon.clear-button[compact] {\r\n width: 1rem;\r\n height: 1rem;\r\n min-width: 1rem;\r\n min-height: 1rem;\r\n font-size: 0.6875rem;\r\n }\r\n\r\n sky-icon.clear-button:hover {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n sky-icon.dropdown-button {\r\n box-sizing: border-box;\r\n flex: 0 0 auto;\r\n width: var(--sky-input-icon-width);\r\n height: auto;\r\n min-width: calc(var(--sky-input-icon-width) - 0.25rem);\r\n margin: 0;\r\n padding: 0;\r\n border: none;\r\n font-size: var(--sky-font-size-sm);\r\n color: var(--sky-text-primary);\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: color var(--sky-transition-normal, 200ms ease);\r\n background: none;\r\n }\r\n\r\n sky-icon.dropdown-button:hover,\r\n .input-wrapper[open] sky-icon.dropdown-button {\r\n color: var(--sky-dropdown-color);\r\n }\r\n\r\n sky-icon.dropdown-button[compact] {\r\n font-size: var(--sky-font-size-md);\r\n }\r\n\r\n .loading-indicator {\r\n flex-shrink: 0;\r\n margin-inline-end: var(--sky-input-pad-x-sm);\r\n width: 16px;\r\n height: 16px;\r\n border: 2px solid var(--sky-border-light, var(--sky-text-tertiary));\r\n border-top: 2px solid var(--sky-dropdown-color, var(--sky-active-primary));\r\n border-radius: var(--sky-radius-full);\r\n animation: spin 1s linear infinite;\r\n }\r\n\r\n ::slotted(.icon-slot) {\r\n display: block;\r\n }\r\n\r\n @keyframes spin {\r\n 0% {\r\n transform: rotate(0deg);\r\n }\r\n 100% {\r\n transform: rotate(360deg);\r\n }\r\n }\r\n\r\n .highlight {\r\n color: var(--sky-dropdown-color);\r\n font-weight: var(--sky-font-weight-semibold);\r\n }\r\n\r\n .progress-container {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: flex-start;\r\n align-items: flex-start;\r\n position: absolute;\r\n width: 100%;\r\n top: 100%;\r\n }\r\n\r\n .progress-message {\r\n pointer-events: none;\r\n width: 100%;\r\n overflow: hidden;\r\n white-space: nowrap;\r\n text-overflow: ellipsis;\r\n font-size: var(--sky-font-size-sm);\r\n margin-inline-start: var(--sky-input-pad-x-sm);\r\n font-family: var(--sky-font);\r\n }\r\n\r\n :dir(rtl) .progress-message {\r\n margin-inline-start: unset;\r\n margin-inline-end: var(--sky-input-pad-x-sm);\r\n }\r\n\r\n .error-list {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0;\r\n width: 100%;\r\n }\r\n\r\n .error {\r\n font-size: var(--sky-font-size-xs);\r\n color: var(--sky-danger-primary);\r\n text-align: start;\r\n white-space: nowrap;\r\n text-overflow: ellipsis;\r\n font-family: var(--sky-font);\r\n }\r\n .sky-checkbox {\r\n appearance: none;\r\n flex-shrink: 0;\r\n width: 16px;\r\n height: 16px;\r\n border-radius: 6px;\r\n margin-right: 5px;\r\n border: 1px solid var(--sky-text-tertiary);\r\n background-color: transparent;\r\n box-shadow: none;\r\n cursor: pointer;\r\n position: relative;\r\n transition:\r\n background-color 0.3s ease,\r\n border-color 0.3s ease,\r\n box-shadow 0.3s ease;\r\n }\r\n\r\n .sky-checkbox:hover {\r\n background-color: var(--sky-text-tertiary);\r\n border-color: var(--sky-text-tertiary);\r\n }\r\n\r\n .sky-checkbox:focus-visible {\r\n background-color: var(--sky-text-tertiary);\r\n border-color: var(--sky-text-tertiary);\r\n outline: none;\r\n }\r\n\r\n .sky-checkbox:checked {\r\n background-color: var(--sky-active-primary);\r\n border-color: var(--sky-active-primary);\r\n }\r\n\r\n .sky-checkbox::after {\r\n content: \"\";\r\n width: 8px;\r\n height: 4px;\r\n border: 2px solid var(--sky-on-color-fallback-light, var(--sky-text-white));\r\n border-top: none;\r\n border-right: none;\r\n position: absolute;\r\n top: 6px;\r\n left: 50%;\r\n transform: translate(-50%, -50%) rotate(-90deg) scale(0.8);\r\n opacity: 0;\r\n transition:\r\n opacity 0.2s ease-in-out,\r\n transform 0.2s ease-in-out;\r\n }\r\n\r\n .sky-checkbox.indeterminate {\r\n background-color: var(--sky-active-primary);\r\n border-color: var(--sky-active-primary);\r\n }\r\n\r\n .sky-checkbox.indeterminate::after {\r\n width: 8px;\r\n height: 2px;\r\n background-color: var(--sky-on-color-fallback-light, var(--sky-text-white));\r\n border: none;\r\n top: 50%;\r\n left: 50%;\r\n opacity: 1;\r\n transform: translate(-50%, -50%) scale(1);\r\n }\r\n\r\n .sky-checkbox:checked::after {\r\n opacity: 1;\r\n transform: translate(-50%, -50%) rotate(-45deg) scale(1);\r\n }\r\n\r\n .sky-checkbox:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n }\r\n\r\n ${unsafeCSS(\r\n cssOnFillEnhance([\r\n {\r\n selector: \".placeholder-label.active[compact]\",\r\n fillVar: \"--sky-dropdown-color\",\r\n },\r\n {\r\n selector: \".sky-checkbox:checked::after\",\r\n fillVar: \"--sky-active-primary\",\r\n property: \"border-color\",\r\n },\r\n {\r\n selector: \".sky-checkbox.indeterminate::after\",\r\n fillVar: \"--sky-active-primary\",\r\n property: \"background-color\",\r\n },\r\n ]),\r\n )}\r\n `;\r\n\r\n constructor() {\r\n super();\r\n this.captureDefaultValue(\"\");\r\n }\r\n\r\n static override shadowRootOptions = {\r\n ...LitElement.shadowRootOptions,\r\n delegatesFocus: true,\r\n };\r\n\r\n override connectedCallback() {\r\n super.connectedCallback();\r\n\r\n if (!this.hasAttribute(\"tabindex\")) {\r\n this.tabIndex = this.disabled ? -1 : 0;\r\n }\r\n this.refreshOptionSlots();\r\n\r\n }\r\n\r\n override firstUpdated() {\r\n this.dropdownPopover.refreshTargets();\r\n this.hiddenPopover.refreshTargets();\r\n }\r\n\r\n private refreshOptionSlots = () => {\r\n const set = new Set<string>();\r\n this.querySelectorAll<HTMLElement>('[slot^=\"option-\"]').forEach((el) => {\r\n const slotName = (el as HTMLElement).slot;\r\n if (slotName) set.add(slotName);\r\n });\r\n this.optionSlotSet = set;\r\n };\r\n\r\n /** Get the current value for form submission */\r\n protected override getFormValue(): FormState {\r\n if (this.disabled || !this.name) return null;\r\n\r\n if (this.multiSelect) {\r\n const formData = new FormData();\r\n this.selectedItems.forEach((item) => {\r\n const value = this.emitFullObject\r\n ? JSON.stringify(item)\r\n : String(this.getOptionValue(item));\r\n formData.append(this.name, value);\r\n });\r\n // Add a dummy input when nothing is selected (for form validation)\r\n if (this.selectedItems.length === 0 && this.required) {\r\n formData.append(this.name, \"\");\r\n }\r\n return formData;\r\n } else {\r\n if (this.selectedItems.length === 0) return \"\";\r\n const item = this.selectedItems[0];\r\n return this.emitFullObject\r\n ? JSON.stringify(item)\r\n : String(this.getOptionValue(item));\r\n }\r\n }\r\n\r\n /** Set value from form state (e.g., form reset) */\r\n protected override setValueFromFormState(state: FormState): void {\r\n if (state === null || state === \"\") {\r\n this.value = this.multiSelect ? [] : \"\";\r\n this.selectedItems = [];\r\n return;\r\n }\r\n\r\n if (this.multiSelect) {\r\n let values: any[] = [];\r\n\r\n if (state instanceof FormData) {\r\n values = state.getAll(this.name);\r\n } else if (Array.isArray(state)) {\r\n values = state;\r\n } else if (typeof state === \"string\") {\r\n try {\r\n const parsed = JSON.parse(state);\r\n if (Array.isArray(parsed)) {\r\n values = parsed;\r\n } else {\r\n values = [state];\r\n }\r\n } catch {\r\n values = [state];\r\n }\r\n }\r\n\r\n this.setValueFromArray(values);\r\n } else {\r\n let stringValue = \"\";\r\n if (typeof state === \"string\") {\r\n stringValue = state;\r\n } else if (state instanceof FormData) {\r\n stringValue = state.get(this.name)?.toString() || \"\";\r\n } else if (Array.isArray(state) && state.length > 0) {\r\n stringValue = state[0].toString();\r\n }\r\n\r\n this.value = stringValue;\r\n this.syncSelectedItemsWithValue();\r\n }\r\n }\r\n protected override syncFormValue(): void {\r\n if (!this.name || this.disabled) {\r\n this.internals.setFormValue(null);\r\n return;\r\n }\r\n\r\n const v = this.getFormValue();\r\n\r\n if (v === null) {\r\n this.internals.setFormValue(null);\r\n return;\r\n }\r\n\r\n if (this.multiSelect && Array.isArray(v)) {\r\n // Matches native <select multiple> form value shape.\r\n const formData = new FormData();\r\n v.forEach((value) => {\r\n if (value !== null && value !== undefined && value !== \"\") {\r\n formData.append(this.name, String(value));\r\n }\r\n });\r\n this.internals.setFormValue(formData);\r\n } else {\r\n this.internals.setFormValue(v as string | File | null);\r\n }\r\n }\r\n private setValueFromArray(values: any[]) {\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n this.selectedItems = optionsArray.filter((option) => {\r\n const optionValue = this.getOptionValue(option);\r\n const optionValueString = this.emitFullObject\r\n ? JSON.stringify(option)\r\n : String(optionValue);\r\n\r\n return values.some((value) => {\r\n const stringValue = String(value);\r\n\r\n if (this.emitFullObject) {\r\n try {\r\n const parsedValue = JSON.parse(stringValue);\r\n return JSON.stringify(parsedValue) === optionValueString;\r\n } catch {\r\n return stringValue === optionValueString;\r\n }\r\n } else {\r\n return stringValue === optionValueString;\r\n }\r\n });\r\n });\r\n\r\n this.value = this.selectedItems.map((item) =>\r\n this.emitFullObject ? item : this.getOptionValue(item),\r\n );\r\n }\r\n\r\n /** Get the validity anchor (for validation messages) */\r\n protected override getValidityAnchor(): HTMLElement | undefined {\r\n return this;\r\n }\r\n\r\n /** Check if empty (for required validation) */\r\n protected override isEmpty(): boolean {\r\n if (this.multiSelect) {\r\n return this.selectedItems.length === 0;\r\n } else {\r\n return this.selectedItems.length === 0 || !this.value;\r\n }\r\n }\r\n\r\n protected override getNativeControl(): HTMLElement | null {\r\n return this.inputWrapperEl || null;\r\n }\r\n /** Override to provide custom error messages */\r\n protected override getCustomErrorMessage(): string {\r\n return this.validationErrors?.[0] || \"\";\r\n }\r\n\r\n /** Override form reset callback */\r\n protected override onFormReset(): void {\r\n super.onFormReset();\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.open = false;\r\n this.invalid = false;\r\n this.validationErrors = [];\r\n this.validationActive = false;\r\n }\r\n\r\n /** Override form disabled callback */\r\n protected override onFormDisabled(disabled: boolean): void {\r\n this.disabled = disabled;\r\n }\r\n\r\n /** Override form state restore callback */\r\n protected override onFormStateRestore(state: FormState): void {\r\n this.setValueFromFormState(state);\r\n }\r\n\r\n\r\n private toggleSelectAll(): void {\r\n if (this.disabled || this.readonly) return;\r\n\r\n if (this.isAllFilteredSelected()) {\r\n const filteredKeys = new Set(\r\n this.filteredOptions.map((opt) => this.optionKey(opt.original)),\r\n );\r\n\r\n const nextSelected = this.selectedItems.filter(\r\n (item) => !filteredKeys.has(this.optionKey(item)),\r\n );\r\n\r\n // 🚫 prevent going below 1 selection when enforced\r\n if (this.enforceMinOneSelection && nextSelected.length === 0) {\r\n return;\r\n }\r\n\r\n this.selectedItems = nextSelected;\r\n } else {\r\n const selectedKeys = new Set(\r\n this.selectedItems.map((item) => this.optionKey(item)),\r\n );\r\n const additions = this.filteredOptions\r\n .map((o) => o.original)\r\n .filter((opt) => !selectedKeys.has(this.optionKey(opt)));\r\n this.selectedItems = [...this.selectedItems, ...additions];\r\n }\r\n\r\n const valuesArray = this.selectedItems.map((opt) =>\r\n this.emitFullObject ? opt : this.getOptionValue(opt),\r\n );\r\n this.value = valuesArray;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent<SkyComboboxValueChangedDetail>(\"value-changed\", {\r\n detail: {\r\n value: valuesArray,\r\n selectedItems: [...this.selectedItems],\r\n emittedValues: valuesArray,\r\n isFilteredSelection: !!this.searchQuery.trim(),\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n\r\n this.syncFormValue();\r\n this.syncValidity();\r\n this.requestUpdate();\r\n }\r\n\r\n private isAllFilteredSelected(): boolean {\r\n if (this.filteredOptions.length === 0) return false;\r\n\r\n const selectedKeys = new Set(\r\n this.selectedItems.map((item) => this.optionKey(item)),\r\n );\r\n return this.filteredOptions.every((opt) =>\r\n selectedKeys.has(this.optionKey(opt.original)),\r\n );\r\n }\r\n\r\n private truncateText(text: string, maxLength: number): string {\r\n if (text.length > maxLength) {\r\n return text.slice(0, maxLength) + \"...\";\r\n }\r\n return text;\r\n }\r\n\r\n private validateInput(): void {\r\n if (!this.validationActive) return;\r\n\r\n const nextErrors: string[] = [];\r\n const target = this.validationArrayFormat ? this.selectedItems : this.value;\r\n\r\n // 1) required first (single source of truth inside component UI)\r\n if (this.required && this.isEmpty()) {\r\n nextErrors.push(this.requiredMessage || \"Selection is required.\");\r\n } else if (Array.isArray(this.validations) && this.validations.length) {\r\n // 2) run external validations only when not empty (optional but cleaner)\r\n for (const v of this.validations) {\r\n const res = v(target);\r\n if (res !== true) nextErrors.push(String(res || \"Invalid value.\"));\r\n }\r\n }\r\n\r\n const nextInvalid = nextErrors.length > 0;\r\n const errorsChanged = !samePrimitiveArray(this.validationErrors, nextErrors);\r\n if (errorsChanged) this.validationErrors = nextErrors;\r\n if (this.invalid !== nextInvalid) this.invalid = nextInvalid;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent<SkyComboboxValidationErrorDetail | SkyComboboxValidationSuccessDetail>(\r\n this.invalid ? \"validation-error\" : \"validation-success\",\r\n {\r\n detail: this.invalid\r\n ? { errors: this.validationErrors }\r\n : { value: this.selectedItems },\r\n bubbles: true,\r\n composed: true,\r\n },\r\n ),\r\n );\r\n\r\n this.syncValidity();\r\n }\r\n\r\n // Blocks form submit when invalid, even if validationActive is false.\r\n protected override validateForForm(): string {\r\n if (this.disabled) return \"\";\r\n\r\n // What should validators receive?\r\n const target = this.validationArrayFormat ? this.selectedItems : this.value;\r\n\r\n // 1) external validations first\r\n if (Array.isArray(this.validations) && this.validations.length) {\r\n for (const v of this.validations) {\r\n const res = v(target);\r\n if (res !== true) return String(res || \"Invalid value.\");\r\n }\r\n }\r\n\r\n // 2) enforceMinOneSelection as a hard rule (optional but makes form correct)\r\n if (this.enforceMinOneSelection && this.isEmpty()) {\r\n return this.requiredMessage || \"At least one selection is required.\";\r\n }\r\n\r\n // 3) required rule\r\n if (this.required && this.isEmpty()) {\r\n return this.requiredMessage || \"Selection is required.\";\r\n }\r\n\r\n return \"\";\r\n }\r\n\r\n override focus(options?: FocusOptions) {\r\n super.focus(options);\r\n if (this.searchInputEl) {\r\n this.searchInputEl.focus(options);\r\n } else if (this.inputWrapperEl) {\r\n this.inputWrapperEl.focus(options);\r\n }\r\n }\r\n\r\n override blur() {\r\n if (this.open) {\r\n this.dropdownPopover.closePopover(\"light-dismiss\");\r\n }\r\n super.blur();\r\n }\r\n\r\n private handleFocus(): void {\r\n this.focused = true;\r\n\r\n if (!this.validationActive) {\r\n this.validationActive = true;\r\n }\r\n }\r\n\r\n /**\r\n * Resets combobox state and clears validation UI.\r\n *\r\n * @returns {void}\r\n */\r\n public reset(): void {\r\n this.value = this.multiSelect ? [] : \"\";\r\n this.selectedItems = [];\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.filterOptions();\r\n this.validationErrors = [];\r\n this.validationActive = false;\r\n this.open = false;\r\n this.invalid = false;\r\n this.syncFormValue();\r\n this.syncValidity();\r\n this.requestUpdate();\r\n }\r\n\r\n /**\r\n * Opens the combobox dropdown.\r\n *\r\n * @returns {void}\r\n */\r\n public openDropdown(): void {\r\n if (this.disabled || this.readonly) return;\r\n this.dropdownPopover.openPopover();\r\n }\r\n\r\n /**\r\n * Closes the combobox dropdown.\r\n *\r\n * @returns {void}\r\n */\r\n public closeDropdown(): void {\r\n this.dropdownPopover.closePopover(\"api\");\r\n }\r\n\r\n /**\r\n * Clears current selection when allowed by component settings.\r\n *\r\n * @returns {void}\r\n */\r\n public clearSelection(): void {\r\n this.handleClear();\r\n }\r\n\r\n private handleBlur(): void {\r\n // Focus often moves into the popover top-layer; keep open chrome while open.\r\n if (this.open) return;\r\n this.focused = false;\r\n\r\n if (this.validationActive) {\r\n this.validateInput();\r\n }\r\n }\r\n\r\n override updated(changedProperties: Map<string, unknown>) {\r\n if (changedProperties.has(\"color\")) {\r\n this.style.setProperty(\"--sky-dropdown-color\", resolveColor(this.color));\r\n }\r\n if (changedProperties.has(\"height\")) {\r\n this.style.setProperty(\"--sky-scroll-height\", this.height);\r\n }\r\n }\r\n override willUpdate(changedProperties: Map<string, unknown>) {\r\n if (changedProperties.has(\"customRenderers\")) {\r\n this.syncRendererStateFromProp();\r\n }\r\n\r\n if (changedProperties.has(\"value\")) {\r\n this.syncSelectedItemsWithValue();\r\n this.syncFormValue();\r\n this.syncValidity();\r\n }\r\n\r\n if (changedProperties.has(\"options\")) {\r\n if (!Array.isArray(this.options)) {\r\n this.options = EMPTY_ARRAY;\r\n }\r\n this.syncSelectedItemsWithValue();\r\n this.filterOptions();\r\n this.syncFormValue();\r\n this.syncValidity();\r\n }\r\n\r\n if (changedProperties.has(\"searchable\")) {\r\n this.filterOptions();\r\n }\r\n\r\n if (changedProperties.has(\"searchQuery\") && !this._deferSearchFilter) {\r\n this.filterOptions();\r\n }\r\n }\r\n\r\n /** Merges runtime renderer state (from `customRenderers.$rendererState`) and re-renders. */\r\n patchRendererState(patch: Record<string, unknown>): void {\r\n this._rendererRuntimeState = { ...this._rendererRuntimeState, ...patch };\r\n this.requestUpdate();\r\n }\r\n\r\n private syncRendererStateFromProp(): void {\r\n const fromProp = extractComboboxRendererState(this.customRenderers);\r\n this._rendererRuntimeState = {\r\n ...this._rendererRuntimeState,\r\n ...fromProp,\r\n };\r\n }\r\n\r\n private rendererStateApi(): SkyComboboxRendererStateApi {\r\n return {\r\n rendererState: this._rendererRuntimeState,\r\n patchRendererState: (patch: Record<string, unknown>) =>\r\n this.patchRendererState(patch),\r\n };\r\n }\r\n\r\n private buildOptionRenderContext(args: {\r\n option: unknown;\r\n index: number;\r\n sourceIndex: number;\r\n highlightedLabel: string;\r\n selected: boolean;\r\n active: boolean;\r\n }): SkyComboboxOptionRenderContext {\r\n return {\r\n index: args.index,\r\n sourceIndex: args.sourceIndex,\r\n label: String(this.getOptionLabel(args.option)),\r\n highlightedLabel: args.highlightedLabel,\r\n selected: args.selected,\r\n active: args.active,\r\n multiSelect: this.multiSelect,\r\n ...this.rendererStateApi(),\r\n };\r\n }\r\n\r\n private buildSelectedRenderContext(\r\n option: unknown,\r\n index: number,\r\n ): SkyComboboxSelectedRenderContext {\r\n return {\r\n selectedItems: [...this.selectedItems],\r\n index,\r\n multiSelect: this.multiSelect,\r\n multiDisplay: this.resolveMultiDisplay(),\r\n label: String(this.getOptionLabel(option)),\r\n ...this.rendererStateApi(),\r\n };\r\n }\r\n\r\n private renderOptionContent(args: {\r\n option: unknown;\r\n index: number;\r\n sourceIndex: number;\r\n highlighted: string;\r\n selected: boolean;\r\n active: boolean;\r\n hasSlot: boolean;\r\n slotName: string;\r\n }) {\r\n const defaultLabel = html`<span\r\n class=\"highlighted-text\"\r\n part=\"highlighted-text\"\r\n >${unsafeHTML(args.highlighted)}</span\r\n >`;\r\n\r\n // Named slots win over customRenderers (DOM composition).\r\n if (args.hasSlot) {\r\n return html`\r\n <div style=\"display: flex; gap: 8px;width:100%\">\r\n <slot name=${args.slotName}> ${defaultLabel} </slot>\r\n </div>\r\n `;\r\n }\r\n\r\n const customRenderer = this.customRenderers?.option;\r\n if (customRenderer) {\r\n const content = customRenderer(\r\n args.option,\r\n this.buildOptionRenderContext({\r\n option: args.option,\r\n index: args.index,\r\n sourceIndex: args.sourceIndex,\r\n highlightedLabel: args.highlighted,\r\n selected: args.selected,\r\n active: args.active,\r\n }),\r\n );\r\n return html`<div style=\"display: flex; gap: 8px;width:100%\">\r\n ${content}\r\n </div>`;\r\n }\r\n\r\n return defaultLabel;\r\n }\r\n\r\n private renderSelectedLabel(option: unknown, index: number) {\r\n const customRenderer = this.customRenderers?.selected;\r\n if (customRenderer) {\r\n return customRenderer(option, this.buildSelectedRenderContext(option, index));\r\n }\r\n return this.truncateText(String(this.getOptionLabel(option)), this.chipSize);\r\n }\r\n\r\n private renderSelectedSummaryLabel(option: unknown, index: number) {\r\n const customRenderer = this.customRenderers?.selected;\r\n if (customRenderer) {\r\n return customRenderer(option, this.buildSelectedRenderContext(option, index));\r\n }\r\n return String(this.getOptionLabel(option));\r\n }\r\n\r\n private syncSelectedItemsWithValue(): void {\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n // Treat null/undefined or [] (when multi) as empty\r\n const isEmptyMulti =\r\n this.multiSelect && Array.isArray(this.value) && this.value.length === 0;\r\n\r\n if (this.value == null || this.value === \"\" || isEmptyMulti) {\r\n this.selectedItems = [];\r\n this.value = this.multiSelect ? [] : \"\";\r\n return;\r\n }\r\n\r\n // Back-compat: if someone still passes a JSON stringified array\r\n if (this.multiSelect && typeof this.value === \"string\") {\r\n try {\r\n const parsed = JSON.parse(this.value);\r\n if (Array.isArray(parsed)) this.value = parsed;\r\n } catch (_) {\r\n // ignore non-JSON strings\r\n }\r\n }\r\n\r\n if (this.multiSelect) {\r\n // Normalize incoming to an array\r\n const raw = Array.isArray(this.value) ? this.value : [this.value];\r\n\r\n // Build a comparable key set from provided values\r\n const providedKeys = new Set(raw.map((v) => this.optionKey(v)));\r\n\r\n this.selectedItems = optionsArray.filter((opt) =>\r\n providedKeys.has(this.optionKey(opt)),\r\n );\r\n\r\n // Normalize this.value to the canonical emitted values\r\n this.value = this.selectedItems.map((opt) =>\r\n this.emitFullObject ? opt : this.getOptionValue(opt),\r\n );\r\n } else {\r\n const targetValue = this.optionKey(this.value);\r\n\r\n const selectedOption = optionsArray.find(\r\n (opt) => this.optionKey(opt) === targetValue,\r\n );\r\n\r\n this.selectedItems = selectedOption ? [selectedOption] : [];\r\n this.value = selectedOption\r\n ? this.emitFullObject\r\n ? selectedOption\r\n : this.getOptionValue(selectedOption)\r\n : \"\";\r\n }\r\n }\r\n\r\n private filterOptions(): void {\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n const makeRow = (option: any, idx: number) => {\r\n const label = this.getOptionLabel(option);\r\n return {\r\n original: option,\r\n _idx: idx,\r\n label,\r\n highlighted: label,\r\n };\r\n };\r\n\r\n if (!this.searchable || !this.searchQuery.trim()) {\r\n this.filteredOptions = optionsArray.map(makeRow);\r\n return;\r\n }\r\n\r\n const query = this.searchQuery.toLowerCase();\r\n\r\n this.filteredOptions = optionsArray\r\n .map(makeRow)\r\n .filter((row) => String(row.label).toLowerCase().includes(query))\r\n .map((row) => {\r\n const regex = new RegExp(`(${query})`, \"gi\");\r\n return {\r\n ...row,\r\n highlighted: String(row.label).replace(\r\n regex,\r\n (m: string) => `<span class=\"highlight\">${m}</span>`,\r\n ),\r\n };\r\n });\r\n }\r\n\r\n\r\n /** Emit search query for hosts / `v-model:search-query` when `searchQuery` changes outside the search input handler. */\r\n private emitSearchQueryChanged(): void {\r\n this.dispatchEvent(\r\n new CustomEvent<SkyComboboxSearchQueryChangedDetail>(\"search-query-changed\", {\r\n detail: { searchQuery: this.searchQuery },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n\r\n private handleSearchValueChanged(\r\n event: CustomEvent<{ value: string | number }>,\r\n ): void {\r\n event.stopPropagation();\r\n if (this.disabled || this.readonly) return;\r\n this.applySearchQuery(String(event.detail?.value ?? \"\"));\r\n }\r\n\r\n private handleSearchValueCleared(event: Event): void {\r\n event.stopPropagation();\r\n if (this.disabled || this.readonly) return;\r\n this.applySearchQuery(\"\");\r\n }\r\n\r\n private applySearchQuery(raw: string): void {\r\n const optionsLength = Array.isArray(this.options) ? this.options.length : 0;\r\n const shouldDebounce =\r\n this.searchable &&\r\n raw.trim().length > 0 &&\r\n optionsLength > SkyCombobox._SEARCH_DEBOUNCE_OPTIONS_THRESHOLD;\r\n\r\n if (this._searchDebounceId != null) {\r\n clearTimeout(this._searchDebounceId);\r\n this._searchDebounceId = null;\r\n }\r\n\r\n if (shouldDebounce) {\r\n this._deferSearchFilter = true;\r\n this.searchQuery = raw;\r\n this._searchDebounceId = setTimeout(() => {\r\n this._searchDebounceId = null;\r\n this._deferSearchFilter = false;\r\n this.filterOptions();\r\n this.emitSearchQueryChanged();\r\n }, SkyCombobox._SEARCH_DEBOUNCE_MS);\r\n return;\r\n }\r\n\r\n this._deferSearchFilter = false;\r\n this.searchQuery = raw;\r\n this.filterOptions();\r\n this.emitSearchQueryChanged();\r\n }\r\n\r\n override disconnectedCallback() {\r\n super.disconnectedCallback();\r\n this._deferSearchFilter = false;\r\n if (this._searchDebounceId != null) {\r\n clearTimeout(this._searchDebounceId);\r\n this._searchDebounceId = null;\r\n }\r\n if (this._closeResetId != null) {\r\n clearTimeout(this._closeResetId);\r\n this._closeResetId = null;\r\n }\r\n }\r\n\r\n private handleClear(): void {\r\n if (this.disabled || this.readonly) return;\r\n\r\n const hasSelection = this.multiSelect\r\n ? this.selectedItems.length > 0\r\n : !!this.value;\r\n\r\n if (this.enforceMinOneSelection && hasSelection) {\r\n return;\r\n }\r\n this.value = this.multiSelect ? [] : \"\";\r\n this.selectedItems = [];\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.open = false;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent<SkyComboboxValueChangedDetail>(\"value-changed\", {\r\n detail: {\r\n value: this.value,\r\n selectedItems: [],\r\n isFilteredSelection: false,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n\r\n this.syncFormValue();\r\n this.syncValidity();\r\n }\r\n\r\n selectOption(option: any) {\r\n if (this.disabled || this.readonly) return;\r\n\r\n const getEmittedValue = (item: any) => {\r\n return this.emitFullObject ? item : this.getOptionValue(item);\r\n };\r\n\r\n const wasFiltered = this.searchQuery.trim() !== \"\";\r\n\r\n if (!this.multiSelect) {\r\n const alreadySelected =\r\n this.selectedItems.length &&\r\n this.optionKey(this.selectedItems[0]) === this.optionKey(option);\r\n\r\n if (alreadySelected && this.enforceMinOneSelection) {\r\n this.open = false;\r\n return;\r\n }\r\n\r\n if (alreadySelected) {\r\n this.selectedItems = [];\r\n this.value = \"\";\r\n } else {\r\n this.selectedItems = [option];\r\n this.value = getEmittedValue(option);\r\n }\r\n\r\n this.validateInput();\r\n\r\n this.dispatchEvent(\r\n new CustomEvent(\"value-changed\", {\r\n detail: {\r\n value: this.value,\r\n selectedItems: this.selectedItems,\r\n emittedValues: this.selectedItems.map(getEmittedValue),\r\n isFilteredSelection: wasFiltered,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n\r\n // Search reset is deferred in onOpenChange so options stay visible during close animation.\r\n this.dropdownPopover.closePopover(\"api\");\r\n this.syncFormValue();\r\n this.syncValidity();\r\n this.requestUpdate();\r\n return;\r\n }\r\n\r\n const index = this.selectedItems.findIndex(\r\n (item) => this.optionKey(item) === this.optionKey(option),\r\n );\r\n\r\n let nextSelected: any[];\r\n\r\n if (index > -1) {\r\n nextSelected = [\r\n ...this.selectedItems.slice(0, index),\r\n ...this.selectedItems.slice(index + 1),\r\n ];\r\n } else {\r\n nextSelected = [...this.selectedItems, option];\r\n }\r\n\r\n if (this.enforceMinOneSelection && nextSelected.length === 0) {\r\n return;\r\n }\r\n\r\n this.selectedItems = nextSelected;\r\n this.value = nextSelected.map(getEmittedValue);\r\n\r\n this.validateInput();\r\n\r\n this.dispatchEvent(\r\n new CustomEvent(\"value-changed\", {\r\n detail: {\r\n value: this.value,\r\n selectedItems: this.selectedItems,\r\n emittedValues: this.value,\r\n isFilteredSelection: wasFiltered,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n\r\n this.syncFormValue();\r\n this.syncValidity();\r\n this.open = true;\r\n this.requestUpdate();\r\n }\r\n\r\n toggleHiddenChips(e: Event) {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n if (this.disabled || this.readonly) return;\r\n\r\n // close main dropdown if open\r\n if (this.open) {\r\n this.dropdownPopover.closePopover(\"api\");\r\n }\r\n\r\n this.hiddenPopover.toggle();\r\n }\r\n\r\n\r\n renderHiddenChipsDropdown() {\r\n return html`\r\n <div\r\n class=\"hidden-chips-dropdown\"\r\n part=\"hidden-chips-dropdown\"\r\n popover=\"manual\"\r\n @toggle=${this.hiddenPopover.onToggle}\r\n @click=${(e: MouseEvent) => e.stopPropagation()}\r\n style=\"\r\n left: var(--sky-hc-left, 0px);\r\n top: var(--sky-hc-top, 0px);\r\n width: var(--sky-hc-width, max-content);\r\n z-index: ${this.zIndex};\r\n \"\r\n >\r\n ${repeat(\r\n this.selectedItems.slice(this.visibleChips),\r\n (item) => this.optionKey(item),\r\n (item) => html`\r\n <div class=\"hidden-chip-inner\" part=\"hidden-chip-inner\">\r\n <span part=\"hidden-chip-label\">\r\n ${this.renderSelectedLabel(\r\n item,\r\n this.selectedItems.indexOf(item),\r\n )}\r\n </span>\r\n <sky-icon\r\n part=\"remove-chip-icon\"\r\n class=\"remove-chip-inner\"\r\n icon=\"ion:close\"\r\n @click=${(e: MouseEvent) => {\r\n e.stopPropagation();\r\n this.removeChip(item);\r\n }}\r\n ></sky-icon>\r\n </div>\r\n `,\r\n )}\r\n </div>\r\n `;\r\n }\r\n\r\n removeChip(option: any) {\r\n if (this.disabled || this.readonly) return;\r\n\r\n const next = this.selectedItems.filter(\r\n (item) => this.optionKey(item) !== this.optionKey(option),\r\n );\r\n\r\n // 🚫 prevent going below 1 selection when enforced\r\n if (this.enforceMinOneSelection && next.length === 0) {\r\n return;\r\n }\r\n\r\n this.selectedItems = next;\r\n if (this.selectedItems.length <= this.visibleChips) {\r\n this.hiddenPopover.closePopover(\"api\");\r\n }\r\n\r\n if (this.multiSelect) {\r\n const valuesArray = this.selectedItems.map((opt) =>\r\n this.emitFullObject ? opt : this.getOptionValue(opt),\r\n );\r\n this.value = valuesArray;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent(\"value-changed\", {\r\n detail: {\r\n value: valuesArray,\r\n selectedItems: [...this.selectedItems],\r\n emittedValues: valuesArray,\r\n isFilteredSelection: false,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n } else {\r\n this.value = \"\";\r\n this.dispatchEvent(\r\n new CustomEvent(\"value-changed\", {\r\n detail: {\r\n value: this.value,\r\n selectedItems: [],\r\n isFilteredSelection: false,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n\r\n this.syncFormValue();\r\n this.syncValidity();\r\n this.validateInput();\r\n this.requestUpdate();\r\n }\r\n\r\n renderChips() {\r\n // Multi-select chips only — single-select uses value-summary (no chip padding)\r\n const visible = Array.isArray(this.selectedItems)\r\n ? this.selectedItems.slice(0, this.visibleChips)\r\n : [];\r\n const overflow = this.selectedItems.length - this.visibleChips;\r\n return html`\r\n ${repeat(\r\n visible,\r\n (item) => this.optionKey(item),\r\n (item, index) => html`\r\n <span class=\"chip\" ?compact=${this.compact} part=\"chip\">\r\n <span class=\"chip-label\" part=\"chip-label\"\r\n >${this.renderSelectedLabel(item, index)}</span\r\n >\r\n ${when(\r\n this.multiSelect,\r\n () => html`\r\n <sky-icon\r\n class=\"remove-chip\"\r\n part=\"remove-chip-icon\"\r\n ?compact=${this.compact}\r\n @click=${(e: MouseEvent) => {\r\n e.stopPropagation();\r\n this.removeChip(item);\r\n }}\r\n icon=\"ion:close\"\r\n ></sky-icon>\r\n `,\r\n )}\r\n </span>\r\n `,\r\n )}\r\n ${when(\r\n overflow > 0,\r\n () => html`\r\n <span\r\n class=\"chip overflow-chip\"\r\n part=\"overflow-chip\"\r\n style=\"cursor:pointer\"\r\n ?compact=${this.compact}\r\n @click=${this.toggleHiddenChips}\r\n >\r\n + ${overflow}\r\n </span>\r\n `,\r\n )}\r\n `;\r\n }\r\n\r\n private resolveMultiDisplay(): SkyComboboxMultiDisplay {\r\n const mode = this.multiDisplay;\r\n if (mode === \"text\" || mode === \"count\" || mode === \"chips\") return mode;\r\n return \"chips\";\r\n }\r\n\r\n /** Selected value area: chips, joined text, or count summary. */\r\n private renderSelectedValue() {\r\n if (!this.selectedItems.length) return null;\r\n\r\n // Single-select: plain text (no chip chrome / padding)\r\n if (!this.multiSelect) {\r\n const item = this.selectedItems[0];\r\n const label = String(this.getOptionLabel(item));\r\n return html`\r\n <span\r\n class=\"value-summary\"\r\n part=\"value-summary single-select-chip\"\r\n title=${label}\r\n >${this.renderSelectedSummaryLabel(item, 0)}</span\r\n >\r\n `;\r\n }\r\n\r\n const mode = this.resolveMultiDisplay();\r\n\r\n if (mode === \"text\") {\r\n const customRenderer = this.customRenderers?.selected;\r\n if (customRenderer) {\r\n return html`\r\n <span class=\"value-summary\" part=\"value-summary\">\r\n ${this.selectedItems.map(\r\n (item, index) => html`${index > 0 ? \", \" : \"\"}${customRenderer(\r\n item,\r\n this.buildSelectedRenderContext(item, index),\r\n )}`,\r\n )}\r\n </span>\r\n `;\r\n }\r\n const joined = this.selectedItems\r\n .map((item) => String(this.getOptionLabel(item)))\r\n .join(\", \");\r\n return html`\r\n <span class=\"value-summary\" part=\"value-summary\" title=${joined}\r\n >${joined}</span\r\n >\r\n `;\r\n }\r\n\r\n if (mode === \"count\") {\r\n const n = this.selectedItems.length;\r\n const first = String(this.getOptionLabel(this.selectedItems[0]));\r\n const summary = n === 1 ? first : `${first} +${n - 1}`;\r\n const title = this.selectedItems\r\n .map((item) => String(this.getOptionLabel(item)))\r\n .join(\", \");\r\n const customRenderer = this.customRenderers?.selected;\r\n if (customRenderer) {\r\n return html`\r\n <span class=\"value-summary\" part=\"value-summary\" title=${title}>\r\n ${customRenderer(\r\n this.selectedItems[0],\r\n this.buildSelectedRenderContext(this.selectedItems[0], 0),\r\n )}${n > 1 ? ` +${n - 1}` : nothing}\r\n </span>\r\n `;\r\n }\r\n return html`\r\n <span class=\"value-summary\" part=\"value-summary\" title=${title}\r\n >${summary}</span\r\n >\r\n `;\r\n }\r\n\r\n return html`\r\n <div class=\"chip-container\" part=\"chip-container\" ?compact=${this.compact}>\r\n ${this.renderChips()}\r\n </div>\r\n `;\r\n }\r\n\r\n handleKeydown(event: KeyboardEvent) {\r\n if ((event.target as HTMLElement)?.closest(\".search-container\")) return;\r\n const { key, shiftKey } = event;\r\n\r\n if (!this.open && (key === \"ArrowDown\" || key === \"ArrowUp\" || key === \"Enter\")) {\r\n this.dropdownPopover.openPopover();\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (!this.open) return;\r\n\r\n const hasSearchRow = this.searchable || this.addOption;\r\n const firstSelectableIndex =\r\n this.multiSelect && this.selectAll\r\n ? hasSearchRow\r\n ? 1\r\n : 0\r\n : this.headerRows;\r\n\r\n const minIndex = firstSelectableIndex;\r\n const maxIndex =\r\n this.headerRows + Math.max(0, this.filteredOptions.length) - 1;\r\n\r\n if (this.activeIndex < minIndex) this.activeIndex = minIndex;\r\n\r\n if (key === \"ArrowDown\") {\r\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\r\n this.activeIndex = was >= maxIndex ? minIndex : was + 1;\r\n this.scrollActiveItemIntoView();\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (key === \"ArrowUp\") {\r\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\r\n this.activeIndex = was <= minIndex ? maxIndex : was - 1;\r\n this.scrollActiveItemIntoView();\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (key === \"Tab\") {\r\n if (shiftKey) {\r\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\r\n this.activeIndex = was <= minIndex ? maxIndex : was - 1;\r\n } else {\r\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\r\n this.activeIndex = was >= maxIndex ? minIndex : was + 1;\r\n }\r\n this.scrollActiveItemIntoView();\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (key === \"Enter\") {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.commitDropdownEnter();\r\n return;\r\n }\r\n\r\n if (this.readonly) {\r\n if (key === \"Escape\") {\r\n this.open = false;\r\n event.preventDefault();\r\n }\r\n return;\r\n }\r\n\r\n if (key === \"Home\") {\r\n this.activeIndex = minIndex;\r\n this.scrollActiveItemIntoView();\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (key === \"End\") {\r\n this.activeIndex = Math.max(minIndex, maxIndex);\r\n this.scrollActiveItemIntoView();\r\n event.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n private onSearchKeydown = (e: KeyboardEvent) => {\r\n const { key, shiftKey } = e;\r\n\r\n if (key === \"Enter\") {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.commitDropdownEnter();\r\n return;\r\n }\r\n\r\n if (key === \"ArrowDown\" || key === \"ArrowUp\" || key === \"Tab\") {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n const hasSearchRow = this.searchable || this.addOption;\r\n const firstSelectableIndex =\r\n this.multiSelect && this.selectAll\r\n ? hasSearchRow\r\n ? 1\r\n : 0\r\n : this.headerRows;\r\n\r\n const minIndex = firstSelectableIndex;\r\n const maxIndex =\r\n this.headerRows + Math.max(0, this.filteredOptions.length) - 1;\r\n\r\n const dir = key === \"ArrowUp\" || (key === \"Tab\" && e.shiftKey) ? -1 : 1;\r\n if (this.activeIndex < minIndex) this.activeIndex = minIndex;\r\n else\r\n this.activeIndex =\r\n this.activeIndex + dir < minIndex\r\n ? maxIndex\r\n : this.activeIndex + dir > maxIndex\r\n ? minIndex\r\n : this.activeIndex + dir;\r\n\r\n this.scrollActiveItemIntoView();\r\n }\r\n\r\n if (key === \"Escape\") {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.dropdownPopover.closePopover(\"escape\");\r\n return;\r\n }\r\n };\r\n\r\n /** Number of non-option rows before the first option (search + select-all). */\r\n private get headerRows(): number {\r\n let n = 0;\r\n if (this.searchable || this.addOption) n += 1;\r\n if (this.multiSelect && this.selectAll) n += 1;\r\n return n;\r\n }\r\n\r\n\r\n private getOptionByActiveIndex(): {\r\n kind: \"search\" | \"select-all\" | \"option\";\r\n optionIndex?: number;\r\n } | null {\r\n if (!this.open) return null;\r\n const idx = this.activeIndex;\r\n if (idx < 0) return null;\r\n\r\n if (this.searchable || this.addOption) {\r\n if (idx === 0) return { kind: \"search\" };\r\n }\r\n\r\n const selectAllBase = this.searchable || this.addOption ? 1 : 0;\r\n if (this.multiSelect && this.selectAll && idx === selectAllBase) {\r\n return { kind: \"select-all\" };\r\n }\r\n\r\n const optionIndex = idx - this.headerRows;\r\n if (optionIndex >= 0 && optionIndex < this.filteredOptions.length) {\r\n return { kind: \"option\", optionIndex };\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Commits the current keyboard highlight on Enter (search row vs select-all vs option).\r\n * Shared by {@link handleKeydown} and {@link onSearchKeydown} so focus in the search\r\n * field matches the same semantics as the input wrapper.\r\n */\r\n private commitDropdownEnter(): void {\r\n const target = this.getOptionByActiveIndex();\r\n if (!target) return;\r\n\r\n if (target.kind === \"search\") {\r\n if (this.addOption && this.canAddaddOption()) {\r\n this.dispatchEvent(\r\n new CustomEvent(\"add-new-option\", {\r\n detail: { value: this.searchQuery.trim() },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.filterOptions();\r\n } else if (this.filteredOptions.length > 0) {\r\n this.selectOption(this.filteredOptions[0].original);\r\n }\r\n return;\r\n }\r\n if (target.kind === \"select-all\") {\r\n this.toggleSelectAll();\r\n return;\r\n }\r\n if (target.kind === \"option\" && typeof target.optionIndex === \"number\") {\r\n const selectedOption =\r\n this.filteredOptions[target.optionIndex].original;\r\n this.selectOption(selectedOption);\r\n }\r\n }\r\n\r\n /** Focus logic when opening the dropdown. */\r\n private focusOnOpen() {\r\n const search = this.searchInputEl;\r\n if (search && document.activeElement !== search) {\r\n requestAnimationFrame(() => search.focus());\r\n }\r\n\r\n // Highlight first selected option (or first option), not the search row —\r\n // so selected/active chrome is visible as soon as the list opens.\r\n if (this.filteredOptions.length > 0) {\r\n let optionIdx = 0;\r\n if (this.selectedItems.length > 0) {\r\n const firstSelKey = this.optionKey(this.selectedItems[0]);\r\n const idxInFiltered = this.filteredOptions.findIndex(\r\n (o) => this.optionKey(o.original) === firstSelKey,\r\n );\r\n if (idxInFiltered >= 0) optionIdx = idxInFiltered;\r\n }\r\n this.activeIndex = this.headerRows + optionIdx;\r\n this.scrollActiveItemIntoView();\r\n return;\r\n }\r\n\r\n this.activeIndex = this.searchable || this.addOption ? 0 : -1;\r\n }\r\n\r\n private canAddaddOption(): boolean {\r\n if (!this.addOption) return false;\r\n const q = this.searchQuery.trim();\r\n if (!q) return false;\r\n\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n const dup = optionsArray.some((opt) => {\r\n const label = String(this.getOptionLabel(opt) || \"\").toLowerCase();\r\n const val = (this.getOptionValue(opt) ?? \"\").toString().toLowerCase();\r\n return label === q.toLowerCase() || val === q.toLowerCase();\r\n });\r\n return !dup;\r\n }\r\n private handleAddaddOption = (e: MouseEvent) => {\r\n e.stopPropagation();\r\n if (this.disabled || this.readonly) return;\r\n if (!this.canAddaddOption()) return;\r\n\r\n const value = this.searchQuery.trim();\r\n\r\n this.dispatchEvent(\r\n new CustomEvent(\"add-new-option\", {\r\n detail: { value },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.filterOptions();\r\n };\r\n\r\n scrollActiveItemIntoView() {\r\n const rows = Array.from(this.rowEls);\r\n const active = rows.find(\r\n (r) => Number(r.dataset.rowIndex) === this.activeIndex,\r\n );\r\n active?.scrollIntoView({ block: \"nearest\", behavior: \"smooth\" });\r\n }\r\n\r\n toggleDropdown(event: MouseEvent) {\r\n event.stopPropagation();\r\n if (this.disabled || this.readonly) return;\r\n\r\n // close hidden chips if open\r\n if (this.hiddenChipsOpen) {\r\n this.hiddenPopover.closePopover(\"api\");\r\n }\r\n\r\n this.validationActive = true;\r\n this.dropdownPopover.toggle();\r\n }\r\n\r\n\r\n\r\n renderDropdown() {\r\n return html`\r\n <div\r\n class=\"dropdown\"\r\n part=\"dropdown\"\r\n popover=\"manual\"\r\n @toggle=${this.dropdownPopover.onToggle}\r\n @click=${(e: MouseEvent) => e.stopPropagation()}\r\n style=\"\r\n left: var(--sky-dd-left, 0px);\r\n top: var(--sky-dd-top, 0px);\r\n min-width: var(--sky-dd-width, 100%);\r\n \"\r\n >\r\n ${when(\r\n this.searchable || this.addOption,\r\n () => html`\r\n <div\r\n class=\"search-container\"\r\n data-row-index=\"0\"\r\n part=\"search-container\"\r\n >\r\n <sky-input\r\n class=\"dropdown-search-input\"\r\n compact\r\n clearable\r\n part=\"search-input\"\r\n tabindex=\"0\"\r\n ?readonly=${this.readonly ||\r\n (!this.searchable && !this.addOption)}\r\n ?disabled=${this.disabled}\r\n placeholder=${this.searchPlaceholder}\r\n .value=${this.searchQuery}\r\n @value-changed=${this.searchable || this.addOption\r\n ? this.handleSearchValueChanged\r\n : null}\r\n @value-cleared=${this.searchable || this.addOption\r\n ? this.handleSearchValueCleared\r\n : null}\r\n @keydown=${this.onSearchKeydown}\r\n @focus=${this.searchable || this.addOption\r\n ? this.handleFocus\r\n : null}\r\n @blur=${this.searchable || this.addOption\r\n ? this.handleBlur\r\n : null}\r\n >\r\n <sky-icon slot=\"icon-left\" icon=\"ion:search\"></sky-icon>\r\n </sky-input>\r\n\r\n ${when(\r\n this.addOption,\r\n () => html`\r\n <sky-icon\r\n class=\"new-option-btn\"\r\n icon=\"ion:add\"\r\n part=\"add-option-icon\"\r\n title=\"Add as new option\"\r\n aria-label=\"Add as new option\"\r\n @click=${this.handleAddaddOption}\r\n ></sky-icon>\r\n `,\r\n )}\r\n </div>\r\n `,\r\n )}\r\n\r\n<div class=\"dropdown-scroller\">\r\n ${when(\r\n this.multiSelect && this.selectAll && this.filteredOptions.length,\r\n () => {\r\n const selectAllRowIndex = this.searchable || this.addOption ? 1 : 0;\r\n const selectAllClasses = classMap({\r\n \"dropdown-item\": true,\r\n active: this.activeIndex === selectAllRowIndex,\r\n selected: this.isAllFilteredSelected(),\r\n });\r\n return html`\r\n <div\r\n class=${selectAllClasses}\r\n data-row-index=${selectAllRowIndex}\r\n style=\"justify-content: ${this.justify};\"\r\n part=\"select-all\"\r\n @click=${this.toggleSelectAll}\r\n >\r\n <sky-checkbox\r\n .checked=${this.isAllFilteredSelected()}\r\n readonly\r\n ></sky-checkbox>\r\n Select All\r\n </div>\r\n `;\r\n },\r\n )}\r\n ${when(\r\n this.filteredOptions.length > 0,\r\n () => repeat(\r\n this.filteredOptions,\r\n ({ original, _idx }) => `${_idx}-${this.optionKey(original)}`,\r\n ({ original, highlighted, _idx }, index) => {\r\n const slotName = `option-${_idx}`;\r\n const hasSlot = this.optionSlotSet.has(slotName);\r\n\r\n const isSelected =\r\n Array.isArray(this.selectedItems) &&\r\n this.selectedItems.some(\r\n (item) => this.optionKey(item) === this.optionKey(original),\r\n );\r\n const rowIndex = this.headerRows + index;\r\n const isActive = rowIndex === this.activeIndex;\r\n const itemClasses = classMap({\r\n \"dropdown-item\": true,\r\n active: isActive,\r\n selected: isSelected,\r\n });\r\n\r\n return html`\r\n <div\r\n class=${itemClasses}\r\n data-row-index=${rowIndex}\r\n style=\"justify-content: ${this.justify};\"\r\n part=\"option\"\r\n @click=${() => this.selectOption(original)}\r\n @pointerenter=${() => {\r\n this.activeIndex = rowIndex;\r\n }}\r\n ?compact=${this.compact}\r\n >\r\n ${when(\r\n this.multiSelect,\r\n () => html` <sky-checkbox\r\n .checked=${isSelected}\r\n readonly\r\n ></sky-checkbox>`,\r\n )}\r\n ${this.renderOptionContent({\r\n option: original,\r\n index,\r\n sourceIndex: _idx,\r\n highlighted,\r\n selected: isSelected,\r\n active: isActive,\r\n hasSlot,\r\n slotName,\r\n })}\r\n </div>\r\n `;\r\n },\r\n ),\r\n () => html`<div\r\n class=\"dropdown-item\"\r\n part=\"no-options\"\r\n data-row-index=${this.headerRows}\r\n >\r\n No options found\r\n </div>`,\r\n )}\r\n </div>\r\n </div>\r\n `;\r\n }\r\n\r\n\r\n getOptionValue(option: any): any {\r\n if (this.emitFullObject) {\r\n return option; // Return the full object\r\n }\r\n\r\n // When emitFullObject is false, return the emittedKey value\r\n if (typeof option === \"object\" && option !== null) {\r\n // First try the emittedKey\r\n if (this.emittedKey in option) {\r\n return option[this.emittedKey];\r\n }\r\n // Fallback to any value property\r\n if (\"value\" in option) {\r\n return option.value;\r\n }\r\n // Fallback to the object itself\r\n return option;\r\n }\r\n\r\n return option;\r\n }\r\n\r\n /**\r\n * Stable string key for comparing options / selection identity.\r\n * Prefer `emittedKey` when present on object options; for other objects use\r\n * JSON.stringify — never String(object) (\"[object Object]\"), which makes every\r\n * option look selected when `emitFullObject` is true.\r\n */\r\n private optionKey(option: any): string {\r\n if (option == null) return String(option);\r\n\r\n if (typeof option === \"object\") {\r\n if (this.emittedKey && this.emittedKey in option) {\r\n const keyVal = option[this.emittedKey];\r\n return typeof keyVal === \"object\" && keyVal !== null\r\n ? JSON.stringify(keyVal)\r\n : String(keyVal);\r\n }\r\n\r\n const val = this.getOptionValue(option);\r\n if (typeof val === \"object\" && val !== null) {\r\n return JSON.stringify(val);\r\n }\r\n return String(val ?? \"\");\r\n }\r\n\r\n return String(option);\r\n }\r\n\r\n getOptionLabel(option: any): string {\r\n if (!option) return \"\";\r\n\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n if (\r\n this.displayKey &&\r\n typeof option === \"object\" &&\r\n option[this.displayKey]\r\n ) {\r\n return String(option[this.displayKey]);\r\n }\r\n\r\n if (typeof option === \"object\") {\r\n const stringValues = Object.values(option).filter(\r\n (value) => typeof value === \"string\",\r\n ) as string[];\r\n return stringValues.length > 0 ? stringValues[0]! : JSON.stringify(option);\r\n }\r\n\r\n return String(option);\r\n }\r\n\r\n renderValidationErrors() {\r\n if (!this.showErrors || !this.validationActive) return null;\r\n\r\n const msgs = this.getErrorMessages();\r\n\r\n if (!msgs.length) return null;\r\n\r\n const errId = `${this.id || \"sky-combobox\"}-errors`;\r\n\r\n return html`\r\n <div class=\"progress-message\">\r\n <ul id=${errId} class=\"error-list\" part=\"error-list\">\r\n ${repeat(msgs, (m) => m, (m) => html`<li class=\"error\" part=\"error-item\">${m}</li>`)}\r\n </ul>\r\n </div>\r\n `;\r\n }\r\n\r\n getErrorMessages() {\r\n const errs = Array.isArray(this.validationErrors)\r\n ? this.validationErrors\r\n : [];\r\n switch (this.errorDisplayMode) {\r\n case \"single\":\r\n return errs.slice(0, 1);\r\n case \"all\":\r\n return errs;\r\n case \"none\":\r\n default:\r\n return [];\r\n }\r\n }\r\n\r\n handleIconClick(position: \"left\" | \"right\", event: MouseEvent) {\r\n this.dispatchEvent(\r\n new CustomEvent(\"icon-click\", {\r\n detail: { position, event },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n\r\n private onIconSlotChange = () => {\r\n this.hasLeftIcon = (this.iconLeftEls?.length ?? 0) > 0;\r\n this.hasRightIcon = (this.iconRightEls?.length ?? 0) > 0;\r\n };\r\n\r\n override render() {\r\n const leftIconClasses = classMap({ \"icon-slot\": true, left: true, focused: this.focused });\r\n const rightIconClasses = classMap({ \"icon-slot\": true, right: true, focused: this.focused });\r\n const placeholderClasses = classMap({\r\n \"placeholder-label\": true,\r\n active: this.selectedItems.length > 0,\r\n });\r\n\r\n const isFieldset = this.variant === \"fieldset\";\r\n const isInside = this.variant === \"inside\";\r\n const labelEl = this.label\r\n ? isFieldset\r\n ? html`<legend class=\"label\" part=\"label\"><span class=\"legend-text\">${this.label}</span></legend>`\r\n : html`<div class=\"label\" part=\"label\">${this.label}</div>`\r\n : null;\r\n\r\n const leftIcon = html`\r\n <div\r\n class=${leftIconClasses}\r\n part=\"icon-slot\"\r\n ?filled=${this.hasLeftIcon}\r\n @click=${(e: MouseEvent) => this.handleIconClick(\"left\", e)}\r\n >\r\n <slot name=\"icon-left\" @slotchange=${this.onIconSlotChange}></slot>\r\n </div>\r\n `;\r\n\r\n const valueArea = when(\r\n this.selectedItems.length > 0,\r\n () => this.renderSelectedValue(),\r\n () => html`<label\r\n class=${placeholderClasses}\r\n part=\"placeholder-label\"\r\n ?compact=${this.compact}\r\n >\r\n <span style=\"color:${this.prefixColor}\">${this.prefix}</span\r\n >${this.placeholder}<span style=\"color:${this.suffixColor}\"\r\n >${this.suffix}</span\r\n >\r\n </label>`,\r\n );\r\n\r\n const trailingActions = html`\r\n <div class=\"field-trailing\" part=\"field-trailing\">\r\n ${when(\r\n this.clearable &&\r\n !this.enforceMinOneSelection &&\r\n (this.value || this.selectedItems.length),\r\n () => html`<sky-icon\r\n class=\"clear-button\"\r\n part=\"clear-button\"\r\n ?compact=${this.compact}\r\n @click=${(e: MouseEvent) => {\r\n e.stopPropagation();\r\n this.handleClear();\r\n }}\r\n ?loading=${this.loading}\r\n icon=\"ion:close\"\r\n ></sky-icon>`,\r\n )}\r\n ${when(\r\n this.loading,\r\n () => html`<div class=\"loading-indicator right\"></div>`,\r\n () =>\r\n this.hasRightIcon\r\n ? html`<div\r\n part=\"icon-slot\"\r\n class=${rightIconClasses}\r\n ?filled=${true}\r\n @click=${(e: MouseEvent) => this.handleIconClick(\"right\", e)}\r\n >\r\n <slot\r\n name=\"icon-right\"\r\n @slotchange=${this.onIconSlotChange}\r\n ></slot>\r\n </div>`\r\n : html`<slot\r\n name=\"icon-right\"\r\n style=\"display:none\"\r\n @slotchange=${this.onIconSlotChange}\r\n ></slot>`,\r\n )}\r\n <sky-icon\r\n class=\"dropdown-button\"\r\n part=\"dropdown-button\"\r\n ?compact=${this.compact}\r\n @click=${(e: MouseEvent) => {\r\n e.stopPropagation();\r\n if (!this.disabled && !this.readonly) {\r\n this.toggleDropdown(e);\r\n }\r\n }}\r\n icon=${this.open ? \"ion:ios-arrow-up\" : \"ion:chevron-down\"}\r\n >\r\n </sky-icon>\r\n </div>\r\n `;\r\n\r\n const defaultFieldContent = html`\r\n ${leftIcon}\r\n <div class=\"field-main\" part=\"field-main\">${valueArea}</div>\r\n ${this.readonly ? nothing : trailingActions}\r\n `;\r\n\r\n const insideFieldContent = html`\r\n ${leftIcon}\r\n <div class=\"input-inside-main\">\r\n ${labelEl}\r\n <div class=\"input-inside-row\">\r\n <div class=\"field-main\" part=\"field-main\">${valueArea}</div>\r\n </div>\r\n </div>\r\n ${this.readonly ? nothing : trailingActions}\r\n `;\r\n\r\n const fieldBody = isInside ? insideFieldContent : defaultFieldContent;\r\n\r\n const wrapperHandlers = {\r\n click: (e: MouseEvent) => {\r\n if (!this.disabled && !this.readonly) {\r\n this.toggleDropdown(e);\r\n }\r\n },\r\n keydown: this.handleKeydown,\r\n };\r\n\r\n const fieldWrapper = isFieldset\r\n ? html`\r\n <fieldset\r\n class=\"input-wrapper\"\r\n tabindex=\"0\"\r\n part=\"input-wrapper\"\r\n ?disabled=${this.disabled}\r\n ?compact=${this.compact}\r\n ?loading=${this.loading}\r\n ?open=${this.open}\r\n ?invalid=${this.invalid}\r\n @click=${wrapperHandlers.click}\r\n @keydown=${wrapperHandlers.keydown}\r\n >\r\n ${labelEl}\r\n <div class=\"input-fieldset-body\">${fieldBody}</div>\r\n </fieldset>\r\n `\r\n : html`\r\n <div\r\n class=\"input-wrapper\"\r\n tabindex=\"0\"\r\n part=\"input-wrapper\"\r\n ?disabled=${this.disabled}\r\n ?compact=${this.compact}\r\n ?loading=${this.loading}\r\n ?open=${this.open}\r\n ?invalid=${this.invalid}\r\n @click=${wrapperHandlers.click}\r\n @keydown=${wrapperHandlers.keydown}\r\n >\r\n ${fieldBody}\r\n </div>\r\n `;\r\n\r\n return html`\r\n <div class=\"combo-box-container\" part=\"combo-box-container\">\r\n ${!isFieldset && !isInside ? labelEl : nothing}\r\n ${fieldWrapper}\r\n ${this.renderHiddenChipsDropdown()} ${this.renderDropdown()}\r\n ${this.renderValidationErrors()}\r\n <slot style=\"display:none\" @slotchange=${this.refreshOptionSlots}></slot>\r\n </div>\r\n `;\r\n }\r\n}\r\n"],"names":["COMBOBOX_RENDERERS_STATE_KEY","EMPTY_RENDERERS","Object","freeze","extractComboboxRendererState","customRenderers","bag","value","Array","isArray","o","option","selected","isComboboxRendererStateBag","SkyCombobox","FormControlBase","constructor","super","this","placeholder","searchPlaceholder","label","_options","EMPTY_ARRAY","chipSize","color","clearable","loading","compact","disabled","searchable","multiSelect","visibleChips","selectAll","_validations","showErrors","errorDisplayMode","required","emitFullObject","emittedKey","displayKey","_customRenderers","addOption","validationArrayFormat","prefix","suffix","prefixColor","suffixColor","justify","zIndex","height","requiredMessage","readonly","enforceMinOneSelection","openAbove","validationActive","invalid","variant","multiDisplay","searchQuery","filteredOptions","focused","open","selectedItems","hiddenChipsOpen","activeIndex","validationErrors","validationStatus","hasLeftIcon","hasRightIcon","optionSlotSet","Set","_rendererRuntimeState","_searchDebounceId","_deferSearchFilter","_closeResetId","dropdownPopover","PopoverController","getAnchor","inputWrapperEl","getPopover","dropdownEl","cssVarLeft","cssVarTop","cssVarWidth","getPlacement","getAlign","getGap","getPadding","getMatchAnchorWidth","getMaxWidthToViewport","getMaxWidthMode","getFlip","getFlipOrder","getAnimateReposition","getRepositionMs","getCloseOnEscape","getCloseOnOutside","getRestoreFocusOnClose","onOpenChange","meta","clearTimeout","filterOptions","requestAnimationFrame","focusOnOpen","setTimeout","emitSearchQueryChanged","_CLOSE_RESET_MS","hiddenPopover","closePopover","overflowChipEl","hiddenDropdownEl","preset","_presets","PresetController","refreshOptionSlots","set","querySelectorAll","forEach","el","slotName","slot","add","onSearchKeydown","e","key","shiftKey","preventDefault","stopPropagation","commitDropdownEnter","hasSearchRow","minIndex","headerRows","maxIndex","Math","max","length","dir","scrollActiveItemIntoView","handleAddaddOption","canAddaddOption","trim","dispatchEvent","CustomEvent","detail","bubbles","composed","onIconSlotChange","iconLeftEls","iconRightEls","captureDefaultValue","options","coerceArray","validations","connectedCallback","hasAttribute","tabIndex","firstUpdated","refreshTargets","getFormValue","name","formData","FormData","item","JSON","stringify","String","getOptionValue","append","setValueFromFormState","state","values","getAll","parsed","parse","setValueFromArray","stringValue","get","toString","syncSelectedItemsWithValue","syncFormValue","internals","setFormValue","v","optionsArray","filter","optionValue","optionValueString","some","parsedValue","map","getValidityAnchor","isEmpty","getNativeControl","getCustomErrorMessage","onFormReset","onFormDisabled","onFormStateRestore","toggleSelectAll","isAllFilteredSelected","filteredKeys","opt","optionKey","original","nextSelected","has","selectedKeys","additions","valuesArray","emittedValues","isFilteredSelection","syncValidity","requestUpdate","every","truncateText","text","maxLength","slice","validateInput","nextErrors","target","push","res","nextInvalid","a","b","i","samePrimitiveArray","errors","validateForForm","focus","searchInputEl","blur","handleFocus","reset","openDropdown","openPopover","closeDropdown","clearSelection","handleClear","handleBlur","updated","changedProperties","style","setProperty","resolveColor","willUpdate","syncRendererStateFromProp","patchRendererState","patch","fromProp","rendererStateApi","rendererState","buildOptionRenderContext","args","index","sourceIndex","getOptionLabel","highlightedLabel","active","buildSelectedRenderContext","resolveMultiDisplay","renderOptionContent","defaultLabel","html","unsafeHTML","highlighted","hasSlot","customRenderer","content","renderSelectedLabel","renderSelectedSummaryLabel","isEmptyMulti","_","raw","providedKeys","targetValue","selectedOption","find","makeRow","idx","_idx","query","toLowerCase","row","includes","regex","RegExp","replace","m","handleSearchValueChanged","event","applySearchQuery","handleSearchValueCleared","optionsLength","shouldDebounce","_SEARCH_DEBOUNCE_OPTIONS_THRESHOLD","_SEARCH_DEBOUNCE_MS","disconnectedCallback","hasSelection","selectOption","getEmittedValue","wasFiltered","alreadySelected","findIndex","toggleHiddenChips","toggle","renderHiddenChipsDropdown","onToggle","repeat","indexOf","removeChip","next","renderChips","visible","overflow","when","mode","renderSelectedValue","joined","join","n","first","summary","title","nothing","handleKeydown","closest","was","getOptionByActiveIndex","kind","selectAllBase","optionIndex","search","document","activeElement","optionIdx","firstSelKey","idxInFiltered","q","val","from","rowEls","r","Number","dataset","rowIndex","scrollIntoView","block","behavior","toggleDropdown","renderDropdown","selectAllRowIndex","selectAllClasses","classMap","isSelected","isActive","itemClasses","keyVal","stringValues","renderValidationErrors","msgs","getErrorMessages","errId","id","errs","handleIconClick","position","render","leftIconClasses","left","rightIconClasses","right","placeholderClasses","isFieldset","isInside","labelEl","leftIcon","valueArea","trailingActions","defaultFieldContent","insideFieldContent","fieldBody","wrapperHandlers","fieldWrapper","dependencies","SkyIcon","SkyCheckbox","SkyInput","styles","css","unsafeCSS","cssOnFillEnhance","selector","fillVar","property","shadowRootOptions","LitElement","delegatesFocus","__decorateClass","prototype","type","hasChanged","arrayPropHasChanged","Boolean","reflect","attribute","queryAll","queryAssignedElements","customElement"],"mappings":"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"}
|