@ixfx/components 0.2.6 → 0.3.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 (140) hide show
  1. package/bundle/index.d.ts +213 -117
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +1356 -658
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.js +3 -3
  6. package/dist/ac-text.js.map +1 -1
  7. package/dist/{button-B9ztaKyl.js → button-DMt5XWUK.js} +4 -4
  8. package/dist/{button-B9ztaKyl.js.map → button-DMt5XWUK.js.map} +1 -1
  9. package/dist/button.js +1 -1
  10. package/dist/checkbox.d.ts +2 -3
  11. package/dist/checkbox.d.ts.map +1 -1
  12. package/dist/checkbox.js +1 -1
  13. package/dist/checkbox.js.map +1 -1
  14. package/dist/{colour-C3MQIjFJ-BJV-QC-3.js → colour-C3MQIjFJ-BLXg8W3U.js} +2 -2
  15. package/dist/{colour-C3MQIjFJ-BJV-QC-3.js.map → colour-C3MQIjFJ-BLXg8W3U.js.map} +1 -1
  16. package/dist/{colour-picker-BNqDz4wK.js → colour-picker-K6zu82lm.js} +5 -5
  17. package/dist/{colour-picker-BNqDz4wK.js.map → colour-picker-K6zu82lm.js.map} +1 -1
  18. package/dist/colour-picker.js +1 -1
  19. package/dist/crumbs.d.ts +2 -3
  20. package/dist/crumbs.d.ts.map +1 -1
  21. package/dist/crumbs.js +10 -10
  22. package/dist/crumbs.js.map +1 -1
  23. package/dist/data-display.js +3 -3
  24. package/dist/{decorate-O4m1U4l3.js → decorate-D7rC1gLP.js} +10 -8
  25. package/dist/decorate-D7rC1gLP.js.map +1 -0
  26. package/dist/{defaults-FEZaGiYZ.js → defaults-C7elhuyJ.js} +2 -2
  27. package/dist/{defaults-FEZaGiYZ.js.map → defaults-C7elhuyJ.js.map} +1 -1
  28. package/dist/{dist-By5URG0Y.js → dist-BX0OVIm7.js} +2 -2
  29. package/dist/{dist-By5URG0Y.js.map → dist-BX0OVIm7.js.map} +1 -1
  30. package/dist/{dist-D7kJgnSE.js → dist-TAGYwaju.js} +1 -1
  31. package/dist/{dist-D7kJgnSE.js.map → dist-TAGYwaju.js.map} +1 -1
  32. package/dist/editable-label.d.ts +6 -1
  33. package/dist/editable-label.d.ts.map +1 -1
  34. package/dist/editable-label.js +49 -2
  35. package/dist/editable-label.js.map +1 -1
  36. package/dist/{hex-editor-gH3mteMr.js → hex-editor-CsN_ySkH.js} +85 -85
  37. package/dist/hex-editor-CsN_ySkH.js.map +1 -0
  38. package/dist/{hex-editor-2_s0Ua5t.d.ts → hex-editor-DlfoA65y.d.ts} +5 -5
  39. package/dist/{hex-editor-2_s0Ua5t.d.ts.map → hex-editor-DlfoA65y.d.ts.map} +1 -1
  40. package/dist/hex.d.ts +1 -1
  41. package/dist/hex.js +1 -1
  42. package/dist/{highlight-CAjwQ4GE.js → highlight-TPbSHruI.js} +3 -3
  43. package/dist/highlight-TPbSHruI.js.map +1 -0
  44. package/dist/{icon-CYACf6o8.js → icon-9NWTXtE1.js} +4 -5
  45. package/dist/icon-9NWTXtE1.js.map +1 -0
  46. package/dist/icon-CeTDJhC7.d.ts.map +1 -1
  47. package/dist/icons.js +3 -3
  48. package/dist/{incr-search-BZawvrfl.js → incr-search-DSKKsk6w.js} +12 -10
  49. package/dist/incr-search-DSKKsk6w.js.map +1 -0
  50. package/dist/incr-search.d.ts +1 -1
  51. package/dist/incr-search.js +2 -2
  52. package/dist/{index-CwGkb9s1.d.ts → index--hrxPBkQ.d.ts} +69 -69
  53. package/dist/index--hrxPBkQ.d.ts.map +1 -0
  54. package/dist/{index-kY5gxbkI.d.ts → index-DSlPeWLK.d.ts} +15 -15
  55. package/dist/{index-kY5gxbkI.d.ts.map → index-DSlPeWLK.d.ts.map} +1 -1
  56. package/dist/{index-V2cJorlA.d.ts → index-hXFn14tM.d.ts} +4 -4
  57. package/dist/index-hXFn14tM.d.ts.map +1 -0
  58. package/dist/index.d.ts +109 -13
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +666 -24
  61. package/dist/index.js.map +1 -1
  62. package/dist/keyboard-De_vOHLg.js.map +1 -1
  63. package/dist/{labelled-input-base-BvgH7ldm.js → labelled-input-base-CqPL5rKm.js} +2 -2
  64. package/dist/labelled-input-base-CqPL5rKm.js.map +1 -0
  65. package/dist/labelled-radial-input.js +3 -3
  66. package/dist/labelled-radial-input.js.map +1 -1
  67. package/dist/labelled-range-input.js +2 -2
  68. package/dist/led.js +1 -1
  69. package/dist/{menu-C3eANB5M.js → menu-DJJuCm-5.js} +48 -48
  70. package/dist/menu-DJJuCm-5.js.map +1 -0
  71. package/dist/{menu-item-6IU5weHi.js → menu-item-CKRfP0pN.js} +10 -10
  72. package/dist/menu-item-CKRfP0pN.js.map +1 -0
  73. package/dist/menu.d.ts +1 -1
  74. package/dist/menu.js +2 -2
  75. package/dist/miller.d.ts +5 -7
  76. package/dist/miller.d.ts.map +1 -1
  77. package/dist/miller.js +14 -14
  78. package/dist/miller.js.map +1 -1
  79. package/dist/narrowed-text.d.ts.map +1 -1
  80. package/dist/narrowed-text.js +4 -4
  81. package/dist/narrowed-text.js.map +1 -1
  82. package/dist/panel.js +2 -2
  83. package/dist/panel.js.map +1 -1
  84. package/dist/plots.js +1 -1
  85. package/dist/polar-pad.d.ts.map +1 -1
  86. package/dist/polar-pad.js +1 -1
  87. package/dist/polar-pad.js.map +1 -1
  88. package/dist/{popup-Ddx9LCzY.js → popup-ImtS9KnS.js} +1 -1
  89. package/dist/{popup-Ddx9LCzY.js.map → popup-ImtS9KnS.js.map} +1 -1
  90. package/dist/{prominence-CreDBdCs.js → prominence--ic9uWBl.js} +1 -1
  91. package/dist/{prominence-CreDBdCs.js.map → prominence--ic9uWBl.js.map} +1 -1
  92. package/dist/{radial-input-Dbc6fgCK.js → radial-input-DZA6WaFu.js} +14 -14
  93. package/dist/radial-input-DZA6WaFu.js.map +1 -0
  94. package/dist/radial-input.js +1 -1
  95. package/dist/range-input.js +1 -1
  96. package/dist/range.js +2 -2
  97. package/dist/{registry-CZEB1YI9.js → registry-Q2gYQCHM.js} +1 -1
  98. package/dist/{registry-CZEB1YI9.js.map → registry-Q2gYQCHM.js.map} +1 -1
  99. package/dist/selecthorizontal.js +1 -1
  100. package/dist/snap-container.js +1 -1
  101. package/dist/split-layout.js +4 -4
  102. package/dist/split-layout.js.map +1 -1
  103. package/dist/swipe.d.ts +1 -2
  104. package/dist/swipe.d.ts.map +1 -1
  105. package/dist/swipe.js +2 -2
  106. package/dist/swipe.js.map +1 -1
  107. package/dist/tabs.js +2 -2
  108. package/dist/tabs.js.map +1 -1
  109. package/dist/{timeline-B62Sz6J_.js → timeline-Cv75Th2U.js} +120 -116
  110. package/dist/timeline-Cv75Th2U.js.map +1 -0
  111. package/dist/timeline.d.ts +1 -1
  112. package/dist/timeline.js +1 -1
  113. package/dist/tooltip-CwGfb4lp.d.ts.map +1 -1
  114. package/dist/tree-CvvKbO-f.js +1330 -0
  115. package/dist/tree-CvvKbO-f.js.map +1 -0
  116. package/dist/{tree-component-CQpoPo4s.d.ts → tree-component-D8Bg48tt.d.ts} +12 -12
  117. package/dist/{tree-component-CQpoPo4s.d.ts.map → tree-component-D8Bg48tt.d.ts.map} +1 -1
  118. package/dist/tree.d.ts +1 -1
  119. package/dist/tree.js +1 -1143
  120. package/dist/xy-axis-D9uwpGTT.d.ts.map +1 -1
  121. package/dist/{xy-axis-C7fNxDwY.js → xy-axis-DL0tfJDr.js} +10 -10
  122. package/dist/{xy-axis-C7fNxDwY.js.map → xy-axis-DL0tfJDr.js.map} +1 -1
  123. package/dist/xy-pad.js +2 -2
  124. package/package.json +3 -3
  125. package/dist/decorate-O4m1U4l3.js.map +0 -1
  126. package/dist/hex-editor-gH3mteMr.js.map +0 -1
  127. package/dist/highlight-CAjwQ4GE.js.map +0 -1
  128. package/dist/icon-CYACf6o8.js.map +0 -1
  129. package/dist/incr-search-BZawvrfl.js.map +0 -1
  130. package/dist/index-CwGkb9s1.d.ts.map +0 -1
  131. package/dist/index-V2cJorlA.d.ts.map +0 -1
  132. package/dist/labelled-input-base-BvgH7ldm.js.map +0 -1
  133. package/dist/menu-C3eANB5M.js.map +0 -1
  134. package/dist/menu-item-6IU5weHi.js.map +0 -1
  135. package/dist/radial-input-Dbc6fgCK.js.map +0 -1
  136. package/dist/timeline-B62Sz6J_.js.map +0 -1
  137. package/dist/tree-data-model-DGvRVOFY.js +0 -190
  138. package/dist/tree-data-model-DGvRVOFY.js.map +0 -1
  139. package/dist/tree.js.map +0 -1
  140. /package/dist/{interaction-CQDQJf2Q.js → interaction-DG7X1rhI.js} +0 -0
