@ixfx/components 0.12.0 → 0.13.1

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 (130) hide show
  1. package/bundle/index.d.ts +337 -73
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +7396 -6523
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.d.ts +1 -1
  6. package/dist/ac-text.js +1 -1
  7. package/dist/{ac-token--_vCHXWw.d.ts → ac-token-TCLAZeVg.d.ts} +2 -2
  8. package/dist/{ac-token--_vCHXWw.d.ts.map → ac-token-TCLAZeVg.d.ts.map} +1 -1
  9. package/dist/ac-token.d.ts +1 -1
  10. package/dist/ac-token.js +1 -1
  11. package/dist/{button-BYuf72aR.d.ts → button-CTL45aBl.d.ts} +2 -2
  12. package/dist/{button-BYuf72aR.d.ts.map → button-CTL45aBl.d.ts.map} +1 -1
  13. package/dist/button.d.ts +1 -1
  14. package/dist/{checked-select-Dejl13qd.js → checked-select-lDgAQQ7v.js} +3 -3
  15. package/dist/{checked-select-Dejl13qd.js.map → checked-select-lDgAQQ7v.js.map} +1 -1
  16. package/dist/checked-select.js +1 -1
  17. package/dist/colour-picker.d.ts +1 -1
  18. package/dist/crumbs.d.ts +4 -4
  19. package/dist/crumbs.d.ts.map +1 -1
  20. package/dist/crumbs.js +26 -10
  21. package/dist/crumbs.js.map +1 -1
  22. package/dist/{data-grid-Cl_CPSD7.d.ts → data-grid-Ck1Qx2H1.d.ts} +5 -5
  23. package/dist/{data-grid-Cl_CPSD7.d.ts.map → data-grid-Ck1Qx2H1.d.ts.map} +1 -1
  24. package/dist/data-grid.d.ts +2 -2
  25. package/dist/data-grid.js +3 -3
  26. package/dist/{detail-list-lE_5UWVl.d.ts → detail-list-C1xzr1z7.d.ts} +5 -5
  27. package/dist/{detail-list-lE_5UWVl.d.ts.map → detail-list-C1xzr1z7.d.ts.map} +1 -1
  28. package/dist/detail-list.d.ts +3 -3
  29. package/dist/detail-list.js +1 -1
  30. package/dist/editable-label-rzXkjf1H.d.ts.map +1 -1
  31. package/dist/editable-label.js +2 -2
  32. package/dist/editable-label.js.map +1 -1
  33. package/dist/flat-list-DEDG6epz.d.ts +181 -0
  34. package/dist/flat-list-DEDG6epz.d.ts.map +1 -0
  35. package/dist/flat-list.d.ts +2 -0
  36. package/dist/flat-list.js +654 -0
  37. package/dist/flat-list.js.map +1 -0
  38. package/dist/{grid-list-Bwaf61is.js → grid-list-DjIl910A.js} +3 -3
  39. package/dist/{grid-list-Bwaf61is.js.map → grid-list-DjIl910A.js.map} +1 -1
  40. package/dist/{grid-list-Bc-RkDoO.d.ts → grid-list-pefLORIr.d.ts} +5 -5
  41. package/dist/{grid-list-Bc-RkDoO.d.ts.map → grid-list-pefLORIr.d.ts.map} +1 -1
  42. package/dist/grid-list.d.ts +2 -2
  43. package/dist/grid-list.js +1 -1
  44. package/dist/{grouped-item-lister-DETte0Dh.d.ts → grouped-item-lister-Bhyo-dkH.d.ts} +2 -2
  45. package/dist/{grouped-item-lister-DETte0Dh.d.ts.map → grouped-item-lister-Bhyo-dkH.d.ts.map} +1 -1
  46. package/dist/grouped-item-lister.d.ts +1 -1
  47. package/dist/{icon-CDGprSdE.d.ts → icon-DR_3rSyZ.d.ts} +2 -2
  48. package/dist/icon-DR_3rSyZ.d.ts.map +1 -0
  49. package/dist/icons.d.ts +2 -2
  50. package/dist/incr-search.d.ts +1 -1
  51. package/dist/{index-tq6f8007.d.ts → index-BOUaDIW-.d.ts} +2 -2
  52. package/dist/{index-tq6f8007.d.ts.map → index-BOUaDIW-.d.ts.map} +1 -1
  53. package/dist/{index-CoqtMSd9.d.ts → index-BUB5SICW.d.ts} +2 -2
  54. package/dist/{index-CoqtMSd9.d.ts.map → index-BUB5SICW.d.ts.map} +1 -1
  55. package/dist/{index-UvnoZUAo.d.ts → index-CJ5fshD3.d.ts} +2 -2
  56. package/dist/{index-UvnoZUAo.d.ts.map → index-CJ5fshD3.d.ts.map} +1 -1
  57. package/dist/{index-CMsmZ6Or.d.ts → index-CxZ61DO1.d.ts} +4 -4
  58. package/dist/{index-CMsmZ6Or.d.ts.map → index-CxZ61DO1.d.ts.map} +1 -1
  59. package/dist/{index-CSEtqm1T.d.ts → index-Dq30pOnn.d.ts} +4 -4
  60. package/dist/{index-CSEtqm1T.d.ts.map → index-Dq30pOnn.d.ts.map} +1 -1
  61. package/dist/{index-CYndvTWH.d.ts → index-garxxqgV.d.ts} +2 -2
  62. package/dist/{index-CYndvTWH.d.ts.map → index-garxxqgV.d.ts.map} +1 -1
  63. package/dist/index-o-CWDt11.d.ts +78 -0
  64. package/dist/index-o-CWDt11.d.ts.map +1 -0
  65. package/dist/index.d.ts +26 -25
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +10 -9
  68. package/dist/index.js.map +1 -1
  69. package/dist/{interaction-BskmlA9t.js → interaction-ZTh4htzr.js} +1 -1
  70. package/dist/{labelled-input-base-DiTme1JO.d.ts → labelled-input-base-Dp_9KP0G.d.ts} +2 -2
  71. package/dist/{labelled-input-base-DiTme1JO.d.ts.map → labelled-input-base-Dp_9KP0G.d.ts.map} +1 -1
  72. package/dist/labelled-radial-input.d.ts +2 -2
  73. package/dist/labelled-radial-input.d.ts.map +1 -1
  74. package/dist/labelled-range-input.d.ts +1 -1
  75. package/dist/labelled-slider-input.d.ts +1 -1
  76. package/dist/list-group-header.d.ts +1 -1
  77. package/dist/{list-native-drag-controller-CllsHLxw.d.ts → list-native-drag-controller-ChIi3eK5.d.ts} +2 -2
  78. package/dist/{list-native-drag-controller-CllsHLxw.d.ts.map → list-native-drag-controller-ChIi3eK5.d.ts.map} +1 -1
  79. package/dist/{menu-DaAlsyhf.js → menu-CwcXXeLM.js} +3 -3
  80. package/dist/{menu-DaAlsyhf.js.map → menu-CwcXXeLM.js.map} +1 -1
  81. package/dist/{menu-item-bF6narIz.d.ts → menu-item-B0zqw2xp.d.ts} +2 -2
  82. package/dist/{menu-item-bF6narIz.d.ts.map → menu-item-B0zqw2xp.d.ts.map} +1 -1
  83. package/dist/{menu-item-CDPFgaSF.js → menu-item-BDEekBVy.js} +3 -3
  84. package/dist/{menu-item-CDPFgaSF.js.map → menu-item-BDEekBVy.js.map} +1 -1
  85. package/dist/menu.d.ts +2 -2
  86. package/dist/menu.js +2 -2
  87. package/dist/miller.d.ts +4 -4
  88. package/dist/miller.js +2 -2
  89. package/dist/narrowed-text.d.ts +2 -78
  90. package/dist/narrowed-text.js +2 -2
  91. package/dist/panel.d.ts +1 -1
  92. package/dist/select-horiz.js +2 -2
  93. package/dist/{split-layout-JK3xWVX2.d.ts → split-layout-C5SYbDrq.d.ts} +2 -2
  94. package/dist/{split-layout-JK3xWVX2.d.ts.map → split-layout-C5SYbDrq.d.ts.map} +1 -1
  95. package/dist/split-layout.d.ts +1 -1
  96. package/dist/{tab-list-pqfKaVAE.d.ts → tab-list-v8mKX7Fu.d.ts} +2 -2
  97. package/dist/{tab-list-pqfKaVAE.d.ts.map → tab-list-v8mKX7Fu.d.ts.map} +1 -1
  98. package/dist/tabs.d.ts +1 -1
  99. package/dist/{tickled-controller-Dh1Uh_vG.js → tickled-controller-D-HZymaZ.js} +10 -1
  100. package/dist/tickled-controller-D-HZymaZ.js.map +1 -0
  101. package/dist/{tickled-controller-C1ZsHpyg.d.ts → tickled-controller-DodxD3eQ.d.ts} +7 -1
  102. package/dist/{tickled-controller-C1ZsHpyg.d.ts.map → tickled-controller-DodxD3eQ.d.ts.map} +1 -1
  103. package/dist/{titlebar-Tqu-VvMU.d.ts → titlebar-B5zSTZnF.d.ts} +2 -2
  104. package/dist/{titlebar-Tqu-VvMU.d.ts.map → titlebar-B5zSTZnF.d.ts.map} +1 -1
  105. package/dist/titlebar.d.ts +1 -1
  106. package/dist/{tree-Bm2TzTfe.js → tree-DGveys4K.js} +3 -3
  107. package/dist/{tree-Bm2TzTfe.js.map → tree-DGveys4K.js.map} +1 -1
  108. package/dist/{tree-component-DukLqesg.d.ts → tree-component-Cj8V3uar.d.ts} +2 -2
  109. package/dist/{tree-component-DukLqesg.d.ts.map → tree-component-Cj8V3uar.d.ts.map} +1 -1
  110. package/dist/tree.d.ts +5 -5
  111. package/dist/tree.js +1 -1
  112. package/dist/{types-D-kYF16b.d.ts → types-DQ7KOUIj.d.ts} +6 -1
  113. package/dist/types-DQ7KOUIj.d.ts.map +1 -0
  114. package/dist/{vertical-list-DTp-UIUE.d.ts → vertical-list-CqBc-t8w.d.ts} +86 -4
  115. package/dist/vertical-list-CqBc-t8w.d.ts.map +1 -0
  116. package/dist/vertical-list.d.ts +3 -3
  117. package/dist/vertical-list.js +211 -3
  118. package/dist/vertical-list.js.map +1 -1
  119. package/docs-user/README.md +1 -0
  120. package/docs-user/flat-list.md +110 -0
  121. package/docs-user/index.json +7 -2
  122. package/docs-user/llms.txt +1 -0
  123. package/docs-user/vertical-list.md +59 -3
  124. package/llms.txt +1 -0
  125. package/package.json +5 -1
  126. package/dist/icon-CDGprSdE.d.ts.map +0 -1
  127. package/dist/narrowed-text.d.ts.map +0 -1
  128. package/dist/tickled-controller-Dh1Uh_vG.js.map +0 -1
  129. package/dist/types-D-kYF16b.d.ts.map +0 -1
  130. package/dist/vertical-list-DTp-UIUE.d.ts.map +0 -1
