@ixfx/components 0.8.2 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/bundle/index.d.ts +274 -93
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +2135 -637
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.js +2 -2
  6. package/dist/ac-token.js +2 -2
  7. package/dist/checkbox.js +1 -1
  8. package/dist/{colour-picker-Ddsk-7E_.js → colour-picker-CSxwUmtE.js} +2 -2
  9. package/dist/{colour-picker-Ddsk-7E_.js.map → colour-picker-CSxwUmtE.js.map} +1 -1
  10. package/dist/colour-picker.js +1 -1
  11. package/dist/crumbs.js +2 -2
  12. package/dist/data-display.js +1 -1
  13. package/dist/data-grid-D-z7bx5-.d.ts.map +1 -1
  14. package/dist/data-grid.js +7 -4
  15. package/dist/data-grid.js.map +1 -1
  16. package/dist/detail-list-_ZJHYEBr.d.ts.map +1 -1
  17. package/dist/detail-list.js +67 -4
  18. package/dist/detail-list.js.map +1 -1
  19. package/dist/editable-label.js +1 -1
  20. package/dist/{fallbacks-DNI9xt0F.js → fallbacks-BcKGq-2F.js} +17 -1
  21. package/dist/{fallbacks-DNI9xt0F.js.map → fallbacks-BcKGq-2F.js.map} +1 -1
  22. package/dist/{grid-list-bmBWq6P-.js → grid-list-BXfY3XXX.js} +486 -13
  23. package/dist/grid-list-BXfY3XXX.js.map +1 -0
  24. package/dist/{grid-list-C1T6WlEp.d.ts → grid-list-x550wJ0X.d.ts} +97 -2
  25. package/dist/grid-list-x550wJ0X.d.ts.map +1 -0
  26. package/dist/grid-list.d.ts +2 -2
  27. package/dist/grid-list.js +1 -1
  28. package/dist/handle-BPOxBOKf.js +219 -0
  29. package/dist/handle-BPOxBOKf.js.map +1 -0
  30. package/dist/{icon-DcEEGQa_.js → icon-Dy33gu4Z.js} +2 -2
  31. package/dist/{icon-DcEEGQa_.js.map → icon-Dy33gu4Z.js.map} +1 -1
  32. package/dist/icons.js +1 -1
  33. package/dist/{index-BeuCXtiO.d.ts → index-DV3iaUBW.d.ts} +2 -2
  34. package/dist/{index-BeuCXtiO.d.ts.map → index-DV3iaUBW.d.ts.map} +1 -1
  35. package/dist/index.d.ts +130 -48
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +551 -203
  38. package/dist/index.js.map +1 -1
  39. package/dist/labelled-radial-input.js +2 -2
  40. package/dist/{labelled-slider-input-BInB5GKL.js → labelled-slider-input-BCH9968c.js} +3 -3
  41. package/dist/{labelled-slider-input-BInB5GKL.js.map → labelled-slider-input-BCH9968c.js.map} +1 -1
  42. package/dist/labelled-slider-input.js +1 -1
  43. package/dist/list-selection-controller-SA4piSBi.js +589 -0
  44. package/dist/list-selection-controller-SA4piSBi.js.map +1 -0
  45. package/dist/{menu-BDrTh6oo.js → menu-HMoxCPY2.js} +4 -4
  46. package/dist/{menu-BDrTh6oo.js.map → menu-HMoxCPY2.js.map} +1 -1
  47. package/dist/{menu-item-B6pKg2Qq.js → menu-item-BQDYxk5A.js} +3 -3
  48. package/dist/{menu-item-B6pKg2Qq.js.map → menu-item-BQDYxk5A.js.map} +1 -1
  49. package/dist/menu.js +2 -2
  50. package/dist/miller.js +1 -1
  51. package/dist/narrowed-text.js +1 -1
  52. package/dist/notifier.js +1 -1
  53. package/dist/panel.d.ts +1 -1
  54. package/dist/panel.js +1 -1
  55. package/dist/polar-pad.js +1 -1
  56. package/dist/{radial-input-BfA3GO0H.js → radial-input-DyxfbNzD.js} +2 -2
  57. package/dist/{radial-input-BfA3GO0H.js.map → radial-input-DyxfbNzD.js.map} +1 -1
  58. package/dist/radial-input.js +1 -1
  59. package/dist/range-input.js +1 -1
  60. package/dist/range.js +1 -1
  61. package/dist/select-horiz.js +1 -1
  62. package/dist/{slider-input-Bl1hFE89.js → slider-input-WR8_RwHg.js} +2 -2
  63. package/dist/{slider-input-Bl1hFE89.js.map → slider-input-WR8_RwHg.js.map} +1 -1
  64. package/dist/slider-input.js +1 -1
  65. package/dist/snackbar.js +1 -1
  66. package/dist/{split-layout-BFSbUZQv.js → split-layout-CA5jbNbG.js} +22 -33
  67. package/dist/split-layout-CA5jbNbG.js.map +1 -0
  68. package/dist/split-layout-JK3xWVX2.d.ts.map +1 -1
  69. package/dist/split-layout.js +1 -1
  70. package/dist/swipe.js +1 -1
  71. package/dist/tabs.js +1 -1
  72. package/dist/{timeline-B2fgDL4U.js → timeline-THyvH8xy.js} +14 -8
  73. package/dist/timeline-THyvH8xy.js.map +1 -0
  74. package/dist/timeline.d.ts +1 -1
  75. package/dist/timeline.js +1 -1
  76. package/dist/{titlebar-YQ-jVQoS.d.ts → titlebar-Tqu-VvMU.d.ts} +5 -1
  77. package/dist/titlebar-Tqu-VvMU.d.ts.map +1 -0
  78. package/dist/titlebar.d.ts +1 -1
  79. package/dist/titlebar.js +5 -3
  80. package/dist/titlebar.js.map +1 -1
  81. package/dist/{tree-4Jv28Nig.js → tree-DTQon838.js} +2 -2
  82. package/dist/{tree-4Jv28Nig.js.map → tree-DTQon838.js.map} +1 -1
  83. package/dist/tree.js +1 -1
  84. package/dist/vertical-list-CFuFDygi.d.ts.map +1 -1
  85. package/dist/vertical-list.js +67 -3
  86. package/dist/vertical-list.js.map +1 -1
  87. package/dist/xy-pad.js +1 -1
  88. package/docs-user/data-grid.md +1 -1
  89. package/docs-user/detail-list.md +4 -0
  90. package/docs-user/dock.md +33 -8
  91. package/docs-user/grid-list.md +5 -0
  92. package/docs-user/index.json +2 -2
  93. package/docs-user/split-layout.md +2 -4
  94. package/docs-user/twosplit-layout.md +14 -16
  95. package/docs-user/vertical-list.md +4 -0
  96. package/package.json +1 -1
  97. package/dist/grid-list-C1T6WlEp.d.ts.map +0 -1
  98. package/dist/grid-list-bmBWq6P-.js.map +0 -1
  99. package/dist/list-selection-controller-DTFI40li.js +0 -264
  100. package/dist/list-selection-controller-DTFI40li.js.map +0 -1
  101. package/dist/split-layout-BFSbUZQv.js.map +0 -1
  102. package/dist/timeline-B2fgDL4U.js.map +0 -1
  103. package/dist/titlebar-YQ-jVQoS.d.ts.map +0 -1
@@ -1,11 +1,11 @@
1
1
  import { t as TickledController } from "./tickled-controller-Dh1Uh_vG.js";
2
- import { t as themeFallbacks } from "./fallbacks-DNI9xt0F.js";
2
+ import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
3
3
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
4
- import "./icon-DcEEGQa_.js";
4
+ import "./icon-Dy33gu4Z.js";
5
5
  import { t as DataController } from "./data-controller-DOlmqNKb.js";
6
6
  import { c as createElementListSearchAdapter, i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, u as keyForElement } from "./incr-search-C05WjbZh.js";
7
+ import { r as ListDragSelectController, t as ListSelectionController } from "./list-selection-controller-SA4piSBi.js";
7
8
  import { n as animateListItemIn, r as animateListItemOut } from "./list-item-animation-DuiwgN3l.js";
8
- import { t as ListSelectionController } from "./list-selection-controller-DTFI40li.js";
9
9
  import { t as scrollFadeStyles } from "./scroll-fade-CAs1EabA.js";
10
10
  import { LitElement, css, html, nothing, render } from "lit";
11
11
  import { property, query } from "lit/decorators.js";
@@ -60,7 +60,28 @@ let DetailListElement = class DetailListElement extends LitElement {
60
60
  if (id !== void 0) this._dispatch(`list-tickle`, { item: id });
61
61
  },
62
62
  onStateChange: () => this._syncItemStates(),
63
- itemWrap: this.itemWrap
63
+ itemWrap: this.itemWrap,
64
+ hoverDisabled: () => this.#dragSelect.isDragging
65
+ });
66
+ this.#dragSelect = new ListDragSelectController(this, {
67
+ getSurface: () => this.renderRoot.querySelector(`.container`),
68
+ isEnabled: () => this.selection.canDragSelect() && this._getVisibleItems().length > 0 && !this.hasAttribute(`disable-drag-select`),
69
+ hitTest: (rect) => this.#marqueeHitTest(rect),
70
+ getBaseSelection: () => this.selection.selected,
71
+ onPreview: (preview, rect) => {
72
+ this.#marqueeRect = rect;
73
+ for (const el of this._getVisibleItems()) el.toggleAttribute(`data-marquee`, preview.has(el));
74
+ this.requestUpdate();
75
+ },
76
+ onCommit: (finalSet) => {
77
+ this.selection.applyDragSelection(finalSet);
78
+ for (const el of this._getVisibleItems()) el.removeAttribute(`data-marquee`);
79
+ this.#marqueeRect = void 0;
80
+ this.requestUpdate();
81
+ },
82
+ autoScroll: (dx, _dy) => {
83
+ if (this._listEl) this._listEl.scrollLeft += dx;
84
+ }
64
85
  });