package/dist/ac-text.js CHANGED
@@ -1,7 +1,7 @@
1
- import { r as clearHighlights, t as applyHighlights } from "./highlight-CAjwQ4GE.js";
1
+ import { r as clearHighlights, t as applyHighlights } from "./highlight-TPbSHruI.js";
2
2
  import { n as tickledStyles, r as TickledController } from "./tickled-styles-Bg3QbcrD.js";
3
- import { n as safeCustomElement, t as __decorate } from "./decorate-O4m1U4l3.js";
4
- import "./icon-CYACf6o8.js";
3
+ import { n as safeCustomElement, t as __decorate } from "./decorate-D7rC1gLP.js";
4
+ import "./icon-9NWTXtE1.js";
5
5
  import { LitElement, css, html, nothing } from "lit";
6
6
  import { property, state } from "lit/decorators.js";
7
7
  //#region src/ac-text/ac-text.ts
@@ -1 +1 @@
1
- {"version":3,"file":"ac-text.js","names":["#triggerQuery","#cancelPending","#debounceTimer","#scrollActiveIntoView","#selectItem","#commitText","#closePopup","#cache","#applyHighlights","#abortController","#onItemPointerDown","#renderItem","#onInput","#onKeyDown","#onFocus","#onBlur","#renderPopup","customElement"],"sources":["../src/ac-text/ac-text.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\nimport type { HighlightTarget } from '../incr-search/types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { applyHighlights, clearHighlights } from '../incr-search/highlight.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { tickledStyles } from '../interaction/tickled-styles.js';\nimport '../icons/icon.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nconst HIGHLIGHT_KEY = `ac-text-highlight`;\n\n// ---- Public types ----\n\nexport type AcTextItem = {\n readonly label: string;\n readonly subLabel?: string;\n readonly icon?: string;\n readonly key?: string;\n readonly data?: unknown;\n /** When true, Tab-accept will not append `tabSuffix`. */\n readonly isLeaf?: boolean;\n /** Character positions within label that matched the query, used for CSS highlight rendering. */\n readonly positions?: ReadonlySet<number>;\n};\n\nexport type AcTextSelectDetail = {\n readonly item: AcTextItem;\n readonly query: string;\n};\n\nexport type AcTextSelectEvent = CustomEvent<AcTextSelectDetail>;\n\n/**\n * Fired when the user commits a value — either by pressing Enter on typed text\n * or by selecting an item from the autocomplete popup (keyboard or click).\n */\nexport type AcTextChangeDetail = {\n /** The committed text value (typed text, or the selected item's label). */\n readonly value: string;\n /**\n * The item key. For autocomplete items: `item.key ?? item.label`.\n * For plain typed text: the text itself.\n */\n readonly key: string;\n /** The item's `data` payload. Only present for autocomplete selections. */\n readonly data?: unknown;\n /** Whether the commit came from plain typed text or an autocomplete selection. */\n readonly source: `text` | `autocomplete`;\n};\n\nexport type AcTextChangeEvent = CustomEvent<AcTextChangeDetail>;\n\nexport type AcTextCompletionProvider\n = (query: string, signal: AbortSignal) => Promise<AcTextItem[]> | AcTextItem[];\n\n// ---- LRU cache ----\n\ntype LruCache<K, V> = {\n get: (key: K) => V | undefined;\n set: (key: K, value: V) => void;\n has: (key: K) => boolean;\n clear: () => void;\n};\n\nfunction makeLruCache<K, V>(maxSize: number): LruCache<K, V> {\n const map = new Map<K, V>();\n return {\n get: (key: K) => map.get(key),\n set: (key: K, value: V) => {\n if (map.has(key))\n map.delete(key);\n map.set(key, value);\n if (map.size > maxSize)\n map.delete(map.keys().next().value!);\n },\n has: (key: K) => map.has(key),\n clear: () => map.clear(),\n };\n}\n\n// ---- Component ----\n\n/**\n * VS Code command-palette style autocomplete text input.\n *\n * Set `completionProvider` to a function that returns matching items for a\n * given query string. Results are shown in a popup that only exists in the\n * DOM while the input has focus.\n *\n * @fires {AcTextSelectEvent} ac-select — when an autocomplete item is selected\n * @fires {AcTextChangeEvent} change — when the user commits a value (Enter on typed text or autocomplete selection)\n *\n * @example\n * ```html\n * <ixfx-ac-text placeholder=\"Search commands…\"></ixfx-ac-text>\n * ```\n * ```ts\n * el.completionProvider = async (query) => commands.filter(c =>\n * c.label.toLowerCase().includes(query.toLowerCase())\n * );\n * el.addEventListener('change', e => console.log(e.detail));\n * ```\n */\n@customElement(`ixfx-ac-text`)\nexport class AcTextElement extends LitElement {\n /** Provides completion results for a query string. */\n @property({ type: Object })\n completionProvider: AcTextCompletionProvider | undefined;\n\n /** Placeholder text for the input. */\n @property({ type: String })\n placeholder = ``;\n\n /** Maximum number of query results to cache (LRU). */\n @property({ type: Number, attribute: `cache-size` })\n cacheSize = 20;\n\n /** Debounce delay in ms before invoking the provider after keystroke. */\n @property({ type: Number, attribute: `debounce-ms` })\n debounceMs = 150;\n\n /**\n * Pre-populate the input with this value. Updated externally after construction is ignored\n * unless the input is not currently focused.\n */\n @property({ type: String })\n value = ``;\n\n /**\n * String appended to the label when Tab is used to accept a suggestion.\n * Useful for path-style inputs where Tab-accepting a segment should add the separator.\n */\n @property({ type: String, attribute: `tab-suffix` })\n tabSuffix = ``;\n\n @state() private _query = ``;\n @state() private _results: AcTextItem[] = [];\n @state() private _isOpen = false;\n @state() private _isLoading = false;\n\n private tickled = new TickledController<number>(this, {\n getItems: () => this._results.map((_, i) => ({ id: i, enabled: true })),\n });\n\n #cache: LruCache<string, AcTextItem[]> = makeLruCache(20);\n #debounceTimer: ReturnType<typeof setTimeout> | undefined;\n #abortController: AbortController | undefined;\n\n constructor() {\n super();\n this.#cache = makeLruCache(this.cacheSize);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#cancelPending();\n clearHighlights({ key: HIGHLIGHT_KEY });\n }\n\n protected override updated(changedProps: PropertyValues): void {\n if (changedProps.has(`completionProvider`)) {\n this.#cache.clear();\n }\n if (changedProps.has(`cacheSize`)) {\n this.#cache = makeLruCache(this.cacheSize);\n }\n if (changedProps.has(`value`)) {\n // Only sync when the input isn't focused (avoid clobbering user typing)\n const input = this.shadowRoot?.querySelector(`input`);\n if (!input || document.activeElement !== input) {\n this._query = this.value;\n }\n }\n this.#applyHighlights();\n }\n\n #applyHighlights(): void {\n if (!this._isOpen || !this.shadowRoot) {\n clearHighlights({ key: HIGHLIGHT_KEY });\n return;\n }\n const labelEls = this.shadowRoot.querySelectorAll(`.item-label`);\n const targets: HighlightTarget[] = [];\n labelEls.forEach((el, index) => {\n const positions = this._results[index]?.positions;\n if (!positions?.size)\n return;\n targets.push({ element: el, text: this._results[index].label, positions });\n });\n applyHighlights(targets, { key: HIGHLIGHT_KEY });\n }\n\n override focus(options?: FocusOptions, selectionStart?: number, selectionEnd?: number): void {\n const input = this.shadowRoot?.querySelector(`input`) as HTMLInputElement | null;\n if (!input)\n return;\n input.focus(options);\n const start = selectionStart ?? input.value.length;\n const end = selectionEnd ?? input.value.length;\n input.setSelectionRange(start, end);\n input.scrollLeft = input.scrollWidth;\n }\n\n focusWithValue(value: string, selectionStart?: number, selectionEnd?: number): void {\n this._query = value;\n this.updateComplete.then(() => {\n const input = this.shadowRoot?.querySelector(`input`) as HTMLInputElement | null;\n if (!input)\n return;\n input.focus();\n const start = selectionStart ?? input.value.length;\n const end = selectionEnd ?? input.value.length;\n input.setSelectionRange(start, end);\n });\n }\n\n selectRange(start: number, end?: number): void {\n const input = this.shadowRoot?.querySelector(`input`) as HTMLInputElement | null;\n if (!input)\n return;\n const endPos = end ?? input.value.length;\n input.setSelectionRange(start, endPos);\n }\n\n // ---- Handlers ----\n\n #onFocus = (): void => {\n this._isOpen = true;\n if (this._query.trim()) {\n this.#triggerQuery(this._query);\n }\n };\n\n #onBlur = (): void => {\n this.#cancelPending();\n this._isOpen = false;\n this.tickled.clearTickled();\n };\n\n #onInput = (e: Event): void => {\n const input = e.target as HTMLInputElement;\n this._query = input.value;\n\n if (this.#debounceTimer !== undefined) {\n clearTimeout(this.#debounceTimer);\n }\n\n if (!this._query.trim()) {\n this._results = [];\n this.tickled.clearTickled();\n this._isLoading = false;\n this._isOpen = false;\n return;\n }\n\n this._isOpen = true;\n this.#debounceTimer = setTimeout(() => {\n this.#triggerQuery(this._query);\n }, this.debounceMs);\n };\n\n #onKeyDown = (e: KeyboardEvent): void => {\n switch (e.key) {\n case `ArrowDown`: {\n if (!this._isOpen)\n return;\n e.preventDefault();\n if (this._results.length === 0)\n return;\n this.tickled.handleKeyboardNavigation(`next`);\n this.#scrollActiveIntoView();\n break;\n }\n case `ArrowUp`: {\n if (!this._isOpen)\n return;\n e.preventDefault();\n if (this._results.length === 0)\n return;\n this.tickled.handleKeyboardNavigation(`previous`);\n this.#scrollActiveIntoView();\n break;\n }\n case `Enter`: {\n const tickledIndex = this.tickled.tickledId ?? -1;\n if (this._isOpen && tickledIndex >= 0 && this._results[tickledIndex]) {\n // Autocomplete selection via keyboard\n e.preventDefault();\n this.#selectItem(this._results[tickledIndex]);\n } else if (this._query.trim()) {\n // Plain text commit\n e.preventDefault();\n this.#commitText(this._query);\n }\n break;\n }\n case `Tab`: {\n const tickledIndex = this.tickled.tickledId ?? -1;\n if (this._isOpen && tickledIndex >= 0 && this._results[tickledIndex]) {\n e.preventDefault();\n const tabItem = this._results[tickledIndex];\n this._query = tabItem.label + (tabItem.isLeaf ? `` : this.tabSuffix);\n this.tickled.clearTickled();\n this.#triggerQuery(this._query);\n }\n break;\n }\n case `Escape`: {\n if (!this._isOpen)\n return;\n e.preventDefault();\n this.#closePopup();\n break;\n }\n }\n };\n\n /** pointerdown beats blur — prevents popup vanishing before click registers */\n #onItemPointerDown = (e: PointerEvent, item: AcTextItem): void => {\n e.preventDefault();\n this.#selectItem(item);\n };\n\n // ---- Internal logic ----\n\n #triggerQuery(query: string): void {\n if (!this.completionProvider)\n return;\n\n const cached = this.#cache.get(query);\n if (cached !== undefined) {\n this._results = cached;\n this.tickled.clearTickled();\n this._isLoading = false;\n return;\n }\n\n // Cancel any in-flight request\n this.#abortController?.abort();\n this.#abortController = new AbortController();\n const { signal } = this.#abortController;\n\n this._isLoading = true;\n\n Promise.resolve(this.completionProvider(query, signal))\n .then((results) => {\n if (signal.aborted)\n return;\n this.#cache.set(query, results);\n this._results = results;\n this.tickled.clearTickled();\n this._isLoading = false;\n })\n .catch((err) => {\n if (signal.aborted)\n return;\n console.error(`[ixfx-ac-text] completionProvider error:`, err);\n this._results = [];\n this._isLoading = false;\n });\n }\n\n #selectItem(item: AcTextItem): void {\n this.dispatchEvent(new CustomEvent<AcTextSelectDetail>(`ac-select`, {\n detail: { item, query: this._query },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<AcTextChangeDetail>(`change`, {\n detail: {\n value: item.label,\n key: item.key ?? item.label,\n data: item.data,\n source: `autocomplete`,\n },\n bubbles: true,\n composed: true,\n }));\n this._query = item.label;\n this._isOpen = false;\n this.tickled.clearTickled();\n }\n\n #commitText(text: string): void {\n this.dispatchEvent(new CustomEvent<AcTextChangeDetail>(`change`, {\n detail: {\n value: text,\n key: text,\n source: `text`,\n },\n bubbles: true,\n composed: true,\n }));\n this._isOpen = false;\n this.tickled.clearTickled();\n }\n\n #closePopup(): void {\n this._isOpen = false;\n this.tickled.clearTickled();\n clearHighlights({ key: HIGHLIGHT_KEY });\n }\n\n #cancelPending(): void {\n if (this.#debounceTimer !== undefined) {\n clearTimeout(this.#debounceTimer);\n this.#debounceTimer = undefined;\n }\n this.#abortController?.abort();\n this.#abortController = undefined;\n this._isLoading = false;\n }\n\n #scrollActiveIntoView(): void {\n // After Lit renders the new tickled item, scroll it into view\n this.updateComplete.then(() => {\n const item = this.shadowRoot?.querySelector(`.item.tickled`);\n item?.scrollIntoView({ block: `nearest` });\n });\n }\n\n // ---- Render helpers ----\n\n #renderItem(item: AcTextItem, index: number) {\n const isTickled = this.tickled.isTickled(index);\n return html`\n <div\n class=\"item ${isTickled ? `tickled` : ``}\"\n role=\"option\"\n id=\"ac-item-${index}\"\n aria-selected=${isTickled}\n @pointerenter=${() => this.tickled.handlePointerEnter(index)}\n @pointerdown=${(e: PointerEvent) => this.#onItemPointerDown(e, item)}\n >\n ${item.icon ? html`<ixfx-icon class=\"item-icon\" name=${item.icon}></ixfx-icon>` : nothing}\n <span class=\"item-label\">${item.label}</span>\n ${item.subLabel ? html`<span class=\"item-sublabel\">${item.subLabel}</span>` : nothing}\n </div>\n `;\n }\n\n #renderPopup() {\n const showEmpty = !this._isLoading && this._results.length === 0;\n return html`\n <div\n class=\"popup\"\n role=\"listbox\"\n aria-label=\"Suggestions\"\n data-input-mode=${this.tickled.inputMode}\n @pointerleave=${(e: PointerEvent) => this.tickled.handlePointerLeave(e)}\n >\n ${showEmpty\n ? html`<div class=\"no-results\">No matching results</div>`\n : this._results.map((item, i) => this.#renderItem(item, i))\n }\n </div>\n `;\n }\n\n protected override render() {\n const tickledIndex = this.tickled.tickledId ?? -1;\n const activeDescendant = tickledIndex >= 0 ? `ac-item-${tickledIndex}` : undefined;\n return html`\n <div class=\"input-wrapper\">\n <input\n type=\"text\"\n .value=${this._query}\n placeholder=${this.placeholder || nothing}\n autocomplete=\"off\"\n spellcheck=\"false\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=${this._isOpen}\n aria-activedescendant=${activeDescendant ?? nothing}\n @input=${this.#onInput}\n @keydown=${this.#onKeyDown}\n @focus=${this.#onFocus}\n @blur=${this.#onBlur}\n >\n ${this._isLoading\n ? html`<span class=\"spinner\" aria-hidden=\"true\"></span>`\n : nothing\n }\n </div>\n ${this._isOpen ? this.#renderPopup() : nothing}\n `;\n }\n\n static override styles = [\n tickledStyles,\n css`\n :host {\n display: block;\n position: relative;\n font-family: var(--font-family, system-ui, sans-serif);\n font-size: var(--text-m, 12px);\n color: var(--surface-2-text);\n }\n\n /* ---- Input ---- */\n\n .input-wrapper {\n display: flex;\n align-items: center;\n position: relative;\n }\n\n input {\n appearance: none;\n width: 100%;\n box-sizing: border-box;\n padding: var(--ac-input-padding, var(--space-m, 8px) var(--space-l, 12px));\n background: var(--ac-input-background, var(--surface-3, var(--surface-2)));\n color: var(--surface-2-text);\n border: var(--ac-input-border, var(--border));\n border-radius: var(--ac-input-border-radius, var(--radius-m, 4px));\n font: inherit;\n caret-color: var(--accent);\n outline: none;\n transition: border-color var(--transition, 0.15s ease-out);\n }\n\n input:focus {\n border-color: var(--accent);\n }\n\n input::placeholder {\n color: var(--surface-muted-text);\n }\n\n /* ---- Spinner ---- */\n\n .spinner {\n position: absolute;\n right: var(--space-m, 8px);\n width: 12px;\n height: 12px;\n border: 2px solid var(--surface-5);\n border-top-color: var(--accent);\n border-radius: 50%;\n animation: ac-spin 0.7s linear infinite;\n flex-shrink: 0;\n pointer-events: none;\n }\n\n @keyframes ac-spin {\n to { transform: rotate(360deg); }\n }\n\n /* ---- Popup ---- */\n\n .popup {\n position: absolute;\n top: calc(100% + 2px);\n left: 0;\n right: 0;\n z-index: 100;\n background: var(--surface-3, var(--surface-2));\n border: var(--border);\n border-radius: var(--radius-m, 4px);\n box-shadow: var(--shadow-l, 0 4px 24px rgba(0, 0, 0, 0.5));\n padding: var(--space-xs, 3px) 0;\n max-height: 280px;\n overflow-y: auto;\n font-size: var(--ac-popup-font-size, var(--text-s, 11px));\n }\n\n /* ---- Items ---- */\n\n .item {\n display: flex;\n align-items: center;\n gap: var(--space-m, 8px);\n padding: var(--space-xs, 3px) var(--space-l, 12px);\n cursor: pointer;\n border-radius: var(--radius-s, 3px);\n margin: 0 var(--space-xs, 3px);\n transition: background var(--transition, 0.1s ease-out);\n user-select: none;\n white-space: nowrap;\n min-height: 28px;\n }\n\n \n\n .item.tickled {\n background: var(--_item-focused-bg, var(--accent));\n color: var(--accent-text, #fff);\n }\n\n .item.tickled .item-sublabel {\n color: color-mix(in srgb, var(--accent-text, #fff) 70%, transparent);\n }\n\n .item-icon {\n flex-shrink: 0;\n width: 1em;\n height: 1em;\n }\n\n .item-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .item-sublabel {\n flex-shrink: 0;\n margin-left: auto;\n color: var(--surface-muted-text);\n font-size: var(--text-s, 11px);\n }\n\n ::highlight(ac-text-highlight) {\n background: var(--ac-highlight-background, var(--accent));\n color: var(--ac-highlight-color, var(--accent-text, #fff));\n border-radius: 2px;\n padding: 0 1px;\n }\n\n /* ---- Empty state ---- */\n\n .no-results {\n padding: var(--space-m, 8px) var(--space-l, 12px);\n color: var(--surface-muted-text);\n font-style: italic;\n font-size: var(--text-s, 11px);\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-ac-text': AcTextElement;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ac-text.js","names":["#triggerQuery","#cancelPending","#debounceTimer","#scrollActiveIntoView","#selectItem","#commitText","#closePopup","#cache","#applyHighlights","#abortController","#onItemPointerDown","#renderItem","#onInput","#onKeyDown","#onFocus","#onBlur","#renderPopup","customElement"],"sources":["../src/ac-text/ac-text.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\nimport type { HighlightTarget } from '../incr-search/types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { applyHighlights, clearHighlights } from '../incr-search/highlight.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { tickledStyles } from '../interaction/tickled-styles.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../icons/icon.js';\n\nconst HIGHLIGHT_KEY = `ac-text-highlight`;\n\n// ---- Public types ----\n\nexport type AcTextItem = {\n readonly label: string;\n readonly subLabel?: string;\n readonly icon?: string;\n readonly key?: string;\n readonly data?: unknown;\n /** When true, Tab-accept will not append `tabSuffix`. */\n readonly isLeaf?: boolean;\n /** Character positions within label that matched the query, used for CSS highlight rendering. */\n readonly positions?: ReadonlySet<number>;\n};\n\nexport type AcTextSelectDetail = {\n readonly item: AcTextItem;\n readonly query: string;\n};\n\nexport type AcTextSelectEvent = CustomEvent<AcTextSelectDetail>;\n\n/**\n * Fired when the user commits a value — either by pressing Enter on typed text\n * or by selecting an item from the autocomplete popup (keyboard or click).\n */\nexport type AcTextChangeDetail = {\n /** The committed text value (typed text, or the selected item's label). */\n readonly value: string;\n /**\n * The item key. For autocomplete items: `item.key ?? item.label`.\n * For plain typed text: the text itself.\n */\n readonly key: string;\n /** The item's `data` payload. Only present for autocomplete selections. */\n readonly data?: unknown;\n /** Whether the commit came from plain typed text or an autocomplete selection. */\n readonly source: `text` | `autocomplete`;\n};\n\nexport type AcTextChangeEvent = CustomEvent<AcTextChangeDetail>;\n\nexport type AcTextCompletionProvider\n = (query: string, signal: AbortSignal) => Promise<AcTextItem[]> | AcTextItem[];\n\n// ---- LRU cache ----\n\ntype LruCache<K, V> = {\n get: (key: K) => V | undefined;\n set: (key: K, value: V) => void;\n has: (key: K) => boolean;\n clear: () => void;\n};\n\nfunction makeLruCache<K, V>(maxSize: number): LruCache<K, V> {\n const map = new Map<K, V>();\n return {\n get: (key: K) => map.get(key),\n set: (key: K, value: V) => {\n if (map.has(key))\n map.delete(key);\n map.set(key, value);\n if (map.size > maxSize)\n map.delete(map.keys().next().value!);\n },\n has: (key: K) => map.has(key),\n clear: () => map.clear(),\n };\n}\n\n// ---- Component ----\n\n/**\n * VS Code command-palette style autocomplete text input.\n *\n * Set `completionProvider` to a function that returns matching items for a\n * given query string. Results are shown in a popup that only exists in the\n * DOM while the input has focus.\n *\n * @fires {AcTextSelectEvent} ac-select — when an autocomplete item is selected\n * @fires {AcTextChangeEvent} change — when the user commits a value (Enter on typed text or autocomplete selection)\n *\n * @example\n * ```html\n * <ixfx-ac-text placeholder=\"Search commands…\"></ixfx-ac-text>\n * ```\n * ```ts\n * el.completionProvider = async (query) => commands.filter(c =>\n * c.label.toLowerCase().includes(query.toLowerCase())\n * );\n * el.addEventListener('change', e => console.log(e.detail));\n * ```\n */\n@customElement(`ixfx-ac-text`)\nexport class AcTextElement extends LitElement {\n /** Provides completion results for a query string. */\n @property({ type: Object })\n completionProvider: AcTextCompletionProvider | undefined;\n\n /** Placeholder text for the input. */\n @property({ type: String })\n placeholder = ``;\n\n /** Maximum number of query results to cache (LRU). */\n @property({ type: Number, attribute: `cache-size` })\n cacheSize = 20;\n\n /** Debounce delay in ms before invoking the provider after keystroke. */\n @property({ type: Number, attribute: `debounce-ms` })\n debounceMs = 150;\n\n /**\n * Pre-populate the input with this value. Updated externally after construction is ignored\n * unless the input is not currently focused.\n */\n @property({ type: String })\n value = ``;\n\n /**\n * String appended to the label when Tab is used to accept a suggestion.\n * Useful for path-style inputs where Tab-accepting a segment should add the separator.\n */\n @property({ type: String, attribute: `tab-suffix` })\n tabSuffix = ``;\n\n @state() private _query = ``;\n @state() private _results: AcTextItem[] = [];\n @state() private _isOpen = false;\n @state() private _isLoading = false;\n\n private tickled = new TickledController<number>(this, {\n getItems: () => this._results.map((_, i) => ({ id: i, enabled: true })),\n });\n\n #cache: LruCache<string, AcTextItem[]> = makeLruCache(20);\n #debounceTimer: ReturnType<typeof setTimeout> | undefined;\n #abortController: AbortController | undefined;\n\n constructor() {\n super();\n this.#cache = makeLruCache(this.cacheSize);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#cancelPending();\n clearHighlights({ key: HIGHLIGHT_KEY });\n }\n\n protected override updated(changedProps: PropertyValues): void {\n if (changedProps.has(`completionProvider`)) {\n this.#cache.clear();\n }\n if (changedProps.has(`cacheSize`)) {\n this.#cache = makeLruCache(this.cacheSize);\n }\n if (changedProps.has(`value`)) {\n // Only sync when the input isn't focused (avoid clobbering user typing)\n const input = this.shadowRoot?.querySelector(`input`);\n if (!input || document.activeElement !== input) {\n this._query = this.value;\n }\n }\n this.#applyHighlights();\n }\n\n #applyHighlights(): void {\n if (!this._isOpen || !this.shadowRoot) {\n clearHighlights({ key: HIGHLIGHT_KEY });\n return;\n }\n const labelEls = this.shadowRoot.querySelectorAll(`.item-label`);\n const targets: HighlightTarget[] = [];\n labelEls.forEach((el, index) => {\n const positions = this._results[index]?.positions;\n if (!positions?.size)\n return;\n targets.push({ element: el, text: this._results[index].label, positions });\n });\n applyHighlights(targets, { key: HIGHLIGHT_KEY });\n }\n\n override focus(options?: FocusOptions, selectionStart?: number, selectionEnd?: number): void {\n const input = this.shadowRoot?.querySelector(`input`) as HTMLInputElement | null;\n if (!input)\n return;\n input.focus(options);\n const start = selectionStart ?? input.value.length;\n const end = selectionEnd ?? input.value.length;\n input.setSelectionRange(start, end);\n input.scrollLeft = input.scrollWidth;\n }\n\n focusWithValue(value: string, selectionStart?: number, selectionEnd?: number): void {\n this._query = value;\n this.updateComplete.then(() => {\n const input = this.shadowRoot?.querySelector(`input`) as HTMLInputElement | null;\n if (!input)\n return;\n input.focus();\n const start = selectionStart ?? input.value.length;\n const end = selectionEnd ?? input.value.length;\n input.setSelectionRange(start, end);\n });\n }\n\n selectRange(start: number, end?: number): void {\n const input = this.shadowRoot?.querySelector(`input`) as HTMLInputElement | null;\n if (!input)\n return;\n const endPos = end ?? input.value.length;\n input.setSelectionRange(start, endPos);\n }\n\n // ---- Handlers ----\n\n #onFocus = (): void => {\n this._isOpen = true;\n if (this._query.trim()) {\n this.#triggerQuery(this._query);\n }\n };\n\n #onBlur = (): void => {\n this.#cancelPending();\n this._isOpen = false;\n this.tickled.clearTickled();\n };\n\n #onInput = (e: Event): void => {\n const input = e.target as HTMLInputElement;\n this._query = input.value;\n\n if (this.#debounceTimer !== undefined) {\n clearTimeout(this.#debounceTimer);\n }\n\n if (!this._query.trim()) {\n this._results = [];\n this.tickled.clearTickled();\n this._isLoading = false;\n this._isOpen = false;\n return;\n }\n\n this._isOpen = true;\n this.#debounceTimer = setTimeout(() => {\n this.#triggerQuery(this._query);\n }, this.debounceMs);\n };\n\n #onKeyDown = (e: KeyboardEvent): void => {\n switch (e.key) {\n case `ArrowDown`: {\n if (!this._isOpen)\n return;\n e.preventDefault();\n if (this._results.length === 0)\n return;\n this.tickled.handleKeyboardNavigation(`next`);\n this.#scrollActiveIntoView();\n break;\n }\n case `ArrowUp`: {\n if (!this._isOpen)\n return;\n e.preventDefault();\n if (this._results.length === 0)\n return;\n this.tickled.handleKeyboardNavigation(`previous`);\n this.#scrollActiveIntoView();\n break;\n }\n case `Enter`: {\n const tickledIndex = this.tickled.tickledId ?? -1;\n if (this._isOpen && tickledIndex >= 0 && this._results[tickledIndex]) {\n // Autocomplete selection via keyboard\n e.preventDefault();\n this.#selectItem(this._results[tickledIndex]);\n } else if (this._query.trim()) {\n // Plain text commit\n e.preventDefault();\n this.#commitText(this._query);\n }\n break;\n }\n case `Tab`: {\n const tickledIndex = this.tickled.tickledId ?? -1;\n if (this._isOpen && tickledIndex >= 0 && this._results[tickledIndex]) {\n e.preventDefault();\n const tabItem = this._results[tickledIndex];\n this._query = tabItem.label + (tabItem.isLeaf ? `` : this.tabSuffix);\n this.tickled.clearTickled();\n this.#triggerQuery(this._query);\n }\n break;\n }\n case `Escape`: {\n if (!this._isOpen)\n return;\n e.preventDefault();\n this.#closePopup();\n break;\n }\n }\n };\n\n /** pointerdown beats blur — prevents popup vanishing before click registers */\n #onItemPointerDown = (e: PointerEvent, item: AcTextItem): void => {\n e.preventDefault();\n this.#selectItem(item);\n };\n\n // ---- Internal logic ----\n\n #triggerQuery(query: string): void {\n if (!this.completionProvider)\n return;\n\n const cached = this.#cache.get(query);\n if (cached !== undefined) {\n this._results = cached;\n this.tickled.clearTickled();\n this._isLoading = false;\n return;\n }\n\n // Cancel any in-flight request\n this.#abortController?.abort();\n this.#abortController = new AbortController();\n const { signal } = this.#abortController;\n\n this._isLoading = true;\n\n Promise.resolve(this.completionProvider(query, signal))\n .then((results) => {\n if (signal.aborted)\n return;\n this.#cache.set(query, results);\n this._results = results;\n this.tickled.clearTickled();\n this._isLoading = false;\n })\n .catch((err) => {\n if (signal.aborted)\n return;\n console.error(`[ixfx-ac-text] completionProvider error:`, err);\n this._results = [];\n this._isLoading = false;\n });\n }\n\n #selectItem(item: AcTextItem): void {\n this.dispatchEvent(new CustomEvent<AcTextSelectDetail>(`ac-select`, {\n detail: { item, query: this._query },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<AcTextChangeDetail>(`change`, {\n detail: {\n value: item.label,\n key: item.key ?? item.label,\n data: item.data,\n source: `autocomplete`,\n },\n bubbles: true,\n composed: true,\n }));\n this._query = item.label;\n this._isOpen = false;\n this.tickled.clearTickled();\n }\n\n #commitText(text: string): void {\n this.dispatchEvent(new CustomEvent<AcTextChangeDetail>(`change`, {\n detail: {\n value: text,\n key: text,\n source: `text`,\n },\n bubbles: true,\n composed: true,\n }));\n this._isOpen = false;\n this.tickled.clearTickled();\n }\n\n #closePopup(): void {\n this._isOpen = false;\n this.tickled.clearTickled();\n clearHighlights({ key: HIGHLIGHT_KEY });\n }\n\n #cancelPending(): void {\n if (this.#debounceTimer !== undefined) {\n clearTimeout(this.#debounceTimer);\n this.#debounceTimer = undefined;\n }\n this.#abortController?.abort();\n this.#abortController = undefined;\n this._isLoading = false;\n }\n\n #scrollActiveIntoView(): void {\n // After Lit renders the new tickled item, scroll it into view\n this.updateComplete.then(() => {\n const item = this.shadowRoot?.querySelector(`.item.tickled`);\n item?.scrollIntoView({ block: `nearest` });\n });\n }\n\n // ---- Render helpers ----\n\n #renderItem(item: AcTextItem, index: number) {\n const isTickled = this.tickled.isTickled(index);\n return html`\n <div\n class=\"item ${isTickled ? `tickled` : ``}\"\n role=\"option\"\n id=\"ac-item-${index}\"\n aria-selected=${isTickled}\n @pointerenter=${() => this.tickled.handlePointerEnter(index)}\n @pointerdown=${(e: PointerEvent) => this.#onItemPointerDown(e, item)}\n >\n ${item.icon ? html`<ixfx-icon class=\"item-icon\" name=${item.icon}></ixfx-icon>` : nothing}\n <span class=\"item-label\">${item.label}</span>\n ${item.subLabel ? html`<span class=\"item-sublabel\">${item.subLabel}</span>` : nothing}\n </div>\n `;\n }\n\n #renderPopup() {\n const showEmpty = !this._isLoading && this._results.length === 0;\n return html`\n <div\n class=\"popup\"\n role=\"listbox\"\n aria-label=\"Suggestions\"\n data-input-mode=${this.tickled.inputMode}\n @pointerleave=${(e: PointerEvent) => this.tickled.handlePointerLeave(e)}\n >\n ${showEmpty\n ? html`<div class=\"no-results\">No matching results</div>`\n : this._results.map((item, i) => this.#renderItem(item, i))\n }\n </div>\n `;\n }\n\n protected override render() {\n const tickledIndex = this.tickled.tickledId ?? -1;\n const activeDescendant = tickledIndex >= 0 ? `ac-item-${tickledIndex}` : undefined;\n return html`\n <div class=\"input-wrapper\">\n <input\n type=\"text\"\n .value=${this._query}\n placeholder=${this.placeholder || nothing}\n autocomplete=\"off\"\n spellcheck=\"false\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=${this._isOpen}\n aria-activedescendant=${activeDescendant ?? nothing}\n @input=${this.#onInput}\n @keydown=${this.#onKeyDown}\n @focus=${this.#onFocus}\n @blur=${this.#onBlur}\n >\n ${this._isLoading\n ? html`<span class=\"spinner\" aria-hidden=\"true\"></span>`\n : nothing\n }\n </div>\n ${this._isOpen ? this.#renderPopup() : nothing}\n `;\n }\n\n static override styles = [\n tickledStyles,\n css`\n :host {\n display: block;\n position: relative;\n font-family: var(--font-family, system-ui, sans-serif);\n font-size: var(--text-m, 12px);\n color: var(--surface-2-text);\n }\n\n /* ---- Input ---- */\n\n .input-wrapper {\n display: flex;\n align-items: center;\n position: relative;\n }\n\n input {\n appearance: none;\n width: 100%;\n box-sizing: border-box;\n padding: var(--ac-input-padding, var(--space-m, 8px) var(--space-l, 12px));\n background: var(--ac-input-background, var(--surface-3, var(--surface-2)));\n color: var(--surface-2-text);\n border: var(--ac-input-border, var(--border));\n border-radius: var(--ac-input-border-radius, var(--radius-m, 4px));\n font: inherit;\n caret-color: var(--accent);\n outline: none;\n transition: border-color var(--transition, 0.15s ease-out);\n }\n\n input:focus {\n border-color: var(--accent);\n }\n\n input::placeholder {\n color: var(--surface-muted-text);\n }\n\n /* ---- Spinner ---- */\n\n .spinner {\n position: absolute;\n right: var(--space-m, 8px);\n width: 12px;\n height: 12px;\n border: 2px solid var(--surface-5);\n border-top-color: var(--accent);\n border-radius: 50%;\n animation: ac-spin 0.7s linear infinite;\n flex-shrink: 0;\n pointer-events: none;\n }\n\n @keyframes ac-spin {\n to { transform: rotate(360deg); }\n }\n\n /* ---- Popup ---- */\n\n .popup {\n position: absolute;\n top: calc(100% + 2px);\n left: 0;\n right: 0;\n z-index: 100;\n background: var(--surface-3, var(--surface-2));\n border: var(--border);\n border-radius: var(--radius-m, 4px);\n box-shadow: var(--shadow-l, 0 4px 24px rgba(0, 0, 0, 0.5));\n padding: var(--space-xs, 3px) 0;\n max-height: 280px;\n overflow-y: auto;\n font-size: var(--ac-popup-font-size, var(--text-s, 11px));\n }\n\n /* ---- Items ---- */\n\n .item {\n display: flex;\n align-items: center;\n gap: var(--space-m, 8px);\n padding: var(--space-xs, 3px) var(--space-l, 12px);\n cursor: pointer;\n border-radius: var(--radius-s, 3px);\n margin: 0 var(--space-xs, 3px);\n transition: background var(--transition, 0.1s ease-out);\n user-select: none;\n white-space: nowrap;\n min-height: 28px;\n }\n\n \n\n .item.tickled {\n background: var(--_item-focused-bg, var(--accent));\n color: var(--accent-text, #fff);\n }\n\n .item.tickled .item-sublabel {\n color: color-mix(in srgb, var(--accent-text, #fff) 70%, transparent);\n }\n\n .item-icon {\n flex-shrink: 0;\n width: 1em;\n height: 1em;\n }\n\n .item-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .item-sublabel {\n flex-shrink: 0;\n margin-left: auto;\n color: var(--surface-muted-text);\n font-size: var(--text-s, 11px);\n }\n\n ::highlight(ac-text-highlight) {\n background: var(--ac-highlight-background, var(--accent));\n color: var(--ac-highlight-color, var(--accent-text, #fff));\n border-radius: 2px;\n padding: 0 1px;\n }\n\n /* ---- Empty state ---- */\n\n .no-results {\n padding: var(--space-m, 8px) var(--space-l, 12px);\n color: var(--surface-muted-text);\n font-style: italic;\n font-size: var(--text-s, 11px);\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-ac-text': AcTextElement;\n }\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { t as getIcon } from "./registry-CZEB1YI9.js";
2
- import { n as safeCustomElement, t as __decorate } from "./decorate-O4m1U4l3.js";
1
+ import { n as safeCustomElement, t as __decorate } from "./decorate-D7rC1gLP.js";
2
+ import { t as getIcon } from "./registry-Q2gYQCHM.js";
3
3
  import "./icons.js";
4
- import { t as prominenceStyles } from "./prominence-CreDBdCs.js";
4
+ import { t as prominenceStyles } from "./prominence--ic9uWBl.js";
5
5
  import { LitElement, css, html, nothing } from "lit";
6
6
  import { property } from "lit/decorators.js";
7
7
  import { unsafeHTML } from "lit/directives/unsafe-html.js";
@@ -118,4 +118,4 @@ ButtonElement = __decorate([safeCustomElement(`ixfx-button`)], ButtonElement);
118
118
  //#endregion
119
119
  export { buttonStyles as n, ButtonElement as t };
120
120
 
121
- //# sourceMappingURL=button-B9ztaKyl.js.map
121
+ //# sourceMappingURL=button-DMt5XWUK.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"button-B9ztaKyl.js","names":["customElement"],"sources":["../src/button/button-styles.ts","../src/button/button.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const buttonStyles = css`\n :host {\n display: inline-flex;\n max-width: 100%;\n vertical-align: middle;\n user-select: none;\n -webkit-user-select: none;\n }\n\n button {\n cursor: pointer;\n appearance: none;\n background: var(--surface-4, #ccc);\n color: var(--surface-3-text, #000);\n border: var(--border, 1px solid #999);\n border-radius: var(--radius-xl, 8px);\n corner-shape: superellipse(1);\n padding: var(--space-m, 8px) var(--space-l, 12px);\n font-family: var(--font-family, inherit);\n font-size: var(--text-m, 14px);\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5em;\n width: 100%;\n overflow: hidden;\n white-space: nowrap;\n box-shadow: \n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-4) 30%, transparent), inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 20%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 30%, transparent);\n transition: background var(--transition, 0.2s), border-color var(--transition, 0.2s);\n }\n\n button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n button:hover:not(:disabled) {\n background: color-mix(in oklch, var(--surface-4) 80%, transparent);\n border-color: var(--accent, #666);\n box-shadow: \n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-5) 70%, transparent), \n inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 60%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 90%, transparent);\n }\n\n button:active:not(:disabled) {\n background: var(--surface-2, #aaa);\n transform: translateY(1px);\n box-shadow: inset 1px 1px 0px 0.5px color-mix(in oklch,var(--surface-1),transparent);\n }\n\n .button-icon {\n display: var(--ixfx-button-hide-icon, inline-flex);\n align-items: center;\n flex-shrink: 0;\n }\n\n .button-label {\n white-space: nowrap;\n display: var(--ixfx-button-hide-label, inline);\n }\n\n :host([hide-label]) .button-label {\n display: none;\n }\n\n :host([hide-icon]) .button-icon {\n display: none;\n }\n`;\n","import { html, LitElement, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\nimport { getIcon } from \"../icons/index.js\";\nimport { prominenceStyles } from \"../styles/prominence.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\nimport { buttonStyles } from \"./button-styles.js\";\n\n@customElement(`ixfx-button`)\nexport class ButtonElement extends LitElement {\n @property({ type: Boolean })\n disabled = false;\n\n @property({ type: String })\n icon?: string;\n\n @property({ type: Boolean, attribute: `hide-icon`, reflect: true })\n hideIcon = false;\n\n @property({ type: Boolean, attribute: `hide-label`, reflect: true })\n hideLabel = false;\n\n protected _renderIcon() {\n if (this.hideIcon || !this.icon)\n return nothing;\n\n if (this.icon.startsWith(`<svg`)) {\n return html`<span class=\"button-icon\">${unsafeHTML(this.icon)}</span>`;\n }\n\n const svg = getIcon(this.icon);\n\n if (!svg)\n return nothing;\n\n return html`<ixfx-icon class=\"button-icon\" name=\"${this.icon}\"></ixfx-icon>`;\n }\n\n protected render() {\n const label = this.hideLabel\n ? nothing\n : html`<span class=\"button-label\"><slot></slot></span>`;\n return html`<button ?disabled=${this.disabled}>${this._renderIcon()}${label}</button>`;\n }\n\n static styles = [\n prominenceStyles,\n buttonStyles,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-button\": ButtonElement;\n }\n}\n"],"mappings":";;;;;;;;AAEA,MAAa,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACOxB,IAAA,gBAAA,MAAM,sBAAsB,WAAW;;;kBAEjC;kBAMA;mBAGC;;CAEZ,cAAwB;EACtB,IAAI,KAAK,YAAY,CAAC,KAAK,MACzB,OAAO;EAET,IAAI,KAAK,KAAK,WAAW,MAAM,GAC7B,OAAO,IAAI,6BAA6B,WAAW,KAAK,IAAI,EAAE;EAKhE,IAAI,CAFQ,QAAQ,KAAK,IAElB,GACL,OAAO;EAET,OAAO,IAAI,wCAAwC,KAAK,KAAK;CAC/D;CAEA,SAAmB;EACjB,MAAM,QAAQ,KAAK,YACf,UACA,IAAI;EACR,OAAO,IAAI,qBAAqB,KAAK,SAAS,GAAG,KAAK,YAAY,IAAI,MAAM;CAC9E;;gBAEgB,CACd,kBACA,YACF;;AACF;YAvCG,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,cAAA,WAAA,YAAA,KAAA,CAAA;YAG1B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,cAAA,WAAA,QAAA,KAAA,CAAA;YAGzB,SAAS;CAAE,MAAM;CAAS,WAAW;CAAa,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,YAAA,KAAA,CAAA;YAGjE,SAAS;CAAE,MAAM;CAAS,WAAW;CAAc,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,aAAA,KAAA,CAAA;4BAXpEA,kBAAc,aAAa,CAAA,GAAA,aAAA"}
1
+ {"version":3,"file":"button-DMt5XWUK.js","names":["customElement"],"sources":["../src/button/button-styles.ts","../src/button/button.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const buttonStyles = css`\n :host {\n display: inline-flex;\n max-width: 100%;\n vertical-align: middle;\n user-select: none;\n -webkit-user-select: none;\n }\n\n button {\n cursor: pointer;\n appearance: none;\n background: var(--surface-4, #ccc);\n color: var(--surface-3-text, #000);\n border: var(--border, 1px solid #999);\n border-radius: var(--radius-xl, 8px);\n corner-shape: superellipse(1);\n padding: var(--space-m, 8px) var(--space-l, 12px);\n font-family: var(--font-family, inherit);\n font-size: var(--text-m, 14px);\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5em;\n width: 100%;\n overflow: hidden;\n white-space: nowrap;\n box-shadow: \n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-4) 30%, transparent), inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 20%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 30%, transparent);\n transition: background var(--transition, 0.2s), border-color var(--transition, 0.2s);\n }\n\n button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n button:hover:not(:disabled) {\n background: color-mix(in oklch, var(--surface-4) 80%, transparent);\n border-color: var(--accent, #666);\n box-shadow: \n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-5) 70%, transparent), \n inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 60%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 90%, transparent);\n }\n\n button:active:not(:disabled) {\n background: var(--surface-2, #aaa);\n transform: translateY(1px);\n box-shadow: inset 1px 1px 0px 0.5px color-mix(in oklch,var(--surface-1),transparent);\n }\n\n .button-icon {\n display: var(--ixfx-button-hide-icon, inline-flex);\n align-items: center;\n flex-shrink: 0;\n }\n\n .button-label {\n white-space: nowrap;\n display: var(--ixfx-button-hide-label, inline);\n }\n\n :host([hide-label]) .button-label {\n display: none;\n }\n\n :host([hide-icon]) .button-icon {\n display: none;\n }\n`;\n","import { html, LitElement, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\nimport { getIcon } from \"../icons/index.js\";\nimport { prominenceStyles } from \"../styles/prominence.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\nimport { buttonStyles } from \"./button-styles.js\";\n\n@customElement(`ixfx-button`)\nexport class ButtonElement extends LitElement {\n @property({ type: Boolean })\n disabled = false;\n\n @property({ type: String })\n icon?: string;\n\n @property({ type: Boolean, attribute: `hide-icon`, reflect: true })\n hideIcon = false;\n\n @property({ type: Boolean, attribute: `hide-label`, reflect: true })\n hideLabel = false;\n\n protected _renderIcon() {\n if (this.hideIcon || !this.icon)\n return nothing;\n\n if (this.icon.startsWith(`<svg`)) {\n return html`<span class=\"button-icon\">${unsafeHTML(this.icon)}</span>`;\n }\n\n const svg = getIcon(this.icon);\n\n if (!svg)\n return nothing;\n\n return html`<ixfx-icon class=\"button-icon\" name=\"${this.icon}\"></ixfx-icon>`;\n }\n\n protected render() {\n const label = this.hideLabel\n ? nothing\n : html`<span class=\"button-label\"><slot></slot></span>`;\n return html`<button ?disabled=${this.disabled}>${this._renderIcon()}${label}</button>`;\n }\n\n static styles = [\n prominenceStyles,\n buttonStyles,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-button\": ButtonElement;\n }\n}\n"],"mappings":";;;;;;;;AAEA,MAAa,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACOxB,IAAA,gBAAA,MAAM,sBAAsB,WAAW;;;kBAEjC;kBAMA;mBAGC;;CAEZ,cAAwB;EACtB,IAAI,KAAK,YAAY,CAAC,KAAK,MACzB,OAAO;EAET,IAAI,KAAK,KAAK,WAAW,MAAM,GAC7B,OAAO,IAAI,6BAA6B,WAAW,KAAK,IAAI,EAAE;EAKhE,IAAI,CAFQ,QAAQ,KAAK,IAElB,GACL,OAAO;EAET,OAAO,IAAI,wCAAwC,KAAK,KAAK;CAC/D;CAEA,SAAmB;EACjB,MAAM,QAAQ,KAAK,YACf,UACA,IAAI;EACR,OAAO,IAAI,qBAAqB,KAAK,SAAS,GAAG,KAAK,YAAY,IAAI,MAAM;CAC9E;;gBAEgB,CACd,kBACA,YACF;;AACF;YAvCG,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,cAAA,WAAA,YAAA,KAAA,CAAA;YAG1B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,cAAA,WAAA,QAAA,KAAA,CAAA;YAGzB,SAAS;CAAE,MAAM;CAAS,WAAW;CAAa,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,YAAA,KAAA,CAAA;YAGjE,SAAS;CAAE,MAAM;CAAS,WAAW;CAAc,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,aAAA,KAAA,CAAA;4BAXpEA,kBAAc,aAAa,CAAA,GAAA,aAAA"}
package/dist/button.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import "./icons.js";
2
- import { t as ButtonElement } from "./button-B9ztaKyl.js";
2
+ import { t as ButtonElement } from "./button-DMt5XWUK.js";
3
3
  export { ButtonElement };
@@ -22,11 +22,10 @@ declare global {
22
22
  }
23
23
  }
24
24
  interface CheckboxEventMap {
25
- 'change': CheckboxChangeEvent;
25
+ change: CheckboxChangeEvent;
26
26
  }
27
27
  interface Checkbox {
28
- addEventListener<K extends keyof CheckboxEventMap>(type: K, listener: (this: Checkbox, event: CheckboxEventMap[K]) => void, options?: boolean | AddEventListenerOptions): void;
29
- addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
28
+ addEventListener: (<K extends keyof CheckboxEventMap>(type: K, listener: (this: Checkbox, event: CheckboxEventMap[K]) => void, options?: boolean | AddEventListenerOptions) => void) & ((type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => void);
30
29
  }
31
30
  //#endregion
32
31
  export { Checkbox, CheckboxChangeDetail, CheckboxChangeEvent, CheckboxEventMap };
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.d.ts","names":[],"sources":["../src/checkbox.ts"],"mappings":";;;cAwCa,QAAA,SAAiB,UAAA;EAAA;SACrB,MAAA,gBAAM,SAAA;EAiKgB,OAAA;EACA,QAAA;EACA,aAAA;EACD,KAAA;EACA,IAAA;EACA,KAAA;EAanB,MAAA,CAAA,GAAU,UAAA,QAAkB,IAAA;AAAA;AAAA,KAoB3B,oBAAA;EAAA,SACD,OAAO;AAAA;AAAA,KAGN,mBAAA,GAAsB,WAAW,CAAC,oBAAA;AAAA,QAEtC,MAAA;EAAA,UACI,qBAAA;IACR,eAAA,EAAiB,QAAQ;EAAA;AAAA;AAAA,UAIZ,gBAAA;EACf,QAAA,EAAU,mBAAmB;AAAA;AAAA,UAGd,QAAA;EACf,gBAAA,iBAAiC,gBAAA,EAC/B,IAAA,EAAM,CAAA,EACN,QAAA,GAAW,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,gBAAA,CAAiB,CAAA,YACnD,OAAA,aAAoB,uBAAA;EAEtB,gBAAA,CACE,IAAA,UACA,QAAA,EAAU,kCAAA,EACV,OAAA,aAAoB,uBAAA;AAAA"}
1
+ {"version":3,"file":"checkbox.d.ts","names":[],"sources":["../src/checkbox.ts"],"mappings":";;;cAwCa,QAAA,SAAiB,UAAA;EAAA;SACrB,MAAA,gBAAM,SAAA;EAiKgB,OAAA;EACA,QAAA;EACA,aAAA;EACD,KAAA;EACA,IAAA;EACA,KAAA;EAanB,MAAA,CAAA,GAAU,UAAA,QAAkB,IAAA;AAAA;AAAA,KAoB3B,oBAAA;EAAA,SACD,OAAO;AAAA;AAAA,KAGN,mBAAA,GAAsB,WAAW,CAAC,oBAAA;AAAA,QAEtC,MAAA;EAAA,UACI,qBAAA;IACR,eAAA,EAAiB,QAAQ;EAAA;AAAA;AAAA,UAIZ,gBAAA;EACf,MAAA,EAAQ,mBAAmB;AAAA;AAAA,UAGZ,QAAA;EACf,gBAAA,oBAAoC,gBAAA,EAClC,IAAA,EAAM,CAAA,EACN,QAAA,GAAW,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,gBAAA,CAAiB,CAAA,YACnD,OAAA,aAAoB,uBAAA,eAEpB,IAAA,UACA,QAAA,EAAU,kCAAA,EACV,OAAA,aAAoB,uBAAA;AAAA"}
package/dist/checkbox.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as safeCustomElement, t as __decorate } from "./decorate-O4m1U4l3.js";
1
+ import { n as safeCustomElement, t as __decorate } from "./decorate-D7rC1gLP.js";
2
2
  import { LitElement, css, html } from "lit";
3
3
  import { property } from "lit/decorators.js";
4
4
  //#region src/checkbox.ts
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.js","names":["#handleChange","customElement"],"sources":["../src/checkbox.ts"],"sourcesContent":["/**\n * <x-checkbox> — Custom checkbox with diagonal line indicator.\n *\n * A brutalist checkbox component featuring a thick diagonal line\n * (top-left to bottom-right) when checked. Uses shadow DOM with\n * CSS variables for appearance customization.\n *\n * Properties\n * checked – checkbox state (default: false)\n * disabled – disabled state (default: false)\n * label – label text\n * name – form field name\n * value – form field value\n *\n * Events\n * change – CustomEvent { detail: { checked: boolean } }, bubbles + composed\n *\n * CSS Variables\n * --box-size – box size (default: 18px)\n * --box-border-width – border width (default: 2px)\n * --box-border-color – border color\n * --box-bg-unchecked – background when unchecked\n * --box-bg-checked – background when checked\n * --check-line-color – diagonal line color\n * --check-line-width – diagonal line thickness (default: 6px)\n * --box-opacity-unchecked – opacity when unchecked (default: 0.5)\n * --box-opacity-checked – opacity when checked (default: 1)\n * --box-opacity-hover – opacity on hover (default: 1)\n * --box-opacity-disabled – opacity when disabled (default: 0.3)\n * --box-label-gap – gap between box and label (default: 8px)\n * --label-font-size – label font size (default: 14px)\n * --label-opacity – label opacity (default: 1)\n * --label-opacity-unchecked – label opacity when unchecked (default: uses --label-opacity)\n * --transition-duration – animation duration (default: 0.2s)\n */\nimport { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from './util/custom-elements.js';\n\n@customElement(`ixfx-checkbox`)\nexport class Checkbox extends LitElement {\n static styles = css`\n :host {\n /* Box */\n --box-size: 18px;\n --box-border-color: var(--surface-4);\n --box-bg-unchecked: color-mix(in oklch, var(--surface-3) 50%, var(--surface-2));\n --box-bg-checked: color-mix(in oklch, var(--surface-3) 50%, var(--surface-2));\n --box-opacity-checked: 1;\n --box-opacity-hover: 1;\n --box-opacity-disabled: var(--disabled-opacity);\n --box-border-width: 2px;\n \n /* Check */\n --check-line-width: 6px;\n --check-line-color: var(--accent);\n\n /* Spacing & borders */\n --label-gap: var(--space-m);\n\n /* Label */\n --label-opacity: 1;\n --label-opacity-unchecked: var(--label-opacity);\n --label-fg: var(--surface-3-text);\n --label-active: var(--surface-2-text);\n --label-hover: var(--surface-2-text);\n\n /* Animation */\n --transition-duration: var(--transition);\n\n display: inline-flex;\n user-select: none;\n }\n\n label {\n display: inline-flex;\n align-items: center;\n gap: var(--label-gap);\n cursor: pointer;\n position: relative;\n opacity: var(--box-opacity-unchecked);\n transition: opacity var(--transition-duration);\n }\n\n label:hover {\n opacity: var(--box-opacity-hover);\n }\n\n label:has(input:checked) {\n opacity: var(--box-opacity-checked);\n }\n\n input {\n position: absolute;\n opacity: 0;\n width: 1px;\n height: 1px;\n margin: -1px;\n clip: rect(0, 0, 0, 0);\n }\n\n .box {\n position: relative;\n width: var(--box-size);\n height: var(--box-size);\n border: var(--border, 1px solid #999);\n background: var(--box-bg-unchecked);\n flex-shrink: 0;\n transition: background var(--transition-duration);\n overflow: hidden;\n box-shadow: inset 1px 1px 0px 1px color-mix(in oklch, var(--surface-2) 60%, transparent);\n }\n label:has(input:not(:disabled)) {\n .box:hover {\n background: color-mix(in oklch, var(--surface-4) 80%, transparent);\n border-color: var(--accent, #666);\n box-shadow: unset;\n }\n }\n\n input:checked ~ .box {\n background: var(--box-bg-checked);\n }\n\n /* Diagonal line from top-left to bottom-right */\n .box::after {\n content: '';\n position: absolute;\n width: 141.4%; /* sqrt(2) × 100% to span corner-to-corner */\n height: var(--check-line-width);\n background: var(--check-line-color);\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) rotate(45deg);\n opacity: 0;\n transition: opacity var(--transition-duration);\n }\n\n input:checked ~ .box::after {\n opacity: 1;\n }\n\n /* Horizontal line for indeterminate state */\n .box::before {\n content: '';\n position: absolute;\n width: 60%;\n height: var(--check-line-width);\n background: var(--check-line-color);\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n opacity: 0;\n transition: opacity var(--transition-duration);\n }\n\n input:indeterminate ~ .box::before {\n opacity: 1;\n }\n\n /* Hide diagonal checkmark when indeterminate (must come after checked rule) */\n input:indeterminate ~ .box::after {\n opacity: 0;\n }\n\n /* Focus state */\n input:focus-visible ~ .box {\n outline: 2px solid var(--check-line-color);\n outline-offset: 2px;\n }\n\n /* Disabled state */\n label:has(input:disabled) {\n opacity: var(--box-opacity-disabled);\n cursor: not-allowed;\n .box {\n box-shadow: unset;\n } \n }\n\n .label {\n color: var(--label-fg);\n opacity: var(--label-opacity);\n transition: opacity var(--transition-duration);\n user-select: none;\n -webkit-user-select: none;\n }\n\n .label:hover {\n color: var(--label-hover);\n }\n .label:has(+ :hover) {\n color: var(--label-fg-hover);\n }\n .label:has(+ :active) {\n color: var(--label-fg-active);\n }\n input:not(:checked) ~ .label {\n opacity: var(--label-opacity-unchecked);\n }\n `;\n\n @property({ type: Boolean }) checked = false;\n @property({ type: Boolean }) disabled = false;\n @property({ type: Boolean }) indeterminate = false;\n @property({ type: String }) label = ``;\n @property({ type: String }) name = ``;\n @property({ type: String }) value = ``;\n\n #handleChange = (e: Event): void => {\n const target = e.target as HTMLInputElement;\n this.checked = target.checked;\n\n this.dispatchEvent(new CustomEvent<CheckboxChangeDetail>(`change`, {\n detail: { checked: this.checked },\n bubbles: true,\n composed: true,\n }));\n };\n\n override render(): ReturnType<typeof html> {\n return html`\n <label>\n <input\n name=\"checkbox\"\n type=\"checkbox\"\n .checked=${this.checked}\n .disabled=${this.disabled}\n .indeterminate=${this.indeterminate}\n .name=${this.name}\n .value=${this.value}\n @change=${this.#handleChange}\n />\n <span class=\"box\"></span>\n ${this.label ? html`<span class=\"label\">${this.label}</span>` : ``}\n </label>\n `;\n }\n}\n\nexport type CheckboxChangeDetail = {\n readonly checked: boolean;\n};\n\nexport type CheckboxChangeEvent = CustomEvent<CheckboxChangeDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-checkbox': Checkbox;\n }\n}\n\nexport interface CheckboxEventMap {\n 'change': CheckboxChangeEvent;\n}\n\nexport interface Checkbox {\n addEventListener<K extends keyof CheckboxEventMap>(\n type: K,\n listener: (this: Checkbox, event: CheckboxEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions\n ): void;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCO,IAAA,WAAA,MAAM,iBAAiB,WAAW;;;iBAkKA;kBACC;uBACK;eACT;cACD;eACC;wBAEnB,MAAmB;GAClC,MAAM,SAAS,EAAE;GACjB,KAAK,UAAU,OAAO;GAEtB,KAAK,cAAc,IAAI,YAAkC,UAAU;IACjE,QAAQ,EAAE,SAAS,KAAK,QAAQ;IAChC,SAAS;IACT,UAAU;GACZ,CAAC,CAAC;EACJ;;;gBAjLgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwKnB;CAWA,SAA2C;EACzC,OAAO,IAAI;;;;;qBAKM,KAAK,QAAQ;sBACZ,KAAK,SAAS;2BACT,KAAK,cAAc;kBAC5B,KAAK,KAAK;mBACT,KAAK,MAAM;oBACV,KAAKA,cAAc;;;UAG7B,KAAK,QAAQ,IAAI,uBAAuB,KAAK,MAAM,WAAW,GAAG;;;CAGzE;AACF;YApCG,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,SAAA,WAAA,WAAA,KAAA,CAAA;YAC1B,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,SAAA,WAAA,YAAA,KAAA,CAAA;YAC1B,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,SAAA,WAAA,iBAAA,KAAA,CAAA;YAC1B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,SAAA,WAAA,SAAA,KAAA,CAAA;YACzB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,SAAA,WAAA,QAAA,KAAA,CAAA;YACzB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,SAAA,WAAA,SAAA,KAAA,CAAA;uBAxK3BC,kBAAc,eAAe,CAAA,GAAA,QAAA"}
1
+ {"version":3,"file":"checkbox.js","names":["#handleChange","customElement"],"sources":["../src/checkbox.ts"],"sourcesContent":["/**\n * <x-checkbox> — Custom checkbox with diagonal line indicator.\n *\n * A brutalist checkbox component featuring a thick diagonal line\n * (top-left to bottom-right) when checked. Uses shadow DOM with\n * CSS variables for appearance customization.\n *\n * Properties\n * checked – checkbox state (default: false)\n * disabled – disabled state (default: false)\n * label – label text\n * name – form field name\n * value – form field value\n *\n * Events\n * change – CustomEvent { detail: { checked: boolean } }, bubbles + composed\n *\n * CSS Variables\n * --box-size – box size (default: 18px)\n * --box-border-width – border width (default: 2px)\n * --box-border-color – border color\n * --box-bg-unchecked – background when unchecked\n * --box-bg-checked – background when checked\n * --check-line-color – diagonal line color\n * --check-line-width – diagonal line thickness (default: 6px)\n * --box-opacity-unchecked – opacity when unchecked (default: 0.5)\n * --box-opacity-checked – opacity when checked (default: 1)\n * --box-opacity-hover – opacity on hover (default: 1)\n * --box-opacity-disabled – opacity when disabled (default: 0.3)\n * --box-label-gap – gap between box and label (default: 8px)\n * --label-font-size – label font size (default: 14px)\n * --label-opacity – label opacity (default: 1)\n * --label-opacity-unchecked – label opacity when unchecked (default: uses --label-opacity)\n * --transition-duration – animation duration (default: 0.2s)\n */\nimport { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from './util/custom-elements.js';\n\n@customElement(`ixfx-checkbox`)\nexport class Checkbox extends LitElement {\n static styles = css`\n :host {\n /* Box */\n --box-size: 18px;\n --box-border-color: var(--surface-4);\n --box-bg-unchecked: color-mix(in oklch, var(--surface-3) 50%, var(--surface-2));\n --box-bg-checked: color-mix(in oklch, var(--surface-3) 50%, var(--surface-2));\n --box-opacity-checked: 1;\n --box-opacity-hover: 1;\n --box-opacity-disabled: var(--disabled-opacity);\n --box-border-width: 2px;\n \n /* Check */\n --check-line-width: 6px;\n --check-line-color: var(--accent);\n\n /* Spacing & borders */\n --label-gap: var(--space-m);\n\n /* Label */\n --label-opacity: 1;\n --label-opacity-unchecked: var(--label-opacity);\n --label-fg: var(--surface-3-text);\n --label-active: var(--surface-2-text);\n --label-hover: var(--surface-2-text);\n\n /* Animation */\n --transition-duration: var(--transition);\n\n display: inline-flex;\n user-select: none;\n }\n\n label {\n display: inline-flex;\n align-items: center;\n gap: var(--label-gap);\n cursor: pointer;\n position: relative;\n opacity: var(--box-opacity-unchecked);\n transition: opacity var(--transition-duration);\n }\n\n label:hover {\n opacity: var(--box-opacity-hover);\n }\n\n label:has(input:checked) {\n opacity: var(--box-opacity-checked);\n }\n\n input {\n position: absolute;\n opacity: 0;\n width: 1px;\n height: 1px;\n margin: -1px;\n clip: rect(0, 0, 0, 0);\n }\n\n .box {\n position: relative;\n width: var(--box-size);\n height: var(--box-size);\n border: var(--border, 1px solid #999);\n background: var(--box-bg-unchecked);\n flex-shrink: 0;\n transition: background var(--transition-duration);\n overflow: hidden;\n box-shadow: inset 1px 1px 0px 1px color-mix(in oklch, var(--surface-2) 60%, transparent);\n }\n label:has(input:not(:disabled)) {\n .box:hover {\n background: color-mix(in oklch, var(--surface-4) 80%, transparent);\n border-color: var(--accent, #666);\n box-shadow: unset;\n }\n }\n\n input:checked ~ .box {\n background: var(--box-bg-checked);\n }\n\n /* Diagonal line from top-left to bottom-right */\n .box::after {\n content: '';\n position: absolute;\n width: 141.4%; /* sqrt(2) × 100% to span corner-to-corner */\n height: var(--check-line-width);\n background: var(--check-line-color);\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) rotate(45deg);\n opacity: 0;\n transition: opacity var(--transition-duration);\n }\n\n input:checked ~ .box::after {\n opacity: 1;\n }\n\n /* Horizontal line for indeterminate state */\n .box::before {\n content: '';\n position: absolute;\n width: 60%;\n height: var(--check-line-width);\n background: var(--check-line-color);\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n opacity: 0;\n transition: opacity var(--transition-duration);\n }\n\n input:indeterminate ~ .box::before {\n opacity: 1;\n }\n\n /* Hide diagonal checkmark when indeterminate (must come after checked rule) */\n input:indeterminate ~ .box::after {\n opacity: 0;\n }\n\n /* Focus state */\n input:focus-visible ~ .box {\n outline: 2px solid var(--check-line-color);\n outline-offset: 2px;\n }\n\n /* Disabled state */\n label:has(input:disabled) {\n opacity: var(--box-opacity-disabled);\n cursor: not-allowed;\n .box {\n box-shadow: unset;\n } \n }\n\n .label {\n color: var(--label-fg);\n opacity: var(--label-opacity);\n transition: opacity var(--transition-duration);\n user-select: none;\n -webkit-user-select: none;\n }\n\n .label:hover {\n color: var(--label-hover);\n }\n .label:has(+ :hover) {\n color: var(--label-fg-hover);\n }\n .label:has(+ :active) {\n color: var(--label-fg-active);\n }\n input:not(:checked) ~ .label {\n opacity: var(--label-opacity-unchecked);\n }\n `;\n\n @property({ type: Boolean }) checked = false;\n @property({ type: Boolean }) disabled = false;\n @property({ type: Boolean }) indeterminate = false;\n @property({ type: String }) label = ``;\n @property({ type: String }) name = ``;\n @property({ type: String }) value = ``;\n\n #handleChange = (e: Event): void => {\n const target = e.target as HTMLInputElement;\n this.checked = target.checked;\n\n this.dispatchEvent(new CustomEvent<CheckboxChangeDetail>(`change`, {\n detail: { checked: this.checked },\n bubbles: true,\n composed: true,\n }));\n };\n\n override render(): ReturnType<typeof html> {\n return html`\n <label>\n <input\n name=\"checkbox\"\n type=\"checkbox\"\n .checked=${this.checked}\n .disabled=${this.disabled}\n .indeterminate=${this.indeterminate}\n .name=${this.name}\n .value=${this.value}\n @change=${this.#handleChange}\n />\n <span class=\"box\"></span>\n ${this.label ? html`<span class=\"label\">${this.label}</span>` : ``}\n </label>\n `;\n }\n}\n\nexport type CheckboxChangeDetail = {\n readonly checked: boolean;\n};\n\nexport type CheckboxChangeEvent = CustomEvent<CheckboxChangeDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-checkbox': Checkbox;\n }\n}\n\nexport interface CheckboxEventMap {\n change: CheckboxChangeEvent;\n}\n\nexport interface Checkbox {\n addEventListener: (<K extends keyof CheckboxEventMap>(\n type: K,\n listener: (this: Checkbox, event: CheckboxEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCO,IAAA,WAAA,MAAM,iBAAiB,WAAW;;;iBAkKA;kBACC;uBACK;eACT;cACD;eACC;wBAEnB,MAAmB;GAClC,MAAM,SAAS,EAAE;GACjB,KAAK,UAAU,OAAO;GAEtB,KAAK,cAAc,IAAI,YAAkC,UAAU;IACjE,QAAQ,EAAE,SAAS,KAAK,QAAQ;IAChC,SAAS;IACT,UAAU;GACZ,CAAC,CAAC;EACJ;;;gBAjLgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwKnB;CAWA,SAA2C;EACzC,OAAO,IAAI;;;;;qBAKM,KAAK,QAAQ;sBACZ,KAAK,SAAS;2BACT,KAAK,cAAc;kBAC5B,KAAK,KAAK;mBACT,KAAK,MAAM;oBACV,KAAKA,cAAc;;;UAG7B,KAAK,QAAQ,IAAI,uBAAuB,KAAK,MAAM,WAAW,GAAG;;;CAGzE;AACF;YApCG,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,SAAA,WAAA,WAAA,KAAA,CAAA;YAC1B,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,SAAA,WAAA,YAAA,KAAA,CAAA;YAC1B,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,SAAA,WAAA,iBAAA,KAAA,CAAA;YAC1B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,SAAA,WAAA,SAAA,KAAA,CAAA;YACzB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,SAAA,WAAA,QAAA,KAAA,CAAA;YACzB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,SAAA,WAAA,SAAA,KAAA,CAAA;uBAxK3BC,kBAAc,eAAe,CAAA,GAAA,QAAA"}
@@ -1,4 +1,4 @@
1
- import { C as resultThrow, S as percentTest, a as movingAverageLight, b as numberInclusiveRangeTest, g as errorResult, i as interpolate, m as pairwise, t as clamp, u as scaleClamped, x as numberTest } from "./dist-D7kJgnSE.js";
1
+ import { C as resultThrow, S as percentTest, a as movingAverageLight, b as numberInclusiveRangeTest, g as errorResult, i as interpolate, m as pairwise, t as clamp, u as scaleClamped, x as numberTest } from "./dist-TAGYwaju.js";
2
2
  //#region node_modules/.pnpm/@ixfx+visual@0.56.12/node_modules/@ixfx/visual/dist/chunk-pbuEa-1d.js
3
3
  var __defProp$2 = Object.defineProperty;
4
4
  var __exportAll$1 = (all, no_symbols) => {
@@ -4135,4 +4135,4 @@ var colour_exports = /* @__PURE__ */ __exportAll$1({
4135
4135
  //#endregion
4136
4136
  export { isPoint3d as A, guard$5 as C, isNull as D, isNaN as E, __exportAll as M, isPlaceholder as O, toString as S, isEmpty as T, getTwoPointParameters as _, Unit3d as a, to3d as b, angleRadianThreePoint as c, fromCartesian as d, rotate$1 as f, getPointParameter as g, distance2d as h, Unit as i, test as j, isPoint as k, average$1 as l, distance as m, Empty as n, angleRadian as o, toCartesian$1 as p, Empty3d as r, angleRadianCircle as s, colour_exports as t, averager as u, subtract as v, guardNonZeroPoint as w, toIntegerValues as x, to2d as y };
4137
4137
 
4138
- //# sourceMappingURL=colour-C3MQIjFJ-BJV-QC-3.js.map
4138
+ //# sourceMappingURL=colour-C3MQIjFJ-BLXg8W3U.js.map