{
  "schemaVersion": "1.0.0",
  "readme": "",
  "modules": [
    {
      "kind": "javascript-module",
      "path": "src/converters.ts",
      "declarations": [
        {
          "kind": "function",
          "name": "toInitialValues",
          "return": {
            "type": {
              "text": "Converter<Array<string | number>>"
            }
          },
          "description": "`initial-values` — accepted as JSON (`[\"a\",\"b\"]` / `[1,2]`) or a bare CSV\nfallback (`a,b,c`). Absent/blank → empty array. Also travels the property\npath (assign an array directly), validated as an array of strings/numbers."
        }
      ],
      "exports": [
        {
          "kind": "js",
          "name": "toInitialValues",
          "declaration": {
            "name": "toInitialValues",
            "module": "src/converters.ts"
          }
        }
      ]
    },
    {
      "kind": "javascript-module",
      "path": "src/logger.ts",
      "declarations": [
        {
          "kind": "variable",
          "name": "logging",
          "description": "The single core logger bundle for this component. Exported so the element\nregistration (`index.ts` → `registerComponent`) can expose its controls on\n`window.components['web-multiselect'].logging` and `BlissElement` can build the\nper-instance `this.log` loggers from it."
        },
        {
          "kind": "variable",
          "name": "initLogger",
          "type": {
            "text": "Logger"
          }
        },
        {
          "kind": "variable",
          "name": "dataLogger",
          "type": {
            "text": "Logger"
          }
        },
        {
          "kind": "variable",
          "name": "uiLogger",
          "type": {
            "text": "Logger"
          }
        },
        {
          "kind": "variable",
          "name": "interactionLogger",
          "type": {
            "text": "Logger"
          }
        },
        {
          "kind": "variable",
          "name": "LOGGING_CATEGORIES",
          "description": "Full (namespaced) category names, kept for the `getCategories()` global API\nand any consumer that introspected the list."
        },
        {
          "kind": "function",
          "name": "enableLogging",
          "return": {
            "type": {
              "text": "void"
            }
          },
          "description": "Enable all logging (debug level)."
        },
        {
          "kind": "function",
          "name": "disableLogging",
          "return": {
            "type": {
              "text": "void"
            }
          },
          "description": "Disable all logging (silent)."
        },
        {
          "kind": "function",
          "name": "setLogLevel",
          "return": {
            "type": {
              "text": "void"
            }
          },
          "parameters": [
            {
              "name": "level",
              "type": {
                "text": "LogLevelDesc"
              }
            }
          ],
          "description": "Set the same level on every category."
        },
        {
          "kind": "function",
          "name": "setCategoryLevel",
          "return": {
            "type": {
              "text": "void"
            }
          },
          "parameters": [
            {
              "name": "category",
              "type": {
                "text": "string"
              }
            },
            {
              "name": "level",
              "type": {
                "text": "LogLevelDesc"
              }
            }
          ],
          "description": "Set the level of one category. Accepts the full prefixed name\n(`MULTISELECT:UI`) or the bare suffix (`UI`) — both normalize to the category\nkey the core bundle expects."
        }
      ],
      "exports": [
        {
          "kind": "js",
          "name": "logging",
          "declaration": {
            "name": "logging",
            "module": "src/logger.ts"
          }
        },
        {
          "kind": "js",
          "name": "initLogger",
          "declaration": {
            "name": "initLogger",
            "module": "src/logger.ts"
          }
        },
        {
          "kind": "js",
          "name": "dataLogger",
          "declaration": {
            "name": "dataLogger",
            "module": "src/logger.ts"
          }
        },
        {
          "kind": "js",
          "name": "uiLogger",
          "declaration": {
            "name": "uiLogger",
            "module": "src/logger.ts"
          }
        },
        {
          "kind": "js",
          "name": "interactionLogger",
          "declaration": {
            "name": "interactionLogger",
            "module": "src/logger.ts"
          }
        },
        {
          "kind": "js",
          "name": "LOGGING_CATEGORIES",
          "declaration": {
            "name": "LOGGING_CATEGORIES",
            "module": "src/logger.ts"
          }
        },
        {
          "kind": "js",
          "name": "enableLogging",
          "declaration": {
            "name": "enableLogging",
            "module": "src/logger.ts"
          }
        },
        {
          "kind": "js",
          "name": "disableLogging",
          "declaration": {
            "name": "disableLogging",
            "module": "src/logger.ts"
          }
        },
        {
          "kind": "js",
          "name": "setLogLevel",
          "declaration": {
            "name": "setLogLevel",
            "module": "src/logger.ts"
          }
        },
        {
          "kind": "js",
          "name": "setCategoryLevel",
          "declaration": {
            "name": "setCategoryLevel",
            "module": "src/logger.ts"
          }
        }
      ]
    },
    {
      "kind": "javascript-module",
      "path": "src/multiselect.ts",
      "declarations": [
        {
          "kind": "class",
          "description": "",
          "name": "WebMultiSelect",
          "members": [
            {
              "kind": "field",
              "name": "element",
              "type": {
                "text": "HTMLElement"
              },
              "privacy": "private",
              "default": "element"
            },
            {
              "kind": "field",
              "name": "instanceId",
              "type": {
                "text": "string"
              },
              "privacy": "private",
              "default": "`MS-${Math.random().toString(36).slice(2, 11)}`"
            },
            {
              "kind": "field",
              "name": "options",
              "type": {
                "text": "MultiSelectConfig<T>"
              },
              "privacy": "private",
              "default": "{ // String options searchHint: element.dataset.searchHint || '', searchPlaceholder: element.dataset.searchPlaceholder || undefined, selectPlaceholder: element.dataset.selectPlaceholder || 'Pick an option...', noDataPlaceholder: element.dataset.noDataPlaceholder || undefined, dropdownMinWidth: element.dataset.dropdownMinWidth || undefined, dropdownMaxWidth: element.dataset.dropdownMaxWidth || undefined, badgesDisplayMode: (element.dataset.badgesDisplayMode as any) || 'badges', badgesPosition: (element.dataset.badgesPosition as BadgesPosition) || 'bottom', badgesThresholdMode: (element.dataset.badgesThresholdMode as any) || 'count', maxHeight: element.dataset.maxHeight || '20rem', emptyMessage: element.dataset.emptyMessage || 'No results found', addNewText: element.dataset.addNewText || undefined, addNewPendingText: element.dataset.addNewPendingText || undefined, loadingMessage: element.dataset.loadingMessage || 'Loading...', searchInputMode: (element.dataset.searchInputMode as SearchInputMode) || 'normal', searchMode: (element.dataset.searchMode as SearchMode) || 'filter', // Number options badgesThreshold: element.dataset.badgesThreshold ? parseInt(element.dataset.badgesThreshold) : undefined, minSearchLength: parseInt(element.dataset.minSearchLength || '0') || 0, searchDebounce: parseInt(element.dataset.searchDebounce || '0') || 0, // Boolean options (internal names with 'is' prefix) isMultipleEnabled: element.dataset.multiple !== 'false', isGroupsAllowed: element.dataset.allowGroups !== 'false', isCheckboxesShown: element.dataset.showCheckboxes !== 'false', isActionsSticky: element.dataset.stickyActions !== 'false', isCloseOnSelect: element.dataset.closeOnSelect === 'true', isPlacementLocked: element.dataset.lockPlacement !== 'false', isSearchEnabled: element.dataset.enableSearch !== 'false', isAddNewAllowed: element.dataset.allowAddNew === 'true', isCounterShown: element.dataset.showCounter === 'true', isSelectedPopoverEnabled: element.dataset.enableSelectedPopover !== 'false', isSearchModeToggleShown: element.dataset.showSearchModeToggle === 'true', isKeepOptionsOnSearch: element.dataset.keepOptionsOnSearch !== 'false', shouldKeepSearchOnClose: element.dataset.keepSearchOnClose !== 'false', // Data and callbacks options: [], container: undefined, // Override with provided options ...options }"
            },
            {
              "kind": "field",
              "name": "#isOpen",
              "privacy": "private",
              "type": {
                "text": "boolean"
              },
              "default": "false"
            },
            {
              "kind": "field",
              "name": "selectedValues",
              "privacy": "private",
              "default": "new Set<string>()"
            },
            {
              "kind": "field",
              "name": "selectedOptions",
              "privacy": "private",
              "default": "new Map<string, T>()"
            },
            {
              "kind": "field",
              "name": "allOptions",
              "type": {
                "text": "T[]"
              },
              "privacy": "private",
              "default": "[]"
            },
            {
              "kind": "field",
              "name": "filteredOptions",
              "type": {
                "text": "T[]"
              },
              "privacy": "private",
              "default": "[]"
            },
            {
              "kind": "field",
              "name": "tree",
              "type": {
                "text": "LTree<T> | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "treeNodes",
              "type": {
                "text": "LTreeNode<T>[]"
              },
              "privacy": "private",
              "default": "[]"
            },
            {
              "kind": "field",
              "name": "cascadeIndex",
              "type": {
                "text": "CascadeIndex<T> | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "cascadeCheckedAtoms",
              "type": {
                "text": "Set<string>"
              },
              "privacy": "private",
              "default": "new Set()"
            },
            {
              "kind": "field",
              "name": "hiddenInputs",
              "type": {
                "text": "HTMLInputElement[]"
              },
              "privacy": "private",
              "default": "[]"
            },
            {
              "kind": "field",
              "name": "focusedIndex",
              "type": {
                "text": "number"
              },
              "privacy": "private",
              "default": "-1"
            },
            {
              "kind": "field",
              "name": "keyboardController",
              "type": {
                "text": "MultiSelectKeyboardController<T> | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "matchingIndices",
              "type": {
                "text": "Set<number>"
              },
              "privacy": "private",
              "default": "new Set()"
            },
            {
              "kind": "field",
              "name": "searchTerm",
              "type": {
                "text": "string"
              },
              "privacy": "private",
              "default": "''"
            },
            {
              "kind": "field",
              "name": "addNewFocused",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "default": "false",
              "description": "Keyboard focus sits on the empty-state \"add new\" prompt (arrow-navigated)."
            },
            {
              "kind": "field",
              "name": "addNewPending",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "default": "false",
              "description": "An async addNewCallback is in flight — the prompt shows a spinner + pending text."
            },
            {
              "kind": "field",
              "name": "isLoading",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "default": "false"
            },
            {
              "kind": "field",
              "name": "searchDebounceTimer",
              "type": {
                "text": "ReturnType<typeof setTimeout> | undefined"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "searchAbortController",
              "type": {
                "text": "AbortController | undefined"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "showSelectedPopover",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "default": "false"
            },
            {
              "kind": "field",
              "name": "selectedPopoverPlacement",
              "type": {
                "text": "Placement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "dropdownPlacement",
              "type": {
                "text": "Placement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "isRTL",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "default": "false"
            },
            {
              "kind": "field",
              "name": "effectiveBadgesPosition",
              "type": {
                "text": "BadgesPosition"
              },
              "privacy": "private",
              "default": "'bottom'"
            },
            {
              "kind": "field",
              "name": "justClosedViaClick",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "default": "false"
            },
            {
              "kind": "field",
              "name": "justOpenedViaClick",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "default": "false"
            },
            {
              "kind": "field",
              "name": "positioningDriftWarned",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "default": "false"
            },
            {
              "kind": "field",
              "name": "fullscreenContainingBlockWarned",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "default": "false"
            },
            {
              "kind": "field",
              "name": "presentationMode",
              "type": {
                "text": "'floating' | 'fullscreen'"
              },
              "privacy": "private",
              "default": "'floating'"
            },
            {
              "kind": "field",
              "name": "fullscreenHeader",
              "type": {
                "text": "HTMLDivElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "fullscreenSearchInput",
              "type": {
                "text": "HTMLInputElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "fullscreenSearchClear",
              "type": {
                "text": "HTMLButtonElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "fullscreenModeToggle",
              "type": {
                "text": "HTMLButtonElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "fullscreenNav",
              "type": {
                "text": "HTMLDivElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "fullscreenNavCount",
              "type": {
                "text": "HTMLElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "fullscreenNavPrev",
              "type": {
                "text": "HTMLButtonElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "fullscreenNavNext",
              "type": {
                "text": "HTMLButtonElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "bodyScrollUnlock",
              "type": {
                "text": "(() => void) | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "overflowXClamp",
              "type": {
                "text": "{ html: string } | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "keyboardInsetCleanup",
              "type": {
                "text": "(() => void) | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "overlayHistoryActive",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "default": "false"
            },
            {
              "kind": "field",
              "name": "onOverlayPopstate",
              "privacy": "private",
              "readonly": true
            },
            {
              "kind": "field",
              "name": "dropdownCleanup",
              "type": {
                "text": "(() => void) | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "hintCleanup",
              "type": {
                "text": "(() => void) | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "selectedPopoverCleanup",
              "type": {
                "text": "(() => void) | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "tooltips",
              "privacy": "private",
              "default": "new Map<string, TooltipHandle>()"
            },
            {
              "kind": "field",
              "name": "labelRevealTrigger",
              "type": {
                "text": "HTMLElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "labelRevealPanel",
              "type": {
                "text": "HTMLDivElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "labelRevealPopover",
              "type": {
                "text": "PopoverHandle | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "messageEl",
              "type": {
                "text": "HTMLDivElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "messageCleanup",
              "type": {
                "text": "(() => void) | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "messageTimer",
              "type": {
                "text": "ReturnType<typeof setTimeout> | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "onDropdownScroll",
              "privacy": "private",
              "readonly": true
            },
            {
              "kind": "field",
              "name": "virtualScroll",
              "type": {
                "text": "VirtualScroll<T> | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "optionsContainer",
              "type": {
                "text": "HTMLDivElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "selectedPopoverVirtualScroll",
              "type": {
                "text": "VirtualScroll<T> | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "selectedPopoverContainer",
              "type": {
                "text": "HTMLDivElement | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "input",
              "type": {
                "text": "HTMLInputElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "inputWrapper",
              "type": {
                "text": "HTMLDivElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "dropdown",
              "type": {
                "text": "HTMLDivElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "dropdownInner",
              "type": {
                "text": "HTMLDivElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "badgesContainer",
              "type": {
                "text": "HTMLDivElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "counter",
              "type": {
                "text": "HTMLSpanElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "clearButton",
              "type": {
                "text": "HTMLButtonElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "hint",
              "type": {
                "text": "HTMLDivElement | undefined"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "selectedPopover",
              "type": {
                "text": "HTMLDivElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "documentKeydownHandler",
              "type": {
                "text": "((e: KeyboardEvent) => void) | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "documentClickHandler",
              "type": {
                "text": "((e: MouseEvent) => void) | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "field",
              "name": "overlayCoord",
              "type": {
                "text": "OverlayHandle | null"
              },
              "privacy": "private",
              "default": "null"
            },
            {
              "kind": "method",
              "name": "extractField",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "R"
                }
              },
              "parameters": [
                {
                  "name": "item",
                  "type": {
                    "text": "T"
                  }
                },
                {
                  "name": "opts",
                  "type": {
                    "text": "{\n        member?: string;\n        callback?: (item: T) => R;\n        tupleIndex?: 0 | 1;\n        tupleSkip?: boolean;\n        transform?: (raw: any) => R;\n        fallback: R | (() => R);\n    }"
                  }
                }
              ],
              "description": "Generic field extractor with the precedence:\n  tuple short-circuit -> member property -> callback -> fallback\n\nTuple handling:\n  - `tupleIndex` (0 | 1): for `[key, value]` items, return that slot.\n  - `tupleSkip: true`: for any tuple, skip directly to fallback (used for icon/subtitle/group/disabled —\n    fields that don't make sense on a 2-element array).\n  - neither: tuples flow through the member/callback/fallback chain as if they were objects.\n\n`transform` is applied to tuple-slot and member-property reads (not to callback returns or the fallback),\nso e.g. you can pass `String` to coerce numeric members to strings while letting a typed callback return its\nown type unchanged."
            },
            {
              "kind": "method",
              "name": "getItemValue",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string | number"
                }
              },
              "parameters": [
                {
                  "name": "item",
                  "type": {
                    "text": "T"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "getItemDisplayValue",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "item",
                  "type": {
                    "text": "T"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "getItemBadgeDisplayValue",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "item",
                  "type": {
                    "text": "T"
                  }
                }
              ],
              "description": "Badge display falls back to the regular display value rather than '[N/A]', so consumers can override badge\ntext independently. Doesn't fit the extractField shape (no tuple/member layer of its own)."
            },
            {
              "kind": "method",
              "name": "getItemFullTitle",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string | undefined"
                }
              },
              "parameters": [
                {
                  "name": "item",
                  "type": {
                    "text": "T"
                  }
                }
              ],
              "description": "Full title — a fully-qualified label supplied with the data (never computed here). Used by\nbadges when `isBadgeFullTitleShown` is on. Returns undefined when the option has none."
            },
            {
              "kind": "method",
              "name": "getItemSearchValue",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "item",
                  "type": {
                    "text": "T"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "getItemIcon",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string | undefined"
                }
              },
              "parameters": [
                {
                  "name": "item",
                  "type": {
                    "text": "T"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "getItemSubtitle",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string | undefined"
                }
              },
              "parameters": [
                {
                  "name": "item",
                  "type": {
                    "text": "T"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "getItemGroup",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string | undefined"
                }
              },
              "parameters": [
                {
                  "name": "item",
                  "type": {
                    "text": "T"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "getItemDisabled",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "item",
                  "type": {
                    "text": "T"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "isIndexSelectable",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "index",
                  "type": {
                    "text": "number"
                  }
                }
              ],
              "description": "Tree mode: whether the visible node at `index` may be selected. Non-selectable\nnodes (see `isSelectableMember`/`getIsSelectableCallback`) still render — just\nwithout a checkbox — but are skipped by focus and cannot be toggled. Always\ntrue outside tree mode. `treeNodes` is index-aligned with `filteredOptions`."
            },
            {
              "kind": "method",
              "name": "isOptionSelectable",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "option",
                  "type": {
                    "text": "T"
                  }
                }
              ],
              "description": "Whether an option may be selected. Always true outside tree mode."
            },
            {
              "kind": "method",
              "name": "init",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "parseOptions",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "isTreeMode",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "description": "Whether options should be rendered as an (always-expanded) tree."
            },
            {
              "kind": "method",
              "name": "buildTree",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "(Re)build the ltree from `allOptions` and derive the visible flat list."
            },
            {
              "kind": "method",
              "name": "isCascadeMode",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "description": "Whether cascade checkbox mode is active: a multi-select tree with\n`checkbox-mode=\"cascade\"`. Checking a node then toggles its whole subtree\nand branches show a tristate box."
            },
            {
              "kind": "method",
              "name": "cascadePolicy",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "CascadeSelectPolicy"
                }
              }
            },
            {
              "kind": "method",
              "name": "refreshCascadeAtoms",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Refresh the derived checked-atom set from the emitted `selectedValues`."
            },
            {
              "kind": "method",
              "name": "toggleTreeCascade",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "node",
                  "type": {
                    "text": "LTreeNode<T>"
                  }
                }
              ],
              "description": "Toggle a tree node in cascade mode: flip its whole subtree, re-project the\nchecked atoms to emitted values under the active policy, and commit the diff\nso badges / form / change events reflect the policy (rolled-up branches, etc.)."
            },
            {
              "kind": "method",
              "name": "commitCascadeAtoms",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "checkedAtoms",
                  "type": {
                    "text": "Set<string>"
                  }
                }
              ],
              "description": "Given a checked-atom set, project it to emitted values under the active\npolicy, diff it against the current selection, and commit. Shared by every\ncascade entry point (node toggle, Select All) so they all emit the same\npolicy-projected shape (e.g. a full subtree rolls up to one value)."
            },
            {
              "kind": "method",
              "name": "counterSelection",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "T[]"
                }
              },
              "description": "The \"meaningful selection\" list used by the counter chip — the rolled-up\nminimal cover, regardless of the active emit policy. In cascade mode\n`leaves`/`all` emit many values for a single branch pick, which made the\ncounter read e.g. `[5]` for what a person experiences as two selections.\nThe counter should count the branches actually chosen, and stay stable when\nthe policy knob flips. Outside cascade this is just the selected options."
            },
            {
              "kind": "method",
              "name": "buildCounterTooltip",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "items",
                  "type": {
                    "text": "T[]"
                  }
                }
              ],
              "description": "Native `title` for the counter chip: the picked items, capped so it can't grow unbounded."
            },
            {
              "kind": "method",
              "name": "rebuildTreeVisible",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Derive `treeNodes` + `filteredOptions` from the full tree, applying the\ncurrent search term. Matching nodes keep all their ancestors visible so\nindentation stays coherent (the tree is always fully expanded)."
            },
            {
              "kind": "method",
              "name": "resetVisibleToAll",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Reset the visible list to \"everything\". **Tree-aware**: in tree mode it\nrebuilds `treeNodes` (kept index-aligned with `filteredOptions`) from the\nfull tree, so the two never drift. A raw `filteredOptions = [...allOptions]`\nwould leave `treeNodes` stale after clearing a search — the virtual list\nthen reserves height for every option but renders blank rows because\n`treeNodes[index]` is undefined. Always use this to clear the visible list."
            },
            {
              "kind": "method",
              "name": "rebuildTreeVisibleFromMatches",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "matches",
                  "type": {
                    "text": "T[]"
                  }
                }
              ],
              "description": "Tree mode: derive the visible list from an **external** set of matched\noptions — e.g. the results returned by `searchCallback` — keeping each\nmatch's ancestors so indentation stays coherent. This is the async-search\nanalogue of `rebuildTreeVisible`: the matching is done by the caller (their\nown index/engine) instead of a local substring test, but ancestor\npreservation and `treeNodes`/`filteredOptions` index-alignment still happen\nhere. Pass all options to show the whole tree."
            },
            {
              "kind": "method",
              "name": "rebuildTreeVisibleForNavigate",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "number"
                }
              },
              "description": "Tree + `search-mode=\"navigate\"`: keep the ENTIRE tree visible (the tree is always\nfully expanded, so `flatNodes` is the whole thing) and record which visible rows\nmatch the term in `matchingIndices` — the flat-list navigate behavior, but over\n`treeNodes`. Filter mode collapses the hierarchy to matches + ancestors; navigate\nmode instead leaves the structure intact so the user can jump between matches\n(Ctrl+Arrow on desktop, the fullscreen navigator on touch). Returns the index of\nthe first match, or -1 (no term / no matches), so the caller can set focus."
            },
            {
              "kind": "method",
              "name": "detectRTL",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "(Re)compute `isRTL` from the host's `dir` (or an RTL ancestor) and derive the\ndirection-mirrored badges position. Pure state — callers apply the DOM effects\n(class toggle, panel `dir`, badge re-render). In Shadow DOM the `dir` lives on\nthe host element, not the shadow content, so we resolve the host first."
            },
            {
              "kind": "method",
              "name": "refreshDirection",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Re-read `dir` and re-apply RTL mirroring live. The web-component calls this when\nits `dir` attribute changes at runtime (e.g. an app-wide language/direction\nswitch). Most layout follows the inherited CSS `direction` automatically (the\ncomponent is authored with logical properties); this fixes the parts pinned at\nbuild time — the `.ms--rtl` class (badges/count-display placement) and the\nexplicit `dir` on the shadow-root-appended panels (which don't sit under the\n`.ms--rtl` element, so they'd otherwise keep a stale build-time direction)."
            },
            {
              "kind": "method",
              "name": "buildHTML",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "shouldUseVirtualScroll",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "description": "Check if virtual scroll should be used"
            },
            {
              "kind": "method",
              "name": "hasGroups",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "description": "Check if any options have groups"
            },
            {
              "kind": "method",
              "name": "renderDropdown",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "{ preserveScroll?: boolean }"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "applyEdgeOptionRadii",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Round the OUTER corners of the row at the very top and the row at the very\nbottom of the list so a focused/selected row's background — and crucially its\nfocus `outline`, which traces the row's OWN box and follows its border-radius\nbut NOT an ancestor's overflow clip — curves with the panel instead of poking a\nsquare corner past it.\n\nKeyed off DOM order, not option index, so grouping works: when grouped the top\nrow is a `.ms__group-label` (not the first option, which sits below it), so we\nround whichever element is physically first/last. VirtualScroll renders rows in\nindex order into one innerHTML, so DOM order == visual order there too.\n\nLogical corners (`border-start-*` / `border-end-*`) so it mirrors in RTL. A\nspace-taking vertical scrollbar occupies the inline-END gutter, so the END-side\ncorners stay square then (the panel's rounded end corner is the scrollbar\ntrack's). The radius is 0 in the fullscreen sheet (that scope zeroes the var)."
            },
            {
              "kind": "method",
              "name": "renderDropdownVirtual",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Render dropdown with virtual scrolling"
            },
            {
              "kind": "method",
              "name": "getBuiltInActionDisabled",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "action",
                  "type": {
                    "text": "string"
                  }
                }
              ],
              "description": "Default enabled/disabled state for the built-in actions, applied only when the consumer hasn't\nset an explicit `isDisabled` / `getIsDisabledCallback`:\n- `select-all` is disabled when it would add nothing (every selectable, non-disabled filtered\n  option is already selected — this also covers an empty list).\n- `clear-all` is disabled when nothing is selected."
            },
            {
              "kind": "method",
              "name": "renderActionsHTML",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              }
            },
            {
              "kind": "method",
              "name": "renderOption",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "option",
                  "type": {
                    "text": "T"
                  }
                },
                {
                  "name": "index",
                  "type": {
                    "text": "number"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "renderOptionInfoButton",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "description": "Trailing info affordance for an option row, emitted only for the fullscreen\noverlay. CSS keeps it hidden until `markTruncatedOptions()` tags the row\n`.ms__option--truncated`, so it appears only when the label is actually clipped.\nTapping it reveals the full label — the touch substitute for the hover option\ntooltip, which never fires on touch (the very devices that get fullscreen).\n`tabindex=\"-1\"` keeps it out of the tab order; the search input owns keyboarding."
            },
            {
              "kind": "method",
              "name": "renderTreeNode",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "node",
                  "type": {
                    "text": "LTreeNode<T>"
                  }
                },
                {
                  "name": "index",
                  "type": {
                    "text": "number"
                  }
                }
              ],
              "description": "Render a single tree-mode row. Separate from `renderOption`: a tree row is\nindented by its depth (via the `--ms-tree-depth` custom property) and\ntagged branch/leaf, but otherwise carries the same selection/checkbox/\nicon/subtitle content. The tree is always fully expanded, so there is no\nchevron/toggle — every node is just a normal, selectable option."
            },
            {
              "kind": "method",
              "name": "renderEmptyStateHTML",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "description": "Empty-dropdown content. When \"add new\" is enabled (isAddNewAllowed) AND the user has typed\na non-empty search term, show a clickable \"add new\" prompt instead of the plain emptyMessage —\nchoosing it (click via handleDropdownClick, or Enter via the keydown handler) runs handleAddNew.\nOtherwise fall back to the emptyMessage."
            },
            {
              "kind": "method",
              "name": "isAddNewPromptShown",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "description": "True when the empty dropdown is currently showing the clickable \"add new\" prompt."
            },
            {
              "kind": "method",
              "name": "getAddNewText",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "value",
                  "type": {
                    "text": "string"
                  }
                }
              ],
              "description": "Resolve the \"add new\" prompt label for the typed text. Priority: getAddNewTextCallback\n(returns plain text — fully escaped here) → addNewText template (trusted config string;\nonly the `{value}` substitution is escaped) → the default `Add \"{value}\"`."
            },
            {
              "kind": "method",
              "name": "getAddNewPendingText",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "value",
                  "type": {
                    "text": "string"
                  }
                }
              ],
              "description": "Pending-prompt label shown (with a spinner) while an async addNewCallback runs."
            },
            {
              "kind": "method",
              "name": "escapeHtml",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "value",
                  "type": {
                    "text": "string"
                  }
                }
              ],
              "description": "Minimal HTML entity escape for untrusted text spliced into an innerHTML string."
            },
            {
              "kind": "method",
              "name": "highlightMatch",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "text",
                  "type": {
                    "text": "string"
                  }
                },
                {
                  "name": "searchTerm",
                  "type": {
                    "text": "string"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "groupOptions",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "Record<string, T[]>"
                }
              },
              "parameters": [
                {
                  "name": "options",
                  "type": {
                    "text": "T[]"
                  }
                }
              ]
            },
            {
              "kind": "field",
              "name": "isSearchUsable",
              "type": {
                "text": "boolean"
              },
              "privacy": "private",
              "description": "Whether the input currently functions as a usable search field (drives placeholder wording).",
              "readonly": true
            },
            {
              "kind": "method",
              "name": "getPlaceholderText",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "description": "Resolve the closed-state input placeholder for the current data/search state.\nPriority: explicit no-data placeholder (when the list is empty) → \"pick\" prompt when\nsearch is unusable → the search placeholder."
            },
            {
              "kind": "method",
              "name": "getSearchPlaceholder",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "description": "The search field placeholder. An explicit `searchPlaceholder` always wins and stays\nfixed. Otherwise the default is \"Search...\" — except when the in-overlay mode toggle\nis enabled (`isSearchModeToggleShown`), where it becomes mode-aware so the field labels\nthe current behavior: \"Search…\" in navigate mode, \"Filter…\" in filter mode. Refreshed\non a live mode switch (see setSearchModeLive → refreshSearchPlaceholder)."
            },
            {
              "kind": "method",
              "name": "refreshSearchPlaceholder",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Re-apply the (possibly mode-aware) placeholder to the live inputs after a mode switch."
            },
            {
              "kind": "method",
              "name": "renderBadges",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "attachEvents",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "handleSearch",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "Promise<void>"
                }
              },
              "parameters": [
                {
                  "name": "value",
                  "type": {
                    "text": "string"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "abortInFlightSearch",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Abort the search request currently in flight, if any. The aborted request's results\nare then ignored (and the consumer's `searchCallback` can short-circuit its fetch via\nthe `AbortSignal` it was handed)."
            },
            {
              "kind": "method",
              "name": "performAsyncSearch",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "Promise<void>"
                }
              },
              "parameters": [
                {
                  "name": "value",
                  "type": {
                    "text": "string"
                  }
                },
                {
                  "name": "processedValue",
                  "type": {
                    "text": "string"
                  }
                }
              ],
              "description": "Invoke the async `searchCallback` and apply its results. Split out of `handleSearch`\nso it can be called immediately or after the debounce timer.\n\nAny request still in flight is aborted before a new one starts, so a slow earlier\nrequest can't overwrite a newer one — and consumers that wire the passed `AbortSignal`\ninto their fetch get the request actually cancelled, not just ignored. The\n`aborted` / `searchTerm === value` guards drop superseded or out-of-order responses."
            },
            {
              "kind": "method",
              "name": "handleKeydown",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "e",
                  "type": {
                    "text": "KeyboardEvent"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "handleDropdownClick",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "e",
                  "type": {
                    "text": "MouseEvent"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "handleBadgeClick",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "e",
                  "type": {
                    "text": "MouseEvent"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "handleClickOutside",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "e",
                  "type": {
                    "text": "MouseEvent"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "focusBy",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "compute",
                  "type": {
                    "text": "(current: number, total: number) => number"
                  }
                },
                {
                  "name": "dir",
                  "default": "1",
                  "type": {
                    "text": "1 | -1"
                  }
                }
              ],
              "description": "Move focus by computing a new index from (current, total).\nReturning -1 from `compute` is a no-op (used for empty list / no match)."
            },
            {
              "kind": "method",
              "name": "resolveSelectableIndex",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "number"
                }
              },
              "parameters": [
                {
                  "name": "start",
                  "type": {
                    "text": "number"
                  }
                },
                {
                  "name": "dir",
                  "type": {
                    "text": "1 | -1"
                  }
                },
                {
                  "name": "total",
                  "type": {
                    "text": "number"
                  }
                }
              ],
              "description": "Given a target index and a preferred direction, return the nearest index\nwhose node is selectable (skipping non-selectable tree nodes). Falls back to\nthe opposite direction, then to -1 if nothing is selectable. No-op outside\ntree mode."
            },
            {
              "kind": "method",
              "name": "focusNext",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "focusPrevious",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "focusFirst",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "focusLast",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "focusPageUp",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "focusPageDown",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "focusAddNewPrompt",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Move keyboard focus onto the empty-state \"add new\" prompt (the only actionable row)."
            },
            {
              "kind": "method",
              "name": "focusNextMatch",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "focusPreviousMatch",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "getKeyboardController",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "MultiSelectKeyboardController<T>"
                }
              },
              "description": "Lazily build (and cache) the imperative facade passed to `keydownCallback`. Bound to the\nsame private actions the built-in key handling uses, so consumer shortcuts behave identically."
            },
            {
              "kind": "method",
              "name": "clearSearch",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Clear the search box and restore the full option list (resets the visible/matched sets and\ndrops keyboard focus). Public building block: pair it with `scrollToValue()` to reveal then\nscroll to an option the current search had filtered out — `el.clearSearch(); el.scrollToValue(v)`.\nDoes not touch the selection (use `clearAll()` for that)."
            },
            {
              "kind": "method",
              "name": "search",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "term",
                  "type": {
                    "text": "string"
                  }
                }
              ],
              "description": "Programmatically set the search text and filter — exactly as if the user typed it, so\n`beforeSearchCallback`, `minSearchLength` and async `searchCallback` all apply the same way.\nReflects into the search box (and the fullscreen sheet's field). Does NOT open the dropdown —\ncall `open()` if you want it visible. Passing `''` clears (equivalent to `clearSearch()`)."
            },
            {
              "kind": "method",
              "name": "scrollToFocused",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "applyScrollIntoView",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "el",
                  "type": {
                    "text": "HTMLElement"
                  }
                },
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "{ block?: ScrollLogicalPosition }"
                  }
                }
              ],
              "description": "scrollIntoView with the fullscreen-safe default. In the fullscreen sheet the soft keyboard\ncovers the lower viewport, so `block:'nearest'` can bottom-align a match BEHIND the keyboard;\ncentre it instead and scroll INSTANTLY (a smooth animation kicked off per-keystroke is torn\ndown by the next re-render and never settles — the \"list jumps every letter\" bug). Floating\nscrolls the nearest edge smoothly. The caller may override `block`."
            },
            {
              "kind": "method",
              "name": "scrollToIndex",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "index",
                  "type": {
                    "text": "number"
                  }
                },
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "{ block?: ScrollLogicalPosition }"
                  }
                }
              ],
              "description": "Scroll the open dropdown so the option at `index` (into the current `filteredOptions`) is\nvisible. Works in floating, fullscreen (mobile), virtual-scroll and tree modes. Returns\nfalse if the dropdown is closed or the index is out of range. The scroll is deferred a frame\nwhen the list isn't rendered yet (e.g. right after `open()` in virtual mode / the fullscreen\nsheet build), so `el.open(); el.scrollToIndex(i)` works."
            },
            {
              "kind": "method",
              "name": "scrollToValue",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "value",
                  "type": {
                    "text": "string | number"
                  }
                },
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "{ block?: ScrollLogicalPosition }"
                  }
                }
              ],
              "description": "Scroll to the option whose value matches `value` (resolved within the current\n`filteredOptions`). Returns false if it isn't in the currently visible list — e.g. filtered\nout by a search, or (tree) under a collapsed ancestor. Call `clearSearch()` (or expand the\nbranch) first to reveal it, then scroll."
            },
            {
              "kind": "method",
              "name": "scrollToGroup",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "name",
                  "type": {
                    "text": "string"
                  }
                },
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "{ block?: ScrollLogicalPosition }"
                  }
                }
              ],
              "description": "Scroll to a group. In standard rendering the group's header (`.ms__group-label`) is brought\ninto view; in virtual-scroll mode (which renders no headers) it scrolls to the group's FIRST\noption instead. Returns false in tree mode (groups don't apply) or if the group has no\noptions in the current filtered list."
            },
            {
              "kind": "method",
              "name": "scrollToRenderedIndex",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "index",
                  "type": {
                    "text": "number"
                  }
                },
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "{ block?: ScrollLogicalPosition }"
                  }
                },
                {
                  "name": "retried",
                  "default": "false"
                }
              ],
              "description": "Shared scroll worker for the public scrollTo* methods. Virtual mode uses the fixed-height\nmath (works even if the row isn't currently rendered); otherwise scrolls the\n`.ms__option[data-index]` element into view. Defers one frame if the list isn't ready yet\n(post-open virtual init / fullscreen sheet build), then retries once."
            },
            {
              "kind": "method",
              "name": "toggleOption",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "option",
                  "type": {
                    "text": "T"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "interactiveSelect",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "option",
                  "type": {
                    "text": "T"
                  }
                }
              ],
              "description": "The single funnel for an interactive (user-initiated) selection. Consults\n`beforeSelectCallback` and only mutates state if allowed, so the veto can\nnever be bypassed by a new UI entry point. Programmatic `setSelected` and\nthe Select-All button deliberately do not route through here.\nReturns true if the option was selected, false if the veto blocked it."
            },
            {
              "kind": "method",
              "name": "interactiveDeselect",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "option",
                  "type": {
                    "text": "T"
                  }
                }
              ],
              "description": "The single funnel for an interactive (user-initiated) deselection. Every\nremoval affordance — dropdown toggle, badge × button, selected-items\npopover × button, and the \"remove hidden\" badge — routes through here so\nthe `beforeDeselectCallback` veto applies uniformly. Programmatic\n`setSelected` and the Clear-All button deliberately bypass it.\nReturns true if the option was deselected, false if the veto blocked it."
            },
            {
              "kind": "method",
              "name": "handleAddNew",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "Promise<void>"
                }
              },
              "parameters": [
                {
                  "name": "value",
                  "type": {
                    "text": "string"
                  }
                }
              ],
              "description": "Commit the \"add new\" affordance for the typed text. Two modes:\n - `addNewCallback` set → create the option, append it, select it, clear the search.\n - no callback → the consumer owns creation; we only notify (via the `add` event) so they\n   can open a modal / POST / add the option imperatively.\nThe `add` event fires in BOTH modes (with `option` present only when one was created)."
            },
            {
              "kind": "method",
              "name": "selectOption",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "option",
                  "type": {
                    "text": "T"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "deselectOption",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "option",
                  "type": {
                    "text": "T"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "selectAll",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "clearAll",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "clearClick",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Inline clear (✕) handler: wipe the whole selection and any search text, then\nrestore focus to the input. clearAll() → commit() → renderBadges() already\nrefreshes this button's visibility (it hides once nothing is selected)."
            },
            {
              "kind": "method",
              "name": "updateClearButton",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Show the inline clear (✕) only when it is opted in (isClearShown), something is\nselected, and the control is enabled. Called from renderBadges() so it tracks\nevery selection change. Uses inline display like the counter / fullscreen clear."
            },
            {
              "kind": "method",
              "name": "commit",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "delta",
                  "type": {
                    "text": "{ added?: T[]; removed?: T[] }"
                  }
                }
              ],
              "description": "Re-render and fire callbacks after a selection state change.\n`added` / `removed` drive per-item select/deselect callbacks.\n`onChange` fires once if anything actually changed."
            },
            {
              "kind": "method",
              "name": "armClickGuard",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Shield the trailing document `click` for one tick. A consumer that drives the\ndropdown from their OWN button's click handler (`el.open()` / `el.toggle()`, or a\nscrollTo* command re-driving the already-open panel) would otherwise have that\nsame click bubble to our document-level outside-click listener and immediately\nclose it. Centralizing it here means every entry point — open(), the internal\npointer path, and the public scrollTo* API — is covered. Cleared next tick, so a\ngenuine later outside-click still closes as normal. Harmless for non-click\ncallers (typing, programmatic-on-load, server-driven): no trailing click arrives\nbefore it clears."
            },
            {
              "kind": "method",
              "name": "open",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Open the dropdown (no-op if already open, or if there is nothing to show)."
            },
            {
              "kind": "method",
              "name": "close",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Close the dropdown (no-op if already closed)."
            },
            {
              "kind": "method",
              "name": "toggle",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Toggle the dropdown open/closed."
            },
            {
              "kind": "field",
              "name": "isOpen",
              "type": {
                "text": "boolean"
              },
              "description": "Whether the dropdown is currently open. Assigning opens/closes it."
            },
            {
              "kind": "method",
              "name": "anchorFloatingPanel",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "() => void"
                }
              },
              "parameters": [
                {
                  "name": "panel",
                  "type": {
                    "text": "HTMLElement"
                  }
                },
                {
                  "name": "opts",
                  "type": {
                    "text": "{\n        getPlacement: () => Placement | null;\n        setPlacement: (p: Placement) => void;\n        /** When false, never locks (re-flips on every update). Defaults to true. */\n        isLocked?: () => boolean;\n        applyMaxWidth?: boolean;\n        afterPosition?: () => void;\n    }"
                  }
                }
              ],
              "description": "Anchor a floating panel (dropdown or selected-items popover) below/above the input with\nplacement-locking and width-syncing. Returns the `autoUpdate` cleanup.\n\nBoth panels share: anchor on input, sync width, default to 'bottom-start', flip on first\ncompute then lock the resulting placement, optionally clamp by dropdownMin/MaxWidth."
            },
            {
              "kind": "method",
              "name": "warnDrift",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "drift",
                  "type": {
                    "text": "DriftReport"
                  }
                }
              ],
              "description": "Surface a multiselect-branded, once-per-instance warning when core's drift check\n(`anchor`'s `onDrift`) reports the panel didn't land where it was positioned. The\nconsumer has an ancestor that establishes a fixed containing block but isn't on the\nreliable-anchors list (likely `contain: paint|layout|strict` or `container-type`).\nWe can't fix it from inside the library, but we point at the likely culprit. Core\nowns the measurement + culprit-finding + CB-CSS diagnostic (`detectFixedDrift`)."
            },
            {
              "kind": "method",
              "name": "warnFullscreenContainingBlock",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Fullscreen counterpart of warnDrift. The overlay is a `position: fixed`,\nfull-viewport sheet — but if an ancestor of the host establishes a fixed-positioning\ncontaining block (`transform` / `perspective` / `filter` / `backdrop-filter` / a\nqualifying `will-change`), the browser anchors the sheet to THAT ancestor's box instead\nof the viewport, so it no longer covers the screen (offset, clipped, or mis-sized).\n\nUnlike the floating path — where core measures real drift after positioning — nothing\nanchors the sheet, so there's no drift to observe. Instead we ask core's shared\nheuristic (`getFixedPositionOffsetParent`, the same one that feeds the floating platform)\nwhether the sheet's true offset parent is the viewport (`window`) or an element. An\nelement means it WILL be mis-anchored; warn once, pointing at the culprit. We only check\nthe reliably-honoured properties core lists (transform family) — `contain` /\n`container-type` are omitted because browsers don't honour them for fixed positioning,\nso they don't actually break the sheet."
            },
            {
              "kind": "method",
              "name": "positionDropdown",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "setPresentation",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "mode",
                  "type": {
                    "text": "'floating' | 'fullscreen'"
                  }
                }
              ],
              "description": "Switch how the open panels are presented. 'floating' anchors them to the input\n(the default); 'fullscreen' renders them as full-viewport overlays (the phone\npattern) — the dropdown with its own search header + close, the selected-items\npopover with its existing header + close. Driven by the element's\n`environmentChanged` hook (auto → fullscreen on phones). A no-op when unchanged;\nwhen a panel is already open it re-applies live so an orientation flip / viewport\nresize can swap presentation without a reopen."
            },
            {
              "kind": "method",
              "name": "lockBodyScroll",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Lock page scroll behind a fullscreen overlay via the core ref-counted helper.\nIdempotent per instance: the dropdown and the selected-items popover are mutually\nexclusive (opening one closes the other), so we hold at most one lock at a time,\nand a redundant call is a no-op rather than acquiring a second."
            },
            {
              "kind": "method",
              "name": "unlockBodyScroll",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Restore page scroll (no-op if it wasn't locked)."
            },
            {
              "kind": "method",
              "name": "clampDocumentOverflowX",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Clip the host document's horizontal overflow while a fullscreen sheet is open.\n\nA page that overflows horizontally (e.g. an unbreakable-wide token in a heading)\nmakes the mobile browser SHRINK-TO-FIT: it zooms the page out so the overflow fits,\nwhich desyncs the visual viewport from the layout viewport. Our fullscreen sheet is\n`position: fixed` — anchored to the LAYOUT viewport — so under that zoom it no longer\nlands flush against the physical screen edges, and the top slips under the system bar\n(looks like \"the bar covers the sheet\"). This is NOT a safe-area problem; safe-area\ninsets are 0 in that state. Clamping `overflow-x: hidden` on <html>/<body> removes the\noverflow, so the browser drops the zoom and the sheet sits flush. Complements\nlockBodyScroll() (vertical axis); the saved inline value is restored on close.\n\nOnly <html> is touched (not <body>): clipping the root's horizontal overflow is\nenough to collapse the scrollWidth and cancel the shrink-to-fit, and it avoids\nconflicting with core's lockBodyScroll(), which owns <body>'s `overflow`. Idempotent."
            },
            {
              "kind": "method",
              "name": "releaseDocumentOverflowX",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Restore the <html> `overflow-x` clamped by clampDocumentOverflowX() (no-op if unset)."
            },
            {
              "kind": "method",
              "name": "observeKeyboardInset",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "While the fullscreen dropdown is open, keep it sitting above the soft keyboard.\nDelegates to core's `observeKeyboardInset` (which tracks `window.visualViewport`\nand pins the panel's height/top so its flex column reflows above the keyboard);\nwe just hold the returned cleanup. No-op where `visualViewport` is unavailable."
            },
            {
              "kind": "method",
              "name": "unobserveKeyboardInset",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Detach keyboard-inset tracking and restore the panel's CSS-driven geometry."
            },
            {
              "kind": "method",
              "name": "fullscreenScale",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "number"
                }
              },
              "description": "The fullscreen size multiplier = `--ms-fullscreen-rem ÷ --ms-rem` (both read off\nthe host). CSS scales itself — every size is `calc(N × --ms-rem)` and the panel\noverrides `--ms-rem` — so this exists only for the JS-driven pixel heights that\nCSS can't reach: the virtual/fixed option rows and the popover's virtual badges.\nReturns 1 when floating (or when computed styles aren't readable, e.g. jsdom)."
            },
            {
              "kind": "method",
              "name": "scaledOptionHeight",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "number"
                }
              },
              "description": "Virtual/fixed row height (px), scaled up in the fullscreen phone view."
            },
            {
              "kind": "method",
              "name": "applyVirtualOptionsSizing",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "container",
                  "type": {
                    "text": "HTMLElement"
                  }
                }
              ],
              "description": "Size the virtual options scroll container for the current presentation. Applied on\nevery render (the container itself is built once), so a floating⇄fullscreen switch\nre-sizes it: floating = a fixed maxHeight scroll box; fullscreen = flex-fill the\npanel's flex column (no fixed height). Also refreshes --ms-option-height to the\nscaled row height so the CSS row height matches the virtual scroller's itemHeight."
            },
            {
              "kind": "method",
              "name": "scaledBadgeHeight",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "number"
                }
              },
              "description": "Virtual popover badge row height (px). In the fullscreen phone view the rows are\nscaled up AND given extra height so a selected item is a comfortable, dropdown-like\ntouch target (the default 36px pill is short for touch). Mirrors the CSS\n`--ms-badge-height` override for the fullscreen popover (floating.css) so the\nvirtual list's fixed height agrees with the non-virtual pills."
            },
            {
              "kind": "method",
              "name": "clearFloatingInlineGeometry",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "panel",
                  "type": {
                    "text": "HTMLElement"
                  }
                }
              ],
              "description": "Clear the inline geometry that floating-ui's `anchor` writes on a panel\n(position/left/top plus our composed max-width/min-width). Inline styles beat\nthe stylesheet, so a panel left over from a floating cycle would otherwise pin\nitself where it last anchored and ignore the fullscreen CSS (position: fixed;\ninset: 0; width: 100vw). Must run when switching a panel floating → fullscreen."
            },
            {
              "kind": "method",
              "name": "enterFullscreen",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Stand up the fullscreen dropdown overlay: modifier class, header, scroll lock, focus."
            },
            {
              "kind": "method",
              "name": "exitFullscreen",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Tear down the fullscreen dropdown chrome and restore page scroll (no-op if floating)."
            },
            {
              "kind": "method",
              "name": "pushOverlayHistory",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Back-gesture handling for the fullscreen sheet. On open we push a history entry\n(same URL) and listen for `popstate`; the phone Back gesture/button then pops that\nentry — which we treat as \"close the sheet\" — instead of navigating away from the\npage. A programmatic close (✕, selection, Escape) consumes the entry via\n`history.back()` so the stack is left as it was found."
            },
            {
              "kind": "method",
              "name": "handleOverlayPopstate",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Back gesture/button fired: our pushed entry is already gone, so just close the\nsheet — WITHOUT popping history again (popOverlayHistory becomes a no-op)."
            },
            {
              "kind": "method",
              "name": "popOverlayHistory",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Programmatic close: remove the listener and pop the entry we pushed (so the\nhistory stack returns to its pre-open state). No-op if a Back gesture already\nconsumed it (overlayHistoryActive is false by then)."
            },
            {
              "kind": "method",
              "name": "buildFullscreenHeader",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Build the fullscreen overlay header: a search field (proxying to the same\n`handleSearch`/`handleKeydown` path as the main input, since the overlay covers\nit) plus a close button. Inserted before the scrolling list so it pins to the\ntop of the fixed panel. `renderDropdown()` only rewrites `dropdownInner`, so the\nheader survives re-renders."
            },
            {
              "kind": "method",
              "name": "ensureFullscreenNav",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Build the navigate-mode match navigator (count + prev/next) and append it to the\nfullscreen header, once. No-op if already built or the header isn't present. The\nnav wraps onto its own full-width row under the search box (header is flex-wrap;\nthe nav takes 100% basis)."
            },
            {
              "kind": "method",
              "name": "removeFullscreenNav",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Remove the match navigator (switching to filter mode, which has no jump UI)."
            },
            {
              "kind": "method",
              "name": "toggleSearchModeLive",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Flip searchMode filter<->navigate from the in-overlay toggle."
            },
            {
              "kind": "method",
              "name": "setSearchModeLive",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "mode",
                  "type": {
                    "text": "SearchMode"
                  }
                }
              ],
              "description": "Switch searchMode in place — the overlay's toggle path. The `search-mode` attribute\nis reinit-on-change (it rebuilds and closes the overlay); this instead mutates the\nlive config, adds/removes the match navigator to match, and re-projects the current\nterm under the new mode (filter narrows the list / navigate keeps all + highlights),\nall without tearing the open sheet down. Focus stays on the search field."
            },
            {
              "kind": "method",
              "name": "updateFullscreenModeToggle",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Sync the mode toggle's icon (via data-mode) and labels with the current searchMode.\nNo-op when the toggle isn't built (opt-out, floating panel, or search hidden)."
            },
            {
              "kind": "method",
              "name": "updateFullscreenNav",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Sync the fullscreen match navigator (navigate mode only) with the current search\nstate: hide it until there's a term, then show \"N of M\" while a match is focused\n(or \"M matches\" / \"No matches\"), and disable the prev/next buttons when there's\nnothing to step through. No-op when the navigator isn't built (floating panel,\nfilter mode, or search disabled)."
            },
            {
              "kind": "method",
              "name": "updateFullscreenSearchClear",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Show the fullscreen search's inline clear (✕) only while the field has text.\nNo-op when the button isn't built (floating panel, readonly/hidden search)."
            },
            {
              "kind": "method",
              "name": "clearFullscreenSearch",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Clear the fullscreen search term via the same path a keystroke takes, then\nrefocus the field so the user can keep typing. Touch has no keyboard Escape,\nso this button is the on-screen way to reset a search."
            },
            {
              "kind": "method",
              "name": "positionHint",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "parseInitialSelection",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "reconcileSelectedOptions",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Resolve any `selectedValues` entries that don't yet have a matching\n`selectedOptions` object by looking them up in the current `allOptions`.\nIdempotent; safe to call after init *and* after `options` is replaced\n(e.g., async fetch, `searchCallback` result, or late `element.options =`\nassignment). Without this, `initial-values` declared before options\narrive ends up with phantom values that `getValue()` can never report."
            },
            {
              "kind": "method",
              "name": "toggleSelectedPopover",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "showPopover",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "hideSelectedPopover",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "renderSelectedPopover",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "renderSelectedPopoverVirtual",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "selectedOptions",
                  "type": {
                    "text": "T[]"
                  }
                },
                {
                  "name": "count",
                  "type": {
                    "text": "number"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "toHtml",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "v",
                  "type": {
                    "text": "string | HTMLElement | null | undefined"
                  }
                }
              ],
              "description": "Coerce a render-callback result to an HTML string. Callbacks may return a string\n(HTML) or an HTMLElement (serialized via `outerHTML`); null/undefined → ''. Used by\nevery \"return string | HTMLElement\" content callback that builds into an innerHTML\nstring. (DOM sinks that hold a live node instead — the reveal/message panels — use\ntextContent/appendChild directly and intentionally don't go through here.)"
            },
            {
              "kind": "method",
              "name": "classSuffix",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "v",
                  "type": {
                    "text": "string | string[] | null | undefined"
                  }
                }
              ],
              "description": "Normalize a class callback result (`string | string[] | null`) to a single\nspace-joined string with falsy entries dropped — e.g. `['a', '', 'b'] → \"a b\"`,\n`null → \"\"`. Callers add their own leading space / base class as needed."
            },
            {
              "kind": "method",
              "name": "renderBadgeHTML",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "option",
                  "type": {
                    "text": "T"
                  }
                },
                {
                  "name": "ctx",
                  "type": {
                    "text": "Omit<BadgeContentRenderContext, 'presentation' | 'isFullscreen' | 'isModal'>"
                  }
                }
              ],
              "description": "Render a removable badge for a selected option (used by the badges/partial display modes\nand by the selected-items popover).\n\n- In the popover, `renderSelectedItemContentCallback` and `getSelectedItemClassCallback` win\n  over the regular badge callbacks; that's how consumers customize popover items independently.\n- The `data-value` and aria-label both go through `getItemBadgeDisplayValue` so badge text and\n  accessible name stay in sync."
            },
            {
              "kind": "method",
              "name": "handleSelectedPopoverClick",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "e",
                  "type": {
                    "text": "MouseEvent"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "positionSelectedPopover",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "updateHiddenInput",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "getFormValue",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              }
            },
            {
              "kind": "method",
              "name": "getSelected",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "T[]"
                }
              }
            },
            {
              "kind": "method",
              "name": "setSelected",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "values",
                  "type": {
                    "text": "(string | number)[]"
                  }
                },
                {
                  "name": "opts",
                  "default": "{}",
                  "type": {
                    "text": "{ notify?: boolean }"
                  }
                }
              ],
              "description": "Set the selection programmatically. **Silent by default** — it does not fire\n`select`/`deselect`/`change` (so restoring saved state, cascade resets, or a\nserver-authoritative correction can't loop back or trip \"user changed it\"\nhandlers). Pass `{ notify: true }` to announce the result as a **single\naggregate `change`** — for a deliberate user gesture (e.g. an action button)\nthat should reach the same listeners a manual pick does, without the per-item\n`select`/`deselect` flood a bulk change would otherwise cause."
            },
            {
              "kind": "method",
              "name": "updateOptions",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "partial",
                  "type": {
                    "text": "Partial<MultiSelectConfig<T>>"
                  }
                }
              ],
              "description": "Merge a partial config update into the live picker without tearing down the DOM.\n\nHandles the cheap structural toggles inline (no-checkboxes class, badges-position class,\ninput placeholder, search-input mode) and re-renders dropdown + badges + hidden inputs.\n\nReturns `true` if the change could be applied in place. Returns `false` for changes that\ntruly require rebuilding the DOM scaffolding (currently: adding/removing the `searchHint`\nelement, since it's only created in `buildHTML` if a hint string was provided). The caller\nshould fall back to destroy + re-init in that case."
            },
            {
              "kind": "field",
              "name": "selectedItem",
              "type": {
                "text": "T | null"
              },
              "privacy": "public",
              "readonly": true
            },
            {
              "kind": "field",
              "name": "searchText",
              "type": {
                "text": "string"
              },
              "privacy": "public",
              "description": "The current search box text (empty string when nothing is typed). Read-only; clear it with `clearSearch()`.",
              "readonly": true
            },
            {
              "kind": "field",
              "name": "selectedValue",
              "type": {
                "text": "string | number | (string | number)[] | null"
              },
              "privacy": "public",
              "readonly": true
            },
            {
              "kind": "method",
              "name": "getValue",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "string | number | (string | number)[] | null"
                }
              }
            },
            {
              "kind": "method",
              "name": "spawnTooltip",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "spec",
                  "type": {
                    "text": "{\n        id: string;\n        trigger: HTMLElement;\n        content: string | HTMLElement;\n        onBeforeShow?: () => void;\n        /** Override placement (default: `badgeTooltipPlacement`). */\n        placement?: Placement;\n        /** Override offset (default: `badgeTooltipOffset`). */\n        offsetDistance?: number;\n        /** Override show delay (default: `badgeTooltipDelay`). */\n        showDelay?: number;\n        /** Tooltip element CSS class (default: badge tooltip styling). */\n        cssClass?: string;\n        /** Visibility-toggle CSS class (default: badge tooltip visible class). */\n        visibleClass?: string;\n        /** Anchor to and follow the mouse pointer. */\n        followCursor?: boolean;\n    }"
                  }
                }
              ],
              "description": "Create or replace a tracked tooltip with the given id. Replacing destroys the old one,\nwhich is the normal flow when re-rendering badges/actions."
            },
            {
              "kind": "method",
              "name": "destroyAllTooltips",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "buildBadgeTooltipContent",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string | HTMLElement"
                }
              },
              "parameters": [
                {
                  "name": "option",
                  "type": {
                    "text": "T"
                  }
                }
              ],
              "description": "Build the badge-text tooltip content (callback overrides; default = displayValue + optional subtitle on next line)."
            },
            {
              "kind": "method",
              "name": "buildRemoveButtonTooltipText",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string"
                }
              },
              "parameters": [
                {
                  "name": "itemName",
                  "type": {
                    "text": "string"
                  }
                },
                {
                  "name": "option",
                  "optional": true,
                  "type": {
                    "text": "T"
                  }
                }
              ],
              "description": "Build the remove-button tooltip text (callback > format string with {0} > \"Remove {name}\")."
            },
            {
              "kind": "method",
              "name": "attachBadgeTooltips",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "container",
                  "optional": true,
                  "type": {
                    "text": "HTMLElement"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "buildOptionTooltipContent",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "string | HTMLElement"
                }
              },
              "parameters": [
                {
                  "name": "option",
                  "type": {
                    "text": "T"
                  }
                }
              ],
              "description": "Build the option tooltip content (callback overrides; default = displayValue + optional subtitle on next line)."
            },
            {
              "kind": "method",
              "name": "attachOptionTooltips",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Attach hover tooltips to the currently rendered dropdown options. Prunes existing option\ntooltips first, so it's safe to call on every render and on every virtual-scroll range change\n(where option DOM is recycled). Each option resolves its source object via `data-index` into\n`filteredOptions`, the same global index `renderOption` was given."
            },
            {
              "kind": "method",
              "name": "markTruncatedOptions",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Tag each currently-rendered fullscreen option row whose title is horizontally\nclipped with `.ms__option--truncated`, so CSS reveals its info affordance.\nRuns per virtual-scroll render (rows recycle) and on the non-virtual render.\nHorizontal (ellipsis) overflow only — the truncation mode this pairs with;\na wrapping title isn't \"cut\", it grows vertically. No-op unless fullscreen."
            },
            {
              "kind": "method",
              "name": "toggleLabelReveal",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "infoBtn",
                  "type": {
                    "text": "HTMLElement"
                  }
                }
              ],
              "description": "Reveal (or dismiss) the full label of a clipped fullscreen row when its info\naffordance is tapped — hover tooltips don't fire on touch, and a hover tooltip's\nsynthetic mouseleave (from the tap itself, under devtools touch emulation) would\nflash it away. So this is a manually-controlled `createPopover` panel, mounted in\nthe shadow root for component styling, that stays until explicitly dismissed:\na second tap on the same button, a list scroll, a re-render, an outside tap, or\nclosing the panel (see hideLabelReveal + its call sites). Tapping the same button\nwhile it's shown toggles it off."
            },
            {
              "kind": "method",
              "name": "hideLabelReveal",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Dismiss the full-label reveal popover, if shown. Idempotent."
            },
            {
              "kind": "method",
              "name": "showMessage",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "content",
                  "type": {
                    "text": "string | HTMLElement"
                  }
                },
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "MessageOptions"
                  }
                }
              ],
              "description": "Show a transient message (\"toast\") on top of the component. Its reason for existing:\nin the fullscreen overlay the sheet covers the whole page, so a consumer can't surface\nfeedback (a blocked veto, a hint) where the user can see it. This renders above the\npanel in BOTH presentations — anchored under the control when floating, pinned to the\nbottom of the viewport (over the overlay) when fullscreen.\n\nContent is a string (plain text) or an HTMLElement (rich markup). `opts.variant`\n(info | warning | error | success) picks the tone; `opts.duration` sets auto-dismiss\n(0 = sticky). Tapping the message dismisses it. Only one shows at a time — a new call\nreplaces the previous. Also reached automatically when a veto callback returns a string."
            },
            {
              "kind": "method",
              "name": "hideMessage",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Dismiss the transient message, if shown. Idempotent."
            },
            {
              "kind": "method",
              "name": "hideOptionTooltips",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Hide (don't destroy) every currently-shown option tooltip immediately,\nignoring the hide delay. Wired to dropdown scroll so a tooltip can't trail\nits recycling/scrolling anchor row. Handles stay in the map; a fresh hover\nre-shows them."
            },
            {
              "kind": "method",
              "name": "destroyAllOptionTooltips",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Destroy only the option tooltips (prefixed `option-`). Called before re-rendering or\nrecycling the options list so per-option tooltip state doesn't leak."
            },
            {
              "kind": "method",
              "name": "attachActionButtonTooltips",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "destroyAllActionButtonTooltips",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Destroy only the action-button tooltips. Called from `renderDropdown`/`renderDropdownVirtual`\nbefore rebuilding the actions row, so per-button tooltip state doesn't leak."
            },
            {
              "kind": "method",
              "name": "destroyAllBadgeTooltips",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Destroy main-badges-container tooltips. Called before re-rendering the badges container.\nPopover tooltips (prefixed `popover-`) survive — they're owned by the popover lifecycle and\ncleaned up in `hideSelectedPopover`. Action-button tooltips (prefixed `action-`) survive too."
            },
            {
              "kind": "method",
              "name": "destroy",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            }
          ]
        },
        {
          "kind": "variable",
          "name": "index"
        },
        {
          "kind": "variable",
          "name": "isSelected"
        },
        {
          "kind": "variable",
          "name": "isFocused"
        },
        {
          "kind": "variable",
          "name": "isMatched"
        }
      ],
      "exports": [
        {
          "kind": "js",
          "name": "WebMultiSelect",
          "declaration": {
            "name": "WebMultiSelect",
            "module": "src/multiselect.ts"
          }
        }
      ]
    },
    {
      "kind": "javascript-module",
      "path": "src/option-formats.ts",
      "declarations": [
        {
          "kind": "variable",
          "name": "OPTIONS_FORMATS",
          "type": {
            "text": "['json', 'csv', 'plain']"
          },
          "default": "['json', 'csv', 'plain']",
          "description": "`data-options` payload parsers. The `data-options-format` attribute selects\none; each turns the raw attribute string into an options array the picker\nunderstands. Pure + total (never throws) so they unit-test in isolation and a\nmalformed payload degrades to `[]` with a describable error rather than\nbreaking reinit."
        },
        {
          "kind": "variable",
          "name": "DEFAULT_SPLITTER",
          "type": {
            "text": "string"
          },
          "default": "','",
          "description": "Default field and row delimiters (used by `csv` and `plain`; ignored by `json`)."
        },
        {
          "kind": "variable",
          "name": "DEFAULT_ROW_SPLITTER",
          "type": {
            "text": "string"
          },
          "default": "'\\n'"
        },
        {
          "kind": "function",
          "name": "parseOptionsData",
          "return": {
            "type": {
              "text": "ParsedOptions"
            }
          },
          "parameters": [
            {
              "name": "raw",
              "type": {
                "text": "string | null | undefined"
              }
            },
            {
              "name": "format",
              "type": {
                "text": "OptionsFormat"
              }
            },
            {
              "name": "opts",
              "default": "{}",
              "type": {
                "text": "ParseOptionsOptions"
              }
            }
          ],
          "description": "Parse a `data-options` payload per `format`:\n - `json`  — a JSON array of option objects or `[value, label]` tuples.\n             (`splitter`/`rowSplitter` do not apply.)\n - `csv`   — rows split on `rowSplitter`, cells on `splitter`; the first row is a\n             header and each later row becomes an object keyed by the header cells\n             (map columns via `*-member`). RFC-4180-ish quoting on the cell splitter.\n - `plain` — bare values split on `splitter` and `rowSplitter` -> `[value, label]`\n             tuples (value === label), so it renders with no member config."
        }
      ],
      "exports": [
        {
          "kind": "js",
          "name": "OPTIONS_FORMATS",
          "declaration": {
            "name": "OPTIONS_FORMATS",
            "module": "src/option-formats.ts"
          }
        },
        {
          "kind": "js",
          "name": "DEFAULT_SPLITTER",
          "declaration": {
            "name": "DEFAULT_SPLITTER",
            "module": "src/option-formats.ts"
          }
        },
        {
          "kind": "js",
          "name": "DEFAULT_ROW_SPLITTER",
          "declaration": {
            "name": "DEFAULT_ROW_SPLITTER",
            "module": "src/option-formats.ts"
          }
        },
        {
          "kind": "js",
          "name": "parseOptionsData",
          "declaration": {
            "name": "parseOptionsData",
            "module": "src/option-formats.ts"
          }
        }
      ]
    },
    {
      "kind": "javascript-module",
      "path": "src/types.ts",
      "declarations": [],
      "exports": []
    },
    {
      "kind": "javascript-module",
      "path": "src/virtual-scroll.ts",
      "declarations": [
        {
          "kind": "class",
          "description": "",
          "name": "VirtualScroll",
          "members": [
            {
              "kind": "field",
              "name": "container",
              "type": {
                "text": "HTMLElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "wrapper",
              "type": {
                "text": "HTMLDivElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "viewport",
              "type": {
                "text": "HTMLDivElement"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "itemHeight",
              "type": {
                "text": "number"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "items",
              "type": {
                "text": "T[]"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "renderItem",
              "type": {
                "text": "(item: T, index: number) => string"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "bufferSize",
              "type": {
                "text": "number"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "onVisibleRangeChange",
              "type": {
                "text": "(start: number, end: number) => void | undefined"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "onScroll",
              "type": {
                "text": "(scrollTop: number) => void | undefined"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "scrollTop",
              "type": {
                "text": "number"
              },
              "privacy": "private",
              "default": "0"
            },
            {
              "kind": "field",
              "name": "viewportHeight",
              "type": {
                "text": "number"
              },
              "privacy": "private",
              "default": "0"
            },
            {
              "kind": "field",
              "name": "visibleStart",
              "type": {
                "text": "number"
              },
              "privacy": "private",
              "default": "0"
            },
            {
              "kind": "field",
              "name": "visibleEnd",
              "type": {
                "text": "number"
              },
              "privacy": "private",
              "default": "0"
            },
            {
              "kind": "field",
              "name": "scrollHandler",
              "type": {
                "text": "() => void"
              },
              "privacy": "private"
            },
            {
              "kind": "field",
              "name": "resizeObserver",
              "type": {
                "text": "ResizeObserver | undefined"
              },
              "privacy": "private"
            },
            {
              "kind": "method",
              "name": "init",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Initialize virtual scroll DOM structure\n\nStructure:\ncontainer (overflow-y: auto)\n  └─ wrapper (height: totalItems * itemHeight)\n     └─ viewport (position: absolute, top: 0)\n        └─ items (position: absolute, top: index * itemHeight)"
            },
            {
              "kind": "method",
              "name": "updateViewportHeight",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Update viewport height (visible area)"
            },
            {
              "kind": "method",
              "name": "handleScroll",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Handle scroll event"
            },
            {
              "kind": "method",
              "name": "calculateVisibleRange",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "{ start: number; end: number }"
                }
              },
              "description": "Calculate visible range based on scroll position"
            },
            {
              "kind": "method",
              "name": "render",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Render visible items"
            },
            {
              "kind": "method",
              "name": "setItems",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "items",
                  "type": {
                    "text": "T[]"
                  }
                }
              ],
              "description": "Update items and re-render"
            },
            {
              "kind": "method",
              "name": "scrollToIndex",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "index",
                  "type": {
                    "text": "number"
                  }
                },
                {
                  "name": "block",
                  "default": "'start'",
                  "type": {
                    "text": "'start' | 'center' | 'nearest'"
                  }
                }
              ],
              "description": "Scroll to make item at index visible (like scrollIntoView with block: 'nearest')\nOnly scrolls if item is outside visible area, and scrolls minimally"
            },
            {
              "kind": "method",
              "name": "getVisibleRange",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "{ start: number; end: number }"
                }
              },
              "description": "Get currently visible range"
            },
            {
              "kind": "method",
              "name": "getItemCount",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "number"
                }
              },
              "description": "Get total number of items"
            },
            {
              "kind": "method",
              "name": "setItemHeight",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "height",
                  "type": {
                    "text": "number"
                  }
                }
              ],
              "description": "Update item height and re-render"
            },
            {
              "kind": "method",
              "name": "setBufferSize",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "size",
                  "type": {
                    "text": "number"
                  }
                }
              ],
              "description": "Update buffer size"
            },
            {
              "kind": "method",
              "name": "refresh",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Refresh/force re-render"
            },
            {
              "kind": "method",
              "name": "destroy",
              "privacy": "public",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Cleanup and remove event listeners"
            }
          ]
        }
      ],
      "exports": [
        {
          "kind": "js",
          "name": "VirtualScroll",
          "declaration": {
            "name": "VirtualScroll",
            "module": "src/virtual-scroll.ts"
          }
        }
      ]
    },
    {
      "kind": "javascript-module",
      "path": "src/web-component.ts",
      "declarations": [
        {
          "kind": "class",
          "description": "",
          "name": "MultiSelectElement",
          "members": [
            {
              "kind": "field",
              "name": "formAssociated",
              "type": {
                "text": "boolean"
              },
              "static": true,
              "default": "true"
            },
            {
              "kind": "field",
              "name": "inputs",
              "privacy": "protected",
              "static": true,
              "default": "[ // ── Strings (cosmetic → update). Optional ones are nullable: absent → null ─ { configKey: 'searchHint', attribute: 'search-hint', converter: toText({ isNullable: true }), on: 'update', description: 'Small hint text shown beneath the search input.' }, { configKey: 'searchPlaceholder', attribute: 'search-placeholder', converter: toText({ isNullable: true }), on: 'update', description: 'Placeholder text for the search input. When unset it defaults to \"Search...\"; if `show-search-mode-toggle` is on, the default instead becomes mode-aware (\"Search…\" in navigate, \"Filter…\" in filter). An explicit value always wins and stays fixed.' }, { configKey: 'selectPlaceholder', attribute: 'select-placeholder', converter: toText({ default: 'Pick an option...' }), on: 'update', description: 'Placeholder shown on the control when nothing is selected.' }, { configKey: 'noDataPlaceholder', attribute: 'no-data-placeholder', converter: toText({ isNullable: true }), on: 'update', description: 'Text shown when there are no options at all.' }, { configKey: 'dropdownMinWidth', attribute: 'dropdown-min-width', converter: toText({ isNullable: true }), on: 'update', description: 'Minimum width of the dropdown panel (any CSS length).' }, { configKey: 'dropdownMaxWidth', attribute: 'dropdown-max-width', converter: toText({ isNullable: true }), on: 'update', description: 'Maximum width of the dropdown panel (any CSS length).' }, { configKey: 'maxHeight', attribute: 'max-height', converter: toText({ default: '20rem' }), on: 'update', description: 'Maximum height of the dropdown list before it scrolls.' }, { configKey: 'emptyMessage', attribute: 'empty-message', converter: toText({ default: 'No results found' }), on: 'update', description: 'Message shown when a search yields no matches.' }, { configKey: 'addNewText', attribute: 'add-new-text', converter: toText({ isNullable: true }), on: 'update', description: 'Template for the clickable \"add new\" prompt shown (when `allow-add-new` is on) in place of the empty message once a search yields no matches. `{value}` is replaced with the typed text. Default: `Add \"{value}\"`. A `getAddNewTextCallback` wins.' }, { configKey: 'addNewPendingText', attribute: 'add-new-pending-text', converter: toText({ isNullable: true }), on: 'update', description: 'Template for the pending prompt (spinner + text) shown while an async `addNewCallback` runs. `{value}` is replaced with the typed text. Default: `Adding \"{value}\"…`.' }, { configKey: 'loadingMessage', attribute: 'loading-message', converter: toText({ default: 'Loading...' }), on: 'update', description: 'Message shown while options are loading.' }, { configKey: 'removeButtonTooltipText', attribute: 'remove-button-tooltip-text', converter: toText({ isNullable: true }), on: 'update', description: 'Tooltip text for a badge remove (×) button.' }, { configKey: 'formFieldId', attribute: 'name', converter: toText({ isNullable: true }), on: 'reinit', description: 'HTML form field name/id used for the hidden input(s).' }, // ── CSS-var sugar (mirrored to a host style prop in reinit()/update()) ──── { configKey: 'dropdownWidth', attribute: 'dropdown-width', converter: toText({ isNullable: true }), on: 'update', description: 'Fixed dropdown width; mirrored to the `--ms-dropdown-width` CSS variable.' }, { configKey: 'selectedPopoverWidth', attribute: 'selected-popover-width', converter: toText({ isNullable: true }), on: 'update', description: 'Selected-items popover width; mirrored to `--ms-selected-popover-width`.' }, // ── Member properties (structural → reinit; optional → nullable) ───────── { configKey: 'valueMember', attribute: 'value-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name on an option object that holds its value.' }, { configKey: 'displayValueMember', attribute: 'display-value-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option display label.' }, { configKey: 'searchValueMember', attribute: 'search-value-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name searched against (falls back to the display value).' }, { configKey: 'iconMember', attribute: 'icon-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option icon.' }, { configKey: 'subtitleMember', attribute: 'subtitle-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option subtitle.' }, { configKey: 'fullTitleMember', attribute: 'full-title-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option full/long title.' }, { configKey: 'groupMember', attribute: 'group-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name used to group options under headers.' }, { configKey: 'disabledMember', attribute: 'disabled-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that marks an option disabled.' }, // ── Tree of options (structural → reinit; optional → nullable) ─────────── { configKey: 'pathMember', attribute: 'path-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name holding a node materialized tree path.' }, { configKey: 'parentPathMember', attribute: 'parent-path-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name holding a node parent path.' }, { configKey: 'levelMember', attribute: 'level-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name holding a node depth level.' }, { configKey: 'hasChildrenMember', attribute: 'has-children-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name flagging that a node has children.' }, { configKey: 'isSelectableMember', attribute: 'is-selectable-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name marking whether a node can be selected.' }, { configKey: 'treePathSeparator', attribute: 'tree-path-separator', converter: toText({ default: '.' }), reflect: true, on: 'reinit', description: 'Separator between segments in a materialized tree path.' }, { configKey: 'isTreeEnabled', converter: toBool('tristate'), on: 'reinit', type: 'boolean', description: 'Force tree mode on/off. Property-only; when unset (null) tree mode auto-enables if a path source (path-member / getPathCallback) is present.' }, { configKey: 'checkboxMode', attribute: 'checkbox-mode', converter: toEnum(['independent', 'cascade'] as const, { default: 'independent' }), reflect: true, on: 'update', description: `Tree checkbox interaction. - \\`independent\\` (default) — toggles only the clicked node. - \\`cascade\\` — checks a node whole subtree and shows a tristate (checked / indeterminate / unchecked) box on branches. Tree + multiple only.` }, { configKey: 'cascadeSelectPolicy', attribute: 'cascade-select-policy', converter: toEnum(['rolled-up', 'leaves', 'all'] as const, { default: 'rolled-up' }), reflect: true, on: 'update', description: `In \\`cascade\\` mode, which values a selection emits (badges / form / change): - \\`rolled-up\\` (default) — minimal cover: a fully-selected subtree collapses to its root; partially-selected branches emit their individually-checked descendants. - \\`leaves\\` — only the checked leaf-level nodes. - \\`all\\` — every fully-checked node (branches and leaves).` }, // ── Enums ──────────────────────────────────────────────────────────────── { configKey: 'badgesDisplayMode', attribute: 'badges-display-mode', converter: toEnum(['badges', 'count', 'compact', 'partial', 'none'] as const, { default: 'badges' }), on: 'reinit', description: 'How the current selection is shown in the control.' }, { configKey: 'badgesPosition', attribute: 'badges-position', converter: toEnum(['top', 'bottom', 'left', 'right'] as const, { default: 'bottom' }), on: 'reinit', description: 'Where the badges/selection appear relative to the input.' }, { configKey: 'badgesThresholdMode', attribute: 'badges-threshold-mode', converter: toEnum(['count', 'partial'] as const, { default: 'count' }), on: 'update', description: 'How `badgesThreshold` is interpreted: collapse to a count badge, or keep partial badges + a \"more\" badge.' }, { configKey: 'searchInputMode', attribute: 'search-input-mode', converter: toEnum(['normal', 'readonly', 'hidden'] as const, { default: 'normal' }), on: 'reinit', description: 'Search field mode: editable, read-only, or hidden.' }, { configKey: 'searchMode', attribute: 'search-mode', converter: toEnum(['filter', 'navigate'] as const, { default: 'filter' }), on: 'reinit', description: 'Whether typing filters the list or navigates it.' }, { configKey: 'overlayGroup', attribute: 'overlay-group', converter: toText({ isNullable: true }), on: 'reinit', description: 'Scope the \"one overlay open at a time\" coordination to a named group. Overlays (multiselects, datepickers, external popovers) sharing a group dismiss each other when one opens; different groups are independent. Unset = the default (ungrouped) group.' }, { configKey: 'actionsLayout', attribute: 'actions-layout', converter: toEnum(['nowrap', 'wrap'] as const, { default: 'nowrap' }), on: 'reinit', description: 'Whether the action bar wraps or stays on one line.' }, { configKey: 'actionsPosition', attribute: 'actions-position', converter: toEnum(['top', 'bottom'] as const, { default: 'top' }), on: 'reinit', description: 'Whether the action bar sits above or below the list.' }, { configKey: 'actionsAlign', attribute: 'actions-align', converter: toEnum(['stretch', 'left', 'right', 'center', 'space-between'] as const, { default: 'stretch' }), on: 'update', description: 'Horizontal alignment of the action buttons.' }, { configKey: 'checkboxAlign', attribute: 'checkbox-align', converter: toEnum(['top', 'center', 'bottom'] as const, { default: 'center' }), on: 'update', description: 'Vertical alignment of an option checkbox.' }, { configKey: 'valueFormat', attribute: 'value-format', converter: toEnum(['json', 'csv', 'array'] as const, { default: 'json' }), on: 'reinit', description: 'Serialization format the control emits its value in.' }, { configKey: 'badgeTooltipPlacement', attribute: 'badge-tooltip-placement', converter: toEnum(PLACEMENTS, { default: 'top' }), on: 'update', description: 'Preferred placement of a badge tooltip relative to its badge (floating-ui placement).' }, { configKey: 'optionTooltipPlacement', attribute: 'option-tooltip-placement', converter: toEnum(PLACEMENTS, { default: 'top-start' }), on: 'update', description: 'Preferred placement of an option tooltip (floating-ui placement).' }, { configKey: 'mobilePresentation', attribute: 'mobile-presentation', converter: toEnum(['auto', 'floating', 'fullscreen'] as const, { default: 'auto' }), reflect: true, on: 'update', description: 'How the open dropdown is presented on phones. `auto` (default) keeps the floating panel on desktop/tablet and switches to a full-screen overlay on phone-sized touch devices (touch primary + shorter viewport side < 600px, orientation-robust); `floating` forces the anchored panel everywhere; `fullscreen` forces the full-screen overlay on any device (handy for previews/testing). Resolved reactively from the device/viewport environment.' }, { configKey: 'fullscreenAutofocus', attribute: 'fullscreen-autofocus', converter: toBool('default-false'), on: 'update', description: 'In the phone fullscreen overlay, auto-focus the search field on open (pops the soft keyboard immediately). Default `false`: the sheet opens with the list visible and the keyboard closed, appearing only when the user taps the search. Set `true` to type-to-filter right away. No effect in the floating presentation.' }, // ── Numbers ────────────────────────────────────────────────────────────── { configKey: 'badgesThreshold', attribute: 'badges-threshold', converter: toInt(), on: 'update', description: 'Threshold at which badges collapse to a count/compact view.' }, { configKey: 'badgesMaxVisible', attribute: 'badges-max-visible', converter: toInt(), on: 'update', description: 'Maximum number of badges rendered before overflow.' }, { configKey: 'collapseBadgesBelow', attribute: 'collapse-badges-below', converter: toInt(), on: 'update', description: 'Container-responsive opt-in (off by default). When set to a px width, the control watches its OWN border box (not the window, via the core `resized` hook / a shared ResizeObserver) and collapses `badges-display-mode` to `count` (\"N selected\") while the box is narrower than this — so a picker in a narrow column/sidebar never overflows with pills, even on a wide monitor. Widening past the threshold restores the configured badges mode. Element-only: the override is applied to the live picker, never to your `badges-display-mode` config.' }, { configKey: 'minSearchLength', attribute: 'min-search-length', converter: toInt({ default: 0 }), on: 'update', description: 'Minimum characters before searching/filtering starts.' }, { configKey: 'searchDebounce', attribute: 'search-debounce', converter: toInt({ default: 0 }), on: 'update', description: 'Debounce delay in ms applied to the search input.' }, { configKey: 'virtualScrollThreshold', attribute: 'virtual-scroll-threshold', converter: toInt({ default: 100 }), on: 'reinit', description: 'Option count above which virtual scrolling turns on.' }, { configKey: 'optionHeight', attribute: 'option-height', converter: toInt({ default: 50 }), on: 'update', description: 'Fixed row height in px used by virtual scrolling.' }, { configKey: 'badgeHeight', attribute: 'badge-height', converter: toInt({ default: 36 }), on: 'update', description: 'Fixed badge height in px used for layout/virtualization.' }, { configKey: 'virtualScrollBuffer', attribute: 'virtual-scroll-buffer', converter: toInt({ default: 10 }), on: 'update', description: 'Extra rows rendered above/below the viewport when virtualizing.' }, { configKey: 'badgeTooltipDelay', attribute: 'badge-tooltip-delay', converter: toInt({ default: 100 }), on: 'update', description: 'Delay in ms before a badge tooltip appears.' }, { configKey: 'badgeTooltipOffset', attribute: 'badge-tooltip-offset', converter: toInt({ default: 8 }), on: 'update', description: 'Gap in px between a badge and its tooltip.' }, { configKey: 'optionTooltipDelay', attribute: 'option-tooltip-delay', converter: toInt(), on: 'update', description: 'Delay in ms before an option tooltip appears (falls back to badgeTooltipDelay).' }, { configKey: 'optionTooltipOffset', attribute: 'option-tooltip-offset', converter: toInt(), on: 'update', description: 'Gap in px between an option and its tooltip.' }, // ── Booleans (default true) ────────────────────────────────────────────── { configKey: 'isMultipleEnabled', attribute: 'multiple', converter: toBool('default-true'), on: 'reinit', description: 'Allow selecting multiple options. When off, selecting one replaces the previous.' }, { configKey: 'isGroupsAllowed', attribute: 'allow-groups', converter: toBool('default-true'), on: 'reinit', description: 'Allow grouping options under group headers.' }, { configKey: 'isCheckboxesShown', attribute: 'show-checkboxes', converter: toBool('default-true'), on: 'reinit', description: 'Show a checkbox on each option.' }, { configKey: 'isActionsSticky', attribute: 'sticky-actions', converter: toBool('default-true'), on: 'update', description: 'Keep the action bar pinned while the list scrolls.' }, { configKey: 'isPlacementLocked', attribute: 'lock-placement', converter: toBool('default-true'), on: 'update', description: 'Keep the dropdown initial placement instead of flipping when it fits.' }, { configKey: 'isSearchEnabled', attribute: 'enable-search', converter: toBool('default-true'), on: 'reinit', description: 'Show the search input.' }, { configKey: 'isKeepOptionsOnSearch', attribute: 'keep-options-on-search', converter: toBool('default-true'), on: 'update', description: 'Keep already-selected options visible while filtering.' }, { configKey: 'shouldKeepSearchOnClose', attribute: 'should-keep-search-on-close', converter: toBool('default-true'), on: 'update', description: 'Preserve the search text after the dropdown closes.' }, { configKey: 'isSelectedPopoverEnabled', attribute: 'enable-selected-popover', converter: toBool('default-true'), on: 'update', description: 'Allow the selected-items popover to open (from the count/compact/\"+X more\" badge or the in-input counter). Turn off when you render your own selection UI, so those affordances become inert.' }, // ── Booleans (default false) ───────────────────────────────────────────── { configKey: 'isCloseOnSelect', attribute: 'close-on-select', converter: toBool('default-false'), on: 'update', description: 'Close the dropdown immediately after a selection.' }, { configKey: 'isAddNewAllowed', attribute: 'allow-add-new', converter: toBool('default-false'), on: 'reinit', description: 'Allow adding a new option from the search text.' }, { configKey: 'isCounterShown', attribute: 'show-counter', converter: toBool('default-false'), on: 'update', description: 'Show a selected-count indicator.' }, { configKey: 'isClearShown', attribute: 'show-clear', converter: toBool('default-false'), on: 'update', description: 'Show an inline clear (✕) button inside the input that wipes the whole selection. Appears only while something is selected and the control is enabled; clicking it clears the selection and any search text, fires `change`, and refocuses.' }, { configKey: 'isBadgeFullTitleShown', attribute: 'show-badge-full-title', converter: toBool('default-false'), on: 'update', description: 'Show the full title on badges instead of the short label.' }, { configKey: 'isVirtualScrollEnabled', attribute: 'enable-virtual-scroll', converter: toBool('default-false'), on: 'reinit', description: 'Force virtual scrolling on regardless of the threshold.' }, { configKey: 'isBadgeTooltipsEnabled', attribute: 'enable-badge-tooltips', converter: toBool('default-false'), on: 'update', description: 'Enable tooltips on badges.' }, { configKey: 'isOptionTooltipsEnabled', attribute: 'enable-option-tooltips', converter: toBool('default-false'), on: 'update', description: 'Enable tooltips on options.' }, { configKey: 'isOptionTooltipFollowCursor', attribute: 'option-tooltip-follow-cursor', converter: toBool('default-false'), on: 'update', description: 'Make option tooltips follow the pointer.' }, { configKey: 'isSearchModeToggleShown', attribute: 'show-search-mode-toggle', converter: toBool('default-false'), on: 'update', description: 'Show a clickable toggle in the phone fullscreen overlay search header that flips `search-mode` between `filter` and `navigate` live. Fullscreen-only; no effect in the floating presentation or when search is disabled.' }, // ── Special attributes ─────────────────────────────────────────────────── { configKey: 'initialValues', attribute: 'initial-values', converter: toInitialValues(), default: [], on: 'reinit', type: 'Array<string | number>', description: 'Values selected on first render. Accepts a JSON array (`[\"a\",\"b\"]`) or a bare CSV (`a,b,c`).' }, { configKey: 'showDebugInfo', attribute: 'show-debug-info', converter: toBool('default-false'), on: 'update', description: 'Render an in-component debug panel.', deprecated: 'Use per-instance logging (el.enableLogging()) instead.' }, // ── Render gate (element-only; NON_PICKER) ─────────────────────────────── { configKey: 'deferRender', attribute: 'defer', converter: toBool('presence'), on: 'reinit', description: 'Hold the initial render. When the `defer` attribute is present on upgrade the component builds nothing (it only reserves space) — so options, callbacks (e.g. `customStylesCallback`) and event listeners can all be wired first, then released with `el.ready()` (or by removing the `defer` attribute, for server-driven frameworks). The release builds the picker ONCE with everything already in place, avoiding the upgrade-then-restyle flash. Absent (default): builds immediately on connect. Latched — once released the gate never re-closes.' }, // ── Complex property (data) ────────────────────────────────────────────── { configKey: 'options', converter: toObjectArray(), on: 'reinit', type: 'ReadonlyArray<Record<string, unknown>>', description: 'The array of option objects to render. The JS API — assign `el.options` directly. For HTML authoring use the `data-options` attribute (parsed per `data-options-format`) or declarative <option> children; both feed the same list and take precedence over this property in the order: <option> children > property > data-options.' }, { configKey: 'optionsSource', attribute: 'data-options', converter: toText({ isNullable: true }), on: 'reinit', type: 'string', description: 'HTML-authoring source for the option list, parsed per `data-options-format`. Reactive: changing either attribute re-renders. Prefer the `options` property in JS; a set `options` property and declarative <option> children both win over this.' }, { configKey: 'optionsFormat', attribute: 'data-options-format', converter: toEnum(OPTIONS_FORMATS, { default: 'json' }), on: 'reinit', type: \"'json' | 'csv' | 'plain'\", description: 'How to parse the `data-options` attribute: `json` (a JSON array of objects or [value, label] tuples), `csv` (rows split on `data-options-row-splitter`, cells on `data-options-splitter`; the first row is a header — map columns via *-member), or `plain` (bare values split on both splitters -> [value, label] tuples, value === label). Default `json`.' }, { configKey: 'optionsSplitter', attribute: 'data-options-splitter', converter: toText({ default: ',' }), on: 'reinit', type: 'string', description: 'Field/cell delimiter for the `csv` and `plain` `data-options` formats. Default `,`. Escapes `\\\\t` `\\\\n` `\\\\r` are honoured (e.g. `data-options-splitter=\"\\\\t\"` for TSV). Ignored for `json`.' }, { configKey: 'optionsRowSplitter', attribute: 'data-options-row-splitter', converter: toText({ default: '\\n' }), on: 'reinit', type: 'string', description: 'Row/record delimiter for the `csv` and `plain` `data-options` formats. Default newline. Escapes honoured (e.g. `data-options-row-splitter=\";\"` for single-line data). Ignored for `json`.' }, { configKey: 'actionButtons', converter: toValue({ validate: (v): v is unknown[] => Array.isArray(v) }), on: 'reinit', type: 'Array<Record<string, unknown>>', description: 'Custom action buttons for the dropdown footer/header. Property-only; when unset the default Select-All / Clear buttons apply.' }, // ── Callbacks: data shape (structural → reinit) ────────────────────────── { configKey: 'getValueCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string | number', description: 'Extract an option value (overrides valueMember).' }, { configKey: 'getPathCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string', description: 'Extract a node tree path (enables tree mode; overrides pathMember).' }, { configKey: 'getGroupCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string', description: 'Extract the group name from an option (overrides groupMember).' }, { configKey: 'getDisabledCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => boolean', description: 'Whether an option is disabled (overrides disabledMember).' }, { configKey: 'getIsSelectableCallback', converter: cb(), on: 'reinit', type: '(node: unknown) => boolean', description: 'Whether a tree node can be selected (overrides is-selectable-member).' }, { configKey: 'getSearchValueCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string', description: 'Text an option is searched against (overrides searchValueMember).' }, { configKey: 'searchCallback', converter: cb(), on: 'reinit', type: '(searchTerm: string, signal?: AbortSignal) => Promise<unknown[]>', description: 'Custom / async search; return the filtered options.' }, // ── Callbacks: display / render (cosmetic → update) ────────────────────── { configKey: 'getDisplayValueCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Compute the display label for an option (overrides displayValueMember).' }, { configKey: 'getBadgeDisplayCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Compute the text shown on an option badge.' }, { configKey: 'getBadgeClassCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | string[]', description: 'Extra CSS class(es) for an option badge.' }, { configKey: 'getIconCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Icon for an option (overrides iconMember).' }, { configKey: 'getSubtitleCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Subtitle for an option (overrides subtitleMember).' }, { configKey: 'getFullTitleCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Full title for an option (used by badges when show-badge-full-title is on).' }, { configKey: 'getCounterCallback', converter: cb(), on: 'update', type: '(count: number, moreCount?: number) => string', description: 'Render the selected-count label.' }, { configKey: 'getValueFormatCallback', converter: cb(), on: 'update', type: '(selectedValues: (string | number)[]) => string', description: 'Serialize the selected values for form submission.' }, { configKey: 'getBadgeTooltipCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | HTMLElement', description: 'Tooltip content for an option badge.' }, { configKey: 'getOptionTooltipCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | HTMLElement', description: 'Tooltip content for an option row.' }, { configKey: 'getRemoveButtonTooltipCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Tooltip text for a badge remove button.' }, { configKey: 'getSelectedItemClassCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | string[]', description: 'Extra CSS class(es) for a selected item.' }, { configKey: 'renderOptionContentCallback', converter: cb(), on: 'update', type: '(item: unknown, context: OptionContentRenderContext) => string | HTMLElement', description: 'Custom render for an option row; may return HTML or an element.' }, { configKey: 'renderBadgeContentCallback', converter: cb(), on: 'update', type: '(item: unknown, context: BadgeContentRenderContext) => string | HTMLElement', description: 'Custom render for a badge content (fills the built-in pill); may return HTML or an element.' }, { configKey: 'renderBadgeCallback', converter: cb(), on: 'update', type: '(item: unknown, context: BadgeContentRenderContext) => string | HTMLElement | null', description: 'Custom render for the WHOLE badge (main area), not just its content — return the entire pill/card. The component wraps it in `.ms__badge.ms__badge--custom` with `data-value` and delegates removal to any inner element with `data-action=\"remove\"` (or `.ms__badge-remove`). Return null/empty to fall back to the default pill for that item.' }, { configKey: 'renderGroupLabelContentCallback', converter: cb(), on: 'update', type: '(groupName: string) => string | HTMLElement', description: 'Customize a group label; may return an HTML string or element.' }, { configKey: 'renderSelectedContentCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Custom render for the whole selected area.' }, { configKey: 'renderSelectedItemContentCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | HTMLElement', description: 'Custom render for one selected item.' }, { configKey: 'customStylesCallback', converter: cb(), on: 'update', type: '() => string', description: 'Returns a CSS string injected into the component via a replaceable style slot (§12.8).' }, // ── Callbacks: before-hooks (behavior-shaping) ─────────────────────────── { configKey: 'beforeSearchCallback', converter: cb(), on: 'update', type: '(searchTerm: string) => string | null', description: 'Runs before a search; return a rewritten term or null to veto.' }, { configKey: 'beforeSelectCallback', converter: cb(), on: 'update', type: '(option: unknown, selectedOptions: unknown[]) => boolean | string | void', description: 'Runs before selecting; return false to veto, or a string to veto and show it as a message.' }, { configKey: 'beforeDeselectCallback', converter: cb(), on: 'update', type: '(option: unknown, selectedOptions: unknown[]) => boolean | string | void', description: 'Runs before deselecting; return false to veto, or a string to veto and show it as a message.' }, { configKey: 'addNewCallback', converter: cb(), on: 'update', type: '(value: string) => unknown | null | undefined | Promise<unknown | null | undefined>', description: 'Create a new option from the typed text. May return a rich option object (renders via the same get*/render* callbacks as any option). Async + cancelable: return null/undefined to abort (no add, no `add` event). Omit entirely to handle creation yourself via the `add` event.' }, { configKey: 'getAddNewTextCallback', converter: cb(), on: 'update', type: '(value: string) => string', description: 'Dynamically compute the \"add new\" prompt label from the typed text (returns plain text). Takes precedence over `add-new-text`.' }, { configKey: 'keydownCallback', converter: cb(), on: 'update', type: '(context: MultiSelectKeydownContext) => boolean | void', description: 'Intercept keydown before built-in handling; return true to suppress the default. Gets the event, current state, and an imperative controller.' }, ]",
              "type": {
                "text": "readonly InputDef[]"
              }
            },
            {
              "kind": "field",
              "name": "events",
              "privacy": "protected",
              "static": true,
              "default": "[ { name: 'select', description: 'An option was selected. `detail.option` is the selected option; `detail.selectedOptions`/`detail.selectedValues` are the full selection.' }, { name: 'deselect', description: 'An option was removed from the selection. `detail.option` is that option.' }, { name: 'change', description: 'The selection changed. `detail.selectedOptions`/`detail.selectedValues` are the full selection.' }, { name: 'add', description: 'The user chose to create a new option from the typed text (via the \"add new\" prompt or Enter) — requires `allow-add-new`. `detail.value` is the typed text; `detail.option` is the created item when `addNewCallback` produced one.' }, { name: 'ready', description: 'The picker was built and painted for the first time (once per element lifetime). Fires right after the first build — synchronously during upgrade for a normal element, or when the render gate is released (`el.ready()` / removing `defer`) for a deferred one. No detail.' }, ]",
              "type": {
                "text": "[\r\n  { name: 'select', description: 'An option was selected. `detail.option` is the selected option; `detail.selectedOptions`/`detail.selectedValues` are the full selection.' },\r\n  { name: 'deselect', description: 'An option was removed from the selection. `detail.option` is that option.' },\r\n  { name: 'change', description: 'The selection changed. `detail.selectedOptions`/`detail.selectedValues` are the full selection.' },\r\n  { name: 'add', description: 'The user chose to create a new option from the typed text (via the \"add new\" prompt or Enter) — requires `allow-add-new`. `detail.value` is the typed text; `detail.option` is the created item when `addNewCallback` produced one.' },\r\n  { name: 'ready', description: 'The picker was built and painted for the first time (once per element lifetime). Fires right after the first build — synchronously during upgrade for a normal element, or when the render gate is released (`el.ready()` / removing `defer`) for a deferred one. No detail.' },\r\n]"
              }
            },
            {
              "kind": "field",
              "name": "onSelect",
              "type": {
                "text": "((e: CustomEvent<MultiSelectEventDetail<T>>) => void) | null"
              }
            },
            {
              "kind": "field",
              "name": "onDeselect",
              "type": {
                "text": "((e: CustomEvent<MultiSelectEventDetail<T>>) => void) | null"
              }
            },
            {
              "kind": "field",
              "name": "onChange",
              "type": {
                "text": "((e: CustomEvent<MultiSelectEventDetail<T>>) => void) | null"
              }
            },
            {
              "kind": "field",
              "name": "onAdd",
              "type": {
                "text": "((e: CustomEvent<MultiSelectEventDetail<T>>) => void) | null"
              }
            },
            {
              "kind": "field",
              "name": "onReady",
              "type": {
                "text": "((e: CustomEvent<undefined>) => void) | null"
              }
            },
            {
              "kind": "field",
              "name": "#shadow",
              "privacy": "private",
              "type": {
                "text": "ShadowRoot"
              }
            },
            {
              "kind": "field",
              "name": "#picker",
              "privacy": "private",
              "type": {
                "text": "WebMultiSelect<T> | undefined"
              }
            },
            {
              "kind": "field",
              "name": "#container",
              "privacy": "private",
              "type": {
                "text": "HTMLDivElement | undefined"
              }
            },
            {
              "kind": "field",
              "name": "#released",
              "privacy": "private",
              "type": {
                "text": "boolean"
              },
              "default": "false"
            },
            {
              "kind": "field",
              "name": "#customStyles",
              "privacy": "private",
              "type": {
                "text": "StyleSlot | null"
              },
              "default": "null"
            },
            {
              "kind": "field",
              "name": "#warnedCssVars",
              "privacy": "private",
              "default": "new Set<string>()"
            },
            {
              "kind": "field",
              "name": "#declParsed",
              "privacy": "private",
              "type": {
                "text": "boolean"
              },
              "default": "false"
            },
            {
              "kind": "field",
              "name": "#hasDeclarativeOptions",
              "privacy": "private",
              "type": {
                "text": "boolean"
              },
              "default": "false"
            },
            {
              "kind": "field",
              "name": "#declarativeOptions",
              "privacy": "private",
              "type": {
                "text": "T[] | undefined"
              }
            },
            {
              "kind": "field",
              "name": "#declarativeSelectedValues",
              "privacy": "private",
              "type": {
                "text": "(string | number)[] | undefined"
              }
            },
            {
              "kind": "method",
              "name": "formResetCallback",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Called by the browser when the surrounding <form> is reset. Clears the\r\npicker's selection so the control participates in the standard reset."
            },
            {
              "kind": "method",
              "name": "directionChanged",
              "privacy": "protected",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "_isRTL",
                  "type": {
                    "text": "boolean"
                  }
                }
              ],
              "description": "Runtime writing-direction switch (core observes `dir`): re-mirror the live\r\npicker. Layout mostly follows the inherited `direction` (logical properties);\r\nrefreshDirection() fixes the parts pinned at build time (the `.ms--rtl` class\r\nand the panels' explicit `dir`). The initial direction is read by the build."
            },
            {
              "kind": "method",
              "name": "reinit",
              "privacy": "protected",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Structural change (or first connect): mirror CSS vars, then (re)build the picker."
            },
            {
              "kind": "method",
              "name": "update",
              "privacy": "protected",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "partial",
                  "type": {
                    "text": "Record<string, unknown>"
                  }
                }
              ],
              "description": "Cosmetic change: mirror CSS vars / custom styles / debug, patch the picker in place."
            },
            {
              "kind": "method",
              "name": "connect",
              "privacy": "protected",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Activate: ensure the picker exists (a DOM move destroyed it in disconnect())."
            },
            {
              "kind": "method",
              "name": "#renderHeld",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "description": "Whether the initial render is being held by the `defer` gate (not yet released)."
            },
            {
              "kind": "method",
              "name": "disconnect",
              "privacy": "protected",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Deactivate: tear the picker down (rebuilt on the next connect)."
            },
            {
              "kind": "method",
              "name": "environmentChanged",
              "privacy": "protected",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "env",
                  "type": {
                    "text": "EnvironmentSnapshot"
                  }
                }
              ],
              "description": "Device/viewport/orientation changed (core §12.9). Overriding this opts the\r\nelement into the shared environment observable — core subscribes on connect\r\n(firing immediately with the current snapshot) and unsubscribes on disconnect.\r\nWe map it to the picker's floating/fullscreen presentation; the immediate fire\r\nlands right after `connect()` builds the picker, so the initial presentation is\r\nset before the dropdown can open."
            },
            {
              "kind": "method",
              "name": "#applyPresentation",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "env",
                  "type": {
                    "text": "EnvironmentSnapshot"
                  }
                }
              ],
              "description": "Resolve `mobile-presentation` against `env` and relay it to the live picker."
            },
            {
              "kind": "field",
              "name": "#badgesCollapsed",
              "privacy": "private",
              "type": {
                "text": "boolean"
              },
              "default": "false",
              "description": "Whether the live picker is currently forced to the collapsed count view."
            },
            {
              "kind": "method",
              "name": "resized",
              "privacy": "protected",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "{ width }",
                  "type": {
                    "text": "ElementSize"
                  }
                }
              ],
              "description": "This element's own border box changed (core §12.9 `resized`). Overriding the\r\nhook opts us into a shared page-wide ResizeObserver, subscribed on connect and\r\ndropped on disconnect. Unlike `environmentChanged`/`viewportChanged` (the\r\nWINDOW), this is our OWN box — a picker in a 400px sidebar on a 2560px monitor\r\nreflows on its width, not the viewport's. We only act when `collapse-badges-\r\nbelow` is set; otherwise it's a cheap no-op."
            },
            {
              "kind": "method",
              "name": "#applyBadgeCollapse",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "width",
                  "type": {
                    "text": "number"
                  }
                }
              ],
              "description": "Resolve `collapse-badges-below` against `width` and relay the decision to the\r\nlive picker. The override is pushed via `updateOptions` (never written back to\r\n`this.config`), so `this.config.badgesDisplayMode` stays the consumer's truth\r\nand widening past the threshold restores it exactly. A structural JS decision,\r\nso it lives here rather than in a CSS container query."
            },
            {
              "kind": "method",
              "name": "#restoreBadgesMode",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Re-assert the consumer's configured badges mode from the pristine base config."
            },
            {
              "kind": "method",
              "name": "#pushBadgesMode",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "mode",
                  "type": {
                    "text": "MultiSelectConfig<T>['badgesDisplayMode']"
                  }
                }
              ],
              "description": "Relay a badges-display-mode override to the live picker (never written to `this.config`)."
            },
            {
              "kind": "method",
              "name": "#rebuildPicker",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "#buildPicker",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "#ensureContainer",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "#assembleConfig",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "Record<string, unknown>"
                }
              },
              "description": "Build the picker config from the merged `this.config`, minus the keys the\r\npicker doesn't own, plus the runtime wiring (event bridges, container, host,\r\ndeclarative option data + member defaults, counter default)."
            },
            {
              "kind": "method",
              "name": "#resolveInitialValues",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "(string | number)[] | undefined"
                }
              }
            },
            {
              "kind": "method",
              "name": "#collectSelectedValues",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "(string | number)[]"
                }
              }
            },
            {
              "kind": "method",
              "name": "#applyCustomStyles",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "#checkCustomStyleVars",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "css",
                  "type": {
                    "text": "string"
                  }
                }
              ],
              "description": "Dev-only lint: warn when `customStylesCallback` *sets* a `--ms-*` variable\r\nthat no web-multiselect style ever reads (`var(--ms-…)`) — a misspelled or\r\nrenamed variable fails silently otherwise (e.g. `--ms-badge-text-background`\r\ninstead of `--ms-badge-text-bg`). Guarded by `import.meta.env.DEV`, so it's\r\nstripped from the production build and never fires for shipped consumers.\r\nDe-duped per instance. If you genuinely define a `--ms-*` var for your own\r\ncustom-rendered content, ignore the warning (or use a different prefix)."
            },
            {
              "kind": "method",
              "name": "#mirrorAllCssVars",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "#mirrorCssVars",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "partial",
                  "type": {
                    "text": "Record<string, unknown>"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "#setVar",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "name",
                  "type": {
                    "text": "string"
                  }
                },
                {
                  "name": "value",
                  "type": {
                    "text": "unknown"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "#parseDeclarativeOptionsOnce",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "#parseDeclarativeOptions",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "any[] | null"
                }
              }
            },
            {
              "kind": "method",
              "name": "#syncDebugPanel",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "#updateDebugInfo",
              "privacy": "private",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "field",
              "name": "name",
              "type": {
                "text": "string | null"
              },
              "description": "Form field name (mirrors the `name` attribute → `formFieldId`)."
            },
            {
              "kind": "field",
              "name": "selectedValue",
              "type": {
                "text": "string | number | (string | number)[] | null"
              },
              "readonly": true
            },
            {
              "kind": "field",
              "name": "selectedItem",
              "type": {
                "text": "T | null"
              },
              "readonly": true
            },
            {
              "kind": "method",
              "name": "getSelected",
              "return": {
                "type": {
                  "text": "T[]"
                }
              }
            },
            {
              "kind": "method",
              "name": "setSelected",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "values",
                  "type": {
                    "text": "(string | number)[]"
                  }
                },
                {
                  "name": "opts",
                  "default": "{}",
                  "type": {
                    "text": "{ notify?: boolean }"
                  }
                }
              ]
            },
            {
              "kind": "method",
              "name": "getValue",
              "return": {
                "type": {
                  "text": "string | number | (string | number)[] | null"
                }
              }
            },
            {
              "kind": "method",
              "name": "showMessage",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "content",
                  "type": {
                    "text": "string | HTMLElement"
                  }
                },
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "MessageOptions"
                  }
                }
              ],
              "description": "Surface a transient message (\"toast\") on top of the component — visible even in the\r\nfullscreen overlay, where page-level UI is hidden behind the sheet. Content is text or\r\nan element; `opts.variant` sets the tone and `opts.duration` the auto-dismiss (0 =\r\nsticky). Also reached automatically when a `beforeSelect`/`beforeDeselect` callback\r\nreturns a reason string."
            },
            {
              "kind": "method",
              "name": "hideMessage",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Dismiss the transient message shown by showMessage, if any."
            },
            {
              "kind": "method",
              "name": "clearSearch",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Clear the search box and restore the full option list (does not touch the selection — use\r\nclearAll for that). Pair with scrollToValue to reveal then scroll to an option\r\na search had filtered out: `el.clearSearch(); el.scrollToValue(v)`."
            },
            {
              "kind": "field",
              "name": "searchText",
              "type": {
                "text": "string"
              },
              "description": "The current search box text (empty string when nothing is typed). Read via this getter, write with search.",
              "readonly": true
            },
            {
              "kind": "method",
              "name": "search",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "parameters": [
                {
                  "name": "term",
                  "type": {
                    "text": "string"
                  }
                }
              ],
              "description": "Programmatically set the search text and filter, as if the user typed it (runs\r\n`beforeSearchCallback` / `minSearchLength` / async `searchCallback`). Does not open the dropdown\r\n— call open if you want it visible. Pass `''` to clear (same as clearSearch)."
            },
            {
              "kind": "method",
              "name": "scrollToIndex",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "index",
                  "type": {
                    "text": "number"
                  }
                },
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "{ block?: ScrollLogicalPosition }"
                  }
                }
              ],
              "description": "Scroll the open dropdown to the option at `index` (into the current filtered list). Returns\r\nfalse if closed or out of range. Deferred internally so `el.open(); el.scrollToIndex(i)` works."
            },
            {
              "kind": "method",
              "name": "scrollToValue",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "value",
                  "type": {
                    "text": "string | number"
                  }
                },
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "{ block?: ScrollLogicalPosition }"
                  }
                }
              ],
              "description": "Scroll the open dropdown to the option with this `value`. Returns false if it isn't in the\r\ncurrently visible list (filtered out by search, or under a collapsed tree branch) — call\r\nclearSearch / expand first."
            },
            {
              "kind": "method",
              "name": "scrollToGroup",
              "return": {
                "type": {
                  "text": "boolean"
                }
              },
              "parameters": [
                {
                  "name": "name",
                  "type": {
                    "text": "string"
                  }
                },
                {
                  "name": "opts",
                  "optional": true,
                  "type": {
                    "text": "{ block?: ScrollLogicalPosition }"
                  }
                }
              ],
              "description": "Scroll to a group: its header in standard rendering, or the group's first option in\r\nvirtual-scroll mode (no headers there). Returns false in tree mode or if the group is empty\r\nin the current filtered list."
            },
            {
              "kind": "method",
              "name": "open",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Open the dropdown."
            },
            {
              "kind": "method",
              "name": "close",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Close the dropdown."
            },
            {
              "kind": "method",
              "name": "toggle",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Toggle the dropdown open/closed."
            },
            {
              "kind": "field",
              "name": "isOpen",
              "type": {
                "text": "boolean"
              },
              "description": "Whether the dropdown is currently open. Assigning opens/closes it."
            },
            {
              "kind": "method",
              "name": "destroy",
              "return": {
                "type": {
                  "text": "void"
                }
              }
            },
            {
              "kind": "method",
              "name": "ready",
              "return": {
                "type": {
                  "text": "void"
                }
              },
              "description": "Release the `defer` render gate: build the picker now (once), with every\r\noption, callback and listener wired while deferred already in place. No-op\r\nwhen the element wasn't deferred or is already built. `flush()` first so a\r\nsynchronous `el.options = …; el.customStylesCallback = …; el.ready()` lands\r\nthose pending writes in the single build rather than after it. Latched — the\r\ngate never re-closes. Fires the `ready` event on the first build."
            },
            {
              "kind": "field",
              "name": "isReady",
              "type": {
                "text": "boolean"
              },
              "description": "Whether the picker has been built (the `ready` event has fired). False while a `defer` gate is still held.",
              "readonly": true
            },
            {
              "kind": "field",
              "name": "searchHint",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "search-hint",
              "description": "Small hint text shown beneath the search input."
            },
            {
              "kind": "field",
              "name": "searchPlaceholder",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "search-placeholder",
              "description": "Placeholder text for the search input. When unset it defaults to \"Search...\"; if `show-search-mode-toggle` is on, the default instead becomes mode-aware (\"Search…\" in navigate, \"Filter…\" in filter). An explicit value always wins and stays fixed."
            },
            {
              "kind": "field",
              "name": "selectPlaceholder",
              "privacy": "public",
              "type": {
                "text": "string"
              },
              "default": "'Pick an option...'",
              "attribute": "select-placeholder",
              "description": "Placeholder shown on the control when nothing is selected."
            },
            {
              "kind": "field",
              "name": "noDataPlaceholder",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "no-data-placeholder",
              "description": "Text shown when there are no options at all."
            },
            {
              "kind": "field",
              "name": "dropdownMinWidth",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "dropdown-min-width",
              "description": "Minimum width of the dropdown panel (any CSS length)."
            },
            {
              "kind": "field",
              "name": "dropdownMaxWidth",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "dropdown-max-width",
              "description": "Maximum width of the dropdown panel (any CSS length)."
            },
            {
              "kind": "field",
              "name": "maxHeight",
              "privacy": "public",
              "type": {
                "text": "string"
              },
              "default": "'20rem'",
              "attribute": "max-height",
              "description": "Maximum height of the dropdown list before it scrolls."
            },
            {
              "kind": "field",
              "name": "emptyMessage",
              "privacy": "public",
              "type": {
                "text": "string"
              },
              "default": "'No results found'",
              "attribute": "empty-message",
              "description": "Message shown when a search yields no matches."
            },
            {
              "kind": "field",
              "name": "addNewText",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "add-new-text",
              "description": "Template for the clickable \"add new\" prompt shown (when `allow-add-new` is on) in place of the empty message once a search yields no matches. `{value}` is replaced with the typed text. Default: `Add \"{value}\"`. A `getAddNewTextCallback` wins."
            },
            {
              "kind": "field",
              "name": "addNewPendingText",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "add-new-pending-text",
              "description": "Template for the pending prompt (spinner + text) shown while an async `addNewCallback` runs. `{value}` is replaced with the typed text. Default: `Adding \"{value}\"…`."
            },
            {
              "kind": "field",
              "name": "loadingMessage",
              "privacy": "public",
              "type": {
                "text": "string"
              },
              "default": "'Loading...'",
              "attribute": "loading-message",
              "description": "Message shown while options are loading."
            },
            {
              "kind": "field",
              "name": "removeButtonTooltipText",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "remove-button-tooltip-text",
              "description": "Tooltip text for a badge remove (×) button."
            },
            {
              "kind": "field",
              "name": "formFieldId",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "name",
              "description": "HTML form field name/id used for the hidden input(s)."
            },
            {
              "kind": "field",
              "name": "dropdownWidth",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "dropdown-width",
              "description": "Fixed dropdown width; mirrored to the `--ms-dropdown-width` CSS variable."
            },
            {
              "kind": "field",
              "name": "selectedPopoverWidth",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "selected-popover-width",
              "description": "Selected-items popover width; mirrored to `--ms-selected-popover-width`."
            },
            {
              "kind": "field",
              "name": "valueMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "value-member",
              "reflects": true,
              "description": "Property name on an option object that holds its value."
            },
            {
              "kind": "field",
              "name": "displayValueMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "display-value-member",
              "reflects": true,
              "description": "Property name that holds an option display label."
            },
            {
              "kind": "field",
              "name": "searchValueMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "search-value-member",
              "reflects": true,
              "description": "Property name searched against (falls back to the display value)."
            },
            {
              "kind": "field",
              "name": "iconMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "icon-member",
              "reflects": true,
              "description": "Property name that holds an option icon."
            },
            {
              "kind": "field",
              "name": "subtitleMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "subtitle-member",
              "reflects": true,
              "description": "Property name that holds an option subtitle."
            },
            {
              "kind": "field",
              "name": "fullTitleMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "full-title-member",
              "reflects": true,
              "description": "Property name that holds an option full/long title."
            },
            {
              "kind": "field",
              "name": "groupMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "group-member",
              "reflects": true,
              "description": "Property name used to group options under headers."
            },
            {
              "kind": "field",
              "name": "disabledMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "disabled-member",
              "reflects": true,
              "description": "Property name that marks an option disabled."
            },
            {
              "kind": "field",
              "name": "pathMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "path-member",
              "reflects": true,
              "description": "Property name holding a node materialized tree path."
            },
            {
              "kind": "field",
              "name": "parentPathMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "parent-path-member",
              "reflects": true,
              "description": "Property name holding a node parent path."
            },
            {
              "kind": "field",
              "name": "levelMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "level-member",
              "reflects": true,
              "description": "Property name holding a node depth level."
            },
            {
              "kind": "field",
              "name": "hasChildrenMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "has-children-member",
              "reflects": true,
              "description": "Property name flagging that a node has children."
            },
            {
              "kind": "field",
              "name": "isSelectableMember",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "is-selectable-member",
              "reflects": true,
              "description": "Property name marking whether a node can be selected."
            },
            {
              "kind": "field",
              "name": "treePathSeparator",
              "privacy": "public",
              "type": {
                "text": "string"
              },
              "default": "'.'",
              "attribute": "tree-path-separator",
              "reflects": true,
              "description": "Separator between segments in a materialized tree path."
            },
            {
              "kind": "field",
              "name": "isTreeEnabled",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "description": "Force tree mode on/off. Property-only; when unset (null) tree mode auto-enables if a path source (path-member / getPathCallback) is present."
            },
            {
              "kind": "field",
              "name": "checkboxMode",
              "privacy": "public",
              "type": {
                "text": "'independent' | 'cascade'"
              },
              "default": "'independent'",
              "attribute": "checkbox-mode",
              "reflects": true,
              "description": "Tree checkbox interaction.\n- `independent` (default) — toggles only the clicked node.\n- `cascade` — checks a node whole subtree and shows a tristate (checked / indeterminate / unchecked) box on branches.\n\nTree + multiple only."
            },
            {
              "kind": "field",
              "name": "cascadeSelectPolicy",
              "privacy": "public",
              "type": {
                "text": "'rolled-up' | 'leaves' | 'all'"
              },
              "default": "'rolled-up'",
              "attribute": "cascade-select-policy",
              "reflects": true,
              "description": "In `cascade` mode, which values a selection emits (badges / form / change):\n- `rolled-up` (default) — minimal cover: a fully-selected subtree collapses to its root; partially-selected branches emit their individually-checked descendants.\n- `leaves` — only the checked leaf-level nodes.\n- `all` — every fully-checked node (branches and leaves)."
            },
            {
              "kind": "field",
              "name": "badgesDisplayMode",
              "privacy": "public",
              "type": {
                "text": "'badges' | 'count' | 'compact' | 'partial' | 'none'"
              },
              "default": "'badges'",
              "attribute": "badges-display-mode",
              "description": "How the current selection is shown in the control."
            },
            {
              "kind": "field",
              "name": "badgesPosition",
              "privacy": "public",
              "type": {
                "text": "'top' | 'bottom' | 'left' | 'right'"
              },
              "default": "'bottom'",
              "attribute": "badges-position",
              "description": "Where the badges/selection appear relative to the input."
            },
            {
              "kind": "field",
              "name": "badgesThresholdMode",
              "privacy": "public",
              "type": {
                "text": "'count' | 'partial'"
              },
              "default": "'count'",
              "attribute": "badges-threshold-mode",
              "description": "How `badgesThreshold` is interpreted: collapse to a count badge, or keep partial badges + a \"more\" badge."
            },
            {
              "kind": "field",
              "name": "searchInputMode",
              "privacy": "public",
              "type": {
                "text": "'normal' | 'readonly' | 'hidden'"
              },
              "default": "'normal'",
              "attribute": "search-input-mode",
              "description": "Search field mode: editable, read-only, or hidden."
            },
            {
              "kind": "field",
              "name": "searchMode",
              "privacy": "public",
              "type": {
                "text": "'filter' | 'navigate'"
              },
              "default": "'filter'",
              "attribute": "search-mode",
              "description": "Whether typing filters the list or navigates it."
            },
            {
              "kind": "field",
              "name": "overlayGroup",
              "privacy": "public",
              "type": {
                "text": "string | null"
              },
              "attribute": "overlay-group",
              "description": "Scope the \"one overlay open at a time\" coordination to a named group. Overlays (multiselects, datepickers, external popovers) sharing a group dismiss each other when one opens; different groups are independent. Unset = the default (ungrouped) group."
            },
            {
              "kind": "field",
              "name": "actionsLayout",
              "privacy": "public",
              "type": {
                "text": "'nowrap' | 'wrap'"
              },
              "default": "'nowrap'",
              "attribute": "actions-layout",
              "description": "Whether the action bar wraps or stays on one line."
            },
            {
              "kind": "field",
              "name": "actionsPosition",
              "privacy": "public",
              "type": {
                "text": "'top' | 'bottom'"
              },
              "default": "'top'",
              "attribute": "actions-position",
              "description": "Whether the action bar sits above or below the list."
            },
            {
              "kind": "field",
              "name": "actionsAlign",
              "privacy": "public",
              "type": {
                "text": "'stretch' | 'left' | 'right' | 'center' | 'space-between'"
              },
              "default": "'stretch'",
              "attribute": "actions-align",
              "description": "Horizontal alignment of the action buttons."
            },
            {
              "kind": "field",
              "name": "checkboxAlign",
              "privacy": "public",
              "type": {
                "text": "'top' | 'center' | 'bottom'"
              },
              "default": "'center'",
              "attribute": "checkbox-align",
              "description": "Vertical alignment of an option checkbox."
            },
            {
              "kind": "field",
              "name": "valueFormat",
              "privacy": "public",
              "type": {
                "text": "'json' | 'csv' | 'array'"
              },
              "default": "'json'",
              "attribute": "value-format",
              "description": "Serialization format the control emits its value in."
            },
            {
              "kind": "field",
              "name": "badgeTooltipPlacement",
              "privacy": "public",
              "type": {
                "text": "'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'"
              },
              "default": "'top'",
              "attribute": "badge-tooltip-placement",
              "description": "Preferred placement of a badge tooltip relative to its badge (floating-ui placement)."
            },
            {
              "kind": "field",
              "name": "optionTooltipPlacement",
              "privacy": "public",
              "type": {
                "text": "'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'"
              },
              "default": "'top-start'",
              "attribute": "option-tooltip-placement",
              "description": "Preferred placement of an option tooltip (floating-ui placement)."
            },
            {
              "kind": "field",
              "name": "mobilePresentation",
              "privacy": "public",
              "type": {
                "text": "'auto' | 'floating' | 'fullscreen'"
              },
              "default": "'auto'",
              "attribute": "mobile-presentation",
              "reflects": true,
              "description": "How the open dropdown is presented on phones. `auto` (default) keeps the floating panel on desktop/tablet and switches to a full-screen overlay on phone-sized touch devices (touch primary + shorter viewport side < 600px, orientation-robust); `floating` forces the anchored panel everywhere; `fullscreen` forces the full-screen overlay on any device (handy for previews/testing). Resolved reactively from the device/viewport environment."
            },
            {
              "kind": "field",
              "name": "fullscreenAutofocus",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "fullscreen-autofocus",
              "description": "In the phone fullscreen overlay, auto-focus the search field on open (pops the soft keyboard immediately). Default `false`: the sheet opens with the list visible and the keyboard closed, appearing only when the user taps the search. Set `true` to type-to-filter right away. No effect in the floating presentation."
            },
            {
              "kind": "field",
              "name": "badgesThreshold",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "attribute": "badges-threshold",
              "description": "Threshold at which badges collapse to a count/compact view."
            },
            {
              "kind": "field",
              "name": "badgesMaxVisible",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "attribute": "badges-max-visible",
              "description": "Maximum number of badges rendered before overflow."
            },
            {
              "kind": "field",
              "name": "collapseBadgesBelow",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "attribute": "collapse-badges-below",
              "description": "Container-responsive opt-in (off by default). When set to a px width, the control watches its OWN border box (not the window, via the core `resized` hook / a shared ResizeObserver) and collapses `badges-display-mode` to `count` (\"N selected\") while the box is narrower than this — so a picker in a narrow column/sidebar never overflows with pills, even on a wide monitor. Widening past the threshold restores the configured badges mode. Element-only: the override is applied to the live picker, never to your `badges-display-mode` config."
            },
            {
              "kind": "field",
              "name": "minSearchLength",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "default": "0",
              "attribute": "min-search-length",
              "description": "Minimum characters before searching/filtering starts."
            },
            {
              "kind": "field",
              "name": "searchDebounce",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "default": "0",
              "attribute": "search-debounce",
              "description": "Debounce delay in ms applied to the search input."
            },
            {
              "kind": "field",
              "name": "virtualScrollThreshold",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "default": "100",
              "attribute": "virtual-scroll-threshold",
              "description": "Option count above which virtual scrolling turns on."
            },
            {
              "kind": "field",
              "name": "optionHeight",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "default": "50",
              "attribute": "option-height",
              "description": "Fixed row height in px used by virtual scrolling."
            },
            {
              "kind": "field",
              "name": "badgeHeight",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "default": "36",
              "attribute": "badge-height",
              "description": "Fixed badge height in px used for layout/virtualization."
            },
            {
              "kind": "field",
              "name": "virtualScrollBuffer",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "default": "10",
              "attribute": "virtual-scroll-buffer",
              "description": "Extra rows rendered above/below the viewport when virtualizing."
            },
            {
              "kind": "field",
              "name": "badgeTooltipDelay",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "default": "100",
              "attribute": "badge-tooltip-delay",
              "description": "Delay in ms before a badge tooltip appears."
            },
            {
              "kind": "field",
              "name": "badgeTooltipOffset",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "default": "8",
              "attribute": "badge-tooltip-offset",
              "description": "Gap in px between a badge and its tooltip."
            },
            {
              "kind": "field",
              "name": "optionTooltipDelay",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "attribute": "option-tooltip-delay",
              "description": "Delay in ms before an option tooltip appears (falls back to badgeTooltipDelay)."
            },
            {
              "kind": "field",
              "name": "optionTooltipOffset",
              "privacy": "public",
              "type": {
                "text": "number"
              },
              "attribute": "option-tooltip-offset",
              "description": "Gap in px between an option and its tooltip."
            },
            {
              "kind": "field",
              "name": "isMultipleEnabled",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "multiple",
              "description": "Allow selecting multiple options. When off, selecting one replaces the previous."
            },
            {
              "kind": "field",
              "name": "isGroupsAllowed",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "allow-groups",
              "description": "Allow grouping options under group headers."
            },
            {
              "kind": "field",
              "name": "isCheckboxesShown",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "show-checkboxes",
              "description": "Show a checkbox on each option."
            },
            {
              "kind": "field",
              "name": "isActionsSticky",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "sticky-actions",
              "description": "Keep the action bar pinned while the list scrolls."
            },
            {
              "kind": "field",
              "name": "isPlacementLocked",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "lock-placement",
              "description": "Keep the dropdown initial placement instead of flipping when it fits."
            },
            {
              "kind": "field",
              "name": "isSearchEnabled",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "enable-search",
              "description": "Show the search input."
            },
            {
              "kind": "field",
              "name": "isKeepOptionsOnSearch",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "keep-options-on-search",
              "description": "Keep already-selected options visible while filtering."
            },
            {
              "kind": "field",
              "name": "shouldKeepSearchOnClose",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "should-keep-search-on-close",
              "description": "Preserve the search text after the dropdown closes."
            },
            {
              "kind": "field",
              "name": "isSelectedPopoverEnabled",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "enable-selected-popover",
              "description": "Allow the selected-items popover to open (from the count/compact/\"+X more\" badge or the in-input counter). Turn off when you render your own selection UI, so those affordances become inert."
            },
            {
              "kind": "field",
              "name": "isCloseOnSelect",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "close-on-select",
              "description": "Close the dropdown immediately after a selection."
            },
            {
              "kind": "field",
              "name": "isAddNewAllowed",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "allow-add-new",
              "description": "Allow adding a new option from the search text."
            },
            {
              "kind": "field",
              "name": "isCounterShown",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "show-counter",
              "description": "Show a selected-count indicator."
            },
            {
              "kind": "field",
              "name": "isClearShown",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "show-clear",
              "description": "Show an inline clear (✕) button inside the input that wipes the whole selection. Appears only while something is selected and the control is enabled; clicking it clears the selection and any search text, fires `change`, and refocuses."
            },
            {
              "kind": "field",
              "name": "isBadgeFullTitleShown",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "show-badge-full-title",
              "description": "Show the full title on badges instead of the short label."
            },
            {
              "kind": "field",
              "name": "isVirtualScrollEnabled",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "enable-virtual-scroll",
              "description": "Force virtual scrolling on regardless of the threshold."
            },
            {
              "kind": "field",
              "name": "isBadgeTooltipsEnabled",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "enable-badge-tooltips",
              "description": "Enable tooltips on badges."
            },
            {
              "kind": "field",
              "name": "isOptionTooltipsEnabled",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "enable-option-tooltips",
              "description": "Enable tooltips on options."
            },
            {
              "kind": "field",
              "name": "isOptionTooltipFollowCursor",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "option-tooltip-follow-cursor",
              "description": "Make option tooltips follow the pointer."
            },
            {
              "kind": "field",
              "name": "isSearchModeToggleShown",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "show-search-mode-toggle",
              "description": "Show a clickable toggle in the phone fullscreen overlay search header that flips `search-mode` between `filter` and `navigate` live. Fullscreen-only; no effect in the floating presentation or when search is disabled."
            },
            {
              "kind": "field",
              "name": "initialValues",
              "privacy": "public",
              "type": {
                "text": "Array<string | number>"
              },
              "default": "[]",
              "attribute": "initial-values",
              "description": "Values selected on first render. Accepts a JSON array (`[\"a\",\"b\"]`) or a bare CSV (`a,b,c`)."
            },
            {
              "kind": "field",
              "name": "showDebugInfo",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "show-debug-info",
              "description": "Render an in-component debug panel.",
              "deprecated": "Use per-instance logging (el.enableLogging()) instead."
            },
            {
              "kind": "field",
              "name": "deferRender",
              "privacy": "public",
              "type": {
                "text": "boolean"
              },
              "attribute": "defer",
              "description": "Hold the initial render. When the `defer` attribute is present on upgrade the component builds nothing (it only reserves space) — so options, callbacks (e.g. `customStylesCallback`) and event listeners can all be wired first, then released with `el.ready()` (or by removing the `defer` attribute, for server-driven frameworks). The release builds the picker ONCE with everything already in place, avoiding the upgrade-then-restyle flash. Absent (default): builds immediately on connect. Latched — once released the gate never re-closes."
            },
            {
              "kind": "field",
              "name": "options",
              "privacy": "public",
              "type": {
                "text": "ReadonlyArray<Record<string, unknown>>"
              },
              "description": "The array of option objects to render. The JS API — assign `el.options` directly. For HTML authoring use the `data-options` attribute (parsed per `data-options-format`) or declarative <option> children; both feed the same list and take precedence over this property in the order: <option> children > property > data-options."
            },
            {
              "kind": "field",
              "name": "optionsSource",
              "privacy": "public",
              "type": {
                "text": "string"
              },
              "attribute": "data-options",
              "description": "HTML-authoring source for the option list, parsed per `data-options-format`. Reactive: changing either attribute re-renders. Prefer the `options` property in JS; a set `options` property and declarative <option> children both win over this."
            },
            {
              "kind": "field",
              "name": "optionsFormat",
              "privacy": "public",
              "type": {
                "text": "'json' | 'csv' | 'plain'"
              },
              "default": "'json'",
              "attribute": "data-options-format",
              "description": "How to parse the `data-options` attribute: `json` (a JSON array of objects or [value, label] tuples), `csv` (rows split on `data-options-row-splitter`, cells on `data-options-splitter`; the first row is a header — map columns via *-member), or `plain` (bare values split on both splitters -> [value, label] tuples, value === label). Default `json`."
            },
            {
              "kind": "field",
              "name": "optionsSplitter",
              "privacy": "public",
              "type": {
                "text": "string"
              },
              "default": "','",
              "attribute": "data-options-splitter",
              "description": "Field/cell delimiter for the `csv` and `plain` `data-options` formats. Default `,`. Escapes `\\t` `\\n` `\\r` are honoured (e.g. `data-options-splitter=\"\\t\"` for TSV). Ignored for `json`."
            },
            {
              "kind": "field",
              "name": "optionsRowSplitter",
              "privacy": "public",
              "type": {
                "text": "string"
              },
              "default": "'\\n'",
              "attribute": "data-options-row-splitter",
              "description": "Row/record delimiter for the `csv` and `plain` `data-options` formats. Default newline. Escapes honoured (e.g. `data-options-row-splitter=\";\"` for single-line data). Ignored for `json`."
            },
            {
              "kind": "field",
              "name": "actionButtons",
              "privacy": "public",
              "type": {
                "text": "Array<Record<string, unknown>>"
              },
              "description": "Custom action buttons for the dropdown footer/header. Property-only; when unset the default Select-All / Clear buttons apply."
            },
            {
              "kind": "field",
              "name": "getValueCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string | number"
              },
              "description": "Extract an option value (overrides valueMember)."
            },
            {
              "kind": "field",
              "name": "getPathCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string"
              },
              "description": "Extract a node tree path (enables tree mode; overrides pathMember)."
            },
            {
              "kind": "field",
              "name": "getGroupCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string"
              },
              "description": "Extract the group name from an option (overrides groupMember)."
            },
            {
              "kind": "field",
              "name": "getDisabledCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => boolean"
              },
              "description": "Whether an option is disabled (overrides disabledMember)."
            },
            {
              "kind": "field",
              "name": "getIsSelectableCallback",
              "privacy": "public",
              "type": {
                "text": "(node: unknown) => boolean"
              },
              "description": "Whether a tree node can be selected (overrides is-selectable-member)."
            },
            {
              "kind": "field",
              "name": "getSearchValueCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string"
              },
              "description": "Text an option is searched against (overrides searchValueMember)."
            },
            {
              "kind": "field",
              "name": "searchCallback",
              "privacy": "public",
              "type": {
                "text": "(searchTerm: string, signal?: AbortSignal) => Promise<unknown[]>"
              },
              "description": "Custom / async search; return the filtered options."
            },
            {
              "kind": "field",
              "name": "getDisplayValueCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string"
              },
              "description": "Compute the display label for an option (overrides displayValueMember)."
            },
            {
              "kind": "field",
              "name": "getBadgeDisplayCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string"
              },
              "description": "Compute the text shown on an option badge."
            },
            {
              "kind": "field",
              "name": "getBadgeClassCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string | string[]"
              },
              "description": "Extra CSS class(es) for an option badge."
            },
            {
              "kind": "field",
              "name": "getIconCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string"
              },
              "description": "Icon for an option (overrides iconMember)."
            },
            {
              "kind": "field",
              "name": "getSubtitleCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string"
              },
              "description": "Subtitle for an option (overrides subtitleMember)."
            },
            {
              "kind": "field",
              "name": "getFullTitleCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string"
              },
              "description": "Full title for an option (used by badges when show-badge-full-title is on)."
            },
            {
              "kind": "field",
              "name": "getCounterCallback",
              "privacy": "public",
              "type": {
                "text": "(count: number, moreCount?: number) => string"
              },
              "description": "Render the selected-count label."
            },
            {
              "kind": "field",
              "name": "getValueFormatCallback",
              "privacy": "public",
              "type": {
                "text": "(selectedValues: (string | number)[]) => string"
              },
              "description": "Serialize the selected values for form submission."
            },
            {
              "kind": "field",
              "name": "getBadgeTooltipCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string | HTMLElement"
              },
              "description": "Tooltip content for an option badge."
            },
            {
              "kind": "field",
              "name": "getOptionTooltipCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string | HTMLElement"
              },
              "description": "Tooltip content for an option row."
            },
            {
              "kind": "field",
              "name": "getRemoveButtonTooltipCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string"
              },
              "description": "Tooltip text for a badge remove button."
            },
            {
              "kind": "field",
              "name": "getSelectedItemClassCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string | string[]"
              },
              "description": "Extra CSS class(es) for a selected item."
            },
            {
              "kind": "field",
              "name": "renderOptionContentCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown, context: OptionContentRenderContext) => string | HTMLElement"
              },
              "description": "Custom render for an option row; may return HTML or an element."
            },
            {
              "kind": "field",
              "name": "renderBadgeContentCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown, context: BadgeContentRenderContext) => string | HTMLElement"
              },
              "description": "Custom render for a badge content (fills the built-in pill); may return HTML or an element."
            },
            {
              "kind": "field",
              "name": "renderBadgeCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown, context: BadgeContentRenderContext) => string | HTMLElement | null"
              },
              "description": "Custom render for the WHOLE badge (main area), not just its content — return the entire pill/card. The component wraps it in `.ms__badge.ms__badge--custom` with `data-value` and delegates removal to any inner element with `data-action=\"remove\"` (or `.ms__badge-remove`). Return null/empty to fall back to the default pill for that item."
            },
            {
              "kind": "field",
              "name": "renderGroupLabelContentCallback",
              "privacy": "public",
              "type": {
                "text": "(groupName: string) => string | HTMLElement"
              },
              "description": "Customize a group label; may return an HTML string or element."
            },
            {
              "kind": "field",
              "name": "renderSelectedContentCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string"
              },
              "description": "Custom render for the whole selected area."
            },
            {
              "kind": "field",
              "name": "renderSelectedItemContentCallback",
              "privacy": "public",
              "type": {
                "text": "(item: unknown) => string | HTMLElement"
              },
              "description": "Custom render for one selected item."
            },
            {
              "kind": "field",
              "name": "customStylesCallback",
              "privacy": "public",
              "type": {
                "text": "() => string"
              },
              "description": "Returns a CSS string injected into the component via a replaceable style slot (§12.8)."
            },
            {
              "kind": "field",
              "name": "beforeSearchCallback",
              "privacy": "public",
              "type": {
                "text": "(searchTerm: string) => string | null"
              },
              "description": "Runs before a search; return a rewritten term or null to veto."
            },
            {
              "kind": "field",
              "name": "beforeSelectCallback",
              "privacy": "public",
              "type": {
                "text": "(option: unknown, selectedOptions: unknown[]) => boolean | string | void"
              },
              "description": "Runs before selecting; return false to veto, or a string to veto and show it as a message."
            },
            {
              "kind": "field",
              "name": "beforeDeselectCallback",
              "privacy": "public",
              "type": {
                "text": "(option: unknown, selectedOptions: unknown[]) => boolean | string | void"
              },
              "description": "Runs before deselecting; return false to veto, or a string to veto and show it as a message."
            },
            {
              "kind": "field",
              "name": "addNewCallback",
              "privacy": "public",
              "type": {
                "text": "(value: string) => unknown | null | undefined | Promise<unknown | null | undefined>"
              },
              "description": "Create a new option from the typed text. May return a rich option object (renders via the same get*/render* callbacks as any option). Async + cancelable: return null/undefined to abort (no add, no `add` event). Omit entirely to handle creation yourself via the `add` event."
            },
            {
              "kind": "field",
              "name": "getAddNewTextCallback",
              "privacy": "public",
              "type": {
                "text": "(value: string) => string"
              },
              "description": "Dynamically compute the \"add new\" prompt label from the typed text (returns plain text). Takes precedence over `add-new-text`."
            },
            {
              "kind": "field",
              "name": "keydownCallback",
              "privacy": "public",
              "type": {
                "text": "(context: MultiSelectKeydownContext) => boolean | void"
              },
              "description": "Intercept keydown before built-in handling; return true to suppress the default. Gets the event, current state, and an imperative controller."
            }
          ],
          "superclass": {
            "name": "BlissElement",
            "package": "@keenmate/web-components-core"
          },
          "attributes": [
            {
              "name": "search-hint",
              "fieldName": "searchHint",
              "type": {
                "text": "string | null"
              },
              "description": "Small hint text shown beneath the search input."
            },
            {
              "name": "search-placeholder",
              "fieldName": "searchPlaceholder",
              "type": {
                "text": "string | null"
              },
              "description": "Placeholder text for the search input. When unset it defaults to \"Search...\"; if `show-search-mode-toggle` is on, the default instead becomes mode-aware (\"Search…\" in navigate, \"Filter…\" in filter). An explicit value always wins and stays fixed."
            },
            {
              "name": "select-placeholder",
              "fieldName": "selectPlaceholder",
              "type": {
                "text": "string"
              },
              "default": "'Pick an option...'",
              "description": "Placeholder shown on the control when nothing is selected."
            },
            {
              "name": "no-data-placeholder",
              "fieldName": "noDataPlaceholder",
              "type": {
                "text": "string | null"
              },
              "description": "Text shown when there are no options at all."
            },
            {
              "name": "dropdown-min-width",
              "fieldName": "dropdownMinWidth",
              "type": {
                "text": "string | null"
              },
              "description": "Minimum width of the dropdown panel (any CSS length)."
            },
            {
              "name": "dropdown-max-width",
              "fieldName": "dropdownMaxWidth",
              "type": {
                "text": "string | null"
              },
              "description": "Maximum width of the dropdown panel (any CSS length)."
            },
            {
              "name": "max-height",
              "fieldName": "maxHeight",
              "type": {
                "text": "string"
              },
              "default": "'20rem'",
              "description": "Maximum height of the dropdown list before it scrolls."
            },
            {
              "name": "empty-message",
              "fieldName": "emptyMessage",
              "type": {
                "text": "string"
              },
              "default": "'No results found'",
              "description": "Message shown when a search yields no matches."
            },
            {
              "name": "add-new-text",
              "fieldName": "addNewText",
              "type": {
                "text": "string | null"
              },
              "description": "Template for the clickable \"add new\" prompt shown (when `allow-add-new` is on) in place of the empty message once a search yields no matches. `{value}` is replaced with the typed text. Default: `Add \"{value}\"`. A `getAddNewTextCallback` wins."
            },
            {
              "name": "add-new-pending-text",
              "fieldName": "addNewPendingText",
              "type": {
                "text": "string | null"
              },
              "description": "Template for the pending prompt (spinner + text) shown while an async `addNewCallback` runs. `{value}` is replaced with the typed text. Default: `Adding \"{value}\"…`."
            },
            {
              "name": "loading-message",
              "fieldName": "loadingMessage",
              "type": {
                "text": "string"
              },
              "default": "'Loading...'",
              "description": "Message shown while options are loading."
            },
            {
              "name": "remove-button-tooltip-text",
              "fieldName": "removeButtonTooltipText",
              "type": {
                "text": "string | null"
              },
              "description": "Tooltip text for a badge remove (×) button."
            },
            {
              "name": "name",
              "fieldName": "formFieldId",
              "type": {
                "text": "string | null"
              },
              "description": "HTML form field name/id used for the hidden input(s)."
            },
            {
              "name": "dropdown-width",
              "fieldName": "dropdownWidth",
              "type": {
                "text": "string | null"
              },
              "description": "Fixed dropdown width; mirrored to the `--ms-dropdown-width` CSS variable."
            },
            {
              "name": "selected-popover-width",
              "fieldName": "selectedPopoverWidth",
              "type": {
                "text": "string | null"
              },
              "description": "Selected-items popover width; mirrored to `--ms-selected-popover-width`."
            },
            {
              "name": "value-member",
              "fieldName": "valueMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name on an option object that holds its value."
            },
            {
              "name": "display-value-member",
              "fieldName": "displayValueMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name that holds an option display label."
            },
            {
              "name": "search-value-member",
              "fieldName": "searchValueMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name searched against (falls back to the display value)."
            },
            {
              "name": "icon-member",
              "fieldName": "iconMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name that holds an option icon."
            },
            {
              "name": "subtitle-member",
              "fieldName": "subtitleMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name that holds an option subtitle."
            },
            {
              "name": "full-title-member",
              "fieldName": "fullTitleMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name that holds an option full/long title."
            },
            {
              "name": "group-member",
              "fieldName": "groupMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name used to group options under headers."
            },
            {
              "name": "disabled-member",
              "fieldName": "disabledMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name that marks an option disabled."
            },
            {
              "name": "path-member",
              "fieldName": "pathMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name holding a node materialized tree path."
            },
            {
              "name": "parent-path-member",
              "fieldName": "parentPathMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name holding a node parent path."
            },
            {
              "name": "level-member",
              "fieldName": "levelMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name holding a node depth level."
            },
            {
              "name": "has-children-member",
              "fieldName": "hasChildrenMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name flagging that a node has children."
            },
            {
              "name": "is-selectable-member",
              "fieldName": "isSelectableMember",
              "type": {
                "text": "string | null"
              },
              "description": "Property name marking whether a node can be selected."
            },
            {
              "name": "tree-path-separator",
              "fieldName": "treePathSeparator",
              "type": {
                "text": "string"
              },
              "default": "'.'",
              "description": "Separator between segments in a materialized tree path."
            },
            {
              "name": "checkbox-mode",
              "fieldName": "checkboxMode",
              "type": {
                "text": "'independent' | 'cascade'"
              },
              "default": "'independent'",
              "description": "Tree checkbox interaction.\n- `independent` (default) — toggles only the clicked node.\n- `cascade` — checks a node whole subtree and shows a tristate (checked / indeterminate / unchecked) box on branches.\n\nTree + multiple only."
            },
            {
              "name": "cascade-select-policy",
              "fieldName": "cascadeSelectPolicy",
              "type": {
                "text": "'rolled-up' | 'leaves' | 'all'"
              },
              "default": "'rolled-up'",
              "description": "In `cascade` mode, which values a selection emits (badges / form / change):\n- `rolled-up` (default) — minimal cover: a fully-selected subtree collapses to its root; partially-selected branches emit their individually-checked descendants.\n- `leaves` — only the checked leaf-level nodes.\n- `all` — every fully-checked node (branches and leaves)."
            },
            {
              "name": "badges-display-mode",
              "fieldName": "badgesDisplayMode",
              "type": {
                "text": "'badges' | 'count' | 'compact' | 'partial' | 'none'"
              },
              "default": "'badges'",
              "description": "How the current selection is shown in the control."
            },
            {
              "name": "badges-position",
              "fieldName": "badgesPosition",
              "type": {
                "text": "'top' | 'bottom' | 'left' | 'right'"
              },
              "default": "'bottom'",
              "description": "Where the badges/selection appear relative to the input."
            },
            {
              "name": "badges-threshold-mode",
              "fieldName": "badgesThresholdMode",
              "type": {
                "text": "'count' | 'partial'"
              },
              "default": "'count'",
              "description": "How `badgesThreshold` is interpreted: collapse to a count badge, or keep partial badges + a \"more\" badge."
            },
            {
              "name": "search-input-mode",
              "fieldName": "searchInputMode",
              "type": {
                "text": "'normal' | 'readonly' | 'hidden'"
              },
              "default": "'normal'",
              "description": "Search field mode: editable, read-only, or hidden."
            },
            {
              "name": "search-mode",
              "fieldName": "searchMode",
              "type": {
                "text": "'filter' | 'navigate'"
              },
              "default": "'filter'",
              "description": "Whether typing filters the list or navigates it."
            },
            {
              "name": "overlay-group",
              "fieldName": "overlayGroup",
              "type": {
                "text": "string | null"
              },
              "description": "Scope the \"one overlay open at a time\" coordination to a named group. Overlays (multiselects, datepickers, external popovers) sharing a group dismiss each other when one opens; different groups are independent. Unset = the default (ungrouped) group."
            },
            {
              "name": "actions-layout",
              "fieldName": "actionsLayout",
              "type": {
                "text": "'nowrap' | 'wrap'"
              },
              "default": "'nowrap'",
              "description": "Whether the action bar wraps or stays on one line."
            },
            {
              "name": "actions-position",
              "fieldName": "actionsPosition",
              "type": {
                "text": "'top' | 'bottom'"
              },
              "default": "'top'",
              "description": "Whether the action bar sits above or below the list."
            },
            {
              "name": "actions-align",
              "fieldName": "actionsAlign",
              "type": {
                "text": "'stretch' | 'left' | 'right' | 'center' | 'space-between'"
              },
              "default": "'stretch'",
              "description": "Horizontal alignment of the action buttons."
            },
            {
              "name": "checkbox-align",
              "fieldName": "checkboxAlign",
              "type": {
                "text": "'top' | 'center' | 'bottom'"
              },
              "default": "'center'",
              "description": "Vertical alignment of an option checkbox."
            },
            {
              "name": "value-format",
              "fieldName": "valueFormat",
              "type": {
                "text": "'json' | 'csv' | 'array'"
              },
              "default": "'json'",
              "description": "Serialization format the control emits its value in."
            },
            {
              "name": "badge-tooltip-placement",
              "fieldName": "badgeTooltipPlacement",
              "type": {
                "text": "'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'"
              },
              "default": "'top'",
              "description": "Preferred placement of a badge tooltip relative to its badge (floating-ui placement)."
            },
            {
              "name": "option-tooltip-placement",
              "fieldName": "optionTooltipPlacement",
              "type": {
                "text": "'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'"
              },
              "default": "'top-start'",
              "description": "Preferred placement of an option tooltip (floating-ui placement)."
            },
            {
              "name": "mobile-presentation",
              "fieldName": "mobilePresentation",
              "type": {
                "text": "'auto' | 'floating' | 'fullscreen'"
              },
              "default": "'auto'",
              "description": "How the open dropdown is presented on phones. `auto` (default) keeps the floating panel on desktop/tablet and switches to a full-screen overlay on phone-sized touch devices (touch primary + shorter viewport side < 600px, orientation-robust); `floating` forces the anchored panel everywhere; `fullscreen` forces the full-screen overlay on any device (handy for previews/testing). Resolved reactively from the device/viewport environment."
            },
            {
              "name": "fullscreen-autofocus",
              "fieldName": "fullscreenAutofocus",
              "type": {
                "text": "boolean"
              },
              "description": "In the phone fullscreen overlay, auto-focus the search field on open (pops the soft keyboard immediately). Default `false`: the sheet opens with the list visible and the keyboard closed, appearing only when the user taps the search. Set `true` to type-to-filter right away. No effect in the floating presentation."
            },
            {
              "name": "badges-threshold",
              "fieldName": "badgesThreshold",
              "type": {
                "text": "number"
              },
              "description": "Threshold at which badges collapse to a count/compact view."
            },
            {
              "name": "badges-max-visible",
              "fieldName": "badgesMaxVisible",
              "type": {
                "text": "number"
              },
              "description": "Maximum number of badges rendered before overflow."
            },
            {
              "name": "collapse-badges-below",
              "fieldName": "collapseBadgesBelow",
              "type": {
                "text": "number"
              },
              "description": "Container-responsive opt-in (off by default). When set to a px width, the control watches its OWN border box (not the window, via the core `resized` hook / a shared ResizeObserver) and collapses `badges-display-mode` to `count` (\"N selected\") while the box is narrower than this — so a picker in a narrow column/sidebar never overflows with pills, even on a wide monitor. Widening past the threshold restores the configured badges mode. Element-only: the override is applied to the live picker, never to your `badges-display-mode` config."
            },
            {
              "name": "min-search-length",
              "fieldName": "minSearchLength",
              "type": {
                "text": "number"
              },
              "default": "0",
              "description": "Minimum characters before searching/filtering starts."
            },
            {
              "name": "search-debounce",
              "fieldName": "searchDebounce",
              "type": {
                "text": "number"
              },
              "default": "0",
              "description": "Debounce delay in ms applied to the search input."
            },
            {
              "name": "virtual-scroll-threshold",
              "fieldName": "virtualScrollThreshold",
              "type": {
                "text": "number"
              },
              "default": "100",
              "description": "Option count above which virtual scrolling turns on."
            },
            {
              "name": "option-height",
              "fieldName": "optionHeight",
              "type": {
                "text": "number"
              },
              "default": "50",
              "description": "Fixed row height in px used by virtual scrolling."
            },
            {
              "name": "badge-height",
              "fieldName": "badgeHeight",
              "type": {
                "text": "number"
              },
              "default": "36",
              "description": "Fixed badge height in px used for layout/virtualization."
            },
            {
              "name": "virtual-scroll-buffer",
              "fieldName": "virtualScrollBuffer",
              "type": {
                "text": "number"
              },
              "default": "10",
              "description": "Extra rows rendered above/below the viewport when virtualizing."
            },
            {
              "name": "badge-tooltip-delay",
              "fieldName": "badgeTooltipDelay",
              "type": {
                "text": "number"
              },
              "default": "100",
              "description": "Delay in ms before a badge tooltip appears."
            },
            {
              "name": "badge-tooltip-offset",
              "fieldName": "badgeTooltipOffset",
              "type": {
                "text": "number"
              },
              "default": "8",
              "description": "Gap in px between a badge and its tooltip."
            },
            {
              "name": "option-tooltip-delay",
              "fieldName": "optionTooltipDelay",
              "type": {
                "text": "number"
              },
              "description": "Delay in ms before an option tooltip appears (falls back to badgeTooltipDelay)."
            },
            {
              "name": "option-tooltip-offset",
              "fieldName": "optionTooltipOffset",
              "type": {
                "text": "number"
              },
              "description": "Gap in px between an option and its tooltip."
            },
            {
              "name": "multiple",
              "fieldName": "isMultipleEnabled",
              "type": {
                "text": "boolean"
              },
              "description": "Allow selecting multiple options. When off, selecting one replaces the previous."
            },
            {
              "name": "allow-groups",
              "fieldName": "isGroupsAllowed",
              "type": {
                "text": "boolean"
              },
              "description": "Allow grouping options under group headers."
            },
            {
              "name": "show-checkboxes",
              "fieldName": "isCheckboxesShown",
              "type": {
                "text": "boolean"
              },
              "description": "Show a checkbox on each option."
            },
            {
              "name": "sticky-actions",
              "fieldName": "isActionsSticky",
              "type": {
                "text": "boolean"
              },
              "description": "Keep the action bar pinned while the list scrolls."
            },
            {
              "name": "lock-placement",
              "fieldName": "isPlacementLocked",
              "type": {
                "text": "boolean"
              },
              "description": "Keep the dropdown initial placement instead of flipping when it fits."
            },
            {
              "name": "enable-search",
              "fieldName": "isSearchEnabled",
              "type": {
                "text": "boolean"
              },
              "description": "Show the search input."
            },
            {
              "name": "keep-options-on-search",
              "fieldName": "isKeepOptionsOnSearch",
              "type": {
                "text": "boolean"
              },
              "description": "Keep already-selected options visible while filtering."
            },
            {
              "name": "should-keep-search-on-close",
              "fieldName": "shouldKeepSearchOnClose",
              "type": {
                "text": "boolean"
              },
              "description": "Preserve the search text after the dropdown closes."
            },
            {
              "name": "enable-selected-popover",
              "fieldName": "isSelectedPopoverEnabled",
              "type": {
                "text": "boolean"
              },
              "description": "Allow the selected-items popover to open (from the count/compact/\"+X more\" badge or the in-input counter). Turn off when you render your own selection UI, so those affordances become inert."
            },
            {
              "name": "close-on-select",
              "fieldName": "isCloseOnSelect",
              "type": {
                "text": "boolean"
              },
              "description": "Close the dropdown immediately after a selection."
            },
            {
              "name": "allow-add-new",
              "fieldName": "isAddNewAllowed",
              "type": {
                "text": "boolean"
              },
              "description": "Allow adding a new option from the search text."
            },
            {
              "name": "show-counter",
              "fieldName": "isCounterShown",
              "type": {
                "text": "boolean"
              },
              "description": "Show a selected-count indicator."
            },
            {
              "name": "show-clear",
              "fieldName": "isClearShown",
              "type": {
                "text": "boolean"
              },
              "description": "Show an inline clear (✕) button inside the input that wipes the whole selection. Appears only while something is selected and the control is enabled; clicking it clears the selection and any search text, fires `change`, and refocuses."
            },
            {
              "name": "show-badge-full-title",
              "fieldName": "isBadgeFullTitleShown",
              "type": {
                "text": "boolean"
              },
              "description": "Show the full title on badges instead of the short label."
            },
            {
              "name": "enable-virtual-scroll",
              "fieldName": "isVirtualScrollEnabled",
              "type": {
                "text": "boolean"
              },
              "description": "Force virtual scrolling on regardless of the threshold."
            },
            {
              "name": "enable-badge-tooltips",
              "fieldName": "isBadgeTooltipsEnabled",
              "type": {
                "text": "boolean"
              },
              "description": "Enable tooltips on badges."
            },
            {
              "name": "enable-option-tooltips",
              "fieldName": "isOptionTooltipsEnabled",
              "type": {
                "text": "boolean"
              },
              "description": "Enable tooltips on options."
            },
            {
              "name": "option-tooltip-follow-cursor",
              "fieldName": "isOptionTooltipFollowCursor",
              "type": {
                "text": "boolean"
              },
              "description": "Make option tooltips follow the pointer."
            },
            {
              "name": "show-search-mode-toggle",
              "fieldName": "isSearchModeToggleShown",
              "type": {
                "text": "boolean"
              },
              "description": "Show a clickable toggle in the phone fullscreen overlay search header that flips `search-mode` between `filter` and `navigate` live. Fullscreen-only; no effect in the floating presentation or when search is disabled."
            },
            {
              "name": "initial-values",
              "fieldName": "initialValues",
              "type": {
                "text": "Array<string | number>"
              },
              "default": "[]",
              "description": "Values selected on first render. Accepts a JSON array (`[\"a\",\"b\"]`) or a bare CSV (`a,b,c`)."
            },
            {
              "name": "show-debug-info",
              "fieldName": "showDebugInfo",
              "type": {
                "text": "boolean"
              },
              "description": "Render an in-component debug panel.",
              "deprecated": "Use per-instance logging (el.enableLogging()) instead."
            },
            {
              "name": "defer",
              "fieldName": "deferRender",
              "type": {
                "text": "boolean"
              },
              "description": "Hold the initial render. When the `defer` attribute is present on upgrade the component builds nothing (it only reserves space) — so options, callbacks (e.g. `customStylesCallback`) and event listeners can all be wired first, then released with `el.ready()` (or by removing the `defer` attribute, for server-driven frameworks). The release builds the picker ONCE with everything already in place, avoiding the upgrade-then-restyle flash. Absent (default): builds immediately on connect. Latched — once released the gate never re-closes."
            },
            {
              "name": "data-options",
              "fieldName": "optionsSource",
              "type": {
                "text": "string"
              },
              "description": "HTML-authoring source for the option list, parsed per `data-options-format`. Reactive: changing either attribute re-renders. Prefer the `options` property in JS; a set `options` property and declarative <option> children both win over this."
            },
            {
              "name": "data-options-format",
              "fieldName": "optionsFormat",
              "type": {
                "text": "'json' | 'csv' | 'plain'"
              },
              "default": "'json'",
              "description": "How to parse the `data-options` attribute: `json` (a JSON array of objects or [value, label] tuples), `csv` (rows split on `data-options-row-splitter`, cells on `data-options-splitter`; the first row is a header — map columns via *-member), or `plain` (bare values split on both splitters -> [value, label] tuples, value === label). Default `json`."
            },
            {
              "name": "data-options-splitter",
              "fieldName": "optionsSplitter",
              "type": {
                "text": "string"
              },
              "default": "','",
              "description": "Field/cell delimiter for the `csv` and `plain` `data-options` formats. Default `,`. Escapes `\\t` `\\n` `\\r` are honoured (e.g. `data-options-splitter=\"\\t\"` for TSV). Ignored for `json`."
            },
            {
              "name": "data-options-row-splitter",
              "fieldName": "optionsRowSplitter",
              "type": {
                "text": "string"
              },
              "default": "'\\n'",
              "description": "Row/record delimiter for the `csv` and `plain` `data-options` formats. Default newline. Escapes honoured (e.g. `data-options-row-splitter=\";\"` for single-line data). Ignored for `json`."
            }
          ],
          "events": [
            {
              "name": "select",
              "description": "An option was selected. `detail.option` is the selected option; `detail.selectedOptions`/`detail.selectedValues` are the full selection."
            },
            {
              "name": "deselect",
              "description": "An option was removed from the selection. `detail.option` is that option."
            },
            {
              "name": "change",
              "description": "The selection changed. `detail.selectedOptions`/`detail.selectedValues` are the full selection."
            },
            {
              "name": "add",
              "description": "The user chose to create a new option from the typed text (via the \"add new\" prompt or Enter) — requires `allow-add-new`. `detail.value` is the typed text; `detail.option` is the created item when `addNewCallback` produced one."
            },
            {
              "name": "ready",
              "description": "The picker was built and painted for the first time (once per element lifetime). Fires right after the first build — synchronously during upgrade for a normal element, or when the render gate is released (`el.ready()` / removing `defer`) for a deferred one. No detail."
            }
          ],
          "tagName": "web-multiselect",
          "customElement": true,
          "cssProperties": [
            {
              "name": "--ms-rem",
              "description": "Base sizing unit for proportional scaling (default: 10px)"
            },
            {
              "name": "--ms-accent-color",
              "description": "Primary accent color"
            },
            {
              "name": "--ms-accent-color-hover",
              "description": "Accent color on hover"
            },
            {
              "name": "--ms-accent-color-active",
              "description": "Accent color when pressed"
            },
            {
              "name": "--ms-accent-color-light",
              "description": "Light accent background"
            },
            {
              "name": "--ms-accent-color-light-hover",
              "description": "Light accent hover"
            },
            {
              "name": "--ms-text-color-1",
              "description": "Primary text color"
            },
            {
              "name": "--ms-text-color-2",
              "description": "Secondary text color"
            },
            {
              "name": "--ms-text-color-3",
              "description": "Tertiary text color"
            },
            {
              "name": "--ms-text-color-4",
              "description": "Quaternary text color"
            },
            {
              "name": "--ms-text-color-on-accent",
              "description": "Text on accent backgrounds"
            },
            {
              "name": "--ms-text-primary",
              "description": "Legacy alias for text-color-1"
            },
            {
              "name": "--ms-text-secondary",
              "description": "Legacy alias for text-color-3"
            },
            {
              "name": "--ms-primary-bg",
              "description": "Hover/focus background (options, action buttons, counter); reads --base-hover-bg"
            },
            {
              "name": "--ms-primary-bg-hover",
              "description": "Active/stronger background (counter badge text); reads --base-active-bg"
            },
            {
              "name": "--ms-border-color",
              "description": "Default border color"
            },
            {
              "name": "--ms-border",
              "description": "Full border shorthand"
            },
            {
              "name": "--ms-input-bg",
              "description": "Input field background"
            },
            {
              "name": "--ms-input-color",
              "description": "Input text color"
            },
            {
              "name": "--ms-input-border",
              "description": "Input border"
            },
            {
              "name": "--ms-input-border-hover",
              "description": "Input border on hover"
            },
            {
              "name": "--ms-input-border-focus",
              "description": "Input border when focused"
            },
            {
              "name": "--ms-input-placeholder-color",
              "description": "Placeholder text color"
            },
            {
              "name": "--ms-input-bg-disabled",
              "description": "Disabled input background"
            },
            {
              "name": "--ms-input-height",
              "description": "Input height"
            },
            {
              "name": "--ms-input-font-size",
              "description": "Input font size"
            },
            {
              "name": "--ms-input-border-width",
              "description": "Input border width"
            },
            {
              "name": "--ms-input-border-radius",
              "description": "Input border radius"
            },
            {
              "name": "--ms-input-text",
              "description": "Input text color"
            },
            {
              "name": "--ms-toggle-color",
              "description": "Toggle icon color"
            },
            {
              "name": "--ms-toggle-icon-color",
              "description": "Toggle icon color (semantic)"
            },
            {
              "name": "--ms-toggle-icon-color-open",
              "description": "Toggle icon color when open"
            },
            {
              "name": "--ms-counter-padding",
              "description": "Counter badge padding"
            },
            {
              "name": "--ms-counter-bg",
              "description": "Counter badge background"
            },
            {
              "name": "--ms-counter-color",
              "description": "Counter badge text color"
            },
            {
              "name": "--ms-counter-font-size",
              "description": "Counter badge font size"
            },
            {
              "name": "--ms-counter-font-weight",
              "description": "Counter badge font weight"
            },
            {
              "name": "--ms-counter-border-radius",
              "description": "Counter badge border radius"
            },
            {
              "name": "--ms-counter-bg-hover",
              "description": "Counter badge hover background"
            },
            {
              "name": "--ms-counter-badge-bg",
              "description": "Counter badge semantic background"
            },
            {
              "name": "--ms-counter-badge-bg-hover",
              "description": "Counter badge semantic hover"
            },
            {
              "name": "--ms-counter-badge-color",
              "description": "Counter badge semantic color"
            },
            {
              "name": "--ms-hint-padding",
              "description": "Floating hint padding"
            },
            {
              "name": "--ms-hint-border",
              "description": "Floating hint border"
            },
            {
              "name": "--ms-hint-border-radius",
              "description": "Floating hint border radius"
            },
            {
              "name": "--ms-hint-box-shadow",
              "description": "Floating hint shadow"
            },
            {
              "name": "--ms-hint-font-size",
              "description": "Floating hint font size"
            },
            {
              "name": "--ms-hint-bg",
              "description": "Floating hint background"
            },
            {
              "name": "--ms-hint-color",
              "description": "Floating hint text color"
            },
            {
              "name": "--ms-hint-border-color",
              "description": "Floating hint border color"
            },
            {
              "name": "--ms-dropdown-bg",
              "description": "Dropdown background"
            },
            {
              "name": "--ms-dropdown-text-color",
              "description": "Dropdown text color"
            },
            {
              "name": "--ms-dropdown-border",
              "description": "Dropdown border"
            },
            {
              "name": "--ms-dropdown-border-color",
              "description": "Dropdown border color"
            },
            {
              "name": "--ms-dropdown-border-radius",
              "description": "Dropdown border radius"
            },
            {
              "name": "--ms-dropdown-box-shadow",
              "description": "Dropdown shadow"
            },
            {
              "name": "--ms-dropdown-box-shadow-semantic",
              "description": "Dropdown semantic shadow"
            },
            {
              "name": "--ms-dropdown-width",
              "description": "Options dropdown width (defaults to the input width; also set via the dropdown-width attribute)"
            },
            {
              "name": "--ms-options-max-height",
              "description": "Options list max height"
            },
            {
              "name": "--ms-z-index-dropdown",
              "description": "Dropdown z-index"
            },
            {
              "name": "--ms-z-index-sticky",
              "description": "Sticky elements z-index"
            },
            {
              "name": "--ms-actions-gap",
              "description": "Actions row gap"
            },
            {
              "name": "--ms-actions-padding",
              "description": "Actions row padding"
            },
            {
              "name": "--ms-actions-border-bottom",
              "description": "Actions row border"
            },
            {
              "name": "--ms-actions-bg",
              "description": "Actions row background"
            },
            {
              "name": "--ms-actions-border-color",
              "description": "Actions row border color"
            },
            {
              "name": "--ms-action-btn-padding",
              "description": "Action button padding"
            },
            {
              "name": "--ms-action-btn-font-size",
              "description": "Action button font size"
            },
            {
              "name": "--ms-action-btn-border",
              "description": "Action button border"
            },
            {
              "name": "--ms-action-btn-border-radius",
              "description": "Action button border radius"
            },
            {
              "name": "--ms-action-btn-bg",
              "description": "Action button background"
            },
            {
              "name": "--ms-action-btn-color",
              "description": "Action button color"
            },
            {
              "name": "--ms-action-btn-bg-hover",
              "description": "Action button hover background"
            },
            {
              "name": "--ms-action-btn-border-color-hover",
              "description": "Action button hover border"
            },
            {
              "name": "--ms-action-button-bg",
              "description": "Semantic action button background"
            },
            {
              "name": "--ms-action-button-bg-hover",
              "description": "Semantic action button hover"
            },
            {
              "name": "--ms-action-button-border-color",
              "description": "Semantic action button border"
            },
            {
              "name": "--ms-action-button-border-color-hover",
              "description": "Semantic action button hover border"
            },
            {
              "name": "--ms-action-button-color",
              "description": "Semantic action button color"
            },
            {
              "name": "--ms-options-padding",
              "description": "Options container padding"
            },
            {
              "name": "--ms-group-border-top",
              "description": "Group border top"
            },
            {
              "name": "--ms-group-margin-top",
              "description": "Group margin top"
            },
            {
              "name": "--ms-group-padding-top",
              "description": "Group padding top"
            },
            {
              "name": "--ms-group-border-color",
              "description": "Group border color"
            },
            {
              "name": "--ms-group-label-padding",
              "description": "Group label padding"
            },
            {
              "name": "--ms-group-label-font-size",
              "description": "Group label font size"
            },
            {
              "name": "--ms-group-label-font-weight",
              "description": "Group label font weight"
            },
            {
              "name": "--ms-group-label-color",
              "description": "Group label color"
            },
            {
              "name": "--ms-group-label-transform",
              "description": "Group label text transform"
            },
            {
              "name": "--ms-group-label-letter-spacing",
              "description": "Group label letter spacing"
            },
            {
              "name": "--ms-option-gap",
              "description": "Option content gap"
            },
            {
              "name": "--ms-option-padding",
              "description": "Option padding"
            },
            {
              "name": "--ms-option-padding-h",
              "description": "Option horizontal padding"
            },
            {
              "name": "--ms-option-color",
              "description": "Option text color"
            },
            {
              "name": "--ms-option-bg",
              "description": "Option background"
            },
            {
              "name": "--ms-option-bg-hover",
              "description": "Option hover background"
            },
            {
              "name": "--ms-option-bg-focused",
              "description": "Option focused background"
            },
            {
              "name": "--ms-option-outline-focused",
              "description": "Option focus outline"
            },
            {
              "name": "--ms-option-focus-outline-offset",
              "description": "Option focus outline offset"
            },
            {
              "name": "--ms-option-bg-matched",
              "description": "Matched option background"
            },
            {
              "name": "--ms-option-border-matched",
              "description": "Matched option border"
            },
            {
              "name": "--ms-option-bg-selected",
              "description": "Selected option background"
            },
            {
              "name": "--ms-option-text-color",
              "description": "Option text color (semantic)"
            },
            {
              "name": "--ms-option-color-hover",
              "description": "Option hover color"
            },
            {
              "name": "--ms-option-color-focused",
              "description": "Option focused color"
            },
            {
              "name": "--ms-option-outline-color-focused",
              "description": "Option focus outline color"
            },
            {
              "name": "--ms-option-color-matched",
              "description": "Matched option color"
            },
            {
              "name": "--ms-option-border-matched-color",
              "description": "Matched option border color"
            },
            {
              "name": "--ms-option-bg-focused-hover",
              "description": "Focused option hover background"
            },
            {
              "name": "--ms-option-bg-matched-hover",
              "description": "Matched option hover background"
            },
            {
              "name": "--ms-option-bg-selected-focused",
              "description": "Selected focused background"
            },
            {
              "name": "--ms-option-bg-selected-matched",
              "description": "Selected matched background"
            },
            {
              "name": "--ms-option-disabled-bg",
              "description": "Disabled option background"
            },
            {
              "name": "--ms-option-bg-disabled-selected",
              "description": "Disabled selected background"
            },
            {
              "name": "--ms-disabled-opacity",
              "description": "Disabled option opacity"
            },
            {
              "name": "--ms-option-content-gap",
              "description": "Option content gap"
            },
            {
              "name": "--ms-option-icon-size",
              "description": "Option icon size"
            },
            {
              "name": "--ms-option-icon-font-size",
              "description": "Option icon font size"
            },
            {
              "name": "--ms-option-title-font-size",
              "description": "Option title font size"
            },
            {
              "name": "--ms-option-title-color",
              "description": "Option title color"
            },
            {
              "name": "--ms-option-subtitle-margin-top",
              "description": "Option subtitle margin"
            },
            {
              "name": "--ms-option-subtitle-font-size",
              "description": "Option subtitle font size"
            },
            {
              "name": "--ms-option-subtitle-line-height",
              "description": "Option subtitle line height"
            },
            {
              "name": "--ms-option-subtitle-color",
              "description": "Option subtitle color"
            },
            {
              "name": "--ms-option-mark-bg",
              "description": "Search match highlight background"
            },
            {
              "name": "--ms-option-mark-color",
              "description": "Search match highlight color"
            },
            {
              "name": "--ms-option-mark-font-weight",
              "description": "Search match highlight weight"
            },
            {
              "name": "--ms-checkbox-margin-top",
              "description": "Checkbox margin top"
            },
            {
              "name": "--ms-checkbox-margin-right",
              "description": "Checkbox margin right"
            },
            {
              "name": "--ms-checkbox-margin-bottom",
              "description": "Checkbox margin bottom"
            },
            {
              "name": "--ms-checkbox-margin-left",
              "description": "Checkbox margin left"
            },
            {
              "name": "--ms-checkbox-size",
              "description": "Checkbox size"
            },
            {
              "name": "--ms-checkbox-scale",
              "description": "Checkbox scale"
            },
            {
              "name": "--ms-checkbox-align",
              "description": "Checkbox alignment"
            },
            {
              "name": "--ms-checkbox-bg",
              "description": "Checkbox background"
            },
            {
              "name": "--ms-checkbox-border",
              "description": "Checkbox border"
            },
            {
              "name": "--ms-checkbox-border-radius",
              "description": "Checkbox border radius"
            },
            {
              "name": "--ms-checkbox-checked-bg",
              "description": "Checked checkbox background"
            },
            {
              "name": "--ms-checkbox-checked-border",
              "description": "Checked checkbox border"
            },
            {
              "name": "--ms-checkbox-checkmark-color",
              "description": "Checkmark color"
            },
            {
              "name": "--ms-checkbox-hover-border-color",
              "description": "Checkbox hover border"
            },
            {
              "name": "--ms-checkbox-disabled-bg",
              "description": "Disabled checkbox background"
            },
            {
              "name": "--ms-checkbox-disabled-border",
              "description": "Disabled checkbox border"
            },
            {
              "name": "--ms-checkbox-checked-bg-hover",
              "description": "Checked checkbox hover background"
            },
            {
              "name": "--ms-checkbox-checked-border-color-hover",
              "description": "Checked checkbox hover border"
            },
            {
              "name": "--ms-state-min-height",
              "description": "Shared min-height for the empty and loading states so the dropdown doesn't resize when swapping between them"
            },
            {
              "name": "--ms-empty-padding",
              "description": "Empty state padding"
            },
            {
              "name": "--ms-empty-font-size",
              "description": "Empty state font size"
            },
            {
              "name": "--ms-empty-color",
              "description": "Empty state text color"
            },
            {
              "name": "--ms-loader-padding",
              "description": "Loader padding"
            },
            {
              "name": "--ms-loader-gap",
              "description": "Loader gap"
            },
            {
              "name": "--ms-loading-text-font-size",
              "description": "Loading text font size"
            },
            {
              "name": "--ms-loading-text-color",
              "description": "Loading text color"
            },
            {
              "name": "--ms-loading-color",
              "description": "Loading color (semantic)"
            },
            {
              "name": "--ms-badges-gap",
              "description": "Badges container gap"
            },
            {
              "name": "--ms-badges-margin-bottom",
              "description": "Badges margin bottom"
            },
            {
              "name": "--ms-badges-margin-top",
              "description": "Badges margin top"
            },
            {
              "name": "--ms-badges-margin-left",
              "description": "Badges margin left"
            },
            {
              "name": "--ms-badges-margin-right",
              "description": "Badges margin right"
            },
            {
              "name": "--ms-badge-gap",
              "description": "Badge internal gap"
            },
            {
              "name": "--ms-badge-height",
              "description": "Badge height"
            },
            {
              "name": "--ms-badge-font-size",
              "description": "Badge font size"
            },
            {
              "name": "--ms-badge-font-weight",
              "description": "Badge font weight"
            },
            {
              "name": "--ms-badge-border-radius",
              "description": "Badge border radius"
            },
            {
              "name": "--ms-badge-bg",
              "description": "Badge background"
            },
            {
              "name": "--ms-badge-bg-hover",
              "description": "Badge hover background"
            },
            {
              "name": "--ms-badge-bg-active",
              "description": "Badge active background"
            },
            {
              "name": "--ms-badge-text-padding",
              "description": "Badge text padding"
            },
            {
              "name": "--ms-badge-text-bg",
              "description": "Badge text background"
            },
            {
              "name": "--ms-badge-text-color",
              "description": "Badge text color"
            },
            {
              "name": "--ms-badge-text-border",
              "description": "Badge text border"
            },
            {
              "name": "--ms-badge-text-bg-hover",
              "description": "Badge text hover background"
            },
            {
              "name": "--ms-badge-text-color-hover",
              "description": "Badge text hover color"
            },
            {
              "name": "--ms-badge-remove-width",
              "description": "Badge remove button width"
            },
            {
              "name": "--ms-badge-remove-bg",
              "description": "Badge remove button background"
            },
            {
              "name": "--ms-badge-remove-color",
              "description": "Badge remove button color"
            },
            {
              "name": "--ms-badge-remove-border",
              "description": "Badge remove button border"
            },
            {
              "name": "--ms-badge-remove-font-size",
              "description": "Badge remove button font size (unused since 1.10.0 — kept for backward-compat)"
            },
            {
              "name": "--ms-badge-remove-icon-size",
              "description": "Badge remove X icon size (mask SVG)"
            },
            {
              "name": "--ms-badge-remove-bg-hover",
              "description": "Badge remove button hover background"
            },
            {
              "name": "--ms-badge-remove-box-shadow-focus",
              "description": "Badge remove button focus shadow"
            },
            {
              "name": "--ms-icon-remove",
              "description": "Remove icon as CSS url() to a mask-friendly SVG; color comes from currentColor"
            },
            {
              "name": "--ms-icon-filter",
              "description": "Funnel glyph (fullscreen search-mode toggle); chains to --base-icon-filter"
            },
            {
              "name": "--ms-icon-check",
              "description": "Checkmark glyph (mask) for a checked checkbox/option; chains to --base-icon-check"
            },
            {
              "name": "--ms-icon-indeterminate",
              "description": "Dash glyph (mask) for a tri-state/partial checkbox; chains to --base-icon-indeterminate"
            },
            {
              "name": "--ms-icon-check-size",
              "description": "mask-size for the checkmark/dash glyph inside the checkbox box; chains to --base-icon-check-size (default 68%, the same knob as pure-admin's .pa-checkbox)"
            },
            {
              "name": "--ms-badge-counter-bg",
              "description": "Counter badge background"
            },
            {
              "name": "--ms-badge-counter-border",
              "description": "Counter badge border"
            },
            {
              "name": "--ms-badge-counter-border-color",
              "description": "Counter badge border color"
            },
            {
              "name": "--ms-badge-counter-border-radius",
              "description": "Counter badge border radius"
            },
            {
              "name": "--ms-badge-counter-text-color",
              "description": "Counter badge text color"
            },
            {
              "name": "--ms-badge-counter-text-bg",
              "description": "Counter badge text background"
            },
            {
              "name": "--ms-badge-counter-remove-bg",
              "description": "Counter badge remove background"
            },
            {
              "name": "--ms-badge-counter-remove-color",
              "description": "Counter badge remove color"
            },
            {
              "name": "--ms-badge-counter-remove-bg-hover",
              "description": "Counter badge remove hover background"
            },
            {
              "name": "--ms-more-badge-bg",
              "description": "More badge background"
            },
            {
              "name": "--ms-more-badge-hover-bg",
              "description": "More badge hover background"
            },
            {
              "name": "--ms-more-badge-active-bg",
              "description": "More badge active background"
            },
            {
              "name": "--ms-count-display-margin-bottom",
              "description": "Count display margin bottom"
            },
            {
              "name": "--ms-count-display-margin-top",
              "description": "Count display margin top"
            },
            {
              "name": "--ms-count-display-margin-left",
              "description": "Count display margin left"
            },
            {
              "name": "--ms-count-display-margin-right",
              "description": "Count display margin right"
            },
            {
              "name": "--ms-counter-wrapper-bg",
              "description": "Counter wrapper background"
            },
            {
              "name": "--ms-counter-wrapper-border",
              "description": "Counter wrapper border"
            },
            {
              "name": "--ms-counter-wrapper-border-radius",
              "description": "Counter wrapper border radius"
            },
            {
              "name": "--ms-counter-wrapper-padding",
              "description": "Counter wrapper padding"
            },
            {
              "name": "--ms-counter-wrapper-gap",
              "description": "Counter wrapper gap"
            },
            {
              "name": "--ms-counter-wrapper-bg-hover",
              "description": "Counter wrapper hover background"
            },
            {
              "name": "--ms-counter-wrapper-border-color",
              "description": "Counter wrapper border color"
            },
            {
              "name": "--ms-counter-wrapper-border-color-hover",
              "description": "Counter wrapper hover border"
            },
            {
              "name": "--ms-count-text-bg",
              "description": "Count text background"
            },
            {
              "name": "--ms-count-text-border",
              "description": "Count text border"
            },
            {
              "name": "--ms-count-text-font-size",
              "description": "Count text font size"
            },
            {
              "name": "--ms-count-text-color",
              "description": "Count text color"
            },
            {
              "name": "--ms-count-clear-size",
              "description": "Count clear button size"
            },
            {
              "name": "--ms-count-clear-bg",
              "description": "Count clear button background"
            },
            {
              "name": "--ms-count-clear-color",
              "description": "Count clear button color"
            },
            {
              "name": "--ms-count-clear-font-size",
              "description": "Count clear button font size (unused since 1.10.0 — kept for backward-compat)"
            },
            {
              "name": "--ms-count-clear-icon-size",
              "description": "Count clear X icon size (mask SVG)"
            },
            {
              "name": "--ms-count-clear-border-radius",
              "description": "Count clear button border radius"
            },
            {
              "name": "--ms-count-clear-bg-hover",
              "description": "Count clear button hover background"
            },
            {
              "name": "--ms-count-clear-color-hover",
              "description": "Count clear button hover color"
            },
            {
              "name": "--ms-icon-clear",
              "description": "Clear icon as CSS url() to a mask-friendly SVG; defaults to var(--ms-icon-remove)"
            },
            {
              "name": "--ms-tooltip-bg",
              "description": "Tooltip background"
            },
            {
              "name": "--ms-tooltip-text-color",
              "description": "Tooltip text color"
            },
            {
              "name": "--ms-tooltip-color",
              "description": "Tooltip color"
            },
            {
              "name": "--ms-tooltip-padding",
              "description": "Tooltip padding"
            },
            {
              "name": "--ms-tooltip-border-radius",
              "description": "Tooltip border radius"
            },
            {
              "name": "--ms-tooltip-font-size",
              "description": "Tooltip font size"
            },
            {
              "name": "--ms-tooltip-max-width",
              "description": "Tooltip max width"
            },
            {
              "name": "--ms-tooltip-shadow",
              "description": "Tooltip shadow"
            },
            {
              "name": "--ms-tooltip-z-index",
              "description": "Tooltip z-index"
            },
            {
              "name": "--ms-z-index-popover",
              "description": "Popover z-index"
            },
            {
              "name": "--ms-selected-popover-width",
              "description": "Selected popover width"
            },
            {
              "name": "--ms-selected-popover-max-height",
              "description": "Selected popover max height"
            },
            {
              "name": "--ms-selected-popover-border",
              "description": "Selected popover border"
            },
            {
              "name": "--ms-selected-popover-border-radius",
              "description": "Selected popover border radius"
            },
            {
              "name": "--ms-selected-popover-box-shadow",
              "description": "Selected popover shadow"
            },
            {
              "name": "--ms-selected-popover-bg",
              "description": "Selected popover background"
            },
            {
              "name": "--ms-selected-popover-border-color",
              "description": "Selected popover border color"
            },
            {
              "name": "--ms-selected-popover-header-padding",
              "description": "Popover header padding"
            },
            {
              "name": "--ms-selected-popover-header-bg",
              "description": "Popover header background"
            },
            {
              "name": "--ms-selected-popover-header-border-bottom",
              "description": "Popover header border"
            },
            {
              "name": "--ms-selected-popover-header-font-size",
              "description": "Popover header font size"
            },
            {
              "name": "--ms-selected-popover-header-font-weight",
              "description": "Popover header font weight"
            },
            {
              "name": "--ms-selected-popover-header-color",
              "description": "Popover header color"
            },
            {
              "name": "--ms-selected-popover-header-border-color",
              "description": "Popover header border color"
            },
            {
              "name": "--ms-popover-close-size",
              "description": "Popover close button size"
            },
            {
              "name": "--ms-selected-popover-close-bg",
              "description": "Popover close button background"
            },
            {
              "name": "--ms-selected-popover-close-color",
              "description": "Popover close button color"
            },
            {
              "name": "--ms-selected-popover-close-font-size",
              "description": "Popover close button font size (unused since 1.10.0 — kept for backward-compat)"
            },
            {
              "name": "--ms-selected-popover-close-icon-size",
              "description": "Popover close X icon size (mask SVG)"
            },
            {
              "name": "--ms-selected-popover-close-border-radius",
              "description": "Popover close button border radius"
            },
            {
              "name": "--ms-selected-popover-close-bg-hover",
              "description": "Popover close button hover background"
            },
            {
              "name": "--ms-selected-popover-close-color-hover",
              "description": "Popover close button hover color"
            },
            {
              "name": "--ms-selected-popover-body-gap",
              "description": "Popover body gap"
            },
            {
              "name": "--ms-selected-popover-body-padding",
              "description": "Popover body padding"
            },
            {
              "name": "--ms-selected-popover-body-max-height",
              "description": "Popover body max height"
            },
            {
              "name": "--ms-font-size-2xs",
              "description": "Extra extra small font size"
            },
            {
              "name": "--ms-font-size-xs",
              "description": "Extra small font size"
            },
            {
              "name": "--ms-font-size-sm",
              "description": "Small font size"
            },
            {
              "name": "--ms-font-size-base",
              "description": "Base font size"
            },
            {
              "name": "--ms-font-size-lg",
              "description": "Large font size"
            },
            {
              "name": "--ms-font-weight-normal",
              "description": "Normal font weight"
            },
            {
              "name": "--ms-font-weight-medium",
              "description": "Medium font weight"
            },
            {
              "name": "--ms-font-weight-semibold",
              "description": "Semibold font weight"
            },
            {
              "name": "--ms-line-height-none",
              "description": "No line height (1)"
            },
            {
              "name": "--ms-line-height-tight",
              "description": "Tight line height"
            },
            {
              "name": "--ms-line-height-normal",
              "description": "Normal line height"
            },
            {
              "name": "--ms-line-height-relaxed",
              "description": "Relaxed line height"
            },
            {
              "name": "--ms-border-radius-sm",
              "description": "Small border radius"
            },
            {
              "name": "--ms-border-radius-md",
              "description": "Medium border radius"
            },
            {
              "name": "--ms-border-radius-lg",
              "description": "Large border radius"
            },
            {
              "name": "--ms-border-radius",
              "description": "Default border radius"
            },
            {
              "name": "--ms-spacing-xs",
              "description": "Extra small spacing"
            },
            {
              "name": "--ms-spacing-sm",
              "description": "Small spacing"
            },
            {
              "name": "--ms-spacing-md",
              "description": "Medium spacing"
            },
            {
              "name": "--ms-spacing-lg",
              "description": "Large spacing"
            },
            {
              "name": "--ms-transition-fast",
              "description": "Fast transition duration"
            },
            {
              "name": "--ms-transition-normal",
              "description": "Normal transition duration"
            },
            {
              "name": "--ms-easing-snappy",
              "description": "Snappy easing function"
            },
            {
              "name": "--ms-placeholder-opacity",
              "description": "Placeholder opacity"
            },
            {
              "name": "--ms-disabled-input-opacity",
              "description": "Disabled input opacity"
            },
            {
              "name": "--ms-scrollbar-width",
              "description": "Scrollbar width"
            },
            {
              "name": "--ms-scrollbar-track-bg",
              "description": "Scrollbar track background"
            },
            {
              "name": "--ms-scrollbar-thumb-bg",
              "description": "Scrollbar thumb background"
            },
            {
              "name": "--ms-scrollbar-thumb-bg-hover",
              "description": "Scrollbar thumb hover background"
            },
            {
              "name": "--ms-scrollbar-thumb-border-radius",
              "description": "Scrollbar thumb border radius"
            },
            {
              "name": "--ms-debug-bg",
              "description": "Debug panel background"
            },
            {
              "name": "--ms-debug-border-color",
              "description": "Debug panel border"
            },
            {
              "name": "--ms-debug-text-color",
              "description": "Debug panel text"
            },
            {
              "name": "--ms-debug-border-radius",
              "description": "Debug panel corner radius"
            },
            {
              "name": "--ms-debug-summary-color",
              "description": "Debug section heading color"
            },
            {
              "name": "--ms-debug-summary-bg-hover",
              "description": "Debug section heading hover background"
            },
            {
              "name": "--ms-debug-summary-outline-color",
              "description": "Debug section heading focus outline"
            },
            {
              "name": "--ms-debug-summary-border-radius",
              "description": "Debug section heading corner radius"
            },
            {
              "name": "--ms-debug-stats-bg",
              "description": "Debug stats nested panel background"
            },
            {
              "name": "--ms-debug-stats-border-radius",
              "description": "Debug stats nested panel corner radius"
            },
            {
              "name": "--ms-debug-bullet-color",
              "description": "Debug stat bullet marker color"
            },
            {
              "name": "--ms-transform-rotate-180",
              "description": "180 degree rotation"
            },
            {
              "name": "--ms-transform-scale-hover",
              "description": "Hover scale transform"
            },
            {
              "name": "--ms-transform-scale-active",
              "description": "Active scale transform"
            },
            {
              "name": "--ms-order-first",
              "description": "Order first (-1)"
            }
          ]
        }
      ],
      "exports": [
        {
          "kind": "js",
          "name": "MultiSelectElement",
          "declaration": {
            "name": "MultiSelectElement",
            "module": "src/web-component.ts"
          }
        },
        {
          "kind": "custom-element-definition",
          "name": "web-multiselect",
          "declaration": {
            "name": "MultiSelectElement",
            "module": "src/web-component.ts"
          }
        }
      ]
    },
    {
      "kind": "javascript-module",
      "path": "src/tree/cascade.ts",
      "declarations": [
        {
          "kind": "function",
          "name": "buildCascadeIndex",
          "return": {
            "type": {
              "text": "CascadeIndex<T>"
            }
          },
          "parameters": [
            {
              "name": "tree",
              "type": {
                "text": "LTree<T>"
              }
            },
            {
              "name": "getValue",
              "type": {
                "text": "(data: T) => string"
              }
            }
          ],
          "description": "Build the cascade index from a tree and a value accessor."
        },
        {
          "kind": "function",
          "name": "nodeCheckState",
          "return": {
            "type": {
              "text": "NodeCheckState"
            }
          },
          "parameters": [
            {
              "name": "index",
              "type": {
                "text": "CascadeIndex<T>"
              }
            },
            {
              "name": "node",
              "type": {
                "text": "LTreeNode<T>"
              }
            },
            {
              "name": "checkedAtoms",
              "type": {
                "text": "Set<string>"
              }
            }
          ],
          "description": "The tristate of a node given the current checked-atom set."
        },
        {
          "kind": "function",
          "name": "expandToAtoms",
          "return": {
            "type": {
              "text": "Set<string>"
            }
          },
          "parameters": [
            {
              "name": "index",
              "type": {
                "text": "CascadeIndex<T>"
              }
            },
            {
              "name": "emittedValues",
              "type": {
                "text": "Iterable<string>"
              }
            }
          ],
          "description": "Expand an emitted value set (any policy) back to the canonical checked-atom\nset. Every emitted value denotes a fully-checked node, so its atoms are all\nchecked; unknown values (non-tree) are ignored."
        },
        {
          "kind": "function",
          "name": "toggleNodeCascade",
          "return": {
            "type": {
              "text": "{ checkedAtoms: Set<string>; addedAtoms: string[]; removedAtoms: string[] }"
            }
          },
          "parameters": [
            {
              "name": "index",
              "type": {
                "text": "CascadeIndex<T>"
              }
            },
            {
              "name": "node",
              "type": {
                "text": "LTreeNode<T>"
              }
            },
            {
              "name": "checkedAtoms",
              "type": {
                "text": "Set<string>"
              }
            }
          ],
          "description": "Toggle a node in cascade mode. Returns the new checked-atom set plus the atoms\nthat were added / removed. Toggling an `indeterminate` or `unchecked` node\nchecks its whole subtree; toggling a `checked` node unchecks it (matches\nsvelte-treeview: a dash click completes the selection)."
        },
        {
          "kind": "function",
          "name": "projectSelection",
          "return": {
            "type": {
              "text": "string[]"
            }
          },
          "parameters": [
            {
              "name": "index",
              "type": {
                "text": "CascadeIndex<T>"
              }
            },
            {
              "name": "checkedAtoms",
              "type": {
                "text": "Set<string>"
              }
            },
            {
              "name": "policy",
              "type": {
                "text": "CascadeSelectPolicy"
              }
            },
            {
              "name": "getValue",
              "type": {
                "text": "(data: T) => string"
              }
            }
          ],
          "description": "Project the checked-atom set to the emitted value list under a policy, in tree\n(depth-first) order:\n  - `all`      → every fully-checked selectable node (branches + atoms).\n  - `leaves`   → the checked atoms only.\n  - `rolled-up`→ minimal cover: a fully-checked selectable node emits itself and\n                 stops; a fully-checked *non-selectable* node rolls into its\n                 subtree (nearest selectable descendants); an indeterminate node\n                 descends so its individually-checked descendants surface."
        }
      ],
      "exports": [
        {
          "kind": "js",
          "name": "buildCascadeIndex",
          "declaration": {
            "name": "buildCascadeIndex",
            "module": "src/tree/cascade.ts"
          }
        },
        {
          "kind": "js",
          "name": "nodeCheckState",
          "declaration": {
            "name": "nodeCheckState",
            "module": "src/tree/cascade.ts"
          }
        },
        {
          "kind": "js",
          "name": "expandToAtoms",
          "declaration": {
            "name": "expandToAtoms",
            "module": "src/tree/cascade.ts"
          }
        },
        {
          "kind": "js",
          "name": "toggleNodeCascade",
          "declaration": {
            "name": "toggleNodeCascade",
            "module": "src/tree/cascade.ts"
          }
        },
        {
          "kind": "js",
          "name": "projectSelection",
          "declaration": {
            "name": "projectSelection",
            "module": "src/tree/cascade.ts"
          }
        }
      ]
    },
    {
      "kind": "javascript-module",
      "path": "src/tree/helpers.ts",
      "declarations": [
        {
          "kind": "function",
          "name": "isEmptyString",
          "return": {
            "type": {
              "text": "boolean"
            }
          },
          "parameters": [
            {
              "name": "str",
              "type": {
                "text": "string | null | undefined"
              }
            }
          ],
          "description": "Path/string helpers for the ltree option model.\n\nLifted (trimmed) from web-treeview's `helpers/string-helpers.ts` and\n`helpers/ltree-helpers.ts`. Options in tree mode are addressed by a\nmaterialized dot-path (e.g. `\"1.2.3\"`); parentPath and level are derived\nfrom that path by these functions."
        },
        {
          "kind": "function",
          "name": "getParentPath",
          "return": {
            "type": {
              "text": "string | null"
            }
          },
          "parameters": [
            {
              "name": "path",
              "type": {
                "text": "string"
              }
            },
            {
              "name": "pathSeparator",
              "default": "'.'",
              "type": {
                "text": "string"
              }
            }
          ],
          "description": "Parent of a dot-path: `\"a.b.c\"` -> `\"a.b\"`, `\"a\"` -> `\"\"`, empty -> null."
        },
        {
          "kind": "function",
          "name": "getRelativePath",
          "return": {
            "type": {
              "text": "string"
            }
          },
          "parameters": [
            {
              "name": "path",
              "type": {
                "text": "string"
              }
            },
            {
              "name": "parentPath",
              "type": {
                "text": "string"
              }
            },
            {
              "name": "pathSeparator",
              "default": "'.'",
              "type": {
                "text": "string"
              }
            }
          ],
          "description": "Path relative to a parent: `getRelativePath(\"a.b.c\", \"a\")` -> `\"b.c\"`."
        },
        {
          "kind": "function",
          "name": "getPathSegments",
          "return": {
            "type": {
              "text": "string"
            }
          },
          "parameters": [
            {
              "name": "path",
              "type": {
                "text": "string"
              }
            },
            {
              "name": "start",
              "default": "0",
              "type": {
                "text": "number"
              }
            },
            {
              "name": "count",
              "default": "1",
              "type": {
                "text": "number"
              }
            },
            {
              "name": "pathSeparator",
              "default": "'.'",
              "type": {
                "text": "string"
              }
            }
          ],
          "description": "Take `count` segments of `path` starting at `start`."
        },
        {
          "kind": "function",
          "name": "getLevel",
          "return": {
            "type": {
              "text": "number"
            }
          },
          "parameters": [
            {
              "name": "path",
              "type": {
                "text": "string"
              }
            },
            {
              "name": "pathSeparator",
              "type": {
                "text": "string"
              }
            }
          ],
          "description": "Depth of a path = segment count (`\"a.b.c\"` -> 3)."
        }
      ],
      "exports": [
        {
          "kind": "js",
          "name": "isEmptyString",
          "declaration": {
            "name": "isEmptyString",
            "module": "src/tree/helpers.ts"
          }
        },
        {
          "kind": "js",
          "name": "getParentPath",
          "declaration": {
            "name": "getParentPath",
            "module": "src/tree/helpers.ts"
          }
        },
        {
          "kind": "js",
          "name": "getRelativePath",
          "declaration": {
            "name": "getRelativePath",
            "module": "src/tree/helpers.ts"
          }
        },
        {
          "kind": "js",
          "name": "getPathSegments",
          "declaration": {
            "name": "getPathSegments",
            "module": "src/tree/helpers.ts"
          }
        },
        {
          "kind": "js",
          "name": "getLevel",
          "declaration": {
            "name": "getLevel",
            "module": "src/tree/helpers.ts"
          }
        }
      ]
    },
    {
      "kind": "javascript-module",
      "path": "src/tree/ltree-node.ts",
      "declarations": [
        {
          "kind": "function",
          "name": "createLTreeNode",
          "return": {
            "type": {
              "text": "LTreeNode<T>"
            }
          },
          "parameters": [
            {
              "name": "data",
              "optional": true,
              "type": {
                "text": "Partial<LTreeNode<T>>"
              }
            }
          ]
        }
      ],
      "exports": [
        {
          "kind": "js",
          "name": "createLTreeNode",
          "declaration": {
            "name": "createLTreeNode",
            "module": "src/tree/ltree-node.ts"
          }
        }
      ]
    },
    {
      "kind": "javascript-module",
      "path": "src/tree/ltree.ts",
      "declarations": [
        {
          "kind": "function",
          "name": "createLTree",
          "return": {
            "type": {
              "text": "LTree<T>"
            }
          },
          "parameters": [
            {
              "name": "options",
              "default": "{}",
              "type": {
                "text": "LTreeOptions<T>"
              }
            }
          ]
        },
        {
          "kind": "variable",
          "name": "treePathSeparator"
        },
        {
          "kind": "variable",
          "name": "root"
        }
      ],
      "exports": [
        {
          "kind": "js",
          "name": "createLTree",
          "declaration": {
            "name": "createLTree",
            "module": "src/tree/ltree.ts"
          }
        }
      ]
    }
  ]
}
