@ixfx/components 0.16.2 → 0.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/bundle/index.d.ts +61 -7
  2. package/bundle/index.js +151 -143
  3. package/dist/ac-text.d.ts +1 -1
  4. package/dist/{ac-token-Cq7lsYf-.d.ts → ac-token-qEs3FsQv.d.ts} +1 -1
  5. package/dist/ac-token.d.ts +1 -1
  6. package/dist/ac-token.js +1 -1
  7. package/dist/{button-D1sPDUCM.d.ts → button-N92DKoWb.d.ts} +1 -1
  8. package/dist/button.d.ts +1 -1
  9. package/dist/colour-picker.d.ts +1 -1
  10. package/dist/{crumb-navigation-nnr881n-.d.ts → crumb-navigation-BbqfmkYs.d.ts} +1 -1
  11. package/dist/crumbs.d.ts +1 -1
  12. package/dist/{data-grid-CaPLWt5E.js → data-grid-8TsiF2ES.js} +7 -6
  13. package/dist/{data-grid-BAEpfTkb.d.ts → data-grid-CslzF16R.d.ts} +4 -4
  14. package/dist/data-grid.d.ts +1 -1
  15. package/dist/data-grid.js +1 -1
  16. package/dist/{detail-list-DK49TsJd.d.ts → detail-list-n1MbNbhF.d.ts} +4 -4
  17. package/dist/{detail-list-C3XKTRmE.js → detail-list-w3GXKO2k.js} +4 -3
  18. package/dist/detail-list.d.ts +2 -2
  19. package/dist/detail-list.js +1 -1
  20. package/dist/{flat-list-Bv4-qfjp.d.ts → flat-list-D_4y3wgn.d.ts} +4 -4
  21. package/dist/flat-list.d.ts +1 -1
  22. package/dist/flat-list.js +2 -2
  23. package/dist/{grid-list-DaeSHv9P.d.ts → grid-list-CqYS28NY.d.ts} +4 -2
  24. package/dist/{grid-list-51XsR2X2.js → grid-list-Cz2tKcNZ.js} +4 -3
  25. package/dist/grid-list.d.ts +2 -2
  26. package/dist/grid-list.js +1 -1
  27. package/dist/{grouped-item-lister-DZIjo9nO.d.ts → grouped-item-lister-CS4yInuw.d.ts} +2 -2
  28. package/dist/grouped-item-lister.d.ts +1 -1
  29. package/dist/{icon-DR_3rSyZ.d.ts → icon-CDGprSdE.d.ts} +1 -1
  30. package/dist/icons.d.ts +2 -2
  31. package/dist/{incr-search-2YaxUUA9.js → incr-search-Dc6gYpJG.js} +24 -4
  32. package/dist/incr-search.d.ts +1 -1
  33. package/dist/incr-search.js +1 -1
  34. package/dist/{index-BjRoPrwj.d.ts → index-Bm9a9S3_.d.ts} +3 -2
  35. package/dist/{index-garxxqgV.d.ts → index-CYndvTWH.d.ts} +1 -1
  36. package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +1 -1
  37. package/dist/{index-Bz3loIAf.d.ts → index-DN2BWctP.d.ts} +1 -1
  38. package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +1 -1
  39. package/dist/{index-vdbbGE7N.d.ts → index-VAs9akt4.d.ts} +18 -2
  40. package/dist/{index-DXDz60XH.d.ts → index-YCDugjdu.d.ts} +4 -4
  41. package/dist/{index-DM9OLgTH.d.ts → index-ZaA90u09.d.ts} +2 -2
  42. package/dist/index.d.ts +37 -26
  43. package/dist/index.js +88 -13
  44. package/dist/item-appearance-BjcMyauw.js +29 -0
  45. package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +1 -1
  46. package/dist/labelled-radial-input.d.ts +2 -2
  47. package/dist/labelled-range-input.d.ts +1 -1
  48. package/dist/labelled-slider-input.d.ts +1 -1
  49. package/dist/list-group-header.d.ts +1 -1
  50. package/dist/{list-selection-controller-CJDdjH7E.js → list-selection-controller-D4iIrvJH.js} +12 -8
  51. package/dist/{list-selection-types-hj9Njei3.d.ts → list-selection-types-Dnamh2Lu.d.ts} +29 -3
  52. package/dist/{menu-item-B0zqw2xp.d.ts → menu-item-bF6narIz.d.ts} +1 -1
  53. package/dist/menu.d.ts +2 -2
  54. package/dist/{miller-BfrTcujx.js → miller-BrmBywNZ.js} +20 -9
  55. package/dist/miller.d.ts +1 -1
  56. package/dist/miller.js +1 -1
  57. package/dist/narrowed-text.js +1 -1
  58. package/dist/panel.d.ts +1 -1
  59. package/dist/{item-appearance-Bl6rMIID.js → partial-keys-Ck6CiprB.js} +1 -29
  60. package/dist/{split-layout-ChZ0Glrs.d.ts → split-layout-CophkNeU.d.ts} +1 -1
  61. package/dist/split-layout.d.ts +1 -1
  62. package/dist/sunburst-tree.d.ts +1 -1
  63. package/dist/sunburst-tree.js +1 -1
  64. package/dist/{sunbursttree-list-BAS0KrDG.d.ts → sunbursttree-list-Bk20giTF.d.ts} +1 -1
  65. package/dist/{sunbursttree-list-906G33ME.js → sunbursttree-list-DQF6DcsS.js} +1 -1
  66. package/dist/{tab-list-wC0xNz1b.d.ts → tab-list-Df371rqw.d.ts} +1 -1
  67. package/dist/tabs.d.ts +1 -1
  68. package/dist/timeline.d.ts +1 -1
  69. package/dist/{titlebar-B5zSTZnF.d.ts → titlebar-Tqu-VvMU.d.ts} +1 -1
  70. package/dist/titlebar.d.ts +1 -1
  71. package/dist/{tree-C_H1COTf.js → tree-BaXYyt5U.js} +185 -69
  72. package/dist/tree.d.ts +1 -1
  73. package/dist/tree.js +1 -1
  74. package/dist/{vertical-list-od4050Bo.d.ts → vertical-list-DtHX26JO.d.ts} +2 -2
  75. package/dist/{vertical-list-qMRIxZIT.js → vertical-list-o5hfqH87.js} +4 -3
  76. package/dist/vertical-list.d.ts +2 -2
  77. package/dist/vertical-list.js +1 -1
  78. package/docs-user/README.md +6 -0
  79. package/docs-user/bottom-drawer.md +2 -2
  80. package/docs-user/crumbs.md +1 -1
  81. package/docs-user/data-grid.md +3 -3
  82. package/docs-user/detail-list.md +3 -3
  83. package/docs-user/dock.md +3 -3
  84. package/docs-user/flat-list.md +7 -7
  85. package/docs-user/grid-list.md +4 -4
  86. package/docs-user/hyperbolic-tree.md +6 -6
  87. package/docs-user/icicle-tree.md +2 -2
  88. package/docs-user/incr-search.md +1 -1
  89. package/docs-user/index.json +26 -2
  90. package/docs-user/infra-handle.md +122 -0
  91. package/docs-user/infra-incremental.md +154 -0
  92. package/docs-user/infra-theming.md +510 -0
  93. package/docs-user/infra-view-state.md +210 -0
  94. package/docs-user/list-state.md +656 -0
  95. package/docs-user/llms.txt +6 -0
  96. package/docs-user/miller.md +5 -1
  97. package/docs-user/multicol-list.md +6 -0
  98. package/docs-user/panel.md +3 -3
  99. package/docs-user/select-horiz.md +1 -1
  100. package/docs-user/split-layout.md +2 -2
  101. package/docs-user/sunburst-tree.md +3 -3
  102. package/docs-user/titlebar.md +2 -2
  103. package/docs-user/tree.md +8 -2
  104. package/docs-user/treemap.md +2 -2
  105. package/docs-user/twosplit-layout.md +3 -3
  106. package/docs-user/user-selection-intents.md +86 -0
  107. package/docs-user/user-theming.md +1 -1
  108. package/docs-user/vertical-list.md +3 -3
  109. package/llms.txt +6 -0
  110. package/package.json +1 -1
  111. /package/dist/{index-DV3iaUBW.d.ts → index-DV3iaUBW2.d.ts} +0 -0
