@ixfx/components 0.5.19 → 0.6.0

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 (198) hide show
  1. package/bundle/index.d.ts +462 -210
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +8027 -6493
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.js +3 -3
  6. package/dist/ac-token-DVbmHmky.d.ts +107 -0
  7. package/dist/ac-token-DVbmHmky.d.ts.map +1 -0
  8. package/dist/ac-token.d.ts +2 -0
  9. package/dist/ac-token.js +646 -0
  10. package/dist/ac-token.js.map +1 -0
  11. package/dist/{button-CphdEaZd.js → button-Bn0BuLpO.js} +2 -3
  12. package/dist/{button-CphdEaZd.js.map → button-Bn0BuLpO.js.map} +1 -1
  13. package/dist/button.d.ts +1 -1
  14. package/dist/button.d.ts.map +1 -1
  15. package/dist/button.js +1 -1
  16. package/dist/checkbox.js +1 -1
  17. package/dist/{colour-picker-37NyVenk.js → colour-picker-0stHB90J.js} +18 -8
  18. package/dist/colour-picker-0stHB90J.js.map +1 -0
  19. package/dist/colour-picker.d.ts +1 -1
  20. package/dist/colour-picker.js +1 -1
  21. package/dist/crumbs.d.ts +2 -2
  22. package/dist/crumbs.js +1152 -1
  23. package/dist/crumbs.js.map +1 -0
  24. package/dist/data-controller-DOlmqNKb.js +171 -0
  25. package/dist/data-controller-DOlmqNKb.js.map +1 -0
  26. package/dist/data-display.js +1 -1
  27. package/dist/data-grid-BeAkORz2.d.ts +215 -0
  28. package/dist/data-grid-BeAkORz2.d.ts.map +1 -0
  29. package/dist/data-grid.d.ts +2 -0
  30. package/dist/data-grid.js +1225 -0
  31. package/dist/data-grid.js.map +1 -0
  32. package/dist/data-provider-BAn_-oR1.d.ts +61 -0
  33. package/dist/data-provider-BAn_-oR1.d.ts.map +1 -0
  34. package/dist/{defaults-BkWCPJFL.js → defaults-BCiDhZbF.js} +20 -3
  35. package/dist/defaults-BCiDhZbF.js.map +1 -0
  36. package/dist/drag-ghost-DtSDvjri.js +85 -0
  37. package/dist/drag-ghost-DtSDvjri.js.map +1 -0
  38. package/dist/editable-label.js +1 -1
  39. package/dist/{incr-search-2pz21xtR.js → element-search-Y8SRfPGM.js} +2 -133
  40. package/dist/element-search-Y8SRfPGM.js.map +1 -0
  41. package/dist/fallbacks-DEE1nCTt.js +406 -0
  42. package/dist/fallbacks-DEE1nCTt.js.map +1 -0
  43. package/dist/form-CsXJX15p.js +64 -0
  44. package/dist/form-CsXJX15p.js.map +1 -0
  45. package/dist/form.d.ts +15 -0
  46. package/dist/form.d.ts.map +1 -0
  47. package/dist/form.js +2 -0
  48. package/dist/grouped-item-lister-CNLMgdIr.d.ts +121 -0
  49. package/dist/grouped-item-lister-CNLMgdIr.d.ts.map +1 -0
  50. package/dist/grouped-item-lister.d.ts +2 -0
  51. package/dist/grouped-item-lister.js +177 -0
  52. package/dist/grouped-item-lister.js.map +1 -0
  53. package/dist/{icon-DG9Lm3LT.js → icons-Bm2ByQ3s.js} +6 -3
  54. package/dist/icons-Bm2ByQ3s.js.map +1 -0
  55. package/dist/icons.js +2 -8
  56. package/dist/incr-search-vCzuao-2.js +137 -0
  57. package/dist/incr-search-vCzuao-2.js.map +1 -0
  58. package/dist/incr-search.d.ts +1 -1
  59. package/dist/incr-search.js +2 -1
  60. package/dist/{index-BKAlRgbq.d.ts → index-BOUaDIW-.d.ts} +4 -1
  61. package/dist/index-BOUaDIW-.d.ts.map +1 -0
  62. package/dist/{index-D9u_Q7-b.d.ts → index-Cu5i8zZY.d.ts} +3 -3
  63. package/dist/{index-D9u_Q7-b.d.ts.map → index-Cu5i8zZY.d.ts.map} +1 -1
  64. package/dist/{index-DkhBGHgF.d.ts → index-ovq_GTdl.d.ts} +2 -2
  65. package/dist/{index-DkhBGHgF.d.ts.map → index-ovq_GTdl.d.ts.map} +1 -1
  66. package/dist/index.d.ts +54 -572
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +1898 -4253
  69. package/dist/index.js.map +1 -1
  70. package/dist/labelled-radial-input.d.ts +1 -1
  71. package/dist/labelled-radial-input.js +1 -2
  72. package/dist/labelled-radial-input.js.map +1 -1
  73. package/dist/led.d.ts +0 -1
  74. package/dist/led.d.ts.map +1 -1
  75. package/dist/led.js +2 -4
  76. package/dist/led.js.map +1 -1
  77. package/dist/menu-DIfU70AA.js +1609 -0
  78. package/dist/menu-DIfU70AA.js.map +1 -0
  79. package/dist/menu-item-BG5w7fi4.d.ts.map +1 -1
  80. package/dist/menu.d.ts +1 -1
  81. package/dist/menu.js +1 -2
  82. package/dist/miller.d.ts +3 -3
  83. package/dist/miller.js +3 -3
  84. package/dist/narrowed-text.d.ts.map +1 -1
  85. package/dist/narrowed-text.js +4 -4
  86. package/dist/narrowed-text.js.map +1 -1
  87. package/dist/notification-pill-DyZydXoZ.d.ts +68 -0
  88. package/dist/notification-pill-DyZydXoZ.d.ts.map +1 -0
  89. package/dist/notifier.d.ts +2 -0
  90. package/dist/notifier.js +146 -0
  91. package/dist/notifier.js.map +1 -0
  92. package/dist/panel.js +1 -2
  93. package/dist/panel.js.map +1 -1
  94. package/dist/plots.js +1 -1
  95. package/dist/polar-pad.d.ts +1 -1
  96. package/dist/polar-pad.js +1 -1
  97. package/dist/{radial-input-BhZeyyP-.d.ts → radial-input-DXMN55Nz.d.ts} +2 -2
  98. package/dist/{radial-input-BhZeyyP-.d.ts.map → radial-input-DXMN55Nz.d.ts.map} +1 -1
  99. package/dist/{radial-input-CVxGH-Cp.js → radial-input-Dk8Wydp5.js} +4 -4
  100. package/dist/radial-input-Dk8Wydp5.js.map +1 -0
  101. package/dist/radial-input.d.ts +1 -1
  102. package/dist/radial-input.js +1 -1
  103. package/dist/range-input.d.ts +1 -1
  104. package/dist/range-input.js +1 -1
  105. package/dist/range.d.ts +1 -1
  106. package/dist/range.js +1 -1
  107. package/dist/scroll-fade-CAs1EabA.js +70 -0
  108. package/dist/scroll-fade-CAs1EabA.js.map +1 -0
  109. package/dist/select-horiz.d.ts +50 -0
  110. package/dist/select-horiz.d.ts.map +1 -0
  111. package/dist/select-horiz.js +263 -0
  112. package/dist/select-horiz.js.map +1 -0
  113. package/dist/{slider-input-CzmSVgm7.js → slider-input-CT4gcF-o.js} +2 -2
  114. package/dist/{slider-input-CzmSVgm7.js.map → slider-input-CT4gcF-o.js.map} +1 -1
  115. package/dist/{slider-input-TidGhvXt.d.ts → slider-input-XppH3vcy.d.ts} +2 -2
  116. package/dist/{slider-input-TidGhvXt.d.ts.map → slider-input-XppH3vcy.d.ts.map} +1 -1
  117. package/dist/slider-input.d.ts +1 -1
  118. package/dist/slider-input.js +1 -1
  119. package/dist/snackbar.d.ts +58 -0
  120. package/dist/snackbar.d.ts.map +1 -0
  121. package/dist/snackbar.js +265 -0
  122. package/dist/snackbar.js.map +1 -0
  123. package/dist/split-layout.js +1 -1
  124. package/dist/swipe.d.ts +1 -1
  125. package/dist/swipe.js +1 -1
  126. package/dist/tabs.js +533 -1
  127. package/dist/tabs.js.map +1 -0
  128. package/dist/{tickled-controller-BF2Ea0DE.d.ts → tickled-controller-BtevrRLV.d.ts} +8 -6
  129. package/dist/tickled-controller-BtevrRLV.d.ts.map +1 -0
  130. package/dist/{tickled-styles-fNDdqf6l.js → tickled-controller-DkAU-0qL.js} +19 -105
  131. package/dist/tickled-controller-DkAU-0qL.js.map +1 -0
  132. package/dist/tickled-styles-BrAHEj1q.js +89 -0
  133. package/dist/tickled-styles-BrAHEj1q.js.map +1 -0
  134. package/dist/transitory-label.d.ts +30 -0
  135. package/dist/transitory-label.d.ts.map +1 -0
  136. package/dist/transitory-label.js +249 -0
  137. package/dist/transitory-label.js.map +1 -0
  138. package/dist/{tree-BtiiDX1a.js → tree-BO6BXI2b.js} +4 -4
  139. package/dist/{tree-BtiiDX1a.js.map → tree-BO6BXI2b.js.map} +1 -1
  140. package/dist/{tree-component-DQ9vzdy5.d.ts → tree-component-BvV4muxx.d.ts} +2 -2
  141. package/dist/{tree-component-DQ9vzdy5.d.ts.map → tree-component-BvV4muxx.d.ts.map} +1 -1
  142. package/dist/tree.d.ts +3 -3
  143. package/dist/tree.js +1 -1
  144. package/dist/{types-DO3gt5vg.d.ts → types-Bc23SI94.d.ts} +3 -61
  145. package/dist/types-Bc23SI94.d.ts.map +1 -0
  146. package/dist/types-DlVNJez_.d.ts +41 -0
  147. package/dist/types-DlVNJez_.d.ts.map +1 -0
  148. package/dist/vertical-list.d.ts +122 -0
  149. package/dist/vertical-list.d.ts.map +1 -0
  150. package/dist/vertical-list.js +737 -0
  151. package/dist/vertical-list.js.map +1 -0
  152. package/dist/wheel-nudge-BlSCe_hD.js.map +1 -1
  153. package/dist/{wheel-nudge-DgMTRYlh.d.ts → wheel-nudge-DGrNzWuE.d.ts} +3 -3
  154. package/dist/wheel-nudge-DGrNzWuE.d.ts.map +1 -0
  155. package/dist/{xy-axis-CxHC8z5E.js → xy-axis-B6yMjckW.js} +3 -109
  156. package/dist/xy-axis-B6yMjckW.js.map +1 -0
  157. package/dist/xy-pad.d.ts +1 -1
  158. package/dist/xy-pad.js +1 -1
  159. package/docs-user/README.md +3 -2
  160. package/docs-user/ac-token.md +7 -1
  161. package/docs-user/colour-picker.md +8 -4
  162. package/docs-user/data-grid.md +248 -0
  163. package/docs-user/index.json +217 -0
  164. package/docs-user/llms.txt +57 -0
  165. package/docs-user/menu.md +11 -8
  166. package/docs-user/rating.md +102 -0
  167. package/llms.txt +57 -0
  168. package/package.json +21 -11
  169. package/dist/colour-picker-37NyVenk.js.map +0 -1
  170. package/dist/crumb-navigation-BrB0r14u.js +0 -1220
  171. package/dist/crumb-navigation-BrB0r14u.js.map +0 -1
  172. package/dist/defaults-BkWCPJFL.js.map +0 -1
  173. package/dist/fallbacks-DPgPEqo8.js +0 -218
  174. package/dist/fallbacks-DPgPEqo8.js.map +0 -1
  175. package/dist/icon-DG9Lm3LT.js.map +0 -1
  176. package/dist/icons.js.map +0 -1
  177. package/dist/incr-search-2pz21xtR.js.map +0 -1
  178. package/dist/index-BKAlRgbq.d.ts.map +0 -1
  179. package/dist/interaction-D6efrBLo.js +0 -1
  180. package/dist/menu-CdwSe_XN.js +0 -825
  181. package/dist/menu-CdwSe_XN.js.map +0 -1
  182. package/dist/menu-item-CrmUwIoJ.js +0 -782
  183. package/dist/menu-item-CrmUwIoJ.js.map +0 -1
  184. package/dist/radial-input-CVxGH-Cp.js.map +0 -1
  185. package/dist/registry-CkW7q09Q.js +0 -21
  186. package/dist/registry-CkW7q09Q.js.map +0 -1
  187. package/dist/selecthorizontal.d.ts +0 -15
  188. package/dist/selecthorizontal.d.ts.map +0 -1
  189. package/dist/selecthorizontal.js +0 -43
  190. package/dist/selecthorizontal.js.map +0 -1
  191. package/dist/tab-list-mAoD6L0e.js +0 -615
  192. package/dist/tab-list-mAoD6L0e.js.map +0 -1
  193. package/dist/tickled-controller-BF2Ea0DE.d.ts.map +0 -1
  194. package/dist/tickled-styles-fNDdqf6l.js.map +0 -1
  195. package/dist/types-DO3gt5vg.d.ts.map +0 -1
  196. package/dist/wheel-nudge-DgMTRYlh.d.ts.map +0 -1
  197. package/dist/xy-axis-CxHC8z5E.js.map +0 -1
  198. package/docs-user/selecthorizontal.md +0 -32
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vertical-list.js","names":["#search","#selectionAnchor","#customWrappers","#wrappedElements","customElement"],"sources":["../src/vertical-list/vertical-list.ts"],"sourcesContent":["import type { CommandId } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { ElementIncrSearch } from '../incr-search/element-search.js';\nimport type {\n ListActivateDetail,\n ListElementEventMap,\n ListInteractionMode,\n ListItemClickDetail,\n ListSelectDetail,\n ListSelectionMode,\n ListTickleDetail,\n} from './types.js';\nimport { css, html, LitElement, render } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { createElementIncrSearch } from '../incr-search/element-search.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nexport type {\n ListActivateDetail,\n ListActivateEvent,\n ListElementEventMap,\n ListInteractionMode,\n ListItemClickDetail,\n ListItemClickEvent,\n ListSelectDetail,\n ListSelectEvent,\n ListSelectionMode,\n ListTickleDetail,\n ListTickleEvent,\n} from './types.js';\n\nexport interface CustomCheckboxOptions {\n renderer: (checked: boolean) => unknown;\n margin?: string;\n width?: string;\n}\n\nexport interface AddItemOptions {\n /**\n * In `checked` interaction mode, adds the item without a checkbox column and\n * without the ability to be checked/selected. Equivalent to setting the\n * `not-checked` attribute on the item. Ignored outside `checked` mode.\n */\n notChecked?: boolean;\n}\n\nconst ITEM_SELECTOR = `li, [data-list-item]`;\n\n// Whether the mode allows building a multi-item selection\nfunction isMultiMode(mode: ListInteractionMode): boolean {\n return mode === `checked` || mode === `sticky` || mode === `vscode` || mode === `standard`;\n}\n\n@customElement(`ixfx-vertical-list`)\nexport class VerticalListElement 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({ attribute: false })\n filterPredicate: ((el: Element) => boolean) | undefined;\n\n /**\n * Optional renderer for the checkbox shown in `checked` interactionMode.\n * Receives the current `checked` state and returns a Lit template result.\n *\n * When set, the per-row checkbox becomes a `<span role=\"checkbox\">` whose\n * contents are whatever this returns (rendered with `lit`'s `render()`).\n * When unset, a native `<input type=\"checkbox\">` is used.\n *\n * @example\n * list.checkboxRenderer = (checked) => checked\n * ? html`<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\"\n * fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n * stroke-linecap=\"round\" stroke-linejoin=\"round\"\n * style=\"opacity:0.5\">\n * <polyline points=\"3,8 7,12 13,4\" />\n * </svg>`\n * : html``;\n */\n @property({ attribute: false })\n checkboxRenderer: ((checked: boolean) => unknown) | CustomCheckboxOptions | undefined;\n\n @state() private _selectedItems: ReadonlySet<Element> = new Set();\n @state() private _searchVisible = false;\n @state() private _searchQuery = ``;\n\n @query(`.search-input`)\n private _searchInputEl!: HTMLInputElement;\n\n #search: ElementIncrSearch | undefined;\n // Anchor for range/shift selection — updated on plain-click or plain-keyboard select\n #selectionAnchor: Element | undefined;\n #customWrappers = new Map<HTMLLIElement, Element>();\n #wrappedElements = new Set<Element>();\n\n private tickled = new TickledController<Element>(this, {\n getItems: () => this._getVisibleItems().map(el => ({ id: el, enabled: true })),\n onTickle: (id) => {\n if (id !== undefined) {\n this._dispatch<ListTickleDetail>(`list-tickle`, { item: id });\n }\n },\n onStateChange: () => this._syncItemStates(),\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 }\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.#search?.dispose();\n this.#search = undefined;\n }\n\n override firstUpdated(): void {\n this.#search = createElementIncrSearch({\n container: this,\n itemSelector: ITEM_SELECTOR,\n getLabel: el => el.getAttribute(`data-search-label`) ?? el.textContent?.trim() ?? ``,\n getKey: el =>\n el.getAttribute(`data-key`)\n ?? el.getAttribute(`data-search-label`)\n ?? el.textContent?.trim()\n ?? ``,\n highlightKey: `vertical-list-search`,\n });\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n if (changed.has(`interactionMode`)) {\n this.#selectionAnchor = undefined;\n const previousSelected = this._selectedItems;\n // Save wrapper→inner map before _syncCheckboxes() clears it on unwrap\n const leavingChecked = (changed.get(`interactionMode`) as ListInteractionMode) === `checked`;\n const savedWrappers = leavingChecked ? new Map(this.#customWrappers) : null;\n\n this._syncCheckboxes();\n\n // Remap _selectedItems across the wrap/unwrap element-reference boundary\n if (previousSelected.size > 0) {\n let remapped: Set<Element>;\n if (savedWrappers && savedWrappers.size > 0) {\n // Leaving checked: wrapper refs → inner element refs\n remapped = new Set([...previousSelected].map(el => savedWrappers.get(el as HTMLLIElement) ?? el));\n } else if (this.#customWrappers.size > 0) {\n // Entering checked: inner element refs → wrapper refs\n const innerToWrapper = new Map([...this.#customWrappers].map(([w, i]) => [i, w]));\n remapped = new Set([...previousSelected].map(el => innerToWrapper.get(el) ?? el));\n } else {\n remapped = new Set(previousSelected);\n }\n this._selectedItems = remapped;\n }\n\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._selectedItems].at(-1);\n }\n\n /** The full current selection set (read-only). */\n get selectedItems(): ReadonlySet<Element> {\n return this._selectedItems;\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 li.textContent = item;\n el = li;\n } else {\n el = item;\n }\n if (options?.notChecked)\n el.setAttribute(`not-checked`, ``);\n this.appendChild(el);\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n }\n\n removeItem(item: Element): void {\n item.remove();\n }\n\n clearItems(): void {\n this.#customWrappers.clear();\n this.replaceChildren();\n this.#selectionAnchor = undefined;\n this._selectedItems = new Set();\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 * Preserves `interactionMode` checkbox wrapping.\n */\n setItems(items: readonly Element[]): void {\n this.clearItems();\n for (const item of items) {\n this.appendChild(item);\n }\n if (this.interactionMode === `checked`)\n this._syncCheckboxes();\n }\n\n /**\n * Dispatch a command to this list. No-op by default.\n * Intended for use with `ixfx-grouped-item-lister`'s `dispatch()` method,\n * which forwards commands to all sub-components.\n */\n dispatch(_commandId: CommandId, _args?: Record<string, unknown>): void {}\n\n select(item: Element): void {\n this._replaceSelection(item);\n }\n\n selectMany(items: Iterable<Element>): void {\n if (this.selectionMode !== `multiple`) {\n throw new Error(`selectMany requires selectionMode=\"multiple\" (current: \"${this.selectionMode}\")`);\n }\n const previous = this._selectedItems;\n const next = new Set([...items].filter(el => this._isCheckable(el)));\n if (next.size === 0)\n return;\n this._selectedItems = next;\n this.#selectionAnchor = [...next].at(-1);\n this._syncItemStates();\n this._dispatch<ListSelectDetail>(`list-select`, { selected: next, previous });\n }\n\n deselect(item: Element): void {\n if (!this._selectedItems.has(item))\n return;\n const previous = this._selectedItems;\n const next = new Set(this._selectedItems);\n next.delete(item);\n this._selectedItems = next;\n this._syncItemStates();\n this._dispatch<ListSelectDetail>(`list-select`, { selected: next, previous });\n }\n\n clearSelection(): void {\n this._clearSelection();\n }\n\n selectAll(): void {\n const canMulti = this.selectionMode === `multiple` || isMultiMode(this.interactionMode);\n if (canMulti && this.selectionMode !== `none`)\n this._selectAll();\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 (this.#wrappedElements.has(el))\n continue;\n if ((el as HTMLElement).hidden)\n continue;\n if (wanted(el))\n yield el;\n }\n }\n\n // --- Private selection primitives ---\n\n // Replace entire selection with one item; updates anchor. Used for plain clicks and Enter.\n private _replaceSelection(item: Element): void {\n if (this.selectionMode === `none`)\n return;\n if (!this._isCheckable(item))\n return;\n const previous = this._selectedItems;\n const next = new Set([item]);\n this._selectedItems = next;\n this.#selectionAnchor = item;\n this._syncItemStates();\n this._dispatch<ListSelectDetail>(`list-select`, { selected: next, previous });\n }\n\n // Toggle a single item in/out of the selection without replacing. Does not update anchor.\n private _toggleItem(item: Element): void {\n if (!this._isCheckable(item))\n return;\n // checked/vscode modes imply multiple selection capacity\n const effectiveMultiple\n = this.selectionMode === `multiple` || isMultiMode(this.interactionMode);\n if (this.selectionMode === `none` && this.interactionMode !== `checked` && this.interactionMode !== `sticky`)\n return;\n\n const previous = this._selectedItems;\n const next = new Set(this._selectedItems);\n if (next.has(item)) {\n next.delete(item);\n } else {\n if (!effectiveMultiple)\n next.clear();\n next.add(item);\n }\n this._selectedItems = next;\n this._syncItemStates();\n this._dispatch<ListSelectDetail>(`list-select`, { selected: next, previous });\n }\n\n // Select the contiguous range from anchor to item. Anchor is not changed.\n private _rangeSelectTo(item: Element): void {\n if (this.selectionMode === `none`)\n return;\n if (!this.#selectionAnchor) {\n this._replaceSelection(item);\n return;\n }\n const visible = this._getVisibleItems();\n const anchorIdx = visible.indexOf(this.#selectionAnchor);\n const targetIdx = visible.indexOf(item);\n if (anchorIdx === -1 || targetIdx === -1) {\n this._replaceSelection(item);\n return;\n }\n const start = Math.min(anchorIdx, targetIdx);\n const end = Math.max(anchorIdx, targetIdx);\n const previous = this._selectedItems;\n const next = new Set(visible.slice(start, end + 1).filter(el => this._isCheckable(el)));\n this._selectedItems = next;\n this._syncItemStates();\n this._dispatch<ListSelectDetail>(`list-select`, { selected: next, previous });\n }\n\n private _clearSelection(): void {\n if (this._selectedItems.size === 0)\n return;\n const previous = this._selectedItems;\n this._selectedItems = new Set();\n this._syncItemStates();\n this._dispatch<ListSelectDetail>(`list-select`, { selected: new Set(), previous });\n }\n\n private _selectAll(): void {\n const visible = this._getVisibleItems();\n if (visible.length === 0)\n return;\n const previous = this._selectedItems;\n const next = new Set(visible.filter(el => this._isCheckable(el)));\n if (next.size === 0)\n return;\n this._selectedItems = next;\n this._syncItemStates();\n this._dispatch<ListSelectDetail>(`list-select`, { selected: next, previous });\n }\n\n // --- Click interaction routing per interactionMode ---\n\n private _handleClickSelection(item: Element, e: MouseEvent): void {\n const mode = this.interactionMode;\n if (mode === `manual`)\n return;\n if (this.selectionMode === `none` && mode !== `checked` && mode !== `sticky`)\n return;\n\n switch (mode) {\n case `implicit`:\n // Single-select only; modifier keys have no effect\n this._replaceSelection(item);\n break;\n\n case `standard`:\n case `vscode`:\n if (e.ctrlKey || e.metaKey) {\n // Ctrl/Cmd+click: toggle item; requires effective multi-select\n if (this.selectionMode === `multiple` || mode === `vscode`) {\n this._toggleItem(item);\n }\n } else if (e.shiftKey && (this.selectionMode === `multiple` || mode === `vscode`)) {\n // Shift+click: range-select from anchor\n this._rangeSelectTo(item);\n } else {\n // Plain click: replace selection, update anchor\n this._replaceSelection(item);\n }\n break;\n\n case `checked`:\n // Body clicks do nothing — only the full-height checkbox column toggles.\n break;\n\n case `sticky`:\n // Every tap/click toggles — multi-select without modifier keys (touchscreens).\n this._toggleItem(item);\n break;\n }\n }\n\n // --- Space key routing per interactionMode ---\n\n private _handleSpaceKey(item: Element): void {\n const mode = this.interactionMode;\n if (mode === `manual`)\n return;\n if (mode === `implicit`) {\n // Space selects (same as click) in implicit mode\n this._replaceSelection(item);\n } else {\n // standard / vscode / checked / sticky: Space toggles\n this._toggleItem(item);\n }\n }\n\n // --- Helpers ---\n\n private _getVisibleItems(): Element[] {\n return Array.from(this.querySelectorAll(ITEM_SELECTOR)).filter((el) => {\n if (this.#wrappedElements.has(el))\n return false;\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 // Whether an item participates in checked-mode selection. Items carrying the\n // `not-checked` attribute are skipped; outside `checked` mode it has no effect.\n // For wrapped custom elements the flag lives on the inner element, so resolve\n // through the wrapper map.\n private _isCheckable(item: Element): boolean {\n if (this.interactionMode !== `checked`)\n return true;\n const real = this.#customWrappers.get(item as HTMLLIElement) ?? item;\n return !real.hasAttribute(`not-checked`);\n }\n\n private _syncItemStates(): void {\n for (const el of this.querySelectorAll(ITEM_SELECTOR)) {\n if (this.#wrappedElements.has(el))\n continue;\n const item = this.#customWrappers.get(el as HTMLLIElement) ?? el;\n el.toggleAttribute(`data-tickled`, this.tickled.isTickled(el));\n el.toggleAttribute(`data-selected`, this._selectedItems.has(el));\n if (this.interactionMode === `checked`) {\n el.toggleAttribute(`data-checked`, !item.hasAttribute(`not-checked`) && this._selectedItems.has(el));\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 if (inCheckedMode) {\n for (const inner of Array.from(this.children)) {\n if (!inner.hasAttribute(`data-list-item`))\n continue;\n if (inner.parentElement !== this)\n continue; // idempotency: already wrapped\n const wrapper = document.createElement(`li`);\n wrapper.className = `ixfx-custom-row`;\n const key = inner.getAttribute(`data-key`);\n const label = inner.getAttribute(`data-search-label`);\n if (key !== null)\n wrapper.setAttribute(`data-key`, key);\n if (label !== null)\n wrapper.setAttribute(`data-search-label`, label);\n inner.removeAttribute(`data-list-item`);\n this.insertBefore(wrapper, inner);\n wrapper.appendChild(inner);\n this.#customWrappers.set(wrapper, inner);\n this.#wrappedElements.add(inner);\n }\n } else {\n for (const [wrapper, inner] of this.#customWrappers) {\n if (wrapper.parentElement !== this)\n continue;\n inner.setAttribute(`data-list-item`, ``);\n this.insertBefore(inner, wrapper);\n wrapper.remove();\n }\n this.#customWrappers.clear();\n this.#wrappedElements.clear();\n }\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 const itemEl = this.#customWrappers.get(el as HTMLLIElement) ?? el;\n if (itemEl.hasAttribute(`not-checked`)) {\n if (existing)\n existing.remove();\n continue;\n }\n\n // In checked mode: if the existing checkbox is the wrong variant, drop it.\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._selectedItems.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._toggleItem(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 /**\n * Custom checkbox cell: same shape as the native cell (a stretching span)\n * so behaviour is identical. The renderer's content goes inside.\n */\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._toggleItem(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(ITEM_SELECTOR))\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 private _openSearch(): void {\n this._searchVisible = true;\n void this.updateComplete.then(() => this._searchInputEl?.focus());\n }\n\n private _closeSearch(): void {\n this._searchVisible = false;\n this._searchQuery = ``;\n void this.#search?.clearQuery();\n this.focus();\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 ((e.ctrlKey || e.metaKey) && e.key === `f`) {\n e.preventDefault();\n this._openSearch();\n return;\n }\n if ((e.ctrlKey || e.metaKey) && e.key === `a`) {\n const canMulti\n = this.selectionMode === `multiple` || isMultiMode(this.interactionMode);\n if (canMulti && this.selectionMode !== `none`) {\n e.preventDefault();\n this._selectAll();\n }\n return;\n }\n if (this._searchVisible)\n return;\n\n switch (e.key) {\n case `ArrowDown`: {\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\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._rangeSelectTo(cur);\n }\n break;\n }\n case `ArrowUp`: {\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n if (e.shiftKey && this.interactionMode === `vscode`) {\n const cur = this.tickled.tickledId;\n if (cur)\n this._rangeSelectTo(cur);\n }\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._handleSpaceKey(id);\n }\n break;\n }\n case `Escape`:\n this._clearSelection();\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._dispatch<ListItemClickDetail>(`list-item-click`, { item });\n this._handleClickSelection(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 _activateItem(item: Element): void {\n // manual mode: never auto-select; just fire the event\n if (this.interactionMode !== `manual`) {\n this._replaceSelection(item);\n }\n this._dispatch<ListActivateDetail>(`list-activate`, { item });\n }\n\n private _onSearchInput = (e: Event): void => {\n const input = e.target as HTMLInputElement;\n this._searchQuery = input.value;\n void this.#search?.setQuery(this._searchQuery);\n };\n\n private _onSearchKeydown = (e: KeyboardEvent): void => {\n if (e.key === `Escape`) {\n e.stopPropagation();\n this._closeSearch();\n } else if (e.key === `ArrowDown`) {\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\n } else if (e.key === `ArrowUp`) {\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n } else if (e.key === `Enter`) {\n e.preventDefault();\n e.stopPropagation();\n const id = this.tickled.tickledId ?? this._getVisibleItems()[0];\n if (id) {\n this._dispatch<ListItemClickDetail>(`list-item-click`, { item: id });\n this._activateItem(id);\n this._closeSearch();\n }\n }\n };\n\n // --- Styles ---\n\n static override styles = [themeFallbacks, css`\n :host {\n display: block;\n position: relative;\n background: var(--list-bg, var(--surface-3));\n color: var(--list-text, var(--surface-3-text));\n border-radius: var(--list-radius, var(--radius-s));\n border: 1px solid var(--list-border, var(--border));\n width: 100%;\n height: 100%;\n overflow: hidden;\n box-sizing: border-box;\n outline: none;\n --ixfx-list-item-padding: var(--ixfx-list-item-padding, var(--list-item-padding, 4px var(--space-m, 8px)));\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 width: 100%;\n height: 100%;\n overflow-x: hidden;\n overflow-y: auto;\n box-sizing: border-box;\n /* Scrollbar theming: end users override these CSS variables to control\n the native scrollbar (scrollbar-width, scrollbar-gutter, scrollbar-color). */\n scrollbar-width: var(--list-scrollbar-width, auto);\n scrollbar-gutter: var(--list-scrollbar-gutter, auto);\n scrollbar-color: var(--list-scrollbar-color, auto);\n }\n\n ::slotted([hidden]) {\n display: none !important;\n }\n\n ::slotted(li) {\n display: flex;\n align-items: center;\n padding: var(--ixfx-list-item-padding);\n min-height: var(--list-item-height, 28px);\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 box-sizing: border-box;\n outline: 1px solid transparent;\n }\n\n /* Custom shadow-DOM components handle their own internal layout/padding */\n ::slotted([data-list-item]) {\n display: block;\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 :host([interaction-mode=\"checked\"]) ::slotted([data-list-item]) {\n cursor: default;\n }\n\n /* Wrapper inserted around custom [data-list-item] elements in checked mode.\n Provides the flex layout so the injected checkbox can stretch to the\n row's full height via align-self:stretch. */\n .ixfx-custom-row {\n display: flex;\n align-items: center;\n min-height: var(--list-item-height, 28px);\n box-sizing: border-box;\n cursor: default;\n user-select: none;\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: checkbox (injected into li) communicates selection — suppress bg highlight */\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 .search-overlay {\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 10;\n display: flex;\n align-items: center;\n gap: 4px;\n background: var(--surface-4, #2a2a2a);\n border: 1px solid var(--border, #444);\n border-radius: var(--radius-m, 4px);\n padding: 4px 6px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n }\n\n .search-overlay[hidden] {\n display: none;\n }\n\n .search-input {\n background: transparent;\n border: none;\n outline: none;\n color: inherit;\n font-size: var(--text-m, 0.875em);\n min-width: 140px;\n }\n\n .search-close {\n background: transparent;\n border: none;\n color: var(--surface-muted-text, #888);\n cursor: pointer;\n font-size: 1.1em;\n line-height: 1;\n padding: 0 2px;\n }\n\n .search-close:hover {\n color: inherit;\n }\n `];\n\n // --- Render ---\n\n override render() {\n return html`\n <div class=\"container\">\n <ul part=\"list\">\n <slot></slot>\n </ul>\n <div\n class=\"search-overlay\"\n part=\"search-overlay\"\n ?hidden=${!this._searchVisible}\n >\n <input\n type=\"text\"\n class=\"search-input\"\n placeholder=\"Search…\"\n .value=${this._searchQuery}\n @input=${this._onSearchInput}\n @keydown=${this._onSearchKeydown}\n />\n <button class=\"search-close\" @click=${this._closeSearch} title=\"Close search (Esc)\">×</button>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-vertical-list': VerticalListElement;\n }\n\n interface HTMLElementEventMap extends ListElementEventMap {}\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"wheel-nudge-BlSCe_hD.js","names":[],"sources":["../src/mixins/wheel-nudge.ts"],"sourcesContent":["import type { LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\n\ntype Constructor<T = object> = new (...args: any[]) => T;\n\n/**\n * Direction of a wheel tick. `+1` for `deltaY < 0` (wheel up/away), `-1` for\n * `deltaY > 0` (wheel down/toward).\n */\nexport type WheelDirection = 1 | -1;\n\n/**\n * Abstract surface a consumer of {@link WheelNudgeMixin} must implement.\n *\n * `_applyWheelDelta` is called once per handled wheel tick. The consumer is\n * expected to reuse its existing arrow-key step math (typically a shared\n * `_stepByDelta(direction, effectiveStep)` private method) and call it here.\n *\n * `_shouldHandleWheel` may be overridden to restrict when the wheel acts\n * (e.g. editable-number rejects while the user is typing).\n */\nexport interface WheelNudgeConsumer {\n _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void;\n _shouldHandleWheel(): boolean;\n}\n\n/**\n * Internal: the surface a {@link WheelNudgeMixin}-decorated class exposes to\n * TypeScript — its own members plus the consumer contract.\n */\nexport type WheelNudgeConsumerType<TBase> = TBase & WheelNudgeConsumer;\ntype WheelNudgeMixinBase<T> = T extends Constructor<infer U> ? U : never;\ntype WheelNudgeMixinResult<T extends Constructor<LitElement>>\n = Constructor<WheelNudgeConsumerType<WheelNudgeMixinBase<T>>> & T;\n\n/**\n * Mixin that adds mousewheel support with an optional `lighttouch` hover mode.\n *\n * Activation rule:\n * - If the host's `disabled` property is truthy → ignore.\n * - Otherwise, handle if EITHER:\n * • `lighttouch` is true AND the pointer is currently over the host, OR\n * • the host (or anything in its shadow tree) currently has focus.\n *\n * Direction convention: `deltaY < 0` (wheel up/away) → +1 step; `deltaY > 0` → -1 step.\n *\n * Consumers must implement `_applyWheelDelta(direction, event)` (see\n * {@link WheelNudgeConsumer}). The mixin calls `event.preventDefault()` only when\n * the activation rule accepts the event, so page scroll is suppressed during\n * interaction without blocking wheel events over empty space.\n *\n * Usage:\n *\n * ```ts\n * class MyInput extends WheelNudgeMixin(LitElement) {\n * protected _applyWheelDelta(direction, event) {\n * const step = resolveAxisStep(this.range, this.stops, this.step, event.shiftKey);\n * this._stepByDelta(direction, step);\n * }\n * }\n * ```\n */\nexport function WheelNudgeMixin<T extends Constructor<LitElement>>(superClass: T): WheelNudgeMixinResult<T> {\n class WheelNudgeMixinClass extends superClass {\n /**\n * When true, the wheel adjusts the value simply when the pointer is hovering\n * over the host (no focus required). When false (default), the host must\n * have focus for the wheel to act.\n */\n @property({ type: Boolean, reflect: true })\n lighttouch = false;\n\n /**\n * Imperative hover flag — not Lit-reactive (avoids update churn for what\n * is purely an interaction-time predicate).\n */\n _isHovering = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener(`pointerenter`, this._onPointerEnter);\n this.addEventListener(`pointerleave`, this._onPointerLeave);\n this.addEventListener(`wheel`, this._onWheel, { passive: false });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`pointerenter`, this._onPointerEnter);\n this.removeEventListener(`pointerleave`, this._onPointerLeave);\n this.removeEventListener(`wheel`, this._onWheel);\n this._isHovering = false;\n }\n\n _onPointerEnter = (): void => {\n this._isHovering = true;\n };\n\n _onPointerLeave = (): void => {\n this._isHovering = false;\n };\n\n /**\n * Override to restrict when wheel is handled (e.g. editable-number rejects\n * while the user is typing). Default: respect `disabled`, then apply the\n * focus-or-lighttouch rule described on the mixin.\n */\n _shouldHandleWheel(): boolean {\n const anyThis = this as unknown as { disabled?: boolean };\n if (anyThis.disabled)\n return false;\n if (this.lighttouch && this._isHovering)\n return true;\n if (this.matches?.(`:focus, :focus-within`))\n return true;\n const root = this.renderRoot;\n if (root && (root as ShadowRoot).activeElement !== null)\n return true;\n return false;\n }\n\n _onWheel = (event: WheelEvent): void => {\n if (!this._shouldHandleWheel())\n return;\n event.preventDefault();\n // Some browsers (notably when the user holds Shift) send `deltaY=0`\n // and route the scroll into `deltaX` instead. Use whichever axis\n // actually moved so the direction sign matches the user's intent.\n const delta = event.deltaY !== 0 ? event.deltaY : event.deltaX;\n const direction: WheelDirection = delta < 0 ? 1 : -1;\n (this as unknown as WheelNudgeConsumer)._applyWheelDelta(direction, event);\n };\n }\n return WheelNudgeMixinClass as unknown as WheelNudgeMixinResult<T>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,SAAgB,gBAAmD,YAAyC;CAC1G,MAAM,6BAA6B,WAAW;;;GAO/B,KAAA,aAAA;GAMC,KAAA,cAAA;GAiBgB,KAAA,wBAAA;IAC5B,KAAK,cAAc;GACrB;GAE8B,KAAA,wBAAA;IAC5B,KAAK,cAAc;GACrB;GAqBY,KAAA,YAAA,UAA4B;IACtC,IAAI,CAAC,KAAK,mBAAmB,GAC3B;IACF,MAAM,eAAe;IAKrB,MAAM,aADQ,MAAM,WAAW,IAAI,MAAM,SAAS,MAAM,UACd,IAAI,IAAI;IAClD,KAAwC,iBAAiB,WAAW,KAAK;GAC3E;;EApDA,oBAAmC;GACjC,MAAM,kBAAkB;GACxB,KAAK,iBAAiB,gBAAgB,KAAK,eAAe;GAC1D,KAAK,iBAAiB,gBAAgB,KAAK,eAAe;GAC1D,KAAK,iBAAiB,SAAS,KAAK,UAAU,EAAE,SAAS,MAAM,CAAC;EAClE;EAEA,uBAAsC;GACpC,MAAM,qBAAqB;GAC3B,KAAK,oBAAoB,gBAAgB,KAAK,eAAe;GAC7D,KAAK,oBAAoB,gBAAgB,KAAK,eAAe;GAC7D,KAAK,oBAAoB,SAAS,KAAK,QAAQ;GAC/C,KAAK,cAAc;EACrB;;;;;;EAeA,qBAA8B;GAE5B,IAAI,KAAQ,UACV,OAAO;GACT,IAAI,KAAK,cAAc,KAAK,aAC1B,OAAO;GACT,IAAI,KAAK,UAAU,uBAAuB,GACxC,OAAO;GACT,MAAM,OAAO,KAAK;GAClB,IAAI,QAAS,KAAoB,kBAAkB,MACjD,OAAO;GACT,OAAO;EACT;CAaF;CA9DG,WAAA,CAAA,SAAS;EAAE,MAAM;EAAS,SAAS;CAAK,CAAC,CAAA,GAAA,qBAAA,WAAA,cAAA,KAAA,CAAA;CA+D5C,OAAO;AACT"}
1
+ {"version":3,"file":"wheel-nudge-BlSCe_hD.js","names":[],"sources":["../src/mixins/wheel-nudge.ts"],"sourcesContent":["import type { LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\n\ntype Constructor<T = object> = new (...args: any[]) => T;\n\n/**\n * Direction of a wheel tick. `+1` for `deltaY < 0` (wheel up/away), `-1` for\n * `deltaY > 0` (wheel down/toward).\n */\nexport type WheelDirection = 1 | -1;\n\n/**\n * Abstract surface a consumer of {@link WheelNudgeMixin} must implement.\n *\n * `_applyWheelDelta` is called once per handled wheel tick. The consumer is\n * expected to reuse its existing arrow-key step math (typically a shared\n * `_stepByDelta(direction, effectiveStep)` private method) and call it here.\n *\n * `_shouldHandleWheel` may be overridden to restrict when the wheel acts\n * (e.g. editable-number rejects while the user is typing).\n */\nexport interface WheelNudgeConsumer {\n _applyWheelDelta: (direction: WheelDirection, event: WheelEvent) => void;\n _shouldHandleWheel: () => boolean;\n}\n\n/**\n * Internal: the surface a {@link WheelNudgeMixin}-decorated class exposes to\n * TypeScript — its own members plus the consumer contract.\n */\nexport type WheelNudgeConsumerType<TBase> = TBase & WheelNudgeConsumer;\ntype WheelNudgeMixinBase<T> = T extends Constructor<infer U> ? U : never;\ntype WheelNudgeMixinResult<T extends Constructor<LitElement>>\n = Constructor<WheelNudgeConsumerType<WheelNudgeMixinBase<T>>> & T;\n\n/**\n * Mixin that adds mousewheel support with an optional `lighttouch` hover mode.\n *\n * Activation rule:\n * - If the host's `disabled` property is truthy → ignore.\n * - Otherwise, handle if EITHER:\n * • `lighttouch` is true AND the pointer is currently over the host, OR\n * • the host (or anything in its shadow tree) currently has focus.\n *\n * Direction convention: `deltaY < 0` (wheel up/away) → +1 step; `deltaY > 0` → -1 step.\n *\n * Consumers must implement `_applyWheelDelta(direction, event)` (see\n * {@link WheelNudgeConsumer}). The mixin calls `event.preventDefault()` only when\n * the activation rule accepts the event, so page scroll is suppressed during\n * interaction without blocking wheel events over empty space.\n *\n * Usage:\n *\n * ```ts\n * class MyInput extends WheelNudgeMixin(LitElement) {\n * protected _applyWheelDelta(direction, event) {\n * const step = resolveAxisStep(this.range, this.stops, this.step, event.shiftKey);\n * this._stepByDelta(direction, step);\n * }\n * }\n * ```\n */\nexport function WheelNudgeMixin<T extends Constructor<LitElement>>(superClass: T): WheelNudgeMixinResult<T> {\n class WheelNudgeMixinClass extends superClass {\n /**\n * When true, the wheel adjusts the value simply when the pointer is hovering\n * over the host (no focus required). When false (default), the host must\n * have focus for the wheel to act.\n */\n @property({ type: Boolean, reflect: true })\n lighttouch = false;\n\n /**\n * Imperative hover flag — not Lit-reactive (avoids update churn for what\n * is purely an interaction-time predicate).\n */\n _isHovering = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener(`pointerenter`, this._onPointerEnter);\n this.addEventListener(`pointerleave`, this._onPointerLeave);\n this.addEventListener(`wheel`, this._onWheel, { passive: false });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`pointerenter`, this._onPointerEnter);\n this.removeEventListener(`pointerleave`, this._onPointerLeave);\n this.removeEventListener(`wheel`, this._onWheel);\n this._isHovering = false;\n }\n\n _onPointerEnter = (): void => {\n this._isHovering = true;\n };\n\n _onPointerLeave = (): void => {\n this._isHovering = false;\n };\n\n /**\n * Override to restrict when wheel is handled (e.g. editable-number rejects\n * while the user is typing). Default: respect `disabled`, then apply the\n * focus-or-lighttouch rule described on the mixin.\n */\n _shouldHandleWheel(): boolean {\n const anyThis = this as unknown as { disabled?: boolean };\n if (anyThis.disabled)\n return false;\n if (this.lighttouch && this._isHovering)\n return true;\n if (this.matches?.(`:focus, :focus-within`))\n return true;\n const root = this.renderRoot;\n if (root && (root as ShadowRoot).activeElement !== null)\n return true;\n return false;\n }\n\n _onWheel = (event: WheelEvent): void => {\n if (!this._shouldHandleWheel())\n return;\n event.preventDefault();\n // Some browsers (notably when the user holds Shift) send `deltaY=0`\n // and route the scroll into `deltaX` instead. Use whichever axis\n // actually moved so the direction sign matches the user's intent.\n const delta = event.deltaY !== 0 ? event.deltaY : event.deltaX;\n const direction: WheelDirection = delta < 0 ? 1 : -1;\n (this as unknown as WheelNudgeConsumer)._applyWheelDelta(direction, event);\n };\n }\n return WheelNudgeMixinClass as unknown as WheelNudgeMixinResult<T>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,SAAgB,gBAAmD,YAAyC;CAC1G,MAAM,6BAA6B,WAAW;;;GAO/B,KAAA,aAAA;GAMC,KAAA,cAAA;GAiBgB,KAAA,wBAAA;IAC5B,KAAK,cAAc;GACrB;GAE8B,KAAA,wBAAA;IAC5B,KAAK,cAAc;GACrB;GAqBY,KAAA,YAAA,UAA4B;IACtC,IAAI,CAAC,KAAK,mBAAmB,GAC3B;IACF,MAAM,eAAe;IAKrB,MAAM,aADQ,MAAM,WAAW,IAAI,MAAM,SAAS,MAAM,UACd,IAAI,IAAI;IAClD,KAAwC,iBAAiB,WAAW,KAAK;GAC3E;;EApDA,oBAAmC;GACjC,MAAM,kBAAkB;GACxB,KAAK,iBAAiB,gBAAgB,KAAK,eAAe;GAC1D,KAAK,iBAAiB,gBAAgB,KAAK,eAAe;GAC1D,KAAK,iBAAiB,SAAS,KAAK,UAAU,EAAE,SAAS,MAAM,CAAC;EAClE;EAEA,uBAAsC;GACpC,MAAM,qBAAqB;GAC3B,KAAK,oBAAoB,gBAAgB,KAAK,eAAe;GAC7D,KAAK,oBAAoB,gBAAgB,KAAK,eAAe;GAC7D,KAAK,oBAAoB,SAAS,KAAK,QAAQ;GAC/C,KAAK,cAAc;EACrB;;;;;;EAeA,qBAA8B;GAE5B,IAAI,KAAQ,UACV,OAAO;GACT,IAAI,KAAK,cAAc,KAAK,aAC1B,OAAO;GACT,IAAI,KAAK,UAAU,uBAAuB,GACxC,OAAO;GACT,MAAM,OAAO,KAAK;GAClB,IAAI,QAAS,KAAoB,kBAAkB,MACjD,OAAO;GACT,OAAO;EACT;CAaF;CA9DG,WAAA,CAAA,SAAS;EAAE,MAAM;EAAS,SAAS;CAAK,CAAC,CAAA,GAAA,qBAAA,WAAA,cAAA,KAAA,CAAA;CA+D5C,OAAO;AACT"}
@@ -16,8 +16,8 @@ type WheelDirection = 1 | -1;
16
16
  * (e.g. editable-number rejects while the user is typing).
17
17
  */
18
18
  interface WheelNudgeConsumer {
19
- _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void;
20
- _shouldHandleWheel(): boolean;
19
+ _applyWheelDelta: (direction: WheelDirection, event: WheelEvent) => void;
20
+ _shouldHandleWheel: () => boolean;
21
21
  }
22
22
  /**
23
23
  * Internal: the surface a {@link WheelNudgeMixin}-decorated class exposes to
@@ -26,4 +26,4 @@ interface WheelNudgeConsumer {
26
26
  type WheelNudgeConsumerType<TBase> = TBase & WheelNudgeConsumer;
27
27
  //#endregion
28
28
  export { WheelNudgeConsumerType as n, WheelDirection as t };
29
- //# sourceMappingURL=wheel-nudge-DgMTRYlh.d.ts.map
29
+ //# sourceMappingURL=wheel-nudge-DGrNzWuE.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wheel-nudge-DGrNzWuE.d.ts","names":[],"sources":["../src/mixins/wheel-nudge.ts"],"mappings":";;;;;;KASY;;;;;;;;;;;UAYK;EACf,mBAAmB,WAAW,gBAAgB,OAAO;EACrD;;;;;;KAOU,uBAAuB,SAAS,QAAQ"}
@@ -1,14 +1,10 @@
1
1
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
2
- import { t as getIcon } from "./registry-CkW7q09Q.js";
3
- import "./icons.js";
4
- import { LitElement, css, html, nothing, svg } from "lit";
2
+ import { LitElement, css, html, svg } from "lit";
5
3
  import { property, state } from "lit/decorators.js";
6
- import { unsafeHTML } from "lit/directives/unsafe-html.js";
7
4
  import { Colour } from "@ixfx/visual";
8
5
  import { clamp, rangeStream } from "@ixfx/numbers";
9
6
  import { repeat } from "lit/directives/repeat.js";
10
7
  import { Easings } from "@ixfx/modulation";
11
- import { classMap } from "lit/directives/class-map.js";
12
8
  //#region src/plots/colour-map.ts
13
9
  const DEFAULT_BASE = `oklch(60% 0.15 140)`;
14
10
  const DEFAULT_PALETTE = [
@@ -247,108 +243,6 @@ var PlotDataSeries = class {
247
243
  }
248
244
  };
249
245
  //#endregion
250
- //#region src/util/is-numeric.ts
251
- function isNumeric(str) {
252
- if (typeof str === `number`) return true;
253
- if (typeof str !== `string`) return false;
254
- const trimmed = str.trim();
255
- return trimmed !== `` && !Number.isNaN(Number(trimmed));
256
- }
257
- //#endregion
258
- //#region src/util/tooltip.ts
259
- var _TooltipElement;
260
- let _baseStylesInjected = false;
261
- function ensureBaseTooltipStyles() {
262
- if (_baseStylesInjected) return;
263
- _baseStylesInjected = true;
264
- const style = document.createElement(`style`);
265
- style.textContent = `
266
- ixfx-tooltip {
267
- display: inline-block;
268
- background: var(--surface-5);
269
- color: var(--surface-5-text);
270
- border: var(--border);
271
- border-radius: var(--radius-l, 6px);
272
- box-shadow: var(--shadow-m);
273
- padding: var(--space-s, 4px);
274
- font-size: 10px;
275
- font-family: var(--font-family, inherit);
276
- }
277
- ixfx-tooltip .tooltip-type-number {
278
- font-family: var(--font-mono, ui-monospace, monospace);
279
- }
280
- `;
281
- document.head.appendChild(style);
282
- }
283
- let TooltipElement = class TooltipElement extends LitElement {
284
- static {
285
- _TooltipElement = this;
286
- }
287
- constructor(..._args) {
288
- super(..._args);
289
- this.valueFormatTooltip = _TooltipElement.defaultFormatter;
290
- this.orientation = `top`;
291
- this.anchor = `--tooltip`;
292
- }
293
- connectedCallback() {
294
- super.connectedCallback();
295
- ensureBaseTooltipStyles();
296
- }
297
- static {
298
- this.numberFormatter = (v) => Math.floor(v).toString();
299
- }
300
- static {
301
- this.defaultFormatter = (v) => {
302
- if (typeof v === `number`) {
303
- if (Number.isInteger(v)) return v.toString();
304
- return v.toFixed(2);
305
- } else if (typeof v === `string`) return v;
306
- else return JSON.stringify(v);
307
- };
308
- }
309
- #renderIcon() {
310
- if (!this.icon) return nothing;
311
- if (this.icon.startsWith(`<svg`)) return html`<span class="tooltip-icon" style="display:inline-flex;align-items:center;margin-right:0.25em">${unsafeHTML(this.icon)}</span>`;
312
- if (!getIcon(this.icon)) return nothing;
313
- return html`<ixfx-icon class="tooltip-icon" style="margin-right:0.25em" name="${this.icon}"></ixfx-icon>`;
314
- }
315
- render() {
316
- const classes = {
317
- "tooltip": true,
318
- "tooltip-orientation-top": this.orientation === `top`,
319
- "tooltip-orientation-bottom": this.orientation === `bottom`,
320
- "tooltip-orientation-right": this.orientation === `right`,
321
- "tooltip-orientation-left": this.orientation === `left`,
322
- "tooltip-type-text": true,
323
- "tooltip-type-number": false,
324
- "tooltip-style-bubble": true
325
- };
326
- let value = ``;
327
- switch (typeof this.value) {
328
- case `number`:
329
- classes[`tooltip-type-number`] = true;
330
- value = this.valueFormatTooltip(this.value);
331
- break;
332
- case `string`:
333
- if (isNumeric(this.value)) {
334
- classes[`tooltip-type-number`] = true;
335
- value = this.valueFormatTooltip(Number.parseFloat(this.value));
336
- } else value = this.value;
337
- break;
338
- default: value = JSON.stringify(this.value);
339
- }
340
- return html`<output style="--anchor-id: ${this.anchor}" class=${classMap(classes)}>${this.#renderIcon()}${value}</output>`;
341
- }
342
- createRenderRoot() {
343
- return this;
344
- }
345
- };
346
- __decorate([property({ type: String })], TooltipElement.prototype, "orientation", void 0);
347
- __decorate([property({ type: String })], TooltipElement.prototype, "anchor", void 0);
348
- __decorate([property()], TooltipElement.prototype, "value", void 0);
349
- __decorate([property({ type: String })], TooltipElement.prototype, "icon", void 0);
350
- TooltipElement = _TooltipElement = __decorate([safeCustomElement(`ixfx-tooltip`)], TooltipElement);
351
- //#endregion
352
246
  //#region src/plots/svg-utils.ts
353
247
  let _tooltipEl = null;
354
248
  let _tooltipOwner = null;
@@ -1844,6 +1738,6 @@ __decorate([state()], PlotXyAxis.prototype, "_width", void 0);
1844
1738
  __decorate([state()], PlotXyAxis.prototype, "_height", void 0);
1845
1739
  PlotXyAxis = __decorate([safeCustomElement(`ixfx-plot-xy-axis`)], PlotXyAxis);
1846
1740
  //#endregion
1847
- export { TooltipElement as a, computeColour as c, PlotMultiAxis as i, parseColourScaleAttr as l, PlotSingleAxis as n, PlotDataSeries as o, PlotHistogram as r, applyAgeModification as s, PlotXyAxis as t, readBaseColour as u };
1741
+ export { PlotDataSeries as a, parseColourScaleAttr as c, PlotMultiAxis as i, readBaseColour as l, PlotSingleAxis as n, applyAgeModification as o, PlotHistogram as r, computeColour as s, PlotXyAxis as t };
1848
1742
 
1849
- //# sourceMappingURL=xy-axis-CxHC8z5E.js.map
1743
+ //# sourceMappingURL=xy-axis-B6yMjckW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xy-axis-B6yMjckW.js","names":["#options","#rangeManual","#recompute","#rangeAuto","#rangeStream","#addToSeries","#ensurePlot","#seriesSet","#seriesOrder","#instances","#pendingStyles","#onSubPlotPointerMove","#onSubPlotPointerLeave","#escapeHTML","customElement","#bucketIndexFromPointer","#setInlineIndex","#updateBubbleTooltip","#hasProgrammaticData","#series","#parseDeclarativeData","#resetHoverState","#readCssVar","#computeGeometry","#getGapPx","#getBarLengthOverride","#computeBars","#valueRefreshTimer","#clearValueRefreshTimer","#scheduleValueRefresh","#tooltipShowTimer","#tooltipHideTimer","#tooltipVisible","#tooltipIndex","#tooltipPosition","#clearBubbleTooltip","#tooltipPositionFor","#refreshBubbleText","#formatBarAt","#emitClick","#onPointerMove","#onPointerLeave","customElement","#lastClientX","#lastClientY","#updateTooltip","#getIndexFromX","#series","#hasProgrammaticData","#updateTooltipAtLastPos","#parseDeclarativeData","#computePoints","#renderByStyle","#onPointerMove","#onPointerLeave","#onClick","customElement","#lastClientX","#lastClientY","#updateTooltip","#findNearestPoint","#lastPoints","#xSeries","#ySeries","#updateTooltipAtLastPos","#computePoints","#computeColours","#onPointerMove","#onPointerLeave","#onClick","customElement"],"sources":["../src/plots/colour-map.ts","../src/plots/data.ts","../src/plots/svg-utils.ts","../src/plots/multi-axis.ts","../src/plots/plot-histogram.ts","../src/plots/single-axis.ts","../src/plots/xy-axis.ts"],"sourcesContent":["/**\n * Colour mapping for plot components.\n *\n * Pipeline:\n * scaledValue (0..1)\n * → applyMapping (easing / custom fn)\n * → computeColour (mode → ColourResult)\n * → applyAgeModification (xy-axis only, compounds age-style on top)\n */\nimport type { EasingName } from '@ixfx/modulation';\nimport { Easings } from '@ixfx/modulation';\nimport { Colour } from '@ixfx/visual';\n\n// --- Types ---\n\nexport type ColourMode = `fixed` | `opacity` | `hue` | `saturation` | `lightness` | `scale`;\n\nexport type ColourMapConfig = {\n mode: ColourMode;\n /** Parsed colours for 'scale' mode. Must have ≥ 2 entries. */\n palette: string[];\n /** ixfx easing name — applied before the colour mode mapping. Takes precedence over valueMap. */\n easingName: string;\n /** Custom value mapping fn (0..1 → 0..1). Used when easingName is empty. */\n valueMap: ((v: number) => number) | null;\n};\n\nexport type ColourResult = { fill: string; opacity: number };\n\n// --- Defaults ---\n\nconst DEFAULT_BASE = `oklch(60% 0.15 140)`;\nconst DEFAULT_PALETTE = [`green`, `yellow`, `red`];\n\n// --- Scale cache: keyed by palette string to avoid recomputing colour steps every render ---\n\nconst _scaleCache = new Map<string, string[]>();\n\nfunction getScaleSteps(palette: string[]): string[] {\n const key = palette.join(`\\x00`);\n if (!_scaleCache.has(key)) {\n _scaleCache.set(key, Colour.scale(palette as Parameters<typeof Colour.scale>[0], { stepsBetween: 99 }));\n }\n return _scaleCache.get(key)!;\n}\n\n// --- Helpers ---\n\n/** Resolve a CSS custom property to its final value, handling var() references. */\nfunction resolveCssVariable(el: Element, prop: string): string {\n const style = getComputedStyle(el);\n let value = style.getPropertyValue(prop).trim();\n\n // Handle var() references - resolve up to 5 levels deep\n const varRegex = /var\\((--[\\w-]+)(?:,\\s*(.*))?\\)/g;\n for (let i = 0; i < 5 && value.includes(`var(`); i++) {\n value = value.replace(varRegex, (_, varName, fallback) => {\n const resolved = style.getPropertyValue(varName).trim();\n if (resolved)\n return resolved;\n if (fallback)\n return fallback.trim();\n return ``;\n });\n }\n\n return value;\n}\n\n/** Read the resolved --plot-color CSS variable from an element. */\nexport function readBaseColour(el: Element): string {\n const v = resolveCssVariable(el, `--plot-color`);\n return v || DEFAULT_BASE;\n}\n\n/** Parse a comma-separated colour string attribute into an array. Falls back to default palette. */\nexport function parseColourScaleAttr(attr: string): string[] {\n if (!attr.trim())\n return DEFAULT_PALETTE;\n const parsed = attr.split(`,`).map(s => s.trim()).filter(Boolean);\n return parsed.length >= 2 ? parsed : DEFAULT_PALETTE;\n}\n\n/** Parse any CSS colour string to HSL scalars (h, s, l all 0..1). */\nfunction toHslScalar(css: string): { h: number; s: number; l: number } {\n try {\n const hsl = Colour.HslSpace.fromCss(css, { scalar: true });\n return { h: hsl.h, s: hsl.s, l: hsl.l };\n } catch {\n return { h: 0.39, s: 0.5, l: 0.55 }; // ~green fallback\n }\n}\n\n/** Apply easing or custom mapping to a 0..1 value. Returns clamped 0..1. */\nfunction applyMapping(v: number, config: ColourMapConfig): number {\n const clamped = Math.max(0, Math.min(1, v));\n if (config.easingName) {\n try {\n return Math.max(0, Math.min(1, Easings.get(config.easingName as EasingName)(clamped)));\n } catch { /* invalid easing name — fall through */ }\n }\n if (config.valueMap) {\n return Math.max(0, Math.min(1, config.valueMap(clamped)));\n }\n return clamped;\n}\n\n// --- Main colour computation ---\n\n/**\n * Compute the fill colour and opacity for a single data point.\n * @param scaledValue Normalised value in 0..1 (data range for single-axis; age fraction for xy).\n * @param baseColour Resolved base colour string (from --plot-color).\n * @param config Colour map configuration.\n */\nexport function computeColour(scaledValue: number, baseColour: string, config: ColourMapConfig): ColourResult {\n const mapped = applyMapping(scaledValue, config);\n\n switch (config.mode) {\n case `fixed`:\n return { fill: baseColour, opacity: 1 };\n\n case `opacity`:\n return { fill: baseColour, opacity: Math.max(0.04, mapped) };\n\n case `hue`: {\n const hsl = toHslScalar(baseColour);\n return {\n fill: `hsl(${Math.round(mapped * 360)}deg ${Math.round(hsl.s * 100)}% ${Math.round(hsl.l * 100)}%)`,\n opacity: 1,\n };\n }\n\n case `saturation`: {\n const hsl = toHslScalar(baseColour);\n return {\n fill: `hsl(${Math.round(hsl.h * 360)}deg ${Math.round(mapped * 100)}% ${Math.round(hsl.l * 100)}%)`,\n opacity: 1,\n };\n }\n\n case `lightness`: {\n const hsl = toHslScalar(baseColour);\n return {\n fill: `hsl(${Math.round(hsl.h * 360)}deg ${Math.round(hsl.s * 100)}% ${Math.round(mapped * 100)}%)`,\n opacity: 1,\n };\n }\n\n case `scale`: {\n const palette = config.palette.length >= 2 ? config.palette : DEFAULT_PALETTE;\n const steps = getScaleSteps(palette);\n const idx = Math.min(steps.length - 1, Math.floor(mapped * steps.length));\n return { fill: steps[idx], opacity: 1 };\n }\n\n default:\n return { fill: baseColour, opacity: 1 };\n }\n}\n\n/**\n * Apply xy-axis age-style modification on top of a base ColourResult.\n * 'size' is not handled here — the caller adjusts the radius separately.\n */\nexport function applyAgeModification(base: ColourResult, ageFraction: number, ageStyle: string): ColourResult {\n if (ageStyle === `opacity`) {\n return { ...base, opacity: base.opacity * Math.max(0.08, ageFraction ** 0.6) };\n }\n if (ageStyle === `desaturation`) {\n const hsl = toHslScalar(base.fill);\n const sFaded = hsl.s * ageFraction; // older → less saturation\n return {\n fill: `hsl(${Math.round(hsl.h * 360)}deg ${Math.round(sFaded * 100)}% ${Math.round(hsl.l * 100)}%)`,\n opacity: base.opacity,\n };\n }\n return base;\n}\n","import { rangeStream } from \"@ixfx/numbers\";\n\nexport type PlotDataSeriesOptions = {\n /**\n * Limit of how many data points to store.\n * Default: 100\n */\n capacityLimit: number;\n /**\n * If _true_, it maintains the same scale over its lifetime.\n * If _false_, scale adjusts based on items in its cache.\n *\n * Default: true\n */\n persistentScaling: boolean;\n\n fixedRange: { min: number; max: number } | null;\n};\n\n/**\n * A data series\n */\nexport class PlotDataSeries {\n values: number[] = [];\n #rangeStream = rangeStream();\n #rangeAuto: { min: number; max: number } = { min: 0, max: 0 };\n #rangeManual: { min: number; max: number } | null = null;\n #options: PlotDataSeriesOptions;\n\n /**\n * Constructor.\n *\n * Default options:\n * - `capacityLimit`: 100\n * - `persistentScaling`: true\n * - `fixedRange`: null\n * @param options\n */\n constructor(options: Partial<PlotDataSeriesOptions> = {}) {\n this.#options = {\n capacityLimit: 100,\n persistentScaling: true,\n fixedRange: null,\n ...options,\n };\n if (this.#options.fixedRange !== null) {\n this.#rangeManual = this.#options.fixedRange;\n }\n }\n\n /**\n * Sets a manual range, this disabled auto-scaling.\n * Use {@link unsetRange} to re-enable auto-scaling.\n * @param min\n * @param max\n */\n setRange(min: number, max: number) {\n this.#rangeManual = { min, max };\n }\n\n /**\n * Disable the manual range\n */\n unsetRange() {\n this.#rangeManual = null;\n this.#recompute();\n }\n\n get isAutoRange() {\n return this.#rangeManual === null;\n }\n\n /**\n * Adds a single value\n * @param valueOrValues Value to add\n */\n add(valueOrValues: number | number[]) {\n if (typeof valueOrValues === `number`) {\n this.values.push(valueOrValues);\n if (this.isAutoRange) {\n this.#rangeAuto = this.#rangeStream.seen(valueOrValues);\n }\n } else {\n this.values.push(...valueOrValues);\n if (this.isAutoRange) {\n for (const v of valueOrValues) {\n this.#rangeAuto = this.#rangeStream.seen(v);\n }\n }\n }\n if (this.values.length > this.#options.capacityLimit) {\n this.values = this.values.slice(this.values.length - this.#options.capacityLimit);\n if (!this.#options.persistentScaling && this.isAutoRange) {\n this.#recompute();\n }\n }\n }\n\n #recompute() {\n if (!this.#options.persistentScaling) {\n this.#rangeStream = rangeStream();\n }\n for (let i = 0; i < this.values.length; i++) {\n this.#rangeAuto = this.#rangeStream.seen(this.values[i]);\n }\n }\n\n /**\n * Sets the entire data series at once, replacing any existing data. If the number of values exceeds the `capacityLimit`, only the most recent values up to the limit are kept.\n * @param values\n */\n set(values: number[]) {\n if (values.length > this.#options.capacityLimit) {\n values = values.slice(values.length - this.#options.capacityLimit);\n }\n this.values = values;\n this.#recompute();\n }\n\n /**\n * Returns the manual range if this is in effect, or the automatic\n */\n get range() {\n if (this.#rangeManual)\n return this.#rangeManual;\n return this.#rangeAuto;\n }\n\n /**\n * Clear all data and reset range. If `persistentScaling` is _false_, also resets scaling to initial state.\n * @returns _true_ if there was data to clear\n */\n clear(): boolean {\n const empty = this.values.length === 0;\n this.values = [];\n if (!this.#options.persistentScaling) {\n this.#recompute();\n }\n return !empty;\n }\n}","/**\n * Shared utilities for SVG-based plot components.\n */\nimport type { TooltipElement } from '../util/tooltip.js';\nimport '../util/tooltip.js';\n\n// --- Tooltip singleton ---\n\nlet _tooltipEl: HTMLDivElement | null = null;\nlet _tooltipOwner: Element | null = null;\n\nfunction ensureTooltip(): HTMLDivElement {\n if (_tooltipEl)\n return _tooltipEl;\n const el = document.createElement(`div`);\n el.style.cssText = `\n position: fixed;\n pointer-events: none;\n z-index: 9999;\n background: var(--surface-5);\n color: var(--surface-5-text);\n border: var(--border);\n border-radius: var(--radius-l, 6px);\n box-shadow: var(--shadow-m);\n padding: 2px 6px;\n font-size: 10px;\n font-family: ui-monospace, monospace;\n opacity: 0;\n transition: opacity 0.1s ease;\n `;\n document.body.appendChild(el);\n _tooltipEl = el;\n return el;\n}\n\nexport function showTooltip(owner: Element, clientX: number, clientY: number, text: string): void {\n const el = ensureTooltip();\n _tooltipOwner = owner;\n el.textContent = text;\n el.style.whiteSpace = `nowrap`;\n el.style.left = `${clientX + 14}px`;\n el.style.top = `${clientY + 14}px`;\n el.style.opacity = `1`;\n}\n\nexport function showTooltipHTML(owner: Element, clientX: number, clientY: number, html: string): void {\n const el = ensureTooltip();\n _tooltipOwner = owner;\n el.innerHTML = html;\n el.style.whiteSpace = `normal`;\n el.style.left = `${clientX + 14}px`;\n el.style.top = `${clientY + 14}px`;\n el.style.opacity = `1`;\n}\n\nexport function hideTooltip(owner: Element): void {\n if (_tooltipOwner !== owner)\n return;\n const el = ensureTooltip();\n el.style.opacity = `0`;\n _tooltipOwner = null;\n}\n\n// --- Bar/segment bubble tooltip (ixfx-tooltip based) ---\n//\n// Unlike showTooltip() above (which tracks the cursor directly), this variant is meant\n// for discrete hover targets (e.g. histogram buckets): the caller decides *when* to\n// (re)position it (typically only on a hovered-index change, not on every pointermove),\n// and where along the cross-axis it should sit (typically cursor-relative, captured once).\n\nlet _bubbleEl: TooltipElement | null = null;\nlet _bubbleOwner: Element | null = null;\n\n// Visual chrome (background/border/radius/shadow/padding/font) is intrinsic to `ixfx-tooltip`\n// itself (see ensureBaseTooltipStyles() in util/tooltip.ts) - only positioning/animation is set here.\nfunction ensureBubble(): TooltipElement {\n if (_bubbleEl)\n return _bubbleEl;\n const el = document.createElement(`ixfx-tooltip`) as TooltipElement;\n el.style.cssText = `\n position: fixed;\n z-index: 9999;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.12s ease;\n `;\n document.body.appendChild(el);\n _bubbleEl = el;\n return el;\n}\n\n/**\n * Shows/repositions an `ixfx-tooltip` bubble.\n * `mainClient` centers the bubble along the given axis (e.g. a bar's midpoint);\n * `crossClient` places it along the other axis (e.g. an offset from the cursor).\n */\nexport function showBubbleTooltip(owner: Element, text: string, mainClient: number, crossClient: number, orientation: `horizontal` | `vertical`): void {\n const el = ensureBubble();\n _bubbleOwner = owner;\n el.value = text;\n if (orientation === `horizontal`) {\n el.style.left = `${mainClient}px`;\n el.style.top = `${crossClient}px`;\n el.style.transform = `translate(-50%, -100%)`;\n } else {\n el.style.left = `${crossClient}px`;\n el.style.top = `${mainClient}px`;\n el.style.transform = `translate(0, -50%)`;\n }\n el.style.opacity = `1`;\n}\n\nexport function hideBubbleTooltip(owner: Element): void {\n if (_bubbleOwner !== owner)\n return;\n const el = ensureBubble();\n el.style.opacity = `0`;\n _bubbleOwner = null;\n}\n\n// --- Sizing helpers ---\n\n/** Stroke width proportional to the smaller dimension of the viewport. */\nexport function adaptiveStroke(width: number, height: number): number {\n return Math.max(1, Math.min(width, height) / 25);\n}\n\n/** Dot radius based on available space per data point and viewport height. */\nexport function adaptiveRadius(width: number, height: number, dataLength: number): number {\n if (dataLength === 0)\n return 3;\n const widthPerPoint = width / dataLength;\n return Math.max(1.5, Math.min(widthPerPoint * 0.45, height * 0.2, 8));\n}\n\n// --- Value scaling ---\n\n/** Normalize a value from [min, max] to [0, 1]. Returns 0.5 if range is zero. */\nexport function scaleValue(v: number, min: number, max: number): number {\n const range = max - min;\n return range === 0 ? 0.5 : (v - min) / range;\n}\n","import type { PlotSingleAxis, PlotSingleAxisPointerMoveDetail } from './single-axis.js';\nimport { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { hideTooltip, showTooltipHTML } from './svg-utils.js';\n\nexport type PlotMultiAxisLayout = `overlap` | `horizontal` | `vertical` | `grid`;\n\nexport type PlotMultiAxisDataPointClickDetail = {\n readonly value: number;\n readonly index: number;\n readonly series: string;\n};\n\nexport type PlotMultiAxisDataPointClickEvent = CustomEvent<PlotMultiAxisDataPointClickDetail>;\n\nexport interface PlotMultiAxisElementEventMap {\n 'plot-datapoint-click': PlotMultiAxisDataPointClickEvent;\n}\n\nconst PLOT_PALETTE = [\n `oklch(60% 0.15 30)`,\n `oklch(60% 0.15 90)`,\n `oklch(60% 0.15 150)`,\n `oklch(60% 0.15 210)`,\n `oklch(60% 0.15 270)`,\n `oklch(60% 0.15 330)`,\n `oklch(60% 0.15 60)`,\n `oklch(60% 0.15 180)`,\n];\n\n@customElement(`ixfx-plot-multi-axis`)\n// eslint-disable-next-line ts/no-unsafe-declaration-merging\nexport class PlotMultiAxis extends LitElement {\n @property() layout: PlotMultiAxisLayout = `overlap`;\n\n @property({ attribute: `grid-min-width`, type: Number })\n gridMinWidth = 200;\n\n /** Override to customize tooltip value display. */\n valueFormat: (v: number | undefined) => string = v => v ? v.toFixed(2) : ``;\n\n #instances = new Map<string, PlotSingleAxis>();\n #seriesOrder: string[] = [];\n #seriesSet = new Set<string>();\n #pendingStyles = new Map<string, Record<string, string>>();\n\n /**\n * Adds a single data point\n * @param name Series name\n * @param value Value\n * @param witholdRedraw If _false_ (default) plot is automatically redrawn\n */\n addData(name: string, value: number, witholdRedraw = false): PlotSingleAxis {\n const el = this.#addToSeries(name, value, witholdRedraw);\n // if (witholdRedraw)\n // return el;\n // this.requestUpdate();\n // this.redraw();\n return el;\n }\n\n setData(name: string, values: number[], witholdRedraw = false): PlotSingleAxis {\n const [el, created] = this.#ensurePlot(name);\n if (!this.#seriesSet.has(name)) {\n this.#seriesSet.add(name);\n this.#seriesOrder.push(name);\n }\n el.set(values, witholdRedraw);\n // if (witholdRedraw)\n // return el;\n if (created)\n this.requestUpdate();\n return el;\n }\n\n setObjects(data: Record<string, number[]>, witholdRedraw = false): void {\n const entries = Object.entries(data);\n for (const [name, vals] of entries) {\n this.setData(name, vals, true);\n }\n if (witholdRedraw)\n return;\n // this.requestUpdate();\n this.redraw();\n }\n\n /**\n * Calls redraw() on all subplots.\n */\n redraw(): void {\n for (const el of this.#instances.values()) {\n el.redraw();\n }\n }\n\n /**\n * Adds a record of data points to the plot. Each key in the record corresponds to a series name, and its value is added as a data point to that series. If a series does not exist for a given key, it will be created.\n * @param data Data to add\n * @param witholdRedraw If _false_ (default) plot is automatically redrawn after adding the data. If _true_, plot is not redrawn automatically, and you need to call `redraw()` manually to update the plot after adding the data.\n */\n addObject(data: Record<string, number | number[]>, witholdRedraw = false): void {\n const entries = Object.entries(data);\n for (const [name, val] of entries) {\n this.#addToSeries(name, val, true);\n }\n if (witholdRedraw)\n return;\n // this.requestUpdate();\n this.redraw();\n }\n\n /**\n * Styles a series by setting CSS variables on the subplot.\n * @param name Name of series\n * @param styles Styles to apply\n */\n styleSeries(name: string, styles: Record<string, string>): void {\n const normalised: Record<string, string> = {};\n for (const [key, val] of Object.entries(styles)) {\n normalised[key.startsWith(`--`) ? key : `--${key}`] = val;\n }\n\n const el = this.#instances.get(name);\n if (!el) {\n this.#pendingStyles.set(name, normalised);\n return;\n }\n for (const [key, val] of Object.entries(normalised)) {\n el.style.setProperty(key, val);\n }\n }\n\n /**\n * Clears data from all sub-plots\n * @returns _True_ if there was data to clear\n */\n clear(): boolean {\n let cleared = false;\n for (const el of this.#instances.values()) {\n cleared = cleared || el.clear();\n }\n return cleared;\n }\n\n /**\n * Clears data from a given series\n * @param name Series name\n * @returns _True_ if series was found and had data\n */\n clearSeries(name: string): boolean {\n const el = this.#instances.get(name);\n if (el) {\n el.clear();\n return true;\n }\n return false;\n }\n\n /**\n * Returns a copy of the series names\n */\n get series(): string[] {\n return [...this.#seriesOrder];\n }\n\n #addToSeries(name: string, valueOrValues: number[] | number, withholdRedraw = false): PlotSingleAxis {\n const [el, created] = this.#ensurePlot(name);\n\n if (!this.#seriesSet.has(name)) {\n this.#seriesSet.add(name);\n this.#seriesOrder.push(name);\n }\n\n el.add(valueOrValues, withholdRedraw);\n if (created)\n this.requestUpdate();\n return el;\n }\n\n #ensurePlot(name: string): [el: PlotSingleAxis, created: boolean] {\n let el = this.#instances.get(name);\n if (el)\n return [el, false];\n\n el = document.createElement(`ixfx-plot-single-axis`) as PlotSingleAxis;\n el.tooltips = false;\n this.#instances.set(name, el);\n\n const colorIndex = this.#instances.size % PLOT_PALETTE.length;\n el.style.setProperty(`--plot-color`, PLOT_PALETTE[colorIndex]);\n\n const pending = this.#pendingStyles.get(name);\n if (pending) {\n for (const [key, val] of Object.entries(pending)) {\n el.style.setProperty(key, val);\n }\n this.#pendingStyles.delete(name);\n }\n\n el.addEventListener(`plot-datapoint-click`, (e: Event) => {\n const ce = e as CustomEvent<{ value: number; index: number }>;\n this.dispatchEvent(\n new CustomEvent<PlotMultiAxisDataPointClickDetail>(`plot-datapoint-click`, {\n detail: { ...ce.detail, series: name },\n bubbles: true,\n composed: true,\n }),\n );\n });\n\n el.addEventListener(`plot-pointer-move`, (e: Event) => {\n const ce = e as CustomEvent<PlotSingleAxisPointerMoveDetail>;\n this.#onSubPlotPointerMove(ce.detail.clientX, ce.detail.clientY, ce.detail.index);\n });\n\n el.addEventListener(`plot-pointer-leave`, () => {\n this.#onSubPlotPointerLeave();\n });\n\n return [el, true];\n }\n\n #onSubPlotPointerMove(clientX: number, clientY: number, index: number): void {\n if (index < 0) {\n hideTooltip(this);\n return;\n }\n\n const parts: string[] = [];\n for (const [name, inst] of this.#instances) {\n const val = inst.getValueAt(index);\n if (val === undefined)\n continue;\n const color = getComputedStyle(inst).getPropertyValue(`--plot-color`).trim();\n parts.push(`<span style=\"color:${color}\">${this.#escapeHTML(name)}</span> ${this.valueFormat(val)}`);\n }\n\n if (parts.length === 0) {\n hideTooltip(this);\n return;\n }\n\n showTooltipHTML(this, clientX, clientY, parts.join(`<br>`));\n }\n\n #onSubPlotPointerLeave(): void {\n hideTooltip(this);\n }\n\n #escapeHTML(s: string): string {\n return s.replace(/&/g, `&amp;`).replace(/</g, `&lt;`).replace(/>/g, `&gt;`).replace(/\"/g, `&quot;`);\n }\n\n protected override render() {\n const gridStyle = this.layout === `grid` ? `--grid-min-width: ${this.gridMinWidth}px` : ``;\n\n return html`\n <div\n id=\"container\"\n class=\"layout layout-${this.layout}\"\n part=\"container\"\n style=${gridStyle}\n >\n ${repeat(\n this.#seriesOrder,\n name => name,\n name => this.#ensurePlot(name)[0],\n )}\n </div>\n `;\n }\n\n static override styles = css`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n min-height: 40px;\n --plot-color: var(--accent);\n }\n\n #container {\n width: 100%;\n height: 100%;\n }\n\n #container.layout-overlap {\n display: grid;\n }\n #container.layout-overlap > * {\n grid-area: 1 / 1;\n background: transparent;\n }\n\n #container.layout-horizontal {\n display: flex;\n flex-direction: row;\n gap: var(--space-s, 4px);\n }\n #container.layout-horizontal > * {\n flex: 1;\n min-width: 0;\n }\n\n #container.layout-vertical {\n display: flex;\n flex-direction: column;\n gap: var(--space-s, 4px);\n }\n #container.layout-vertical > * {\n flex: 1;\n min-height: 0;\n }\n\n #container.layout-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(var(--grid-min-width, 200px), 1fr));\n gap: var(--space-s, 4px);\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-plot-multi-axis': PlotMultiAxis;\n }\n}\n\n// eslint-disable-next-line ts/no-unsafe-declaration-merging\nexport interface PlotMultiAxis {\n addEventListener: {\n <K extends keyof PlotMultiAxisElementEventMap>(\n type: K,\n listener: (this: PlotMultiAxis, event: PlotMultiAxisElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n (\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n };\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { PropertyValues } from 'lit';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { PlotDataSeries } from './data.js';\nimport { hideBubbleTooltip, showBubbleTooltip } from './svg-utils.js';\n\nexport type PlotHistogramOrientation = `horizontal` | `vertical`;\n\n/**\n * - `hover`: floating `ixfx-tooltip` bubble, shown/hidden with a debounce delay.\n * - `inline`: the title overlay-text switches to the hovered bucket's value, instantly.\n * - `none`: no hover feedback.\n */\nexport type PlotHistogramValueTooltips = `hover` | `inline` | `none`;\n\nexport type PlotHistogramBucketClickDetail = {\n readonly bucketIndex: number;\n readonly valueMin: number;\n readonly valueMax: number;\n readonly relativeValue: number;\n};\n\nexport type PlotHistogramBucketClickEvent = CustomEvent<PlotHistogramBucketClickDetail>;\n\nexport interface PlotHistogramElementEventMap {\n 'plot-bucket-click': PlotHistogramBucketClickEvent;\n}\n\ntype BarLayout = {\n count: number;\n valueMin: number;\n valueMax: number;\n relativeValue: number;\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\n@customElement(`ixfx-plot-histogram`)\nexport class PlotHistogram extends LitElement {\n @property({ attribute: `orientation` })\n orientation: PlotHistogramOrientation = `horizontal`;\n\n @property({ type: Number })\n resolution = 0.1;\n\n @property({ type: Number })\n min?: number;\n\n @property({ type: Number })\n max?: number;\n\n @property({ type: Number })\n capacity = 100;\n\n /**\n * Fallback overlay-text, shown when nothing is hovered.\n * Not reflected to the native `title` attribute, so the browser's own hover tooltip doesn't show.\n */\n @property({ attribute: false })\n title = ``;\n\n @property({ type: Boolean, reflect: true })\n paused = false;\n\n /** How hovering a bucket is communicated: a floating tooltip, the inline overlay-text, or nothing. */\n @property({ attribute: `value-tooltips` })\n valueTooltips: PlotHistogramValueTooltips = `hover`;\n\n /** Delay (ms) before the `hover` tooltip appears/disappears. Switching directly between buckets is instant. */\n @property({ type: Number, attribute: `tooltip-delay` })\n tooltipDelay = 400;\n\n /** Max rate (ms) at which an already-shown value display refreshes to match live-changing bucket data. */\n @property({ type: Number, attribute: `value-update-interval` })\n valueUpdateInterval = 500;\n\n /** Override to customize the value/frequency label used by the tooltip and overlay text. */\n valueFormat: (valueMin: number, valueMax: number, frequency: number) => string\n = (valueMin, valueMax, frequency) => `${valueMin.toFixed(2)} - ${valueMax.toFixed(2)}: ${frequency}`;\n\n @state() private _width = 100;\n @state() private _height = 40;\n @state() private _hoveredIndex: number | null = null;\n @state() private _inlineOverlayText: string | null = null;\n\n #series = new PlotDataSeries({ capacityLimit: 100, persistentScaling: true });\n #hasProgrammaticData = false;\n\n #parseDeclarativeData(text: string): number[] {\n if (!text)\n return [];\n const tokens = text.trim().split(/[,\\s;]+/);\n return tokens.map(t => Number.parseFloat(t)).filter(n => !Number.isNaN(n));\n }\n\n add(v: number): void {\n this.#hasProgrammaticData = true;\n this.#series.add(v);\n if (this.paused)\n return;\n this.requestUpdate();\n }\n\n set(values: number[]): void {\n this.#hasProgrammaticData = true;\n this.#series.set(values);\n if (this.paused)\n return;\n this.requestUpdate();\n }\n\n clear(): void {\n this.#series.clear();\n this.requestUpdate();\n }\n\n protected override firstUpdated(_changed: PropertyValues): void {\n this._width = this.clientWidth || 100;\n this._height = this.clientHeight || 40;\n const ro = new ResizeObserver((entries) => {\n const e = entries[0];\n this._width = e.contentRect.width;\n this._height = e.contentRect.height;\n });\n ro.observe(this);\n\n if (!this.#hasProgrammaticData) {\n const data = this.#parseDeclarativeData(this.textContent ?? ``);\n if (data.length > 0) {\n this.#series.set(data);\n }\n }\n\n // `title` is a standard global HTML attribute the browser uses for its own native hover\n // tooltip. Read any declarative value into our (attribute-less) property, then strip the\n // attribute so only our overlay-text/tooltip UI reacts to hover, not the browser's.\n const declaredTitle = this.getAttribute(`title`);\n if (declaredTitle !== null) {\n this.title = declaredTitle;\n this.removeAttribute(`title`);\n }\n }\n\n protected override updated(changed: PropertyValues): void {\n if (changed.has(`capacity`)) {\n const old = [...this.#series.values];\n this.#series = new PlotDataSeries({\n capacityLimit: this.capacity,\n persistentScaling: true,\n });\n if (old.length > 0)\n this.#series.set(old);\n }\n if (changed.has(`valueTooltips`))\n this.#resetHoverState();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#resetHoverState();\n }\n\n #readCssVar(name: string): string {\n return getComputedStyle(this).getPropertyValue(name).trim();\n }\n\n #getGapPx(): number {\n const val = this.#readCssVar(`--plot-histogram-gap`);\n if (val === ``)\n return 1;\n const parsed = Number.parseFloat(val);\n return Number.isFinite(parsed) ? Math.max(0, parsed) : 1;\n }\n\n #getBarLengthOverride(): number | null {\n const val = this.#readCssVar(`--plot-histogram-bar-length`);\n if (val === `` || val === `auto`)\n return null;\n const parsed = Number.parseFloat(val);\n return Number.isFinite(parsed) ? Math.max(0, Math.min(1, parsed)) : null;\n }\n\n #emitClick(i: number, valueMin: number, valueMax: number, relativeValue: number): void {\n this.dispatchEvent(\n new CustomEvent<PlotHistogramBucketClickDetail>(`plot-bucket-click`, {\n detail: { bucketIndex: i, valueMin, valueMax, relativeValue },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /** Bucket layout + counts, shared by render() and pointer hit-testing. */\n #computeGeometry() {\n const { values, range } = this.#series;\n const w = this._width;\n const h = this._height;\n const isHorizontal = this.orientation === `horizontal`;\n const padding = Math.min(4, (isHorizontal ? h : w) * 0.05);\n\n const dataMin = this.min ?? range.min;\n const dataMax = this.max ?? range.max;\n const dataSpan = dataMax - dataMin || 1;\n\n const bucketCount = Math.max(1, Math.floor(1 / this.resolution));\n\n const availableMain = (isHorizontal ? w : h) - padding * 2;\n const availableCross = (isHorizontal ? h : w) - padding * 2;\n\n const buckets: number[] = Array.from({ length: bucketCount }).fill(0) as number[];\n for (const v of values) {\n const normalized = (v - dataMin) / dataSpan;\n const index = Math.min(bucketCount - 1, Math.max(0, Math.floor(normalized * bucketCount)));\n buckets[index]++;\n }\n\n return { w, h, isHorizontal, padding, dataMin, dataMax, dataSpan, bucketCount, availableMain, availableCross, buckets };\n }\n\n /** Per-bucket rect geometry (SVG pixel coords) + value/count, shared by render() and pointer hit-testing. */\n #computeBars(): BarLayout[] {\n const { isHorizontal, padding, dataMin, dataSpan, bucketCount, availableMain, availableCross, buckets } = this.#computeGeometry();\n const bucketSize = availableMain / bucketCount;\n const gap = this.#getGapPx();\n const barLengthOverride = this.#getBarLengthOverride();\n const maxCount = Math.max(1, ...buckets);\n\n return buckets.map((count, i) => {\n const relativeValue = count / maxCount;\n const barLen = barLengthOverride !== null\n ? barLengthOverride * availableCross\n : relativeValue * availableCross;\n\n const valueMin = dataMin + (i / bucketCount) * dataSpan;\n const valueMax = dataMin + ((i + 1) / bucketCount) * dataSpan;\n\n if (isHorizontal) {\n const x = padding + i * bucketSize;\n const width = i === bucketCount - 1\n ? Math.max(0, padding + availableMain - x)\n : Math.max(0, bucketSize - gap);\n const y = padding + availableCross - barLen;\n return { count, valueMin, valueMax, relativeValue, x, y, width, height: barLen };\n } else {\n const y = padding + i * bucketSize;\n const height = i === bucketCount - 1\n ? Math.max(0, padding + availableMain - y)\n : Math.max(0, bucketSize - gap);\n return { count, valueMin, valueMax, relativeValue, x: padding, y, width: barLen, height };\n }\n });\n }\n\n /** Index of the bar rect under the pointer, or -1 if none (matches click hit-testing). */\n #bucketIndexFromPointer(clientX: number, clientY: number): number {\n const rect = this.getBoundingClientRect();\n const x = clientX - rect.left;\n const y = clientY - rect.top;\n return this.#computeBars().findIndex(b => x >= b.x && x <= b.x + b.width && y >= b.y && y <= b.y + b.height);\n }\n\n // --- Hover state (drives both the `inline` overlay-text and the `hover` bubble tooltip) ---\n\n #tooltipIndex: number | null = null;\n #tooltipVisible = false;\n #tooltipShowTimer: number | null = null;\n #tooltipHideTimer: number | null = null;\n #tooltipPosition: { mainClient: number; crossClient: number } | null = null;\n #valueRefreshTimer: number | null = null;\n\n #clearValueRefreshTimer(): void {\n if (this.#valueRefreshTimer !== null) {\n clearTimeout(this.#valueRefreshTimer);\n this.#valueRefreshTimer = null;\n }\n }\n\n /** While a bucket stays hovered, re-invoke `tick` at most every `valueUpdateInterval` ms, so a live-streaming bucket's displayed value stays fresh without updating on every single data point. */\n #scheduleValueRefresh(tick: () => void): void {\n this.#clearValueRefreshTimer();\n this.#valueRefreshTimer = window.setTimeout(() => {\n this.#valueRefreshTimer = null;\n tick();\n this.#scheduleValueRefresh(tick);\n }, this.valueUpdateInterval);\n }\n\n #clearBubbleTooltip(): void {\n if (this.#tooltipShowTimer !== null) {\n clearTimeout(this.#tooltipShowTimer);\n this.#tooltipShowTimer = null;\n }\n if (this.#tooltipHideTimer !== null) {\n clearTimeout(this.#tooltipHideTimer);\n this.#tooltipHideTimer = null;\n }\n if (this.#tooltipVisible) {\n this.#tooltipVisible = false;\n hideBubbleTooltip(this);\n }\n this.#tooltipIndex = null;\n this.#tooltipPosition = null;\n }\n\n #resetHoverState(): void {\n this.#clearValueRefreshTimer();\n this.#clearBubbleTooltip();\n this._hoveredIndex = null;\n this._inlineOverlayText = null;\n }\n\n /** Bubble position: centred on the bar along the bucket axis, offset from the cursor on the other axis. */\n #tooltipPositionFor(bar: BarLayout, clientX: number, clientY: number): { mainClient: number; crossClient: number } {\n const hostRect = this.getBoundingClientRect();\n const offset = 14;\n if (this.orientation === `horizontal`) {\n return { mainClient: hostRect.left + bar.x + bar.width / 2, crossClient: clientY - offset };\n }\n return { mainClient: hostRect.top + bar.y + bar.height / 2, crossClient: clientX + offset };\n }\n\n #refreshBubbleText(): void {\n if (this.#tooltipIndex === null || !this.#tooltipVisible || !this.#tooltipPosition)\n return;\n const bar = this.#computeBars()[this.#tooltipIndex];\n if (!bar)\n return;\n const text = this.valueFormat(bar.valueMin, bar.valueMax, bar.count);\n showBubbleTooltip(this, text, this.#tooltipPosition.mainClient, this.#tooltipPosition.crossClient, this.orientation);\n }\n\n /**\n * Drives the floating bubble tooltip. Only reacts to the hovered bucket *changing*\n * (not every pointermove), so the tooltip doesn't track minor cursor movement.\n * Debounces the initial show and the final hide; switching between buckets while\n * already visible updates instantly. While a bucket stays hovered, its displayed\n * value is refreshed at `valueUpdateInterval`.\n */\n #updateBubbleTooltip(index: number | null, clientX: number, clientY: number): void {\n if (index === this.#tooltipIndex)\n return;\n this.#tooltipIndex = index;\n this.#clearValueRefreshTimer();\n\n if (index === null) {\n if (this.#tooltipShowTimer !== null) {\n clearTimeout(this.#tooltipShowTimer);\n this.#tooltipShowTimer = null;\n }\n if (this.#tooltipVisible) {\n this.#tooltipHideTimer = window.setTimeout(() => {\n this.#tooltipHideTimer = null;\n this.#tooltipVisible = false;\n this.#tooltipPosition = null;\n hideBubbleTooltip(this);\n }, this.tooltipDelay);\n }\n return;\n }\n\n if (this.#tooltipHideTimer !== null) {\n clearTimeout(this.#tooltipHideTimer);\n this.#tooltipHideTimer = null;\n }\n\n const bar = this.#computeBars()[index];\n if (!bar)\n return;\n const text = this.valueFormat(bar.valueMin, bar.valueMax, bar.count);\n const position = this.#tooltipPositionFor(bar, clientX, clientY);\n this.#tooltipPosition = position;\n\n if (this.#tooltipVisible) {\n showBubbleTooltip(this, text, position.mainClient, position.crossClient, this.orientation);\n this.#scheduleValueRefresh(() => this.#refreshBubbleText());\n return;\n }\n\n if (this.#tooltipShowTimer !== null)\n clearTimeout(this.#tooltipShowTimer);\n this.#tooltipShowTimer = window.setTimeout(() => {\n this.#tooltipShowTimer = null;\n this.#tooltipVisible = true;\n showBubbleTooltip(this, text, position.mainClient, position.crossClient, this.orientation);\n this.#scheduleValueRefresh(() => this.#refreshBubbleText());\n }, this.tooltipDelay);\n }\n\n #formatBarAt(index: number): string | null {\n const bar = this.#computeBars()[index];\n return bar ? this.valueFormat(bar.valueMin, bar.valueMax, bar.count) : null;\n }\n\n /**\n * Drives the `inline` overlay-text: instant on hover change, throttled while stationary\n * over a live-changing bucket. `_inlineOverlayText` is cached reactive state rather than\n * being recomputed fresh in render() on every data change, since add()/set() trigger their\n * own re-render independent of the throttle timer.\n */\n #setInlineIndex(index: number | null): void {\n if (index === this._hoveredIndex)\n return;\n this._hoveredIndex = index;\n this.#clearValueRefreshTimer();\n if (index === null) {\n this._inlineOverlayText = null;\n return;\n }\n this._inlineOverlayText = this.#formatBarAt(index);\n this.#scheduleValueRefresh(() => {\n if (this._hoveredIndex !== null)\n this._inlineOverlayText = this.#formatBarAt(this._hoveredIndex);\n });\n }\n\n #onPointerMove = (e: PointerEvent): void => {\n if (this.valueTooltips === `none`)\n return;\n const index = this.#bucketIndexFromPointer(e.clientX, e.clientY);\n const bucketIndex = index >= 0 ? index : null;\n\n if (this.valueTooltips === `inline`)\n this.#setInlineIndex(bucketIndex);\n else\n this.#updateBubbleTooltip(bucketIndex, e.clientX, e.clientY);\n };\n\n #onPointerLeave = (): void => {\n if (this.valueTooltips === `none`)\n return;\n if (this.valueTooltips === `inline`)\n this.#setInlineIndex(null);\n else\n this.#updateBubbleTooltip(null, 0, 0);\n };\n\n override render() {\n const { w, h, padding } = this.#computeGeometry();\n const bars = this.#computeBars();\n\n const barsContent = bars.map((b, i) => svg`\n <rect class=\"bar\" x=${b.x} y=${b.y} width=${b.width} height=${b.height}\n style=\"--value: ${b.relativeValue}\"\n @click=${() => this.#emitClick(i, b.valueMin, b.valueMax, b.relativeValue)} />\n `);\n\n const textColor = `var(--plot-text, var(--surface-2-text, #fff))`;\n const overlayText = (this.valueTooltips === `inline` && this._inlineOverlayText !== null) ? this._inlineOverlayText : this.title;\n const titleContent = overlayText\n ? svg`<text x=${padding + 2} y=${padding + Math.min(10, h * 0.6)}\n class=\"overlay-text\" fill=${textColor}\n style=\"opacity: 0.6\">${overlayText}</text>`\n : svg``;\n\n return html`\n <svg width=${w} height=${h} viewBox=\"0 0 ${w} ${h}\"\n xmlns=\"http://www.w3.org/2000/svg\"\n @pointermove=${this.#onPointerMove}\n @pointerleave=${this.#onPointerLeave}>\n <rect width=${w} height=${h} fill=\"transparent\" />\n ${barsContent}\n ${titleContent}\n </svg>\n `;\n }\n\n static override styles = css`\n :host {\n display: inline-block;\n width: 100%;\n height: 100%;\n min-width: 20px;\n min-height: 20px;\n\n --plot-histogram-fill: currentColor;\n --plot-histogram-gap: 1px;\n --plot-histogram-border-radius: 0;\n --plot-histogram-bar-length: auto;\n }\n\n svg {\n display: block;\n cursor: crosshair;\n overflow: visible;\n }\n\n rect.bar {\n fill: var(--plot-histogram-fill, currentColor);\n rx: var(--plot-histogram-border-radius, 0);\n opacity: calc(0.15 + var(--value) * 0.85);\n }\n\n .overlay-text {\n font-family: var(--font-mono, ui-monospace, monospace);\n font-size: 9px;\n dominant-baseline: hanging;\n pointer-events: none;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-plot-histogram': PlotHistogram;\n }\n}\n\nexport interface PlotHistogram {\n addEventListener: (<K extends keyof PlotHistogramElementEventMap>(\n type: K,\n listener: (this: PlotHistogram, event: PlotHistogramElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","import type { PropertyValues, SVGTemplateResult } from 'lit';\nimport type { ColourMode, ColourResult } from './colour-map.js';\nimport { clamp } from '@ixfx/numbers';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { applyAgeModification, computeColour, parseColourScaleAttr, readBaseColour } from './colour-map.js';\nimport { PlotDataSeries } from './data.js';\nimport { adaptiveRadius, adaptiveStroke, hideTooltip, scaleValue, showTooltip } from './svg-utils.js';\n\nexport type SingleAxisDrawStyle\n = | `line-sharp`\n | `line-round`\n | `circles`\n | `squares`\n | `vbar`\n | `hbar`\n | `hist-bottom`\n | `hist-top`\n | `hist-middle`;\n\nexport type SingleAxisAgeStyle = `none` | `opacity` | `desaturation` | `size`;\n\ntype PlotPoint = { x: number; y: number; value: number; scaledValue: number; index: number; ageFraction: number };\n\n// --- Pure SVG fragment renderers ---\n// Lines use a single ColourResult (the last / most-recent point's colour).\n// Per-point styles use a ColourResult[] aligned with the points array.\n\nfunction buildLinePath(points: PlotPoint[]): string {\n if (points.length === 0)\n return ``;\n let d = `M ${points[0].x},${points[0].y}`;\n for (let i = 1; i < points.length; i++) {\n d += ` L ${points[i].x},${points[i].y}`;\n }\n return d;\n}\n\nfunction renderLine(points: PlotPoint[], cr: ColourResult, strokeW: number, round: boolean) {\n return svg`<path\n d=${buildLinePath(points)}\n fill=\"none\"\n stroke=${cr.fill}\n stroke-width=${strokeW}\n opacity=${cr.opacity}\n stroke-linecap=${round ? `round` : `butt`}\n stroke-linejoin=${round ? `round` : `miter`}\n />`;\n}\n\nfunction renderArea(points: PlotPoint[], cr: ColourResult, bottom: number, areaColor?: string): SVGTemplateResult {\n if (points.length < 2)\n return svg``;\n const lineD = buildLinePath(points);\n const fillColor = areaColor || cr.fill;\n const areaD = `${lineD} L ${points[points.length - 1].x},${bottom} L ${points[0].x},${bottom} Z`;\n return svg`<path d=${areaD} fill=${fillColor} opacity=${cr.opacity * 0.2} />`;\n}\n\nfunction renderCircles(points: PlotPoint[], crs: ColourResult[], radius: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const r = ageStyle === `size` ? radius * Math.max(0.2, p.ageFraction) : radius;\n return svg`<circle cx=${p.x} cy=${p.y} r=${r} fill=${crs[i].fill} opacity=${crs[i].opacity} />`;\n });\n}\n\nfunction renderSquares(points: PlotPoint[], crs: ColourResult[], size: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const s = ageStyle === `size` ? size * Math.max(0.2, p.ageFraction) : size;\n return svg`<rect\n x=${p.x - s / 2} y=${p.y - s / 2}\n width=${s} height=${s}\n fill=${crs[i].fill} opacity=${crs[i].opacity}\n />`;\n });\n}\n\nfunction renderVbars(points: PlotPoint[], crs: ColourResult[], strokeW: number, bottom: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const sw = ageStyle === `size` ? strokeW * Math.max(0.2, p.ageFraction) : strokeW;\n return svg`<line\n x1=${p.x} y1=${bottom} x2=${p.x} y2=${p.y}\n stroke=${crs[i].fill} stroke-width=${sw} opacity=${crs[i].opacity}\n />`;\n });\n}\n\nfunction renderHbars(points: PlotPoint[], crs: ColourResult[], strokeW: number, tickLen: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const tl = ageStyle === `size` ? tickLen * Math.max(0.2, p.ageFraction) : tickLen;\n return svg`<line\n x1=${p.x - tl / 2} y1=${p.y} x2=${p.x + tl / 2} y2=${p.y}\n stroke=${crs[i].fill} stroke-width=${strokeW} opacity=${crs[i].opacity}\n />`;\n });\n}\n\nfunction renderHistBottom(points: PlotPoint[], crs: ColourResult[], barW: number, bottom: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const w = ageStyle === `size` ? barW * Math.max(0.2, p.ageFraction) : barW;\n return svg`<rect\n x=${p.x - w / 2} y=${p.y}\n width=${w} height=${Math.max(1, bottom - p.y)}\n fill=${crs[i].fill} opacity=${crs[i].opacity}\n />`;\n });\n}\n\nfunction renderHistTop(points: PlotPoint[], crs: ColourResult[], barW: number, top: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const w = ageStyle === `size` ? barW * Math.max(0.2, p.ageFraction) : barW;\n return svg`<rect\n x=${p.x - w / 2} y=${top}\n width=${w} height=${Math.max(1, p.y - top)}\n fill=${crs[i].fill} opacity=${crs[i].opacity}\n />`;\n });\n}\n\nfunction renderHistMiddle(points: PlotPoint[], crs: ColourResult[], barW: number, mid: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const w = ageStyle === `size` ? barW * Math.max(0.2, p.ageFraction) : barW;\n return svg`<rect\n x=${p.x - w / 2} y=${Math.min(p.y, mid)}\n width=${w} height=${Math.max(1, Math.abs(p.y - mid))}\n fill=${crs[i].fill} opacity=${crs[i].opacity}\n />`;\n });\n}\n\n// --- Component ---\n\n/**\n * PlotSingleAxis\n *\n * Adding data:\n * - add(value: number): adds a single value to the end of the data series.\n * - set(values: number[]): replaces the entire data series at once.\n */\n@customElement(`ixfx-plot-single-axis`)\n// eslint-disable-next-line ts/no-unsafe-declaration-merging\nexport class PlotSingleAxis extends LitElement {\n @property({ attribute: `draw-style` })\n drawStyle: SingleAxisDrawStyle = `line-sharp`;\n\n @property({ attribute: `age-style` })\n ageStyle: SingleAxisAgeStyle = `none`;\n\n @property() title = ``;\n\n @property({ type: Boolean }) precise = false;\n @property({ type: Boolean }) tooltips = true;\n @property({ type: Number }) capacity = 100;\n\n @property({ type: Number }) rangeMin = Number.NaN;\n @property({ type: Number }) rangeMax = Number.NaN;\n\n @property({ type: Boolean, attribute: `persistent-scale` })\n persistentScale = true;\n\n @property({ type: Boolean, reflect: true }) paused = false;\n @property({ type: Boolean, attribute: `click-pauses` }) clickPauses = false;\n\n @property({ type: Boolean, attribute: `shaded` })\n shaded = false;\n\n @property({ attribute: `area-color` })\n areaColor = ``;\n\n // --- Colour mapping ---\n @property({ attribute: `color-mode` }) colorMode: ColourMode = `fixed`;\n @property({ attribute: `color-easing` }) colorEasing = ``;\n @property({ attribute: `color-scale` }) colorScale = ``;\n /** Custom value-mapping function (0..1 → 0..1). Ignored when color-easing is set. */\n colorValueMap: ((v: number) => number) | null = null;\n\n @state() private _width = 100;\n @state() private _height = 40;\n\n #series = new PlotDataSeries();\n #hasProgrammaticData = false;\n #lastClientX: number | null = null;\n #lastClientY: number | null = null;\n\n #parseDeclarativeData(text: string): number[] {\n if (!text)\n return [];\n const tokens = text.trim().split(/[,\\s;]+/);\n return tokens\n .map(t => Number.parseFloat(t))\n .filter(n => !Number.isNaN(n));\n }\n\n /** Override to customize tooltip label. */\n valueFormat: (v: number | undefined) => string = v => v ? v.toFixed(2) : ``;\n\n /**\n * Adds a value to the data series.\n *\n * Pass `withholdRedraw = true` to prevent automatic redraw after adding the value. In this case, call `redraw()` manually after adding all values to update the plot.\n *\n * Use {@link set} to replace the entire data series at once.\n * @param valueOrValues Single value, or several values\n * @param withholdRedraw If _false_ (default) plot is automatically redrawn\n */\n add(valueOrValues: number | number[], withholdRedraw = false): void {\n this.#hasProgrammaticData = true;\n this.#series.add(valueOrValues);\n if (this.paused)\n return;\n if (withholdRedraw)\n return;\n this.redraw();\n }\n\n /**\n * Redraws the plot.\n * Normally not needed, unless add() is called with withholdRedraw = true, or styleSeries() is used to update series styles.\n */\n redraw() {\n this.requestUpdate();\n this.#updateTooltipAtLastPos();\n }\n\n /**\n * Sets the entire data for a series at once, replacing contents.\n *\n * Use add() to add values one by one.\n *\n * Pass `withholdRedraw = true` to prevent automatic redraw after setting the values. In this case, call `redraw()` manually after setting the values to update the plot.\n * @param values Values\n * @param withholdRedraw If _false_ (default) plot is automatically redrawn\n */\n set(values: number[], withholdRedraw = false): void {\n this.#hasProgrammaticData = true;\n this.#series.set(values);\n if (this.paused)\n return;\n if (withholdRedraw)\n return;\n this.redraw();\n }\n\n /**\n * Clears all data and redraws\n */\n clear(): boolean {\n const result = this.#series.clear();\n this.requestUpdate();\n return result;\n }\n\n protected override firstUpdated(_changed: PropertyValues): void {\n this._width = this.clientWidth || 100;\n this._height = this.clientHeight || 40;\n const ro = new ResizeObserver((entries) => {\n const e = entries[0];\n this._width = e.contentRect.width;\n this._height = e.contentRect.height;\n });\n ro.observe(this);\n\n if (!this.#hasProgrammaticData) {\n const data = this.#parseDeclarativeData(this.textContent ?? ``);\n if (data.length > 0) {\n this.#series.set(data);\n }\n }\n }\n\n protected override updated(changed: PropertyValues): void {\n if (changed.has(`capacity`) || changed.has(`persistentScale`) || changed.has(`rangeMin`) || changed.has(`rangeMax`)) {\n const old = [...this.#series.values];\n const fixedRange = (!Number.isNaN(this.rangeMin) && !Number.isNaN(this.rangeMax)) ? { min: this.rangeMin, max: this.rangeMax } : null;\n this.#series = new PlotDataSeries({\n capacityLimit: this.capacity,\n persistentScaling: this.persistentScale,\n fixedRange,\n });\n if (old.length > 0)\n this.#series.set(old);\n }\n }\n\n #getIndexFromX(clientX: number, rect: DOMRect): number {\n const n = this.#series.values.length;\n if (n === 0)\n return -1;\n const x = clientX - rect.left;\n if (x < 0 || x > rect.width)\n return -1;\n const padding = rect.height < 20 ? 0 : Math.min(4, rect.height * 0.05);\n const plotW = rect.width - padding * 2;\n const index = Math.floor((x - padding) / (plotW / n));\n return index >= 0 && index < n ? index : -1;\n }\n\n #updateTooltip(clientX: number, clientY: number): void {\n if (!this.tooltips)\n return;\n const rect = this.getBoundingClientRect();\n const index = this.#getIndexFromX(clientX, rect);\n if (index < 0) {\n hideTooltip(this); return;\n }\n showTooltip(this, clientX, clientY, this.valueFormat(this.#series.values[index]));\n }\n\n #updateTooltipAtLastPos(): void {\n if (this.#lastClientX === null || this.#lastClientY === null)\n return;\n this.#updateTooltip(this.#lastClientX, this.#lastClientY);\n }\n\n #onPointerMove = (e: PointerEvent): void => {\n this.#lastClientX = e.clientX;\n this.#lastClientY = e.clientY;\n this.#updateTooltip(e.clientX, e.clientY);\n const index = this.#getIndexFromX(e.clientX, this.getBoundingClientRect());\n this.dispatchEvent(new CustomEvent(`plot-pointer-move`, {\n detail: { clientX: e.clientX, clientY: e.clientY, index },\n bubbles: true,\n composed: true,\n }));\n };\n\n #onPointerLeave = (): void => {\n this.#lastClientX = null;\n this.#lastClientY = null;\n hideTooltip(this);\n this.dispatchEvent(new CustomEvent(`plot-pointer-leave`, {\n bubbles: true,\n composed: true,\n }));\n };\n\n #onClick = (e: MouseEvent): void => {\n if (this.clickPauses)\n this.paused = !this.paused;\n const index = this.#getIndexFromX(e.clientX, this.getBoundingClientRect());\n if (index < 0)\n return;\n this.dispatchEvent(new CustomEvent(`plot-datapoint-click`, {\n detail: { value: this.#series.values[index], index },\n bubbles: true,\n composed: true,\n }));\n };\n\n #computePoints(values: number[], min: number, max: number, padding: number, plotW: number, plotH: number): PlotPoint[] {\n const n = values.length;\n const widthPerPoint = n > 0 ? plotW / n : plotW;\n const scaleX = (i: number) => padding + (i + 0.5) * widthPerPoint;\n return values.map((value, index) => {\n const sv = clamp(scaleValue(value, min, max));\n const ageFraction = n > 1 ? index / (n - 1) : 1;\n return { x: scaleX(index), y: padding + (1 - sv) * plotH, value, scaledValue: sv, index, ageFraction };\n });\n }\n\n get series() {\n return this.#series;\n }\n\n /**\n * Get all values in the data series as a readonly array.\n */\n get values(): readonly number[] {\n return this.#series.values;\n }\n\n /**\n * Get length of data series\n */\n get dataLength(): number {\n return this.#series.values.length;\n }\n\n /**\n * Get value at specific index of data series\n * @param index\n */\n getValueAt(index: number): number | undefined {\n return this.#series.values[index];\n }\n\n /**\n * Get value index based on client X position\n * @param clientX\n */\n getIndexFromClientX(clientX: number): number {\n return this.#getIndexFromX(clientX, this.getBoundingClientRect());\n }\n\n #renderByStyle(\n points: PlotPoint[],\n crs: ColourResult[],\n strokeW: number,\n radius: number,\n barW: number,\n bottom: number,\n top: number,\n mid: number,\n ): SVGTemplateResult[] {\n const lineCr = crs.at(-1) ?? { fill: `currentColor`, opacity: 1 };\n const isLine = this.drawStyle === `line-sharp` || this.drawStyle === `line-round`;\n const needsArea = isLine && this.shaded;\n const areaColor = this.areaColor || undefined;\n\n if (needsArea) {\n const area = renderArea(points, lineCr, bottom, areaColor);\n const line = this.drawStyle === `line-sharp`\n ? renderLine(points, lineCr, strokeW, false)\n : renderLine(points, lineCr, strokeW, true);\n return [area, line];\n }\n\n switch (this.drawStyle) {\n case `line-sharp`: return [renderLine(points, lineCr, strokeW, false)];\n case `line-round`: return [renderLine(points, lineCr, strokeW, true)];\n case `circles`: return renderCircles(points, crs, radius, this.ageStyle);\n case `squares`: return renderSquares(points, crs, radius * 2, this.ageStyle);\n case `vbar`: return renderVbars(points, crs, strokeW, bottom, this.ageStyle);\n case `hbar`: return renderHbars(points, crs, strokeW, barW, this.ageStyle);\n case `hist-bottom`: return renderHistBottom(points, crs, barW, bottom, this.ageStyle);\n case `hist-top`: return renderHistTop(points, crs, barW, top, this.ageStyle);\n case `hist-middle`: return renderHistMiddle(points, crs, barW, mid, this.ageStyle);\n default: return [];\n }\n }\n\n override render() {\n const { values, range } = this.#series;\n const w = this._width;\n const h = this._height;\n const padding = h < 20 ? 0 : Math.min(4, h * 0.05);\n const plotW = Math.max(1, w - padding * 2);\n const plotH = Math.max(1, h - padding * 2);\n const bottom = padding + plotH;\n const top = padding;\n const mid = padding + plotH / 2;\n\n const strokeW = adaptiveStroke(w, h);\n const radius = adaptiveRadius(w, h, values.length);\n const barW = values.length > 0\n ? Math.max(1, (plotW / values.length) * 0.85)\n : plotW;\n\n const textColor = `var(--plot-text, var(--surface-2-text, #fff))`;\n\n const points = values.length > 0\n ? this.#computePoints(values, range.min, range.max, padding, plotW, plotH)\n : [];\n\n // Colour mapping\n const baseColour = points.length > 0 ? readBaseColour(this) : ``;\n const colourConfig = {\n mode: this.colorMode,\n palette: parseColourScaleAttr(this.colorScale),\n easingName: this.colorEasing,\n valueMap: this.colorValueMap,\n };\n const isDiscrete = this.drawStyle !== `line-sharp` && this.drawStyle !== `line-round`;\n const crs: ColourResult[] = points.map((p) => {\n const base = computeColour(p.scaledValue, baseColour, colourConfig);\n return isDiscrete ? applyAgeModification(base, p.ageFraction, this.ageStyle) : base;\n });\n\n const dataContent = points.length > 0\n ? this.#renderByStyle(points, crs, strokeW, radius, barW, bottom, top, mid)\n : [];\n\n const titleContent = this.title\n ? svg`<text\n x=${padding + 2} y=${top + Math.min(10, h * 0.6)}\n class=\"overlay-text\"\n fill=${textColor}\n style=\"opacity: 0.6\"\n >${this.title}</text>`\n : svg``;\n\n const latestValue = values.length > 0 ? values.at(-1) : null;\n const preciseContent = this.precise && latestValue !== null\n ? svg`<text\n x=${w - padding - 2} y=${top + Math.min(10, h * 0.6)}\n class=\"overlay-text\"\n text-anchor=\"end\"\n fill=${textColor}\n style=\"opacity: 0.8\"\n >${this.valueFormat(latestValue)}</text>`\n : svg``;\n\n return html`\n <svg\n width=${w} height=${h}\n viewBox=\"0 0 ${w} ${h}\"\n xmlns=\"http://www.w3.org/2000/svg\"\n @pointermove=${this.#onPointerMove}\n @pointerleave=${this.#onPointerLeave}\n @click=${this.#onClick}\n >\n <rect width=${w} height=${h} fill=\"transparent\" />\n ${dataContent.map(c => c)}\n ${titleContent}\n ${preciseContent}\n </svg>\n `;\n }\n\n static override styles = css`\n :host {\n display: inline-block;\n width: 100%;\n height: 100%;\n min-width: 20px;\n min-height: 4px;\n }\n\n svg {\n display: block;\n cursor: crosshair;\n overflow: visible;\n }\n\n .overlay-text {\n font-family: var(--font-mono, ui-monospace, monospace);\n font-size: 9px;\n dominant-baseline: hanging;\n pointer-events: none;\n }\n `;\n}\n\nexport type PlotSingleAxisPointerMoveDetail = {\n readonly clientX: number;\n readonly clientY: number;\n readonly index: number;\n};\n\nexport type PlotSingleAxisPointerMoveEvent = CustomEvent<PlotSingleAxisPointerMoveDetail>;\n\nexport interface PlotSingleAxisElementEventMap {\n 'plot-pointer-move': PlotSingleAxisPointerMoveEvent;\n 'plot-pointer-leave': Event;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-plot-single-axis': PlotSingleAxis;\n }\n}\n\n// eslint-disable-next-line ts/no-unsafe-declaration-merging\nexport interface PlotSingleAxis {\n addEventListener: {\n <K extends keyof PlotSingleAxisElementEventMap>(\n type: K,\n listener: (this: PlotSingleAxis, event: PlotSingleAxisElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n (\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n };\n}\n","import type { PropertyValues } from 'lit';\nimport type { ColourMode, ColourResult } from './colour-map.js';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { applyAgeModification, computeColour, parseColourScaleAttr, readBaseColour } from './colour-map.js';\nimport { PlotDataSeries } from './data.js';\nimport { adaptiveRadius, hideTooltip, scaleValue, showTooltip } from './svg-utils.js';\n\nexport type XyDrawStyle = `circles` | `squares`;\nexport type XyAgeStyle = `none` | `opacity` | `desaturation` | `size`;\n\ntype XyPoint = { x: number; y: number; xVal: number; yVal: number; index: number; ageFraction: number };\n\n// --- Component ---\n\n@customElement(`ixfx-plot-xy-axis`)\nexport class PlotXyAxis extends LitElement {\n @property({ attribute: `draw-style` })\n drawStyle: XyDrawStyle = `circles`;\n\n @property({ attribute: `age-style` })\n ageStyle: XyAgeStyle = `none`;\n\n @property() title = ``;\n @property({ type: Boolean }) precise = false;\n @property({ type: Boolean }) tooltips = true;\n @property({ type: Number }) capacity = 100;\n\n @property({ type: Boolean, attribute: `persistent-scale` })\n persistentScale = true;\n\n @property({ type: Boolean, reflect: true }) paused = false;\n @property({ type: Boolean, attribute: `click-pauses` }) clickPauses = false;\n\n // --- Colour mapping ---\n @property({ attribute: `color-mode` }) colorMode: ColourMode = `fixed`;\n @property({ attribute: `color-easing` }) colorEasing = ``;\n @property({ attribute: `color-scale` }) colorScale = ``;\n /**\n * Custom value-mapping fn (0..1 → 0..1). For xy-axis the input is the point's ageFraction\n * (0 = oldest, 1 = newest). Ignored when color-easing is set.\n */\n colorValueMap: ((v: number) => number) | null = null;\n\n @state() private _width = 100;\n @state() private _height = 100;\n\n #xSeries = new PlotDataSeries({ capacityLimit: 100, persistentScaling: true });\n #ySeries = new PlotDataSeries({ capacityLimit: 100, persistentScaling: true });\n\n /** Override to customize tooltip label. */\n valueFormat: (x: number, y: number) => string = (x, y) => `${x.toFixed(2)}, ${y.toFixed(2)}`;\n\n add(x: number, y: number): void {\n this.#xSeries.add(x);\n this.#ySeries.add(y);\n if (this.paused)\n return;\n this.requestUpdate();\n this.#updateTooltipAtLastPos();\n }\n\n setXY(xs: number[], ys: number[]): void {\n this.#xSeries.set(xs);\n this.#ySeries.set(ys);\n if (this.paused)\n return;\n this.requestUpdate();\n this.#updateTooltipAtLastPos();\n }\n\n clear(): void {\n this.#xSeries.clear();\n this.#ySeries.clear();\n this.requestUpdate();\n }\n\n protected override firstUpdated(_changed: PropertyValues): void {\n this._width = this.clientWidth || 100;\n this._height = this.clientHeight || 100;\n const ro = new ResizeObserver((entries) => {\n const e = entries[0];\n this._width = e.contentRect.width;\n this._height = e.contentRect.height;\n });\n ro.observe(this);\n }\n\n protected override updated(changed: PropertyValues): void {\n if (changed.has(`capacity`) || changed.has(`persistentScale`)) {\n const opts = { capacityLimit: this.capacity, persistentScaling: this.persistentScale };\n const oldX = [...this.#xSeries.values];\n const oldY = [...this.#ySeries.values];\n this.#xSeries = new PlotDataSeries(opts);\n this.#ySeries = new PlotDataSeries(opts);\n if (oldX.length > 0) {\n this.#xSeries.set(oldX); this.#ySeries.set(oldY);\n }\n }\n }\n\n #computePoints(padding: number, plotW: number, plotH: number): XyPoint[] {\n const xs = this.#xSeries.values;\n const ys = this.#ySeries.values;\n const n = Math.min(xs.length, ys.length);\n if (n === 0)\n return [];\n\n const { min: xMin, max: xMax } = this.#xSeries.range;\n const { min: yMin, max: yMax } = this.#ySeries.range;\n\n return Array.from({ length: n }, (_, i) => ({\n x: padding + scaleValue(xs[i], xMin, xMax) * plotW,\n y: padding + (1 - scaleValue(ys[i], yMin, yMax)) * plotH,\n xVal: xs[i],\n yVal: ys[i],\n index: i,\n ageFraction: n > 1 ? i / (n - 1) : 1,\n }));\n }\n\n /** Compute the final ColourResult for each xy point: base colour → age modification. */\n #computeColours(points: XyPoint[], baseColour: string): ColourResult[] {\n const config = {\n mode: this.colorMode,\n palette: parseColourScaleAttr(this.colorScale),\n easingName: this.colorEasing,\n valueMap: this.colorValueMap,\n };\n return points.map((p) => {\n const base = computeColour(p.ageFraction, baseColour, config);\n return applyAgeModification(base, p.ageFraction, this.ageStyle);\n });\n }\n\n #findNearestPoint(clientX: number, clientY: number, points: XyPoint[], rect: DOMRect): XyPoint | null {\n const x = clientX - rect.left;\n const y = clientY - rect.top;\n let best: XyPoint | null = null;\n let bestDist = Infinity;\n for (const p of points) {\n const dx = p.x - x;\n const dy = p.y - y;\n const d = dx * dx + dy * dy;\n if (d < bestDist) {\n bestDist = d; best = p;\n }\n }\n return best && Math.sqrt(bestDist) < 30 ? best : null;\n }\n\n #lastPoints: XyPoint[] = [];\n #lastClientX: number | null = null;\n #lastClientY: number | null = null;\n\n #updateTooltip(clientX: number, clientY: number): void {\n if (!this.tooltips)\n return;\n const rect = this.getBoundingClientRect();\n const nearest = this.#findNearestPoint(clientX, clientY, this.#lastPoints, rect);\n if (!nearest) {\n hideTooltip(this); return;\n }\n showTooltip(this, clientX, clientY, this.valueFormat(nearest.xVal, nearest.yVal));\n }\n\n #updateTooltipAtLastPos(): void {\n if (this.#lastClientX === null || this.#lastClientY === null)\n return;\n this.#updateTooltip(this.#lastClientX, this.#lastClientY);\n }\n\n #onPointerMove = (e: PointerEvent): void => {\n this.#lastClientX = e.clientX;\n this.#lastClientY = e.clientY;\n this.#updateTooltip(e.clientX, e.clientY);\n };\n\n #onPointerLeave = (): void => {\n this.#lastClientX = null;\n this.#lastClientY = null;\n hideTooltip(this);\n };\n\n #onClick = (e: MouseEvent): void => {\n if (this.clickPauses)\n this.paused = !this.paused;\n const rect = (e.currentTarget as SVGElement).getBoundingClientRect();\n const nearest = this.#findNearestPoint(e.clientX, e.clientY, this.#lastPoints, rect);\n if (!nearest)\n return;\n this.dispatchEvent(new CustomEvent(`plot-datapoint-click`, {\n detail: { x: nearest.xVal, y: nearest.yVal, index: nearest.index },\n bubbles: true,\n composed: true,\n }));\n };\n\n override render() {\n const w = this._width;\n const h = this._height;\n const padding = Math.min(6, Math.min(w, h) * 0.06);\n const plotW = Math.max(1, w - padding * 2);\n const plotH = Math.max(1, h - padding * 2);\n\n const points = this.#computePoints(padding, plotW, plotH);\n this.#lastPoints = points;\n\n const baseColour = points.length > 0 ? readBaseColour(this) : ``;\n const colours = this.#computeColours(points, baseColour);\n\n const radius = adaptiveRadius(w, h, points.length);\n const textColor = `var(--plot-text, var(--surface-2-text, #fff))`;\n\n const dataContent = points.map((p, i) => {\n const cr = colours[i];\n const sizeFactor = this.ageStyle === `size` ? Math.max(0.2, p.ageFraction) : 1;\n if (this.drawStyle === `circles`) {\n const r = radius * sizeFactor;\n return svg`<circle cx=${p.x} cy=${p.y} r=${r} fill=${cr.fill} opacity=${cr.opacity} />`;\n }\n const s = radius * 2 * sizeFactor;\n return svg`<rect x=${p.x - s / 2} y=${p.y - s / 2} width=${s} height=${s} fill=${cr.fill} opacity=${cr.opacity} />`;\n });\n\n const titleContent = this.title\n ? svg`<text\n x=${padding + 2} y=${padding + 2}\n class=\"overlay-text\"\n fill=${textColor}\n style=\"opacity: 0.6\"\n >${this.title}</text>`\n : svg``;\n\n const n = Math.min(this.#xSeries.values.length, this.#ySeries.values.length);\n const latestX = n > 0 ? this.#xSeries.values[n - 1] : null;\n const latestY = n > 0 ? this.#ySeries.values[n - 1] : null;\n const preciseContent = this.precise && latestX !== null && latestY !== null\n ? svg`<text\n x=${w - padding - 2} y=${padding + 2}\n class=\"overlay-text\"\n text-anchor=\"end\"\n fill=${textColor}\n style=\"opacity: 0.8\"\n >${this.valueFormat(latestX, latestY)}</text>`\n : svg``;\n\n return html`\n <svg\n width=${w} height=${h}\n viewBox=\"0 0 ${w} ${h}\"\n xmlns=\"http://www.w3.org/2000/svg\"\n @pointermove=${this.#onPointerMove}\n @pointerleave=${this.#onPointerLeave}\n @click=${this.#onClick}\n >\n <rect width=${w} height=${h} fill=\"transparent\" />\n ${dataContent}\n ${titleContent}\n ${preciseContent}\n </svg>\n `;\n }\n\n static override styles = css`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n min-width: 40px;\n min-height: 40px;\n }\n\n svg {\n display: block;\n cursor: crosshair;\n }\n\n .overlay-text {\n font-family: var(--font-mono, ui-monospace, monospace);\n font-size: 9px;\n dominant-baseline: hanging;\n pointer-events: none;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-plot-xy-axis': PlotXyAxis;\n }\n}\n"],"mappings":"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"}
package/dist/xy-pad.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as WheelNudgeConsumerType, t as WheelDirection } from "./wheel-nudge-DgMTRYlh.js";
1
+ import { n as WheelNudgeConsumerType, t as WheelDirection } from "./wheel-nudge-DGrNzWuE.js";
2
2
  import { LitElement, PropertyValues, html } from "lit";