@@ -0,0 +1,110 @@
1
+ # `ixfx-flat-list`
2
+
3
+ Navigate a tree inside one flat list. Each level shows its branches and leaves together; entering a branch replaces the list with that branch's children. An [`ixfx-crumb-navigation`](../crumbs/README.md) above the scroll area shows the path and jumps to any ancestor.
4
+
5
+ It wraps [`ixfx-vertical-list`](../vertical-list/README.md), so selection modes, interaction modes, keyboard shortcuts, incremental search, drag-out and drag-select behave as they do there. The data model is the same `TreeNode` / `TreeDataModel` that `ixfx-crumb-navigation` and `ixfx-tree-list` use.
6
+
7
+ ```html
8
+ <ixfx-flat-list style="height: 280px"></ixfx-flat-list>
9
+ ```
10
+
11
+ ```typescript
12
+ const list = document.querySelector('ixfx-flat-list')!;
13
+ list.root = { item: { key: 'root', label: 'Home' }, children: [/* … */] };
14
+ list.addEventListener('flat-list-activate', ({ detail }) => open(detail.node));
15
+ ```
16
+
17
+ ## Properties
18
+
19
+ | Property / attribute | Type | Default | Description |
20
+ |---|---|---|---|
21
+ | `root` | `TreeNode` | | Root of the tree |
22
+ | `model` | `TreeDataModel` | | Alternative to `root` (and `loadChildren`); stays in sync with model changes |
23
+ | `path` | `readonly string[]` | `[]` | Keys from the root (excluded) to the level shown |
24
+ | `loadChildren` | `LoadChildrenCallback` | | Loads a branch whose `children` is `undefined`. Results are written back to `node.children`, as in crumb-navigation |
25
+ | `filterPredicate` | `(node, depth) => boolean` | | Hides non-matching nodes |
26
+ | `sort` | `(a, b) => number` | | Orders nodes within a level |
27
+ | `branchOrder` / `branch-order` | `'first' \| 'mixed'` | `'first'` | `first`: branches then leaves. `mixed`: one list in `sort` / source order |
28
+ | `selectionMode` / `selection-mode` | | `'single'` | As `ixfx-vertical-list` |
29
+ | `interactionMode` / `interaction-mode` | | `'standard'` | As `ixfx-vertical-list` |
30
+ | `itemWrap`, `searchModes`, `itemsDraggable` | | | Passed to the inner list |
31
+ | `itemsDroppable` / `items-droppable` | `boolean` | `false` | Rows and empty space accept native drops. See [Drops](#drops) |
32
+ | `canDrop` | `(node, dataTransfer) => boolean` | | Refuse a drag up front. `node` is the row, or the current level's node over empty space |
33
+ | `validateEdit` | `(value, node) => boolean` | | Opts in to [rename](#rename) and validates the typed text |
34
+ | `markedKey` / `marked-key` | `string` | | Keep this node's row visibly marked across level changes. Not a selection |
35
+ | `virtualize`, `itemHeight` / `item-height` | `boolean`, `number` | `false`, `0` | Render only visible rows; needs a fixed row height. See [virtualisation](../vertical-list/README.md#virtualisation) |
36
+ | `withUp` / `with-up` | `boolean` | `true` | Up button in the crumb bar |
37
+ | `hideRoot` / `hide-root` | `boolean` | `false` | Hide the root crumb |
38
+ | `emptyText` / `empty-text` | `string` | `'Empty'` | Shown for a level with no children |
39
+
40
+ A node counts as a branch unless `item.isLeaf` is `true` or its `children` is `[]`. Set `item.isLeaf: false` to force a branch even when `children` is `[]`: an empty folder that can still be entered, showing `emptyText`. `item.icon`, `iconColor`, `textColor` and `badge` are honoured.
41
+
42
+ ## Methods
43
+
44
+ | Method | Description |
45
+ |---|---|
46
+ | `navigateTo(keys)` | Show the level at this key path. `false` if it does not resolve |
47
+ | `navigateInto(key)` | Enter a child branch |
48
+ | `navigateUp()` | Go to the parent. `false` at the root |
49
+ | `currentNode` | Node whose children are listed |
50
+ | `selectedNodes` | Selected `TreeNode`s in the current level |
51
+ | `beginEdit(key)` | Rename a row in place. Needs `validateEdit` and `item.editable`; `false` otherwise |
52
+ | `registry` / `dispatch(id, args)` | The inner list's command registry, e.g. `dispatch('list.search.filter')` |
53
+ | `list` | The inner `ixfx-vertical-list` |
54
+
55
+ ## Events
56
+
57
+ | Event | Detail | When |
58
+ |---|---|---|
59
+ | `flat-list-navigate` | `{ path, previousPath, node, direction }` | The level changed. `direction` is `into`, `up` or `jump` |
60
+ | `flat-list-select` | `{ selected, selectedKeys, previous }` | Selection changed (nodes, not elements) |
61
+ | `flat-list-activate` | `{ node }` | A **leaf** was double-clicked or Enter was pressed |
62
+ | `flat-list-drop` | `{ node, dataTransfer }` | Something was dropped. See [Drops](#drops) |
63
+ | `flat-list-context-menu` | `{ node, nodes, x, y }` | Cancelable. See [Context menu](#context-menu) |
64
+ | `flat-list-edit-commit` | `{ node, value }` | A rename was committed |
65
+ | `flat-list-edit-cancel` | `{ node }` | A rename ended without a change |
66
+
67
+ The inner list's `list-*` events also cross the shadow boundary, with row elements as their `item`.
68
+
69
+ ## Navigation
70
+
71
+ | Gesture | Action |
72
+ |---|---|
73
+ | Click the chevron, double-click, `Enter`, `Arrow Right` on a branch | Enter it |
74
+ | `Arrow Left`, `Backspace` | Go up. The cursor lands on the branch you came from |
75
+ | Crumb, caret menu, Up button | Jump to that node. Choosing a leaf from a caret menu shows its level and selects it |
76
+ | Everything else | See [vertical-list keyboard navigation](../vertical-list/README.md#keyboard-navigation) |
77
+
78
+ Selection is cleared on every level change. Arrow Left and Backspace are ignored while the search field is focused.
79
+
80
+ ## Drops
81
+
82
+ With `items-droppable`, a drag over a row, or over empty space, is accepted unless `canDrop` refuses it. A drop fires `flat-list-drop` with that row's node, or the **current level's node** for empty space. Dropping on a branch row reports it and does **not** enter it. Native OS drags work: `dataTransfer` carries `files`, `text/uri-list` and any custom MIME type the source wrote. The row under the drag gets the vertical-list [drop highlight](../vertical-list/README.md#drop-targets).
83
+
84
+ ## Context menu
85
+
86
+ `flat-list-context-menu` fires on right-click or the menu key. The row is selected first, so `nodes` is the selection to act on and `node` is the row clicked. Open your own `ixfx-menu-container` at `x, y`. Call `preventDefault()` to suppress the native menu.
87
+
88
+ ## Rename
89
+
90
+ Rename is **opt-in**: set `validateEdit = (value, node) => boolean`, and mark the rows that may be renamed with `item.editable: true`. Without both, rows are plain text and `beginEdit` returns `false`. Returning `false` from the validator rejects the text and the edit ends as a cancel.
91
+
92
+ ```typescript
93
+ list.validateEdit = (value, node) => value.trim() !== '' && !names.has(value);
94
+ list.addEventListener('flat-list-edit-commit', ({ detail }) => rename(detail.node.item.key, detail.value));
95
+ list.beginEdit('set:2'); // e.g. from your own context menu
96
+ ```
97
+
98
+ `beginEdit(key)` starts the edit. Commit and cancel arrive as `flat-list-edit-commit` / `flat-list-edit-cancel`. The label is not rewritten for you: change `item.label` in your tree in response, and the level refreshes.
99
+
100
+ ## Incremental search
101
+
102
+ Navigate / select / filter search works over the current level, as in [`ixfx-vertical-list`](../vertical-list/README.md#incremental-search) — see [`docs/infra-incremental.md`](../../docs/infra-incremental.md). `search-modes` limits the modes. There is no default shortcut: bind a key or button to `dispatch('list.search.filter')` (or `.navigate` / `.select`). The highlight rule is built in, so no page-level `::highlight()` rule is needed. The search is closed when the level changes.
103
+
104
+ ## CSS variables
105
+
106
+ `--flat-list-bg`, `--flat-list-text`, `--flat-list-border`, `--flat-list-radius`, `--flat-list-crumb-padding`, `--flat-list-crumb-font-size` (default `--text-s`), `--flat-list-chevron-gap`, `--flat-list-marked-bg`, `--flat-list-marked-bar`, `--flat-list-empty-text`. Each falls back to the matching `--list-*` variable. Other `--list-*` variables (e.g. `--list-item-height`) reach the inner list.
107
+
108
+ ## CSS parts
109
+
110
+ `crumbs` (the bar above the list), `empty`.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ixfx/components",
3
- "version": "0.11.9",
4
- "generated": "2026-10-01T18:46:24.117Z",
3
+ "version": "0.13.1",
4
+ "generated": "2026-10-01T20:18:51.052Z",
5
5
  "components": [
6
6
  {
7
7
  "name": "ac-text",
@@ -73,6 +73,11 @@
73
73
  "summary": "Inline editable text components. `ixfx-editable-number` extends `ixfx-editable-label` with drag-to-adjust and fill-bar visualization.",
74
74
  "path": "docs-user/editable-label.md"
75
75
  },
76
+ {
77
+ "name": "flat-list",
78
+ "summary": "Navigate a tree inside one flat list. Each level shows its branches and leaves together; entering a branch replaces the list with that branch's children. An [`ixfx-crumb-navigation`](../crumbs/README.",
79
+ "path": "docs-user/flat-list.md"
80
+ },
76
81
  {
77
82
  "name": "form",
78
83
  "summary": "Primitives for typical form layout with responsive label positioning and data binding.",
@@ -25,6 +25,7 @@ import '@ixfx/components/data-grid';
25
25
  - [detail-list](docs-user/detail-list.md): A list that scales horizontally, not vertically. Items are laid out in equal-width columns; they flow top→bottom down a column, then wrap to the top of the next column to the right. The component has
26
26
  - [dock](docs-user/dock.md): Dockable, movable panels like VS Code / Photoshop. Drag a panel by its
27
27
  - [editable-label](docs-user/editable-label.md): Inline editable text components. `ixfx-editable-number` extends `ixfx-editable-label` with drag-to-adjust and fill-bar visualization.
28
+ - [flat-list](docs-user/flat-list.md): Navigate a tree inside one flat list. Each level shows its branches and leaves together; entering a branch replaces the list with that branch's children. An [`ixfx-crumb-navigation`](../crumbs/README.
28
29
  - [form](docs-user/form.md): Primitives for typical form layout with responsive label positioning and data binding.
29
30
  - [grid-list](docs-user/grid-list.md): A virtualised grid of items — thumbnails, cards, or arbitrary slotted markup —
30
31
  - [grouped-item-lister](docs-user/grouped-item-lister.md): A meta-component that renders a typed item list using any sub-component you supply. Items can be displayed in a single sub-component (_ungrouped_ mode) or split into labelled groups, each with its own
@@ -16,9 +16,12 @@ A scrollable vertical list of items with selection, keyboard navigation, and inc
16
16
  8. [Native drag-out](#native-drag-out)
17
17
  9. [Keyboard navigation](#keyboard-navigation)
18
18
  10. [Incremental search](#incremental-search)
19
- 11. [Virtualisation](#virtualisation)
20
- 12. [CSS variables](#css-variables)
21
- 13. [CSS parts](#css-parts)
19
+ 11. [Drop targets](#drop-targets)
20
+ 12. [Context menu](#context-menu)
21
+ 13. [In-place rename](#in-place-rename)
22
+ 14. [Virtualisation](#virtualisation)
23
+ 15. [CSS variables](#css-variables)
24
+ 16. [CSS parts](#css-parts)
22
25
 
23
26
  ---
24
27
 
@@ -120,6 +123,9 @@ To reflect selection state inside the custom element's shadow DOM, target the `:
120
123
  | `interactionMode` / `interaction-mode` | `ListInteractionMode` | `'standard'` | How gestures map to selection changes (see table below) |
121
124
  | `virtualize` / `virtualize` | `boolean` | `false` | Only render the viewport window (+ overscan) into the DOM; pool and recycle the rest. See [Virtualisation](#virtualisation) |
122
125
  | `itemHeight` / `item-height` | `number` | `0` | Fixed row height in px. Required for `virtualize` — every row must be exactly this tall |
126
+ | `itemsDroppable` / `items-droppable` | `boolean` | `false` | Rows and empty space accept native drops. See [Drop targets](#drop-targets) |
127
+ | `editValidator` | `((value, key) => boolean) \| undefined` | `undefined` | Opts in to [in-place rename](#in-place-rename) and validates the typed text. Unset ⇒ rows are plain text |
128
+ | `canDrop` | `((item, dataTransfer) => boolean) \| undefined` | `undefined` | Refuse a drag before any event or highlight |
123
129
  | `filterPredicate` | `((el: Element) => boolean) \| undefined` | `undefined` | External filter; only items returning `true` are shown |
124
130
  | `checkboxRenderer` | `((checked: boolean) => unknown) \| CustomCheckboxOptions \| undefined` | `undefined` | Custom content for the checkbox in `checked` mode. See [Custom checkbox](#custom-checkbox) |
125
131
  | `formatter` | `((item: unknown, index: number) => unknown) \| undefined` | `undefined` | Renders one `items` entry into its row. See [Adapter items](#adapter-items) |
@@ -645,6 +651,56 @@ list.filterPredicate = undefined;
645
651
 
646
652
  ---
647
653
 
654
+ ## Drop targets
655
+
656
+ Set `items-droppable` to make rows — and the empty space around them — accept native drags, including OS drags carrying files (`dataTransfer.files`, `text/uri-list`, custom MIME types).
657
+
658
+ | Event | Detail | Notes |
659
+ |---|---|---|
660
+ | `list-drag-over` | `{ key, item, dataTransfer }` | Cancelable. **`preventDefault()` accepts the drop**; without it the drag is refused. Fires repeatedly while the drag moves |
661
+ | `list-drop` | `{ key, item, dataTransfer }` | The drop landed |
662
+ | `list-drag-leave` | `{ key }` | The drag left its last target (also when it is cancelled) |
663
+
664
+ `key` / `item` are `undefined` over empty list space. The list sets `dropEffect` to `copy` when you accept without choosing one — set `dataTransfer.dropEffect` in the `list-drag-over` handler to override.
665
+
666
+ The row under the drag gets `data-drop-target` (the host does, over empty space). Style it with `--list-drop-target-bg` and `--list-drop-target-outline`.
667
+
668
+ `canDrop = (item, dataTransfer) => boolean` refuses a drag up front — no events, no highlight — e.g. to let a leaf row refuse what a folder row accepts.
669
+
670
+ ```typescript
671
+ list.itemsDroppable = true;
672
+ list.canDrop = (item, dt) => item?.hasAttribute('data-folder') ?? false;
673
+ list.addEventListener('list-drag-over', e => e.preventDefault());
674
+ list.addEventListener('list-drop', ({ detail }) => addFiles(detail.key, detail.dataTransfer.files));
675
+ ```
676
+
677
+ ---
678
+
679
+ ## Context menu
680
+
681
+ `list-context-menu` `{ key, item, x, y, selectedKeys }` fires on right-click, and for the menu key (or Shift+F10) on the cursor row. A row that is not selected is selected first, as dragging does, so `selectedKeys` is what the menu acts on. Open your own `ixfx-menu-container` at `x, y` (viewport coordinates).
682
+
683
+ The event is cancelable: call `preventDefault()` to suppress the browser's native menu. The menu key never shows the native menu; it only fires this event. Right-clicking empty space fires nothing.
684
+
685
+ ---
686
+
687
+ ## In-place rename
688
+
689
+ 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.
690
+
691
+ `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.
692
+
693
+ 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.
694
+
695
+ | Event | Detail | When |
696
+ |---|---|---|
697
+ | `list-edit-commit` | `{ key, value }` | Enter or blur with a changed value |
698
+ | `list-edit-cancel` | `{ key }` | Escape, an unchanged value, or one the label rejects |
699
+
700
+ The list never rewrites the label itself; the original row content returns when editing ends. Update your data in response to `list-edit-commit`. `editingKey` reports the row being edited. Keys typed in the editor do not reach the list.
701
+
702
+ ---
703
+
648
704
  ## Virtualisation
649
705
 
650
706
  Set `virtualize` to window the list: only the rows near the viewport (plus an overscan of 3 rows) ever exist in the DOM. Everything else is pooled off-DOM and recycled **by identity** as you scroll, so a list of tens of thousands of rows keeps a tiny, fast DOM. Works for hand-supplied `<li>` / `data-list-item` elements **and** adapter (`items`) rows.
package/llms.txt CHANGED
@@ -25,6 +25,7 @@ import '@ixfx/components/data-grid';
25
25
  - [detail-list](docs-user/detail-list.md): A list that scales horizontally, not vertically. Items are laid out in equal-width columns; they flow top→bottom down a column, then wrap to the top of the next column to the right. The component has
26
26
  - [dock](docs-user/dock.md): Dockable, movable panels like VS Code / Photoshop. Drag a panel by its
27
27
  - [editable-label](docs-user/editable-label.md): Inline editable text components. `ixfx-editable-number` extends `ixfx-editable-label` with drag-to-adjust and fill-bar visualization.
28
+ - [flat-list](docs-user/flat-list.md): Navigate a tree inside one flat list. Each level shows its branches and leaves together; entering a branch replaces the list with that branch's children. An [`ixfx-crumb-navigation`](../crumbs/README.
28
29
  - [form](docs-user/form.md): Primitives for typical form layout with responsive label positioning and data binding.
29
30
  - [grid-list](docs-user/grid-list.md): A virtualised grid of items — thumbnails, cards, or arbitrary slotted markup —
30
31
  - [grouped-item-lister](docs-user/grouped-item-lister.md): A meta-component that renders a typed item list using any sub-component you supply. Items can be displayed in a single sub-component (_ungrouped_ mode) or split into labelled groups, each with its own
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ixfx/components",
3
3
  "type": "module",
4
- "version": "0.12.0",
4
+ "version": "0.13.1",
5
5
  "packageManager": "pnpm@10.0.0",
6
6
  "description": "Web components for ixfx — Lit-based UI toolkit",
7
7
  "author": "Clint Heyer",
@@ -48,6 +48,10 @@
48
48
  "types": "./dist/editable-label.d.ts",
49
49
  "import": "./dist/editable-label.js"
50
50
  },
51
+ "./flat-list": {
52
+ "types": "./dist/flat-list.d.ts",
53
+ "import": "./dist/flat-list.js"
54
+ },
51
55
  "./hex": {
52
56
  "types": "./dist/hex.d.ts",
53
57
  "import": "./dist/hex.js"
@@ -1 +0,0 @@
1
- {"version":3,"file":"icon-CDGprSdE.d.ts","names":[],"sources":["../src/icons/icon.ts"],"mappings":";;cAUa,wBAAwB;;EACvB;EACgB;EAChB;EAC0C;EACU;EAevD;EAMA;YAMU,iBAAM,wBAAA;YA4BN,QAAQ,SAAS;SAoBpB,sBAAM;;QAiDhB;YACI;IACR,aAAa"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"narrowed-text.d.ts","names":[],"sources":["../src/narrowed-text/types.ts","../src/narrowed-text/narrowed-text.ts"],"mappings":";;;KAAY,mBAAmB;EAC7B;EACA;EACA;EACA;EACA;;KAGU;WACD,MAAM;WACN;WACA,mBAAmB;;KAGlB,0BAA0B,YAAY;KAEtC;KAEA;KAEA;EACV,MAAM;EACN,WAAW;EACX;;;;cCEW,4BAA4B;;EACkB,eAAe;EACV;EACR,aAAa;EACjB;EACE;EACJ;EACC;EACU;EAC/B;EAG5B,UAAU;UAEO;UACA;UACA;UACA;UACM;UAEf;UACA;UACA;UAIA;UACA;UAGA;MAqBJ;MAQA,SAAS;EAgBb;EA0BA;EAmBS;EA+BA;YAcU;YAIA,QAAQ,mBAAmB;UAWtC;UAiBA;UAeA;UAIA;EAiJR;EAUA;EASA,YAAY,UAAU;EA4BtB,WAAW;UAuCH;UAmCA;YA4BW,wBAAM;UAqCjB;SAWQ,sBAAM;;QA6IhB;YACI;IACR,sBAAsB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tickled-controller-Dh1Uh_vG.js","names":[],"sources":["../src/interaction/tickled-controller.ts"],"sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit';\n\n/**\n * Represents an item that can be tickled (highlighted via hover or keyboard navigation)\n */\nexport type TickledItem<T = unknown> = {\n /**\n * Unique identifier for the item (e.g., index, id, path)\n */\n readonly id: T;\n\n /**\n * Whether the item is currently enabled/interactive\n */\n readonly enabled?: boolean;\n};\n\n/**\n * Input mode determines which mechanism controls the tickled state\n */\nexport type InputMode = `keyboard` | `mouse`;\n\n/**\n * Configuration for TickledController\n */\nexport type TickledControllerConfig<T> = {\n /**\n * Function to retrieve all items that can be tickled\n */\n getItems: () => ReadonlyArray<TickledItem<T>>;\n\n /**\n * Optional callback when an item becomes tickled\n * Use this for side effects like opening submenus\n * @param id - The id of the newly tickled item, or undefined if nothing is tickled\n */\n onTickle?: (id: T | undefined) => void;\n\n /**\n * Optional callback fired after any state change (tickled id or input mode)\n * Use this to sync DOM attributes for slotted content that can't use reactive rendering\n *\n * For components that render items directly, this is usually not needed as\n * Lit's reactive rendering will handle updates automatically via requestUpdate()\n *\n * @example\n * ```ts\n * onStateChange: () => {\n * // Sync data-tickled attributes for slotted items\n * const items = this.getItems();\n * items.forEach((item, i) => {\n * if (this.tickled.isTickled(i)) {\n * item.setAttribute('data-tickled', '');\n * } else {\n * item.removeAttribute('data-tickled');\n * }\n * });\n * }\n * ```\n */\n onStateChange?: () => void;\n\n /**\n * Optional initial input mode (defaults to 'mouse')\n */\n initialInputMode?: InputMode;\n\n /**\n * When this returns `true`, pointer hover no longer drives the cursor:\n * `handlePointerEnter` / `handlePointerLeave` become no-ops and hover never\n * switches the input mode to `mouse`. Keyboard navigation, programmatic\n * `focus()` / `setTickled()`, and click handling are unaffected. Read on every\n * hover event, so a host can flip it via a reactive property. Default: `false`.\n */\n hoverDisabled?: () => boolean;\n\n /**\n * Whether keyboard navigation wraps from last to first and vice versa.\n * - 'stop' (default): navigation stops at the boundary\n * - 'wrap': navigation wraps around\n */\n itemWrap?: `stop` | `wrap`;\n};\n\n/**\n * ReactiveController that manages \"tickled\" state for interactive lists.\n *\n * A \"tickled\" item is one that is under active attention via hover (mouse mode)\n * or keyboard focus (keyboard mode). Only one item can be tickled at a time.\n *\n * The input mode determines which mechanism controls tickled state:\n * - Mouse mode: hover controls tickled, keyboard navigation ignored\n * - Keyboard mode: keyboard navigation controls tickled, hover ignored\n *\n * Last interaction wins - any mouse hover switches to mouse mode, any keyboard\n * navigation switches to keyboard mode.\n *\n * ## Global Mouse Tracking\n *\n * This controller uses a single, ref-counted global `pointermove` listener (shared\n * across all instances) to track actual mouse movement. This prevents `pointerenter`\n * events caused by content scrolling from incorrectly switching to mouse mode when\n * the user is actually using keyboard navigation. The listener is attached when the\n * first host connects and removed once the last host disconnects.\n *\n * @example\n * ```ts\n * class MyList extends LitElement {\n * private tickled = new TickledController(this, {\n * getItems: () => this.items.map((item, i) => ({ id: i, enabled: !item.disabled })),\n * onTickle: (id) => {\n * // Optional: perform side effect when item is tickled\n * console.log('Tickled item:', id);\n * }\n * });\n *\n * render() {\n * return html`\n * <ul @pointerleave=${(e) => this.tickled.handlePointerLeave(e)}>\n * ${this.items.map((item, i) => html`\n * <li\n * class=\"item ${this.tickled.isTickled(i) ? 'tickled' : ''}\"\n * @pointerenter=${() => this.tickled.handlePointerEnter(i)}\n * >${item.label}</li>\n * `)}\n * </ul>\n * `;\n * }\n *\n * private handleKeyDown(e: KeyboardEvent) {\n * if (e.key === 'ArrowDown') {\n * this.tickled.handleKeyboardNavigation('next');\n * } else if (e.key === 'ArrowUp') {\n * this.tickled.handleKeyboardNavigation('previous');\n * }\n * }\n * }\n * ```\n */\nexport class TickledController<T = number> implements ReactiveController {\n private host: ReactiveControllerHost;\n private config: TickledControllerConfig<T>;\n private _tickledId: T | undefined = undefined;\n private _inputMode: InputMode;\n private hoverDisabled: () => boolean;\n\n private static _lastMouseClientX: number = Number.NaN;\n private static _lastMouseClientY: number = Number.NaN;\n private static _mouseMovedSinceKeyboard: boolean = true;\n private static _listenerRefCount: number = 0;\n\n private static readonly _onGlobalPointerMove = (e: PointerEvent): void => {\n TickledController.handleGlobalPointerMove(e.clientX, e.clientY);\n };\n\n constructor(host: ReactiveControllerHost, config: TickledControllerConfig<T>) {\n this.host = host;\n this.config = config;\n this._inputMode = config.initialInputMode ?? `mouse`;\n this.hoverDisabled = config.hoverDisabled ?? (() => false);\n host.addController(this);\n }\n\n hostConnected(): void {\n if (TickledController._listenerRefCount === 0) {\n document.addEventListener(`pointermove`, TickledController._onGlobalPointerMove, { passive: true });\n }\n TickledController._listenerRefCount++;\n }\n\n hostDisconnected(): void {\n TickledController._listenerRefCount--;\n if (TickledController._listenerRefCount === 0) {\n document.removeEventListener(`pointermove`, TickledController._onGlobalPointerMove);\n }\n }\n\n /**\n * Get the current input mode\n */\n get inputMode(): InputMode {\n return this._inputMode;\n }\n\n /**\n * Get the currently tickled item id\n */\n get tickledId(): T | undefined {\n return this._tickledId;\n }\n\n /**\n * The item currently under the cursor, or `undefined`. Alias of `tickledId`\n * for parity with other controllers.\n */\n get current(): T | undefined {\n return this._tickledId;\n }\n\n /**\n * Move the cursor programmatically (e.g. to reveal a match or re-seat it\n * after the item set changed). Does not change the input mode. Alias of\n * `setTickled`.\n */\n focus(id: T | undefined): void {\n this.setTickled(id);\n }\n\n /**\n * Check if a specific item is tickled\n */\n isTickled(id: T): boolean {\n return this._tickledId === id;\n }\n\n /**\n * Handle global pointer move event.\n * Called automatically by the global listener.\n * Tracks mouse movement to distinguish real hover from content scrolling.\n */\n private static handleGlobalPointerMove(clientX: number, clientY: number): void {\n if (!Number.isNaN(TickledController._lastMouseClientX)) {\n if (\n clientX !== TickledController._lastMouseClientX\n || clientY !== TickledController._lastMouseClientY\n ) {\n TickledController._mouseMovedSinceKeyboard = true;\n }\n }\n TickledController._lastMouseClientX = clientX;\n TickledController._lastMouseClientY = clientY;\n }\n\n /**\n * Check if actual mouse movement has occurred since last keyboard interaction.\n * Used to distinguish real hover/leave from content-scrolling-induced events.\n */\n static get hasMouseMovedSinceKeyboard(): boolean {\n return TickledController._mouseMovedSinceKeyboard;\n }\n\n /**\n * Handle pointer enter event on an item (mouse hover).\n * Only processes if actual mouse movement is detected (not content scrolling).\n * Switches to mouse mode and tickles the item.\n */\n handlePointerEnter(id: T): void {\n if (this.hoverDisabled()) {\n return;\n }\n\n if (!TickledController._mouseMovedSinceKeyboard) {\n return;\n }\n\n const items = this.config.getItems();\n const item = items.find(item => item.id === id);\n if (item && item.enabled === false) {\n return;\n }\n\n const modeChanged = this._inputMode !== `mouse`;\n this._inputMode = `mouse`;\n\n const previousId = this._tickledId;\n this._tickledId = id;\n\n this.host.requestUpdate();\n\n if (previousId !== id && this.config.onTickle) {\n this.config.onTickle(id);\n }\n\n if ((previousId !== id || modeChanged) && this.config.onStateChange) {\n this.config.onStateChange();\n }\n }\n\n /**\n * Handle pointer leave event on an item.\n * Only clears tickled state if actual mouse movement is detected.\n * @param _e The pointer event (not used, but kept for API compatibility)\n */\n handlePointerLeave(_e: PointerEvent): void {\n if (this.hoverDisabled()) {\n return;\n }\n if (TickledController._mouseMovedSinceKeyboard) {\n this.clearTickled();\n }\n }\n\n /**\n * Handle keyboard navigation.\n * Switches to keyboard mode and moves tickled state.\n *\n * @param direction - 'next', 'previous', 'first', 'last', or specific id\n */\n handleKeyboardNavigation(direction: `next` | `previous` | `first` | `last` | T): void {\n const modeChanged = this._inputMode !== `keyboard`;\n this._inputMode = `keyboard`;\n\n const items = this.config.getItems();\n const enabledItems = items.filter(item => item.enabled !== false);\n\n if (enabledItems.length === 0) {\n return;\n }\n\n let newId: T | undefined;\n\n if (direction === `first`) {\n newId = enabledItems[0].id;\n } else if (direction === `last`) {\n newId = enabledItems.at(-1)?.id;\n } else if (direction === `next` || direction === `previous`) {\n const currentIndex = enabledItems.findIndex(item => item.id === this._tickledId);\n const wrap = this.config.itemWrap === `wrap`;\n\n if (currentIndex === -1) {\n newId = direction === `next` ? enabledItems[0].id : enabledItems.at(-1)?.id;\n } else {\n const delta = direction === `next` ? 1 : -1;\n let newIndex = currentIndex + delta;\n\n if (newIndex >= 0 && newIndex < enabledItems.length) {\n newId = enabledItems[newIndex].id;\n } else if (wrap) {\n // Wrap around\n if (newIndex < 0) {\n newIndex = enabledItems.length - 1;\n } else {\n newIndex = 0;\n }\n newId = enabledItems[newIndex].id;\n }\n // If newIndex is out of bounds and wrap is disabled, keep current tickled item\n }\n } else {\n const item = enabledItems.find(item => item.id === direction);\n if (item) {\n newId = item.id;\n }\n }\n\n if (newId !== undefined) {\n const previousId = this._tickledId;\n this._tickledId = newId;\n this.host.requestUpdate();\n\n if (previousId !== newId && this.config.onTickle) {\n this.config.onTickle(newId);\n }\n\n if ((previousId !== newId || modeChanged) && this.config.onStateChange) {\n this.config.onStateChange();\n }\n }\n }\n\n /**\n * Manually set the tickled item (useful for programmatic control).\n * Does NOT change input mode.\n */\n setTickled(id: T | undefined): void {\n const previousId = this._tickledId;\n this._tickledId = id;\n this.host.requestUpdate();\n\n if (previousId !== id && this.config.onTickle) {\n this.config.onTickle(id);\n }\n\n if (previousId !== id && this.config.onStateChange) {\n this.config.onStateChange();\n }\n }\n\n /**\n * Clear the tickled state (e.g., on pointer leave).\n * Note: For pointer leave events, prefer using handlePointerLeave() which\n * checks for actual mouse movement.\n */\n clearTickled(): void {\n if (this._tickledId !== undefined) {\n this._tickledId = undefined;\n this.host.requestUpdate();\n\n if (this.config.onTickle) {\n this.config.onTickle(undefined);\n }\n\n if (this.config.onStateChange) {\n this.config.onStateChange();\n }\n }\n }\n\n /**\n * Manually set the input mode.\n * When switching to keyboard mode, resets the mouse movement tracking.\n */\n setInputMode(mode: InputMode): void {\n if (this._inputMode !== mode) {\n this._inputMode = mode;\n this.host.requestUpdate();\n\n if (mode === `keyboard`) {\n TickledController._mouseMovedSinceKeyboard = false;\n }\n\n if (this.config.onStateChange) {\n this.config.onStateChange();\n }\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types-D-kYF16b.d.ts","names":[],"sources":["../src/common/types.ts"],"mappings":";;KAQY;;EAEV;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;EAMA;;;;;;EAMA;;;;;;;;EAQA;;EAEA;;EAEA;;;;;;;EAOA;;;KAIU;EACV,MAAM;;;;;;;EAON,WAAW;;;;;;;KAQD,uBAAuB;EAAgB,MAAM;EAAU;GAAiB;;;;;;KAOxE,uBAAuB,MAAM,UAAU;;;;;;;KAQvC;;;;;;;;;KAUA;;;;;;;;;KAUA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"vertical-list-DTp-UIUE.d.ts","names":[],"sources":["../src/vertical-list/vertical-list.ts"],"mappings":";;;;;;;UA4DiB;EACf,WAAW;EACX;EACA;;UAGe;;;;;;EAMf;;cAkCW,4BAA4B;;EAEvC,eAAe;EAGf,iBAAiB;EAGjB,mBAAmB,IAAI;;;;;;EAQvB;;;;;;;;;;;;;;;;;;;EAqBA,oBAAoB,gCAAgC;;;;;;EAQpD;;;;;;EAQA;;;;;EAOA,qBAAqB,wBAAwB;EAG7C,mBAAmB,8BAA8B;;;;;;;;;;;EAajD;;;;;EAOA;;;;;;;;;EAWA,aAAa,eAAe;;;;;;;EAS5B,QAAQ,eAAe;;;;;EAOvB,aAAa,eAAe;;;;;EAO5B,aAAa,eAAe;;;;;;EAQ5B,SAAS,eAAe;;;;;;;;;;;;;;;;;;EAoBxB;;;;;;EAQA;mBAyCiB;UAeT;UA6EA;;WA6EC,QAAM,qBAAA;;MAYX,YAAY;EA2BP;EAsBA;;;;;;YA4BU;EAwDV,QAAQ,SAAS;;MAgFtB,gBAAgB;;MAKhB,iBAAiB,YAAY;EAIjC,QAAQ,MAAM,kBAAkB,UAAU;;;;;;;EA4B1C,WAAW,MAAM,UAAU;;EA2B3B,YAAY,OAAO,SAAS,WAAW;EAIvC;;;;;;EAmBA,SAAS,gBAAgB;;;;;;EAwBzB,SAAS,WAAW,WAAW,OAAO;EAItC,OAAO,MAAM;EAIb,WAAW,OAAO,SAAS;EAI3B,SAAS,MAAM;EAIf;EAIA;;MAQI,gBAAgB;;MAKhB;;EAMJ,WAAW,MAAM;;EAKjB,gBAAgB,MAAM;;EAKtB,mBAAmB,MAAM;;;;;;EASzB,SAAS;;EAgCT,aAAa,cAAc;;;;;;;;EAW3B;;;;;;;EAuBA;EAsBE,eAAe,0CAA0C,UAAU;;;;;EA2CrE,YAAY,MAAM;;;;;;;;;;;EAclB,WAAW,aAAa;UAmiBhB;UAgBA;UAOA;UAiBA;;;;;;;UA4GA;;;;;UAuBA;UAcA;UAYA;UAQA;UAWA;UAMA;UAIA;UAwDA;UAUA;UAMA;SAUQ,sBAAM;EA2Kb,wBAAM;;QAeT;YACI;IACR,sBAAsB;;YAGd,4BAA4B;;UAGvB,oCAAoC;EACnD,iCAAiC;EACjC,0BAA0B,yBAAyB"}