@sky.ui/core 0.0.36 → 0.0.38
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 +3098 -3119
- package/dist/sky-appbar/sky-appbar.js.map +1 -1
- package/dist/sky-card/sky-card.js.map +1 -1
- package/dist/sky-combobox/sky-combobox.d.ts +0 -3
- package/dist/sky-combobox/sky-combobox.js +5 -3
- package/dist/sky-combobox/sky-combobox.js.map +1 -1
- package/dist/sky-dialog/sky-dialog.js.map +1 -1
- package/dist/sky-input/sky-input.js.map +1 -1
- package/dist/sky-radio/sky-radio.js.map +1 -1
- package/dist/sky-sheet/sky-sheet.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 } from \"lit\";\nimport { property, customElement, query, queryAll, queryAssignedElements, state } from \"lit/decorators.js\";\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\nimport { when } from \"lit/directives/when.js\";\nimport { repeat } from \"lit/directives/repeat.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { resolveColor } from \"../helper/utils/color-resolver\";\nimport { PopoverController } from \"../helper/controllers/popover-controller\";\nimport {\n FormControlBase,\n FormState,\n} from \"../helper/internals/form-control-base\";\nimport { SkyIcon } from \"../sky-icon/sky-icon.js\";\nimport { SkyCheckbox } from \"../sky-checkbox/sky-checkbox.js\";\n\nexport type SkyComboboxJustify =\n | \"flex-start\"\n | \"center\"\n | \"flex-end\"\n | \"space-between\"\n | \"space-around\"\n | \"space-evenly\";\nexport type SkyComboboxErrorDisplayMode = \"single\" | \"all\" | \"none\";\nexport type SkyComboboxIconPosition = \"left\" | \"right\";\nexport type SkyComboboxValueChangedDetail = {\n value: any | any[];\n selectedItems: any[];\n emittedValues?: any | any[];\n isFilteredSelection?: boolean;\n};\nexport type SkyComboboxSearchQueryChangedDetail = { searchQuery: string };\nexport type SkyComboboxValidationErrorDetail = { errors: string[] };\nexport type SkyComboboxValidationSuccessDetail = { value: any };\nexport type SkyComboboxIconClickDetail = {\n position: SkyComboboxIconPosition;\n event: MouseEvent;\n};\nexport type SkyComboboxAddNewOptionDetail = { value: string };\n\n/**\n * @element sky-combobox\n *\n * @summary Interactive combobox with single/multi select, search, chips, validation, and popover-based option selection.\n *\n * @status stable\n * @since 1.0.0\n *\n * @documentation https://library.sky-ui.com/components/combobox\n * @dependency sky-icon\n * @dependency sky-checkbox\n *\n * @uiVModel value value-changed\n * @uiVModel searchQuery search-query-changed\n *\n * @slot icon-left - Slot for the left icon in the combobox (e.g., search icon).\n * @slot icon-right - Slot for the right icon in the combobox (e.g., dropdown icon).\n * @slot - Default slot for adding custom options or content.\n *\n * @csspart combo-box-container - The main container element wrapping the entire component\n * @csspart input-wrapper - The input field wrapper that contains chips, icons, and dropdown button\n * @csspart icon-slot - Both left and right icon containers\n * @csspart placeholder-label - The placeholder text label\n * @csspart clear-button - The clear (×) button\n * @csspart dropdown-button - The dropdown toggle arrow button\n * @csspart chip-container - Container for the chips in multi-select mode\n * @csspart chip - Individual chip element\n * @csspart single-select-chip - Chip shown in single-select mode\n * @csspart overflow-chip - The \"+N\" chip that shows hidden chips count\n * @csspart remove-chip-icon - The remove icon within chips\n * @csspart hidden-chips-dropdown - Dropdown that appears when clicking overflow chip\n * @csspart hidden-chip-inner - Individual chip in the hidden chips dropdown\n * @csspart hidden-chip-label - Label text in hidden chips dropdown\n * @csspart dropdown - The main dropdown container\n * @csspart search-container - Container for the search input in the dropdown\n * @csspart search-input - The search input field\n * @csspart add-option-icon - The \"+\" icon for adding new options\n * @csspart select-all - The \"Select All\" row in the dropdown\n * @csspart checkbox - Checkbox elements in multi-select mode\n * @csspart option - Individual option row in the dropdown\n * @csspart highlighted-text - Highlighted text in search results\n * @csspart no-options - \"No options found\" message\n * @csspart error-list - Container for validation error messages\n * @csspart error-item - Individual validation error message\n * @csspart dropdown-scroller - Scrollable container for dropdown options\n * @csspart chip-label - Label text within chips\n *\n * @fires {CustomEvent<SkyComboboxValueChangedDetail>} value-changed - Fired whenever selection changes.\n * @fires {CustomEvent<SkyComboboxSearchQueryChangedDetail>} search-query-changed - Fired when search query changes.\n * @fires {CustomEvent<SkyComboboxValidationErrorDetail>} validation-error - Fired when validation fails.\n * @fires {CustomEvent<SkyComboboxValidationSuccessDetail>} validation-success - Fired when validation passes.\n * @fires {CustomEvent<SkyComboboxIconClickDetail>} icon-click - Fired when icon slot is clicked.\n * @fires {CustomEvent<SkyComboboxAddNewOptionDetail>} add-new-option - Fired when user confirms adding a new option.\n *\n * @property {any} value - Current selection value (single) or value array (multi).\n * @property {string} placeholder - Main placeholder text.\n * @property {string} searchPlaceholder - Search input placeholder text.\n * @property {string} searchQuery - Current search filter text when `searchable` is enabled. Default: `\"\"`.\n * @property {string} label - Optional external label text.\n * @property {any[]} options - Available options list.\n * @property {boolean} searchable - Enables search input and filtering.\n * @property {boolean} addOption - Enables ad-hoc option creation from search query.\n * @property {boolean} multiSelect - Enables multi-select chip behavior.\n * @property {boolean} selectAll - Shows select-all row in eligible modes.\n * @property {boolean} clearable - Shows clear button when value exists.\n * @property {boolean} loading - Shows loading affordance.\n * @property {boolean} compact - Enables compact sizing.\n * @property {boolean} disabled - Disables interaction.\n * @property {boolean} required - Enables required validation.\n * @property {boolean} readonly - Enables read-only mode.\n * @property {boolean} emitFullObject - Emits full option objects in events.\n * @property {string} emittedKey - Key emitted from object options when `emitFullObject` is false.\n * @property {string} displayKey - Key used for visual labels in object options.\n * @property {number} visibleChips - Number of visible chips before `+N` overflow chip.\n * @property {number} chipSize - Maximum label length for each chip.\n * @property {string} color - Accent color token/CSS color.\n * @property {number} zIndex - Dropdown overlay z-index.\n * @property {string} height - Max dropdown scroll height.\n * @property {boolean} openAbove - Opens dropdown above when true.\n * @property {SkyComboboxJustify} justify - Option-row content justification.\n * @property {boolean} showErrors - Renders validation errors below control.\n * @property {SkyComboboxErrorDisplayMode} errorDisplayMode - Validation error rendering strategy.\n * @property {(value:any)=>true|string} validations - External validator callbacks.\n * @property {boolean} validationArrayFormat - Sends selected array into validators when true.\n * @property {string} prefix - Optional inline prefix text.\n * @property {string} suffix - Optional inline suffix text.\n * @property {string} prefixColor - Prefix color value.\n * @property {string} suffixColor - Suffix color value.\n * @property {string} requiredMessage - Required validation failure text.\n * @property {boolean} enforceMinOneSelection - Prevents clearing all selections in multi-select mode.\n * @property {boolean} validationActive - Enables validation UI state.\n * @property {boolean} invalid - Reflects invalid state.\n * @property {string} variant - Visual variant style.\n *\n * @method openDropdown Opens the combobox dropdown.\n * @method closeDropdown Closes the combobox dropdown.\n * @method clearSelection Clears current selection if allowed.\n * @method reset Resets combobox state and clears validation UI.\n *\n * @example\n * ```html\n * <sky-combobox label=\"Assignee\" searchable clearable placeholder=\"Select user\"></sky-combobox>\n * ```\n * ```vue\n * <template>\n * <sky-combobox label=\"Assignee\" searchable clearable placeholder=\"Select user\"></sky-combobox>\n * </template>\n * ```\n * ```jsx\n * export default function Demo() {\n * return <sky-combobox label=\"Assignee\" searchable clearable placeholder=\"Select user\"></sky-combobox>;\n * }\n * ```\n */\n@customElement(\"sky-combobox\")\nexport class SkyCombobox extends FormControlBase {\n\n static dependencies: Record<string, CustomElementConstructor> = {\n \"sky-icon\": SkyIcon,\n \"sky-checkbox\": SkyCheckbox,\n };\n\n // ============================================================\n // ✅ PUBLIC PROPERTIES (user-configurable)\n // ============================================================\n\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. */\n @property() value: any = \"\";\n @property({ type: String }) placeholder: string = \"Select An Option\";\n @property({ type: String }) searchPlaceholder: string = \"Search...\";\n @property({ type: String }) label: string = \"\";\n private _options: any[] = [];\n @property({ type: Array })\n get options(): any[] {\n return this._options;\n }\n set options(value: any[] | null | undefined) {\n const old = this._options;\n this._options = Array.isArray(value) ? value : [];\n this.requestUpdate(\"options\", old);\n }\n @property({ type: Number }) chipSize: number = 20;\n @property({ type: String }) color: string = \"primary\";\n @property({ type: Boolean, reflect: true }) clearable: boolean = false;\n @property({ type: Boolean, reflect: true }) loading: boolean = false;\n @property({ type: Boolean, reflect: true }) compact: boolean = false;\n @property({ type: Boolean, reflect: true }) override disabled: boolean = false;\n @property({ type: Boolean, reflect: true }) searchable: boolean = false;\n @property({ type: Boolean, reflect: true }) multiSelect: boolean = false;\n @property({ type: Number, reflect: true }) visibleChips: number = 2;\n @property({ type: Boolean, reflect: true }) selectAll: boolean = false;\n private _validations: ((value: any) => true | string)[] = [];\n @property({ type: Array })\n get validations(): ((value: any) => true | string)[] {\n return this._validations;\n }\n set validations(value: ((value: any) => true | string)[] | null | undefined) {\n const old = this._validations;\n this._validations = Array.isArray(value) ? value : [];\n this.requestUpdate(\"validations\", old);\n }\n @property({ type: Boolean }) showErrors: boolean = false;\n @property({ type: String }) errorDisplayMode: SkyComboboxErrorDisplayMode = \"single\";\n @property({ type: Boolean, reflect: true }) override required: boolean = false;\n @property({ type: Boolean, reflect: true }) emitFullObject: boolean = false;\n @property({ type: String }) emittedKey: string = \"value\";\n @property({ type: String }) displayKey: string = \"\";\n @property({ type: Boolean }) addOption: boolean = false;\n @property({ type: Boolean }) validationArrayFormat: boolean = false;\n @property({ type: String }) override prefix: string = \"\";\n @property({ type: String }) suffix: string = \"\";\n @property({ type: String }) prefixColor: string = \"\";\n @property({ type: String }) suffixColor: string = \"\";\n @property({ type: String }) justify: SkyComboboxJustify = \"flex-start\";\n @property({ type: Number }) zIndex: number = 11;\n @property({ type: String }) height: string = \"200px\";\n @property({ type: String }) override requiredMessage: string = \"Selection is required.\";\n @property({ type: Boolean, reflect: true }) override readonly: boolean = false;\n @property({ type: Boolean }) enforceMinOneSelection: boolean = false;\n @property({ type: Boolean }) openAbove: boolean = false;\n @property({ type: Boolean, reflect: true }) validationActive: boolean = false;\n @property({ type: Boolean, reflect: true }) invalid = false;\n @property({ type: String, reflect: true }) variant: string = \"default\";\n\n // ============================================================\n // ✅ INTERNAL STATE (read-only, managed by component)\n // ============================================================\n\n /** Current search filter when `searchable`; exposed for controlled search / `v-model:search-query`. */\n @property({ type: String, attribute: false }) searchQuery = \"\";\n @state() filteredOptions: any[] = [];\n @state() focused: boolean = false;\n @state() open: boolean = false;\n @state() selectedItems: any[] = [];\n @state() hiddenChipsOpen: boolean = false;\n @state() activeIndex: number = -1;\n @state() validationErrors: string[] = [];\n @state() validationStatus: any[] = [];\n @state() private hasLeftIcon = false;\n @state() private hasRightIcon = false;\n @state() private optionSlotSet = new Set<string>();\n\n // ============================================================\n // ✅ PRIVATE FIELDS (internal, not reactive)\n // ============================================================\n\n @query(\".input-wrapper\") private inputWrapperEl!: HTMLElement;\n @query(\".dropdown\") private dropdownEl!: HTMLElement;\n @query(\".hidden-chips-dropdown\") private hiddenDropdownEl!: HTMLElement;\n @query(\".search-container .input\") private searchInputEl!: HTMLInputElement;\n @query(\".overflow-chip\") private overflowChipEl!: HTMLElement;\n @query(\".combo-box-container\") private comboContainerEl!: HTMLElement;\n @queryAll(\"[data-row-index]\") private rowEls!: NodeListOf<HTMLElement>;\n @queryAssignedElements({ slot: \"icon-left\" }) private iconLeftEls!: HTMLElement[];\n @queryAssignedElements({ slot: \"icon-right\" }) private iconRightEls!: HTMLElement[];\n\n private _searchDebounceId: ReturnType<typeof setTimeout> | null = null;\n private _closeResetId: ReturnType<typeof setTimeout> | null = null;\n private static readonly _SEARCH_DEBOUNCE_MS = 150;\n private static readonly _SEARCH_DEBOUNCE_OPTIONS_THRESHOLD = 30;\n /** Matches PopoverController exit animation so list stays visible while closing. */\n private static readonly _CLOSE_RESET_MS = 250;\n\n private dropdownPopover = new PopoverController(this, {\n getAnchor: () => this.inputWrapperEl,\n getPopover: () => this.dropdownEl,\n cssVarLeft: \"--sky-dd-left\",\n cssVarTop: \"--sky-dd-top\",\n cssVarWidth: \"--sky-dd-width\",\n getPlacement: () => 'bottom' as any,\n getAlign: () => \"start\" as any,\n getGap: () => 6,\n getPadding: () => 8,\n getMatchAnchorWidth: () => true,\n getMaxWidthToViewport: () => true,\n getMaxWidthMode: () => \"cap\" as any,\n getFlip: () => true,\n getFlipOrder: () => [],\n getAnimateReposition: () => true,\n getRepositionMs: () => 160,\n getCloseOnEscape: () => true,\n getCloseOnOutside: () => true,\n getRestoreFocusOnClose: () => true,\n onOpenChange: (open, meta) => {\n this.open = open;\n\n if (open) {\n if (this._closeResetId != null) {\n clearTimeout(this._closeResetId);\n this._closeResetId = null;\n }\n this.validationActive = true;\n this.filterOptions();\n requestAnimationFrame(() => this.focusOnOpen());\n } else {\n this.activeIndex = -1;\n // Defer search reset so options stay populated during the close animation.\n if (this._closeResetId != null) clearTimeout(this._closeResetId);\n this._closeResetId = setTimeout(() => {\n this._closeResetId = null;\n if (this.open) return;\n this.searchQuery = \"\";\n this.emitSearchQueryChanged();\n this.filterOptions();\n }, SkyCombobox._CLOSE_RESET_MS);\n\n // close hidden chips too\n this.hiddenChipsOpen = false;\n this.hiddenPopover.closePopover(\"api\");\n }\n },\n });\n\n private hiddenPopover = new PopoverController(this, {\n getAnchor: () => this.overflowChipEl,\n getPopover: () => this.hiddenDropdownEl,\n cssVarLeft: \"--sky-hc-left\",\n cssVarTop: \"--sky-hc-top\",\n cssVarWidth: \"--sky-hc-width\",\n getPlacement: () => \"bottom\" as any,\n getAlign: () => \"center\" as any,\n getGap: () => 4,\n getPadding: () => 8,\n getMatchAnchorWidth: () => false,\n getMaxWidthToViewport: () => true,\n getMaxWidthMode: () => \"cap\" as any,\n getFlip: () => true,\n getFlipOrder: () => [],\n getAnimateReposition: () => true,\n getRepositionMs: () => 120,\n getCloseOnEscape: () => true,\n getCloseOnOutside: () => true,\n getRestoreFocusOnClose: () => false,\n onOpenChange: (open) => {\n this.hiddenChipsOpen = open;\n\n // if opening hidden chips, close main dropdown\n if (open && this.open) {\n this.dropdownPopover.closePopover(\"api\");\n }\n },\n });\n\n static override styles = css`\n :host {\n display: block;\n font-family: var(--sky-font);\n width: 100%;\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--sky-opacity-disabled, 0.6);\n }\n\n :host([readonly]) .input-wrapper {\n cursor: default;\n }\n\n :host([variant=\"highlight\"]) {\n .label{\n color: var(--sky-dropdown-color);\n }\n }\n\n .combo-box-container:focus-within .label {\n color: var(--sky-dropdown-color);\n font-size: var(--sky-font-size-sm);\n transition: all 0.3s ease;\n }\n .label {\n font-size: var(--sky-font-size-sm);\n margin-bottom: 5px;\n text-align: start;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: var(--sky-font);\n }\n\n .combo-box-container:focus-within[compact] .label {\n font-size: var(--sky-font-size-xs);\n color: var(--sky-dropdown-color);\n }\n\n .combo-box-container {\n position: relative;\n display: flex;\n flex-direction: column;\n max-width: 100%;\n overflow: visible;\n width: 100%;\n }\n\n .combo-box-container.shake {\n animation: shake 0.3s ease-in-out;\n animation-iteration-count: 1;\n }\n\n @keyframes shake {\n 0% {\n transform: translateX(0);\n }\n 25% {\n transform: translateX(-3px);\n }\n 50% {\n transform: translateX(3px);\n }\n 75% {\n transform: translateX(-3px);\n }\n 100% {\n transform: translateX(0);\n }\n }\n\n .search-container {\n display: flex;\n align-items: center;\n padding: 8px 10px;\n gap: 5px;\n border-bottom: 1px solid var(--sky-border-light);\n justify-content: space-between;\n margin-bottom: 5px;\n }\n\n .search-container sky-icon {\n width: 16px;\n height: 16px;\n color: var(--sky-text-secondary);\n transition: color 0.15s ease;\n }\n\n .search-container:has(.input:focus) sky-icon {\n color: var(--sky-active-primary);\n }\n\n .new-option-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: var(--sky-radius-primary);\n margin-left: 6px;\n cursor: pointer;\n background: var(--sky-hover-primary);\n border: var(--sky-border-primary);\n color: var(--sky-dropdown-color);\n flex-shrink: 0;\n transition: color 0.15s ease;\n }\n .new-option-btn:hover {\n color: var(--sky-active-primary);\n }\n .new-option-btn[disabled] {\n opacity: 0.6;\n pointer-events: none;\n }\n\n .input-wrapper {\n display: flex;\n align-items: center;\n background: var(--sky-glass-solid);\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n box-sizing: border-box;\n border-radius: var(--sky-radius-secondary);\n height: 38px;\n width: 100%;\n flex-wrap: nowrap;\n position: relative;\n border: var(--sky-border-primary);\n box-shadow: var(--sky-box-shadow-primary);\n transition: border-color 0.3s ease, box-shadow 0.3s ease;\n flex: 1 1 auto;\n min-width: 0;\n \n }\n\n .input-wrapper:focus-visible {\n border-bottom: 1px solid var(--sky-dropdown-color);\n outline: none;\n }\n\n .input-wrapper::after {\n content: \"\";\n position: absolute;\n top: -1px;\n left: -1px;\n right: -1px;\n bottom: -1px;\n border-radius: inherit;\n border: 1px solid transparent;\n border-bottom-color: transparent;\n opacity: 0;\n transition:\n opacity 0.3s ease,\n border-color 0.3s ease;\n pointer-events: none;\n }\n\n .input-wrapper[open]::after {\n opacity: 1;\n border-bottom-color: var(--sky-dropdown-color);\n }\n\n :host([validationActive]:invalid) .input-wrapper::after {\n opacity: 1;\n border-bottom-color: var(--sky-danger-primary);\n }\n :host([validationActive]:invalid) .label {\n color: var(--sky-danger-primary);\n }\n\n :host([validationActive]:invalid) .icon-slot {\n color: var(--sky-danger-primary);\n }\n\n .placeholder-label.active[compact] {\n top: 10px;\n background-color: var(--sky-dropdown-color);\n color: white;\n font-size: var(--sky-font-size-xs);\n padding: 0 5px;\n border-radius: 4px;\n }\n\n .input-wrapper[compact] {\n height: 30px;\n }\n\n :host([compact]) .placeholder-label {\n font-size: var(--sky-font-size-sm);\n }\n\n sky-icon {\n display: inline-block;\n width: 1em;\n height: 1em;\n }\n\n .chip-container {\n margin-left: 5px;\n display: flex;\n gap: 8px;\n flex: 1 1 auto;\n min-width: 0;\n flex-wrap: nowrap;\n }\n\n :dir(rtl).chip-container {\n margin-right: 5px;\n margin-left: 0px;\n }\n\n .chip-container::-webkit-scrollbar {\n display: none;\n }\n\n .chip-container[compact] {\n gap: 4px;\n }\n\n .chip {\n background-color: var(--sky-glass-primary);\n border-radius: var(--sky-radius-primary);\n padding: 4px 8px;\n font-size: var(--sky-font-size-sm);\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n min-width: 0;\n border: var(--sky-border-primary);\n font-family: var(--sky-font);\n }\n\n .chip .chip-label {\n min-width: 0;\n flex: 1 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .chip[single-select] {\n background-color: transparent;\n box-shadow: none;\n border: none;\n font-size: var(--sky-font-size-md);\n padding: 4px;\n gap: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n width:100%;\n }\n\n .chip[single-select] .chip-label {\n flex: 1 1 auto;\n min-width: 0;\n }\n\n :host([icon-left]) .chip[single-select] {\n padding:4px 0;\n }\n\n .chip[single-select] .remove-chip {\n display: none;\n }\n\n .chip .remove-chip[compact] {\n flex-shrink: 0;\n }\n .remove-chip-inner {\n font-size: var(--sky-font-size-md);\n color: var(--sky-dropdown-color);\n background-color: var(--sky-hover-primary);\n border-radius: var(--sky-radius-full);\n border: none;\n cursor: pointer;\n transition: color 0.2s ease, background-color 0.2s ease;\n }\n .remove-chip-inner:hover {\n color: var(--sky-danger-primary);\n }\n .remove-chip:hover {\n color: var(--sky-danger-primary);\n }\n\n .chip .remove-chip {\n position: static;\n flex-shrink: 0;\n align-self: center;\n font-size: var(--sky-font-size-sm);\n color: var(--sky-dropdown-color);\n background-color: var(--sky-hover-primary);\n border-radius: var(--sky-radius-full);\n cursor: pointer;\n border: none;\n transition: color 0.2s ease, background-color 0.2s ease;\n }\n\n .input {\n border: none;\n font-family: var(--sky-font);\n outline: none;\n font-size: var(--sky-font-size-md);\n background: transparent;\n box-sizing: border-box;\n color: var(--sky-text-secondary);\n width: 100%;\n transition: all 0.2 ease-in-out;\n }\n\n .search-container:has(.input:focus:focus) {\n border-bottom-color: var(--sky-active-primary);\n }\n\n .input:-webkit-autofill {\n -webkit-text-fill-color: var(--sky-text-secondary, inherit) !important;\n transition: background-color 9999s ease-in-out 0s !important;\n }\n\n .input[disabled] {\n opacity: 70%;\n color: var(--sky-text-primary);\n cursor: disabled;\n }\n\n .input-wrapper[disabled] {\n opacity: 0.6;\n pointer-events: none;\n }\n\n .dropdown {\n position: fixed;\n padding: 5px;\n background: var(--sky-glass-tertiary);\n background-image: var(--sky-glass-surface);\n backdrop-filter: var(--sky-blur-tertiary) var(--sky-brightness-tertiary)\n var(--sky-saturation-tertiary);\n -webkit-backdrop-filter: var(--sky-blur-tertiary)\n var(--sky-brightness-tertiary) var(--sky-saturation-tertiary);\n border-radius: var(--sky-radius-secondary);\n box-shadow:\n var(--sky-box-shadow-inset),\n var(--sky-box-shadow-tertiary);\n box-sizing: border-box;\n pointer-events: auto;\n margin: 0;\n \n border: var(--sky-border-tertiary);\n \n }\n\n .dropdown-scroller {\n max-height: var(--sky-scroll-height);\n overflow: auto;\n scrollbar-width: thin;\n scrollbar-color: var(--sky-scrollbar-thumb) var(--sky-scrollbar-track);\n }\n\n .dropdown-scroller::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n }\n\n .dropdown-scroller::-webkit-scrollbar-thumb {\n background-color: var(--sky-scrollbar-thumb);\n border-radius: var(--sky-radius-full, 9999px);\n transition: background-color var(--sky-duration-normal, 200ms)\n var(--sky-ease-default, ease);\n cursor: grab;\n }\n\n .dropdown-scroller::-webkit-scrollbar-thumb:hover {\n background-color: var(--sky-scrollbar-thumb-hover);\n }\n\n .dropdown-scroller::-webkit-scrollbar-track {\n background: var(--sky-scrollbar-track);\n }\n\n .dropdown-scroller::-webkit-scrollbar-button {\n background-color: transparent;\n }\n\n .dropdown-item.active {\n background-color: var(--sky-hover-primary);\n }\n .dropdown-item.selected {\n color: var(--sky-dropdown-color, var(--sky-active-primary));\n }\n\n .dropdown-item.active.selected {\n background-color: var(--sky-active-g0);\n }\n\n .dropdown-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-radius: var(--sky-radius-secondary);\n cursor: pointer;\n text-align: left;\n font-size: var(--sky-font-size-sm);\n color: var(--sky-text-primary);\n transition: all 0.2s ease-in-out;\n box-sizing: border-box;\n margin: 2px 0;\n font-family: var(--sky-font);\n }\n\n :host([compact]) .dropdown-item {\n font-size: var(--sky-font-size-sm);\n padding: 5px 8px;\n margin: 1px 0;\n }\n\n .icon-slot {\n display: none;\n justify-content: center;\n font-size: var(--sky-font-size-xl);\n align-items: center;\n border-radius: var(--sky-radius-secondary);\n height: inherit;\n max-height: 100%;\n box-sizing: border-box;\n min-width: 36px;\n background: var(--sky-glass-solid);\n color: var(--sky-text-primary);\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n \n transition:\n transform 0.3s ease,\n color 0.3s ease;\n }\n\n.hidden-chips-dropdown {\n position: fixed; /* important: popover top layer */\n background: var(--sky-glass-tertiary);\n background-image: var(--sky-glass-surface);\n backdrop-filter: var(--sky-blur-tertiary) var(--sky-brightness-tertiary)\n var(--sky-saturation-tertiary);\n -webkit-backdrop-filter: var(--sky-blur-tertiary)\n var(--sky-brightness-tertiary) var(--sky-saturation-tertiary);\n box-shadow:\n var(--sky-box-shadow-inset),\n var(--sky-box-shadow-tertiary);\n border-radius: var(--sky-radius-secondary);\n border: var(--sky-border-tertiary);\n width: max-content;\n \n opacity: 0;\n transform: scale(0.98);\n transition: opacity 0.15s ease, transform 0.15s ease;\n margin: 0;\n}\n\n.hidden-chips-dropdown:popover-open {\n opacity: 1;\n transform: scale(1);\n}\n\n\n .hidden-chip-inner {\n padding: 4px 8px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n gap: 5px;\n font-size: var(--sky-font-size-sm);\n border-bottom: var(--sky-border-primary);\n font-family: var(--sky-font);\n }\n\n .hidden-chip-inner:last-child {\n border-bottom: none;\n }\n\n .icon-slot[filled] {\n display: flex;\n cursor: pointer;\n }\n .icon-slot.left {\n border-right: var(--sky-border-primary);\n }\n\n :dir(rtl) .icon-slot.left {\n border-left: var(--sky-border-primary);\n border-right: unset;\n }\n\n .icon-slot.right {\n border-left: var(--sky-border-primary);\n }\n\n :dir(rtl) .icon-slot.right {\n border-right: var(--sky-border-primary);\n border-left: unset;\n }\n\n .input-wrapper[open] .icon-slot {\n transform: translate(-5px, -5px);\n border: var(--sky-border-primary) !important;\n color: var(--sky-dropdown-color);\n background-color: var(--sky-glass-solid);\n }\n\n :dir(rtl) .input-wrapper[open] .icon-slot {\n transform: translate(5px, -5px);\n }\n\n .input-wrapper[open] .icon-slot.right {\n transform: translate(5px, -5px);\n }\n\n :dir(rtl) .input-wrapper[open] .icon-slot.right {\n transform: translate(-5px, -5px);\n }\n\n .placeholder-label {\n white-space: nowrap;\n padding: 0 8px;\n flex: 1 1 0%;\n text-align: start;\n font-size: var(--sky-font-size-md);\n color: var(--sky-text-tertiary);\n transition: all 0.3s ease;\n pointer-events: none;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: var(--sky-font);\n }\n\n .placeholder-label.active {\n display: none;\n }\n\n .dropdown-item:hover {\n background-color: var(--sky-hover-primary);\n }\n\n .clear-button {\n flex-shrink: 0;\n margin-inline-end: var(--sky-space-1, 4px);\n border: none;\n font-size: var(--sky-font-size-xl);\n color: var(--sky-dropdown-color);\n background-color: var(--sky-hover-primary);\n border-radius: var(--sky-radius-full);\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n cursor: pointer;\n transition: color 0.3s ease;\n }\n\n .clear-button[compact] {\n font-size: var(--sky-font-size-md);\n }\n\n .clear-button:hover {\n color: var(--sky-danger-primary);\n }\n\n .dropdown-button {\n flex-shrink: 0;\n color: var(--sky-text-primary);\n height: 100%;\n width: auto;\n aspect-ratio: 1;\n display: flex;\n border: none;\n font-size: var(--sky-font-size-sm);\n cursor: pointer;\n transition: color 0.3s ease;\n }\n\n .dropdown-button[compact] {\n font-size: var(--sky-font-size-md);\n }\n\n .loading-indicator {\n flex-shrink: 0;\n margin-inline-end: var(--sky-space-1, 4px);\n width: 16px;\n height: 16px;\n border: 2px solid var(--sky-text-white);\n border-top: 2px solid var(--sky-dropdown-color, var(--sky-active-primary));\n border-radius: var(--sky-radius-full);\n animation: spin 1s linear infinite;\n }\n\n ::slotted(.icon-slot) {\n display: block;\n }\n\n @keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }\n\n .highlight {\n color: var(--sky-dropdown-color);\n font-weight: var(--sky-font-weight-semibold);\n }\n\n .progress-container {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: flex-start;\n position: absolute;\n width: 100%;\n top: 100%;\n }\n\n .progress-message {\n pointer-events: none;\n width: 100%;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n font-size: var(--sky-font-size-sm);\n margin-left: 5px;\n font-family: var(--sky-font);\n }\n\n :dir(rtl) .progress-message {\n margin-left: unset;\n margin-right: 5px;\n }\n\n .error-list {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n }\n\n .error {\n font-size: var(--sky-font-size-xs);\n color: var(--sky-danger-primary);\n text-align: start;\n white-space: nowrap;\n text-overflow: ellipsis;\n font-family: var(--sky-font);\n }\n .sky-checkbox {\n appearance: none;\n flex-shrink: 0;\n width: 16px;\n height: 16px;\n border-radius: 6px;\n margin-right: 5px;\n border: 1px solid var(--sky-text-tertiary);\n background-color: transparent;\n box-shadow: none;\n cursor: pointer;\n position: relative;\n transition:\n background-color 0.3s ease,\n border-color 0.3s ease,\n box-shadow 0.3s ease;\n }\n\n .sky-checkbox:hover {\n background-color: var(--sky-text-tertiary);\n border-color: var(--sky-text-tertiary);\n }\n\n .sky-checkbox:focus-visible {\n background-color: var(--sky-text-tertiary);\n border-color: var(--sky-text-tertiary);\n outline: none;\n }\n\n .sky-checkbox:checked {\n background-color: var(--sky-active-primary);\n border-color: var(--sky-active-primary);\n }\n\n .sky-checkbox::after {\n content: \"\";\n width: 8px;\n height: 4px;\n border: 2px solid var(--sky-text-white);\n border-top: none;\n border-right: none;\n position: absolute;\n top: 6px;\n left: 50%;\n transform: translate(-50%, -50%) rotate(-90deg) scale(0.8);\n opacity: 0;\n transition:\n opacity 0.2s ease-in-out,\n transform 0.2s ease-in-out;\n }\n\n .sky-checkbox.indeterminate {\n background-color: var(--sky-active-primary);\n border-color: var(--sky-active-primary);\n }\n\n .sky-checkbox.indeterminate::after {\n width: 8px;\n height: 2px;\n background-color: var(--sky-text-white);\n border: none;\n top: 50%;\n left: 50%;\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n }\n\n .sky-checkbox:checked::after {\n opacity: 1;\n transform: translate(-50%, -50%) rotate(-45deg) scale(1);\n }\n\n .sky-checkbox:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n `;\n\n constructor() {\n super();\n this.captureDefaultValue(\"\");\n }\n\n static override shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n override connectedCallback() {\n super.connectedCallback();\n\n // ✅ allow keyboard tabbing to the component\n if (!this.hasAttribute(\"tabindex\")) {\n this.tabIndex = this.disabled ? -1 : 0;\n }\n this.refreshOptionSlots();\n\n }\n\n override firstUpdated() {\n this.dropdownPopover.refreshTargets();\n this.hiddenPopover.refreshTargets();\n }\n\n private refreshOptionSlots = () => {\n const set = new Set<string>();\n this.querySelectorAll<HTMLElement>('[slot^=\"option-\"]').forEach((el) => {\n const slotName = (el as HTMLElement).slot;\n if (slotName) set.add(slotName);\n });\n this.optionSlotSet = set;\n };\n\n /** Get the current value for form submission */\n protected override getFormValue(): FormState {\n if (this.disabled || !this.name) return null;\n\n if (this.multiSelect) {\n // For multi-select, return a FormData object with all selected values\n const formData = new FormData();\n this.selectedItems.forEach((item) => {\n const value = this.emitFullObject\n ? JSON.stringify(item)\n : String(this.getOptionValue(item));\n formData.append(this.name, value);\n });\n // Add a dummy input when nothing is selected (for form validation)\n if (this.selectedItems.length === 0 && this.required) {\n formData.append(this.name, \"\");\n }\n return formData;\n } else {\n // For single select\n if (this.selectedItems.length === 0) return \"\";\n const item = this.selectedItems[0];\n return this.emitFullObject\n ? JSON.stringify(item)\n : String(this.getOptionValue(item));\n }\n }\n\n /** Set value from form state (e.g., form reset) */\n protected override setValueFromFormState(state: FormState): void {\n if (state === null || state === \"\") {\n this.value = this.multiSelect ? [] : \"\";\n this.selectedItems = [];\n return;\n }\n\n if (this.multiSelect) {\n let values: any[] = [];\n\n if (state instanceof FormData) {\n // Get all values with the same name from FormData\n values = state.getAll(this.name);\n } else if (Array.isArray(state)) {\n values = state;\n } else if (typeof state === \"string\") {\n try {\n const parsed = JSON.parse(state);\n if (Array.isArray(parsed)) {\n values = parsed;\n } else {\n values = [state];\n }\n } catch {\n values = [state];\n }\n }\n\n this.setValueFromArray(values);\n } else {\n // Single select\n let stringValue = \"\";\n if (typeof state === \"string\") {\n stringValue = state;\n } else if (state instanceof FormData) {\n stringValue = state.get(this.name)?.toString() || \"\";\n } else if (Array.isArray(state) && state.length > 0) {\n stringValue = state[0].toString();\n }\n\n this.value = stringValue;\n this.syncSelectedItemsWithValue();\n }\n }\n protected override syncFormValue(): void {\n if (!this.name || this.disabled) {\n this.internals.setFormValue(null);\n return;\n }\n\n const v = this.getFormValue();\n\n if (v === null) {\n this.internals.setFormValue(null);\n return;\n }\n\n if (this.multiSelect && Array.isArray(v)) {\n // For multi-select, set multiple form values with the same name\n // This matches how native <select multiple> works\n const formData = new FormData();\n v.forEach((value) => {\n if (value !== null && value !== undefined && value !== \"\") {\n formData.append(this.name, String(value));\n }\n });\n this.internals.setFormValue(formData);\n } else {\n // Single select\n this.internals.setFormValue(v as string | File | null);\n }\n }\n private setValueFromArray(values: any[]) {\n // Ensure options is always an array\n const optionsArray = Array.isArray(this.options) ? this.options : [];\n\n // Filter options based on the submitted values\n this.selectedItems = optionsArray.filter((option) => {\n const optionValue = this.getOptionValue(option);\n const optionValueString = this.emitFullObject\n ? JSON.stringify(option)\n : String(optionValue);\n\n return values.some((value) => {\n const stringValue = String(value);\n\n // Handle both string comparison and JSON comparison\n if (this.emitFullObject) {\n try {\n const parsedValue = JSON.parse(stringValue);\n return JSON.stringify(parsedValue) === optionValueString;\n } catch {\n return stringValue === optionValueString;\n }\n } else {\n return stringValue === optionValueString;\n }\n });\n });\n\n // Update the internal value\n this.value = this.selectedItems.map((item) =>\n this.emitFullObject ? item : this.getOptionValue(item),\n );\n }\n\n /** Get the validity anchor (for validation messages) */\n protected override getValidityAnchor(): HTMLElement | undefined {\n return this;\n }\n\n /** Check if empty (for required validation) */\n protected override isEmpty(): boolean {\n if (this.multiSelect) {\n return this.selectedItems.length === 0;\n } else {\n return this.selectedItems.length === 0 || !this.value;\n }\n }\n\n protected override getNativeControl(): HTMLElement | null {\n // Return the input wrapper or a focusable element within it\n return this.inputWrapperEl || null;\n }\n /** Override to provide custom error messages */\n protected override getCustomErrorMessage(): string {\n return this.validationErrors?.[0] || \"\";\n }\n\n // ============================================================\n // Override FormControlBase methods for combobox-specific behavior\n // ============================================================\n\n /** Override form reset callback */\n protected override onFormReset(): void {\n super.onFormReset();\n this.searchQuery = \"\";\n this.emitSearchQueryChanged();\n this.open = false;\n this.invalid = false;\n this.validationErrors = [];\n this.validationActive = false;\n }\n\n /** Override form disabled callback */\n protected override onFormDisabled(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n /** Override form state restore callback */\n protected override onFormStateRestore(state: FormState): void {\n this.setValueFromFormState(state);\n }\n\n\n private toggleSelectAll(): void {\n if (this.disabled || this.readonly) return;\n const keyOf = (o: any) => String(this.getOptionValue(o));\n\n if (this.isAllFilteredSelected()) {\n const filteredKeys = new Set(\n this.filteredOptions.map((opt) =>\n String(this.getOptionValue(opt.original)),\n ),\n );\n\n const nextSelected = this.selectedItems.filter(\n (item) => !filteredKeys.has(keyOf(item)),\n );\n\n // 🚫 prevent going below 1 selection when enforced\n if (this.enforceMinOneSelection && nextSelected.length === 0) {\n return;\n }\n\n this.selectedItems = nextSelected;\n } else {\n const selectedKeys = new Set(\n this.selectedItems.map((item) => keyOf(item)),\n );\n const additions = this.filteredOptions\n .map((o) => o.original)\n .filter((opt) => !selectedKeys.has(keyOf(opt)));\n this.selectedItems = [...this.selectedItems, ...additions];\n }\n\n const valuesArray = this.selectedItems.map((opt) =>\n this.emitFullObject ? opt : this.getOptionValue(opt),\n );\n this.value = valuesArray;\n\n this.dispatchEvent(\n new CustomEvent<SkyComboboxValueChangedDetail>(\"value-changed\", {\n detail: {\n value: valuesArray,\n selectedItems: [...this.selectedItems],\n emittedValues: valuesArray,\n isFilteredSelection: !!this.searchQuery.trim(),\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n this.syncFormValue();\n this.syncValidity();\n this.requestUpdate();\n }\n\n private isAllFilteredSelected(): boolean {\n if (this.filteredOptions.length === 0) return false;\n\n const filteredValues = this.filteredOptions.map((opt) =>\n this.getOptionValue(opt.original),\n );\n return filteredValues.every((value) =>\n this.selectedItems.some((item) => this.getOptionValue(item) === value),\n );\n }\n\n private truncateText(text: string, maxLength: number): string {\n if (text.length > maxLength) {\n return text.slice(0, maxLength) + \"...\";\n }\n return text;\n }\n\n private validateInput(): void {\n if (!this.validationActive) return;\n\n this.validationErrors = [];\n\n const target = this.validationArrayFormat ? this.selectedItems : this.value;\n\n // 1) required first (single source of truth inside component UI)\n if (this.required && this.isEmpty()) {\n this.validationErrors.push(\n this.requiredMessage || \"Selection is required.\",\n );\n } else {\n // 2) run external validations only when not empty (optional but cleaner)\n if (Array.isArray(this.validations) && this.validations.length) {\n for (const v of this.validations) {\n const res = v(target);\n if (res !== true)\n this.validationErrors.push(String(res || \"Invalid value.\"));\n }\n }\n }\n\n this.invalid = this.validationErrors.length > 0;\n\n this.dispatchEvent(\n new CustomEvent<SkyComboboxValidationErrorDetail | SkyComboboxValidationSuccessDetail>(\n this.invalid ? \"validation-error\" : \"validation-success\",\n {\n detail: this.invalid\n ? { errors: this.validationErrors }\n : { value: this.selectedItems },\n bubbles: true,\n composed: true,\n },\n ),\n );\n\n this.syncValidity();\n this.requestUpdate();\n }\n\n // ✅ Always blocks form submit when invalid (even if validationActive=false)\n protected override validateForForm(): string {\n if (this.disabled) return \"\";\n\n // What should validators receive?\n const target = this.validationArrayFormat ? this.selectedItems : this.value;\n\n // 1) external validations first\n if (Array.isArray(this.validations) && this.validations.length) {\n for (const v of this.validations) {\n const res = v(target);\n if (res !== true) return String(res || \"Invalid value.\");\n }\n }\n\n // 2) enforceMinOneSelection as a hard rule (optional but makes form correct)\n if (this.enforceMinOneSelection && this.isEmpty()) {\n return this.requiredMessage || \"At least one selection is required.\";\n }\n\n // 3) required rule\n if (this.required && this.isEmpty()) {\n return this.requiredMessage || \"Selection is required.\";\n }\n\n return \"\";\n }\n\n override focus(options?: FocusOptions) {\n super.focus(options);\n if (this.searchInputEl) {\n this.searchInputEl.focus(options);\n } else if (this.inputWrapperEl) {\n this.inputWrapperEl.focus(options);\n }\n }\n\n override blur() {\n if (this.open) {\n this.dropdownPopover.closePopover(\"light-dismiss\");\n }\n super.blur();\n }\n\n private handleFocus(): void {\n this.focused = true;\n\n if (!this.validationActive) {\n this.validationActive = true;\n }\n }\n\n /**\n * Resets combobox state and clears validation UI.\n *\n * @returns {void}\n */\n public reset(): void {\n this.value = this.multiSelect ? [] : \"\";\n this.selectedItems = [];\n this.searchQuery = \"\";\n this.emitSearchQueryChanged();\n this.filterOptions();\n this.validationErrors = [];\n this.validationActive = false;\n this.open = false;\n this.invalid = false;\n this.syncFormValue();\n this.syncValidity();\n this.requestUpdate();\n }\n\n /**\n * Opens the combobox dropdown.\n *\n * @returns {void}\n */\n public openDropdown(): void {\n if (this.disabled || this.readonly) return;\n this.dropdownPopover.openPopover();\n }\n\n /**\n * Closes the combobox dropdown.\n *\n * @returns {void}\n */\n public closeDropdown(): void {\n this.dropdownPopover.closePopover(\"api\");\n }\n\n /**\n * Clears current selection when allowed by component settings.\n *\n * @returns {void}\n */\n public clearSelection(): void {\n this.handleClear();\n }\n\n private handleBlur(): void {\n this.focused = false;\n\n if (this.validationActive) {\n this.validateInput();\n }\n }\n\n override updated(changedProperties: Map<string, unknown>) {\n if (changedProperties.has(\"color\")) {\n this.style.setProperty(\"--sky-dropdown-color\", resolveColor(this.color));\n }\n if (changedProperties.has(\"height\")) {\n this.style.setProperty(\"--sky-scroll-height\", this.height);\n }\n }\n override willUpdate(changedProperties: Map<string, unknown>) {\n if (changedProperties.has(\"value\")) {\n this.syncSelectedItemsWithValue();\n this.syncFormValue();\n this.syncValidity();\n }\n\n if (changedProperties.has(\"options\")) {\n // ✅ Ensure options is an array before processing\n if (!Array.isArray(this.options)) {\n this.options = [];\n }\n this.syncSelectedItemsWithValue();\n this.filterOptions();\n this.syncFormValue();\n this.syncValidity();\n }\n\n if (changedProperties.has(\"searchable\")) {\n // ✅ Call filterOptions which now handles non-array options safely\n this.filterOptions();\n }\n\n if (changedProperties.has(\"searchQuery\")) {\n this.filterOptions();\n }\n\n if (changedProperties.has(\"validationErrors\")) {\n this.requestUpdate();\n }\n }\n\n private syncSelectedItemsWithValue(): void {\n // Ensure options is always an array\n const optionsArray = Array.isArray(this.options) ? this.options : [];\n\n // Treat null/undefined or [] (when multi) as empty\n const isEmptyMulti =\n this.multiSelect && Array.isArray(this.value) && this.value.length === 0;\n\n if (this.value == null || this.value === \"\" || isEmptyMulti) {\n this.selectedItems = [];\n this.value = this.multiSelect ? [] : \"\";\n return;\n }\n\n // Back-compat: if someone still passes a JSON stringified array\n if (this.multiSelect && typeof this.value === \"string\") {\n try {\n const parsed = JSON.parse(this.value);\n if (Array.isArray(parsed)) this.value = parsed;\n } catch (_) {\n // ignore non-JSON strings\n }\n }\n\n const getValueForComparison = (item: any) => {\n const val = this.getOptionValue(item);\n return typeof val === \"object\" ? JSON.stringify(val) : String(val);\n };\n\n if (this.multiSelect) {\n // Normalize incoming to an array\n const raw = Array.isArray(this.value) ? this.value : [this.value];\n\n // Build a comparable key set from provided values\n const providedKeys = new Set(\n raw.map((v) => {\n if (this.emitFullObject && typeof v === \"object\") {\n return JSON.stringify(v);\n }\n return String(v);\n }),\n );\n\n // Filter actual option objects whose key is in providedKeys\n this.selectedItems = optionsArray.filter((opt) => {\n const optValue = this.emitFullObject\n ? JSON.stringify(opt)\n : getValueForComparison(opt);\n return providedKeys.has(optValue);\n });\n\n // Normalize this.value to the canonical emitted values\n this.value = this.selectedItems.map((opt) =>\n this.emitFullObject ? opt : this.getOptionValue(opt),\n );\n } else {\n const targetValue =\n this.emitFullObject && typeof this.value === \"object\"\n ? JSON.stringify(this.value)\n : String(this.value);\n\n const selectedOption = optionsArray.find((opt) => {\n const optValue = this.emitFullObject\n ? JSON.stringify(opt)\n : getValueForComparison(opt);\n return optValue === targetValue;\n });\n\n this.selectedItems = selectedOption ? [selectedOption] : [];\n this.value = selectedOption\n ? this.emitFullObject\n ? selectedOption\n : this.getOptionValue(selectedOption)\n : \"\";\n }\n }\n\n private filterOptions(): void {\n const optionsArray = Array.isArray(this.options) ? this.options : [];\n\n const makeRow = (option: any, idx: number) => {\n const label = this.getOptionLabel(option);\n return {\n original: option,\n _idx: idx, // ✅ stable index\n label,\n highlighted: label,\n };\n };\n\n if (!this.searchable || !this.searchQuery.trim()) {\n this.filteredOptions = optionsArray.map(makeRow);\n return;\n }\n\n const query = this.searchQuery.toLowerCase();\n\n this.filteredOptions = optionsArray\n .map(makeRow)\n .filter((row) => String(row.label).toLowerCase().includes(query))\n .map((row) => {\n const regex = new RegExp(`(${query})`, \"gi\");\n return {\n ...row,\n highlighted: String(row.label).replace(\n regex,\n (m: string) => `<span class=\"highlight\">${m}</span>`,\n ),\n };\n });\n }\n\n\n /** Emit search query for hosts / `v-model:search-query` when `searchQuery` changes outside the search input handler. */\n private emitSearchQueryChanged(): void {\n this.dispatchEvent(\n new CustomEvent<SkyComboboxSearchQueryChangedDetail>(\"search-query-changed\", {\n detail: { searchQuery: this.searchQuery },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private handleInput(event: InputEvent): void {\n if (this.disabled || this.readonly) return;\n this.searchQuery = (event.target as HTMLInputElement).value;\n const optionsLength = Array.isArray(this.options) ? this.options.length : 0;\n const shouldDebounce =\n this.searchable &&\n optionsLength > SkyCombobox._SEARCH_DEBOUNCE_OPTIONS_THRESHOLD;\n\n const applyFilter = () => {\n this.filterOptions();\n this.emitSearchQueryChanged();\n };\n\n if (shouldDebounce) {\n if (this._searchDebounceId != null) clearTimeout(this._searchDebounceId);\n this._searchDebounceId = setTimeout(() => {\n this._searchDebounceId = null;\n applyFilter();\n }, SkyCombobox._SEARCH_DEBOUNCE_MS);\n } else {\n applyFilter();\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (this._searchDebounceId != null) {\n clearTimeout(this._searchDebounceId);\n this._searchDebounceId = null;\n }\n if (this._closeResetId != null) {\n clearTimeout(this._closeResetId);\n this._closeResetId = null;\n }\n }\n\n private handleClear(): void {\n if (this.disabled || this.readonly) return;\n\n const hasSelection = this.multiSelect\n ? this.selectedItems.length > 0\n : !!this.value;\n\n if (this.enforceMinOneSelection && hasSelection) {\n return;\n }\n this.value = this.multiSelect ? [] : \"\";\n this.selectedItems = [];\n this.searchQuery = \"\";\n this.emitSearchQueryChanged();\n this.open = false;\n\n this.dispatchEvent(\n new CustomEvent<SkyComboboxValueChangedDetail>(\"value-changed\", {\n detail: {\n value: this.value,\n selectedItems: [],\n isFilteredSelection: false,\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n this.syncFormValue();\n this.syncValidity();\n }\n\n selectOption(option: any) {\n if (this.disabled || this.readonly) return;\n\n // Get the actual value to emit based on configuration\n const getEmittedValue = (item: any) => {\n return this.emitFullObject ? item : this.getOptionValue(item);\n };\n\n const keyOf = (o: any) => {\n const val = this.getOptionValue(o);\n return typeof val === \"object\" ? JSON.stringify(val) : String(val);\n };\n\n const wasFiltered = this.searchQuery.trim() !== \"\";\n\n if (!this.multiSelect) {\n const alreadySelected =\n this.selectedItems.length &&\n keyOf(this.selectedItems[0]) === keyOf(option);\n\n if (alreadySelected && this.enforceMinOneSelection) {\n this.open = false;\n return;\n }\n\n if (alreadySelected) {\n this.selectedItems = [];\n this.value = \"\";\n } else {\n this.selectedItems = [option];\n this.value = getEmittedValue(option);\n }\n\n this.validateInput();\n\n this.dispatchEvent(\n new CustomEvent(\"value-changed\", {\n detail: {\n value: this.value,\n selectedItems: this.selectedItems,\n emittedValues: this.selectedItems.map(getEmittedValue),\n isFilteredSelection: wasFiltered,\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n // Search reset is deferred in onOpenChange so options stay visible during close animation.\n this.dropdownPopover.closePopover(\"api\");\n this.syncFormValue();\n this.syncValidity();\n this.requestUpdate();\n return;\n }\n\n // Multi-select branch\n const index = this.selectedItems.findIndex(\n (item) => keyOf(item) === keyOf(option),\n );\n\n let nextSelected: any[];\n\n if (index > -1) {\n nextSelected = [\n ...this.selectedItems.slice(0, index),\n ...this.selectedItems.slice(index + 1),\n ];\n } else {\n nextSelected = [...this.selectedItems, option];\n }\n\n if (this.enforceMinOneSelection && nextSelected.length === 0) {\n return;\n }\n\n this.selectedItems = nextSelected;\n this.value = nextSelected.map(getEmittedValue);\n\n this.validateInput();\n\n this.dispatchEvent(\n new CustomEvent(\"value-changed\", {\n detail: {\n value: this.value,\n selectedItems: this.selectedItems,\n emittedValues: this.value,\n isFilteredSelection: wasFiltered,\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n this.syncFormValue();\n this.syncValidity();\n this.open = true;\n this.requestUpdate();\n }\n\n toggleHiddenChips(e: Event) {\n e.stopPropagation();\n e.preventDefault();\n if (this.disabled || this.readonly) return;\n\n // close main dropdown if open\n if (this.open) {\n this.dropdownPopover.closePopover(\"api\");\n }\n\n this.hiddenPopover.toggle();\n }\n\n\n renderHiddenChipsDropdown() {\n return html`\n <div\n class=\"hidden-chips-dropdown\"\n part=\"hidden-chips-dropdown\"\n popover=\"manual\"\n @toggle=${this.hiddenPopover.onToggle}\n @click=${(e: MouseEvent) => e.stopPropagation()}\n style=\"\n left: var(--sky-hc-left, 0px);\n top: var(--sky-hc-top, 0px);\n width: var(--sky-hc-width, max-content);\n z-index: ${this.zIndex};\n \"\n >\n ${repeat(\n this.selectedItems.slice(this.visibleChips),\n (item) => String(this.getOptionValue(item)),\n (item) => html`\n <div class=\"hidden-chip-inner\" part=\"hidden-chip-inner\">\n <span part=\"hidden-chip-label\">\n ${this.truncateText(String(this.getOptionLabel(item)), this.chipSize)}\n </span>\n <sky-icon\n part=\"remove-chip-icon\"\n class=\"remove-chip-inner\"\n icon=\"ion:close\"\n @click=${(e: MouseEvent) => {\n e.stopPropagation();\n this.removeChip(item);\n }}\n ></sky-icon>\n </div>\n `,\n )}\n </div>\n `;\n }\n\n removeChip(option: any) {\n if (this.disabled || this.readonly) return;\n const keyOf = (o: any) => String(this.getOptionValue(o));\n\n const next = this.selectedItems.filter(\n (item) => keyOf(item) !== keyOf(option),\n );\n\n // 🚫 prevent going below 1 selection when enforced\n if (this.enforceMinOneSelection && next.length === 0) {\n return;\n }\n\n this.selectedItems = next;\n if (this.selectedItems.length <= this.visibleChips) {\n this.hiddenPopover.closePopover(\"api\");\n }\n\n if (this.multiSelect) {\n const valuesArray = this.selectedItems.map((opt) =>\n this.emitFullObject ? opt : this.getOptionValue(opt),\n );\n this.value = valuesArray;\n\n this.dispatchEvent(\n new CustomEvent(\"value-changed\", {\n detail: {\n value: valuesArray,\n selectedItems: [...this.selectedItems],\n emittedValues: valuesArray,\n isFilteredSelection: false,\n },\n bubbles: true,\n composed: true,\n }),\n );\n } else {\n this.value = \"\";\n this.dispatchEvent(\n new CustomEvent(\"value-changed\", {\n detail: {\n value: this.value,\n selectedItems: [],\n isFilteredSelection: false,\n },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n this.syncFormValue();\n this.syncValidity();\n this.validateInput();\n this.requestUpdate();\n }\n\n renderChips() {\n if (!this.multiSelect && this.selectedItems.length) {\n return html`\n <span class=\"chip\" single-select part=\"single-select-chip\">\n <span class=\"chip-label\" part=\"chip-label\"\n >${this.getOptionLabel(this.selectedItems[0])}</span\n >\n </span>\n `;\n }\n\n const visible = Array.isArray(this.selectedItems)\n ? this.selectedItems.slice(0, this.visibleChips)\n : [];\n const overflow = this.selectedItems.length - this.visibleChips;\n return html`\n ${repeat(\n visible,\n (item) => String(this.getOptionValue(item)),\n (item) => html`\n <span class=\"chip\" ?compact=${this.compact} part=\"chip\">\n <span class=\"chip-label\" part=\"chip-label\"\n >${this.truncateText(String(this.getOptionLabel(item)), this.chipSize)}</span\n >\n ${when(\n this.multiSelect,\n () => html`\n <sky-icon\n class=\"remove-chip\"\n part=\"remove-chip-icon\"\n ?compact=${this.compact}\n @click=${(e: MouseEvent) => {\n e.stopPropagation();\n this.removeChip(item);\n }}\n icon=\"ion:close\"\n ></sky-icon>\n `,\n )}\n </span>\n `,\n )}\n ${when(\n overflow > 0,\n () => html`\n <span\n class=\"chip overflow-chip\"\n part=\"overflow-chip\"\n style=\"cursor:pointer\"\n ?compact=${this.compact}\n @click=${this.toggleHiddenChips}\n >\n + ${overflow}\n </span>\n `,\n )}\n `;\n }\n\n handleKeydown(event: KeyboardEvent) {\n if ((event.target as HTMLElement)?.closest(\".search-container\")) return;\n const { key, shiftKey } = event;\n\n if (!this.open && (key === \"ArrowDown\" || key === \"ArrowUp\" || key === \"Enter\")) {\n this.dropdownPopover.openPopover();\n event.preventDefault();\n return;\n }\n\n if (!this.open) return;\n\n const hasSearchRow = this.searchable || this.addOption;\n const firstSelectableIndex =\n this.multiSelect && this.selectAll\n ? hasSearchRow\n ? 1\n : 0\n : this.headerRows;\n\n const minIndex = firstSelectableIndex;\n const maxIndex =\n this.headerRows + Math.max(0, this.filteredOptions.length) - 1;\n\n if (this.activeIndex < minIndex) this.activeIndex = minIndex;\n\n if (key === \"ArrowDown\") {\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\n this.activeIndex = was >= maxIndex ? minIndex : was + 1;\n this.scrollActiveItemIntoView();\n event.preventDefault();\n return;\n }\n\n if (key === \"ArrowUp\") {\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\n this.activeIndex = was <= minIndex ? maxIndex : was - 1;\n this.scrollActiveItemIntoView();\n event.preventDefault();\n return;\n }\n\n if (key === \"Tab\") {\n if (shiftKey) {\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\n this.activeIndex = was <= minIndex ? maxIndex : was - 1;\n } else {\n const was = this.activeIndex < minIndex ? minIndex : this.activeIndex;\n this.activeIndex = was >= maxIndex ? minIndex : was + 1;\n }\n this.scrollActiveItemIntoView();\n event.preventDefault();\n return;\n }\n\n if (key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n this.commitDropdownEnter();\n return;\n }\n\n if (this.readonly) {\n if (key === \"Escape\") {\n this.open = false;\n event.preventDefault();\n }\n return;\n }\n\n if (key === \"Home\") {\n this.activeIndex = minIndex;\n this.scrollActiveItemIntoView();\n event.preventDefault();\n return;\n }\n\n if (key === \"End\") {\n this.activeIndex = Math.max(minIndex, maxIndex);\n this.scrollActiveItemIntoView();\n event.preventDefault();\n return;\n }\n }\n\n private onSearchKeydown = (e: KeyboardEvent) => {\n const { key, shiftKey } = e;\n\n if (key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n this.commitDropdownEnter();\n return;\n }\n\n if (key === \"ArrowDown\" || key === \"ArrowUp\" || key === \"Tab\") {\n e.preventDefault();\n e.stopPropagation();\n\n const hasSearchRow = this.searchable || this.addOption;\n const firstSelectableIndex =\n this.multiSelect && this.selectAll\n ? hasSearchRow\n ? 1\n : 0\n : this.headerRows;\n\n const minIndex = firstSelectableIndex;\n const maxIndex =\n this.headerRows + Math.max(0, this.filteredOptions.length) - 1;\n\n const dir = key === \"ArrowUp\" || (key === \"Tab\" && e.shiftKey) ? -1 : 1;\n if (this.activeIndex < minIndex) this.activeIndex = minIndex;\n else\n this.activeIndex =\n this.activeIndex + dir < minIndex\n ? maxIndex\n : this.activeIndex + dir > maxIndex\n ? minIndex\n : this.activeIndex + dir;\n\n this.scrollActiveItemIntoView();\n }\n\n if (key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n this.dropdownPopover.closePopover(\"escape\");\n return;\n }\n };\n\n /** Number of non-option rows before the first option (search + select-all). */\n private get headerRows(): number {\n let n = 0;\n if (this.searchable || this.addOption) n += 1;\n if (this.multiSelect && this.selectAll) n += 1;\n return n;\n }\n\n\n private getOptionByActiveIndex(): {\n kind: \"search\" | \"select-all\" | \"option\";\n optionIndex?: number;\n } | null {\n if (!this.open) return null;\n const idx = this.activeIndex;\n if (idx < 0) return null;\n\n if (this.searchable || this.addOption) {\n if (idx === 0) return { kind: \"search\" };\n }\n\n const selectAllBase = this.searchable || this.addOption ? 1 : 0;\n if (this.multiSelect && this.selectAll && idx === selectAllBase) {\n return { kind: \"select-all\" };\n }\n\n const optionIndex = idx - this.headerRows;\n if (optionIndex >= 0 && optionIndex < this.filteredOptions.length) {\n return { kind: \"option\", optionIndex };\n }\n return null;\n }\n\n /**\n * Commits the current keyboard highlight on Enter (search row vs select-all vs option).\n * Shared by {@link handleKeydown} and {@link onSearchKeydown} so focus in the search\n * field matches the same semantics as the input wrapper.\n */\n private commitDropdownEnter(): void {\n const target = this.getOptionByActiveIndex();\n if (!target) return;\n\n if (target.kind === \"search\") {\n if (this.addOption && this.canAddaddOption()) {\n this.dispatchEvent(\n new CustomEvent(\"add-new-option\", {\n detail: { value: this.searchQuery.trim() },\n bubbles: true,\n composed: true,\n }),\n );\n this.searchQuery = \"\";\n this.emitSearchQueryChanged();\n this.filterOptions();\n } else if (this.filteredOptions.length > 0) {\n this.selectOption(this.filteredOptions[0].original);\n }\n return;\n }\n if (target.kind === \"select-all\") {\n this.toggleSelectAll();\n return;\n }\n if (target.kind === \"option\" && typeof target.optionIndex === \"number\") {\n const selectedOption =\n this.filteredOptions[target.optionIndex].original;\n this.selectOption(selectedOption);\n }\n }\n\n /** Focus logic when opening the dropdown. */\n private focusOnOpen() {\n const search = this.searchInputEl;\n if (search) {\n if (document.activeElement !== search) {\n requestAnimationFrame(() => search.focus());\n }\n\n this.activeIndex = 0;\n this.scrollActiveItemIntoView();\n return;\n }\n\n let optionIdx = 0;\n if (this.selectedItems.length > 0) {\n const firstSelVal = this.getOptionValue(this.selectedItems[0]);\n const idxInFiltered = this.filteredOptions.findIndex(\n (o) => this.getOptionValue(o.original) === firstSelVal,\n );\n if (idxInFiltered >= 0) optionIdx = idxInFiltered;\n }\n this.activeIndex = this.headerRows + optionIdx;\n this.scrollActiveItemIntoView();\n }\n\n private canAddaddOption(): boolean {\n if (!this.addOption) return false;\n const q = this.searchQuery.trim();\n if (!q) return false;\n\n // Ensure options is always an array\n const optionsArray = Array.isArray(this.options) ? this.options : [];\n\n const dup = optionsArray.some((opt) => {\n const label = String(this.getOptionLabel(opt) || \"\").toLowerCase();\n const val = (this.getOptionValue(opt) ?? \"\").toString().toLowerCase();\n return label === q.toLowerCase() || val === q.toLowerCase();\n });\n return !dup;\n }\n private handleAddaddOption = (e: MouseEvent) => {\n e.stopPropagation();\n if (this.disabled || this.readonly) return;\n if (!this.canAddaddOption()) return;\n\n const value = this.searchQuery.trim();\n\n this.dispatchEvent(\n new CustomEvent(\"add-new-option\", {\n detail: { value },\n bubbles: true,\n composed: true,\n }),\n );\n\n this.searchQuery = \"\";\n this.emitSearchQueryChanged();\n this.filterOptions();\n };\n\n scrollActiveItemIntoView() {\n const rows = Array.from(this.rowEls);\n const active = rows.find(\n (r) => Number(r.dataset.rowIndex) === this.activeIndex,\n );\n active?.scrollIntoView({ block: \"nearest\", behavior: \"smooth\" });\n }\n\n toggleDropdown(event: MouseEvent) {\n event.stopPropagation();\n if (this.disabled || this.readonly) return;\n\n // close hidden chips if open\n if (this.hiddenChipsOpen) {\n this.hiddenPopover.closePopover(\"api\");\n }\n\n this.validationActive = true;\n this.dropdownPopover.toggle();\n }\n\n\n\n renderDropdown() {\n return html`\n <div\n class=\"dropdown\"\n part=\"dropdown\"\n popover=\"manual\"\n @toggle=${this.dropdownPopover.onToggle}\n @click=${(e: MouseEvent) => e.stopPropagation()}\n style=\"\n left: var(--sky-dd-left, 0px);\n top: var(--sky-dd-top, 0px);\n min-width: var(--sky-dd-width, 100%);\n \"\n >\n ${when(\n this.searchable || this.addOption,\n () => html`\n <div\n class=\"search-container\"\n data-row-index=\"0\"\n part=\"search-container\"\n >\n <sky-icon icon=\"ion:search\"></sky-icon>\n\n <input\n .value=${this.searchQuery}\n part=\"search-input\"\n tabindex=\"0\"\n ?readonly=${this.readonly ||\n (!this.searchable && !this.addOption)}\n @input=${this.searchable || this.addOption\n ? this.handleInput\n : null}\n @keydown=${this.onSearchKeydown}\n @focus=${this.searchable || this.addOption\n ? this.handleFocus\n : null}\n @blur=${this.searchable || this.addOption\n ? this.handleBlur\n : null}\n ?compact=${this.compact}\n ?disabled=${this.disabled}\n placeholder=${this.searchPlaceholder}\n class=\"input\"\n />\n\n ${when(\n this.addOption,\n () => html`\n <sky-icon\n class=\"new-option-btn\"\n icon=\"ion:add\"\n part=\"add-option-icon\"\n title=\"Add as new option\"\n aria-label=\"Add as new option\"\n @click=${this.handleAddaddOption}\n ></sky-icon>\n `,\n )}\n </div>\n `,\n )}\n\n<div class=\"dropdown-scroller\">\n ${when(\n this.multiSelect && this.selectAll && this.filteredOptions.length,\n () => {\n const selectAllRowIndex = this.searchable || this.addOption ? 1 : 0;\n const selectAllClasses = classMap({\n \"dropdown-item\": true,\n active: this.activeIndex === selectAllRowIndex,\n selected: this.isAllFilteredSelected(),\n });\n return html`\n <div\n class=${selectAllClasses}\n data-row-index=${selectAllRowIndex}\n style=\"justify-content: ${this.justify};\"\n part=\"select-all\"\n @click=${this.toggleSelectAll}\n >\n <sky-checkbox\n .checked=${this.isAllFilteredSelected()}\n readonly\n ></sky-checkbox>\n Select All\n </div>\n `;\n },\n )}\n ${when(\n this.filteredOptions.length > 0,\n () => repeat(\n this.filteredOptions,\n ({ original, _idx }) => `${_idx}-${String(this.getOptionValue(original))}`,\n ({ original, highlighted, _idx }, index) => {\n const slotName = `option-${_idx}`;\n const hasSlot = this.optionSlotSet.has(slotName);\n\n const keyOf = (o: any) =>\n String(this.getOptionValue(o.original ?? o));\n const isSelected =\n Array.isArray(this.selectedItems) &&\n this.selectedItems.some(\n (item) => keyOf(item) === keyOf(original),\n );\n const rowIndex = this.headerRows + index;\n const isActive = rowIndex === this.activeIndex;\n const itemClasses = classMap({\n \"dropdown-item\": true,\n active: isActive,\n selected: isSelected,\n });\n\n return html`\n <div\n class=${itemClasses}\n data-row-index=${rowIndex}\n style=\"justify-content: ${this.justify};\"\n part=\"option\"\n @click=${() => this.selectOption(original)}\n ?compact=${this.compact}\n >\n ${when(\n this.multiSelect,\n () => html` <sky-checkbox\n .checked=${isSelected}\n readonly\n ></sky-checkbox>`,\n )}\n ${when(\n hasSlot,\n () => html`\n <div style=\"display: flex; gap: 8px;width:100%\">\n <slot name=${slotName}>\n <span\n class=\"highlighted-text\"\n part=\"highlighted-text\"\n >${unsafeHTML(highlighted)}</span\n >\n </slot>\n </div>\n `,\n () => html`<span\n class=\"highlighted-text\"\n part=\"highlighted-text\"\n >${unsafeHTML(highlighted)}</span\n >`,\n )}\n </div>\n `;\n },\n ),\n () => html`<div\n class=\"dropdown-item\"\n part=\"no-options\"\n data-row-index=${this.headerRows}\n >\n No options found\n </div>`,\n )}\n </div>\n </div>\n `;\n }\n\n\n getOptionValue(option: any): any {\n if (this.emitFullObject) {\n return option; // Return the full object\n }\n\n // When emitFullObject is false, return the emittedKey value\n if (typeof option === \"object\" && option !== null) {\n // First try the emittedKey\n if (this.emittedKey in option) {\n return option[this.emittedKey];\n }\n // Fallback to any value property\n if (\"value\" in option) {\n return option.value;\n }\n // Fallback to the object itself\n return option;\n }\n\n // For primitives, return as-is\n return option;\n }\n\n getOptionLabel(option: any): string {\n if (!option) return \"\";\n\n // Ensure options is an array before calling find/map methods\n const optionsArray = Array.isArray(this.options) ? this.options : [];\n\n if (\n this.displayKey &&\n typeof option === \"object\" &&\n option[this.displayKey]\n ) {\n return String(option[this.displayKey]);\n }\n\n if (typeof option === \"object\") {\n const stringValues = Object.values(option).filter(\n (value) => typeof value === \"string\",\n ) as string[];\n return stringValues.length > 0 ? stringValues[0]! : JSON.stringify(option);\n }\n\n return String(option);\n }\n\n renderValidationErrors() {\n if (!this.showErrors || !this.validationActive) return null;\n\n const msgs = this.getErrorMessages(); // ✅ respects single/all/none\n\n if (!msgs.length) return null;\n\n const errId = `${this.id || \"sky-combobox\"}-errors`;\n\n return html`\n <div class=\"progress-message\">\n <ul id=${errId} class=\"error-list\" part=\"error-list\">\n ${repeat(msgs, (m) => m, (m) => html`<li class=\"error\" part=\"error-item\">${m}</li>`)}\n </ul>\n </div>\n `;\n }\n\n getErrorMessages() {\n const errs = Array.isArray(this.validationErrors)\n ? this.validationErrors\n : [];\n switch (this.errorDisplayMode) {\n case \"single\":\n return errs.slice(0, 1);\n case \"all\":\n return errs;\n case \"none\":\n default:\n return [];\n }\n }\n\n handleIconClick(position: \"left\" | \"right\", event: MouseEvent) {\n this.dispatchEvent(\n new CustomEvent(\"icon-click\", {\n detail: { position, event },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private onIconSlotChange = () => {\n this.hasLeftIcon = (this.iconLeftEls?.length ?? 0) > 0;\n this.hasRightIcon = (this.iconRightEls?.length ?? 0) > 0;\n };\n\n override render() {\n const leftIconClasses = classMap({ \"icon-slot\": true, left: true, focused: this.focused });\n const rightIconClasses = classMap({ \"icon-slot\": true, right: true, focused: this.focused });\n const placeholderClasses = classMap({\n \"placeholder-label\": true,\n active: this.selectedItems.length > 0,\n });\n return html`\n <div class=\"combo-box-container\" part=\"combo-box-container\">\n ${when(this.label, () => html`<div class=\"label\" part=\"label\">${this.label}</div>`)}\n <div\n class=\"input-wrapper\"\n tabindex=\"0\"\n part=\"input-wrapper\"\n ?disabled=${this.disabled}\n ?compact=${this.compact}\n ?loading=${this.loading}\n ?open=${this.open}\n ?invalid=${this.invalid}\n @click=${(e: MouseEvent) => {\n if (!this.disabled && !this.readonly) {\n this.toggleDropdown(e);\n }\n }}\n @keydown=${this.handleKeydown}\n >\n <!-- Left Icon or Loading Indicator -->\n <div\n class=${leftIconClasses}\n part=\"icon-slot\"\n ?filled=${this.hasLeftIcon}\n @click=${(e: MouseEvent) => this.handleIconClick(\"left\", e)}\n >\n <slot name=\"icon-left\" @slotchange=${this.onIconSlotChange}></slot>\n </div>\n ${when(\n this.selectedItems.length > 0,\n () => html`\n <div\n class=\"chip-container\"\n part=\"chip-container\"\n ?compact=${this.compact}\n >\n ${this.renderChips()}\n </div>\n `,\n () => html`<label\n class=${placeholderClasses}\n part=\"placeholder-label\"\n ?compact=${this.compact}\n >\n <span style=\"color:${this.prefixColor}\">${this.prefix}</span\n >${this.placeholder}<span style=\"color:${this.suffixColor}\"\n >${this.suffix}</span\n >\n </label>`,\n )}\n ${when(\n this.clearable &&\n !this.enforceMinOneSelection &&\n (this.value || this.selectedItems.length),\n () => html`<sky-icon\n class=\"clear-button\"\n part=\"clear-button\"\n @click=${this.handleClear}\n ?loading=${this.loading}\n icon=\"ion:close\"\n ></sky-icon>`,\n )}\n ${when(\n this.loading,\n () => html`<div class=\"loading-indicator right\"></div>`,\n () => html`<div\n part=\"icon-slot\"\n class=${rightIconClasses}\n ?filled=${this.hasRightIcon}\n @click=${(e: MouseEvent) => this.handleIconClick(\"right\", e)}\n >\n <slot name=\"icon-right\" @slotchange=${this.onIconSlotChange}></slot>\n </div>`,\n )}\n <sky-icon\n class=\"dropdown-button\"\n part=\"dropdown-button\"\n @click=${(e: MouseEvent) => {\n if (!this.disabled && !this.readonly) {\n this.toggleDropdown(e);\n }\n }}\n icon=${this.open ? \"ion:ios-arrow-up\" : \"ion:chevron-down\"}\n >\n </sky-icon>\n </div>\n ${this.renderHiddenChipsDropdown()} ${this.renderDropdown()}\n ${this.renderValidationErrors()}\n <slot style=\"display:none\" @slotchange=${this.refreshOptionSlots}></slot>\n </div>\n `;\n }\n}\n"],"names":["SkyCombobox","FormControlBase","constructor","super","this","value","placeholder","searchPlaceholder","label","_options","chipSize","color","clearable","loading","compact","disabled","searchable","multiSelect","visibleChips","selectAll","_validations","showErrors","errorDisplayMode","required","emitFullObject","emittedKey","displayKey","addOption","validationArrayFormat","prefix","suffix","prefixColor","suffixColor","justify","zIndex","height","requiredMessage","readonly","enforceMinOneSelection","openAbove","validationActive","invalid","variant","searchQuery","filteredOptions","focused","open","selectedItems","hiddenChipsOpen","activeIndex","validationErrors","validationStatus","hasLeftIcon","hasRightIcon","optionSlotSet","Set","_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","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","Array","isArray","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","option","optionValue","optionValueString","some","parsedValue","map","getValidityAnchor","isEmpty","getNativeControl","getCustomErrorMessage","onFormReset","onFormDisabled","onFormStateRestore","toggleSelectAll","keyOf","o","isAllFilteredSelected","filteredKeys","opt","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","isEmptyMulti","_","getValueForComparison","val","raw","providedKeys","optValue","targetValue","selectedOption","find","makeRow","idx","getOptionLabel","_idx","highlighted","query","toLowerCase","row","includes","regex","RegExp","replace","m","handleInput","event","optionsLength","shouldDebounce","_SEARCH_DEBOUNCE_OPTIONS_THRESHOLD","applyFilter","_SEARCH_DEBOUNCE_MS","disconnectedCallback","hasSelection","selectOption","getEmittedValue","wasFiltered","alreadySelected","index","findIndex","toggleHiddenChips","toggle","renderHiddenChipsDropdown","html","onToggle","repeat","removeChip","next","renderChips","visible","overflow","when","handleKeydown","closest","was","n","getOptionByActiveIndex","kind","selectAllBase","optionIndex","search","document","activeElement","optionIdx","firstSelVal","idxInFiltered","q","active","from","rowEls","r","Number","dataset","rowIndex","scrollIntoView","block","behavior","toggleDropdown","renderDropdown","selectAllRowIndex","selectAllClasses","classMap","selected","hasSlot","isSelected","isActive","itemClasses","unsafeHTML","stringValues","Object","renderValidationErrors","msgs","getErrorMessages","errId","id","errs","handleIconClick","position","render","leftIconClasses","left","rightIconClasses","right","placeholderClasses","dependencies","SkyIcon","SkyCheckbox","styles","css","shadowRootOptions","LitElement","delegatesFocus","__decorateClass","property","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 } 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 { 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\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\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/**\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://library.sky-ui.com/components/combobox\r\n * @dependency sky-icon\r\n * @dependency sky-checkbox\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 dropdown-button - The dropdown toggle arrow button\r\n * @csspart chip-container - Container for the chips in multi-select mode\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 {string} label - Optional external label text.\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 {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 variant style.\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 *\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 };\r\n\r\n // ============================================================\r\n // ✅ PUBLIC PROPERTIES (user-configurable)\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 @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: string = \"default\";\r\n\r\n // ============================================================\r\n // ✅ INTERNAL STATE (read-only, managed by component)\r\n // ============================================================\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\r\n // ============================================================\r\n // ✅ PRIVATE FIELDS (internal, not reactive)\r\n // ============================================================\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 .input\") private searchInputEl!: HTMLInputElement;\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 static readonly _SEARCH_DEBOUNCE_MS = 150;\r\n private static readonly _SEARCH_DEBOUNCE_OPTIONS_THRESHOLD = 30;\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.validationActive = true;\r\n this.filterOptions();\r\n requestAnimationFrame(() => this.focusOnOpen());\r\n } else {\r\n this.activeIndex = -1;\r\n this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\r\n this.filterOptions();\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 static override styles = css`\r\n :host {\r\n display: block;\r\n font-family: var(--sky-font);\r\n width: 100%;\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\"]) {\r\n .label{\r\n color: var(--sky-dropdown-color);\r\n }\r\n }\r\n\r\n .combo-box-container:focus-within .label {\r\n color: var(--sky-dropdown-color);\r\n font-size: var(--sky-font-size-sm);\r\n transition: all 0.3s ease;\r\n }\r\n .label {\r\n font-size: var(--sky-font-size-sm);\r\n margin-bottom: 5px;\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 }\r\n\r\n .combo-box-container:focus-within[compact] .label {\r\n font-size: var(--sky-font-size-xs);\r\n color: var(--sky-dropdown-color);\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: 5px;\r\n border-bottom: 1px solid var(--sky-border-light);\r\n justify-content: space-between;\r\n margin-bottom: 5px;\r\n }\r\n\r\n .search-container sky-icon {\r\n width: 16px;\r\n height: 16px;\r\n color: var(--sky-text-secondary);\r\n transition: color 0.15s ease;\r\n }\r\n\r\n .search-container:has(.input:focus) sky-icon {\r\n color: var(--sky-active-primary);\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: 38px;\r\n width: 100%;\r\n flex-wrap: nowrap;\r\n position: relative;\r\n border: var(--sky-border-primary);\r\n box-shadow: var(--sky-box-shadow-primary);\r\n transition: border-color 0.3s ease, box-shadow 0.3s ease;\r\n flex: 1 1 auto;\r\n min-width: 0;\r\n \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 :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: 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: 30px;\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-block;\r\n width: 1em;\r\n height: 1em;\r\n }\r\n\r\n .chip-container {\r\n margin-left: 5px;\r\n display: flex;\r\n gap: 8px;\r\n flex: 1 1 auto;\r\n min-width: 0;\r\n flex-wrap: nowrap;\r\n }\r\n\r\n :dir(rtl).chip-container {\r\n margin-right: 5px;\r\n margin-left: 0px;\r\n }\r\n\r\n .chip-container::-webkit-scrollbar {\r\n display: none;\r\n }\r\n\r\n .chip-container[compact] {\r\n gap: 4px;\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: 4px 8px;\r\n font-size: var(--sky-font-size-sm);\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n flex-shrink: 0;\r\n min-width: 0;\r\n border: var(--sky-border-primary);\r\n font-family: var(--sky-font);\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 }\r\n\r\n .chip[single-select] {\r\n background-color: transparent;\r\n box-shadow: none;\r\n border: none;\r\n font-size: var(--sky-font-size-md);\r\n padding: 4px;\r\n gap: 0;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n min-width: 0;\r\n width:100%;\r\n }\r\n\r\n .chip[single-select] .chip-label {\r\n flex: 1 1 auto;\r\n min-width: 0;\r\n }\r\n\r\n :host([icon-left]) .chip[single-select] {\r\n padding:4px 0;\r\n }\r\n\r\n .chip[single-select] .remove-chip {\r\n display: none;\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 {\r\n border: none;\r\n font-family: var(--sky-font);\r\n outline: none;\r\n font-size: var(--sky-font-size-md);\r\n background: transparent;\r\n box-sizing: border-box;\r\n color: var(--sky-text-secondary);\r\n width: 100%;\r\n transition: all 0.2 ease-in-out;\r\n }\r\n\r\n .search-container:has(.input:focus:focus) {\r\n border-bottom-color: var(--sky-active-primary);\r\n }\r\n\r\n .input:-webkit-autofill {\r\n -webkit-text-fill-color: var(--sky-text-secondary, inherit) !important;\r\n transition: background-color 9999s ease-in-out 0s !important;\r\n }\r\n\r\n .input[disabled] {\r\n opacity: 70%;\r\n color: var(--sky-text-primary);\r\n cursor: disabled;\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 \r\n border: var(--sky-border-tertiary);\r\n \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.active {\r\n background-color: var(--sky-hover-primary);\r\n }\r\n .dropdown-item.selected {\r\n color: var(--sky-dropdown-color, var(--sky-active-primary));\r\n }\r\n\r\n .dropdown-item.active.selected {\r\n background-color: var(--sky-active-g0);\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: all 0.2s ease-in-out;\r\n box-sizing: border-box;\r\n margin: 2px 0;\r\n font-family: var(--sky-font);\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 border-radius: var(--sky-radius-secondary);\r\n height: inherit;\r\n max-height: 100%;\r\n box-sizing: border-box;\r\n min-width: 36px;\r\n background: var(--sky-glass-solid);\r\n color: var(--sky-text-primary);\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n \r\n transition:\r\n transform 0.3s ease,\r\n color 0.3s 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 \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\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 cursor: pointer;\r\n }\r\n .icon-slot.left {\r\n border-right: var(--sky-border-primary);\r\n }\r\n\r\n :dir(rtl) .icon-slot.left {\r\n border-left: var(--sky-border-primary);\r\n border-right: unset;\r\n }\r\n\r\n .icon-slot.right {\r\n border-left: var(--sky-border-primary);\r\n }\r\n\r\n :dir(rtl) .icon-slot.right {\r\n border-right: var(--sky-border-primary);\r\n border-left: unset;\r\n }\r\n\r\n .input-wrapper[open] .icon-slot {\r\n transform: translate(-5px, -5px);\r\n border: var(--sky-border-primary) !important;\r\n color: var(--sky-dropdown-color);\r\n background-color: var(--sky-glass-solid);\r\n }\r\n\r\n :dir(rtl) .input-wrapper[open] .icon-slot {\r\n transform: translate(5px, -5px);\r\n }\r\n\r\n .input-wrapper[open] .icon-slot.right {\r\n transform: translate(5px, -5px);\r\n }\r\n\r\n :dir(rtl) .input-wrapper[open] .icon-slot.right {\r\n transform: translate(-5px, -5px);\r\n }\r\n\r\n .placeholder-label {\r\n white-space: nowrap;\r\n padding: 0 8px;\r\n flex: 1 1 0%;\r\n text-align: start;\r\n font-size: var(--sky-font-size-md);\r\n color: var(--sky-text-tertiary);\r\n transition: all 0.3s ease;\r\n pointer-events: none;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n font-family: var(--sky-font);\r\n }\r\n\r\n .placeholder-label.active {\r\n display: none;\r\n }\r\n\r\n .dropdown-item:hover {\r\n background-color: var(--sky-hover-primary);\r\n }\r\n\r\n .clear-button {\r\n flex-shrink: 0;\r\n margin-inline-end: var(--sky-space-1, 4px);\r\n border: none;\r\n font-size: var(--sky-font-size-xl);\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 0.3s ease;\r\n }\r\n\r\n .clear-button[compact] {\r\n font-size: var(--sky-font-size-md);\r\n }\r\n\r\n .clear-button:hover {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n .dropdown-button {\r\n flex-shrink: 0;\r\n color: var(--sky-text-primary);\r\n height: 100%;\r\n width: auto;\r\n aspect-ratio: 1;\r\n display: flex;\r\n border: none;\r\n font-size: var(--sky-font-size-sm);\r\n cursor: pointer;\r\n transition: color 0.3s ease;\r\n }\r\n\r\n .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-space-1, 4px);\r\n width: 16px;\r\n height: 16px;\r\n border: 2px solid var(--sky-text-white);\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-left: 5px;\r\n font-family: var(--sky-font);\r\n }\r\n\r\n :dir(rtl) .progress-message {\r\n margin-left: unset;\r\n margin-right: 5px;\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-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-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\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 // ✅ allow keyboard tabbing to the component\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 // For multi-select, return a FormData object with all selected values\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 // For single select\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 // Get all values with the same name from 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 // Single select\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 // For multi-select, set multiple form values with the same name\r\n // This matches how native <select multiple> works\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 // Single select\r\n this.internals.setFormValue(v as string | File | null);\r\n }\r\n }\r\n private setValueFromArray(values: any[]) {\r\n // Ensure options is always an array\r\n const optionsArray = Array.isArray(this.options) ? this.options : [];\r\n\r\n // Filter options based on the submitted values\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 // Handle both string comparison and JSON comparison\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 // Update the internal value\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 the input wrapper or a focusable element within it\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 // ============================================================\r\n // Override FormControlBase methods for combobox-specific behavior\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 const keyOf = (o: any) => String(this.getOptionValue(o));\r\n\r\n if (this.isAllFilteredSelected()) {\r\n const filteredKeys = new Set(\r\n this.filteredOptions.map((opt) =>\r\n String(this.getOptionValue(opt.original)),\r\n ),\r\n );\r\n\r\n const nextSelected = this.selectedItems.filter(\r\n (item) => !filteredKeys.has(keyOf(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) => keyOf(item)),\r\n );\r\n const additions = this.filteredOptions\r\n .map((o) => o.original)\r\n .filter((opt) => !selectedKeys.has(keyOf(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 filteredValues = this.filteredOptions.map((opt) =>\r\n this.getOptionValue(opt.original),\r\n );\r\n return filteredValues.every((value) =>\r\n this.selectedItems.some((item) => this.getOptionValue(item) === value),\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 // ✅ Always blocks form submit when invalid (even if validationActive=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 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(\"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 // ✅ Ensure options is an array before processing\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 // ✅ Call filterOptions which now handles non-array options safely\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 private syncSelectedItemsWithValue(): void {\r\n // Ensure options is always an array\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 const getValueForComparison = (item: any) => {\r\n const val = this.getOptionValue(item);\r\n return typeof val === \"object\" ? JSON.stringify(val) : String(val);\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(\r\n raw.map((v) => {\r\n if (this.emitFullObject && typeof v === \"object\") {\r\n return JSON.stringify(v);\r\n }\r\n return String(v);\r\n }),\r\n );\r\n\r\n // Filter actual option objects whose key is in providedKeys\r\n this.selectedItems = optionsArray.filter((opt) => {\r\n const optValue = this.emitFullObject\r\n ? JSON.stringify(opt)\r\n : getValueForComparison(opt);\r\n return providedKeys.has(optValue);\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 =\r\n this.emitFullObject && typeof this.value === \"object\"\r\n ? JSON.stringify(this.value)\r\n : String(this.value);\r\n\r\n const selectedOption = optionsArray.find((opt) => {\r\n const optValue = this.emitFullObject\r\n ? JSON.stringify(opt)\r\n : getValueForComparison(opt);\r\n return optValue === 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, // ✅ stable index\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 handleInput(event: InputEvent): void {\r\n if (this.disabled || this.readonly) return;\r\n this.searchQuery = (event.target as HTMLInputElement).value;\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 }\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 // Get the actual value to emit based on configuration\r\n const getEmittedValue = (item: any) => {\r\n return this.emitFullObject ? item : this.getOptionValue(item);\r\n };\r\n\r\n const keyOf = (o: any) => {\r\n const val = this.getOptionValue(o);\r\n return typeof val === \"object\" ? JSON.stringify(val) : String(val);\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 keyOf(this.selectedItems[0]) === keyOf(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 this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\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 // Multi-select branch\r\n const index = this.selectedItems.findIndex(\r\n (item) => keyOf(item) === keyOf(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) => String(this.getOptionValue(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.truncateText(String(this.getOptionLabel(item)), this.chipSize)}\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 const keyOf = (o: any) => String(this.getOptionValue(o));\r\n\r\n const next = this.selectedItems.filter(\r\n (item) => keyOf(item) !== keyOf(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 if (!this.multiSelect && this.selectedItems.length) {\r\n return html`\r\n <span class=\"chip\" single-select part=\"single-select-chip\">\r\n <span class=\"chip-label\" part=\"chip-label\"\r\n >${this.getOptionLabel(this.selectedItems[0])}</span\r\n >\r\n </span>\r\n `;\r\n }\r\n\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) => String(this.getOptionValue(item)),\r\n (item) => html`\r\n <span class=\"chip\" ?compact=${this.compact} part=\"chip\">\r\n <span class=\"chip-label\" part=\"chip-label\"\r\n >${this.truncateText(String(this.getOptionLabel(item)), this.chipSize)}</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 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 this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\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 this.searchQuery = \"\";\r\n this.emitSearchQueryChanged();\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) {\r\n if (document.activeElement !== search) {\r\n requestAnimationFrame(() => search.focus());\r\n }\r\n\r\n this.activeIndex = 0;\r\n this.scrollActiveItemIntoView();\r\n return;\r\n }\r\n\r\n let optionIdx = 0;\r\n if (this.selectedItems.length > 0) {\r\n const firstSelVal = this.getOptionValue(this.selectedItems[0]);\r\n const idxInFiltered = this.filteredOptions.findIndex(\r\n (o) => this.getOptionValue(o.original) === firstSelVal,\r\n );\r\n if (idxInFiltered >= 0) optionIdx = idxInFiltered;\r\n }\r\n this.activeIndex = this.headerRows + optionIdx;\r\n this.scrollActiveItemIntoView();\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 // Ensure options is always an array\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-icon icon=\"ion:search\"></sky-icon>\r\n\r\n <input\r\n .value=${this.searchQuery}\r\n part=\"search-input\"\r\n tabindex=\"0\"\r\n ?readonly=${this.readonly ||\r\n (!this.searchable && !this.addOption)}\r\n @input=${this.searchable || this.addOption\r\n ? this.handleInput\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 ?compact=${this.compact}\r\n ?disabled=${this.disabled}\r\n placeholder=${this.searchPlaceholder}\r\n class=\"input\"\r\n />\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(this.open, () => html`\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}-${String(this.getOptionValue(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 keyOf = (o: any) =>\r\n String(this.getOptionValue(o.original ?? o));\r\n const isSelected =\r\n Array.isArray(this.selectedItems) &&\r\n this.selectedItems.some(\r\n (item) => keyOf(item) === keyOf(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 ?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 ${when(\r\n hasSlot,\r\n () => html`\r\n <div style=\"display: flex; gap: 8px;width:100%\">\r\n <slot name=${slotName}>\r\n <span\r\n class=\"highlighted-text\"\r\n part=\"highlighted-text\"\r\n >${unsafeHTML(highlighted)}</span\r\n >\r\n </slot>\r\n </div>\r\n `,\r\n () => html`<span\r\n class=\"highlighted-text\"\r\n part=\"highlighted-text\"\r\n >${unsafeHTML(highlighted)}</span\r\n >`,\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 `)}\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 // For primitives, return as-is\r\n return option;\r\n }\r\n\r\n getOptionLabel(option: any): string {\r\n if (!option) return \"\";\r\n\r\n // Ensure options is an array before calling find/map methods\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(); // ✅ respects single/all/none\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 return html`\r\n <div class=\"combo-box-container\" part=\"combo-box-container\">\r\n ${when(this.label, () => html`<div class=\"label\" part=\"label\">${this.label}</div>`)}\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=${(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 <!-- Left Icon or Loading Indicator -->\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 ${when(\r\n this.selectedItems.length > 0,\r\n () => html`\r\n <div\r\n class=\"chip-container\"\r\n part=\"chip-container\"\r\n ?compact=${this.compact}\r\n >\r\n ${this.renderChips()}\r\n </div>\r\n `,\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 ${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 @click=${this.handleClear}\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 () => html`<div\r\n part=\"icon-slot\"\r\n class=${rightIconClasses}\r\n ?filled=${this.hasRightIcon}\r\n @click=${(e: MouseEvent) => this.handleIconClick(\"right\", e)}\r\n >\r\n <slot name=\"icon-right\" @slotchange=${this.onIconSlotChange}></slot>\r\n </div>`,\r\n )}\r\n <sky-icon\r\n class=\"dropdown-button\"\r\n part=\"dropdown-button\"\r\n @click=${(e: MouseEvent) => {\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 ${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":["SkyCombobox","FormControlBase","constructor","super","this","value","placeholder","searchPlaceholder","label","_options","chipSize","color","clearable","loading","compact","disabled","searchable","multiSelect","visibleChips","selectAll","_validations","showErrors","errorDisplayMode","required","emitFullObject","emittedKey","displayKey","addOption","validationArrayFormat","prefix","suffix","prefixColor","suffixColor","justify","zIndex","height","requiredMessage","readonly","enforceMinOneSelection","openAbove","validationActive","invalid","variant","searchQuery","filteredOptions","focused","open","selectedItems","hiddenChipsOpen","activeIndex","validationErrors","validationStatus","hasLeftIcon","hasRightIcon","optionSlotSet","Set","_searchDebounceId","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","filterOptions","requestAnimationFrame","focusOnOpen","emitSearchQueryChanged","hiddenPopover","closePopover","overflowChipEl","hiddenDropdownEl","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","Array","isArray","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","option","optionValue","optionValueString","some","parsedValue","map","getValidityAnchor","isEmpty","getNativeControl","getCustomErrorMessage","onFormReset","onFormDisabled","onFormStateRestore","toggleSelectAll","keyOf","o","isAllFilteredSelected","filteredKeys","opt","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","isEmptyMulti","_","getValueForComparison","val","raw","providedKeys","optValue","targetValue","selectedOption","find","makeRow","idx","getOptionLabel","_idx","highlighted","query","toLowerCase","row","includes","regex","RegExp","replace","m","handleInput","event","optionsLength","shouldDebounce","_SEARCH_DEBOUNCE_OPTIONS_THRESHOLD","applyFilter","clearTimeout","setTimeout","_SEARCH_DEBOUNCE_MS","disconnectedCallback","hasSelection","selectOption","getEmittedValue","wasFiltered","alreadySelected","index","findIndex","toggleHiddenChips","toggle","renderHiddenChipsDropdown","html","onToggle","repeat","removeChip","next","renderChips","visible","overflow","when","handleKeydown","closest","was","n","getOptionByActiveIndex","kind","selectAllBase","optionIndex","search","document","activeElement","optionIdx","firstSelVal","idxInFiltered","q","active","from","rowEls","r","Number","dataset","rowIndex","scrollIntoView","block","behavior","toggleDropdown","renderDropdown","selectAllRowIndex","selectAllClasses","classMap","selected","hasSlot","isSelected","isActive","itemClasses","unsafeHTML","stringValues","Object","renderValidationErrors","msgs","getErrorMessages","errId","id","errs","handleIconClick","position","render","leftIconClasses","left","rightIconClasses","right","placeholderClasses","dependencies","SkyIcon","SkyCheckbox","styles","css","shadowRootOptions","LitElement","delegatesFocus","__decorateClass","property","prototype","type","Boolean","reflect","attribute","queryAll","queryAssignedElements","customElement"],"mappings":"i5BA0JO,IAAMA,EAAN,cAA0BC,EA64B/B,WAAAC,GACEC,QAl4BUC,KAAAC,MAAa,GACGD,KAAAE,YAAsB,mBACtBF,KAAAG,kBAA4B,YAC5BH,KAAAI,MAAgB,GAC5CJ,KAAQK,SAAkB,GAUEL,KAAAM,SAAmB,GACnBN,KAAAO,MAAgB,UACAP,KAAAQ,WAAqB,EACrBR,KAAAS,SAAmB,EACnBT,KAAAU,SAAmB,EACnBV,KAASW,UAAoB,EAC7BX,KAAAY,YAAsB,EACtBZ,KAAAa,aAAuB,EACxBb,KAAAc,aAAuB,EACtBd,KAAAe,WAAqB,EACjEf,KAAQgB,aAAkD,GAU7BhB,KAAAiB,YAAsB,EACvBjB,KAAAkB,iBAAgD,SAChClB,KAASmB,UAAoB,EAC7BnB,KAAAoB,gBAA0B,EAC1CpB,KAAAqB,WAAqB,QACrBrB,KAAAsB,WAAqB,GACpBtB,KAAAuB,WAAqB,EACrBvB,KAAAwB,uBAAiC,EAClCxB,KAASyB,OAAiB,GAC1BzB,KAAA0B,OAAiB,GACjB1B,KAAA2B,YAAsB,GACtB3B,KAAA4B,YAAsB,GACtB5B,KAAA6B,QAA8B,aAC9B7B,KAAA8B,OAAiB,GACjB9B,KAAA+B,OAAiB,QACjB/B,KAASgC,gBAA0B,yBACnBhC,KAASiC,UAAoB,EAC5CjC,KAAAkC,wBAAkC,EAClClC,KAAAmC,WAAqB,EACNnC,KAAAoC,kBAA4B,EAC5BpC,KAAAqC,SAAU,EACXrC,KAAAsC,QAAkB,UAOftC,KAAAuC,YAAc,GACnDvC,KAAAwC,gBAAyB,GACzBxC,KAAAyC,SAAmB,EACnBzC,KAAA0C,MAAgB,EAChB1C,KAAA2C,cAAuB,GACvB3C,KAAA4C,iBAA2B,EAC3B5C,KAAA6C,aAAsB,EACtB7C,KAAA8C,iBAA6B,GAC7B9C,KAAA+C,iBAA0B,GAC1B/C,KAAQgD,aAAc,EACtBhD,KAAQiD,cAAe,EACvBjD,KAAQkD,kBAAoBC,IAgBrCnD,KAAQoD,kBAA0D,KAIlEpD,KAAQqD,gBAAkB,IAAIC,EAAkBtD,KAAM,CACpDuD,UAAW,IAAMvD,KAAKwD,eACtBC,WAAY,IAAMzD,KAAK0D,WACvBC,WAAY,gBACZC,UAAW,eACXC,YAAa,iBACbC,aAAc,IAAM,SACpBC,SAAU,IAAM,QAChBC,OAAQ,IAAM,EACdC,WAAY,IAAM,EAClBC,oBAAqB,KAAM,EAC3BC,sBAAuB,KAAM,EAC7BC,gBAAiB,IAAM,MACvBC,QAAS,KAAM,EACfC,aAAc,IAAM,GACpBC,qBAAsB,KAAM,EAC5BC,gBAAiB,IAAM,IACvBC,iBAAkB,KAAM,EACxBC,kBAAmB,KAAM,EACzBC,uBAAwB,KAAM,EAC9BC,aAAc,CAAClC,EAAMmC,KACnB7E,KAAK0C,KAAOA,EAERA,GACF1C,KAAKoC,kBAAmB,EACxBpC,KAAK8E,gBACLC,sBAAsB,IAAM/E,KAAKgF,iBAEjChF,KAAK6C,aAAc,EACnB7C,KAAKuC,YAAc,GACnBvC,KAAKiF,yBACLjF,KAAK8E,gBAGL9E,KAAK4C,iBAAkB,EACvB5C,KAAKkF,cAAcC,aAAa,WAKtCnF,KAAQkF,cAAgB,IAAI5B,EAAkBtD,KAAM,CAClDuD,UAAW,IAAMvD,KAAKoF,eACtB3B,WAAY,IAAMzD,KAAKqF,iBACvB1B,WAAY,gBACZC,UAAW,eACXC,YAAa,iBACbC,aAAc,IAAM,SACpBC,SAAU,IAAM,SAChBC,OAAQ,IAAM,EACdC,WAAY,IAAM,EAClBC,oBAAqB,KAAM,EAC3BC,sBAAuB,KAAM,EAC7BC,gBAAiB,IAAM,MACvBC,QAAS,KAAM,EACfC,aAAc,IAAM,GACpBC,qBAAsB,KAAM,EAC5BC,gBAAiB,IAAM,IACvBC,iBAAkB,KAAM,EACxBC,kBAAmB,KAAM,EACzBC,uBAAwB,KAAM,EAC9BC,aAAelC,IACb1C,KAAK4C,gBAAkBF,EAGnBA,GAAQ1C,KAAK0C,MACf1C,KAAKqD,gBAAgB8B,aAAa,UA6vBxCnF,KAAQsF,mBAAqB,KAC3B,MAAMC,MAAUpC,IAChBnD,KAAKwF,iBAA8B,qBAAqBC,QAASC,IAC/D,MAAMC,EAAYD,EAAmBE,KACjCD,GAAUJ,EAAIM,IAAIF,KAExB3F,KAAKkD,cAAgBqC,GAg+BvBvF,KAAQ8F,gBAAmBC,IACzB,MAAMC,IAAEA,EAAAC,SAAKA,GAAaF,EAE1B,GAAY,UAARC,EAIF,OAHAD,EAAEG,iBACFH,EAAEI,uBACFnG,KAAKoG,sBAIP,GAAY,cAARJ,GAA+B,YAARA,GAA6B,QAARA,EAAe,CAC7DD,EAAEG,iBACFH,EAAEI,kBAEF,MAAME,EAAerG,KAAKY,YAAcZ,KAAKuB,UAQvC+E,EANJtG,KAAKa,aAAeb,KAAKe,UACrBsF,EACE,EACA,EACFrG,KAAKuG,WAGLC,EACJxG,KAAKuG,WAAaE,KAAKC,IAAI,EAAG1G,KAAKwC,gBAAgBmE,QAAU,EAEzDC,EAAc,YAARZ,GAA8B,QAARA,GAAiBD,EAAEE,UAAY,EAAK,EAClEjG,KAAK6C,YAAcyD,EAAUtG,KAAK6C,YAAcyD,EAElDtG,KAAK6C,YACH7C,KAAK6C,YAAc+D,EAAMN,EACrBE,EACAxG,KAAK6C,YAAc+D,EAAMJ,EACvBF,EACAtG,KAAK6C,YAAc+D,EAE7B5G,KAAK6G,0BACP,CAEA,MAAY,WAARb,GACFD,EAAEG,iBACFH,EAAEI,uBACFnG,KAAKqD,gBAAgB8B,aAAa,gBAHpC,GA0HFnF,KAAQ8G,mBAAsBf,IAE5B,GADAA,EAAEI,kBACEnG,KAAKW,UAAYX,KAAKiC,SAAU,OACpC,IAAKjC,KAAK+G,kBAAmB,OAE7B,MAAM9G,EAAQD,KAAKuC,YAAYyE,OAE/BhH,KAAKiH,cACH,IAAIC,YAAY,iBAAkB,CAChCC,OAAQ,CAAElH,SACVmH,SAAS,EACTC,UAAU,KAIdrH,KAAKuC,YAAc,GACnBvC,KAAKiF,yBACLjF,KAAK8E,iBA6RP9E,KAAQsH,iBAAmB,KACzBtH,KAAKgD,aAAehD,KAAKuH,aAAaZ,QAAU,GAAK,EACrD3G,KAAKiD,cAAgBjD,KAAKwH,cAAcb,QAAU,GAAK,GA/8CvD3G,KAAKyH,oBAAoB,GAC3B,CA93BA,WAAIC,GACF,OAAO1H,KAAKK,QACd,CACA,WAAIqH,CAAQzH,GACV,MAAM0H,EAAM3H,KAAKK,SACjBL,KAAKK,SAAWuH,MAAMC,QAAQ5H,GAASA,EAAQ,GAC/CD,KAAK8H,cAAc,UAAWH,EAChC,CAaA,eAAII,GACF,OAAO/H,KAAKgB,YACd,CACA,eAAI+G,CAAY9H,GACd,MAAM0H,EAAM3H,KAAKgB,aACjBhB,KAAKgB,aAAe4G,MAAMC,QAAQ5H,GAASA,EAAQ,GACnDD,KAAK8H,cAAc,cAAeH,EACpC,CA02BS,iBAAAK,GACPjI,MAAMiI,oBAGDhI,KAAKiI,aAAa,cACrBjI,KAAKkI,SAAWlI,KAAKW,UAAW,EAAK,GAEvCX,KAAKsF,oBAEP,CAES,YAAA6C,GACPnI,KAAKqD,gBAAgB+E,iBACrBpI,KAAKkF,cAAckD,gBACrB,CAYmB,YAAAC,GACjB,GAAIrI,KAAKW,WAAaX,KAAKsI,KAAM,OAAO,KAExC,GAAItI,KAAKa,YAAa,CAEpB,MAAM0H,EAAW,IAAIC,SAWrB,OAVAxI,KAAK2C,cAAc8C,QAASgD,IAC1B,MAAMxI,EAAQD,KAAKoB,eACfsH,KAAKC,UAAUF,GACfG,OAAO5I,KAAK6I,eAAeJ,IAC/BF,EAASO,OAAO9I,KAAKsI,KAAMrI,KAGK,IAA9BD,KAAK2C,cAAcgE,QAAgB3G,KAAKmB,UAC1CoH,EAASO,OAAO9I,KAAKsI,KAAM,IAEtBC,CACT,CAAO,CAEL,GAAkC,IAA9BvI,KAAK2C,cAAcgE,OAAc,MAAO,GAC5C,MAAM8B,EAAOzI,KAAK2C,cAAc,GAChC,OAAO3C,KAAKoB,eACRsH,KAAKC,UAAUF,GACfG,OAAO5I,KAAK6I,eAAeJ,GACjC,CACF,CAGmB,qBAAAM,CAAsBC,GACvC,GAAc,OAAVA,GAA4B,KAAVA,EAGpB,OAFAhJ,KAAKC,MAAQD,KAAKa,YAAc,GAAK,QACrCb,KAAK2C,cAAgB,IAIvB,GAAI3C,KAAKa,YAAa,CACpB,IAAIoI,EAAgB,GAEpB,GAAID,aAAiBR,SAEnBS,EAASD,EAAME,OAAOlJ,KAAKsI,WAC7B,GAAWV,MAAMC,QAAQmB,GACvBC,EAASD,OACX,GAA4B,iBAAVA,EAChB,IACE,MAAMG,EAAST,KAAKU,MAAMJ,GAExBC,EADErB,MAAMC,QAAQsB,GACPA,EAEA,CAACH,EAEd,CAAA,MACEC,EAAS,CAACD,EACZ,CAGFhJ,KAAKqJ,kBAAkBJ,EACzB,KAAO,CAEL,IAAIK,EAAc,GACG,iBAAVN,EACTM,EAAcN,EACLA,aAAiBR,SAC1Bc,EAAcN,EAAMO,IAAIvJ,KAAKsI,OAAOkB,YAAc,GACzC5B,MAAMC,QAAQmB,IAAUA,EAAMrC,OAAS,IAChD2C,EAAcN,EAAM,GAAGQ,YAGzBxJ,KAAKC,MAAQqJ,EACbtJ,KAAKyJ,4BACP,CACF,CACmB,aAAAC,GACjB,IAAK1J,KAAKsI,MAAQtI,KAAKW,SAErB,YADAX,KAAK2J,UAAUC,aAAa,MAI9B,MAAMC,EAAI7J,KAAKqI,eAEf,GAAU,OAANwB,EAKJ,GAAI7J,KAAKa,aAAe+G,MAAMC,QAAQgC,GAAI,CAGxC,MAAMtB,EAAW,IAAIC,SACrBqB,EAAEpE,QAASxF,IACLA,SAAmD,KAAVA,GAC3CsI,EAASO,OAAO9I,KAAKsI,KAAMM,OAAO3I,MAGtCD,KAAK2J,UAAUC,aAAarB,EAC9B,MAEEvI,KAAK2J,UAAUC,aAAaC,QAhB5B7J,KAAK2J,UAAUC,aAAa,KAkBhC,CACQ,iBAAAP,CAAkBJ,GAExB,MAAMa,EAAelC,MAAMC,QAAQ7H,KAAK0H,SAAW1H,KAAK0H,QAAU,GAGlE1H,KAAK2C,cAAgBmH,EAAaC,OAAQC,IACxC,MAAMC,EAAcjK,KAAK6I,eAAemB,GAClCE,EAAoBlK,KAAKoB,eAC3BsH,KAAKC,UAAUqB,GACfpB,OAAOqB,GAEX,OAAOhB,EAAOkB,KAAMlK,IAClB,MAAMqJ,EAAcV,OAAO3I,GAG3B,IAAID,KAAKoB,eAQP,OAAOkI,IAAgBY,EAPvB,IACE,MAAME,EAAc1B,KAAKU,MAAME,GAC/B,OAAOZ,KAAKC,UAAUyB,KAAiBF,CACzC,CAAA,MACE,OAAOZ,IAAgBY,CACzB,MAQNlK,KAAKC,MAAQD,KAAK2C,cAAc0H,IAAK5B,GACnCzI,KAAKoB,eAAiBqH,EAAOzI,KAAK6I,eAAeJ,GAErD,CAGmB,iBAAA6B,GACjB,OAAOtK,IACT,CAGmB,OAAAuK,GACjB,OAAIvK,KAAKa,YAC8B,IAA9Bb,KAAK2C,cAAcgE,OAEW,IAA9B3G,KAAK2C,cAAcgE,SAAiB3G,KAAKC,KAEpD,CAEmB,gBAAAuK,GAEjB,OAAOxK,KAAKwD,gBAAkB,IAChC,CAEmB,qBAAAiH,GACjB,OAAOzK,KAAK8C,mBAAmB,IAAM,EACvC,CAOmB,WAAA4H,GACjB3K,MAAM2K,cACN1K,KAAKuC,YAAc,GACnBvC,KAAKiF,yBACLjF,KAAK0C,MAAO,EACZ1C,KAAKqC,SAAU,EACfrC,KAAK8C,iBAAmB,GACxB9C,KAAKoC,kBAAmB,CAC1B,CAGmB,cAAAuI,CAAehK,GAChCX,KAAKW,SAAWA,CAClB,CAGmB,kBAAAiK,CAAmB5B,GACpChJ,KAAK+I,sBAAsBC,EAC7B,CAGQ,eAAA6B,GACN,GAAI7K,KAAKW,UAAYX,KAAKiC,SAAU,OACpC,MAAM6I,EAASC,GAAWnC,OAAO5I,KAAK6I,eAAekC,IAErD,GAAI/K,KAAKgL,wBAAyB,CAChC,MAAMC,EAAe,IAAI9H,IACvBnD,KAAKwC,gBAAgB6H,IAAKa,GACxBtC,OAAO5I,KAAK6I,eAAeqC,EAAIC,aAI7BC,EAAepL,KAAK2C,cAAcoH,OACrCtB,IAAUwC,EAAaI,IAAIP,EAAMrC,KAIpC,GAAIzI,KAAKkC,wBAAkD,IAAxBkJ,EAAazE,OAC9C,OAGF3G,KAAK2C,cAAgByI,CACvB,KAAO,CACL,MAAME,EAAe,IAAInI,IACvBnD,KAAK2C,cAAc0H,IAAK5B,GAASqC,EAAMrC,KAEnC8C,EAAYvL,KAAKwC,gBACpB6H,IAAKU,GAAMA,EAAEI,UACbpB,OAAQmB,IAASI,EAAaD,IAAIP,EAAMI,KAC3ClL,KAAK2C,cAAgB,IAAI3C,KAAK2C,iBAAkB4I,EAClD,CAEA,MAAMC,EAAcxL,KAAK2C,cAAc0H,IAAKa,GAC1ClL,KAAKoB,eAAiB8J,EAAMlL,KAAK6I,eAAeqC,IAElDlL,KAAKC,MAAQuL,EAEbxL,KAAKiH,cACH,IAAIC,YAA2C,gBAAiB,CAC9DC,OAAQ,CACNlH,MAAOuL,EACP7I,cAAe,IAAI3C,KAAK2C,eACxB8I,cAAeD,EACfE,sBAAuB1L,KAAKuC,YAAYyE,QAE1CI,SAAS,EACTC,UAAU,KAIdrH,KAAK0J,gBACL1J,KAAK2L,eACL3L,KAAK8H,eACP,CAEQ,qBAAAkD,GACN,GAAoC,IAAhChL,KAAKwC,gBAAgBmE,OAAc,OAAO,EAK9C,OAHuB3G,KAAKwC,gBAAgB6H,IAAKa,GAC/ClL,KAAK6I,eAAeqC,EAAIC,WAEJS,MAAO3L,GAC3BD,KAAK2C,cAAcwH,KAAM1B,GAASzI,KAAK6I,eAAeJ,KAAUxI,GAEpE,CAEQ,YAAA4L,CAAaC,EAAcC,GACjC,OAAID,EAAKnF,OAASoF,EACTD,EAAKE,MAAM,EAAGD,GAAa,MAE7BD,CACT,CAEQ,aAAAG,GACN,IAAKjM,KAAKoC,iBAAkB,OAE5BpC,KAAK8C,iBAAmB,GAExB,MAAMoJ,EAASlM,KAAKwB,sBAAwBxB,KAAK2C,cAAgB3C,KAAKC,MAGtE,GAAID,KAAKmB,UAAYnB,KAAKuK,UACxBvK,KAAK8C,iBAAiBqJ,KACpBnM,KAAKgC,iBAAmB,+BAI1B,GAAI4F,MAAMC,QAAQ7H,KAAK+H,cAAgB/H,KAAK+H,YAAYpB,OACtD,IAAA,MAAWkD,KAAK7J,KAAK+H,YAAa,CAChC,MAAMqE,EAAMvC,EAAEqC,IACF,IAARE,GACFpM,KAAK8C,iBAAiBqJ,KAAKvD,OAAOwD,GAAO,kBAC7C,CAIJpM,KAAKqC,QAAUrC,KAAK8C,iBAAiB6D,OAAS,EAE9C3G,KAAKiH,cACH,IAAIC,YACFlH,KAAKqC,QAAU,mBAAqB,qBACpC,CACE8E,OAAQnH,KAAKqC,QACT,CAAEgK,OAAQrM,KAAK8C,kBACf,CAAE7C,MAAOD,KAAK2C,eAClByE,SAAS,EACTC,UAAU,KAKhBrH,KAAK2L,eACL3L,KAAK8H,eACP,CAGmB,eAAAwE,GACjB,GAAItM,KAAKW,SAAU,MAAO,GAG1B,MAAMuL,EAASlM,KAAKwB,sBAAwBxB,KAAK2C,cAAgB3C,KAAKC,MAGtE,GAAI2H,MAAMC,QAAQ7H,KAAK+H,cAAgB/H,KAAK+H,YAAYpB,OACtD,IAAA,MAAWkD,KAAK7J,KAAK+H,YAAa,CAChC,MAAMqE,EAAMvC,EAAEqC,GACd,IAAY,IAARE,EAAc,OAAOxD,OAAOwD,GAAO,iBACzC,CAIF,OAAIpM,KAAKkC,wBAA0BlC,KAAKuK,UAC/BvK,KAAKgC,iBAAmB,sCAI7BhC,KAAKmB,UAAYnB,KAAKuK,UACjBvK,KAAKgC,iBAAmB,yBAG1B,EACT,CAES,KAAAuK,CAAM7E,GACb3H,MAAMwM,MAAM7E,GACR1H,KAAKwM,cACPxM,KAAKwM,cAAcD,MAAM7E,GAChB1H,KAAKwD,gBACdxD,KAAKwD,eAAe+I,MAAM7E,EAE9B,CAES,IAAA+E,GACHzM,KAAK0C,MACP1C,KAAKqD,gBAAgB8B,aAAa,iBAEpCpF,MAAM0M,MACR,CAEQ,WAAAC,GACN1M,KAAKyC,SAAU,EAEVzC,KAAKoC,mBACRpC,KAAKoC,kBAAmB,EAE5B,CAOO,KAAAuK,GACL3M,KAAKC,MAAQD,KAAKa,YAAc,GAAK,GACrCb,KAAK2C,cAAgB,GACrB3C,KAAKuC,YAAc,GACnBvC,KAAKiF,yBACLjF,KAAK8E,gBACL9E,KAAK8C,iBAAmB,GACxB9C,KAAKoC,kBAAmB,EACxBpC,KAAK0C,MAAO,EACZ1C,KAAKqC,SAAU,EACfrC,KAAK0J,gBACL1J,KAAK2L,eACL3L,KAAK8H,eACP,CAOO,YAAA8E,GACD5M,KAAKW,UAAYX,KAAKiC,UAC1BjC,KAAKqD,gBAAgBwJ,aACvB,CAOO,aAAAC,GACL9M,KAAKqD,gBAAgB8B,aAAa,MACpC,CAOO,cAAA4H,GACL/M,KAAKgN,aACP,CAEQ,UAAAC,GACNjN,KAAKyC,SAAU,EAEXzC,KAAKoC,kBACPpC,KAAKiM,eAET,CAES,OAAAiB,CAAQC,GACXA,EAAkB9B,IAAI,UACxBrL,KAAKoN,MAAMC,YAAY,uBAAwBC,EAAatN,KAAKO,QAE/D4M,EAAkB9B,IAAI,WACxBrL,KAAKoN,MAAMC,YAAY,sBAAuBrN,KAAK+B,OAEvD,CACS,UAAAwL,CAAWJ,GACdA,EAAkB9B,IAAI,WACxBrL,KAAKyJ,6BACLzJ,KAAK0J,gBACL1J,KAAK2L,gBAGHwB,EAAkB9B,IAAI,aAEnBzD,MAAMC,QAAQ7H,KAAK0H,WACtB1H,KAAK0H,QAAU,IAEjB1H,KAAKyJ,6BACLzJ,KAAK8E,gBACL9E,KAAK0J,gBACL1J,KAAK2L,gBAGHwB,EAAkB9B,IAAI,eAExBrL,KAAK8E,gBAGHqI,EAAkB9B,IAAI,gBACxBrL,KAAK8E,gBAGHqI,EAAkB9B,IAAI,qBACxBrL,KAAK8H,eAET,CAEQ,0BAAA2B,GAEN,MAAMK,EAAelC,MAAMC,QAAQ7H,KAAK0H,SAAW1H,KAAK0H,QAAU,GAG5D8F,EACJxN,KAAKa,aAAe+G,MAAMC,QAAQ7H,KAAKC,QAAgC,IAAtBD,KAAKC,MAAM0G,OAE9D,GAAkB,MAAd3G,KAAKC,OAAgC,KAAfD,KAAKC,OAAgBuN,EAG7C,OAFAxN,KAAK2C,cAAgB,QACrB3C,KAAKC,MAAQD,KAAKa,YAAc,GAAK,IAKvC,GAAIb,KAAKa,aAAqC,iBAAfb,KAAKC,MAClC,IACE,MAAMkJ,EAAST,KAAKU,MAAMpJ,KAAKC,OAC3B2H,MAAMC,QAAQsB,UAAclJ,MAAQkJ,EAC1C,OAASsE,GAET,CAGF,MAAMC,EAAyBjF,IAC7B,MAAMkF,EAAM3N,KAAK6I,eAAeJ,GAChC,MAAsB,iBAARkF,EAAmBjF,KAAKC,UAAUgF,GAAO/E,OAAO+E,IAGhE,GAAI3N,KAAKa,YAAa,CAEpB,MAAM+M,EAAMhG,MAAMC,QAAQ7H,KAAKC,OAASD,KAAKC,MAAQ,CAACD,KAAKC,OAGrD4N,EAAe,IAAI1K,IACvByK,EAAIvD,IAAKR,GACH7J,KAAKoB,gBAA+B,iBAANyI,EACzBnB,KAAKC,UAAUkB,GAEjBjB,OAAOiB,KAKlB7J,KAAK2C,cAAgBmH,EAAaC,OAAQmB,IACxC,MAAM4C,EAAW9N,KAAKoB,eAClBsH,KAAKC,UAAUuC,GACfwC,EAAsBxC,GAC1B,OAAO2C,EAAaxC,IAAIyC,KAI1B9N,KAAKC,MAAQD,KAAK2C,cAAc0H,IAAKa,GACnClL,KAAKoB,eAAiB8J,EAAMlL,KAAK6I,eAAeqC,GAEpD,KAAO,CACL,MAAM6C,EACJ/N,KAAKoB,gBAAwC,iBAAfpB,KAAKC,MAC/ByI,KAAKC,UAAU3I,KAAKC,OACpB2I,OAAO5I,KAAKC,OAEZ+N,EAAiBlE,EAAamE,KAAM/C,IACvBlL,KAAKoB,eAClBsH,KAAKC,UAAUuC,GACfwC,EAAsBxC,MACN6C,GAGtB/N,KAAK2C,cAAgBqL,EAAiB,CAACA,GAAkB,GACzDhO,KAAKC,MAAQ+N,EACThO,KAAKoB,eACH4M,EACAhO,KAAK6I,eAAemF,GACtB,EACN,CACF,CAEQ,aAAAlJ,GACN,MAAMgF,EAAelC,MAAMC,QAAQ7H,KAAK0H,SAAW1H,KAAK0H,QAAU,GAE5DwG,EAAU,CAAClE,EAAamE,KAC5B,MAAM/N,EAAQJ,KAAKoO,eAAepE,GAClC,MAAO,CACLmB,SAAUnB,EACVqE,KAAMF,EACN/N,QACAkO,YAAalO,IAIjB,IAAKJ,KAAKY,aAAeZ,KAAKuC,YAAYyE,OAExC,YADAhH,KAAKwC,gBAAkBsH,EAAaO,IAAI6D,IAI1C,MAAMK,EAAQvO,KAAKuC,YAAYiM,cAE/BxO,KAAKwC,gBAAkBsH,EACpBO,IAAI6D,GACJnE,OAAQ0E,GAAQ7F,OAAO6F,EAAIrO,OAAOoO,cAAcE,SAASH,IACzDlE,IAAKoE,IACJ,MAAME,EAAQ,IAAIC,OAAO,IAAIL,KAAU,MACvC,MAAO,IACFE,EACHH,YAAa1F,OAAO6F,EAAIrO,OAAOyO,QAC7BF,EACCG,GAAc,2BAA2BA,cAIpD,CAIQ,sBAAA7J,GACNjF,KAAKiH,cACH,IAAIC,YAAiD,uBAAwB,CAC3EC,OAAQ,CAAE5E,YAAavC,KAAKuC,aAC5B6E,SAAS,EACTC,UAAU,IAGhB,CAEQ,WAAA0H,CAAYC,GAClB,GAAIhP,KAAKW,UAAYX,KAAKiC,SAAU,OACpCjC,KAAKuC,YAAeyM,EAAM9C,OAA4BjM,MACtD,MAAMgP,EAAgBrH,MAAMC,QAAQ7H,KAAK0H,SAAW1H,KAAK0H,QAAQf,OAAS,EACpEuI,EACJlP,KAAKY,YACLqO,EAAgBrP,EAAYuP,mCAExBC,EAAc,KAClBpP,KAAK8E,gBACL9E,KAAKiF,0BAGHiK,GAC4B,MAA1BlP,KAAKoD,mBAA2BiM,aAAarP,KAAKoD,mBACtDpD,KAAKoD,kBAAoBkM,WAAW,KAClCtP,KAAKoD,kBAAoB,KACzBgM,KACCxP,EAAY2P,sBAEfH,GAEJ,CAES,oBAAAI,GACPzP,MAAMyP,uBACwB,MAA1BxP,KAAKoD,oBACPiM,aAAarP,KAAKoD,mBAClBpD,KAAKoD,kBAAoB,KAE7B,CAEQ,WAAA4J,GACN,GAAIhN,KAAKW,UAAYX,KAAKiC,SAAU,OAEpC,MAAMwN,EAAezP,KAAKa,YACtBb,KAAK2C,cAAcgE,OAAS,IAC1B3G,KAAKC,MAEPD,KAAKkC,wBAA0BuN,IAGnCzP,KAAKC,MAAQD,KAAKa,YAAc,GAAK,GACrCb,KAAK2C,cAAgB,GACrB3C,KAAKuC,YAAc,GACnBvC,KAAKiF,yBACLjF,KAAK0C,MAAO,EAEZ1C,KAAKiH,cACH,IAAIC,YAA2C,gBAAiB,CAC9DC,OAAQ,CACNlH,MAAOD,KAAKC,MACZ0C,cAAe,GACf+I,qBAAqB,GAEvBtE,SAAS,EACTC,UAAU,KAIdrH,KAAK0J,gBACL1J,KAAK2L,eACP,CAEA,YAAA+D,CAAa1F,GACX,GAAIhK,KAAKW,UAAYX,KAAKiC,SAAU,OAGpC,MAAM0N,EAAmBlH,GAChBzI,KAAKoB,eAAiBqH,EAAOzI,KAAK6I,eAAeJ,GAGpDqC,EAASC,IACb,MAAM4C,EAAM3N,KAAK6I,eAAekC,GAChC,MAAsB,iBAAR4C,EAAmBjF,KAAKC,UAAUgF,GAAO/E,OAAO+E,IAG1DiC,EAA0C,KAA5B5P,KAAKuC,YAAYyE,OAErC,IAAKhH,KAAKa,YAAa,CACrB,MAAMgP,EACJ7P,KAAK2C,cAAcgE,QACnBmE,EAAM9K,KAAK2C,cAAc,MAAQmI,EAAMd,GAEzC,OAAI6F,GAAmB7P,KAAKkC,4BAC1BlC,KAAK0C,MAAO,IAIVmN,GACF7P,KAAK2C,cAAgB,GACrB3C,KAAKC,MAAQ,KAEbD,KAAK2C,cAAgB,CAACqH,GACtBhK,KAAKC,MAAQ0P,EAAgB3F,IAG/BhK,KAAKiM,gBAELjM,KAAKiH,cACH,IAAIC,YAAY,gBAAiB,CAC/BC,OAAQ,CACNlH,MAAOD,KAAKC,MACZ0C,cAAe3C,KAAK2C,cACpB8I,cAAezL,KAAK2C,cAAc0H,IAAIsF,GACtCjE,oBAAqBkE,GAEvBxI,SAAS,EACTC,UAAU,KAIdrH,KAAKuC,YAAc,GACnBvC,KAAKiF,yBACLjF,KAAKqD,gBAAgB8B,aAAa,OAClCnF,KAAK0J,gBACL1J,KAAK2L,oBACL3L,KAAK8H,gBAEP,CAGA,MAAMgI,EAAQ9P,KAAK2C,cAAcoN,UAC9BtH,GAASqC,EAAMrC,KAAUqC,EAAMd,IAGlC,IAAIoB,EAGFA,EADE0E,GAAQ,EACK,IACV9P,KAAK2C,cAAcqJ,MAAM,EAAG8D,MAC5B9P,KAAK2C,cAAcqJ,MAAM8D,EAAQ,IAGvB,IAAI9P,KAAK2C,cAAeqH,GAGrChK,KAAKkC,wBAAkD,IAAxBkJ,EAAazE,SAIhD3G,KAAK2C,cAAgByI,EACrBpL,KAAKC,MAAQmL,EAAaf,IAAIsF,GAE9B3P,KAAKiM,gBAELjM,KAAKiH,cACH,IAAIC,YAAY,gBAAiB,CAC/BC,OAAQ,CACNlH,MAAOD,KAAKC,MACZ0C,cAAe3C,KAAK2C,cACpB8I,cAAezL,KAAKC,MACpByL,oBAAqBkE,GAEvBxI,SAAS,EACTC,UAAU,KAIdrH,KAAK0J,gBACL1J,KAAK2L,eACL3L,KAAK0C,MAAO,EACZ1C,KAAK8H,gBACP,CAEA,iBAAAkI,CAAkBjK,GAChBA,EAAEI,kBACFJ,EAAEG,iBACElG,KAAKW,UAAYX,KAAKiC,WAGtBjC,KAAK0C,MACP1C,KAAKqD,gBAAgB8B,aAAa,OAGpCnF,KAAKkF,cAAc+K,SACrB,CAGA,yBAAAC,GACE,OAAOC,CAAA;;;;;WAKAnQ,KAAKkF,cAAckL;eACdrK,GAAkBA,EAAEI;;;;;mBAKjBnG,KAAK8B;;;QAGhBuO,EACFrQ,KAAK2C,cAAcqJ,MAAMhM,KAAKc,cAC7B2H,GAASG,OAAO5I,KAAK6I,eAAeJ,IACpCA,GAAS0H,CAAA;;;gBAGAnQ,KAAK6L,aAAajD,OAAO5I,KAAKoO,eAAe3F,IAAQzI,KAAKM;;;;;;uBAMlDyF,IACdA,EAAEI,kBACFnG,KAAKsQ,WAAW7H;;;;;GAQxB,CAEA,UAAA6H,CAAWtG,GACT,GAAIhK,KAAKW,UAAYX,KAAKiC,SAAU,OACpC,MAAM6I,EAASC,GAAWnC,OAAO5I,KAAK6I,eAAekC,IAE/CwF,EAAOvQ,KAAK2C,cAAcoH,OAC7BtB,GAASqC,EAAMrC,KAAUqC,EAAMd,IAIlC,IAAIhK,KAAKkC,wBAA0C,IAAhBqO,EAAK5J,OAAxC,CASA,GALA3G,KAAK2C,cAAgB4N,EACjBvQ,KAAK2C,cAAcgE,QAAU3G,KAAKc,cACpCd,KAAKkF,cAAcC,aAAa,OAG9BnF,KAAKa,YAAa,CACpB,MAAM2K,EAAcxL,KAAK2C,cAAc0H,IAAKa,GAC1ClL,KAAKoB,eAAiB8J,EAAMlL,KAAK6I,eAAeqC,IAElDlL,KAAKC,MAAQuL,EAEbxL,KAAKiH,cACH,IAAIC,YAAY,gBAAiB,CAC/BC,OAAQ,CACNlH,MAAOuL,EACP7I,cAAe,IAAI3C,KAAK2C,eACxB8I,cAAeD,EACfE,qBAAqB,GAEvBtE,SAAS,EACTC,UAAU,IAGhB,MACErH,KAAKC,MAAQ,GACbD,KAAKiH,cACH,IAAIC,YAAY,gBAAiB,CAC/BC,OAAQ,CACNlH,MAAOD,KAAKC,MACZ0C,cAAe,GACf+I,qBAAqB,GAEvBtE,SAAS,EACTC,UAAU,KAKhBrH,KAAK0J,gBACL1J,KAAK2L,eACL3L,KAAKiM,gBACLjM,KAAK8H,eA3CL,CA4CF,CAEA,WAAA0I,GACE,IAAKxQ,KAAKa,aAAeb,KAAK2C,cAAcgE,OAC1C,OAAOwJ,CAAA;;;eAGEnQ,KAAKoO,eAAepO,KAAK2C,cAAc;;;QAMlD,MAAM8N,EAAU7I,MAAMC,QAAQ7H,KAAK2C,eAC/B3C,KAAK2C,cAAcqJ,MAAM,EAAGhM,KAAKc,cACjC,GACE4P,EAAW1Q,KAAK2C,cAAcgE,OAAS3G,KAAKc,aAClD,OAAOqP,CAAA;QACHE,EACFI,EACChI,GAASG,OAAO5I,KAAK6I,eAAeJ,IACpCA,GAAS0H,CAAA;wCACwBnQ,KAAKU;;iBAE5BV,KAAK6L,aAAajD,OAAO5I,KAAKoO,eAAe3F,IAAQzI,KAAKM;;cAE7DqQ,EACN3Q,KAAKa,YACL,IAAMsP,CAAA;;;;+BAIiBnQ,KAAKU;6BACNqF,IACpBA,EAAEI,kBACFnG,KAAKsQ,WAAW7H;;;;;;QASlBkI,EACFD,EAAW,EACX,IAAMP,CAAA;;;;;yBAKanQ,KAAKU;uBACPV,KAAKgQ;;kBAEVU;;;KAKhB,CAEA,aAAAE,CAAc5B,GACZ,GAAKA,EAAM9C,QAAwB2E,QAAQ,qBAAsB,OACjE,MAAM7K,IAAEA,EAAAC,SAAKA,GAAa+I,EAE1B,IAAKhP,KAAK0C,OAAiB,cAARsD,GAA+B,YAARA,GAA6B,UAARA,GAG7D,OAFAhG,KAAKqD,gBAAgBwJ,mBACrBmC,EAAM9I,iBAIR,IAAKlG,KAAK0C,KAAM,OAEhB,MAAM2D,EAAerG,KAAKY,YAAcZ,KAAKuB,UAQvC+E,EANJtG,KAAKa,aAAeb,KAAKe,UACrBsF,EACE,EACA,EACFrG,KAAKuG,WAGLC,EACJxG,KAAKuG,WAAaE,KAAKC,IAAI,EAAG1G,KAAKwC,gBAAgBmE,QAAU,EAI/D,GAFI3G,KAAK6C,YAAcyD,IAAUtG,KAAK6C,YAAcyD,GAExC,cAARN,EAAqB,CACvB,MAAM8K,EAAM9Q,KAAK6C,YAAcyD,EAAWA,EAAWtG,KAAK6C,YAI1D,OAHA7C,KAAK6C,YAAciO,GAAOtK,EAAWF,EAAWwK,EAAM,EACtD9Q,KAAK6G,gCACLmI,EAAM9I,gBAER,CAEA,GAAY,YAARF,EAAmB,CACrB,MAAM8K,EAAM9Q,KAAK6C,YAAcyD,EAAWA,EAAWtG,KAAK6C,YAI1D,OAHA7C,KAAK6C,YAAciO,GAAOxK,EAAWE,EAAWsK,EAAM,EACtD9Q,KAAK6G,gCACLmI,EAAM9I,gBAER,CAEA,GAAY,QAARF,EAAe,CACjB,GAAIC,EAAU,CACZ,MAAM6K,EAAM9Q,KAAK6C,YAAcyD,EAAWA,EAAWtG,KAAK6C,YAC1D7C,KAAK6C,YAAciO,GAAOxK,EAAWE,EAAWsK,EAAM,CACxD,KAAO,CACL,MAAMA,EAAM9Q,KAAK6C,YAAcyD,EAAWA,EAAWtG,KAAK6C,YAC1D7C,KAAK6C,YAAciO,GAAOtK,EAAWF,EAAWwK,EAAM,CACxD,CAGA,OAFA9Q,KAAK6G,gCACLmI,EAAM9I,gBAER,CAEA,MAAY,UAARF,GACFgJ,EAAM9I,iBACN8I,EAAM7I,uBACNnG,KAAKoG,uBAIHpG,KAAKiC,cACK,WAAR+D,IACFhG,KAAK0C,MAAO,EACZsM,EAAM9I,mBAKE,SAARF,GACFhG,KAAK6C,YAAcyD,EACnBtG,KAAK6G,gCACLmI,EAAM9I,kBAII,QAARF,GACFhG,KAAK6C,YAAc4D,KAAKC,IAAIJ,EAAUE,GACtCxG,KAAK6G,gCACLmI,EAAM9I,uBAHR,CAMF,CAkDA,cAAYK,GACV,IAAIwK,EAAI,EAGR,OAFI/Q,KAAKY,YAAcZ,KAAKuB,aAAWwP,GAAK,GACxC/Q,KAAKa,aAAeb,KAAKe,YAAWgQ,GAAK,GACtCA,CACT,CAGQ,sBAAAC,GAIN,IAAKhR,KAAK0C,KAAM,OAAO,KACvB,MAAMyL,EAAMnO,KAAK6C,YACjB,GAAIsL,EAAM,EAAG,OAAO,KAEpB,IAAInO,KAAKY,YAAcZ,KAAKuB,YACd,IAAR4M,EAAW,MAAO,CAAE8C,KAAM,UAGhC,MAAMC,EAAgBlR,KAAKY,YAAcZ,KAAKuB,UAAY,EAAI,EAC9D,GAAIvB,KAAKa,aAAeb,KAAKe,WAAaoN,IAAQ+C,EAChD,MAAO,CAAED,KAAM,cAGjB,MAAME,EAAchD,EAAMnO,KAAKuG,WAC/B,OAAI4K,GAAe,GAAKA,EAAcnR,KAAKwC,gBAAgBmE,OAClD,CAAEsK,KAAM,SAAUE,eAEpB,IACT,CAOQ,mBAAA/K,GACN,MAAM8F,EAASlM,KAAKgR,yBACpB,GAAK9E,EAEL,GAAoB,WAAhBA,EAAO+E,KAmBX,GAAoB,eAAhB/E,EAAO+E,MAIX,GAAoB,WAAhB/E,EAAO+E,MAAmD,iBAAvB/E,EAAOiF,YAA0B,CACtE,MAAMnD,EACJhO,KAAKwC,gBAAgB0J,EAAOiF,aAAahG,SAC3CnL,KAAK0P,aAAa1B,GAClBhO,KAAKuC,YAAc,GACnBvC,KAAKiF,wBACP,OATEjF,KAAK6K,uBAnBD7K,KAAKuB,WAAavB,KAAK+G,mBACzB/G,KAAKiH,cACH,IAAIC,YAAY,iBAAkB,CAChCC,OAAQ,CAAElH,MAAOD,KAAKuC,YAAYyE,QAClCI,SAAS,EACTC,UAAU,KAGdrH,KAAKuC,YAAc,GACnBvC,KAAKiF,yBACLjF,KAAK8E,iBACI9E,KAAKwC,gBAAgBmE,OAAS,IACvC3G,KAAK0P,aAAa1P,KAAKwC,gBAAgB,GAAG2I,UAC1CnL,KAAKuC,YAAc,GACnBvC,KAAKiF,yBAeX,CAGQ,WAAAD,GACN,MAAMoM,EAASpR,KAAKwM,cACpB,GAAI4E,EAOF,OANIC,SAASC,gBAAkBF,GAC7BrM,sBAAsB,IAAMqM,EAAO7E,SAGrCvM,KAAK6C,YAAc,OACnB7C,KAAK6G,2BAIP,IAAI0K,EAAY,EAChB,GAAIvR,KAAK2C,cAAcgE,OAAS,EAAG,CACjC,MAAM6K,EAAcxR,KAAK6I,eAAe7I,KAAK2C,cAAc,IACrD8O,EAAgBzR,KAAKwC,gBAAgBuN,UACxChF,GAAM/K,KAAK6I,eAAekC,EAAEI,YAAcqG,GAEzCC,GAAiB,IAAGF,EAAYE,EACtC,CACAzR,KAAK6C,YAAc7C,KAAKuG,WAAagL,EACrCvR,KAAK6G,0BACP,CAEQ,eAAAE,GACN,IAAK/G,KAAKuB,UAAW,OAAO,EAC5B,MAAMmQ,EAAI1R,KAAKuC,YAAYyE,OAC3B,IAAK0K,EAAG,OAAO,EAUf,QAPqB9J,MAAMC,QAAQ7H,KAAK0H,SAAW1H,KAAK0H,QAAU,IAEzCyC,KAAMe,IAC7B,MAAM9K,EAAQwI,OAAO5I,KAAKoO,eAAelD,IAAQ,IAAIsD,cAC/Cb,GAAO3N,KAAK6I,eAAeqC,IAAQ,IAAI1B,WAAWgF,cACxD,OAAOpO,IAAUsR,EAAElD,eAAiBb,IAAQ+D,EAAElD,eAGlD,CAqBA,wBAAA3H,GACE,MACM8K,EADO/J,MAAMgK,KAAK5R,KAAK6R,QACT5D,KACjB6D,GAAMC,OAAOD,EAAEE,QAAQC,YAAcjS,KAAK6C,aAE7C8O,GAAQO,eAAe,CAAEC,MAAO,UAAWC,SAAU,UACvD,CAEA,cAAAC,CAAerD,GACbA,EAAM7I,kBACFnG,KAAKW,UAAYX,KAAKiC,WAGtBjC,KAAK4C,iBACP5C,KAAKkF,cAAcC,aAAa,OAGlCnF,KAAKoC,kBAAmB,EACxBpC,KAAKqD,gBAAgB4M,SACvB,CAIA,cAAAqC,GACE,OAAOnC,CAAA;;;;;iBAKMnQ,KAAKqD,gBAAgB+M;eACtBrK,GAAkBA,EAAEI;;;;;;;QAO5BwK,EACF3Q,KAAKY,YAAcZ,KAAKuB,UACxB,IAAM4O,CAAA;;;;;;;;;yBASanQ,KAAKuC;;;4BAGFvC,KAAKiC,WACvBjC,KAAKY,aAAeZ,KAAKuB;yBACVvB,KAAKY,YAAcZ,KAAKuB,UACrCvB,KAAK+O,YACL;2BACe/O,KAAK8F;yBACP9F,KAAKY,YAAcZ,KAAKuB,UACrCvB,KAAK0M,YACL;wBACY1M,KAAKY,YAAcZ,KAAKuB,UACpCvB,KAAKiN,WACL;2BACejN,KAAKU;4BACJV,KAAKW;8BACHX,KAAKG;;;;gBAInBwQ,EACJ3Q,KAAKuB,UACL,IAAM4O,CAAA;;;;;;;+BAOanQ,KAAK8G;;;;;;;YASxB6J,EAAK3Q,KAAK0C,KAAM,IAAMyN,CAAA;YACtBQ,EACN3Q,KAAKa,aAAeb,KAAKe,WAAaf,KAAKwC,gBAAgBmE,OAC3D,KACE,MAAM4L,EAAoBvS,KAAKY,YAAcZ,KAAKuB,UAAY,EAAI,EAC5DiR,EAAmBC,EAAS,CAChC,iBAAiB,EACjBd,OAAQ3R,KAAK6C,cAAgB0P,EAC7BG,SAAU1S,KAAKgL,0BAEjB,OAAOmF,CAAA;;0BAEWqC;mCACSD;4CACSvS,KAAK6B;;2BAEtB7B,KAAK6K;;;+BAGD7K,KAAKgL;;;;;;YAQxB2F,EACN3Q,KAAKwC,gBAAgBmE,OAAS,EAC9B,IAAM0J,EACJrQ,KAAKwC,gBACL,EAAG2I,WAAUkD,UAAW,GAAGA,KAAQzF,OAAO5I,KAAK6I,eAAesC,MAC9D,EAAGA,WAAUmD,cAAaD,QAAQyB,KAChC,MAAMnK,EAAW,UAAU0I,IACrBsE,EAAU3S,KAAKkD,cAAcmI,IAAI1F,GAEjCmF,EAASC,GACbnC,OAAO5I,KAAK6I,eAAekC,EAAEI,UAAYJ,IACrC6H,EACJhL,MAAMC,QAAQ7H,KAAK2C,gBACnB3C,KAAK2C,cAAcwH,KAChB1B,GAASqC,EAAMrC,KAAUqC,EAAMK,IAE9B8G,EAAWjS,KAAKuG,WAAauJ,EAC7B+C,EAAWZ,IAAajS,KAAK6C,YAC7BiQ,EAAcL,EAAS,CAC3B,iBAAiB,EACjBd,OAAQkB,EACRH,SAAUE,IAGZ,OAAOzC,CAAA;;4BAEW2C;qCACSb;8CACSjS,KAAK6B;;6BAEtB,IAAM7B,KAAK0P,aAAavE;+BACtBnL,KAAKU;;sBAEdiQ,EACV3Q,KAAKa,YACL,IAAMsP,CAAA;qCACmByC;;;sBAIfjC,EACVgC,EACA,IAAMxC,CAAA;;yCAEuBxK;;;;mCAINoN,EAAWzE;;;;0BAKlC,IAAM6B,CAAA;;;mCAGiB4C,EAAWzE;;;oBAOxC,IAAM6B,CAAA;;;iCAGqBnQ,KAAKuG;;;;;;;GASpC,CAGA,cAAAsC,CAAemB,GACb,OAAIhK,KAAKoB,eACA4I,EAIa,iBAAXA,GAAkC,OAAXA,EAE5BhK,KAAKqB,cAAc2I,EACdA,EAAOhK,KAAKqB,YAGjB,UAAW2I,EACNA,EAAO/J,MAGT+J,EAIFA,CACT,CAEA,cAAAoE,CAAepE,GACb,IAAKA,EAAQ,MAAO,GAKpB,IAFqBpC,MAAMC,QAAQ7H,KAAK0H,UAAW1H,KAAK0H,QAGtD1H,KAAKsB,YACa,iBAAX0I,GACPA,EAAOhK,KAAKsB,YAEZ,OAAOsH,OAAOoB,EAAOhK,KAAKsB,aAG5B,GAAsB,iBAAX0I,EAAqB,CAC9B,MAAMgJ,EAAeC,OAAOhK,OAAOe,GAAQD,OACxC9J,GAA2B,iBAAVA,GAEpB,OAAO+S,EAAarM,OAAS,EAAIqM,EAAa,GAAMtK,KAAKC,UAAUqB,EACrE,CAEA,OAAOpB,OAAOoB,EAChB,CAEA,sBAAAkJ,GACE,IAAKlT,KAAKiB,aAAejB,KAAKoC,iBAAkB,OAAO,KAEvD,MAAM+Q,EAAOnT,KAAKoT,mBAElB,IAAKD,EAAKxM,OAAQ,OAAO,KAEzB,MAAM0M,EAAQ,GAAGrT,KAAKsT,IAAM,wBAE5B,OAAOnD,CAAA;;iBAEMkD;YACLhD,EAAO8C,EAAOrE,GAAMA,EAAIA,GAAMqB,CAAA,uCAA2CrB;;;KAInF,CAEA,gBAAAsE,GACE,MAAMG,EAAO3L,MAAMC,QAAQ7H,KAAK8C,kBAC5B9C,KAAK8C,iBACL,GACJ,OAAQ9C,KAAKkB,kBACX,IAAK,SACH,OAAOqS,EAAKvH,MAAM,EAAG,GACvB,IAAK,MACH,OAAOuH,EAET,QACE,MAAO,GAEb,CAEA,eAAAC,CAAgBC,EAA4BzE,GAC1ChP,KAAKiH,cACH,IAAIC,YAAY,aAAc,CAC5BC,OAAQ,CAAEsM,WAAUzE,SACpB5H,SAAS,EACTC,UAAU,IAGhB,CAOS,MAAAqM,GACP,MAAMC,EAAkBlB,EAAS,CAAE,aAAa,EAAMmB,MAAM,EAAMnR,QAASzC,KAAKyC,UAC1EoR,EAAmBpB,EAAS,CAAE,aAAa,EAAMqB,OAAO,EAAMrR,QAASzC,KAAKyC,UAC5EsR,EAAqBtB,EAAS,CAClC,qBAAqB,EACrBd,OAAQ3R,KAAK2C,cAAcgE,OAAS,IAEtC,OAAOwJ,CAAA;;UAEDQ,EAAK3Q,KAAKI,MAAO,IAAM+P,oCAAuCnQ,KAAKI;;;;;sBAKvDJ,KAAKW;qBACNX,KAAKU;qBACLV,KAAKS;kBACRT,KAAK0C;qBACF1C,KAAKqC;mBACN0D,IACP/F,KAAKW,UAAaX,KAAKiC,UAC1BjC,KAAKqS,eAAetM;qBAGT/F,KAAK4Q;;;;oBAIN+C;;sBAEE3T,KAAKgD;qBACL+C,GAAkB/F,KAAKwT,gBAAgB,OAAQzN;;iDAEpB/F,KAAKsH;;YAE1CqJ,EACJ3Q,KAAK2C,cAAcgE,OAAS,EAC5B,IAAMwJ,CAAA;;;;6BAIenQ,KAAKU;;oBAEdV,KAAKwQ;;gBAGjB,IAAML,CAAA;wBACU4D;;2BAEG/T,KAAKU;;qCAEKV,KAAK2B,gBAAgB3B,KAAKyB;mBAC5CzB,KAAKE,iCAAiCF,KAAK4B;qBACzC5B,KAAK0B;;;YAIdiP,EACJ3Q,KAAKQ,YACJR,KAAKkC,yBACLlC,KAAKC,OAASD,KAAK2C,cAAcgE,QAClC,IAAMwJ,CAAA;;;yBAGWnQ,KAAKgN;2BACHhN,KAAKS;;;YAIpBkQ,EACJ3Q,KAAKS,QACL,IAAM0P,CAAA,8CACN,IAAMA,CAAA;;wBAEU0D;0BACE7T,KAAKiD;yBACL8C,GAAkB/F,KAAKwT,gBAAgB,QAASzN;;sDAEpB/F,KAAKsH;;;;;qBAMrCvB,IACT/F,KAAKW,UAAaX,KAAKiC,UAC1BjC,KAAKqS,eAAetM;mBAGX/F,KAAK0C,KAAO,mBAAqB;;;;UAI1C1C,KAAKkQ,+BAA+BlQ,KAAKsS;UACzCtS,KAAKkT;iDACkClT,KAAKsF;;KAGpD,GAn8EW1F,EAEJoU,aAAyD,CAC9D,WAAYC,EACZ,eAAgBC,GAJPtU,EAsGa2P,oBAAsB,IAtGnC3P,EAuGauP,mCAAqC,GAvGlDvP,EA+KKuU,OAASC,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA/KdxU,EAk5BKyU,kBAAoB,IAC/BC,EAAWD,kBACdE,gBAAgB,GAx4BNC,EAAA,CAAXC,KAZU7U,EAYC8U,UAAA,QAAA,GACgBF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UAbPhJ,EAaiB8U,UAAA,cAAA,GACAF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UAdPhJ,EAciB8U,UAAA,oBAAA,GACAF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UAfPhJ,EAeiB8U,UAAA,QAAA,GAGxBF,EAAA,CADHC,EAAS,CAAEE,KAAM/M,SAjBPhI,EAkBP8U,UAAA,UAAA,GAQwBF,EAAA,CAA3BC,EAAS,CAAEE,KAAM5C,UA1BPnS,EA0BiB8U,UAAA,WAAA,GACAF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UA3BPhJ,EA2BiB8U,UAAA,QAAA,GACgBF,EAAA,CAA3CC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KA5BzBjV,EA4BiC8U,UAAA,YAAA,GACAF,EAAA,CAA3CC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KA7BzBjV,EA6BiC8U,UAAA,UAAA,GACAF,EAAA,CAA3CC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KA9BzBjV,EA8BiC8U,UAAA,UAAA,GACSF,EAAA,CAApDC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KA/BzBjV,EA+B0C8U,UAAA,WAAA,GACTF,EAAA,CAA3CC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KAhCzBjV,EAgCiC8U,UAAA,aAAA,GACAF,EAAA,CAA3CC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KAjCzBjV,EAiCiC8U,UAAA,cAAA,GACDF,EAAA,CAA1CC,EAAS,CAAEE,KAAM5C,OAAQ8C,SAAS,KAlCxBjV,EAkCgC8U,UAAA,eAAA,GACCF,EAAA,CAA3CC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KAnCzBjV,EAmCiC8U,UAAA,YAAA,GAGxCF,EAAA,CADHC,EAAS,CAAEE,KAAM/M,SArCPhI,EAsCP8U,UAAA,cAAA,GAQyBF,EAAA,CAA5BC,EAAS,CAAEE,KAAMC,WA9CPhV,EA8CkB8U,UAAA,aAAA,GACDF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UA/CPhJ,EA+CiB8U,UAAA,mBAAA,GACyBF,EAAA,CAApDC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KAhDzBjV,EAgD0C8U,UAAA,WAAA,GACTF,EAAA,CAA3CC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KAjDzBjV,EAiDiC8U,UAAA,iBAAA,GAChBF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UAlDPhJ,EAkDiB8U,UAAA,aAAA,GACAF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UAnDPhJ,EAmDiB8U,UAAA,aAAA,GACCF,EAAA,CAA5BC,EAAS,CAAEE,KAAMC,WApDPhV,EAoDkB8U,UAAA,YAAA,GACAF,EAAA,CAA5BC,EAAS,CAAEE,KAAMC,WArDPhV,EAqDkB8U,UAAA,wBAAA,GACQF,EAAA,CAApCC,EAAS,CAAEE,KAAM/L,UAtDPhJ,EAsD0B8U,UAAA,SAAA,GACTF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UAvDPhJ,EAuDiB8U,UAAA,SAAA,GACAF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UAxDPhJ,EAwDiB8U,UAAA,cAAA,GACAF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UAzDPhJ,EAyDiB8U,UAAA,cAAA,GACAF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UA1DPhJ,EA0DiB8U,UAAA,UAAA,GACAF,EAAA,CAA3BC,EAAS,CAAEE,KAAM5C,UA3DPnS,EA2DiB8U,UAAA,SAAA,GACAF,EAAA,CAA3BC,EAAS,CAAEE,KAAM/L,UA5DPhJ,EA4DiB8U,UAAA,SAAA,GACSF,EAAA,CAApCC,EAAS,CAAEE,KAAM/L,UA7DPhJ,EA6D0B8U,UAAA,kBAAA,GACgBF,EAAA,CAApDC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KA9DzBjV,EA8D0C8U,UAAA,WAAA,GACxBF,EAAA,CAA5BC,EAAS,CAAEE,KAAMC,WA/DPhV,EA+DkB8U,UAAA,yBAAA,GACAF,EAAA,CAA5BC,EAAS,CAAEE,KAAMC,WAhEPhV,EAgEkB8U,UAAA,YAAA,GACeF,EAAA,CAA3CC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KAjEzBjV,EAiEiC8U,UAAA,mBAAA,GACAF,EAAA,CAA3CC,EAAS,CAAEE,KAAMC,QAASC,SAAS,KAlEzBjV,EAkEiC8U,UAAA,UAAA,GACDF,EAAA,CAA1CC,EAAS,CAAEE,KAAM/L,OAAQiM,SAAS,KAnExBjV,EAmEgC8U,UAAA,UAAA,GAOGF,EAAA,CAA7CC,EAAS,CAAEE,KAAM/L,OAAQkM,WAAW,KA1E1BlV,EA0EmC8U,UAAA,cAAA,GACrCF,EAAA,CAARxL,KA3EUpJ,EA2EF8U,UAAA,kBAAA,GACAF,EAAA,CAARxL,KA5EUpJ,EA4EF8U,UAAA,UAAA,GACAF,EAAA,CAARxL,KA7EUpJ,EA6EF8U,UAAA,OAAA,GACAF,EAAA,CAARxL,KA9EUpJ,EA8EF8U,UAAA,gBAAA,GACAF,EAAA,CAARxL,KA/EUpJ,EA+EF8U,UAAA,kBAAA,GACAF,EAAA,CAARxL,KAhFUpJ,EAgFF8U,UAAA,cAAA,GACAF,EAAA,CAARxL,KAjFUpJ,EAiFF8U,UAAA,mBAAA,GACAF,EAAA,CAARxL,KAlFUpJ,EAkFF8U,UAAA,mBAAA,GACQF,EAAA,CAAhBxL,KAnFUpJ,EAmFM8U,UAAA,cAAA,GACAF,EAAA,CAAhBxL,KApFUpJ,EAoFM8U,UAAA,eAAA,GACAF,EAAA,CAAhBxL,KArFUpJ,EAqFM8U,UAAA,gBAAA,GAMgBF,EAAA,CAAhCjG,EAAM,mBA3FI3O,EA2FsB8U,UAAA,iBAAA,GACLF,EAAA,CAA3BjG,EAAM,cA5FI3O,EA4FiB8U,UAAA,aAAA,GACaF,EAAA,CAAxCjG,EAAM,2BA7FI3O,EA6F8B8U,UAAA,mBAAA,GACEF,EAAA,CAA1CjG,EAAM,6BA9FI3O,EA8FgC8U,UAAA,gBAAA,GACVF,EAAA,CAAhCjG,EAAM,mBA/FI3O,EA+FsB8U,UAAA,iBAAA,GACMF,EAAA,CAAtCjG,EAAM,yBAhGI3O,EAgG4B8U,UAAA,mBAAA,GACDF,EAAA,CAArCO,EAAS,qBAjGCnV,EAiG2B8U,UAAA,SAAA,GACgBF,EAAA,CAArDQ,EAAsB,CAAEpP,KAAM,eAlGpBhG,EAkG2C8U,UAAA,cAAA,GACCF,EAAA,CAAtDQ,EAAsB,CAAEpP,KAAM,gBAnGpBhG,EAmG4C8U,UAAA,eAAA,GAnG5C9U,EAAN4U,EAAA,CADNS,EAAc,iBACFrV"}
|