3
3
  //#region src/xy-pad/xy-pad.d.ts
4
4
  declare const XyPad_base: (new (...args: any[]) => WheelNudgeConsumerType<LitElement>) & typeof LitElement;
package/dist/xy-pad.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as themeFallbacks } from "./fallbacks-DPgPEqo8.js";
1
+ import { t as themeFallbacks } from "./fallbacks-DEE1nCTt.js";
2
2
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
3
  import { t as prominenceStyles } from "./prominence-DlFShic3.js";
4
4
  import { t as resolveAxisStep } from "./keyboard-B5xD7Fz-.js";
@@ -11,6 +11,7 @@ This directory contains documentation for each component and some architectural
11
11
  - [colour-picker](./colour-picker.md)
12
12
  - [crumbs](./crumbs.md)
13
13
  - [data-display](./data-display.md)
14
+ - [data-grid](./data-grid.md)
14
15
  - [editable-label](./editable-label.md)
15
16
  - [form](./form.md)
16
17
  - [grouped-item-lister](./grouped-item-lister.md)
@@ -29,8 +30,8 @@ This directory contains documentation for each component and some architectural
29
30
  - [radial-input](./radial-input.md)
30
31
  - [range](./range.md)
31
32
  - [range-input](./range-input.md)
33
+ - [rating](./rating.md)
32
34
  - [select-horiz](./select-horiz.md)