65
86
  this.search = new ListSearchController(this, { adapter: createElementListSearchAdapter(this, {
66
87
  itemSelector: ITEM_SELECTOR,
@@ -137,6 +158,7 @@ let DetailListElement = class DetailListElement extends LitElement {
137
158
  }
138
159
  };
139
160
  this._onClick = (e) => {
161
+ if (this.#dragSelect.isDragging) return;
140
162
  const item = this._findListItem(e.composedPath());
141
163
  if (!item) return;
142
164
  this.focus();
@@ -163,6 +185,30 @@ let DetailListElement = class DetailListElement extends LitElement {
163
185
  #builtFromProvider;
164
186
  #providerBuilt;
165
187
  #data;
188
+ /** Live drag-select preview rect (surface-relative); the covered items carry `data-marquee`. */
189
+ #marqueeRect;
190
+ #dragSelect;
191
+ /** Collect visible items whose surface-relative box intersects `rect`. */
192
+ #marqueeHitTest(rect) {
193
+ const surface = this.renderRoot.querySelector(`.container`);
194
+ if (!surface) return [];
195
+ const box = surface.getBoundingClientRect();
196
+ const rx0 = rect.x;
197
+ const ry0 = rect.y;
198
+ const rx1 = rect.x + rect.width;
199
+ const ry1 = rect.y + rect.height;
200
+ const out = [];
201
+ for (const el of this._getVisibleItems()) {
202
+ const r = el.getBoundingClientRect();
203
+ const left = r.left - box.left;
204
+ const top = r.top - box.top;
205
+ if (left <= rx1 && left + r.width >= rx0 && top <= ry1 && top + r.height >= ry0) out.push(el);
206
+ }
207
+ return out;
208
+ }
209
+ #marqueeStyle(rect) {
210
+ return `left:${rect.x}px;top:${rect.y}px;width:${Math.max(0, rect.width)}px;height:${Math.max(0, rect.height)}px`;
211
+ }
166
212
  #searchRegistry;
167
213
  #unregisterSearchCommands;
168
214
  /** Command registry carrying this list's `list.search.*` commands. */
@@ -935,6 +981,22 @@ let DetailListElement = class DetailListElement extends LitElement {
935
981
  outline-offset: -2px;
936
982
  }
937
983
 
984
+ /* Drag-select (marquee) rectangle + covered-row preview.
985
+ Style hooks: part="marquee", --detail-list-marquee-border,
986
+ --detail-list-marquee-fill. */
987
+ .marquee {
988
+ position: absolute;
989
+ pointer-events: none;
990
+ z-index: 5;
991
+ border: 1px solid var(--detail-list-marquee-border, var(--accent));
992
+ background: var(--detail-list-marquee-fill, color-mix(in srgb, var(--accent) 15%, transparent));
993
+ }
994
+
995
+ ::slotted([data-marquee]) {
996
+ background: var(--item-bg-selected);
997
+ color: var(--item-text-selected);
998
+ }
999
+
938
1000
  /* checked mode: the injected checkbox communicates selection — suppress bg */
939
1001
  :host([interaction-mode="checked"]) ::slotted([data-selected]) {
940
1002
  background: transparent;
@@ -975,6 +1037,7 @@ let DetailListElement = class DetailListElement extends LitElement {
975
1037
  <ul part="list" class="scroll-fade-x">
976
1038
  <slot></slot>
977
1039
  </ul>
1040
+ ${this.#marqueeRect ? html`<div class="marquee" part="marquee" style=${this.#marqueeStyle(this.#marqueeRect)}></div>` : ``}
978
1041
  <div class="loading" part="loading" ?hidden=${!loading}>
979
1042
  ${loading ? progress !== void 0 ? `${Math.round(progress * 100)}%` : `loading…` : nothing}
980
1043
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"detail-list.js","names":["#navigateDown","#navigateUp","#navigateRight","#navigateLeft","#navigateTo","#findFirstCheckable","#findLastCheckable","#data","#searchRegistry","#effectiveSearchModes","#unregisterSearchCommands","#resizeObserver","#scheduleGeometry","#mutationObserver","#processChildren","#animateChildMutations","#animatedItems","#syncSearchCommands","#applyFilterPredicate","#recomputeGeometry","#builtFromProvider","#providerBuilt","#rebuildFromObjects","#syncFromProvider","#applySort","#ensureIcon","#itemData","#itemForKey","#createItemEl","#propertyValue","#geometryScheduled","#grid","#positions","#gridSize","#itemAt","#positionOf","#findNextCheckable","customElement"],"sources":["../src/detail-list/detail-list.ts"],"sourcesContent":["import type { CommandId, CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { IDataProvider } from '../common/data-provider.js';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type {\n ListActivateDetail,\n ListElementEventMap,\n ListInteractionMode,\n ListItemClickDetail,\n ListSelectDetail,\n ListSelectionMode,\n ListTickleDetail,\n} from '../interaction/list-selection-types.js';\nimport type {\n AddItemOptions,\n CustomCheckboxOptions,\n DetailFormatter,\n DetailSortComparator,\n DetailSortItem,\n DetailSortMode,\n} from './types.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { css, html, LitElement, nothing, render } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { DataController } from '../common/data-controller.js';\nimport {\n createElementListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { keyForElement } from '../interaction/keyed-list.js';\nimport { animateListItemIn, animateListItemOut, LIST_ITEM_MOTION_MS } from '../interaction/list-item-animation.js';\nimport { ListSelectionController } from '../interaction/list-selection-controller.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { scrollFadeStyles } from '../styles/scroll-fade.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../icons/icon.js';\n\nexport type {\n AddItemOptions,\n CustomCheckboxOptions,\n DetailFormatter,\n DetailSortComparator,\n DetailSortItem,\n DetailSortMode,\n} from './types.js';\n\nconst ITEM_SELECTOR = `:scope > li`;\nconst SEARCH_HIGHLIGHT_KEY = `detail-list-search`;\nconst LABEL_SPAN_CSS = `overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0`;\n\ntype GridPosition = { readonly col: number; readonly row: number };\n\n/**\n * A list that scales horizontally, not vertically.\n *\n * Items are laid out in equal-width columns; they flow top→bottom down a\n * column, then wrap to the top of the next column to the right. The\n * component has a fixed vertical extent and scrolls horizontally.\n *\n * Selection semantics match `ixfx-vertical-list` — same modes, same\n * `list-*` events, same keyboard gestures — but navigation is a 2-D grid\n * (Up/Down move within a column, Left/Right jump columns).\n *\n * Items come from any of three sources (later writes win):\n * 1. declarative `<li>` children in light DOM,\n * 2. `addItem()` / `setItems()`,\n * 3. an `items` array of objects rendered via `displayProperty` /\n * `formatter`, optionally streamed in via a `provider`.\n */\n@customElement(`ixfx-detail-list`)\nexport class DetailListElement extends LitElement {\n @property({ type: String, attribute: `selection-mode` })\n selectionMode: ListSelectionMode = `single`;\n\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: ListInteractionMode = `standard`;\n\n @property({ type: String })\n sort: DetailSortMode = `none`;\n\n @property({ type: String, attribute: `sort-by` })\n sortBy = ``;\n\n @property({ attribute: false })\n sortComparator: DetailSortComparator | undefined;\n\n @property({ attribute: false })\n items: readonly unknown[] = [];\n\n @property({ attribute: false })\n provider: IDataProvider<void, unknown> | undefined;\n\n @property({ type: String, attribute: `display-property` })\n displayProperty = ``;\n\n @property({ attribute: false })\n formatter: DetailFormatter | undefined;\n\n @property({ type: String, attribute: `icon-property` })\n iconProperty = ``;\n\n @property({ type: String, attribute: `key-property` })\n keyProperty = ``;\n\n @property({ attribute: false })\n filterPredicate: ((el: Element) => boolean) | undefined;\n\n /**\n * Whether keyboard navigation wraps from last to first and vice versa.\n * - 'stop' (default): navigation stops at the boundary\n * - 'wrap': navigation wraps around\n */\n @property({ type: String, attribute: `item-wrap` })\n itemWrap: `stop` | `wrap` = `stop`;\n\n /** Optional renderer for the checkbox shown in `checked` interactionMode. */\n @property({ attribute: false })\n checkboxRenderer: ((checked: boolean) => unknown) | CustomCheckboxOptions | undefined;\n\n /**\n * Space-separated subset of `navigate select filter` — limits which\n * incremental-search modes are offered. Unset ⇒ all three; empty ⇒ search\n * disabled. See `docs/infra-incremental.md`.\n */\n @property({ type: String, attribute: `search-modes`, reflect: true })\n searchModes: string | undefined;\n\n @query(`ul`)\n private _listEl!: HTMLUListElement;\n\n #itemData = new WeakMap<HTMLLIElement, unknown>();\n #grid: Element[][] = [];\n #positions = new Map<Element, GridPosition>();\n #geometryScheduled = false;\n #resizeObserver: ResizeObserver | undefined;\n #mutationObserver: MutationObserver | undefined;\n /** Items that have already played (or been skipped for) their enter animation. */\n #animatedItems = new WeakSet<Element>();\n #builtFromProvider: readonly unknown[] = [];\n #providerBuilt = 0;\n\n readonly #data = new DataController<void, unknown>(this);\n\n private readonly selection = new ListSelectionController<Element>({\n getOrderedItems: () => this._getVisibleItems(),\n isSelectable: el => this._isCheckable(el),\n getModes: () => ({ selectionMode: this.selectionMode, interactionMode: this.interactionMode }),\n getKey: keyForElement,\n onChange: (selected, previous) => {\n this._syncItemStates();\n this._dispatch<ListSelectDetail>(`list-select`, {\n selected,\n previous,\n selectedKeys: this.selection.selectedKeys,\n });\n },\n });\n\n private tickled = new TickledController<Element>(this, {\n getItems: () => this._getVisibleItems().map(el => ({\n id: el,\n enabled: !el.hasAttribute(`not-checked`),\n })),\n onTickle: (id) => {\n if (id !== undefined) {\n this._dispatch<ListTickleDetail>(`list-tickle`, { item: id });\n }\n },\n onStateChange: () => this._syncItemStates(),\n itemWrap: this.itemWrap,\n });\n\n /** Incremental search (navigate / select / filter). See `docs/infra-incremental.md`. */\n readonly search = new ListSearchController<Element>(this, {\n adapter: createElementListSearchAdapter(this, {\n itemSelector: ITEM_SELECTOR,\n getLabel: el => el.getAttribute(`data-search-label`) ?? el.textContent?.trim() ?? ``,\n highlightKey: SEARCH_HIGHLIGHT_KEY,\n }),\n });\n\n #searchRegistry: CommandRegistry<unknown> | undefined;\n #unregisterSearchCommands: (() => void) | undefined;\n\n /** Command registry carrying this list's `list.search.*` commands. */\n get registry(): CommandRegistry<unknown> | undefined {\n return this.#searchRegistry;\n }\n\n #effectiveSearchModes(): ListSearchMode[] {\n const raw = this.searchModes?.trim();\n if (raw === undefined)\n return [...LIST_SEARCH_MODES];\n const requested = new Set(raw.split(/\\s+/));\n return LIST_SEARCH_MODES.filter(m => requested.has(m));\n }\n\n #syncSearchCommands(): void {\n if (!this.#searchRegistry)\n return;\n this.search.setModes(this.#effectiveSearchModes());\n this.#unregisterSearchCommands?.();\n this.#unregisterSearchCommands = registerListSearchCommands(this.#searchRegistry, this.search);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute(`tabindex`))\n this.tabIndex = 0;\n this.addEventListener(`pointerover`, this._onPointerOver);\n this.addEventListener(`pointerleave`, this._onPointerLeave);\n this.addEventListener(`keydown`, this._onKeyDown);\n this.addEventListener(`click`, this._onClick);\n this.addEventListener(`dblclick`, this._onDblClick);\n this.addEventListener(`wheel`, this._onWheel);\n\n this.#resizeObserver = new ResizeObserver(() => this.#scheduleGeometry());\n this.#resizeObserver.observe(this);\n this.#mutationObserver = new MutationObserver((records) => {\n this.#processChildren();\n this.#animateChildMutations(records);\n this.#scheduleGeometry();\n });\n this.#mutationObserver.observe(this, {\n childList: true,\n subtree: false,\n attributeFilter: [`hidden`],\n });\n for (const el of this.querySelectorAll(ITEM_SELECTOR))\n this.#animatedItems.add(el);\n this.#searchRegistry ??= createCommandRegistry();\n this.#syncSearchCommands();\n }\n\n /**\n * Collapse-in items appended to the light DOM (however they got there). A bulk\n * populate is left alone. Geometry is re-read once the animations settle so\n * keyboard navigation lines back up with the final layout.\n */\n #animateChildMutations(records: MutationRecord[]): void {\n if (!this.isConnected)\n return;\n const fresh: HTMLElement[] = [];\n for (const record of records) {\n for (const node of record.addedNodes) {\n // ITEM_SELECTOR is `:scope > li`, which can't be used with `.matches()`\n // — every item here is a direct `<li>` child, so check that directly.\n if (!(node instanceof HTMLElement) || node.parentElement !== this || node.localName !== `li`)\n continue;\n if (this.#animatedItems.has(node))\n continue;\n this.#animatedItems.add(node);\n fresh.push(node);\n }\n }\n if (fresh.length === 0)\n return;\n const total = this.querySelectorAll(ITEM_SELECTOR).length;\n if (fresh.length >= total)\n return; // first populate / wholesale replace\n for (const el of fresh)\n animateListItemIn(el);\n window.setTimeout(() => this.#scheduleGeometry(), LIST_ITEM_MOTION_MS + 30);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`pointerover`, this._onPointerOver);\n this.removeEventListener(`pointerleave`, this._onPointerLeave);\n this.removeEventListener(`keydown`, this._onKeyDown);\n this.removeEventListener(`click`, this._onClick);\n this.removeEventListener(`dblclick`, this._onDblClick);\n this.removeEventListener(`wheel`, this._onWheel);\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n this.#mutationObserver?.disconnect();\n this.#mutationObserver = undefined;\n this.#unregisterSearchCommands?.();\n this.#unregisterSearchCommands = undefined;\n this.#searchRegistry = undefined;\n }\n\n override firstUpdated(): void {\n this.#processChildren();\n if (this.filterPredicate) {\n this.#applyFilterPredicate();\n }\n this.#recomputeGeometry();\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n if (changed.has(`searchModes`)) {\n this.#syncSearchCommands();\n }\n if (changed.has(`provider`)) {\n this.#builtFromProvider = [];\n this.#providerBuilt = 0;\n this.#data.provider = this.provider;\n queueMicrotask(() => {\n if (this.provider)\n this.#data.request(undefined);\n });\n return;\n }\n if (changed.has(`items`) && this.provider === undefined && this.items.length > 0) {\n this.#rebuildFromObjects(this.items);\n }\n this.#syncFromProvider();\n if (changed.has(`sort`) || changed.has(`sortBy`) || changed.has(`sortComparator`)) {\n this.#applySort();\n }\n if (changed.has(`filterPredicate`)) {\n this.#applyFilterPredicate();\n this.#scheduleGeometry();\n }\n if (changed.has(`interactionMode`)) {\n this.selection.clearAnchor();\n this._syncItemStates();\n } else if (changed.has(`checkboxRenderer`) && this.interactionMode === `checked`) {\n this._syncCheckboxes();\n }\n }\n\n // --- Public API ---\n\n /** The most recently selected item, or `undefined` if nothing is selected. */\n get selectedItem(): Element | undefined {\n return [...this.selection.selected].at(-1);\n }\n\n /** The full current selection set (read-only). */\n get selectedItems(): ReadonlySet<Element> {\n return this.selection.selected;\n }\n\n /**\n * Force an immediate geometry recompute. Called automatically on resize,\n * DOM changes, sort/filter/search changes — only needed when layout is\n * changed by outside forces (e.g. an external font load).\n */\n refreshLayout(): void {\n this.#recomputeGeometry();\n }\n\n addItem(item: Element | string, options?: AddItemOptions): void {\n let el: Element;\n if (typeof item === `string`) {\n const li = document.createElement(`li`);\n this._setLabel(li, item);\n el = li;\n } else {\n el = item;\n }\n if (options?.notChecked)\n el.setAttribute(`not-checked`, ``);\n this.appendChild(el);\n this.#ensureIcon(el as HTMLLIElement);\n if (this.sort !== `none`)\n this.#applySort();\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n }\n\n /**\n * Collapse + fade `item` out, then detach it; the rows after it slide up to\n * close the gap. Resolves once removed. Immediate under reduced motion.\n */\n removeItem(item: Element): Promise<void> {\n this.selection.deselect(item);\n return animateListItemOut(item as HTMLElement).then(() => {\n item.remove();\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n this.#recomputeGeometry();\n });\n }\n\n /** {@link removeItem} for several items at once. */\n removeItems(items: Iterable<Element>): Promise<void> {\n return Promise.all([...items].map(item => this.removeItem(item))).then(() => undefined);\n }\n\n clearItems(): void {\n this.replaceChildren();\n this.selection.reset();\n this.#builtFromProvider = [];\n this.#providerBuilt = 0;\n this._syncItemStates();\n }\n\n /**\n * Replace the entire item list in one call.\n * Equivalent to `clearItems()` followed by `addItem()` for each element.\n */\n setItems(items: readonly Element[]): void {\n this.clearItems();\n for (const item of items) {\n this.appendChild(item);\n this.#ensureIcon(item as HTMLLIElement);\n }\n if (this.sort !== `none`)\n this.#applySort();\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n }\n\n /**\n * Get the source object behind an `<li>` built from an `items` array or\n * provider. Returns `undefined` for declarative / programmatic elements.\n */\n getItemData(item: HTMLLIElement): unknown {\n return this.#itemData.get(item);\n }\n\n /**\n * Dispatch a command to this list — used by `ixfx-grouped-item-lister` to\n * forward commands. Routes through the command registry (so `list.search.*`\n * and any other registered commands work).\n */\n dispatch(commandId: CommandId, args?: Record<string, unknown>): void {\n this.#searchRegistry?.invoke(commandId, args);\n }\n\n select(item: Element): void {\n this.selection.replace(item);\n }\n\n selectMany(items: Iterable<Element>): void {\n this.selection.selectMany(items);\n }\n\n deselect(item: Element): void {\n this.selection.deselect(item);\n }\n\n clearSelection(): void {\n this.selection.clear();\n }\n\n selectAll(): void {\n if (this.selection.canSelectAll())\n this.selection.selectAll();\n }\n\n // --- Key-based selection & cursor ---\n\n /** The selection as stable `data-key` / `data-value` strings. */\n get selectedKeys(): ReadonlySet<string> {\n return this.selection.selectedKeys;\n }\n\n /** The key of the item under the cursor, or `undefined`. */\n get tickledKey(): string | undefined {\n const id = this.tickled.tickledId;\n return id ? keyForElement(id) : undefined;\n }\n\n /** Replace the selection with the items carrying these keys (unknown keys ignored). */\n selectKeys(keys: Iterable<string>): void {\n this.selection.selectKeys(keys, key => this.#itemForKey(key));\n }\n\n /** Add items by key to the selection (multi-select modes only). */\n addSelectedKeys(keys: Iterable<string>): void {\n this.selection.addKeys(keys, key => this.#itemForKey(key));\n }\n\n /** Remove items by key from the selection. */\n removeSelectedKeys(keys: Iterable<string>): void {\n this.selection.removeKeys(keys, key => this.#itemForKey(key));\n }\n\n /** Move the cursor to the item with this key and scroll it into view. */\n focusKey(key: string): void {\n const el = this.#itemForKey(key);\n if (!el)\n return;\n this.tickled.focus(el);\n el.scrollIntoView({ block: `nearest`, inline: `nearest` });\n }\n\n #itemForKey(key: string): Element | undefined {\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n if (keyForElement(el) === key)\n return el;\n }\n return undefined;\n }\n\n * selectedFilter(kind: `selected` | `checked` | `either`): Generator<Element> {\n const wanted = (el: Element) => {\n switch (kind) {\n case `selected`: return el.hasAttribute(`data-selected`);\n case `checked`: return el.hasAttribute(`data-checked`);\n case `either`: return el.hasAttribute(`data-selected`) || el.hasAttribute(`data-checked`);\n }\n };\n\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n if ((el as HTMLElement).hidden)\n continue;\n if (wanted(el))\n yield el;\n }\n }\n\n // --- Object items ---\n\n #rebuildFromObjects(items: readonly unknown[]): void {\n const keyOf = (el: Element): string | null =>\n el.getAttribute(`data-key`) ?? el.getAttribute(`data-search-label`) ?? null;\n const previousKeys = new Set(\n [...this.selection.selected].map(keyOf).filter((k): k is string => k !== null),\n );\n const anchorKey = this.selection.anchor ? keyOf(this.selection.anchor) : null;\n\n this.replaceChildren(...items.map((item, index) => this.#createItemEl(item, index)));\n\n // Re-select by key so selection survives the element-reference rebuild\n if (previousKeys.size > 0 || anchorKey !== null) {\n const next: Element[] = [];\n let anchor: Element | undefined;\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n const key = keyOf(el);\n if (key !== null && previousKeys.has(key))\n next.push(el);\n if (key !== null && key === anchorKey)\n anchor = el;\n }\n this.selection.seed(next, anchor);\n }\n\n if (this.sort !== `none`)\n this.#applySort();\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n this._syncItemStates();\n this.#scheduleGeometry();\n }\n\n #createItemEl(item: unknown, index: number): HTMLLIElement {\n const li = document.createElement(`li`);\n this.#itemData.set(li, item);\n\n const content = this.formatter\n ? this.formatter(item, index)\n : (this.displayProperty\n ? this.#propertyValue(item, this.displayProperty)\n : item);\n if (typeof content === `string`) {\n this._setLabel(li, content);\n if (this.iconProperty) {\n const icon = this.#propertyValue(item, this.iconProperty);\n if (typeof icon === `string` && icon.length > 0)\n li.setAttribute(`data-icon`, icon);\n }\n } else if (content instanceof Node) {\n li.appendChild(content);\n }\n\n if (this.keyProperty) {\n const key = this.#propertyValue(item, this.keyProperty);\n if (key !== undefined && key !== null)\n li.setAttribute(`data-key`, String(key));\n }\n this.#ensureIcon(li);\n return li;\n }\n\n #propertyValue(item: unknown, prop: string): unknown {\n if (typeof item !== `object` || item === null || !(prop in item))\n return undefined;\n return (item as Record<string, unknown>)[prop];\n }\n\n // --- Provider (async) items ---\n\n #syncFromProvider(): void {\n if (this.provider === undefined)\n return;\n const items = this.#data.items;\n if (items === this.#builtFromProvider)\n return;\n\n // Longest common prefix by identity — pure appends extend the columns,\n // anything else rebuilds.\n let prefix = 0;\n while (\n prefix < this.#builtFromProvider.length\n && prefix < items.length\n && this.#builtFromProvider[prefix] === items[prefix]\n ) {\n prefix++;\n }\n\n if (prefix === this.#builtFromProvider.length && prefix <= items.length) {\n const tail = items.slice(prefix);\n for (const item of tail) {\n this.appendChild(this.#createItemEl(item, this.#providerBuilt++));\n }\n if (this.sort !== `none`)\n this.#applySort();\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n this._syncItemStates();\n this.#scheduleGeometry();\n } else {\n this.#providerBuilt = 0;\n this.#rebuildFromObjects(items);\n }\n this.#builtFromProvider = items;\n }\n\n // --- Filtering ---\n\n #applyFilterPredicate(): void {\n if (!this.filterPredicate) {\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n el.removeAttribute(`hidden`);\n }\n return;\n }\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n if (this.filterPredicate(el)) {\n el.removeAttribute(`hidden`);\n } else {\n el.setAttribute(`hidden`, ``);\n }\n }\n }\n\n // --- Sorting ---\n\n #applySort(): void {\n if (this.sort === `none`)\n return;\n const rows = [...this.querySelectorAll(ITEM_SELECTOR)] as HTMLLIElement[];\n if (rows.length < 2)\n return;\n\n const dir = this.sort === `descending` ? -1 : 1;\n const meta = (el: HTMLLIElement): DetailSortItem => ({\n element: el,\n data: this.getItemData(el),\n label: el.getAttribute(`data-search-label`) ?? el.textContent?.trim() ?? ``,\n });\n\n let cmp: (a: HTMLLIElement, b: HTMLLIElement) => number;\n if (this.sortComparator) {\n const user = this.sortComparator;\n cmp = (a, b) => user(meta(a), meta(b));\n } else if (this.sortBy) {\n const prop = this.sortBy;\n const key = (el: HTMLLIElement): string | number => {\n const v = this.#propertyValue(this.getItemData(el), prop);\n if (typeof v === `number`)\n return v;\n return v === undefined || v === null ? `` : String(v);\n };\n cmp = (a, b) => {\n const ka = key(a);\n const kb = key(b);\n if (typeof ka === `number` && typeof kb === `number`)\n return ka - kb;\n return String(ka).localeCompare(String(kb), undefined, { numeric: true });\n };\n } else {\n cmp = (a, b) =>\n meta(a).label.localeCompare(meta(b).label, undefined, { numeric: true });\n }\n\n const indexed = rows.map((el, i) => ({ el, i }));\n indexed.sort((a, b) => cmp(a.el, b.el) * dir || a.i - b.i); // stable\n for (const { el } of indexed)\n this.appendChild(el); // moving reorders in place\n this.#scheduleGeometry();\n }\n\n // --- Geometry (measured grid) ---\n\n #scheduleGeometry(): void {\n if (this.#geometryScheduled)\n return;\n this.#geometryScheduled = true;\n requestAnimationFrame(() => {\n this.#geometryScheduled = false;\n this.#recomputeGeometry();\n });\n }\n\n #recomputeGeometry(): void {\n this.#grid = [];\n this.#positions.clear();\n if (!this.isConnected)\n return;\n\n const columns: Array<{ left: number; items: Element[] }> = [];\n for (const el of this._getVisibleItems()) {\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0)\n continue;\n let ci = columns.findIndex(c => Math.abs(c.left - rect.left) <= 1);\n if (ci === -1) {\n columns.push({ left: rect.left, items: [] });\n ci = columns.length - 1;\n }\n columns[ci].items.push(el);\n }\n columns.sort((a, b) => a.left - b.left);\n for (const col of columns)\n col.items.sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top);\n\n this.#grid = columns.map(c => c.items);\n this.#grid.forEach((col, colIdx) =>\n col.forEach((el, rowIdx) => this.#positions.set(el, { col: colIdx, row: rowIdx })),\n );\n }\n\n #positionOf(el: Element): GridPosition | undefined {\n let pos = this.#positions.get(el);\n if (pos === undefined) {\n this.#recomputeGeometry();\n pos = this.#positions.get(el);\n }\n return pos;\n }\n\n #itemAt(col: number, row: number): Element | undefined {\n return this.#grid[col]?.[row];\n }\n\n #gridSize(): { cols: number; rows: number } {\n if (this.#grid.length === 0)\n this.#recomputeGeometry();\n return { cols: this.#grid.length, rows: Math.max(0, ...this.#grid.map(c => c.length)) };\n }\n\n // --- Keyboard navigation ---\n\n #navigateTo(target: Element | undefined): void {\n if (!target)\n return;\n this.tickled.handleKeyboardNavigation(target);\n this.tickled.tickledId?.scrollIntoView({ block: `nearest`, inline: `nearest` });\n }\n\n #findNextCheckable(fromCol: number, fromRow: number, deltaCol: number, deltaRow: number): Element | undefined {\n const { cols } = this.#gridSize();\n const visibleItems = this._getVisibleItems();\n const maxIterations = visibleItems.length + 1;\n\n // Start from the next position\n // For horizontal nav: move to next column first, keep same row\n // For vertical nav: stay in same column, move row\n // For diagonal nav: both change\n let col = deltaCol !== 0 ? fromCol + deltaCol : fromCol;\n let row = deltaRow !== 0 ? fromRow + deltaRow : fromRow;\n\n // Track whether we've tried wrapping columns\n let wrappedColumns = false;\n\n for (let iterations = 0; iterations < maxIterations; iterations++) {\n // Check bounds\n const colLength = this.#grid[col]?.length ?? 0;\n\n if (row < 0 || row >= colLength) {\n // Need to move to another column\n if (deltaCol !== 0 || wrappedColumns) {\n // Already tried wrapping, or horizontal nav - stop or wrap\n if (this.itemWrap === `wrap`) {\n // Simple wrap: if deltaCol < 0, go to last column; if deltaCol > 0, go to first\n if (deltaCol < 0) {\n col = cols - 1;\n } else if (deltaCol > 0) {\n col = 0;\n }\n wrappedColumns = true;\n } else {\n return undefined;\n }\n }\n\n // Try next/prev column\n if (deltaRow > 0) {\n // Going down - try next column at row 0\n if (col + 1 < cols) {\n col = col + 1;\n row = 0;\n wrappedColumns = true;\n } else if (this.itemWrap === `wrap`) {\n col = 0;\n row = 0;\n wrappedColumns = true;\n } else {\n return undefined;\n }\n } else if (deltaRow < 0) {\n // Going up - try prev column at last row\n if (col - 1 >= 0) {\n col = col - 1;\n row = (this.#grid[col]?.length ?? 1) - 1;\n wrappedColumns = true;\n } else if (this.itemWrap === `wrap`) {\n col = cols - 1;\n row = (this.#grid[col]?.length ?? 1) - 1;\n wrappedColumns = true;\n } else {\n return undefined;\n }\n } else if (deltaCol !== 0) {\n // Horizontal navigation - adjust row if target column is shorter\n const targetColLength = this.#grid[col]?.length ?? 0;\n if (row >= targetColLength && targetColLength > 0) {\n row = targetColLength - 1;\n }\n }\n\n // If we're now at same position as start, we've looped\n if (col === fromCol && row === fromRow + deltaRow) {\n return undefined;\n }\n continue;\n }\n\n const item = this.#itemAt(col, row);\n if (item && this._isCheckable(item)) {\n return item;\n }\n\n // Move to next position\n row += deltaRow;\n }\n\n return undefined;\n }\n\n #findFirstCheckable(): Element | undefined {\n const visibleItems = this._getVisibleItems();\n return visibleItems.find(item => this._isCheckable(item));\n }\n\n #findLastCheckable(): Element | undefined {\n const visibleItems = this._getVisibleItems();\n for (let i = visibleItems.length - 1; i >= 0; i--) {\n if (this._isCheckable(visibleItems[i])) {\n return visibleItems[i];\n }\n }\n return undefined;\n }\n\n #navigateDown(): void {\n this.#recomputeGeometry();\n const cur = this.tickled.tickledId ? this.#positionOf(this.tickled.tickledId) : undefined;\n if (!cur) {\n this.#navigateTo(this.#findFirstCheckable());\n return;\n }\n const next = this.#findNextCheckable(cur.col, cur.row, 0, 1);\n if (next) {\n this.#navigateTo(next);\n }\n }\n\n #navigateUp(): void {\n this.#recomputeGeometry();\n const cur = this.tickled.tickledId ? this.#positionOf(this.tickled.tickledId) : undefined;\n if (!cur) {\n this.#navigateTo(this.#findLastCheckable());\n return;\n }\n const next = this.#findNextCheckable(cur.col, cur.row, 0, -1);\n if (next) {\n this.#navigateTo(next);\n }\n }\n\n #navigateRight(): void {\n this.#recomputeGeometry();\n const cur = this.tickled.tickledId ? this.#positionOf(this.tickled.tickledId) : undefined;\n if (!cur) {\n this.#navigateTo(this.#findFirstCheckable());\n return;\n }\n const next = this.#findNextCheckable(cur.col, cur.row, 1, 0);\n if (next) {\n this.#navigateTo(next);\n } else if (this.itemWrap === `wrap`) {\n this.#navigateTo(this.#findFirstCheckable());\n }\n }\n\n #navigateLeft(): void {\n this.#recomputeGeometry();\n const cur = this.tickled.tickledId ? this.#positionOf(this.tickled.tickledId) : undefined;\n if (!cur) {\n this.#navigateTo(this.#findFirstCheckable());\n return;\n }\n const next = this.#findNextCheckable(cur.col, cur.row, -1, 0);\n if (next) {\n this.#navigateTo(next);\n } else if (this.itemWrap === `wrap`) {\n this.#navigateTo(this.#findLastCheckable());\n }\n }\n\n // --- Helpers ---\n\n private _getVisibleItems(): Element[] {\n return Array.from(this.querySelectorAll(ITEM_SELECTOR)).filter((el) => {\n if ((el as HTMLElement).hidden)\n return false;\n if (this.filterPredicate && !this.filterPredicate(el))\n return false;\n return true;\n });\n }\n\n /**\n * Set the column width to fit the widest visible item.\n *\n * This is opt-in; detail lists continue to use `--detail-list-column-width`\n * (or its 220px fallback) until this method is called. The measured value is\n * set directly on this element, so it takes precedence over an inherited\n * value. Returns the applied width in pixels, or 0 when there are no items.\n */\n async fitColumnWidth(): Promise<number> {\n await this.updateComplete;\n\n const items = this._getVisibleItems();\n if (items.length === 0)\n return 0;\n\n const previousWidth = this.style.getPropertyValue(`--detail-list-column-width`);\n const previousPriority = this.style.getPropertyPriority(`--detail-list-column-width`);\n this.style.setProperty(`--detail-list-column-width`, `max-content`);\n\n // Reading the layout forces the temporary max-content width to resolve.\n const width = Math.ceil(Math.max(...items.map(item => item.getBoundingClientRect().width)));\n\n if (previousWidth) {\n this.style.setProperty(`--detail-list-column-width`, previousWidth, previousPriority);\n } else {\n this.style.removeProperty(`--detail-list-column-width`);\n }\n this.style.setProperty(`--detail-list-column-width`, `${width}px`);\n this.#scheduleGeometry();\n return width;\n }\n\n private _isCheckable(item: Element): boolean {\n if (this.interactionMode !== `checked`)\n return true;\n return !item.hasAttribute(`not-checked`);\n }\n\n private _setLabel(li: HTMLLIElement, label: string): void {\n const span = document.createElement(`span`);\n span.style.cssText = LABEL_SPAN_CSS;\n span.textContent = label;\n li.appendChild(span);\n li.setAttribute(`data-search-label`, label);\n }\n\n /**\n * Inject a leading `<ixfx-icon>` into an item carrying `data-icon`.\n * Idempotent — skips when the item already starts with an icon.\n */\n #ensureIcon(li: HTMLLIElement): void {\n const name = li.getAttribute(`data-icon`);\n if (!name)\n return;\n if (li.firstElementChild?.tagName === `IXFX-ICON`)\n return;\n const icon = document.createElement(`ixfx-icon`);\n icon.setAttribute(`name`, name);\n icon.style.marginInlineEnd = `var(--detail-list-icon-gap, 6px)`;\n icon.style.flexShrink = `0`;\n li.prepend(icon);\n }\n\n /** Scan light-DOM children for unprocessed `data-icon` items. */\n #processChildren(): void {\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n this.#ensureIcon(el as HTMLLIElement);\n }\n }\n\n private _syncItemStates(): void {\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n el.toggleAttribute(`data-tickled`, this.tickled.isTickled(el));\n el.toggleAttribute(`data-selected`, this.selection.selected.has(el));\n if (this.interactionMode === `checked`) {\n el.toggleAttribute(\n `data-checked`,\n !el.hasAttribute(`not-checked`) && this.selection.selected.has(el),\n );\n } else {\n el.removeAttribute(`data-checked`);\n }\n }\n this.dataset.inputMode = this.tickled.inputMode;\n this._syncCheckboxes();\n }\n\n private _syncCheckboxes(): void {\n const inCheckedMode = this.interactionMode === `checked`;\n const wantsCustom = typeof this.checkboxRenderer === `function`;\n\n for (const el of this.querySelectorAll<HTMLElement>(`li`)) {\n const existing = el.querySelector<HTMLElement>(`.ixfx-list-checkbox`);\n if (!inCheckedMode) {\n if (existing)\n existing.remove();\n continue;\n }\n // Rows marked `not-checked` get no checkbox column and can't be checked\n if (el.hasAttribute(`not-checked`)) {\n if (existing)\n existing.remove();\n continue;\n }\n\n const existingIsCustom = existing?.classList.contains(`ixfx-list-checkbox-custom`) ?? false;\n if (existing && existingIsCustom !== wantsCustom)\n existing.remove();\n\n let cb: HTMLElement | null = el.querySelector<HTMLElement>(`.ixfx-list-checkbox`);\n if (!cb) {\n if (wantsCustom) {\n const opts = this.checkboxRenderer as CustomCheckboxOptions;\n const margin = opts.margin ?? `0`;\n const width = opts.width ?? `24px`;\n cb = this._createCustomCheckbox(el, margin, width);\n } else {\n cb = this._createNativeCheckboxCell(el);\n }\n el.prepend(cb);\n }\n\n const checked = this.selection.selected.has(el);\n if (wantsCustom) {\n cb.setAttribute(`aria-checked`, String(checked));\n cb.toggleAttribute(`data-checked`, checked);\n if (this.checkboxRenderer) {\n const renderer = typeof this.checkboxRenderer === `function`\n ? this.checkboxRenderer\n : (this.checkboxRenderer as CustomCheckboxOptions).renderer;\n render(renderer(checked), cb);\n }\n } else {\n const input = cb.querySelector<HTMLInputElement>(`input.ixfx-list-checkbox`);\n if (input)\n input.checked = checked;\n }\n }\n }\n\n /**\n * Native checkbox cell: a span that stretches to the row's full cross-axis\n * (so the entire column height is a click target) with a real `<input>`\n * centred inside. The span owns the click; the input is purely visual and\n * has `pointer-events:none` so a single click produces one toggle.\n */\n private _createNativeCheckboxCell(el: HTMLElement): HTMLSpanElement {\n const cell = document.createElement(`span`);\n cell.className = `ixfx-list-checkbox ixfx-list-checkbox-native`;\n cell.style.cssText = `display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;align-self:stretch;width:18px;margin:0 6px 0 0;cursor:pointer;pointer-events:auto`;\n cell.tabIndex = -1;\n cell.setAttribute(`role`, `checkbox`);\n cell.setAttribute(`part`, `checkbox`);\n cell.addEventListener(`click`, (e) => {\n e.stopPropagation();\n this.selection.toggle(el);\n });\n const input = document.createElement(`input`);\n input.type = `checkbox`;\n input.className = `ixfx-list-checkbox`;\n input.style.cssText = `pointer-events:none;cursor:pointer;margin:0`;\n cell.appendChild(input);\n return cell;\n }\n\n /** Custom checkbox cell: same shape as the native cell; renderer content inside. */\n private _createCustomCheckbox(el: HTMLElement, margin: string, width: string): HTMLSpanElement {\n const span = document.createElement(`span`);\n span.className = `ixfx-list-checkbox ixfx-list-checkbox-custom`;\n span.style.cssText = `display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;align-self:stretch;width:${width};margin:${margin};cursor:pointer;pointer-events:auto`;\n span.tabIndex = -1;\n span.setAttribute(`role`, `checkbox`);\n span.setAttribute(`part`, `checkbox`);\n span.addEventListener(`click`, (e) => {\n e.stopPropagation();\n this.selection.toggle(el);\n });\n return span;\n }\n\n private _findListItem(path: EventTarget[]): Element | undefined {\n for (const target of path) {\n if (!(target instanceof Element))\n continue;\n if (target === this)\n break;\n if (target.parentElement === this && target.matches(`li`))\n return target;\n }\n return undefined;\n }\n\n private _dispatch<T>(name: keyof ListElementEventMap, detail: T): void {\n this.dispatchEvent(new CustomEvent<T>(name as string, {\n detail,\n bubbles: true,\n composed: true,\n }));\n }\n\n // --- Event handlers ---\n\n private _onPointerOver = (e: PointerEvent): void => {\n const item = this._findListItem(e.composedPath());\n if (item)\n this.tickled.handlePointerEnter(item);\n };\n\n private _onPointerLeave = (e: PointerEvent): void => {\n this.tickled.handlePointerLeave(e);\n };\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this.search.isOpen)\n return;\n if ((e.ctrlKey || e.metaKey) && e.key === `a`) {\n if (this.selection.canSelectAll()) {\n e.preventDefault();\n this.selection.selectAll();\n }\n return;\n }\n\n switch (e.key) {\n case `ArrowDown`: {\n e.preventDefault();\n this.#navigateDown();\n // vscode: Shift+Arrow extends range from anchor\n if (e.shiftKey && this.interactionMode === `vscode`) {\n const cur = this.tickled.tickledId;\n if (cur)\n this.selection.rangeTo(cur);\n }\n break;\n }\n case `ArrowUp`: {\n e.preventDefault();\n this.#navigateUp();\n if (e.shiftKey && this.interactionMode === `vscode`) {\n const cur = this.tickled.tickledId;\n if (cur)\n this.selection.rangeTo(cur);\n }\n break;\n }\n case `ArrowRight`: {\n e.preventDefault();\n this.#navigateRight();\n break;\n }\n case `ArrowLeft`: {\n e.preventDefault();\n this.#navigateLeft();\n break;\n }\n case `Home`: {\n e.preventDefault();\n this.#navigateTo(this.#findFirstCheckable());\n break;\n }\n case `End`: {\n e.preventDefault();\n this.#navigateTo(this.#findLastCheckable());\n break;\n }\n case `Enter`: {\n const id = this.tickled.tickledId;\n if (id) {\n e.preventDefault();\n this._dispatch<ListItemClickDetail>(`list-item-click`, { item: id });\n this._activateItem(id);\n }\n break;\n }\n case ` `: {\n const id = this.tickled.tickledId;\n if (id) {\n e.preventDefault();\n this.selection.handleSpace(id);\n }\n break;\n }\n case `Escape`:\n this.selection.clear();\n break;\n }\n };\n\n private _onClick = (e: MouseEvent): void => {\n const item = this._findListItem(e.composedPath());\n if (!item)\n return;\n this.focus();\n this._dispatch<ListItemClickDetail>(`list-item-click`, { item });\n this.selection.handleClick(item, e);\n };\n\n private _onDblClick = (e: MouseEvent): void => {\n const item = this._findListItem(e.composedPath());\n if (item)\n this._activateItem(item);\n };\n\n private _onWheel = (e: WheelEvent): void => {\n e.preventDefault();\n this._listEl.scrollLeft += e.deltaY;\n };\n\n private _activateItem(item: Element): void {\n // manual mode: never auto-select; just fire the event\n if (this.interactionMode !== `manual`) {\n this.selection.replace(item);\n }\n this._dispatch<ListActivateDetail>(`list-activate`, { item });\n }\n\n // --- Styles ---\n\n static override styles = [themeFallbacks, scrollFadeStyles(`x`), listSearchStyles, css`\n :host {\n display: block;\n position: relative;\n background: var(--detail-list-bg, var(--surface-3));\n color: var(--detail-list-text, var(--surface-3-text));\n border-radius: var(--detail-list-radius, var(--radius-s));\n border: 1px solid var(--detail-list-border, var(--border));\n width: 100%;\n height: 100%;\n overflow: hidden;\n box-sizing: border-box;\n outline: none;\n --_detail-list-item-padding:\n var(--ixfx-detail-list-item-padding, var(--detail-list-item-padding, 0 var(--space-xs, 3px)));\n }\n\n :host(:focus-visible) {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n\n .container {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n ul {\n list-style: none;\n margin: 0;\n padding: 0;\n /* keep the last column clear of the scrollbar / right edge */\n padding-inline-end: calc(var(--detail-list-column-gap, 8px) + 4px);\n width: 100%;\n height: 100%;\n display: flex;\n flex-flow: column wrap;\n align-content: flex-start;\n column-gap: var(--detail-list-column-gap, 8px);\n overflow-x: auto;\n overflow-y: hidden;\n box-sizing: border-box;\n /* Scrollbar theming: consumers override these CSS variables to control\n the native scrollbar (scrollbar-width, scrollbar-gutter, scrollbar-color). */\n scrollbar-width: var(--detail-list-scrollbar-width, auto);\n scrollbar-gutter: var(--detail-list-scrollbar-gutter, auto);\n scrollbar-color: var(--detail-list-scrollbar-color, auto);\n }\n\n ::slotted([hidden]) {\n display: none !important;\n }\n\n ::slotted(li) {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n flex: none;\n width: var(--detail-list-column-width, 220px);\n height: var(--detail-list-item-height, 28px);\n padding: var(--_detail-list-item-padding);\n cursor: pointer;\n user-select: none;\n transition: background var(--transition, 0.1s ease-out),\n outline-color var(--transition, 0.1s ease-out);\n outline: 1px solid transparent;\n }\n\n /* In checked mode, only the checkbox column is clickable; the row body\n gets a default cursor so it doesn't suggest otherwise. */\n :host([interaction-mode=\"checked\"]) ::slotted(li) {\n cursor: default;\n }\n\n ::slotted([data-tickled]) {\n background: var(--item-bg-tickled);\n outline: var(--item-border-tickled);\n }\n\n ::slotted([data-selected]) {\n background: var(--item-bg-selected);\n color: var(--item-text-selected);\n outline: 1px solid transparent;\n }\n\n ::slotted([data-selected][data-tickled]) {\n background: var(--item-bg-selected-tickled);\n outline: 2px dashed var(--surface-3);\n outline-offset: -2px;\n }\n\n /* checked mode: the injected checkbox communicates selection — suppress bg */\n :host([interaction-mode=\"checked\"]) ::slotted([data-selected]) {\n background: transparent;\n color: inherit;\n outline: 1px solid transparent;\n }\n\n :host([interaction-mode=\"checked\"]) ::slotted([data-selected][data-tickled]) {\n background: var(--item-bg-tickled);\n color: inherit;\n outline: var(--item-border-tickled);\n }\n\n .loading {\n position: absolute;\n bottom: 8px;\n right: 8px;\n z-index: 10;\n background: var(--surface-4, #2a2a2a);\n border: 1px solid var(--border, #444);\n border-radius: var(--radius-m, 4px);\n padding: 2px 8px;\n font-size: var(--text-s, 11px);\n color: var(--surface-muted-text, #888);\n }\n\n .loading[hidden] {\n display: none;\n }\n `];\n\n // --- Render ---\n\n override render() {\n const loading = this.#data.loading;\n const progress = this.#data.progress;\n return html`\n <div class=\"container\">\n <ul part=\"list\" class=\"scroll-fade-x\">\n <slot></slot>\n </ul>\n <div class=\"loading\" part=\"loading\" ?hidden=${!loading}>\n ${loading\n ? (progress !== undefined ? `${Math.round(progress * 100)}%` : `loading…`)\n : nothing}\n </div>\n ${this.search.renderField()}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-detail-list': DetailListElement;\n }\n\n interface HTMLElementEventMap extends ListElementEventMap {}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"detail-list.js","names":["#dragSelect","#marqueeHitTest","#marqueeRect","#navigateDown","#navigateUp","#navigateRight","#navigateLeft","#navigateTo","#findFirstCheckable","#findLastCheckable","#data","#searchRegistry","#effectiveSearchModes","#unregisterSearchCommands","#resizeObserver","#scheduleGeometry","#mutationObserver","#processChildren","#animateChildMutations","#animatedItems","#syncSearchCommands","#applyFilterPredicate","#recomputeGeometry","#builtFromProvider","#providerBuilt","#rebuildFromObjects","#syncFromProvider","#applySort","#ensureIcon","#itemData","#itemForKey","#createItemEl","#propertyValue","#geometryScheduled","#grid","#positions","#gridSize","#itemAt","#positionOf","#findNextCheckable","#marqueeStyle","customElement"],"sources":["../src/detail-list/detail-list.ts"],"sourcesContent":["import type { CommandId, CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { IDataProvider } from '../common/data-provider.js';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type { DragSelectRect } from '../interaction/list-drag-select-controller.js';\nimport type {\n ListActivateDetail,\n ListElementEventMap,\n ListInteractionMode,\n ListItemClickDetail,\n ListSelectDetail,\n ListSelectionMode,\n ListTickleDetail,\n} from '../interaction/list-selection-types.js';\nimport type {\n AddItemOptions,\n CustomCheckboxOptions,\n DetailFormatter,\n DetailSortComparator,\n DetailSortItem,\n DetailSortMode,\n} from './types.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { css, html, LitElement, nothing, render } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { DataController } from '../common/data-controller.js';\nimport {\n createElementListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { keyForElement } from '../interaction/keyed-list.js';\nimport { ListDragSelectController } from '../interaction/list-drag-select-controller.js';\nimport { animateListItemIn, animateListItemOut, LIST_ITEM_MOTION_MS } from '../interaction/list-item-animation.js';\nimport { ListSelectionController } from '../interaction/list-selection-controller.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { scrollFadeStyles } from '../styles/scroll-fade.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../icons/icon.js';\n\nexport type {\n AddItemOptions,\n CustomCheckboxOptions,\n DetailFormatter,\n DetailSortComparator,\n DetailSortItem,\n DetailSortMode,\n} from './types.js';\n\nconst ITEM_SELECTOR = `:scope > li`;\nconst SEARCH_HIGHLIGHT_KEY = `detail-list-search`;\nconst LABEL_SPAN_CSS = `overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0`;\n\ntype GridPosition = { readonly col: number; readonly row: number };\n\n/**\n * A list that scales horizontally, not vertically.\n *\n * Items are laid out in equal-width columns; they flow top→bottom down a\n * column, then wrap to the top of the next column to the right. The\n * component has a fixed vertical extent and scrolls horizontally.\n *\n * Selection semantics match `ixfx-vertical-list` — same modes, same\n * `list-*` events, same keyboard gestures — but navigation is a 2-D grid\n * (Up/Down move within a column, Left/Right jump columns).\n *\n * Items come from any of three sources (later writes win):\n * 1. declarative `<li>` children in light DOM,\n * 2. `addItem()` / `setItems()`,\n * 3. an `items` array of objects rendered via `displayProperty` /\n * `formatter`, optionally streamed in via a `provider`.\n */\n@customElement(`ixfx-detail-list`)\nexport class DetailListElement extends LitElement {\n @property({ type: String, attribute: `selection-mode` })\n selectionMode: ListSelectionMode = `single`;\n\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: ListInteractionMode = `standard`;\n\n @property({ type: String })\n sort: DetailSortMode = `none`;\n\n @property({ type: String, attribute: `sort-by` })\n sortBy = ``;\n\n @property({ attribute: false })\n sortComparator: DetailSortComparator | undefined;\n\n @property({ attribute: false })\n items: readonly unknown[] = [];\n\n @property({ attribute: false })\n provider: IDataProvider<void, unknown> | undefined;\n\n @property({ type: String, attribute: `display-property` })\n displayProperty = ``;\n\n @property({ attribute: false })\n formatter: DetailFormatter | undefined;\n\n @property({ type: String, attribute: `icon-property` })\n iconProperty = ``;\n\n @property({ type: String, attribute: `key-property` })\n keyProperty = ``;\n\n @property({ attribute: false })\n filterPredicate: ((el: Element) => boolean) | undefined;\n\n /**\n * Whether keyboard navigation wraps from last to first and vice versa.\n * - 'stop' (default): navigation stops at the boundary\n * - 'wrap': navigation wraps around\n */\n @property({ type: String, attribute: `item-wrap` })\n itemWrap: `stop` | `wrap` = `stop`;\n\n /** Optional renderer for the checkbox shown in `checked` interactionMode. */\n @property({ attribute: false })\n checkboxRenderer: ((checked: boolean) => unknown) | CustomCheckboxOptions | undefined;\n\n /**\n * Space-separated subset of `navigate select filter` — limits which\n * incremental-search modes are offered. Unset ⇒ all three; empty ⇒ search\n * disabled. See `docs/infra-incremental.md`.\n */\n @property({ type: String, attribute: `search-modes`, reflect: true })\n searchModes: string | undefined;\n\n @query(`ul`)\n private _listEl!: HTMLUListElement;\n\n #itemData = new WeakMap<HTMLLIElement, unknown>();\n #grid: Element[][] = [];\n #positions = new Map<Element, GridPosition>();\n #geometryScheduled = false;\n #resizeObserver: ResizeObserver | undefined;\n #mutationObserver: MutationObserver | undefined;\n /** Items that have already played (or been skipped for) their enter animation. */\n #animatedItems = new WeakSet<Element>();\n #builtFromProvider: readonly unknown[] = [];\n #providerBuilt = 0;\n\n readonly #data = new DataController<void, unknown>(this);\n\n private readonly selection = new ListSelectionController<Element>({\n getOrderedItems: () => this._getVisibleItems(),\n isSelectable: el => this._isCheckable(el),\n getModes: () => ({ selectionMode: this.selectionMode, interactionMode: this.interactionMode }),\n getKey: keyForElement,\n onChange: (selected, previous) => {\n this._syncItemStates();\n this._dispatch<ListSelectDetail>(`list-select`, {\n selected,\n previous,\n selectedKeys: this.selection.selectedKeys,\n });\n },\n });\n\n private tickled = new TickledController<Element>(this, {\n getItems: () => this._getVisibleItems().map(el => ({\n id: el,\n enabled: !el.hasAttribute(`not-checked`),\n })),\n onTickle: (id) => {\n if (id !== undefined) {\n this._dispatch<ListTickleDetail>(`list-tickle`, { item: id });\n }\n },\n onStateChange: () => this._syncItemStates(),\n itemWrap: this.itemWrap,\n hoverDisabled: () => this.#dragSelect.isDragging,\n });\n\n /** Live drag-select preview rect (surface-relative); the covered items carry `data-marquee`. */\n #marqueeRect: DragSelectRect | undefined;\n\n readonly #dragSelect = new ListDragSelectController<Element>(this, {\n getSurface: () => this.renderRoot.querySelector(`.container`) as HTMLElement | undefined,\n isEnabled: () =>\n this.selection.canDragSelect()\n && this._getVisibleItems().length > 0\n && !this.hasAttribute(`disable-drag-select`),\n hitTest: rect => this.#marqueeHitTest(rect),\n getBaseSelection: () => this.selection.selected,\n onPreview: (preview, rect) => {\n this.#marqueeRect = rect;\n for (const el of this._getVisibleItems())\n el.toggleAttribute(`data-marquee`, preview.has(el));\n this.requestUpdate();\n },\n onCommit: (finalSet) => {\n this.selection.applyDragSelection(finalSet);\n for (const el of this._getVisibleItems())\n el.removeAttribute(`data-marquee`);\n this.#marqueeRect = undefined;\n this.requestUpdate();\n },\n autoScroll: (dx, _dy) => {\n if (this._listEl)\n this._listEl.scrollLeft += dx;\n },\n });\n\n /** Collect visible items whose surface-relative box intersects `rect`. */\n #marqueeHitTest(rect: DragSelectRect): Element[] {\n const surface = this.renderRoot.querySelector(`.container`);\n if (!surface)\n return [];\n const box = surface.getBoundingClientRect();\n const rx0 = rect.x;\n const ry0 = rect.y;\n const rx1 = rect.x + rect.width;\n const ry1 = rect.y + rect.height;\n const out: Element[] = [];\n for (const el of this._getVisibleItems()) {\n const r = el.getBoundingClientRect();\n const left = r.left - box.left;\n const top = r.top - box.top;\n if (left <= rx1 && left + r.width >= rx0 && top <= ry1 && top + r.height >= ry0)\n out.push(el);\n }\n return out;\n }\n\n #marqueeStyle(rect: DragSelectRect): string {\n return `left:${rect.x}px;top:${rect.y}px;width:${Math.max(0, rect.width)}px;height:${Math.max(0, rect.height)}px`;\n }\n\n /** Incremental search (navigate / select / filter). See `docs/infra-incremental.md`. */\n readonly search = new ListSearchController<Element>(this, {\n adapter: createElementListSearchAdapter(this, {\n itemSelector: ITEM_SELECTOR,\n getLabel: el => el.getAttribute(`data-search-label`) ?? el.textContent?.trim() ?? ``,\n highlightKey: SEARCH_HIGHLIGHT_KEY,\n }),\n });\n\n #searchRegistry: CommandRegistry<unknown> | undefined;\n #unregisterSearchCommands: (() => void) | undefined;\n\n /** Command registry carrying this list's `list.search.*` commands. */\n get registry(): CommandRegistry<unknown> | undefined {\n return this.#searchRegistry;\n }\n\n #effectiveSearchModes(): ListSearchMode[] {\n const raw = this.searchModes?.trim();\n if (raw === undefined)\n return [...LIST_SEARCH_MODES];\n const requested = new Set(raw.split(/\\s+/));\n return LIST_SEARCH_MODES.filter(m => requested.has(m));\n }\n\n #syncSearchCommands(): void {\n if (!this.#searchRegistry)\n return;\n this.search.setModes(this.#effectiveSearchModes());\n this.#unregisterSearchCommands?.();\n this.#unregisterSearchCommands = registerListSearchCommands(this.#searchRegistry, this.search);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute(`tabindex`))\n this.tabIndex = 0;\n this.addEventListener(`pointerover`, this._onPointerOver);\n this.addEventListener(`pointerleave`, this._onPointerLeave);\n this.addEventListener(`keydown`, this._onKeyDown);\n this.addEventListener(`click`, this._onClick);\n this.addEventListener(`dblclick`, this._onDblClick);\n this.addEventListener(`wheel`, this._onWheel);\n\n this.#resizeObserver = new ResizeObserver(() => this.#scheduleGeometry());\n this.#resizeObserver.observe(this);\n this.#mutationObserver = new MutationObserver((records) => {\n this.#processChildren();\n this.#animateChildMutations(records);\n this.#scheduleGeometry();\n });\n this.#mutationObserver.observe(this, {\n childList: true,\n subtree: false,\n attributeFilter: [`hidden`],\n });\n for (const el of this.querySelectorAll(ITEM_SELECTOR))\n this.#animatedItems.add(el);\n this.#searchRegistry ??= createCommandRegistry();\n this.#syncSearchCommands();\n }\n\n /**\n * Collapse-in items appended to the light DOM (however they got there). A bulk\n * populate is left alone. Geometry is re-read once the animations settle so\n * keyboard navigation lines back up with the final layout.\n */\n #animateChildMutations(records: MutationRecord[]): void {\n if (!this.isConnected)\n return;\n const fresh: HTMLElement[] = [];\n for (const record of records) {\n for (const node of record.addedNodes) {\n // ITEM_SELECTOR is `:scope > li`, which can't be used with `.matches()`\n // — every item here is a direct `<li>` child, so check that directly.\n if (!(node instanceof HTMLElement) || node.parentElement !== this || node.localName !== `li`)\n continue;\n if (this.#animatedItems.has(node))\n continue;\n this.#animatedItems.add(node);\n fresh.push(node);\n }\n }\n if (fresh.length === 0)\n return;\n const total = this.querySelectorAll(ITEM_SELECTOR).length;\n if (fresh.length >= total)\n return; // first populate / wholesale replace\n for (const el of fresh)\n animateListItemIn(el);\n window.setTimeout(() => this.#scheduleGeometry(), LIST_ITEM_MOTION_MS + 30);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`pointerover`, this._onPointerOver);\n this.removeEventListener(`pointerleave`, this._onPointerLeave);\n this.removeEventListener(`keydown`, this._onKeyDown);\n this.removeEventListener(`click`, this._onClick);\n this.removeEventListener(`dblclick`, this._onDblClick);\n this.removeEventListener(`wheel`, this._onWheel);\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n this.#mutationObserver?.disconnect();\n this.#mutationObserver = undefined;\n this.#unregisterSearchCommands?.();\n this.#unregisterSearchCommands = undefined;\n this.#searchRegistry = undefined;\n }\n\n override firstUpdated(): void {\n this.#processChildren();\n if (this.filterPredicate) {\n this.#applyFilterPredicate();\n }\n this.#recomputeGeometry();\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n if (changed.has(`searchModes`)) {\n this.#syncSearchCommands();\n }\n if (changed.has(`provider`)) {\n this.#builtFromProvider = [];\n this.#providerBuilt = 0;\n this.#data.provider = this.provider;\n queueMicrotask(() => {\n if (this.provider)\n this.#data.request(undefined);\n });\n return;\n }\n if (changed.has(`items`) && this.provider === undefined && this.items.length > 0) {\n this.#rebuildFromObjects(this.items);\n }\n this.#syncFromProvider();\n if (changed.has(`sort`) || changed.has(`sortBy`) || changed.has(`sortComparator`)) {\n this.#applySort();\n }\n if (changed.has(`filterPredicate`)) {\n this.#applyFilterPredicate();\n this.#scheduleGeometry();\n }\n if (changed.has(`interactionMode`)) {\n this.selection.clearAnchor();\n this._syncItemStates();\n } else if (changed.has(`checkboxRenderer`) && this.interactionMode === `checked`) {\n this._syncCheckboxes();\n }\n }\n\n // --- Public API ---\n\n /** The most recently selected item, or `undefined` if nothing is selected. */\n get selectedItem(): Element | undefined {\n return [...this.selection.selected].at(-1);\n }\n\n /** The full current selection set (read-only). */\n get selectedItems(): ReadonlySet<Element> {\n return this.selection.selected;\n }\n\n /**\n * Force an immediate geometry recompute. Called automatically on resize,\n * DOM changes, sort/filter/search changes — only needed when layout is\n * changed by outside forces (e.g. an external font load).\n */\n refreshLayout(): void {\n this.#recomputeGeometry();\n }\n\n addItem(item: Element | string, options?: AddItemOptions): void {\n let el: Element;\n if (typeof item === `string`) {\n const li = document.createElement(`li`);\n this._setLabel(li, item);\n el = li;\n } else {\n el = item;\n }\n if (options?.notChecked)\n el.setAttribute(`not-checked`, ``);\n this.appendChild(el);\n this.#ensureIcon(el as HTMLLIElement);\n if (this.sort !== `none`)\n this.#applySort();\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n }\n\n /**\n * Collapse + fade `item` out, then detach it; the rows after it slide up to\n * close the gap. Resolves once removed. Immediate under reduced motion.\n */\n removeItem(item: Element): Promise<void> {\n this.selection.deselect(item);\n return animateListItemOut(item as HTMLElement).then(() => {\n item.remove();\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n this.#recomputeGeometry();\n });\n }\n\n /** {@link removeItem} for several items at once. */\n removeItems(items: Iterable<Element>): Promise<void> {\n return Promise.all([...items].map(item => this.removeItem(item))).then(() => undefined);\n }\n\n clearItems(): void {\n this.replaceChildren();\n this.selection.reset();\n this.#builtFromProvider = [];\n this.#providerBuilt = 0;\n this._syncItemStates();\n }\n\n /**\n * Replace the entire item list in one call.\n * Equivalent to `clearItems()` followed by `addItem()` for each element.\n */\n setItems(items: readonly Element[]): void {\n this.clearItems();\n for (const item of items) {\n this.appendChild(item);\n this.#ensureIcon(item as HTMLLIElement);\n }\n if (this.sort !== `none`)\n this.#applySort();\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n }\n\n /**\n * Get the source object behind an `<li>` built from an `items` array or\n * provider. Returns `undefined` for declarative / programmatic elements.\n */\n getItemData(item: HTMLLIElement): unknown {\n return this.#itemData.get(item);\n }\n\n /**\n * Dispatch a command to this list — used by `ixfx-grouped-item-lister` to\n * forward commands. Routes through the command registry (so `list.search.*`\n * and any other registered commands work).\n */\n dispatch(commandId: CommandId, args?: Record<string, unknown>): void {\n this.#searchRegistry?.invoke(commandId, args);\n }\n\n select(item: Element): void {\n this.selection.replace(item);\n }\n\n selectMany(items: Iterable<Element>): void {\n this.selection.selectMany(items);\n }\n\n deselect(item: Element): void {\n this.selection.deselect(item);\n }\n\n clearSelection(): void {\n this.selection.clear();\n }\n\n selectAll(): void {\n if (this.selection.canSelectAll())\n this.selection.selectAll();\n }\n\n // --- Key-based selection & cursor ---\n\n /** The selection as stable `data-key` / `data-value` strings. */\n get selectedKeys(): ReadonlySet<string> {\n return this.selection.selectedKeys;\n }\n\n /** The key of the item under the cursor, or `undefined`. */\n get tickledKey(): string | undefined {\n const id = this.tickled.tickledId;\n return id ? keyForElement(id) : undefined;\n }\n\n /** Replace the selection with the items carrying these keys (unknown keys ignored). */\n selectKeys(keys: Iterable<string>): void {\n this.selection.selectKeys(keys, key => this.#itemForKey(key));\n }\n\n /** Add items by key to the selection (multi-select modes only). */\n addSelectedKeys(keys: Iterable<string>): void {\n this.selection.addKeys(keys, key => this.#itemForKey(key));\n }\n\n /** Remove items by key from the selection. */\n removeSelectedKeys(keys: Iterable<string>): void {\n this.selection.removeKeys(keys, key => this.#itemForKey(key));\n }\n\n /** Move the cursor to the item with this key and scroll it into view. */\n focusKey(key: string): void {\n const el = this.#itemForKey(key);\n if (!el)\n return;\n this.tickled.focus(el);\n el.scrollIntoView({ block: `nearest`, inline: `nearest` });\n }\n\n #itemForKey(key: string): Element | undefined {\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n if (keyForElement(el) === key)\n return el;\n }\n return undefined;\n }\n\n * selectedFilter(kind: `selected` | `checked` | `either`): Generator<Element> {\n const wanted = (el: Element) => {\n switch (kind) {\n case `selected`: return el.hasAttribute(`data-selected`);\n case `checked`: return el.hasAttribute(`data-checked`);\n case `either`: return el.hasAttribute(`data-selected`) || el.hasAttribute(`data-checked`);\n }\n };\n\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n if ((el as HTMLElement).hidden)\n continue;\n if (wanted(el))\n yield el;\n }\n }\n\n // --- Object items ---\n\n #rebuildFromObjects(items: readonly unknown[]): void {\n const keyOf = (el: Element): string | null =>\n el.getAttribute(`data-key`) ?? el.getAttribute(`data-search-label`) ?? null;\n const previousKeys = new Set(\n [...this.selection.selected].map(keyOf).filter((k): k is string => k !== null),\n );\n const anchorKey = this.selection.anchor ? keyOf(this.selection.anchor) : null;\n\n this.replaceChildren(...items.map((item, index) => this.#createItemEl(item, index)));\n\n // Re-select by key so selection survives the element-reference rebuild\n if (previousKeys.size > 0 || anchorKey !== null) {\n const next: Element[] = [];\n let anchor: Element | undefined;\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n const key = keyOf(el);\n if (key !== null && previousKeys.has(key))\n next.push(el);\n if (key !== null && key === anchorKey)\n anchor = el;\n }\n this.selection.seed(next, anchor);\n }\n\n if (this.sort !== `none`)\n this.#applySort();\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n this._syncItemStates();\n this.#scheduleGeometry();\n }\n\n #createItemEl(item: unknown, index: number): HTMLLIElement {\n const li = document.createElement(`li`);\n this.#itemData.set(li, item);\n\n const content = this.formatter\n ? this.formatter(item, index)\n : (this.displayProperty\n ? this.#propertyValue(item, this.displayProperty)\n : item);\n if (typeof content === `string`) {\n this._setLabel(li, content);\n if (this.iconProperty) {\n const icon = this.#propertyValue(item, this.iconProperty);\n if (typeof icon === `string` && icon.length > 0)\n li.setAttribute(`data-icon`, icon);\n }\n } else if (content instanceof Node) {\n li.appendChild(content);\n }\n\n if (this.keyProperty) {\n const key = this.#propertyValue(item, this.keyProperty);\n if (key !== undefined && key !== null)\n li.setAttribute(`data-key`, String(key));\n }\n this.#ensureIcon(li);\n return li;\n }\n\n #propertyValue(item: unknown, prop: string): unknown {\n if (typeof item !== `object` || item === null || !(prop in item))\n return undefined;\n return (item as Record<string, unknown>)[prop];\n }\n\n // --- Provider (async) items ---\n\n #syncFromProvider(): void {\n if (this.provider === undefined)\n return;\n const items = this.#data.items;\n if (items === this.#builtFromProvider)\n return;\n\n // Longest common prefix by identity — pure appends extend the columns,\n // anything else rebuilds.\n let prefix = 0;\n while (\n prefix < this.#builtFromProvider.length\n && prefix < items.length\n && this.#builtFromProvider[prefix] === items[prefix]\n ) {\n prefix++;\n }\n\n if (prefix === this.#builtFromProvider.length && prefix <= items.length) {\n const tail = items.slice(prefix);\n for (const item of tail) {\n this.appendChild(this.#createItemEl(item, this.#providerBuilt++));\n }\n if (this.sort !== `none`)\n this.#applySort();\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n this._syncItemStates();\n this.#scheduleGeometry();\n } else {\n this.#providerBuilt = 0;\n this.#rebuildFromObjects(items);\n }\n this.#builtFromProvider = items;\n }\n\n // --- Filtering ---\n\n #applyFilterPredicate(): void {\n if (!this.filterPredicate) {\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n el.removeAttribute(`hidden`);\n }\n return;\n }\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n if (this.filterPredicate(el)) {\n el.removeAttribute(`hidden`);\n } else {\n el.setAttribute(`hidden`, ``);\n }\n }\n }\n\n // --- Sorting ---\n\n #applySort(): void {\n if (this.sort === `none`)\n return;\n const rows = [...this.querySelectorAll(ITEM_SELECTOR)] as HTMLLIElement[];\n if (rows.length < 2)\n return;\n\n const dir = this.sort === `descending` ? -1 : 1;\n const meta = (el: HTMLLIElement): DetailSortItem => ({\n element: el,\n data: this.getItemData(el),\n label: el.getAttribute(`data-search-label`) ?? el.textContent?.trim() ?? ``,\n });\n\n let cmp: (a: HTMLLIElement, b: HTMLLIElement) => number;\n if (this.sortComparator) {\n const user = this.sortComparator;\n cmp = (a, b) => user(meta(a), meta(b));\n } else if (this.sortBy) {\n const prop = this.sortBy;\n const key = (el: HTMLLIElement): string | number => {\n const v = this.#propertyValue(this.getItemData(el), prop);\n if (typeof v === `number`)\n return v;\n return v === undefined || v === null ? `` : String(v);\n };\n cmp = (a, b) => {\n const ka = key(a);\n const kb = key(b);\n if (typeof ka === `number` && typeof kb === `number`)\n return ka - kb;\n return String(ka).localeCompare(String(kb), undefined, { numeric: true });\n };\n } else {\n cmp = (a, b) =>\n meta(a).label.localeCompare(meta(b).label, undefined, { numeric: true });\n }\n\n const indexed = rows.map((el, i) => ({ el, i }));\n indexed.sort((a, b) => cmp(a.el, b.el) * dir || a.i - b.i); // stable\n for (const { el } of indexed)\n this.appendChild(el); // moving reorders in place\n this.#scheduleGeometry();\n }\n\n // --- Geometry (measured grid) ---\n\n #scheduleGeometry(): void {\n if (this.#geometryScheduled)\n return;\n this.#geometryScheduled = true;\n requestAnimationFrame(() => {\n this.#geometryScheduled = false;\n this.#recomputeGeometry();\n });\n }\n\n #recomputeGeometry(): void {\n this.#grid = [];\n this.#positions.clear();\n if (!this.isConnected)\n return;\n\n const columns: Array<{ left: number; items: Element[] }> = [];\n for (const el of this._getVisibleItems()) {\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0)\n continue;\n let ci = columns.findIndex(c => Math.abs(c.left - rect.left) <= 1);\n if (ci === -1) {\n columns.push({ left: rect.left, items: [] });\n ci = columns.length - 1;\n }\n columns[ci].items.push(el);\n }\n columns.sort((a, b) => a.left - b.left);\n for (const col of columns)\n col.items.sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top);\n\n this.#grid = columns.map(c => c.items);\n this.#grid.forEach((col, colIdx) =>\n col.forEach((el, rowIdx) => this.#positions.set(el, { col: colIdx, row: rowIdx })),\n );\n }\n\n #positionOf(el: Element): GridPosition | undefined {\n let pos = this.#positions.get(el);\n if (pos === undefined) {\n this.#recomputeGeometry();\n pos = this.#positions.get(el);\n }\n return pos;\n }\n\n #itemAt(col: number, row: number): Element | undefined {\n return this.#grid[col]?.[row];\n }\n\n #gridSize(): { cols: number; rows: number } {\n if (this.#grid.length === 0)\n this.#recomputeGeometry();\n return { cols: this.#grid.length, rows: Math.max(0, ...this.#grid.map(c => c.length)) };\n }\n\n // --- Keyboard navigation ---\n\n #navigateTo(target: Element | undefined): void {\n if (!target)\n return;\n this.tickled.handleKeyboardNavigation(target);\n this.tickled.tickledId?.scrollIntoView({ block: `nearest`, inline: `nearest` });\n }\n\n #findNextCheckable(fromCol: number, fromRow: number, deltaCol: number, deltaRow: number): Element | undefined {\n const { cols } = this.#gridSize();\n const visibleItems = this._getVisibleItems();\n const maxIterations = visibleItems.length + 1;\n\n // Start from the next position\n // For horizontal nav: move to next column first, keep same row\n // For vertical nav: stay in same column, move row\n // For diagonal nav: both change\n let col = deltaCol !== 0 ? fromCol + deltaCol : fromCol;\n let row = deltaRow !== 0 ? fromRow + deltaRow : fromRow;\n\n // Track whether we've tried wrapping columns\n let wrappedColumns = false;\n\n for (let iterations = 0; iterations < maxIterations; iterations++) {\n // Check bounds\n const colLength = this.#grid[col]?.length ?? 0;\n\n if (row < 0 || row >= colLength) {\n // Need to move to another column\n if (deltaCol !== 0 || wrappedColumns) {\n // Already tried wrapping, or horizontal nav - stop or wrap\n if (this.itemWrap === `wrap`) {\n // Simple wrap: if deltaCol < 0, go to last column; if deltaCol > 0, go to first\n if (deltaCol < 0) {\n col = cols - 1;\n } else if (deltaCol > 0) {\n col = 0;\n }\n wrappedColumns = true;\n } else {\n return undefined;\n }\n }\n\n // Try next/prev column\n if (deltaRow > 0) {\n // Going down - try next column at row 0\n if (col + 1 < cols) {\n col = col + 1;\n row = 0;\n wrappedColumns = true;\n } else if (this.itemWrap === `wrap`) {\n col = 0;\n row = 0;\n wrappedColumns = true;\n } else {\n return undefined;\n }\n } else if (deltaRow < 0) {\n // Going up - try prev column at last row\n if (col - 1 >= 0) {\n col = col - 1;\n row = (this.#grid[col]?.length ?? 1) - 1;\n wrappedColumns = true;\n } else if (this.itemWrap === `wrap`) {\n col = cols - 1;\n row = (this.#grid[col]?.length ?? 1) - 1;\n wrappedColumns = true;\n } else {\n return undefined;\n }\n } else if (deltaCol !== 0) {\n // Horizontal navigation - adjust row if target column is shorter\n const targetColLength = this.#grid[col]?.length ?? 0;\n if (row >= targetColLength && targetColLength > 0) {\n row = targetColLength - 1;\n }\n }\n\n // If we're now at same position as start, we've looped\n if (col === fromCol && row === fromRow + deltaRow) {\n return undefined;\n }\n continue;\n }\n\n const item = this.#itemAt(col, row);\n if (item && this._isCheckable(item)) {\n return item;\n }\n\n // Move to next position\n row += deltaRow;\n }\n\n return undefined;\n }\n\n #findFirstCheckable(): Element | undefined {\n const visibleItems = this._getVisibleItems();\n return visibleItems.find(item => this._isCheckable(item));\n }\n\n #findLastCheckable(): Element | undefined {\n const visibleItems = this._getVisibleItems();\n for (let i = visibleItems.length - 1; i >= 0; i--) {\n if (this._isCheckable(visibleItems[i])) {\n return visibleItems[i];\n }\n }\n return undefined;\n }\n\n #navigateDown(): void {\n this.#recomputeGeometry();\n const cur = this.tickled.tickledId ? this.#positionOf(this.tickled.tickledId) : undefined;\n if (!cur) {\n this.#navigateTo(this.#findFirstCheckable());\n return;\n }\n const next = this.#findNextCheckable(cur.col, cur.row, 0, 1);\n if (next) {\n this.#navigateTo(next);\n }\n }\n\n #navigateUp(): void {\n this.#recomputeGeometry();\n const cur = this.tickled.tickledId ? this.#positionOf(this.tickled.tickledId) : undefined;\n if (!cur) {\n this.#navigateTo(this.#findLastCheckable());\n return;\n }\n const next = this.#findNextCheckable(cur.col, cur.row, 0, -1);\n if (next) {\n this.#navigateTo(next);\n }\n }\n\n #navigateRight(): void {\n this.#recomputeGeometry();\n const cur = this.tickled.tickledId ? this.#positionOf(this.tickled.tickledId) : undefined;\n if (!cur) {\n this.#navigateTo(this.#findFirstCheckable());\n return;\n }\n const next = this.#findNextCheckable(cur.col, cur.row, 1, 0);\n if (next) {\n this.#navigateTo(next);\n } else if (this.itemWrap === `wrap`) {\n this.#navigateTo(this.#findFirstCheckable());\n }\n }\n\n #navigateLeft(): void {\n this.#recomputeGeometry();\n const cur = this.tickled.tickledId ? this.#positionOf(this.tickled.tickledId) : undefined;\n if (!cur) {\n this.#navigateTo(this.#findFirstCheckable());\n return;\n }\n const next = this.#findNextCheckable(cur.col, cur.row, -1, 0);\n if (next) {\n this.#navigateTo(next);\n } else if (this.itemWrap === `wrap`) {\n this.#navigateTo(this.#findLastCheckable());\n }\n }\n\n // --- Helpers ---\n\n private _getVisibleItems(): Element[] {\n return Array.from(this.querySelectorAll(ITEM_SELECTOR)).filter((el) => {\n if ((el as HTMLElement).hidden)\n return false;\n if (this.filterPredicate && !this.filterPredicate(el))\n return false;\n return true;\n });\n }\n\n /**\n * Set the column width to fit the widest visible item.\n *\n * This is opt-in; detail lists continue to use `--detail-list-column-width`\n * (or its 220px fallback) until this method is called. The measured value is\n * set directly on this element, so it takes precedence over an inherited\n * value. Returns the applied width in pixels, or 0 when there are no items.\n */\n async fitColumnWidth(): Promise<number> {\n await this.updateComplete;\n\n const items = this._getVisibleItems();\n if (items.length === 0)\n return 0;\n\n const previousWidth = this.style.getPropertyValue(`--detail-list-column-width`);\n const previousPriority = this.style.getPropertyPriority(`--detail-list-column-width`);\n this.style.setProperty(`--detail-list-column-width`, `max-content`);\n\n // Reading the layout forces the temporary max-content width to resolve.\n const width = Math.ceil(Math.max(...items.map(item => item.getBoundingClientRect().width)));\n\n if (previousWidth) {\n this.style.setProperty(`--detail-list-column-width`, previousWidth, previousPriority);\n } else {\n this.style.removeProperty(`--detail-list-column-width`);\n }\n this.style.setProperty(`--detail-list-column-width`, `${width}px`);\n this.#scheduleGeometry();\n return width;\n }\n\n private _isCheckable(item: Element): boolean {\n if (this.interactionMode !== `checked`)\n return true;\n return !item.hasAttribute(`not-checked`);\n }\n\n private _setLabel(li: HTMLLIElement, label: string): void {\n const span = document.createElement(`span`);\n span.style.cssText = LABEL_SPAN_CSS;\n span.textContent = label;\n li.appendChild(span);\n li.setAttribute(`data-search-label`, label);\n }\n\n /**\n * Inject a leading `<ixfx-icon>` into an item carrying `data-icon`.\n * Idempotent — skips when the item already starts with an icon.\n */\n #ensureIcon(li: HTMLLIElement): void {\n const name = li.getAttribute(`data-icon`);\n if (!name)\n return;\n if (li.firstElementChild?.tagName === `IXFX-ICON`)\n return;\n const icon = document.createElement(`ixfx-icon`);\n icon.setAttribute(`name`, name);\n icon.style.marginInlineEnd = `var(--detail-list-icon-gap, 6px)`;\n icon.style.flexShrink = `0`;\n li.prepend(icon);\n }\n\n /** Scan light-DOM children for unprocessed `data-icon` items. */\n #processChildren(): void {\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n this.#ensureIcon(el as HTMLLIElement);\n }\n }\n\n private _syncItemStates(): void {\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n el.toggleAttribute(`data-tickled`, this.tickled.isTickled(el));\n el.toggleAttribute(`data-selected`, this.selection.selected.has(el));\n if (this.interactionMode === `checked`) {\n el.toggleAttribute(\n `data-checked`,\n !el.hasAttribute(`not-checked`) && this.selection.selected.has(el),\n );\n } else {\n el.removeAttribute(`data-checked`);\n }\n }\n this.dataset.inputMode = this.tickled.inputMode;\n this._syncCheckboxes();\n }\n\n private _syncCheckboxes(): void {\n const inCheckedMode = this.interactionMode === `checked`;\n const wantsCustom = typeof this.checkboxRenderer === `function`;\n\n for (const el of this.querySelectorAll<HTMLElement>(`li`)) {\n const existing = el.querySelector<HTMLElement>(`.ixfx-list-checkbox`);\n if (!inCheckedMode) {\n if (existing)\n existing.remove();\n continue;\n }\n // Rows marked `not-checked` get no checkbox column and can't be checked\n if (el.hasAttribute(`not-checked`)) {\n if (existing)\n existing.remove();\n continue;\n }\n\n const existingIsCustom = existing?.classList.contains(`ixfx-list-checkbox-custom`) ?? false;\n if (existing && existingIsCustom !== wantsCustom)\n existing.remove();\n\n let cb: HTMLElement | null = el.querySelector<HTMLElement>(`.ixfx-list-checkbox`);\n if (!cb) {\n if (wantsCustom) {\n const opts = this.checkboxRenderer as CustomCheckboxOptions;\n const margin = opts.margin ?? `0`;\n const width = opts.width ?? `24px`;\n cb = this._createCustomCheckbox(el, margin, width);\n } else {\n cb = this._createNativeCheckboxCell(el);\n }\n el.prepend(cb);\n }\n\n const checked = this.selection.selected.has(el);\n if (wantsCustom) {\n cb.setAttribute(`aria-checked`, String(checked));\n cb.toggleAttribute(`data-checked`, checked);\n if (this.checkboxRenderer) {\n const renderer = typeof this.checkboxRenderer === `function`\n ? this.checkboxRenderer\n : (this.checkboxRenderer as CustomCheckboxOptions).renderer;\n render(renderer(checked), cb);\n }\n } else {\n const input = cb.querySelector<HTMLInputElement>(`input.ixfx-list-checkbox`);\n if (input)\n input.checked = checked;\n }\n }\n }\n\n /**\n * Native checkbox cell: a span that stretches to the row's full cross-axis\n * (so the entire column height is a click target) with a real `<input>`\n * centred inside. The span owns the click; the input is purely visual and\n * has `pointer-events:none` so a single click produces one toggle.\n */\n private _createNativeCheckboxCell(el: HTMLElement): HTMLSpanElement {\n const cell = document.createElement(`span`);\n cell.className = `ixfx-list-checkbox ixfx-list-checkbox-native`;\n cell.style.cssText = `display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;align-self:stretch;width:18px;margin:0 6px 0 0;cursor:pointer;pointer-events:auto`;\n cell.tabIndex = -1;\n cell.setAttribute(`role`, `checkbox`);\n cell.setAttribute(`part`, `checkbox`);\n cell.addEventListener(`click`, (e) => {\n e.stopPropagation();\n this.selection.toggle(el);\n });\n const input = document.createElement(`input`);\n input.type = `checkbox`;\n input.className = `ixfx-list-checkbox`;\n input.style.cssText = `pointer-events:none;cursor:pointer;margin:0`;\n cell.appendChild(input);\n return cell;\n }\n\n /** Custom checkbox cell: same shape as the native cell; renderer content inside. */\n private _createCustomCheckbox(el: HTMLElement, margin: string, width: string): HTMLSpanElement {\n const span = document.createElement(`span`);\n span.className = `ixfx-list-checkbox ixfx-list-checkbox-custom`;\n span.style.cssText = `display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;align-self:stretch;width:${width};margin:${margin};cursor:pointer;pointer-events:auto`;\n span.tabIndex = -1;\n span.setAttribute(`role`, `checkbox`);\n span.setAttribute(`part`, `checkbox`);\n span.addEventListener(`click`, (e) => {\n e.stopPropagation();\n this.selection.toggle(el);\n });\n return span;\n }\n\n private _findListItem(path: EventTarget[]): Element | undefined {\n for (const target of path) {\n if (!(target instanceof Element))\n continue;\n if (target === this)\n break;\n if (target.parentElement === this && target.matches(`li`))\n return target;\n }\n return undefined;\n }\n\n private _dispatch<T>(name: keyof ListElementEventMap, detail: T): void {\n this.dispatchEvent(new CustomEvent<T>(name as string, {\n detail,\n bubbles: true,\n composed: true,\n }));\n }\n\n // --- Event handlers ---\n\n private _onPointerOver = (e: PointerEvent): void => {\n const item = this._findListItem(e.composedPath());\n if (item)\n this.tickled.handlePointerEnter(item);\n };\n\n private _onPointerLeave = (e: PointerEvent): void => {\n this.tickled.handlePointerLeave(e);\n };\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this.search.isOpen)\n return;\n if ((e.ctrlKey || e.metaKey) && e.key === `a`) {\n if (this.selection.canSelectAll()) {\n e.preventDefault();\n this.selection.selectAll();\n }\n return;\n }\n\n switch (e.key) {\n case `ArrowDown`: {\n e.preventDefault();\n this.#navigateDown();\n // vscode: Shift+Arrow extends range from anchor\n if (e.shiftKey && this.interactionMode === `vscode`) {\n const cur = this.tickled.tickledId;\n if (cur)\n this.selection.rangeTo(cur);\n }\n break;\n }\n case `ArrowUp`: {\n e.preventDefault();\n this.#navigateUp();\n if (e.shiftKey && this.interactionMode === `vscode`) {\n const cur = this.tickled.tickledId;\n if (cur)\n this.selection.rangeTo(cur);\n }\n break;\n }\n case `ArrowRight`: {\n e.preventDefault();\n this.#navigateRight();\n break;\n }\n case `ArrowLeft`: {\n e.preventDefault();\n this.#navigateLeft();\n break;\n }\n case `Home`: {\n e.preventDefault();\n this.#navigateTo(this.#findFirstCheckable());\n break;\n }\n case `End`: {\n e.preventDefault();\n this.#navigateTo(this.#findLastCheckable());\n break;\n }\n case `Enter`: {\n const id = this.tickled.tickledId;\n if (id) {\n e.preventDefault();\n this._dispatch<ListItemClickDetail>(`list-item-click`, { item: id });\n this._activateItem(id);\n }\n break;\n }\n case ` `: {\n const id = this.tickled.tickledId;\n if (id) {\n e.preventDefault();\n this.selection.handleSpace(id);\n }\n break;\n }\n case `Escape`:\n this.selection.clear();\n break;\n }\n };\n\n private _onClick = (e: MouseEvent): void => {\n if (this.#dragSelect.isDragging)\n return;\n const item = this._findListItem(e.composedPath());\n if (!item)\n return;\n this.focus();\n this._dispatch<ListItemClickDetail>(`list-item-click`, { item });\n this.selection.handleClick(item, e);\n };\n\n private _onDblClick = (e: MouseEvent): void => {\n const item = this._findListItem(e.composedPath());\n if (item)\n this._activateItem(item);\n };\n\n private _onWheel = (e: WheelEvent): void => {\n e.preventDefault();\n this._listEl.scrollLeft += e.deltaY;\n };\n\n private _activateItem(item: Element): void {\n // manual mode: never auto-select; just fire the event\n if (this.interactionMode !== `manual`) {\n this.selection.replace(item);\n }\n this._dispatch<ListActivateDetail>(`list-activate`, { item });\n }\n\n // --- Styles ---\n\n static override styles = [themeFallbacks, scrollFadeStyles(`x`), listSearchStyles, css`\n :host {\n display: block;\n position: relative;\n background: var(--detail-list-bg, var(--surface-3));\n color: var(--detail-list-text, var(--surface-3-text));\n border-radius: var(--detail-list-radius, var(--radius-s));\n border: 1px solid var(--detail-list-border, var(--border));\n width: 100%;\n height: 100%;\n overflow: hidden;\n box-sizing: border-box;\n outline: none;\n --_detail-list-item-padding:\n var(--ixfx-detail-list-item-padding, var(--detail-list-item-padding, 0 var(--space-xs, 3px)));\n }\n\n :host(:focus-visible) {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n\n .container {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n ul {\n list-style: none;\n margin: 0;\n padding: 0;\n /* keep the last column clear of the scrollbar / right edge */\n padding-inline-end: calc(var(--detail-list-column-gap, 8px) + 4px);\n width: 100%;\n height: 100%;\n display: flex;\n flex-flow: column wrap;\n align-content: flex-start;\n column-gap: var(--detail-list-column-gap, 8px);\n overflow-x: auto;\n overflow-y: hidden;\n box-sizing: border-box;\n /* Scrollbar theming: consumers override these CSS variables to control\n the native scrollbar (scrollbar-width, scrollbar-gutter, scrollbar-color). */\n scrollbar-width: var(--detail-list-scrollbar-width, auto);\n scrollbar-gutter: var(--detail-list-scrollbar-gutter, auto);\n scrollbar-color: var(--detail-list-scrollbar-color, auto);\n }\n\n ::slotted([hidden]) {\n display: none !important;\n }\n\n ::slotted(li) {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n flex: none;\n width: var(--detail-list-column-width, 220px);\n height: var(--detail-list-item-height, 28px);\n padding: var(--_detail-list-item-padding);\n cursor: pointer;\n user-select: none;\n transition: background var(--transition, 0.1s ease-out),\n outline-color var(--transition, 0.1s ease-out);\n outline: 1px solid transparent;\n }\n\n /* In checked mode, only the checkbox column is clickable; the row body\n gets a default cursor so it doesn't suggest otherwise. */\n :host([interaction-mode=\"checked\"]) ::slotted(li) {\n cursor: default;\n }\n\n ::slotted([data-tickled]) {\n background: var(--item-bg-tickled);\n outline: var(--item-border-tickled);\n }\n\n ::slotted([data-selected]) {\n background: var(--item-bg-selected);\n color: var(--item-text-selected);\n outline: 1px solid transparent;\n }\n\n ::slotted([data-selected][data-tickled]) {\n background: var(--item-bg-selected-tickled);\n outline: 2px dashed var(--surface-3);\n outline-offset: -2px;\n }\n\n /* Drag-select (marquee) rectangle + covered-row preview.\n Style hooks: part=\"marquee\", --detail-list-marquee-border,\n --detail-list-marquee-fill. */\n .marquee {\n position: absolute;\n pointer-events: none;\n z-index: 5;\n border: 1px solid var(--detail-list-marquee-border, var(--accent));\n background: var(--detail-list-marquee-fill, color-mix(in srgb, var(--accent) 15%, transparent));\n }\n\n ::slotted([data-marquee]) {\n background: var(--item-bg-selected);\n color: var(--item-text-selected);\n }\n\n /* checked mode: the injected checkbox communicates selection — suppress bg */\n :host([interaction-mode=\"checked\"]) ::slotted([data-selected]) {\n background: transparent;\n color: inherit;\n outline: 1px solid transparent;\n }\n\n :host([interaction-mode=\"checked\"]) ::slotted([data-selected][data-tickled]) {\n background: var(--item-bg-tickled);\n color: inherit;\n outline: var(--item-border-tickled);\n }\n\n .loading {\n position: absolute;\n bottom: 8px;\n right: 8px;\n z-index: 10;\n background: var(--surface-4, #2a2a2a);\n border: 1px solid var(--border, #444);\n border-radius: var(--radius-m, 4px);\n padding: 2px 8px;\n font-size: var(--text-s, 11px);\n color: var(--surface-muted-text, #888);\n }\n\n .loading[hidden] {\n display: none;\n }\n `];\n\n // --- Render ---\n\n override render() {\n const loading = this.#data.loading;\n const progress = this.#data.progress;\n return html`\n <div class=\"container\">\n <ul part=\"list\" class=\"scroll-fade-x\">\n <slot></slot>\n </ul>\n ${this.#marqueeRect\n ? html`<div class=\"marquee\" part=\"marquee\" style=${this.#marqueeStyle(this.#marqueeRect)}></div>`\n : ``}\n <div class=\"loading\" part=\"loading\" ?hidden=${!loading}>\n ${loading\n ? (progress !== undefined ? `${Math.round(progress * 100)}%` : `loading…`)\n : nothing}\n </div>\n ${this.search.renderField()}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-detail-list': DetailListElement;\n }\n\n interface HTMLElementEventMap extends ListElementEventMap {}\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { t as themeFallbacks } from "./fallbacks-DNI9xt0F.js";
1
+ import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
2
2
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
3
  import { LitElement, css, html, nothing } from "lit";
4
4
  import { property, state } from "lit/decorators.js";
@@ -307,6 +307,22 @@ const _themeFallbacksCss = css`
307
307
  inherits: true;
308
308
  initial-value: 0 4px 24px rgba(0, 0, 0, 0.5);
309
309
  }
310
+ @property --deboss-3 {
311
+ syntax: '*';
312
+ inherits: true;
313
+ initial-value:
314
+ inset 1px 1px 1px 1px color-mix(in oklch, oklch(8% 0.02 240) 60%, transparent),
315
+ inset -1px -1px 1px 1px color-mix(in oklch, oklch(15% 0.02 240) 50%, transparent),
316
+ -2px -2px 1px 0px color-mix(in oklch, oklch(12% 0.02 240) 30%, transparent);
317
+ }
318
+ @property --emboss-3 {
319
+ syntax: '*';
320
+ inherits: true;
321
+ initial-value:
322
+ inset 1px 1px 1px 1px color-mix(in oklch, oklch(22% 0.02 240) 30%, transparent),
323
+ inset -1px -1px 1px 1px color-mix(in oklch, oklch(12% 0.02 240) 20%, transparent),
324
+ 2px 2px 1px 0px color-mix(in oklch, oklch(12% 0.02 240) 30%, transparent);
325
+ }
310
326
  @property --item-bg {
311
327
  syntax: '<color>';
312
328
  inherits: true;
@@ -403,4 +419,4 @@ const themeFallbacks = css``;
403
419
  //#endregion
404
420
  export { themeFallbacks as t };
405
421
 
406
- //# sourceMappingURL=fallbacks-DNI9xt0F.js.map
422
+ //# sourceMappingURL=fallbacks-BcKGq-2F.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fallbacks-DNI9xt0F.js","names":[],"sources":["../src/styles/fallbacks.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * Default fallback values for theme CSS variables.\n *\n * Uses `@property` to register each variable with an initial value that acts\n * as a fallback. This means:\n * - If the theme CSS (`src/style.css`) is loaded, its `:root` values cascade\n * in and override these defaults.\n * - If no theme CSS is loaded, these initial values ensure components still\n * have visible backgrounds, text colours, etc.\n *\n * `@property` registration is document-global — it is not scoped per shadow\n * root — so this is registered exactly once (via `_registerThemeFallbacksOnce`\n * below) rather than adopted into every component's shadow-root stylesheet.\n * Registering the same `@property` rule repeatedly across many shadow roots\n * causes Chrome to log \"Ignored @property rule\" for every repeat.\n */\nconst _themeFallbacksCss = css`\n @property --surface-0 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(5% 0.02 240);\n }\n @property --surface-1 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(8% 0.02 240);\n }\n @property --surface-2 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(12% 0.02 240);\n }\n @property --surface-2-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --surface-3 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(15% 0.02 240);\n }\n @property --surface-3-text {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(75% 0.02 240);\n }\n @property --surface-4 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(22% 0.02 240);\n }\n @property --surface-4-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --surface-5 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(19% 0.02 240);\n }\n @property --surface-5-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --surface-6 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(35% 0.02 240);\n }\n @property --surface-6-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --surface-muted-text {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(55% 0.02 240);\n }\n @property --content {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(10% 0.01 240);\n }\n @property --content-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --accent {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(60% 0.15 140);\n }\n @property --accent-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --error {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(60% 0.15 20);\n }\n @property --error-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --border {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid oklch(25% 0.02 240);\n }\n @property --border-subtle {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid oklch(18% 0.02 240);\n }\n @property --disabled-opacity {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.5;\n }\n @property --transition {\n syntax: '<time>';\n inherits: true;\n initial-value: 0.15s;\n }\n @property --prominence-idle-opacity {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.6;\n }\n @property --prominence-idle-saturate {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.4;\n }\n @property --prominence-tickled-opacity {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.85;\n }\n @property --prominence-tickled-saturate {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.8;\n }\n @property --prominence-disabled-opacity {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.3;\n }\n @property --prominence-disabled-saturate {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.1;\n }\n @property --crumb-item-bg {\n syntax: '<color>';\n inherits: true;\n initial-value: transparent;\n }\n @property --crumb-item-bg-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: var(--surface-5);\n }\n @property --crumb-item-text-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: inherit;\n }\n @property --crumb-item-border {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid transparent;\n }\n @property --crumb-item-border-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: var(--accent);\n }\n @property --crumb-item-padding {\n syntax: '*';\n inherits: true;\n initial-value: var(--space-xs);\n }\n @property --crumb-item-border-radius {\n syntax: '<length>';\n inherits: true;\n initial-value: var(--radius-m);\n }\n @property --crumb-item-gap {\n syntax: '<length>';\n inherits: true;\n initial-value: var(--space-xs);\n }\n @property --crumb-separator {\n syntax: '<color>';\n inherits: true;\n initial-value: var(--surface-muted-text);\n }\n @property --crumb-truncate-min-width {\n syntax: '<length>';\n inherits: true;\n initial-value: 5ch;\n }\n @property --space-xs {\n syntax: '<length>';\n inherits: true;\n initial-value: 3px;\n }\n @property --space-s {\n syntax: '<length>';\n inherits: true;\n initial-value: 4px;\n }\n @property --space-m {\n syntax: '<length>';\n inherits: true;\n initial-value: 8px;\n }\n @property --space-l {\n syntax: '<length>';\n inherits: true;\n initial-value: 12px;\n }\n @property --space-xl {\n syntax: '<length>';\n inherits: true;\n initial-value: 16px;\n }\n @property --space-2xl {\n syntax: '<length>';\n inherits: true;\n initial-value: 20px;\n }\n @property --text-xs {\n syntax: '<length>';\n inherits: true;\n initial-value: 9px;\n }\n @property --text-s {\n syntax: '<length>';\n inherits: true;\n initial-value: 11px;\n }\n @property --text-m {\n syntax: '<length>';\n inherits: true;\n initial-value: 12px;\n }\n @property --text-l {\n syntax: '<length>';\n inherits: true;\n initial-value: 13px;\n }\n @property --text-xl {\n syntax: '<length>';\n inherits: true;\n initial-value: 16px;\n }\n @property --text-2xl {\n syntax: '<length>';\n inherits: true;\n initial-value: 20px;\n }\n @property --font-weight-bold {\n syntax: '<number>';\n inherits: true;\n initial-value: 600;\n }\n @property --radius-s {\n syntax: '<length>';\n inherits: true;\n initial-value: 3px;\n }\n @property --radius-m {\n syntax: '<length>';\n inherits: true;\n initial-value: 4px;\n }\n @property --radius-l {\n syntax: '<length>';\n inherits: true;\n initial-value: 6px;\n }\n @property --radius-xl {\n syntax: '<length>';\n inherits: true;\n initial-value: 8px;\n }\n @property --shadow-m {\n syntax: '*';\n inherits: true;\n initial-value: 0 4px 12px rgba(0, 0, 0, 0.3);\n }\n @property --shadow-l {\n syntax: '*';\n inherits: true;\n initial-value: 0 4px 24px rgba(0, 0, 0, 0.5);\n }\n @property --item-bg {\n syntax: '<color>';\n inherits: true;\n initial-value: transparent;\n }\n @property --item-bg-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(19% 0.02 240);\n }\n @property --item-bg-selected {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(60% 0.15 140);\n }\n @property --item-bg-selected-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: color-mix(in oklch, oklch(60% 0.15 140) 80%, oklch(0% 0 0));\n }\n @property --item-text-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --item-text-selected {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --item-border {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid oklch(19% 0.02 240);\n }\n @property --item-border-tickled {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid color-mix(in oklch, oklch(60% 0.15 140) 40%, transparent);\n }\n @property --item-border-selected {\n syntax: '*';\n inherits: true;\n initial-value: 1px dashed oklch(60% 0.15 140);\n }\n @property --item-border-active {\n syntax: '*';\n inherits: true;\n initial-value: 2px solid oklch(60% 0.15 140);\n }\n @property --item-border-dragged {\n syntax: '*';\n inherits: true;\n initial-value: 2px dotted color-mix(in oklch, oklch(60% 0.15 140) 80%, transparent);\n }\n @property --item-border-disabled {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid oklch(22% 0.02 240);\n }\n @property --item-padding {\n syntax: '*';\n inherits: true;\n initial-value: 4px 8px;\n }\n @property --item-border-radius {\n syntax: '<length>';\n inherits: true;\n initial-value: 4px;\n }\n @property --item-icon-spacing {\n syntax: '<length>';\n inherits: true;\n initial-value: 4px;\n }\n`;\n\nlet _themeFallbacksRegistered = false;\n\nfunction _registerThemeFallbacksOnce(): void {\n if (_themeFallbacksRegistered || typeof document === `undefined`)\n return;\n _themeFallbacksRegistered = true;\n const styleEl = document.createElement(`style`);\n styleEl.textContent = _themeFallbacksCss.cssText;\n document.head.append(styleEl);\n}\n\n_registerThemeFallbacksOnce();\n\n/**\n * Spread this into any component whose styles reference theme variables.\n * It is an empty stylesheet — the actual `@property` rules are registered\n * once at the document level as a side effect of importing this module — so\n * this exists only to keep the familiar `static styles = [themeFallbacks, ...]`\n * pattern working across all consuming components.\n */\nexport const themeFallbacks = css``;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgX9B,IAAI,4BAA4B;AAEhC,SAAS,8BAAoC;CAC3C,IAAI,6BAA6B,OAAO,aAAa,aACnD;CACF,4BAA4B;CAC5B,MAAM,UAAU,SAAS,cAAc,OAAO;CAC9C,QAAQ,cAAc,mBAAmB;CACzC,SAAS,KAAK,OAAO,OAAO;AAC9B;AAEA,4BAA4B;;;;;;;;AAS5B,MAAa,iBAAiB,GAAG"}
1
+ {"version":3,"file":"fallbacks-BcKGq-2F.js","names":[],"sources":["../src/styles/fallbacks.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * Default fallback values for theme CSS variables.\n *\n * Uses `@property` to register each variable with an initial value that acts\n * as a fallback. This means:\n * - If the theme CSS (`src/style.css`) is loaded, its `:root` values cascade\n * in and override these defaults.\n * - If no theme CSS is loaded, these initial values ensure components still\n * have visible backgrounds, text colours, etc.\n *\n * `@property` registration is document-global — it is not scoped per shadow\n * root — so this is registered exactly once (via `_registerThemeFallbacksOnce`\n * below) rather than adopted into every component's shadow-root stylesheet.\n * Registering the same `@property` rule repeatedly across many shadow roots\n * causes Chrome to log \"Ignored @property rule\" for every repeat.\n */\nconst _themeFallbacksCss = css`\n @property --surface-0 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(5% 0.02 240);\n }\n @property --surface-1 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(8% 0.02 240);\n }\n @property --surface-2 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(12% 0.02 240);\n }\n @property --surface-2-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --surface-3 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(15% 0.02 240);\n }\n @property --surface-3-text {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(75% 0.02 240);\n }\n @property --surface-4 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(22% 0.02 240);\n }\n @property --surface-4-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --surface-5 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(19% 0.02 240);\n }\n @property --surface-5-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --surface-6 {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(35% 0.02 240);\n }\n @property --surface-6-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --surface-muted-text {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(55% 0.02 240);\n }\n @property --content {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(10% 0.01 240);\n }\n @property --content-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --accent {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(60% 0.15 140);\n }\n @property --accent-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --error {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(60% 0.15 20);\n }\n @property --error-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --border {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid oklch(25% 0.02 240);\n }\n @property --border-subtle {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid oklch(18% 0.02 240);\n }\n @property --disabled-opacity {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.5;\n }\n @property --transition {\n syntax: '<time>';\n inherits: true;\n initial-value: 0.15s;\n }\n @property --prominence-idle-opacity {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.6;\n }\n @property --prominence-idle-saturate {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.4;\n }\n @property --prominence-tickled-opacity {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.85;\n }\n @property --prominence-tickled-saturate {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.8;\n }\n @property --prominence-disabled-opacity {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.3;\n }\n @property --prominence-disabled-saturate {\n syntax: '<number>';\n inherits: true;\n initial-value: 0.1;\n }\n @property --crumb-item-bg {\n syntax: '<color>';\n inherits: true;\n initial-value: transparent;\n }\n @property --crumb-item-bg-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: var(--surface-5);\n }\n @property --crumb-item-text-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: inherit;\n }\n @property --crumb-item-border {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid transparent;\n }\n @property --crumb-item-border-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: var(--accent);\n }\n @property --crumb-item-padding {\n syntax: '*';\n inherits: true;\n initial-value: var(--space-xs);\n }\n @property --crumb-item-border-radius {\n syntax: '<length>';\n inherits: true;\n initial-value: var(--radius-m);\n }\n @property --crumb-item-gap {\n syntax: '<length>';\n inherits: true;\n initial-value: var(--space-xs);\n }\n @property --crumb-separator {\n syntax: '<color>';\n inherits: true;\n initial-value: var(--surface-muted-text);\n }\n @property --crumb-truncate-min-width {\n syntax: '<length>';\n inherits: true;\n initial-value: 5ch;\n }\n @property --space-xs {\n syntax: '<length>';\n inherits: true;\n initial-value: 3px;\n }\n @property --space-s {\n syntax: '<length>';\n inherits: true;\n initial-value: 4px;\n }\n @property --space-m {\n syntax: '<length>';\n inherits: true;\n initial-value: 8px;\n }\n @property --space-l {\n syntax: '<length>';\n inherits: true;\n initial-value: 12px;\n }\n @property --space-xl {\n syntax: '<length>';\n inherits: true;\n initial-value: 16px;\n }\n @property --space-2xl {\n syntax: '<length>';\n inherits: true;\n initial-value: 20px;\n }\n @property --text-xs {\n syntax: '<length>';\n inherits: true;\n initial-value: 9px;\n }\n @property --text-s {\n syntax: '<length>';\n inherits: true;\n initial-value: 11px;\n }\n @property --text-m {\n syntax: '<length>';\n inherits: true;\n initial-value: 12px;\n }\n @property --text-l {\n syntax: '<length>';\n inherits: true;\n initial-value: 13px;\n }\n @property --text-xl {\n syntax: '<length>';\n inherits: true;\n initial-value: 16px;\n }\n @property --text-2xl {\n syntax: '<length>';\n inherits: true;\n initial-value: 20px;\n }\n @property --font-weight-bold {\n syntax: '<number>';\n inherits: true;\n initial-value: 600;\n }\n @property --radius-s {\n syntax: '<length>';\n inherits: true;\n initial-value: 3px;\n }\n @property --radius-m {\n syntax: '<length>';\n inherits: true;\n initial-value: 4px;\n }\n @property --radius-l {\n syntax: '<length>';\n inherits: true;\n initial-value: 6px;\n }\n @property --radius-xl {\n syntax: '<length>';\n inherits: true;\n initial-value: 8px;\n }\n @property --shadow-m {\n syntax: '*';\n inherits: true;\n initial-value: 0 4px 12px rgba(0, 0, 0, 0.3);\n }\n @property --shadow-l {\n syntax: '*';\n inherits: true;\n initial-value: 0 4px 24px rgba(0, 0, 0, 0.5);\n }\n @property --deboss-3 {\n syntax: '*';\n inherits: true;\n initial-value:\n inset 1px 1px 1px 1px color-mix(in oklch, oklch(8% 0.02 240) 60%, transparent),\n inset -1px -1px 1px 1px color-mix(in oklch, oklch(15% 0.02 240) 50%, transparent),\n -2px -2px 1px 0px color-mix(in oklch, oklch(12% 0.02 240) 30%, transparent);\n }\n @property --emboss-3 {\n syntax: '*';\n inherits: true;\n initial-value:\n inset 1px 1px 1px 1px color-mix(in oklch, oklch(22% 0.02 240) 30%, transparent),\n inset -1px -1px 1px 1px color-mix(in oklch, oklch(12% 0.02 240) 20%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, oklch(12% 0.02 240) 30%, transparent);\n }\n @property --item-bg {\n syntax: '<color>';\n inherits: true;\n initial-value: transparent;\n }\n @property --item-bg-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(19% 0.02 240);\n }\n @property --item-bg-selected {\n syntax: '<color>';\n inherits: true;\n initial-value: oklch(60% 0.15 140);\n }\n @property --item-bg-selected-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: color-mix(in oklch, oklch(60% 0.15 140) 80%, oklch(0% 0 0));\n }\n @property --item-text-tickled {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --item-text-selected {\n syntax: '<color>';\n inherits: true;\n initial-value: #fff;\n }\n @property --item-border {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid oklch(19% 0.02 240);\n }\n @property --item-border-tickled {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid color-mix(in oklch, oklch(60% 0.15 140) 40%, transparent);\n }\n @property --item-border-selected {\n syntax: '*';\n inherits: true;\n initial-value: 1px dashed oklch(60% 0.15 140);\n }\n @property --item-border-active {\n syntax: '*';\n inherits: true;\n initial-value: 2px solid oklch(60% 0.15 140);\n }\n @property --item-border-dragged {\n syntax: '*';\n inherits: true;\n initial-value: 2px dotted color-mix(in oklch, oklch(60% 0.15 140) 80%, transparent);\n }\n @property --item-border-disabled {\n syntax: '*';\n inherits: true;\n initial-value: 1px solid oklch(22% 0.02 240);\n }\n @property --item-padding {\n syntax: '*';\n inherits: true;\n initial-value: 4px 8px;\n }\n @property --item-border-radius {\n syntax: '<length>';\n inherits: true;\n initial-value: 4px;\n }\n @property --item-icon-spacing {\n syntax: '<length>';\n inherits: true;\n initial-value: 4px;\n }\n`;\n\nlet _themeFallbacksRegistered = false;\n\nfunction _registerThemeFallbacksOnce(): void {\n if (_themeFallbacksRegistered || typeof document === `undefined`)\n return;\n _themeFallbacksRegistered = true;\n const styleEl = document.createElement(`style`);\n styleEl.textContent = _themeFallbacksCss.cssText;\n document.head.append(styleEl);\n}\n\n_registerThemeFallbacksOnce();\n\n/**\n * Spread this into any component whose styles reference theme variables.\n * It is an empty stylesheet — the actual `@property` rules are registered\n * once at the document level as a side effect of importing this module — so\n * this exists only to keep the familiar `static styles = [themeFallbacks, ...]`\n * pattern working across all consuming components.\n */\nexport const themeFallbacks = css``;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgY9B,IAAI,4BAA4B;AAEhC,SAAS,8BAAoC;CAC3C,IAAI,6BAA6B,OAAO,aAAa,aACnD;CACF,4BAA4B;CAC5B,MAAM,UAAU,SAAS,cAAc,OAAO;CAC9C,QAAQ,cAAc,mBAAmB;CACzC,SAAS,KAAK,OAAO,OAAO;AAC9B;AAEA,4BAA4B;;;;;;;;AAS5B,MAAa,iBAAiB,GAAG"}