@@ -62,6 +62,12 @@ one column (the first category) once `categories` is assigned.
62
62
 
63
63
  ---
64
64
 
65
+ ## Selection intents and partial rows
66
+
67
+ Gestures in a column (click, Space, Enter, Shift+Arrow, Cmd/Ctrl+A, marquee, the column's incremental search, the "All" row) fire a cancelable `list-select-intent` on the multicol host with `columnId` set; `keys` are that column's item keys. Going back to "All" is a `clear` intent. `preventDefault()` leaves the column alone.
68
+
69
+ `partialKeys` marks items as partially selected in every column that has an item with that key; `setColumnPartialKeys(columnId, keys)` adds keys for one column only. Selected wins. See [Selection intents, partial rows, unloaded keys](./user-selection-intents.md).
70
+
65
71
  ## Data flow
66
72
 
67
73
  1. A selection change in column *i* re-queries **every other** column; column *i*'s list
@@ -2,7 +2,7 @@
2
2
 
3
3
  An collapsible panel component with support for titles, icons, toolbars, and multiple visual variants.
4
4
 
5
- The header chrome is an `ixfx-titlebar` (see [`ixfx-titlebar`](../titlebar/README.md)); the panel adds the collapsible content area beneath it.
5
+ The header chrome is an `ixfx-titlebar` (see [`ixfx-titlebar`](./titlebar.md)); the panel adds the collapsible content area beneath it.
6
6
 
7
7
  ```html
8
8
  <ixfx-panel title="Settings">
@@ -341,5 +341,5 @@ import type { TitlebarOrientation, TitlebarVariant, TitlebarToggleInteraction, T
341
341
 
342
342
  ## See also
343
343
 
344
- - [`ixfx-titlebar`](../titlebar/README.md) — Standalone titlebar chrome composed by this panel
345
- - [`ixfx-icon`](../icons/README.md) — Icon component used by panel
344
+ - [`ixfx-titlebar`](./titlebar.md) — Standalone titlebar chrome composed by this panel
345
+ - [`ixfx-icon`](./icons.md) — Icon component used by panel
@@ -98,7 +98,7 @@ Click an item (or Tab to the element) to focus it first — a focus ring appears
98
98
  | `--select-horiz-spacer-width` | `10%` | Width of the leading/trailing spacer that lets the first/last item scroll to center |
99
99
  | `--scroll-fade-width` | `30px` | Width of the edge fade and the inner horizontal padding (shared with `scrollFadeStyles`) |
100
100
 
101
- Items are styled with the standard `--item-*` theming tokens (see [`docs/user-theming.md`](../../docs/user-theming.md)):
101
+ Items are styled with the standard `--item-*` theming tokens (see [`docs/user-theming.md`](./user-theming.md)):
102
102
 
103
103
  | Property | State |
104
104
  |---|---|
@@ -132,7 +132,7 @@ Nested `<ixfx-split-layout>` elements create sub-groups:
132
132
  | `--split-collapsed-size` | `0px` | Size of collapsed panels |
133
133
  | `--split-snap` | `24px` | Snap/hysteresis distance |
134
134
  The gutter grip is the shared `dimpled` handle — theme it with the
135
- `--ixfx-handle-*` variables (see [docs/infra-handle.md](../../docs/infra-handle.md)).
135
+ `--ixfx-handle-*` variables (see [docs/infra-handle.md](./infra-handle.md)).
136
136
 
137
137
  ---
138
138
 
@@ -202,7 +202,7 @@ layouts, resizing several splits with one gesture.
202
202
  `getViewState()` / `setViewState()` snapshot and restore the size and
203
203
  collapse of each direct child that has an `id`, as plain JSON (`kind:
204
204
  'split-layout'`). The component never persists anything itself — see
205
- [docs/infra-view-state.md](../../docs/infra-view-state.md) and
205
+ [docs/infra-view-state.md](./infra-view-state.md) and
206
206
  `bindViewState()`.
207
207
 
208
208
  ```ts
@@ -2,7 +2,7 @@
2
2
 
3
3
  `<ixfx-sunbursttree-list>` — a zoomable sunburst over weighted tree data. The zoom node is the centre disc; each ring outward is one generation, and each arc's angle is its share of its parent's value. Every change — data arriving, a different weighting, a zoom — animates from what's on screen to the new layout.
4
4
 
5
- It implements the shared `TreeComponent` interface (see [`src/tree/README.md`](../tree/README.md)), so `TreeDataModel`, `IncrSearchTreeController`, and `TreeComponent`-typed code work unmodified. Geometrically it is a polar [icicle](../icicle-tree/), and shares its API shape.
5
+ It implements the shared `TreeComponent` interface (see [`src/tree/README.md`](./tree.md)), so `TreeDataModel`, `IncrSearchTreeController`, and `TreeComponent`-typed code work unmodified. Geometrically it is a polar [icicle](./icicle-tree.md), and shares its API shape.
6
6
 
7
7
  ---
8
8
 
@@ -123,7 +123,7 @@ All of it is computed in CSS from per-arc custom properties, so the palette is t
123
123
  | `animationDuration` (`animation-duration`) | `number` | `600` | Transition length in ms; `0` snaps. Respects `prefers-reduced-motion` |
124
124
  | `filterPredicate` | `TreeFilterPredicate \| undefined` | `undefined` | Non-matching arcs (with no matching descendant) are dimmed |
125
125
  | `disableKeyboardNavigation` (`disable-keyboard-navigation`) | `boolean` | `false` | Turn off keyboard handling |
126
- | `searchModes` (`search-modes`) | `string \| undefined` | `undefined` | Subset of `navigate select filter` — see [`docs/infra-incremental.md`](../../docs/infra-incremental.md) |
126
+ | `searchModes` (`search-modes`) | `string \| undefined` | `undefined` | Subset of `navigate select filter` — see [`docs/infra-incremental.md`](./infra-incremental.md) |
127
127
  | `exclusivity` | `TreeExclusivity` | `'none'` | Accepted for interface compatibility, ignored |
128
128
  | `selectedNode` / `selectedNodes` | | | Same contract as `ixfx-tree-list` |
129
129
  | `focusedNode` | `TreeNode \| undefined` (read-only) | `undefined` | Current zoom node; `undefined` when showing the full tree |
@@ -174,7 +174,7 @@ All events **bubble** and are **composed**. `depth` counts from the root's child
174
174
 
175
175
  ## View state
176
176
 
177
- Implements the shared view-state API (`getViewState()` / `setViewState()` / `clearPendingViewState()` / `view-state-change`) — see [`docs/infra-view-state.md`](../../docs/infra-view-state.md). `kind` is `sunbursttree-list`.
177
+ Implements the shared view-state API (`getViewState()` / `setViewState()` / `clearPendingViewState()` / `view-state-change`) — see [`docs/infra-view-state.md`](./infra-view-state.md). `kind` is `sunbursttree-list`.
178
178
 
179
179
  | Field | Type | Meaning |
180
180
  |---|---|---|
@@ -97,5 +97,5 @@ import type { TitlebarOrientation, TitlebarVariant, TitlebarToggleInteraction, T
97
97
 
98
98
  ## See also
99
99
 
100
- - [`ixfx-panel`](../panel/README.md) — Collapsible panel that composes this titlebar
101
- - [`ixfx-icon`](../icons/README.md) — Icon component used by the titlebar
100
+ - [`ixfx-panel`](./panel.md) — Collapsible panel that composes this titlebar
101
+ - [`ixfx-icon`](./icons.md) — Icon component used by the titlebar
package/docs-user/tree.md CHANGED
@@ -424,6 +424,12 @@ el.addEventListener('select', ({ detail }) => {
424
424
 
425
425
  ---
426
426
 
427
+ ### Selection intents and partial rows (`ixfx-tree-list`)
428
+
429
+ A cancelable `list-select-intent` fires before a click, Space, Enter, Shift+Arrow, Ctrl/Cmd+A, a checkbox or `selectAll()` changes the selection (in every interaction mode, including `manual`); `preventDefault()` means "I'll apply it". Expansion and the cursor still behave normally. Checking a branch in `checked` mode is one `toggle` intent with `descendants: true` and `checked` (the state it is being set to): `keys` lists the loaded selectable nodes under it, but the caller can express it as a rule ("this folder and everything under it"). `list-select` `{ selectedKeys, previousKeys, previous }` fires next to `select`.
430
+
431
+ `partialKeys` marks nodes as partially selected: in `checked` mode the checkbox is indeterminate if either the loaded descendants or `partialKeys` say so (selected wins over partial); otherwise `data-partial` and an accessible description. Incremental search in `select` mode fires a `match` intent first (see below). See [Selection intents, partial rows, unloaded keys](./user-selection-intents.md).
432
+
427
433
  ## Expansion
428
434
 
429
435
  ### Programmatic expansion
@@ -460,7 +466,7 @@ Notes:
460
466
  ## View state (`ixfx-tree-list`)
461
467
 
462
468
  Snapshot and restore selection, expansion, keyboard cursor and scroll
463
- separately from the data — see [`docs/infra-view-state.md`](../../docs/infra-view-state.md)
469
+ separately from the data — see [`docs/infra-view-state.md`](./infra-view-state.md)
464
470
  for the shared contract. `kind: 'tree-list'`; fields `selected`, `expanded`,
465
471
  `focus`, `scroll`, all keyed by `item.key`.
466
472
 
@@ -695,7 +701,7 @@ el.registry.invoke('list.search.navigate'); // or .select / .filter
695
701
  ```
696
702
 
697
703
  Limit the offered modes with the `search-modes` attribute
698
- (`search-modes="navigate filter"`). Full model: [`docs/infra-incremental.md`](../../docs/infra-incremental.md).
704
+ (`search-modes="navigate filter"`). Full model: [`docs/infra-incremental.md`](./infra-incremental.md).
699
705
 
700
706
  ### Deprecated: `IncrSearchTreeController`
701
707
 
@@ -1,12 +1,12 @@
1
1
  # Treemap
2
2
 
3
- `<ixfx-treemap-list>` — a nested-area (treemap) view over tree data. The zoom root fills the viewport; each node's rectangle is subdivided among its children by `valueAccessor` share. Clicking a branch zooms into it, and ancestors collapse into a breadcrumb strip. It implements the shared `TreeComponent` interface (see [`src/tree/README.md`](../tree/README.md)). See the class docs in `treemap-list.ts` for properties and events.
3
+ `<ixfx-treemap-list>` — a nested-area (treemap) view over tree data. The zoom root fills the viewport; each node's rectangle is subdivided among its children by `valueAccessor` share. Clicking a branch zooms into it, and ancestors collapse into a breadcrumb strip. It implements the shared `TreeComponent` interface (see [`src/tree/README.md`](./tree.md)). See the class docs in `treemap-list.ts` for properties and events.
4
4
 
5
5
  ---
6
6
 
7
7
  ## View state
8
8
 
9
- Implements the shared view-state API (`getViewState()` / `setViewState()` / `clearPendingViewState()` / `view-state-change`) — see [`docs/infra-view-state.md`](../../docs/infra-view-state.md). `kind` is `treemap-list`.
9
+ Implements the shared view-state API (`getViewState()` / `setViewState()` / `clearPendingViewState()` / `view-state-change`) — see [`docs/infra-view-state.md`](./infra-view-state.md). `kind` is `treemap-list`.
10
10
 
11
11
  ```typescript
12
12
  type TreemapListViewState = ViewStateBase & {
@@ -39,7 +39,7 @@ A Lit web component that lays out two elements within a container with a split b
39
39
 
40
40
  When `--handle-size` exceeds `5px` the split bar shows the shared `dimpled` grip —
41
41
  theme it with the `--ixfx-handle-*` variables (see
42
- [docs/infra-handle.md](../../docs/infra-handle.md)).
42
+ [docs/infra-handle.md](./infra-handle.md)).
43
43
 
44
44
  ### Events
45
45
 
@@ -53,7 +53,7 @@ theme it with the `--ixfx-handle-*` variables (see
53
53
  `getViewState()` / `setViewState()` snapshot and restore both sides as plain
54
54
  JSON (`kind: 'twosplit-layout'`), keyed by slot name. The component never
55
55
  persists anything itself — see
56
- [docs/infra-view-state.md](../../docs/infra-view-state.md) and `bindViewState()`.
56
+ [docs/infra-view-state.md](./infra-view-state.md) and `bindViewState()`.
57
57
 
58
58
  ```ts
59
59
  split.getViewState();
@@ -211,7 +211,7 @@ ixfx-twosplit-layout {
211
211
  When `--handle-size` is greater than `5px`, a grip appears in the centre of the
212
212
  split bar — the shared `dimpled` handle (a debossed square grid), oriented along
213
213
  the split. Theme it with the `--ixfx-handle-*` variables; see
214
- [docs/infra-handle.md](../../docs/infra-handle.md).
214
+ [docs/infra-handle.md](./infra-handle.md).
215
215
 
216
216
  ```css
217
217
  ixfx-twosplit-layout {
@@ -0,0 +1,86 @@
1
+ # Selection intents, partial rows, unloaded keys
2
+
3
+ Shared by every list-like component: `ixfx-vertical-list`, `ixfx-flat-list`, `ixfx-detail-list`, `ixfx-grid-list`, `ixfx-data-grid`, `ixfx-miller-list`, `ixfx-tree-list` and `ixfx-multicol-list`. For a caller that owns the selection itself (e.g. a selection that is an expression or a set of rules, not a key set), so a list shows what it is given and reports what the user did.
4
+
5
+ ---
6
+
7
+ ## `list-select-intent` (cancelable)
8
+
9
+ Fired **before** a component changes its selection, in every interaction mode (including `manual`, where nothing is selected by default). `preventDefault()` means "I apply this myself": the component changes nothing. Without it, behaviour is unchanged.
10
+
11
+ ```ts
12
+ type ListSelectIntentDetail = {
13
+ readonly kind:
14
+ | `replace` // plain click / Enter: select only `keys`
15
+ | `toggle` // Cmd/Ctrl-click, Space, sticky tap, checkbox: flip `keys`
16
+ | `extend` // Shift-click / Shift+Arrow: range from `anchorKey` to `targetKey`
17
+ | `all` // Cmd/Ctrl+A or selectAll(): "everything in this view", not a key list
18
+ | `marquee` // drag-select: `keys` covered; `mode` says how they combine with the selection
19
+ | `match` // incremental search in `select` mode / "Select matches"
20
+ | `clear`; // Escape / click on empty space / back to "All" in a multicol column
21
+ readonly keys: readonly string[]; // keys directly affected (empty for `all` / `clear`)
22
+ readonly anchorKey?: string; // `extend`
23
+ readonly targetKey?: string; // `extend`
24
+ readonly mode?: `replace` | `add` | `toggle`; // `marquee`
25
+ readonly additive?: boolean; // `marquee`: `mode` is not `replace`
26
+ readonly query?: string; // `match`: the search text
27
+ readonly groupKey?: string | null; // `all`: the group the select-all is confined to
28
+ readonly descendants?: boolean; // `toggle` on a tree branch checkbox: node + loaded descendants
29
+ readonly checked?: boolean; // ...and the state it is being set to
30
+ readonly columnId?: string; // multicol-list: the column
31
+ readonly source: `pointer` | `keyboard` | `touch` | `api`;
32
+ };
33
+ ```
34
+
35
+ ```ts
36
+ list.addEventListener('list-select-intent', (e) => {
37
+ e.preventDefault();
38
+ const { kind, keys, anchorKey, targetKey } = e.detail;
39
+ // ...compute the new selection from your own model, then:
40
+ list.selectKeys(newKeys);
41
+ });
42
+ ```
43
+
44
+ - **`extend` gives endpoints.** `keys` also holds the range as loaded here, but rows in between may not be loaded (virtualised / progressive listings): compute the range from your own order using `anchorKey` / `targetKey`.
45
+ - **`all` is a meaning, not a list.** Turn it into your own scope rule instead of enumerating keys. In grouped lists with `cross-group-selection` off, select-all is confined to one group (the anchor's group, else the cursor's): `groupKey` names it, so a caller that takes over does the same. It is absent when select-all is not confined.
46
+ - **`marquee` `mode`.** `replace`: the selection becomes the covered `keys` (plain drag). `add`: covered keys are added (Shift-drag). `toggle`: each covered key flips, so a Cmd/Ctrl-drag can deselect. `additive` is just `mode !== 'replace'`; use `mode`.
47
+ - **`match` is a search.** Incremental search in `select` mode (typing, and `selectMatches()` / the "Select matches" button) reports `{ kind: 'match', query, keys }` — `keys` are the current matches, a convenience; `query` is what to keep as a live rule. Cancelling it leaves the selection untouched while the popover keeps showing the matches. Source is `keyboard` while typing, `pointer` for the button, `api` for `selectMatches()`.
48
+ - **Tree branch checkboxes.** In `ixfx-tree-list` `checked` mode, checking a branch is one `toggle` with `descendants: true` and `checked` (the state the branch is being set to); `keys` lists the loaded selectable nodes under it, but express it as a rule.
49
+ - **Cursor and anchor keep moving when cancelled.** They are view state, not selection; the next `extend` still has its `anchorKey`.
50
+ - **Who fires it.** Gestures (click, Space, Enter, double-click, checkbox, Shift+Arrow, Cmd/Ctrl+A, marquee, Escape, click on empty space) and `selectAll()`. The imperative `select()` / `selectKeys()` / `clearSelection()` family never fires it, so applying your decision through them cannot re-enter your handler.
51
+ - **`manual` mode.** The intent is reported and nothing else happens, so the caller never re-implements modifier handling. (`ixfx-data-grid` keeps Space toggling in `manual`, as before.)
52
+ - **Not covered.** Right-click auto-select and the drag-origin auto-select of native drag-out still apply directly. `ixfx-miller-list` reports click / checkbox / Shift+Arrow; it has no select-all, and Escape navigates rather than clears.
53
+
54
+ ## `list-select` (consistent)
55
+
56
+ Every list-like component fires `list-select` with the same key-based detail:
57
+
58
+ ```ts
59
+ { selectedKeys: ReadonlySet<string>, previousKeys: ReadonlySet<string> /* , plus component-specific extras */ }
60
+ ```
61
+
62
+ Vertical-list, detail-list and grid-list keep their element-based `selected` / `previous`; data-grid keeps `datagrid-select` (and adds `list-select` with `previous` as keys); miller keeps `select` (and adds `list-select`). One adapter can read any of them through `selectedKeys` / `previousKeys`. Miller now also fires for Cmd-click and Shift-click selection changes.
63
+
64
+ ## `partialKeys`
65
+
66
+ A row whose resource is only partly selected (a time range of an audio file, a region of an image):
67
+
68
+ ```ts
69
+ list.partialKeys = ['k1', 'k2']; // ReadonlySet<string> getter; replace-on-set
70
+ ```
71
+
72
+ - Independent of `selectedKeys`; a key in both counts as selected.
73
+ - Light-DOM lists (vertical, detail): `data-partial` on the row; grid-list cell and data-grid row: `data-partial` plus `.partial` (`part="item partial"` on grid-list); miller: `.partial`.
74
+ - Accessibility: in `checked` mode the checkbox is indeterminate with `aria-checked="mixed"`; otherwise the row gets `aria-description="Partially selected"` (an author-set `aria-description` is never overwritten).
75
+ - Style hooks: `--item-bg-partial`, `--item-border-partial` (`--grid-list-partial-outline` on grid-list).
76
+ - `ixfx-flat-list` forwards `partialKeys` to its inner list. In `checked` mode (tree-list and miller-list alike) indeterminate comes from loaded descendants or `partialKeys`, whichever says so.
77
+
78
+ ## Selected keys that aren't loaded yet
79
+
80
+ `selectKeys()` on vertical-list, flat-list (`flat.list`), detail-list and grid-list keeps keys with no row yet as *pending* and selects them when the row appears (`selectedKeys` lists only present rows). `addSelectedKeys()` does the same; `removeSelectedKeys()` also drops pending keys. Any explicit gesture-driven selection change supersedes pending keys, in single-select only the last unresolved key is kept, and pending keys are capped (2000, oldest dropped). `ixfx-data-grid` already behaved this way. A key that is selected and then leaves the data is reselected if it returns (view-state pending).
81
+
82
+ ## Per-component notes
83
+
84
+ - **`ixfx-tree-list`** — also fires `list-select` next to `select`. `partialKeys` combines with the checkbox state derived from loaded descendants: indeterminate if either says so; selected wins.
85
+ - **`ixfx-multicol-list`** — the intent is re-fired on the host with `columnId`; the "All" row is a `clear`. `partialKeys` applies to every column with a matching item key; `setColumnPartialKeys(columnId, keys)` targets one column.
86
+ - **`ixfx-miller-list`** — same contract as the tree: a branch checkbox is one `toggle` with `descendants: true` and `checked`, `keys` = the node and its loaded descendants; `partialKeys` combines with the derived checkbox state (indeterminate if either says so; selected wins).
@@ -482,7 +482,7 @@ If you're upgrading from previous versions:
482
482
 
483
483
  For implementation details, see:
484
484
  - [`docs/infra-theming.md`](infra-theming.md) - Internal theming specification
485
- - [`docs-user/icons.md`](/docs-user/icons.md) - Full icon registry reference
485
+ - [`docs-user/icons.md`](./icons.md) - Full icon registry reference
486
486
  - [`demo/loader.html?demo=icons`](/demo/loader.html?demo=icons) - Interactive icons demo
487
487
  - [`src/style.css`] - Base theme definitions
488
488
  - [`demo/shared/`] - Example theme implementations
@@ -537,7 +537,7 @@ type ListItemClickDetail = { readonly item: Element };
537
537
  ### Caller-owned selection: `list-select-intent` and `partialKeys`
538
538
 
539
539
  `list-select-intent` is fired before any gesture changes the selection (in every `interactionMode`, including `manual`); `preventDefault()` means "I'll apply it". `partialKeys` marks rows as partially selected (`data-partial`, indeterminate checkbox in `checked` mode). Both are shared across the list-like components.
540
- See [Selection intents, partial rows, unloaded keys](../../docs/infra-selection-intents.md): `list-select-intent`, `partialKeys`, and keys that arrive later.
540
+ See [Selection intents, partial rows, unloaded keys](./user-selection-intents.md): `list-select-intent`, `partialKeys`, and keys that arrive later.
541
541
 
542
542
  ### Usage example
543
543
 
@@ -620,7 +620,7 @@ The element must be focused (click it or tab to it) before keyboard navigation w
620
620
 
621
621
  ## Incremental search
622
622
 
623
- A built-in type-ahead popover with three modes — **navigate** (cursor jumps to the best match, ↑/↓ cycle), **select** (matches become the selection), **filter** (non-matches hidden). See [`docs/infra-incremental.md`](../../docs/infra-incremental.md) for the full model, conversions between modes, and the `search-modes` attribute.
623
+ A built-in type-ahead popover with three modes — **navigate** (cursor jumps to the best match, ↑/↓ cycle), **select** (matches become the selection), **filter** (non-matches hidden). See [`docs/infra-incremental.md`](./infra-incremental.md) for the full model, conversions between modes, and the `search-modes` attribute.
624
624
 
625
625
  There is **no default shortcut**. Open it by invoking one of the commands on `list.registry`:
626
626
 
@@ -701,7 +701,7 @@ The event is cancelable: call `preventDefault()` to suppress the browser's nativ
701
701
 
702
702
  Rename is **opt-in**: set `editValidator = (value, key) => boolean` first. Without it `beginEdit` returns `false` and rows stay plain text. The validator runs on commit; returning `false` rejects the text and the edit ends as a cancel.
703
703
 
704
- `list.beginEdit(key)` swaps an [`ixfx-editable-label`](../editable-label/README.md) into the row, selects its text and focuses it. It returns `false` if there is no `editValidator`, or the row is unknown or not rendered.
704
+ `list.beginEdit(key)` swaps an [`ixfx-editable-label`](./editable-label.md) into the row, selects its text and focuses it. It returns `false` if there is no `editValidator`, or the row is unknown or not rendered.
705
705
 
706
706
  The editor replaces the row's `[data-edit-label]` element, or the whole row if there is none. Mark the text element in rows that carry icons or badges, and set `data-edit-value` there if the editable text differs from its content.
707
707
 
package/llms.txt CHANGED
@@ -73,6 +73,12 @@ import '@ixfx/components/data-grid';
73
73
  - [xy-pad](docs-user/xy-pad.md): A 2D touch-friendly XY pad for controlling two parameters simultaneously. Each axis supports independent linear/logarithmic scaling.
74
74
 
75
75
  ## Overviews
76
+ - [infra-handle.md](docs-user/infra-handle.md)
77
+ - [infra-incremental.md](docs-user/infra-incremental.md)
78
+ - [infra-theming.md](docs-user/infra-theming.md)
76
79
  - [infra-tickled.md](docs-user/infra-tickled.md)
80
+ - [infra-view-state.md](docs-user/infra-view-state.md)
81
+ - [list-state.md](docs-user/list-state.md)
77
82
  - [user-catalog.md](docs-user/user-catalog.md)
83
+ - [user-selection-intents.md](docs-user/user-selection-intents.md)
78
84
  - [user-theming.md](docs-user/user-theming.md)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ixfx/components",
3
3
  "type": "module",
4
- "version": "0.16.2",
4
+ "version": "0.16.4",
5
5
  "packageManager": "pnpm@10.0.0",
6
6
  "description": "Web components for ixfx — Lit-based UI toolkit",
7
7
  "author": "Clint Heyer",