@ixfx/components 0.12.0 → 0.13.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.
- package/bundle/index.d.ts +124 -1
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +7061 -6522
- package/bundle/index.js.map +1 -1
- package/dist/ac-text.d.ts +1 -1
- package/dist/ac-text.js +1 -1
- package/dist/{ac-token--_vCHXWw.d.ts → ac-token-TCLAZeVg.d.ts} +2 -2
- package/dist/{ac-token--_vCHXWw.d.ts.map → ac-token-TCLAZeVg.d.ts.map} +1 -1
- package/dist/ac-token.d.ts +1 -1
- package/dist/ac-token.js +1 -1
- package/dist/{checked-select-Dejl13qd.js → checked-select-lDgAQQ7v.js} +3 -3
- package/dist/{checked-select-Dejl13qd.js.map → checked-select-lDgAQQ7v.js.map} +1 -1
- package/dist/checked-select.js +1 -1
- package/dist/colour-picker.d.ts +1 -1
- package/dist/crumbs.d.ts +2 -2
- package/dist/crumbs.d.ts.map +1 -1
- package/dist/crumbs.js +26 -10
- package/dist/crumbs.js.map +1 -1
- package/dist/{data-grid-Cl_CPSD7.d.ts → data-grid-BJ6XXvRc.d.ts} +4 -4
- package/dist/{data-grid-Cl_CPSD7.d.ts.map → data-grid-BJ6XXvRc.d.ts.map} +1 -1
- package/dist/data-grid.d.ts +1 -1
- package/dist/data-grid.js +3 -3
- package/dist/{detail-list-lE_5UWVl.d.ts → detail-list-B0waVNeS.d.ts} +4 -4
- package/dist/{detail-list-lE_5UWVl.d.ts.map → detail-list-B0waVNeS.d.ts.map} +1 -1
- package/dist/detail-list.d.ts +2 -2
- package/dist/detail-list.js +1 -1
- package/dist/flat-list-eYItri8-.d.ts +126 -0
- package/dist/flat-list-eYItri8-.d.ts.map +1 -0
- package/dist/flat-list.d.ts +2 -0
- package/dist/flat-list.js +519 -0
- package/dist/flat-list.js.map +1 -0
- package/dist/{grid-list-Bwaf61is.js → grid-list-DjIl910A.js} +3 -3
- package/dist/{grid-list-Bwaf61is.js.map → grid-list-DjIl910A.js.map} +1 -1
- package/dist/{grid-list-Bc-RkDoO.d.ts → grid-list-_gI9ckcT.d.ts} +3 -3
- package/dist/{grid-list-Bc-RkDoO.d.ts.map → grid-list-_gI9ckcT.d.ts.map} +1 -1
- package/dist/grid-list.d.ts +1 -1
- package/dist/grid-list.js +1 -1
- package/dist/{grouped-item-lister-DETte0Dh.d.ts → grouped-item-lister-Bhyo-dkH.d.ts} +2 -2
- package/dist/{grouped-item-lister-DETte0Dh.d.ts.map → grouped-item-lister-Bhyo-dkH.d.ts.map} +1 -1
- package/dist/grouped-item-lister.d.ts +1 -1
- package/dist/{icon-CDGprSdE.d.ts → icon-DR_3rSyZ.d.ts} +2 -2
- package/dist/icon-DR_3rSyZ.d.ts.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/incr-search.d.ts +1 -1
- package/dist/{index-tq6f8007.d.ts → index-BOUaDIW-.d.ts} +2 -2
- package/dist/{index-tq6f8007.d.ts.map → index-BOUaDIW-.d.ts.map} +1 -1
- package/dist/{index-CoqtMSd9.d.ts → index-BUB5SICW.d.ts} +2 -2
- package/dist/{index-CoqtMSd9.d.ts.map → index-BUB5SICW.d.ts.map} +1 -1
- package/dist/{index-CMsmZ6Or.d.ts → index-BvxHQUME.d.ts} +2 -2
- package/dist/{index-CMsmZ6Or.d.ts.map → index-BvxHQUME.d.ts.map} +1 -1
- package/dist/{index-UvnoZUAo.d.ts → index-CJ5fshD3.d.ts} +2 -2
- package/dist/{index-UvnoZUAo.d.ts.map → index-CJ5fshD3.d.ts.map} +1 -1
- package/dist/{index-CSEtqm1T.d.ts → index-CW2QL33o.d.ts} +3 -3
- package/dist/{index-CSEtqm1T.d.ts.map → index-CW2QL33o.d.ts.map} +1 -1
- package/dist/{index-CYndvTWH.d.ts → index-garxxqgV.d.ts} +2 -2
- package/dist/{index-CYndvTWH.d.ts.map → index-garxxqgV.d.ts.map} +1 -1
- package/dist/index-o-CWDt11.d.ts +78 -0
- package/dist/index-o-CWDt11.d.ts.map +1 -0
- package/dist/index.d.ts +21 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/{interaction-BskmlA9t.js → interaction-ZTh4htzr.js} +1 -1
- package/dist/{labelled-input-base-DiTme1JO.d.ts → labelled-input-base-Dp_9KP0G.d.ts} +2 -2
- package/dist/{labelled-input-base-DiTme1JO.d.ts.map → labelled-input-base-Dp_9KP0G.d.ts.map} +1 -1
- package/dist/labelled-radial-input.d.ts +2 -2
- package/dist/labelled-radial-input.d.ts.map +1 -1
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/labelled-slider-input.d.ts +1 -1
- package/dist/list-group-header.d.ts +1 -1
- package/dist/{menu-DaAlsyhf.js → menu-CwcXXeLM.js} +3 -3
- package/dist/{menu-DaAlsyhf.js.map → menu-CwcXXeLM.js.map} +1 -1
- package/dist/{menu-item-bF6narIz.d.ts → menu-item-B0zqw2xp.d.ts} +2 -2
- package/dist/{menu-item-bF6narIz.d.ts.map → menu-item-B0zqw2xp.d.ts.map} +1 -1
- package/dist/{menu-item-CDPFgaSF.js → menu-item-BDEekBVy.js} +3 -3
- package/dist/{menu-item-CDPFgaSF.js.map → menu-item-BDEekBVy.js.map} +1 -1
- package/dist/menu.d.ts +2 -2
- package/dist/menu.js +2 -2
- package/dist/miller.d.ts +2 -2
- package/dist/miller.js +2 -2
- package/dist/narrowed-text.d.ts +2 -78
- package/dist/narrowed-text.js +2 -2
- package/dist/panel.d.ts +1 -1
- package/dist/select-horiz.js +2 -2
- package/dist/{split-layout-JK3xWVX2.d.ts → split-layout-C5SYbDrq.d.ts} +2 -2
- package/dist/{split-layout-JK3xWVX2.d.ts.map → split-layout-C5SYbDrq.d.ts.map} +1 -1
- package/dist/split-layout.d.ts +1 -1
- package/dist/{tab-list-pqfKaVAE.d.ts → tab-list-v8mKX7Fu.d.ts} +2 -2
- package/dist/{tab-list-pqfKaVAE.d.ts.map → tab-list-v8mKX7Fu.d.ts.map} +1 -1
- package/dist/tabs.d.ts +1 -1
- package/dist/{tickled-controller-Dh1Uh_vG.js → tickled-controller-D-HZymaZ.js} +10 -1
- package/dist/tickled-controller-D-HZymaZ.js.map +1 -0
- package/dist/{tickled-controller-C1ZsHpyg.d.ts → tickled-controller-DodxD3eQ.d.ts} +7 -1
- package/dist/{tickled-controller-C1ZsHpyg.d.ts.map → tickled-controller-DodxD3eQ.d.ts.map} +1 -1
- package/dist/{titlebar-Tqu-VvMU.d.ts → titlebar-B5zSTZnF.d.ts} +2 -2
- package/dist/{titlebar-Tqu-VvMU.d.ts.map → titlebar-B5zSTZnF.d.ts.map} +1 -1
- package/dist/titlebar.d.ts +1 -1
- package/dist/{tree-Bm2TzTfe.js → tree-DGveys4K.js} +3 -3
- package/dist/{tree-Bm2TzTfe.js.map → tree-DGveys4K.js.map} +1 -1
- package/dist/tree.d.ts +2 -2
- package/dist/tree.js +1 -1
- package/dist/{vertical-list-DTp-UIUE.d.ts → vertical-list-DheZSEmB.d.ts} +2 -2
- package/dist/{vertical-list-DTp-UIUE.d.ts.map → vertical-list-DheZSEmB.d.ts.map} +1 -1
- package/dist/vertical-list.d.ts +1 -1
- package/dist/vertical-list.js +9 -1
- package/dist/vertical-list.js.map +1 -1
- package/docs-user/README.md +1 -0
- package/docs-user/flat-list.md +80 -0
- package/docs-user/index.json +7 -2
- package/docs-user/llms.txt +1 -0
- package/llms.txt +1 -0
- package/package.json +5 -1
- package/dist/icon-CDGprSdE.d.ts.map +0 -1
- package/dist/narrowed-text.d.ts.map +0 -1
- package/dist/tickled-controller-Dh1Uh_vG.js.map +0 -1
package/dist/ac-text.d.ts
CHANGED
package/dist/ac-text.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as clearHighlights, t as applyHighlights } from "./highlight-B-eQrhhb.js";
|
|
2
|
-
import { t as TickledController } from "./tickled-controller-
|
|
2
|
+
import { t as TickledController } from "./tickled-controller-D-HZymaZ.js";
|
|
3
3
|
import { n as tickledStyles } from "./tickled-styles-BrAHEj1q.js";
|
|
4
4
|
import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
|
|
5
5
|
import { t as popupSurfaceStyles } from "./popup-D80sj2QC.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./icon-
|
|
1
|
+
import "./icon-DR_3rSyZ.js";
|
|
2
2
|
import { r as IDataProvider } from "./data-provider-BAn_-oR1.js";
|
|
3
3
|
import { LitElement, PropertyValues } from "lit";
|
|
4
4
|
//#region src/ac-token/types.d.ts
|
|
@@ -104,4 +104,4 @@ interface AcTokenElement {
|
|
|
104
104
|
}
|
|
105
105
|
//#endregion
|
|
106
106
|
export { AcTokenItem as a, AcTokenizerFn as c, AcTokenElementEventMap as i, AcTokensChangeDetail as l, AcTokenAddDetail as n, AcTokenRemoveDetail as o, AcTokenAddEvent as r, AcTokenRemoveEvent as s, AcTokenElement as t, AcTokensChangeEvent as u };
|
|
107
|
-
//# sourceMappingURL=ac-token
|
|
107
|
+
//# sourceMappingURL=ac-token-TCLAZeVg.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ac-token
|
|
1
|
+
{"version":3,"file":"ac-token-TCLAZeVg.d.ts","names":[],"sources":["../src/ac-token/types.ts","../src/ac-token/ac-token.ts"],"mappings":";;;;KAAY;WACD;WACA;WACA;WACA;WACA;WACA,YAAY;;KAGX,iBAAiB;KAEjB;WACD,iBAAiB;;KAEhB,sBAAsB,YAAY;KAElC;WACD,MAAM;WACN;;KAEC,kBAAkB,YAAY;KAE9B;WACD,MAAM;WACN;;KAEC,qBAAqB,YAAY;UAE5B;EACf,mBAAmB;EACnB,gBAAgB;EAChB,mBAAmB;;;;;;;;;;;;;;;;;;;;cCgDR,uBAAuB;;;EAGlC,oBAAoB,sBAAsB;;EAI1C,WAAW;;EAIX;;EAIA;;EAIA;;;;;EAOA;;;;;;EAQA;UAEiB;UACA;UACA;UACA;UAET;;MAqBJ,mBAAmB;MAInB,OAAO,gBAAgB;;;;;;;EAW3B,UAAU,gBAAgB;;MAKtB;EAMK;EAKA;YASU,QAAQ,cAAc;YA6btB,wBAAM;SA+BT,sBAAM;;QAkLhB;YACI;IACR,iBAAiB;;;UAIJ;EACf,oBAAoB,gBAAgB,wBAClC,MAAM,GACN,WAAW,MAAM,gBAAgB,OAAO,uBAAuB,aAC/D,oBAAoB,sCAEpB,cACA,UAAU,oCACV,oBAAoB"}
|
package/dist/ac-token.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as AcTokenItem, c as AcTokenizerFn, i as AcTokenElementEventMap, l as AcTokensChangeDetail, n as AcTokenAddDetail, o as AcTokenRemoveDetail, r as AcTokenAddEvent, s as AcTokenRemoveEvent, t as AcTokenElement, u as AcTokensChangeEvent } from "./ac-token
|
|
1
|
+
import { a as AcTokenItem, c as AcTokenizerFn, i as AcTokenElementEventMap, l as AcTokensChangeDetail, n as AcTokenAddDetail, o as AcTokenRemoveDetail, r as AcTokenAddEvent, s as AcTokenRemoveEvent, t as AcTokenElement, u as AcTokensChangeEvent } from "./ac-token-TCLAZeVg.js";
|
|
2
2
|
export { type AcTokenAddDetail, type AcTokenAddEvent, AcTokenElement, type AcTokenElementEventMap, type AcTokenItem, type AcTokenRemoveDetail, type AcTokenRemoveEvent, type AcTokenizerFn, type AcTokensChangeDetail, type AcTokensChangeEvent };
|
package/dist/ac-token.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as TickledController } from "./tickled-controller-
|
|
1
|
+
import { t as TickledController } from "./tickled-controller-D-HZymaZ.js";
|
|
2
2
|
import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrAHEj1q.js";
|
|
3
3
|
import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
|
|
4
4
|
import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { t as TickledController } from "./tickled-controller-
|
|
1
|
+
import { t as TickledController } from "./tickled-controller-D-HZymaZ.js";
|
|
2
2
|
import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrAHEj1q.js";
|
|
3
3
|
import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
|
|
4
4
|
import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
|
|
5
5
|
import { t as handleStyles } from "./handle-DAXs7kbJ.js";
|
|
6
|
-
import "./interaction-
|
|
6
|
+
import "./interaction-ZTh4htzr.js";
|
|
7
7
|
import "./checkbox.js";
|
|
8
8
|
import { LitElement, css, html, nothing } from "lit";
|
|
9
9
|
import { property, state } from "lit/decorators.js";
|
|
@@ -601,4 +601,4 @@ CheckedSelect = __decorate([safeCustomElement(`ixfx-checked-select`)], CheckedSe
|
|
|
601
601
|
//#endregion
|
|
602
602
|
export { CheckedSelect as t };
|
|
603
603
|
|
|
604
|
-
//# sourceMappingURL=checked-select-
|
|
604
|
+
//# sourceMappingURL=checked-select-lDgAQQ7v.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checked-select-Dejl13qd.js","names":["#emitChange","#focusRestCheckbox","#popup","#trigger","#rows","#tickled","#scrollToCursor","#toggleRow","#listbox","#anchorName","#onDocumentPointerDown","#close","#onRestCheckboxChange","#onRowClick","#onTriggerClick","#onTriggerKeyDown","#renderRest","#onListKeyDown","#renderRow","#onResizeDown","customElement"],"sources":["../src/checked-select/logic.ts","../src/checked-select/checked-select.ts"],"sourcesContent":["import type { CheckedSelectItem, CheckState, Size } from './types.js';\n\nfunction byLabel(a: CheckedSelectItem, b: CheckedSelectItem): number {\n return a.label.localeCompare(b.label, undefined, { sensitivity: `base` });\n}\n\n/** Checked/indeterminate items first, then the rest; each group sorted by label. */\nexport function sortForOpen(items: readonly CheckedSelectItem[]): CheckedSelectItem[] {\n const on = items.filter(i => i.checked !== `false`).toSorted(byLabel);\n const off = items.filter(i => i.checked === `false`).toSorted(byLabel);\n return [...on, ...off];\n}\n\n/** User toggle: indeterminate and unchecked become checked, checked becomes unchecked. */\nexport function toggleState(state: CheckState): CheckState {\n return state === `true` ? `false` : `true`;\n}\n\n/** Items shown in the resting state, alphabetically. */\nexport function visibleAtRest(items: readonly CheckedSelectItem[]): CheckedSelectItem[] {\n return items.filter(i => i.checked !== `false`).toSorted(byLabel);\n}\n\nexport const VARIES_LABEL = `(varies)`;\n\n/** Resting text entries: checked labels, then a single `(varies)` if any are indeterminate. */\nexport function restTextParts(items: readonly CheckedSelectItem[]): string[] {\n const on = items.filter(i => i.checked === `true`).toSorted(byLabel).map(i => i.label);\n const varies = items.some(i => i.checked === `indeterminate`) ? [VARIES_LABEL] : [];\n return [...on, ...varies];\n}\n\n/** Plain-text resting summary, comma separated. */\nexport function restText(items: readonly CheckedSelectItem[]): string {\n return restTextParts(items).join(`, `);\n}\n\n/** Returns a new list with the item matching `value` toggled. */\nexport function applyToggle(items: readonly CheckedSelectItem[], value: string): CheckedSelectItem[] {\n return items.map(i => i.value === value ? { ...i, checked: toggleState(i.checked) } : i);\n}\n\n/**\n * Index of the next label after `current` beginning with `char` (case-insensitive),\n * wrapping around. Returns -1 if nothing matches.\n */\nexport function nextMatchIndex(labels: readonly string[], current: number, char: string): number {\n const c = char.toLocaleLowerCase();\n const count = labels.length;\n for (let step = 1; step <= count; step++) {\n const index = (current + step + count) % count;\n if (labels[index].toLocaleLowerCase().startsWith(c))\n return index;\n }\n return -1;\n}\n\n/** Items in `draft` whose state differs from `original`. */\nexport function diffItems(original: readonly CheckedSelectItem[], draft: readonly CheckedSelectItem[]): CheckedSelectItem[] {\n const before = new Map(original.map(i => [i.value, i.checked]));\n return draft.filter(i => before.get(i.value) !== i.checked);\n}\n\nexport function clampSize(size: Size, min: Size, max: Size): Size {\n return {\n width: Math.min(Math.max(size.width, min.width), Math.max(max.width, min.width)),\n height: Math.min(Math.max(size.height, min.height), Math.max(max.height, min.height)),\n };\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\n/**\n * <ixfx-checked-select> — a SELECT-like multi-choice control with tri-state items.\n *\n * At rest it shows the checked and indeterminate items as a flow of display-only\n * `ixfx-checkbox`. Opening it shows a scrollable, resizable popup of every item\n * (checked first, sorted once at open time). Edits are made to a draft:\n * Enter (or clicking the resting area again) commits, Escape or clicking outside\n * cancels.\n *\n * Properties\n * items – CheckedSelectItem[] ({ value, label, checked: 'true'|'false'|'indeterminate' })\n * multiline – let the resting flow wrap (default: false)\n * items-inert – resting checkboxes are display-only; clicking them opens the popup\n * orientation – 'horizontal' (default) flows items in a row; 'vertical' stacks one per row\n * (vertical ignores multiline; text mode then lists one entry per line, no commas)\n * item-display – 'checkbox' (default) or 'text' (comma-separated labels, then '(varies)' if any are indeterminate)\n * placeholder – shown when nothing is checked\n * disabled – prevents opening\n *\n * Events\n * change – CustomEvent { detail: { items, changed } }, bubbles + composed.\n * Fired once per commit, and only if something changed.\n *\n * CSS Variables\n * --checked-select-gap – gap between resting checkboxes\n * --checked-select-padding – padding of the resting area\n * --checked-select-caret-width – width of the always-visible caret (default: 2rem)\n * --checked-select-rest-max-height – resting height before it scrolls when multiline (default: 8rem)\n * --checked-select-max-height – popup height before it scrolls (default: 16rem)\n * --checked-select-min-width – minimum popup width when resized (default: 8rem)\n * --checked-select-min-height – minimum popup height when resized (default: 5rem)\n */\nimport type { PropertyValues } from 'lit';\nimport type { CheckedSelectItem, ItemDisplay, ItemOrientation, Size } from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { TickledController, tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { handleStyles } from '../styles/handle.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { applyToggle, clampSize, diffItems, nextMatchIndex, restText, restTextParts, sortForOpen, visibleAtRest } from './logic.js';\nimport '../checkbox/checkbox.js';\n\nexport type { CheckedSelectItem, CheckState, ItemDisplay, ItemOrientation } from './types.js';\n\nlet instanceCounter = 0;\n\n@customElement(`ixfx-checked-select`)\nexport class CheckedSelect extends LitElement {\n static override styles = [themeFallbacks, handleStyles, tickledStyles, tickledItemStyles, css`\n :host {\n --checked-select-gap: var(--space-m);\n --checked-select-padding: var(--space-s) var(--space-m);\n --checked-select-caret-width: 2rem;\n --checked-select-rest-max-height: 8rem;\n --checked-select-max-height: 16rem;\n --checked-select-min-width: 8rem;\n --checked-select-min-height: 5rem;\n\n display: block;\n position: relative;\n }\n\n :host([disabled]) {\n opacity: var(--prominence-disabled-opacity, 0.4);\n pointer-events: none;\n }\n\n .rest {\n position: relative;\n box-sizing: border-box;\n cursor: pointer;\n background: var(--surface-4);\n color: var(--surface-4-text);\n border: var(--border);\n border-radius: var(--radius-m);\n user-select: none;\n }\n\n .rest-items {\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n gap: var(--checked-select-gap);\n padding: var(--checked-select-padding);\n /* Room to scroll the last item clear of the caret */\n padding-inline-end: var(--checked-select-caret-width);\n min-height: 1.5em;\n box-sizing: border-box;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: thin;\n }\n :host([multiline]) .rest-items {\n flex-wrap: wrap;\n overflow-x: hidden;\n overflow-y: auto;\n max-height: var(--checked-select-rest-max-height);\n /* Wrapping never runs under the caret, so keep its column clear (and the scrollbar beside it) */\n padding-inline-end: var(--space-m);\n margin-inline-end: var(--checked-select-caret-width);\n }\n\n /* Vertical: one item per row, scrolling vertically beside the caret. Must follow the multiline rule. */\n :host([orientation=\"vertical\"]) .rest-items {\n flex-direction: column;\n flex-wrap: nowrap;\n align-items: flex-start;\n overflow-x: hidden;\n overflow-y: auto;\n max-height: var(--checked-select-rest-max-height);\n padding-inline-end: var(--space-m);\n margin-inline-end: var(--checked-select-caret-width);\n }\n\n /* Always-visible caret; items scroll underneath it */\n .caret {\n position: absolute;\n inset-block: 0;\n inset-inline-end: 0;\n width: var(--checked-select-caret-width);\n display: grid;\n place-items: center;\n background: inherit;\n border-radius: inherit;\n pointer-events: auto;\n }\n .caret svg {\n width: 1.1em;\n height: 1.1em;\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n transition: rotate var(--transition, 0.1s ease-out);\n }\n .rest[aria-expanded=\"true\"] .caret svg {\n rotate: 180deg;\n }\n /* While the popup is open its draft is authoritative */\n .rest[aria-expanded=\"true\"] ixfx-checkbox {\n pointer-events: none;\n }\n .rest:hover {\n background: var(--surface-5);\n }\n .rest:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n .rest ixfx-checkbox {\n flex-shrink: 0;\n }\n .rest-text {\n white-space: nowrap;\n }\n :host([multiline]) .rest-text {\n white-space: normal;\n }\n .placeholder {\n opacity: 0.6;\n }\n\n .popup {\n /* Reset popover UA styles */\n inset: unset;\n margin: 0;\n padding: 0;\n border: none;\n background: transparent;\n overflow: visible;\n\n /* CSS anchor positioning — position-anchor set inline */\n position: fixed;\n left: anchor(left);\n top: anchor(bottom);\n /* anchor-size() only works on the anchored element itself, so the width lives here */\n width: anchor-size(width);\n min-width: var(--checked-select-min-width);\n position-try-fallbacks: flip-block;\n margin-block: 4px;\n z-index: 100;\n }\n\n .frame {\n position: relative;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n width: 100%;\n max-height: var(--checked-select-max-height);\n background: var(--surface-3);\n color: var(--surface-3-text);\n border: var(--border);\n border-radius: var(--radius-m);\n }\n\n .listbox {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: var(--space-s);\n outline: none;\n }\n .listbox:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: -2px;\n }\n\n .item {\n display: flex;\n width: 100%;\n box-sizing: border-box;\n }\n\n /* Key-repeat outpaces the fade, smearing the cursor across rows. Snap while\n the keyboard drives the cursor; hover (mouse mode) keeps the transition. */\n .listbox[data-input-mode=\"keyboard\"] .item {\n transition: none;\n }\n\n .resize-zone {\n position: absolute;\n inset-block-end: 0;\n inset-inline-end: 0;\n width: 16px;\n height: 16px;\n display: grid;\n place-items: center;\n cursor: nwse-resize;\n touch-action: none;\n }\n .resize-zone .ixfx-handle {\n --ixfx-handle-spot-size: 10px;\n }\n `];\n\n @property({ type: Array }) items: readonly CheckedSelectItem[] = [];\n @property({ type: Boolean, reflect: true }) multiline = false;\n /** At-rest checkboxes are display-only; clicking them just opens the popup. (Not `inert`: that native attribute would block the whole element.) */\n @property({ type: Boolean, attribute: `items-inert`, reflect: true }) itemsInert = false;\n /** How at-rest items are shown: as `checkbox`es, or as comma-separated `text`. */\n @property({ type: String, attribute: `item-display`, reflect: true }) itemDisplay: ItemDisplay = `checkbox`;\n /** Direction the resting items flow: `horizontal` (default) or `vertical` (one per row). */\n @property({ type: String, reflect: true }) orientation: ItemOrientation = `horizontal`;\n @property({ type: String }) placeholder = ``;\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n @state() private _open = false;\n @state() private _draft: readonly CheckedSelectItem[] = [];\n @state() private _order: readonly string[] = [];\n @state() private _size: Size | undefined;\n\n readonly #anchorName = `--checked-select-anchor-${instanceCounter++}`;\n\n #tickled = new TickledController<number>(this, {\n getItems: () => this._order.map((_, i) => ({ id: i })),\n });\n\n get isOpen(): boolean {\n return this._open;\n }\n\n get #trigger(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>(`.rest`) ?? null;\n }\n\n get #popup(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>(`.popup`) ?? null;\n }\n\n get #listbox(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>(`.listbox`) ?? null;\n }\n\n /** Draft items in their frozen open-time order. */\n #rows(): CheckedSelectItem[] {\n const byValue = new Map(this._draft.map(i => [i.value, i]));\n return this._order.flatMap(v => byValue.get(v) ?? []);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener(`pointerdown`, this.#onDocumentPointerDown, true);\n }\n\n override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n if (changed.has(`disabled`) && this.disabled && this._open) {\n this.cancel();\n }\n }\n\n async open(): Promise<void> {\n if (this._open || this.disabled)\n return;\n this._draft = this.items;\n this._order = sortForOpen(this.items).map(i => i.value);\n this._size = undefined;\n this._open = true;\n if (this._order.length > 0)\n this.#tickled.handleKeyboardNavigation(`first`);\n document.addEventListener(`pointerdown`, this.#onDocumentPointerDown, true);\n await this.updateComplete;\n this.#popup?.showPopover?.();\n this.#listbox?.focus();\n }\n\n commit(): void {\n if (!this._open)\n return;\n const changed = diffItems(this.items, this._draft);\n const next = this._draft;\n this.#close();\n if (changed.length === 0)\n return;\n this.#emitChange(next, changed);\n }\n\n #emitChange(next: readonly CheckedSelectItem[], changed: readonly CheckedSelectItem[]): void {\n this.items = next;\n this.dispatchEvent(new CustomEvent<CheckedSelectChangeDetail>(`change`, {\n detail: { items: next, changed },\n bubbles: true,\n composed: true,\n }));\n }\n\n /** A resting checkbox was used directly: toggle and commit immediately. */\n #onRestCheckboxChange = (e: Event, value: string): void => {\n // The checkbox's own `change` bubbles out of this shadow root; ours replaces it\n e.stopPropagation();\n if (this._open)\n return;\n const next = applyToggle(this.items, value);\n this.#emitChange(next, diffItems(this.items, next));\n void this.#focusRestCheckbox(value);\n };\n\n async #focusRestCheckbox(value: string): Promise<void> {\n await this.updateComplete;\n const box = this.shadowRoot?.querySelector<HTMLElement>(`.rest ixfx-checkbox[data-value=\"${CSS.escape(value)}\"]`);\n // Unchecking removes the checkbox from the resting view; keep focus on the control\n (box ?? this.#trigger)?.focus();\n }\n\n cancel(): void {\n if (!this._open)\n return;\n this.#close();\n }\n\n #close(): void {\n document.removeEventListener(`pointerdown`, this.#onDocumentPointerDown, true);\n this.#popup?.hidePopover?.();\n this._open = false;\n this._draft = [];\n this.#tickled.clearTickled();\n this.#trigger?.focus();\n }\n\n #onDocumentPointerDown = (e: PointerEvent): void => {\n const path = e.composedPath();\n const popup = this.#popup;\n const trigger = this.#trigger;\n if ((popup && path.includes(popup)) || (trigger && path.includes(trigger)))\n return;\n this.cancel();\n };\n\n #onTriggerClick = (e: Event): void => {\n // Clicks on a resting checkbox toggle it; only empty space (or the caret) opens/commits\n if ((e.target as Element).closest?.(`ixfx-checkbox`))\n return;\n // Grabbing the scrollbar of the resting items isn't a click on the control\n const scroller = e.composedPath()[0] as HTMLElement;\n if (scroller.classList?.contains(`rest-items`) && e instanceof MouseEvent\n && (e.offsetX > scroller.clientWidth || e.offsetY > scroller.clientHeight)) {\n return;\n }\n if (this._open)\n this.commit();\n else void this.open();\n };\n\n #onTriggerKeyDown = (e: KeyboardEvent): void => {\n // Keys on a focused resting checkbox belong to that checkbox\n if (this._open || e.target !== e.currentTarget)\n return;\n if (e.key === `Enter` || e.key === ` ` || e.key === `ArrowDown`) {\n e.preventDefault();\n void this.open();\n }\n };\n\n #toggleRow(value: string): void {\n this._draft = applyToggle(this._draft, value);\n }\n\n #onRowClick(value: string, index: number): void {\n this.#tickled.setTickled(index);\n this.#toggleRow(value);\n }\n\n #onListKeyDown = (e: KeyboardEvent): void => {\n const rows = this.#rows();\n switch (e.key) {\n case `ArrowDown`:\n e.preventDefault();\n this.#tickled.handleKeyboardNavigation(`next`);\n void this.#scrollToCursor();\n return;\n case `ArrowUp`:\n e.preventDefault();\n this.#tickled.handleKeyboardNavigation(`previous`);\n void this.#scrollToCursor();\n return;\n case `Home`:\n e.preventDefault();\n this.#tickled.handleKeyboardNavigation(`first`);\n void this.#scrollToCursor();\n return;\n case `End`:\n e.preventDefault();\n this.#tickled.handleKeyboardNavigation(`last`);\n void this.#scrollToCursor();\n return;\n case ` `: {\n e.preventDefault();\n const row = rows[this.#tickled.tickledId ?? -1];\n if (row)\n this.#toggleRow(row.value);\n return;\n }\n case `Enter`:\n e.preventDefault();\n this.commit();\n return;\n case `Escape`:\n e.preventDefault();\n this.cancel();\n return;\n case `Tab`:\n this.cancel();\n return;\n }\n if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {\n const next = nextMatchIndex(rows.map(r => r.label), this.#tickled.tickledId ?? -1, e.key);\n if (next >= 0) {\n this.#tickled.handleKeyboardNavigation(next);\n void this.#scrollToCursor();\n }\n }\n };\n\n async #scrollToCursor(): Promise<void> {\n await this.updateComplete;\n const index = this.#tickled.tickledId;\n this.shadowRoot?.querySelector(`[data-index=\"${index}\"]`)?.scrollIntoView?.({ block: `nearest` });\n }\n\n #onResizeDown = (e: PointerEvent): void => {\n const frame = this.shadowRoot?.querySelector<HTMLElement>(`.frame`);\n const zone = e.currentTarget as HTMLElement;\n if (!frame)\n return;\n e.preventDefault();\n const start = frame.getBoundingClientRect();\n const originX = e.clientX;\n const originY = e.clientY;\n const style = getComputedStyle(this);\n const min: Size = {\n width: Number.parseFloat(style.getPropertyValue(`--checked-select-min-width`)) || 128,\n height: Number.parseFloat(style.getPropertyValue(`--checked-select-min-height`)) || 80,\n };\n const max: Size = {\n width: window.innerWidth - start.left - 8,\n height: window.innerHeight - start.top - 8,\n };\n zone.setPointerCapture?.(e.pointerId);\n zone.setAttribute(`data-active`, ``);\n const onMove = (m: PointerEvent): void => {\n this._size = clampSize({\n width: start.width + m.clientX - originX,\n height: start.height + m.clientY - originY,\n }, min, max);\n };\n const onEnd = (): void => {\n zone.removeAttribute(`data-active`);\n zone.removeEventListener(`pointermove`, onMove);\n zone.removeEventListener(`pointerup`, onEnd);\n zone.removeEventListener(`pointercancel`, onEnd);\n this.#listbox?.focus();\n };\n zone.addEventListener(`pointermove`, onMove);\n zone.addEventListener(`pointerup`, onEnd);\n zone.addEventListener(`pointercancel`, onEnd);\n };\n\n #renderRest() {\n const shown = visibleAtRest(this.items);\n if (shown.length === 0) {\n return html`<span class=\"placeholder\">${this.placeholder}</span>`;\n }\n if (this.itemDisplay === `text`) {\n if (this.orientation === `vertical`) {\n return restTextParts(this.items).map(part => html`<span class=\"rest-text\">${part}</span>`);\n }\n return html`<span class=\"rest-text\">${restText(this.items)}</span>`;\n }\n return repeat(shown, i => i.value, i => html`\n <ixfx-checkbox\n ?readonly=${this.itemsInert}\n data-value=${i.value}\n label=${i.label}\n .checked=${i.checked === `true`}\n .indeterminate=${i.checked === `indeterminate`}\n @change=${(e: Event) => this.#onRestCheckboxChange(e, i.value)}\n ></ixfx-checkbox>`);\n }\n\n #renderRow(row: CheckedSelectItem, index: number) {\n return html`\n <div\n class=\"item ${this.#tickled.isTickled(index) ? `tickled` : ``}\"\n role=\"option\"\n id=\"opt-${index}\"\n data-index=${index}\n aria-checked=${row.checked === `indeterminate` ? `mixed` : row.checked}\n @pointerenter=${() => this.#tickled.handlePointerEnter(index)}\n @click=${() => this.#onRowClick(row.value, index)}\n >\n <ixfx-checkbox\n readonly\n label=${row.label}\n .checked=${row.checked === `true`}\n .indeterminate=${row.checked === `indeterminate`}\n ></ixfx-checkbox>\n </div>`;\n }\n\n protected override render() {\n const rows = this._open ? this.#rows() : [];\n const cursor = this.#tickled.tickledId;\n const popupSize = this._size ? `width: ${this._size.width}px;` : ``;\n const frameStyle = this._size ? `height: ${this._size.height}px; max-height: none;` : ``;\n const summary = visibleAtRest(this.items).map(i => i.label).join(`, `);\n return html`\n <div\n class=\"rest\"\n role=\"combobox\"\n tabindex=${this.disabled ? `-1` : `0`}\n aria-haspopup=\"listbox\"\n aria-expanded=${this._open ? `true` : `false`}\n aria-disabled=${this.disabled ? `true` : nothing}\n title=${summary || nothing}\n style=\"anchor-name: ${this.#anchorName}\"\n @click=${this.#onTriggerClick}\n @keydown=${this.#onTriggerKeyDown}\n >\n <div class=\"rest-items\">${this.#renderRest()}</div>\n <div class=\"caret\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\"><path d=\"m6 9 6 6 6-6\" /></svg>\n </div>\n </div>\n <div class=\"popup\" popover=\"manual\" style=\"position-anchor: ${this.#anchorName}; ${popupSize}\">\n <div class=\"frame\" style=${frameStyle}>\n <div\n class=\"listbox\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n tabindex=\"-1\"\n aria-activedescendant=${cursor === undefined ? nothing : `opt-${cursor}`}\n data-input-mode=${this.#tickled.inputMode}\n @pointerleave=${(e: PointerEvent) => this.#tickled.handlePointerLeave(e)}\n @keydown=${this.#onListKeyDown}\n >${rows.map((r, i) => this.#renderRow(r, i))}</div>\n <div class=\"resize-zone\" @pointerdown=${this.#onResizeDown}>\n <span class=\"ixfx-handle\" data-handle=\"dotted\" data-shape=\"spot\" part=\"handle\"></span>\n </div>\n </div>\n </div>\n `;\n }\n}\n\nexport type CheckedSelectChangeDetail = {\n /** Every item, with its committed state. */\n readonly items: readonly CheckedSelectItem[];\n /** Only the items whose state changed. */\n readonly changed: readonly CheckedSelectItem[];\n};\n\nexport type CheckedSelectChangeEvent = CustomEvent<CheckedSelectChangeDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-checked-select': CheckedSelect;\n }\n}\n\nexport interface CheckedSelectEventMap {\n change: CheckedSelectChangeEvent;\n}\n\nexport interface CheckedSelect {\n addEventListener: (<K extends keyof CheckedSelectEventMap>(\n type: K,\n listener: (this: CheckedSelect, event: CheckedSelectEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n"],"mappings":";;;;;;;;;;;AAEA,SAAS,QAAQ,GAAsB,GAA8B;CACnE,OAAO,EAAE,MAAM,cAAc,EAAE,OAAO,KAAA,GAAW,EAAE,aAAa,OAAO,CAAC;AAC1E;;AAGA,SAAgB,YAAY,OAA0D;CACpF,MAAM,KAAK,MAAM,QAAO,MAAK,EAAE,YAAY,OAAO,CAAC,CAAC,SAAS,OAAO;CACpE,MAAM,MAAM,MAAM,QAAO,MAAK,EAAE,YAAY,OAAO,CAAC,CAAC,SAAS,OAAO;CACrE,OAAO,CAAC,GAAG,IAAI,GAAG,GAAG;AACvB;;AAGA,SAAgB,YAAY,OAA+B;CACzD,OAAO,UAAU,SAAS,UAAU;AACtC;;AAGA,SAAgB,cAAc,OAA0D;CACtF,OAAO,MAAM,QAAO,MAAK,EAAE,YAAY,OAAO,CAAC,CAAC,SAAS,OAAO;AAClE;AAEA,MAAa,eAAe;;AAG5B,SAAgB,cAAc,OAA+C;CAC3E,MAAM,KAAK,MAAM,QAAO,MAAK,EAAE,YAAY,MAAM,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,KAAI,MAAK,EAAE,KAAK;CACrF,MAAM,SAAS,MAAM,MAAK,MAAK,EAAE,YAAY,eAAe,IAAI,CAAC,YAAY,IAAI,CAAC;CAClF,OAAO,CAAC,GAAG,IAAI,GAAG,MAAM;AAC1B;;AAGA,SAAgB,SAAS,OAA6C;CACpE,OAAO,cAAc,KAAK,CAAC,CAAC,KAAK,IAAI;AACvC;;AAGA,SAAgB,YAAY,OAAqC,OAAoC;CACnG,OAAO,MAAM,KAAI,MAAK,EAAE,UAAU,QAAQ;EAAE,GAAG;EAAG,SAAS,YAAY,EAAE,OAAO;CAAE,IAAI,CAAC;AACzF;;;;;AAMA,SAAgB,eAAe,QAA2B,SAAiB,MAAsB;CAC/F,MAAM,IAAI,KAAK,kBAAkB;CACjC,MAAM,QAAQ,OAAO;CACrB,KAAK,IAAI,OAAO,GAAG,QAAQ,OAAO,QAAQ;EACxC,MAAM,SAAS,UAAU,OAAO,SAAS;EACzC,IAAI,OAAO,MAAM,CAAC,kBAAkB,CAAC,CAAC,WAAW,CAAC,GAChD,OAAO;CACX;CACA,OAAO;AACT;;AAGA,SAAgB,UAAU,UAAwC,OAA0D;CAC1H,MAAM,SAAS,IAAI,IAAI,SAAS,KAAI,MAAK,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;CAC9D,OAAO,MAAM,QAAO,MAAK,OAAO,IAAI,EAAE,KAAK,MAAM,EAAE,OAAO;AAC5D;AAEA,SAAgB,UAAU,MAAY,KAAW,KAAiB;CAChE,OAAO;EACL,OAAO,KAAK,IAAI,KAAK,IAAI,KAAK,OAAO,IAAI,KAAK,GAAG,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,CAAC;EAC/E,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,QAAQ,IAAI,MAAM,GAAG,KAAK,IAAI,IAAI,QAAQ,IAAI,MAAM,CAAC;CACtF;AACF;;;ACrBA,IAAI,kBAAkB;AAGf,IAAM,gBAAN,MAAM,sBAAsB,WAAW;;;EA8LqB,KAAA,QAAA,CAAC;EACV,KAAA,YAAA;EAE2B,KAAA,aAAA;EAEc,KAAA,cAAA;EAEvB,KAAA,cAAA;EAChC,KAAA,cAAA;EACa,KAAA,WAAA;EAE9B,KAAA,QAAA;EAC+B,KAAA,SAAA,CAAC;EACZ,KAAA,SAAA,CAAC;EAGvB,KAAA,cAAA,2BAA2B;EAEvC,KAAA,WAAA,IAAI,kBAA0B,MAAM,EAC7C,gBAAgB,KAAK,OAAO,KAAK,GAAG,OAAO,EAAE,IAAI,EAAE,EAAE,EACvD,CAAC;EAwEwB,KAAA,yBAAA,GAAU,UAAwB;GAEzD,EAAE,gBAAgB;GAClB,IAAI,KAAK,OACP;GACF,MAAM,OAAO,YAAY,KAAK,OAAO,KAAK;GAC1C,KAAKA,YAAY,MAAM,UAAU,KAAK,OAAO,IAAI,CAAC;GAClD,KAAUC,mBAAmB,KAAK;EACpC;EAwB0B,KAAA,0BAAA,MAA0B;GAClD,MAAM,OAAO,EAAE,aAAa;GAC5B,MAAM,QAAQ,KAAKC;GACnB,MAAM,UAAU,KAAKC;GACrB,IAAK,SAAS,KAAK,SAAS,KAAK,KAAO,WAAW,KAAK,SAAS,OAAO,GACtE;GACF,KAAK,OAAO;EACd;EAEmB,KAAA,mBAAA,MAAmB;GAEpC,IAAK,EAAE,OAAmB,UAAU,eAAe,GACjD;GAEF,MAAM,WAAW,EAAE,aAAa,CAAC,CAAC;GAClC,IAAI,SAAS,WAAW,SAAS,YAAY,KAAK,aAAa,eACzD,EAAE,UAAU,SAAS,eAAe,EAAE,UAAU,SAAS,eAC7D;GAEF,IAAI,KAAK,OACP,KAAK,OAAO;QACT,KAAU,KAAK;EACtB;EAEqB,KAAA,qBAAA,MAA2B;GAE9C,IAAI,KAAK,SAAS,EAAE,WAAW,EAAE,eAC/B;GACF,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,OAAO,EAAE,QAAQ,aAAa;IAC/D,EAAE,eAAe;IACjB,KAAU,KAAK;GACjB;EACF;EAWkB,KAAA,kBAAA,MAA2B;GAC3C,MAAM,OAAO,KAAKC,MAAM;GACxB,QAAQ,EAAE,KAAV;IACE,KAAK;KACH,EAAE,eAAe;KACjB,KAAKC,SAAS,yBAAyB,MAAM;KAC7C,KAAUC,gBAAgB;KAC1B;IACF,KAAK;KACH,EAAE,eAAe;KACjB,KAAKD,SAAS,yBAAyB,UAAU;KACjD,KAAUC,gBAAgB;KAC1B;IACF,KAAK;KACH,EAAE,eAAe;KACjB,KAAKD,SAAS,yBAAyB,OAAO;KAC9C,KAAUC,gBAAgB;KAC1B;IACF,KAAK;KACH,EAAE,eAAe;KACjB,KAAKD,SAAS,yBAAyB,MAAM;KAC7C,KAAUC,gBAAgB;KAC1B;IACF,KAAK,KAAK;KACR,EAAE,eAAe;KACjB,MAAM,MAAM,KAAK,KAAKD,SAAS,aAAa;KAC5C,IAAI,KACF,KAAKE,WAAW,IAAI,KAAK;KAC3B;IACF;IACA,KAAK;KACH,EAAE,eAAe;KACjB,KAAK,OAAO;KACZ;IACF,KAAK;KACH,EAAE,eAAe;KACjB,KAAK,OAAO;KACZ;IACF,KAAK;KACH,KAAK,OAAO;KACZ;GACJ;GACA,IAAI,EAAE,IAAI,WAAW,KAAK,CAAC,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,EAAE,QAAQ;IAC/D,MAAM,OAAO,eAAe,KAAK,KAAI,MAAK,EAAE,KAAK,GAAG,KAAKF,SAAS,aAAa,IAAI,EAAE,GAAG;IACxF,IAAI,QAAQ,GAAG;KACb,KAAKA,SAAS,yBAAyB,IAAI;KAC3C,KAAUC,gBAAgB;IAC5B;GACF;EACF;EAQiB,KAAA,iBAAA,MAA0B;GACzC,MAAM,QAAQ,KAAK,YAAY,cAA2B,QAAQ;GAClE,MAAM,OAAO,EAAE;GACf,IAAI,CAAC,OACH;GACF,EAAE,eAAe;GACjB,MAAM,QAAQ,MAAM,sBAAsB;GAC1C,MAAM,UAAU,EAAE;GAClB,MAAM,UAAU,EAAE;GAClB,MAAM,QAAQ,iBAAiB,IAAI;GACnC,MAAM,MAAY;IAChB,OAAO,OAAO,WAAW,MAAM,iBAAiB,4BAA4B,CAAC,KAAK;IAClF,QAAQ,OAAO,WAAW,MAAM,iBAAiB,6BAA6B,CAAC,KAAK;GACtF;GACA,MAAM,MAAY;IAChB,OAAO,OAAO,aAAa,MAAM,OAAO;IACxC,QAAQ,OAAO,cAAc,MAAM,MAAM;GAC3C;GACA,KAAK,oBAAoB,EAAE,SAAS;GACpC,KAAK,aAAa,eAAe,EAAE;GACnC,MAAM,UAAU,MAA0B;IACxC,KAAK,QAAQ,UAAU;KACrB,OAAO,MAAM,QAAQ,EAAE,UAAU;KACjC,QAAQ,MAAM,SAAS,EAAE,UAAU;IACrC,GAAG,KAAK,GAAG;GACb;GACA,MAAM,cAAoB;IACxB,KAAK,gBAAgB,aAAa;IAClC,KAAK,oBAAoB,eAAe,MAAM;IAC9C,KAAK,oBAAoB,aAAa,KAAK;IAC3C,KAAK,oBAAoB,iBAAiB,KAAK;IAC/C,KAAKE,UAAU,MAAM;GACvB;GACA,KAAK,iBAAiB,eAAe,MAAM;GAC3C,KAAK,iBAAiB,aAAa,KAAK;GACxC,KAAK,iBAAiB,iBAAiB,KAAK;EAC9C;;;EAjcyB,KAAA,SAAA;GAAC;GAAgB;GAAc;GAAe;GAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2L5F;;CAkBD;CAEA;CAIA,IAAI,SAAkB;EACpB,OAAO,KAAK;CACd;CAEA,IAAIL,WAA+B;EACjC,OAAO,KAAK,YAAY,cAA2B,OAAO,KAAK;CACjE;CAEA,IAAID,SAA6B;EAC/B,OAAO,KAAK,YAAY,cAA2B,QAAQ,KAAK;CAClE;CAEA,IAAIM,WAA+B;EACjC,OAAO,KAAK,YAAY,cAA2B,UAAU,KAAK;CACpE;;CAGA,QAA6B;EAC3B,MAAM,UAAU,IAAI,IAAI,KAAK,OAAO,KAAI,MAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;EAC1D,OAAO,KAAK,OAAO,SAAQ,MAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC;CACtD;CAEA,uBAAsC;EACpC,MAAM,qBAAqB;EAC3B,SAAS,oBAAoB,eAAe,KAAKE,wBAAwB,IAAI;CAC/E;CAEA,WAAoB,SAA+B;EACjD,MAAM,WAAW,OAAO;EACxB,IAAI,QAAQ,IAAI,UAAU,KAAK,KAAK,YAAY,KAAK,OACnD,KAAK,OAAO;CAEhB;CAEA,MAAM,OAAsB;EAC1B,IAAI,KAAK,SAAS,KAAK,UACrB;EACF,KAAK,SAAS,KAAK;EACnB,KAAK,SAAS,YAAY,KAAK,KAAK,CAAC,CAAC,KAAI,MAAK,EAAE,KAAK;EACtD,KAAK,QAAQ,KAAA;EACb,KAAK,QAAQ;EACb,IAAI,KAAK,OAAO,SAAS,GACvB,KAAKL,SAAS,yBAAyB,OAAO;EAChD,SAAS,iBAAiB,eAAe,KAAKK,wBAAwB,IAAI;EAC1E,MAAM,KAAK;EACX,KAAKR,QAAQ,cAAc;EAC3B,KAAKM,UAAU,MAAM;CACvB;CAEA,SAAe;EACb,IAAI,CAAC,KAAK,OACR;EACF,MAAM,UAAU,UAAU,KAAK,OAAO,KAAK,MAAM;EACjD,MAAM,OAAO,KAAK;EAClB,KAAKG,OAAO;EACZ,IAAI,QAAQ,WAAW,GACrB;EACF,KAAKX,YAAY,MAAM,OAAO;CAChC;CAEA,YAAY,MAAoC,SAA6C;EAC3F,KAAK,QAAQ;EACb,KAAK,cAAc,IAAI,YAAuC,UAAU;GACtE,QAAQ;IAAE,OAAO;IAAM;GAAQ;GAC/B,SAAS;GACT,UAAU;EACZ,CAAC,CAAC;CACJ;;CAGA;CAUA,MAAMC,mBAAmB,OAA8B;EACrD,MAAM,KAAK;EAGX,CAFY,KAAK,YAAY,cAA2B,mCAAmC,IAAI,OAAO,KAAK,EAAE,GAAG,KAExG,KAAKE,SAAAA,EAAW,MAAM;CAChC;CAEA,SAAe;EACb,IAAI,CAAC,KAAK,OACR;EACF,KAAKQ,OAAO;CACd;CAEA,SAAe;EACb,SAAS,oBAAoB,eAAe,KAAKD,wBAAwB,IAAI;EAC7E,KAAKR,QAAQ,cAAc;EAC3B,KAAK,QAAQ;EACb,KAAK,SAAS,CAAC;EACf,KAAKG,SAAS,aAAa;EAC3B,KAAKF,UAAU,MAAM;CACvB;CAEA;CASA;CAeA;CAUA,WAAW,OAAqB;EAC9B,KAAK,SAAS,YAAY,KAAK,QAAQ,KAAK;CAC9C;CAEA,YAAY,OAAe,OAAqB;EAC9C,KAAKE,SAAS,WAAW,KAAK;EAC9B,KAAKE,WAAW,KAAK;CACvB;CAEA;CAmDA,MAAMD,kBAAiC;EACrC,MAAM,KAAK;EACX,MAAM,QAAQ,KAAKD,SAAS;EAC5B,KAAK,YAAY,cAAc,gBAAgB,MAAM,GAAG,CAAC,EAAE,iBAAiB,EAAE,OAAO,UAAU,CAAC;CAClG;CAEA;CAsCA,cAAc;EACZ,MAAM,QAAQ,cAAc,KAAK,KAAK;EACtC,IAAI,MAAM,WAAW,GACnB,OAAO,IAAI,6BAA6B,KAAK,YAAY;EAE3D,IAAI,KAAK,gBAAgB,QAAQ;GAC/B,IAAI,KAAK,gBAAgB,YACvB,OAAO,cAAc,KAAK,KAAK,CAAC,CAAC,KAAI,SAAQ,IAAI,2BAA2B,KAAK,QAAQ;GAE3F,OAAO,IAAI,2BAA2B,SAAS,KAAK,KAAK,EAAE;EAC7D;EACA,OAAO,OAAO,QAAO,MAAK,EAAE,QAAO,MAAK,IAAI;;oBAE5B,KAAK,WAAW;qBACf,EAAE,MAAM;gBACb,EAAE,MAAM;mBACL,EAAE,YAAY,OAAO;yBACf,EAAE,YAAY,gBAAgB;mBACpC,MAAa,KAAKO,sBAAsB,GAAG,EAAE,KAAK,EAAE;wBAC/C;CACtB;CAEA,WAAW,KAAwB,OAAe;EAChD,OAAO,IAAI;;sBAEO,KAAKP,SAAS,UAAU,KAAK,IAAI,YAAY,GAAG;;kBAEpD,MAAM;qBACH,MAAM;uBACJ,IAAI,YAAY,kBAAkB,UAAU,IAAI,QAAQ;8BACjD,KAAKA,SAAS,mBAAmB,KAAK,EAAE;uBAC/C,KAAKQ,YAAY,IAAI,OAAO,KAAK,EAAE;;;;kBAIxC,IAAI,MAAM;qBACP,IAAI,YAAY,OAAO;2BACjB,IAAI,YAAY,gBAAgB;;;CAGzD;CAEA,SAA4B;EAC1B,MAAM,OAAO,KAAK,QAAQ,KAAKT,MAAM,IAAI,CAAC;EAC1C,MAAM,SAAS,KAAKC,SAAS;EAC7B,MAAM,YAAY,KAAK,QAAQ,UAAU,KAAK,MAAM,MAAM,OAAO;EACjE,MAAM,aAAa,KAAK,QAAQ,WAAW,KAAK,MAAM,OAAO,yBAAyB;EACtF,MAAM,UAAU,cAAc,KAAK,KAAK,CAAC,CAAC,KAAI,MAAK,EAAE,KAAK,CAAC,CAAC,KAAK,IAAI;EACrE,OAAO,IAAI;;;;mBAII,KAAK,WAAW,OAAO,IAAI;;wBAEtB,KAAK,QAAQ,SAAS,QAAQ;wBAC9B,KAAK,WAAW,SAAS,QAAQ;gBACzC,WAAW,QAAQ;8BACL,KAAKI,YAAY;iBAC9B,KAAKK,gBAAgB;mBACnB,KAAKC,kBAAkB;;kCAER,KAAKC,YAAY,EAAE;;;;;oEAKe,KAAKP,YAAY,IAAI,UAAU;mCAChE,WAAW;;;;;;oCAMV,WAAW,KAAA,IAAY,UAAU,OAAO,SAAS;8BACvD,KAAKJ,SAAS,UAAU;6BACzB,MAAoB,KAAKA,SAAS,mBAAmB,CAAC,EAAE;uBAC9D,KAAKY,eAAe;aAC9B,KAAK,KAAK,GAAG,MAAM,KAAKC,WAAW,GAAG,CAAC,CAAC,EAAE;kDACL,KAAKC,cAAc;;;;;;CAMnE;AACF;AA3VG,WAAA,CAAA,SAAS,EAAE,MAAM,MAAM,CAAC,CAAA,GAAA,cAAA,WAAA,SAAA,KAAA,CAAA;AACxB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,aAAA,KAAA,CAAA;AAEzC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,WAAW;CAAe,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,cAAA,KAAA,CAAA;AAEnE,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;CAAgB,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,eAAA,KAAA,CAAA;AAEnE,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,eAAA,KAAA,CAAA;AACxC,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,cAAA,WAAA,eAAA,KAAA,CAAA;AACzB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,YAAA,KAAA,CAAA;AAEzC,WAAA,CAAA,MAAM,CAAA,GAAA,cAAA,WAAA,SAAA,KAAA,CAAA;AACN,WAAA,CAAA,MAAM,CAAA,GAAA,cAAA,WAAA,UAAA,KAAA,CAAA;AACN,WAAA,CAAA,MAAM,CAAA,GAAA,cAAA,WAAA,UAAA,KAAA,CAAA;AACN,WAAA,CAAA,MAAM,CAAA,GAAA,cAAA,WAAA,SAAA,KAAA,CAAA;AA7MRC,gBAAAA,WAAAA,CAAAA,kBAAc,qBAAqB,CAAA,GAAA,aAAA"}
|
|
1
|
+
{"version":3,"file":"checked-select-lDgAQQ7v.js","names":["#emitChange","#focusRestCheckbox","#popup","#trigger","#rows","#tickled","#scrollToCursor","#toggleRow","#listbox","#anchorName","#onDocumentPointerDown","#close","#onRestCheckboxChange","#onRowClick","#onTriggerClick","#onTriggerKeyDown","#renderRest","#onListKeyDown","#renderRow","#onResizeDown","customElement"],"sources":["../src/checked-select/logic.ts","../src/checked-select/checked-select.ts"],"sourcesContent":["import type { CheckedSelectItem, CheckState, Size } from './types.js';\n\nfunction byLabel(a: CheckedSelectItem, b: CheckedSelectItem): number {\n return a.label.localeCompare(b.label, undefined, { sensitivity: `base` });\n}\n\n/** Checked/indeterminate items first, then the rest; each group sorted by label. */\nexport function sortForOpen(items: readonly CheckedSelectItem[]): CheckedSelectItem[] {\n const on = items.filter(i => i.checked !== `false`).toSorted(byLabel);\n const off = items.filter(i => i.checked === `false`).toSorted(byLabel);\n return [...on, ...off];\n}\n\n/** User toggle: indeterminate and unchecked become checked, checked becomes unchecked. */\nexport function toggleState(state: CheckState): CheckState {\n return state === `true` ? `false` : `true`;\n}\n\n/** Items shown in the resting state, alphabetically. */\nexport function visibleAtRest(items: readonly CheckedSelectItem[]): CheckedSelectItem[] {\n return items.filter(i => i.checked !== `false`).toSorted(byLabel);\n}\n\nexport const VARIES_LABEL = `(varies)`;\n\n/** Resting text entries: checked labels, then a single `(varies)` if any are indeterminate. */\nexport function restTextParts(items: readonly CheckedSelectItem[]): string[] {\n const on = items.filter(i => i.checked === `true`).toSorted(byLabel).map(i => i.label);\n const varies = items.some(i => i.checked === `indeterminate`) ? [VARIES_LABEL] : [];\n return [...on, ...varies];\n}\n\n/** Plain-text resting summary, comma separated. */\nexport function restText(items: readonly CheckedSelectItem[]): string {\n return restTextParts(items).join(`, `);\n}\n\n/** Returns a new list with the item matching `value` toggled. */\nexport function applyToggle(items: readonly CheckedSelectItem[], value: string): CheckedSelectItem[] {\n return items.map(i => i.value === value ? { ...i, checked: toggleState(i.checked) } : i);\n}\n\n/**\n * Index of the next label after `current` beginning with `char` (case-insensitive),\n * wrapping around. Returns -1 if nothing matches.\n */\nexport function nextMatchIndex(labels: readonly string[], current: number, char: string): number {\n const c = char.toLocaleLowerCase();\n const count = labels.length;\n for (let step = 1; step <= count; step++) {\n const index = (current + step + count) % count;\n if (labels[index].toLocaleLowerCase().startsWith(c))\n return index;\n }\n return -1;\n}\n\n/** Items in `draft` whose state differs from `original`. */\nexport function diffItems(original: readonly CheckedSelectItem[], draft: readonly CheckedSelectItem[]): CheckedSelectItem[] {\n const before = new Map(original.map(i => [i.value, i.checked]));\n return draft.filter(i => before.get(i.value) !== i.checked);\n}\n\nexport function clampSize(size: Size, min: Size, max: Size): Size {\n return {\n width: Math.min(Math.max(size.width, min.width), Math.max(max.width, min.width)),\n height: Math.min(Math.max(size.height, min.height), Math.max(max.height, min.height)),\n };\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\n/**\n * <ixfx-checked-select> — a SELECT-like multi-choice control with tri-state items.\n *\n * At rest it shows the checked and indeterminate items as a flow of display-only\n * `ixfx-checkbox`. Opening it shows a scrollable, resizable popup of every item\n * (checked first, sorted once at open time). Edits are made to a draft:\n * Enter (or clicking the resting area again) commits, Escape or clicking outside\n * cancels.\n *\n * Properties\n * items – CheckedSelectItem[] ({ value, label, checked: 'true'|'false'|'indeterminate' })\n * multiline – let the resting flow wrap (default: false)\n * items-inert – resting checkboxes are display-only; clicking them opens the popup\n * orientation – 'horizontal' (default) flows items in a row; 'vertical' stacks one per row\n * (vertical ignores multiline; text mode then lists one entry per line, no commas)\n * item-display – 'checkbox' (default) or 'text' (comma-separated labels, then '(varies)' if any are indeterminate)\n * placeholder – shown when nothing is checked\n * disabled – prevents opening\n *\n * Events\n * change – CustomEvent { detail: { items, changed } }, bubbles + composed.\n * Fired once per commit, and only if something changed.\n *\n * CSS Variables\n * --checked-select-gap – gap between resting checkboxes\n * --checked-select-padding – padding of the resting area\n * --checked-select-caret-width – width of the always-visible caret (default: 2rem)\n * --checked-select-rest-max-height – resting height before it scrolls when multiline (default: 8rem)\n * --checked-select-max-height – popup height before it scrolls (default: 16rem)\n * --checked-select-min-width – minimum popup width when resized (default: 8rem)\n * --checked-select-min-height – minimum popup height when resized (default: 5rem)\n */\nimport type { PropertyValues } from 'lit';\nimport type { CheckedSelectItem, ItemDisplay, ItemOrientation, Size } from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { TickledController, tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { handleStyles } from '../styles/handle.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { applyToggle, clampSize, diffItems, nextMatchIndex, restText, restTextParts, sortForOpen, visibleAtRest } from './logic.js';\nimport '../checkbox/checkbox.js';\n\nexport type { CheckedSelectItem, CheckState, ItemDisplay, ItemOrientation } from './types.js';\n\nlet instanceCounter = 0;\n\n@customElement(`ixfx-checked-select`)\nexport class CheckedSelect extends LitElement {\n static override styles = [themeFallbacks, handleStyles, tickledStyles, tickledItemStyles, css`\n :host {\n --checked-select-gap: var(--space-m);\n --checked-select-padding: var(--space-s) var(--space-m);\n --checked-select-caret-width: 2rem;\n --checked-select-rest-max-height: 8rem;\n --checked-select-max-height: 16rem;\n --checked-select-min-width: 8rem;\n --checked-select-min-height: 5rem;\n\n display: block;\n position: relative;\n }\n\n :host([disabled]) {\n opacity: var(--prominence-disabled-opacity, 0.4);\n pointer-events: none;\n }\n\n .rest {\n position: relative;\n box-sizing: border-box;\n cursor: pointer;\n background: var(--surface-4);\n color: var(--surface-4-text);\n border: var(--border);\n border-radius: var(--radius-m);\n user-select: none;\n }\n\n .rest-items {\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n gap: var(--checked-select-gap);\n padding: var(--checked-select-padding);\n /* Room to scroll the last item clear of the caret */\n padding-inline-end: var(--checked-select-caret-width);\n min-height: 1.5em;\n box-sizing: border-box;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: thin;\n }\n :host([multiline]) .rest-items {\n flex-wrap: wrap;\n overflow-x: hidden;\n overflow-y: auto;\n max-height: var(--checked-select-rest-max-height);\n /* Wrapping never runs under the caret, so keep its column clear (and the scrollbar beside it) */\n padding-inline-end: var(--space-m);\n margin-inline-end: var(--checked-select-caret-width);\n }\n\n /* Vertical: one item per row, scrolling vertically beside the caret. Must follow the multiline rule. */\n :host([orientation=\"vertical\"]) .rest-items {\n flex-direction: column;\n flex-wrap: nowrap;\n align-items: flex-start;\n overflow-x: hidden;\n overflow-y: auto;\n max-height: var(--checked-select-rest-max-height);\n padding-inline-end: var(--space-m);\n margin-inline-end: var(--checked-select-caret-width);\n }\n\n /* Always-visible caret; items scroll underneath it */\n .caret {\n position: absolute;\n inset-block: 0;\n inset-inline-end: 0;\n width: var(--checked-select-caret-width);\n display: grid;\n place-items: center;\n background: inherit;\n border-radius: inherit;\n pointer-events: auto;\n }\n .caret svg {\n width: 1.1em;\n height: 1.1em;\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n transition: rotate var(--transition, 0.1s ease-out);\n }\n .rest[aria-expanded=\"true\"] .caret svg {\n rotate: 180deg;\n }\n /* While the popup is open its draft is authoritative */\n .rest[aria-expanded=\"true\"] ixfx-checkbox {\n pointer-events: none;\n }\n .rest:hover {\n background: var(--surface-5);\n }\n .rest:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n .rest ixfx-checkbox {\n flex-shrink: 0;\n }\n .rest-text {\n white-space: nowrap;\n }\n :host([multiline]) .rest-text {\n white-space: normal;\n }\n .placeholder {\n opacity: 0.6;\n }\n\n .popup {\n /* Reset popover UA styles */\n inset: unset;\n margin: 0;\n padding: 0;\n border: none;\n background: transparent;\n overflow: visible;\n\n /* CSS anchor positioning — position-anchor set inline */\n position: fixed;\n left: anchor(left);\n top: anchor(bottom);\n /* anchor-size() only works on the anchored element itself, so the width lives here */\n width: anchor-size(width);\n min-width: var(--checked-select-min-width);\n position-try-fallbacks: flip-block;\n margin-block: 4px;\n z-index: 100;\n }\n\n .frame {\n position: relative;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n width: 100%;\n max-height: var(--checked-select-max-height);\n background: var(--surface-3);\n color: var(--surface-3-text);\n border: var(--border);\n border-radius: var(--radius-m);\n }\n\n .listbox {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: var(--space-s);\n outline: none;\n }\n .listbox:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: -2px;\n }\n\n .item {\n display: flex;\n width: 100%;\n box-sizing: border-box;\n }\n\n /* Key-repeat outpaces the fade, smearing the cursor across rows. Snap while\n the keyboard drives the cursor; hover (mouse mode) keeps the transition. */\n .listbox[data-input-mode=\"keyboard\"] .item {\n transition: none;\n }\n\n .resize-zone {\n position: absolute;\n inset-block-end: 0;\n inset-inline-end: 0;\n width: 16px;\n height: 16px;\n display: grid;\n place-items: center;\n cursor: nwse-resize;\n touch-action: none;\n }\n .resize-zone .ixfx-handle {\n --ixfx-handle-spot-size: 10px;\n }\n `];\n\n @property({ type: Array }) items: readonly CheckedSelectItem[] = [];\n @property({ type: Boolean, reflect: true }) multiline = false;\n /** At-rest checkboxes are display-only; clicking them just opens the popup. (Not `inert`: that native attribute would block the whole element.) */\n @property({ type: Boolean, attribute: `items-inert`, reflect: true }) itemsInert = false;\n /** How at-rest items are shown: as `checkbox`es, or as comma-separated `text`. */\n @property({ type: String, attribute: `item-display`, reflect: true }) itemDisplay: ItemDisplay = `checkbox`;\n /** Direction the resting items flow: `horizontal` (default) or `vertical` (one per row). */\n @property({ type: String, reflect: true }) orientation: ItemOrientation = `horizontal`;\n @property({ type: String }) placeholder = ``;\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n @state() private _open = false;\n @state() private _draft: readonly CheckedSelectItem[] = [];\n @state() private _order: readonly string[] = [];\n @state() private _size: Size | undefined;\n\n readonly #anchorName = `--checked-select-anchor-${instanceCounter++}`;\n\n #tickled = new TickledController<number>(this, {\n getItems: () => this._order.map((_, i) => ({ id: i })),\n });\n\n get isOpen(): boolean {\n return this._open;\n }\n\n get #trigger(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>(`.rest`) ?? null;\n }\n\n get #popup(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>(`.popup`) ?? null;\n }\n\n get #listbox(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>(`.listbox`) ?? null;\n }\n\n /** Draft items in their frozen open-time order. */\n #rows(): CheckedSelectItem[] {\n const byValue = new Map(this._draft.map(i => [i.value, i]));\n return this._order.flatMap(v => byValue.get(v) ?? []);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener(`pointerdown`, this.#onDocumentPointerDown, true);\n }\n\n override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n if (changed.has(`disabled`) && this.disabled && this._open) {\n this.cancel();\n }\n }\n\n async open(): Promise<void> {\n if (this._open || this.disabled)\n return;\n this._draft = this.items;\n this._order = sortForOpen(this.items).map(i => i.value);\n this._size = undefined;\n this._open = true;\n if (this._order.length > 0)\n this.#tickled.handleKeyboardNavigation(`first`);\n document.addEventListener(`pointerdown`, this.#onDocumentPointerDown, true);\n await this.updateComplete;\n this.#popup?.showPopover?.();\n this.#listbox?.focus();\n }\n\n commit(): void {\n if (!this._open)\n return;\n const changed = diffItems(this.items, this._draft);\n const next = this._draft;\n this.#close();\n if (changed.length === 0)\n return;\n this.#emitChange(next, changed);\n }\n\n #emitChange(next: readonly CheckedSelectItem[], changed: readonly CheckedSelectItem[]): void {\n this.items = next;\n this.dispatchEvent(new CustomEvent<CheckedSelectChangeDetail>(`change`, {\n detail: { items: next, changed },\n bubbles: true,\n composed: true,\n }));\n }\n\n /** A resting checkbox was used directly: toggle and commit immediately. */\n #onRestCheckboxChange = (e: Event, value: string): void => {\n // The checkbox's own `change` bubbles out of this shadow root; ours replaces it\n e.stopPropagation();\n if (this._open)\n return;\n const next = applyToggle(this.items, value);\n this.#emitChange(next, diffItems(this.items, next));\n void this.#focusRestCheckbox(value);\n };\n\n async #focusRestCheckbox(value: string): Promise<void> {\n await this.updateComplete;\n const box = this.shadowRoot?.querySelector<HTMLElement>(`.rest ixfx-checkbox[data-value=\"${CSS.escape(value)}\"]`);\n // Unchecking removes the checkbox from the resting view; keep focus on the control\n (box ?? this.#trigger)?.focus();\n }\n\n cancel(): void {\n if (!this._open)\n return;\n this.#close();\n }\n\n #close(): void {\n document.removeEventListener(`pointerdown`, this.#onDocumentPointerDown, true);\n this.#popup?.hidePopover?.();\n this._open = false;\n this._draft = [];\n this.#tickled.clearTickled();\n this.#trigger?.focus();\n }\n\n #onDocumentPointerDown = (e: PointerEvent): void => {\n const path = e.composedPath();\n const popup = this.#popup;\n const trigger = this.#trigger;\n if ((popup && path.includes(popup)) || (trigger && path.includes(trigger)))\n return;\n this.cancel();\n };\n\n #onTriggerClick = (e: Event): void => {\n // Clicks on a resting checkbox toggle it; only empty space (or the caret) opens/commits\n if ((e.target as Element).closest?.(`ixfx-checkbox`))\n return;\n // Grabbing the scrollbar of the resting items isn't a click on the control\n const scroller = e.composedPath()[0] as HTMLElement;\n if (scroller.classList?.contains(`rest-items`) && e instanceof MouseEvent\n && (e.offsetX > scroller.clientWidth || e.offsetY > scroller.clientHeight)) {\n return;\n }\n if (this._open)\n this.commit();\n else void this.open();\n };\n\n #onTriggerKeyDown = (e: KeyboardEvent): void => {\n // Keys on a focused resting checkbox belong to that checkbox\n if (this._open || e.target !== e.currentTarget)\n return;\n if (e.key === `Enter` || e.key === ` ` || e.key === `ArrowDown`) {\n e.preventDefault();\n void this.open();\n }\n };\n\n #toggleRow(value: string): void {\n this._draft = applyToggle(this._draft, value);\n }\n\n #onRowClick(value: string, index: number): void {\n this.#tickled.setTickled(index);\n this.#toggleRow(value);\n }\n\n #onListKeyDown = (e: KeyboardEvent): void => {\n const rows = this.#rows();\n switch (e.key) {\n case `ArrowDown`:\n e.preventDefault();\n this.#tickled.handleKeyboardNavigation(`next`);\n void this.#scrollToCursor();\n return;\n case `ArrowUp`:\n e.preventDefault();\n this.#tickled.handleKeyboardNavigation(`previous`);\n void this.#scrollToCursor();\n return;\n case `Home`:\n e.preventDefault();\n this.#tickled.handleKeyboardNavigation(`first`);\n void this.#scrollToCursor();\n return;\n case `End`:\n e.preventDefault();\n this.#tickled.handleKeyboardNavigation(`last`);\n void this.#scrollToCursor();\n return;\n case ` `: {\n e.preventDefault();\n const row = rows[this.#tickled.tickledId ?? -1];\n if (row)\n this.#toggleRow(row.value);\n return;\n }\n case `Enter`:\n e.preventDefault();\n this.commit();\n return;\n case `Escape`:\n e.preventDefault();\n this.cancel();\n return;\n case `Tab`:\n this.cancel();\n return;\n }\n if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {\n const next = nextMatchIndex(rows.map(r => r.label), this.#tickled.tickledId ?? -1, e.key);\n if (next >= 0) {\n this.#tickled.handleKeyboardNavigation(next);\n void this.#scrollToCursor();\n }\n }\n };\n\n async #scrollToCursor(): Promise<void> {\n await this.updateComplete;\n const index = this.#tickled.tickledId;\n this.shadowRoot?.querySelector(`[data-index=\"${index}\"]`)?.scrollIntoView?.({ block: `nearest` });\n }\n\n #onResizeDown = (e: PointerEvent): void => {\n const frame = this.shadowRoot?.querySelector<HTMLElement>(`.frame`);\n const zone = e.currentTarget as HTMLElement;\n if (!frame)\n return;\n e.preventDefault();\n const start = frame.getBoundingClientRect();\n const originX = e.clientX;\n const originY = e.clientY;\n const style = getComputedStyle(this);\n const min: Size = {\n width: Number.parseFloat(style.getPropertyValue(`--checked-select-min-width`)) || 128,\n height: Number.parseFloat(style.getPropertyValue(`--checked-select-min-height`)) || 80,\n };\n const max: Size = {\n width: window.innerWidth - start.left - 8,\n height: window.innerHeight - start.top - 8,\n };\n zone.setPointerCapture?.(e.pointerId);\n zone.setAttribute(`data-active`, ``);\n const onMove = (m: PointerEvent): void => {\n this._size = clampSize({\n width: start.width + m.clientX - originX,\n height: start.height + m.clientY - originY,\n }, min, max);\n };\n const onEnd = (): void => {\n zone.removeAttribute(`data-active`);\n zone.removeEventListener(`pointermove`, onMove);\n zone.removeEventListener(`pointerup`, onEnd);\n zone.removeEventListener(`pointercancel`, onEnd);\n this.#listbox?.focus();\n };\n zone.addEventListener(`pointermove`, onMove);\n zone.addEventListener(`pointerup`, onEnd);\n zone.addEventListener(`pointercancel`, onEnd);\n };\n\n #renderRest() {\n const shown = visibleAtRest(this.items);\n if (shown.length === 0) {\n return html`<span class=\"placeholder\">${this.placeholder}</span>`;\n }\n if (this.itemDisplay === `text`) {\n if (this.orientation === `vertical`) {\n return restTextParts(this.items).map(part => html`<span class=\"rest-text\">${part}</span>`);\n }\n return html`<span class=\"rest-text\">${restText(this.items)}</span>`;\n }\n return repeat(shown, i => i.value, i => html`\n <ixfx-checkbox\n ?readonly=${this.itemsInert}\n data-value=${i.value}\n label=${i.label}\n .checked=${i.checked === `true`}\n .indeterminate=${i.checked === `indeterminate`}\n @change=${(e: Event) => this.#onRestCheckboxChange(e, i.value)}\n ></ixfx-checkbox>`);\n }\n\n #renderRow(row: CheckedSelectItem, index: number) {\n return html`\n <div\n class=\"item ${this.#tickled.isTickled(index) ? `tickled` : ``}\"\n role=\"option\"\n id=\"opt-${index}\"\n data-index=${index}\n aria-checked=${row.checked === `indeterminate` ? `mixed` : row.checked}\n @pointerenter=${() => this.#tickled.handlePointerEnter(index)}\n @click=${() => this.#onRowClick(row.value, index)}\n >\n <ixfx-checkbox\n readonly\n label=${row.label}\n .checked=${row.checked === `true`}\n .indeterminate=${row.checked === `indeterminate`}\n ></ixfx-checkbox>\n </div>`;\n }\n\n protected override render() {\n const rows = this._open ? this.#rows() : [];\n const cursor = this.#tickled.tickledId;\n const popupSize = this._size ? `width: ${this._size.width}px;` : ``;\n const frameStyle = this._size ? `height: ${this._size.height}px; max-height: none;` : ``;\n const summary = visibleAtRest(this.items).map(i => i.label).join(`, `);\n return html`\n <div\n class=\"rest\"\n role=\"combobox\"\n tabindex=${this.disabled ? `-1` : `0`}\n aria-haspopup=\"listbox\"\n aria-expanded=${this._open ? `true` : `false`}\n aria-disabled=${this.disabled ? `true` : nothing}\n title=${summary || nothing}\n style=\"anchor-name: ${this.#anchorName}\"\n @click=${this.#onTriggerClick}\n @keydown=${this.#onTriggerKeyDown}\n >\n <div class=\"rest-items\">${this.#renderRest()}</div>\n <div class=\"caret\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\"><path d=\"m6 9 6 6 6-6\" /></svg>\n </div>\n </div>\n <div class=\"popup\" popover=\"manual\" style=\"position-anchor: ${this.#anchorName}; ${popupSize}\">\n <div class=\"frame\" style=${frameStyle}>\n <div\n class=\"listbox\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n tabindex=\"-1\"\n aria-activedescendant=${cursor === undefined ? nothing : `opt-${cursor}`}\n data-input-mode=${this.#tickled.inputMode}\n @pointerleave=${(e: PointerEvent) => this.#tickled.handlePointerLeave(e)}\n @keydown=${this.#onListKeyDown}\n >${rows.map((r, i) => this.#renderRow(r, i))}</div>\n <div class=\"resize-zone\" @pointerdown=${this.#onResizeDown}>\n <span class=\"ixfx-handle\" data-handle=\"dotted\" data-shape=\"spot\" part=\"handle\"></span>\n </div>\n </div>\n </div>\n `;\n }\n}\n\nexport type CheckedSelectChangeDetail = {\n /** Every item, with its committed state. */\n readonly items: readonly CheckedSelectItem[];\n /** Only the items whose state changed. */\n readonly changed: readonly CheckedSelectItem[];\n};\n\nexport type CheckedSelectChangeEvent = CustomEvent<CheckedSelectChangeDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-checked-select': CheckedSelect;\n }\n}\n\nexport interface CheckedSelectEventMap {\n change: CheckedSelectChangeEvent;\n}\n\nexport interface CheckedSelect {\n addEventListener: (<K extends keyof CheckedSelectEventMap>(\n type: K,\n listener: (this: CheckedSelect, event: CheckedSelectEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n"],"mappings":"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"}
|
package/dist/checked-select.js
CHANGED
package/dist/colour-picker.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as ColourPickerInputEvent, i as ColourPickerEventDetail, n as ColourPicker, o as OklchValue, r as ColourPickerChangeEvent, t as ColourPickerPopup } from "./index-
|
|
1
|
+
import { a as ColourPickerInputEvent, i as ColourPickerEventDetail, n as ColourPicker, o as OklchValue, r as ColourPickerChangeEvent, t as ColourPickerPopup } from "./index-BOUaDIW-.js";
|
|
2
2
|
export { ColourPicker, type ColourPickerChangeEvent, type ColourPickerEventDetail, type ColourPickerInputEvent, ColourPickerPopup, type OklchValue };
|
package/dist/crumbs.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { E as TreeSelectEvent, O as TreeTickleEvent, a as TreeComponent, k as TreeDataModel, n as TreeActivateEvent, o as TreeComponentEventMap, x as TreeItemClickEvent, y as TreeExpandEvent } from "./tree-component-DukLqesg.js";
|
|
2
2
|
import { n as TreeExclusivity, o as TreeNode, r as TreeFilterPredicate, s as TreeSelectionFilter, t as LoadChildrenCallback } from "./types-D-kYF16b.js";
|
|
3
|
-
import "./menu-item-
|
|
4
|
-
import "./
|
|
3
|
+
import "./menu-item-B0zqw2xp.js";
|
|
4
|
+
import "./index-o-CWDt11.js";
|
|
5
5
|
import { LitElement, PropertyValues } from "lit";
|
|
6
6
|
//#region src/crumbs/crumb-navigation.d.ts
|
|
7
7
|
/** @deprecated Use TreeSelectDetail from src/common/tree-component.ts */
|
package/dist/crumbs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crumbs.d.ts","names":[],"sources":["../src/crumbs/crumb-navigation.ts"],"mappings":";;;;;;;KAoCY;WACD,UAAU;WACV,UAAU;;KAGT,6BAA6B,YAAY;KAEzC;EAAmC,MAAM;EAAU;;KACnD,gCAAgC,YAAY;KAE5C;EAAgC,MAAM;EAAU;;KAChD,6BAA6B,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"crumbs.d.ts","names":[],"sources":["../src/crumbs/crumb-navigation.ts"],"mappings":";;;;;;;KAoCY;WACD,UAAU;WACV,UAAU;;KAGT,6BAA6B,YAAY;KAEzC;EAAmC,MAAM;EAAU;;KACnD,gCAAgC,YAAY;KAE5C;EAAgC,MAAM;EAAU;;KAChD,6BAA6B,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;cAiCxC,+BAA+B,sBAAsB;;EAEhE,MAAM;EAGN,OAAO;EAGP,cAAc;UAGN;MAEJ,iBAAiB,YAAY;;EAMjC,cAAc;EAGd,iBAAiB;EAGjB,aAAa;EAGb,iBAAiB;UAGT;UAGA;UAGA;UAGA;EAGR;EAGA;EAGA;EAGA;EAGA;EAGA;EAGA;EAGA;UAUQ;EAiTR,OAAO,MAAM;EAIb,SAAS,OAAO;EAIhB;;EAMA;;EAKA;EAIA,YAAY;IAAgB,MAAM;IAAU;;EAgBnC,QAAQ,cAAc;EAkBtB;EAMA;EAUA;;EA0TT,WAAW;;EAiBX,eAAe,YAAY,MAAM;;EAUjC,UAAU;;EAKV,WAAW,OAAO,SAAS;EAuC3B,wBAAM;SA6QC,sBAAM;;QAsQP;YACI;IACR,yBAAyB;;;UAIZ,uCAAuC;EACtD,cAAc;EACd,UAAU;EACV,UAAU;EACV,UAAU;EACV,YAAY;;UAGG;EACf,oBAAoB,gBAAgB,gCAClC,MAAM,GACN,WAAW,MAAM,wBAAwB,OAAO,+BAA+B,aAC/E,oBAAoB,sCAEpB,cACA,UAAU,oCACV,oBAAoB"}
|
package/dist/crumbs.js
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import { t as TickledController } from "./tickled-controller-
|
|
1
|
+
import { t as TickledController } from "./tickled-controller-D-HZymaZ.js";
|
|
2
2
|
import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrAHEj1q.js";
|
|
3
3
|
import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
|
|
4
4
|
import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
|
|
5
|
-
import "./interaction-
|
|
6
|
-
import "./menu-item-
|
|
5
|
+
import "./interaction-ZTh4htzr.js";
|
|
6
|
+
import "./menu-item-BDEekBVy.js";
|
|
7
7
|
import { t as collectDataResult } from "./data-provider-35TyWclX.js";
|
|
8
8
|
import { t as scrollFadeStyles } from "./scroll-fade-BrNUIYnm.js";
|
|
9
9
|
import "./narrowed-text.js";
|
|
10
10
|
import { LitElement, css, html, nothing } from "lit";
|
|
11
11
|
import { property, state } from "lit/decorators.js";
|
|
12
12
|
//#region src/crumbs/crumb-navigation.ts
|
|
13
|
+
/** Menu / suggestion order: by label, without mutating the tree's own order. */
|
|
14
|
+
function sortNodesByLabel(nodes) {
|
|
15
|
+
return [...nodes].sort((a, b) => (a.item.label ?? ``).localeCompare(b.item.label ?? ``));
|
|
16
|
+
}
|
|
13
17
|
let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
14
18
|
constructor(..._args) {
|
|
15
19
|
super(..._args);
|
|
@@ -531,7 +535,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
531
535
|
#getSiblingMenuItems(pathNodes, index) {
|
|
532
536
|
if (index === 0) {
|
|
533
537
|
if (!this.hideRoot || !this.root) return [];
|
|
534
|
-
const siblings =
|
|
538
|
+
const siblings = sortNodesByLabel(this.root.children ?? []);
|
|
535
539
|
this.#currentLeadingSiblings = siblings;
|
|
536
540
|
return siblings.map((sibling) => html`
|
|
537
541
|
<ixfx-menu-item
|
|
@@ -544,7 +548,8 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
544
548
|
></ixfx-menu-item>
|
|
545
549
|
`);
|
|
546
550
|
}
|
|
547
|
-
const
|
|
551
|
+
const parent = pathNodes[index - 1];
|
|
552
|
+
const siblings = sortNodesByLabel(parent.children ?? []);
|
|
548
553
|
this.#currentLeadingSiblings = siblings;
|
|
549
554
|
return siblings.map((sibling) => html`
|
|
550
555
|
<ixfx-menu-item
|
|
@@ -649,7 +654,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
649
654
|
const showLeadingCaret = this.leadingCaret && (i > 0 || this.hideRoot) && hasChildren;
|
|
650
655
|
const showTrailingCaret = !this.leadingCaret && hasChildren || this.leadingCaret && isLast && hasChildren;
|
|
651
656
|
const siblingMenuItems = showLeadingCaret ? this.#getSiblingMenuItems(pathNodes, i) : [];
|
|
652
|
-
const childMenuItems = (node.children ?? []).map((c) => html`
|
|
657
|
+
const childMenuItems = sortNodesByLabel(node.children ?? []).map((c) => html`
|
|
653
658
|
<ixfx-menu-item
|
|
654
659
|
label="${c.item.label}"
|
|
655
660
|
command="${c.item.key}"
|
|
@@ -759,7 +764,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
759
764
|
aria-label="Go up one level"
|
|
760
765
|
@click=${this.#onUpClick}
|
|
761
766
|
>
|
|
762
|
-
<ixfx-icon name="folder-up"></ixfx-icon>
|
|
767
|
+
<span class="label"><ixfx-icon name="folder-up"></ixfx-icon></span>
|
|
763
768
|
</button>
|
|
764
769
|
` : nothing}
|
|
765
770
|
<div
|
|
@@ -824,7 +829,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
824
829
|
@narrowed-text-blur=${this.#onNarrowedTextBlur}
|
|
825
830
|
@narrowed-text-shift-tab=${this.#onNarrowedTextShiftTab}
|
|
826
831
|
>
|
|
827
|
-
${children.map((c) => html`
|
|
832
|
+
${sortNodesByLabel(children).map((c) => html`
|
|
828
833
|
<span data-value="${c.item.key}" data-label="${c.item.label}"></span>
|
|
829
834
|
`)}
|
|
830
835
|
</ixfx-narrowed-text>
|
|
@@ -882,6 +887,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
882
887
|
}
|
|
883
888
|
|
|
884
889
|
.up-button {
|
|
890
|
+
box-sizing: border-box;
|
|
885
891
|
display: inline-flex;
|
|
886
892
|
align-items: center;
|
|
887
893
|
justify-content: center;
|
|
@@ -889,9 +895,12 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
889
895
|
background: var(--crumb-item-bg);
|
|
890
896
|
border: var(--crumb-item-border);
|
|
891
897
|
border-radius: var(--crumb-item-border-radius);
|
|
892
|
-
padding:
|
|
898
|
+
padding: 0;
|
|
899
|
+
margin: 0;
|
|
893
900
|
cursor: pointer;
|
|
894
901
|
color: inherit;
|
|
902
|
+
font: inherit;
|
|
903
|
+
line-height: normal;
|
|
895
904
|
}
|
|
896
905
|
|
|
897
906
|
.up-button:disabled {
|
|
@@ -904,7 +913,14 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
904
913
|
border-color: var(--crumb-item-border-tickled);
|
|
905
914
|
}
|
|
906
915
|
|
|
907
|
-
.up-button
|
|
916
|
+
.up-button .label {
|
|
917
|
+
display: flex;
|
|
918
|
+
align-items: center;
|
|
919
|
+
padding: var(--crumb-item-padding);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
.up-button .label ixfx-icon {
|
|
923
|
+
display: block;
|
|
908
924
|
width: 1em;
|
|
909
925
|
height: 1em;
|
|
910
926
|
pointer-events: none;
|