33
- - [selecthorizontal](./selecthorizontal.md)
34
35
  - [slider-input](./slider-input.md)
35
36
  - [snackbar](./snackbar.md)
36
37
  - [snap-container](./snap-container.md)
@@ -47,4 +48,4 @@ This directory contains documentation for each component and some architectural
47
48
  ## Architectural Overviews
48
49
 
49
50
  - [user-catalog.md](user-catalog.md)
50
- - [user-theming.md](user-theming.md)
51
+ - [user-theming.md](user-theming.md)
@@ -41,9 +41,15 @@ el.addEventListener('ac-token-change', e => {
41
41
  | `strict` | `boolean` | `false` | When true, only suggestions from the popup can be committed. Free-form typed text is ignored. |
42
42
  | `cacheSize` | `number` | `20` | LRU cache size for provider results. |
43
43
  | `debounceMs` | `number` | `150` | Debounce delay in ms before invoking the provider after a keystroke.|
44
- | `tokens` (property) | `readonly AcTokenItem[]` | `[]` | Get or set the full token list programmatically. |
44
+ | `tokens` (property) | `readonly AcTokenItem[]` | `[]` | Get or set the full token list programmatically. Setting it dispatches `ac-token-change`, same as a user edit — beware feedback loops if a parent updates this binding from its own `ac-token-change` handler. Use `setTokens()` to avoid that. |
45
45
  | `value` (property, read-only) | `string` | — | All committed token labels joined with `, `. |
46
46
 
47
+ ### Methods
48
+
49
+ | Method | Description |
50
+ |--------|-------------|
51
+ | `setTokens(tokens)` | Set the token list programmatically without dispatching `ac-token-change`. Prefer this over the `tokens` property for initialisation or any other update driven by the component's own state. |
52
+
47
53
  ---
48
54
 
49
55
  ### Events