@ixfx/components 0.16.2 → 0.16.3

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 (91) hide show
  1. package/bundle/index.d.ts +59 -5
  2. package/bundle/index.js +148 -140
  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-DXDz60XH.d.ts → index-DyaHA9Kk.d.ts} +2 -2
  39. package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +1 -1
  40. package/dist/{index-vdbbGE7N.d.ts → index-VAs9akt4.d.ts} +18 -2
  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-Be7x4ufN.js} +3 -2
  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 +1 -0
  79. package/docs-user/data-grid.md +1 -1
  80. package/docs-user/grid-list.md +1 -1
  81. package/docs-user/index.json +6 -2
  82. package/docs-user/llms.txt +1 -0
  83. package/docs-user/miller.md +4 -0
  84. package/docs-user/multicol-list.md +6 -0
  85. package/docs-user/select-horiz.md +1 -1
  86. package/docs-user/tree.md +6 -0
  87. package/docs-user/user-selection-intents.md +86 -0
  88. package/docs-user/vertical-list.md +1 -1
  89. package/llms.txt +1 -0
  90. package/package.json +1 -1
  91. /package/dist/{index-DV3iaUBW.d.ts → index-DV3iaUBW2.d.ts} +0 -0
@@ -33,7 +33,14 @@ type ListSelectKeysDetail = Pick<ListSelectDetail, `selectedKeys` | `previousKey
33
33
  * What the user (or API) is trying to do to the selection. See
34
34
  * {@link ListSelectIntentDetail}.
35
35
  */
36
- type ListSelectIntentKind = `replace` | `toggle` | `extend` | `all` | `marquee` | `clear`;
36
+ type ListSelectIntentKind = `replace` | `toggle` | `extend` | `all` | `marquee` | `match` | `clear`;
37
+ /**
38
+ * How a `marquee` combines the covered keys with the current selection:
39
+ * `replace` (plain drag: the selection becomes the covered keys), `add`
40
+ * (Shift-drag: covered keys are added), `toggle` (Cmd/Ctrl-drag: each covered
41
+ * key flips, so a drag can deselect).
42
+ */
43
+ type ListMarqueeMode = `replace` | `add` | `toggle`;
37
44
  type ListSelectIntentSource = `pointer` | `keyboard` | `touch` | `api`;
38
45
  /**
39
46
  * Detail of the cancelable `list-select-intent` event: fired *before* a
@@ -54,8 +61,27 @@ type ListSelectIntentDetail = {
54
61
  readonly anchorKey?: string;
55
62
  /** Range end, for `extend`. */
56
63
  readonly targetKey?: string;
57
- /** Add to rather than replace the selection (a modifier was held). */
64
+ /** `marquee`: a modifier was held, i.e. `mode` is not `replace`. */
58
65
  readonly additive?: boolean;
66
+ /** `marquee`: how the covered `keys` combine with the selection. */
67
+ readonly mode?: ListMarqueeMode;
68
+ /** `match`: the search text. `keys` holds the current matches (a convenience). */
69
+ readonly query?: string;
70
+ /**
71
+ * `all`: the group the select-all is confined to (grouped lists with
72
+ * cross-group selection off). Absent when it is not confined to a group.
73
+ */
74
+ readonly groupKey?: string | null;
75
+ /**
76
+ * `toggle` from a branch checkbox in a tree: the toggle applies to the node
77
+ * and every loaded node under it (`keys` lists them), as a rule rather than
78
+ * a key list.
79
+ */
80
+ readonly descendants?: boolean;
81
+ /** `toggle` with `descendants`: the state the branch is being set to (`true` = checked). */
82
+ readonly checked?: boolean;
83
+ /** Multi-column lists (`ixfx-multicol-list`): the column the intent is for. Keys are that column's item keys. */
84
+ readonly columnId?: string;
59
85
  readonly source: ListSelectIntentSource;
60
86
  };
61
87
  type ListTickleDetail = {
@@ -80,4 +106,4 @@ interface ListElementEventMap {
80
106
  'list-item-click': ListItemClickEvent;
81
107
  }
82
108
  //#endregion
83
- export { ListItemClickDetail as a, ListSelectEvent as c, ListSelectIntentKind as d, ListSelectIntentSource as f, ListTickleEvent as g, ListTickleDetail as h, ListInteractionMode as i, ListSelectIntentDetail as l, ListSelectionMode as m, ListActivateEvent as n, ListItemClickEvent as o, ListSelectKeysDetail as p, ListElementEventMap as r, ListSelectDetail as s, ListActivateDetail as t, ListSelectIntentEvent as u };
109
+ export { ListTickleEvent as _, ListItemClickDetail as a, ListSelectDetail as c, ListSelectIntentEvent as d, ListSelectIntentKind as f, ListTickleDetail as g, ListSelectionMode as h, ListInteractionMode as i, ListSelectEvent as l, ListSelectKeysDetail as m, ListActivateEvent as n, ListItemClickEvent as o, ListSelectIntentSource as p, ListElementEventMap as r, ListMarqueeMode as s, ListActivateDetail as t, ListSelectIntentDetail as u };
@@ -1,4 +1,4 @@
1
- import "./icon-DR_3rSyZ.js";
1
+ import "./icon-CDGprSdE.js";
2
2
  import { LitElement } from "lit";
3
3
  import { CommandRegistry, KeyboardManager } from "@clinth/ui-commands";
4
4
  //#region src/menu/menu-container.d.ts
package/dist/menu.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { i as MenuContainer, n as MenuTrigger, t as MenuItem } from "./menu-item-B0zqw2xp.js";
2
- import { a as menuFromTree, c as MenuSeparator, d as MenuCheckItem, f as MenuBar, i as MenuFromTreeOptions, l as MenuSubTrigger, n as MenuRadioGroup, o as menuFromTreeToElements, r as MenuRadioItem, s as MenuHeader, u as MenuCommandController } from "./index-DM9OLgTH.js";
1
+ import { i as MenuContainer, n as MenuTrigger, t as MenuItem } from "./menu-item-bF6narIz.js";
2
+ import { a as menuFromTree, c as MenuSeparator, d as MenuCheckItem, f as MenuBar, i as MenuFromTreeOptions, l as MenuSubTrigger, n as MenuRadioGroup, o as menuFromTreeToElements, r as MenuRadioItem, s as MenuHeader, u as MenuCommandController } from "./index-ZaA90u09.js";
3
3
  export { MenuBar, MenuCheckItem, MenuCommandController, MenuContainer, type MenuFromTreeOptions, MenuHeader, MenuItem, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSubTrigger, MenuTrigger, menuFromTree, menuFromTreeToElements };
@@ -2,12 +2,13 @@ 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 { i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, t as createTreeListSearchAdapter } from "./incr-search-2YaxUUA9.js";
5
+ import { i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, t as createTreeListSearchAdapter } from "./incr-search-Dc6gYpJG.js";
6
6
  import { a as capKeys, d as partitionKeys, l as keysToArray, n as EMPTY_KEYS } from "./pending-BGidHppL.js";
7
- import { a as isPartialKey, n as appearanceColor, o as sameKeySet, r as PARTIAL_DESCRIPTION, t as appearanceAbsent } from "./item-appearance-Bl6rMIID.js";
7
+ import { i as sameKeySet, r as isPartialKey, t as PARTIAL_DESCRIPTION } from "./partial-keys-Ck6CiprB.js";
8
8
  import "./interaction-E-uMGHkJ.js";
9
9
  import { t as collectDataResult } from "./data-provider-35TyWclX.js";
10
10
  import { a as restoreElementScroll, i as onUserScrollIntent, o as scrollToOffset, r as captureElementScroll, t as ViewStateController } from "./view-state-controller-BdyXWUUM.js";
11
+ import { n as appearanceColor, t as appearanceAbsent } from "./item-appearance-BjcMyauw.js";
11
12
  import { LitElement, css, html, nothing } from "lit";
12
13
  import { property, state } from "lit/decorators.js";
13
14
  import { createCommandRegistry } from "@clinth/ui-commands";
package/dist/miller.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { A as TreeTickleDetail, O as TreeSelectDetail, b as TreeItemClickDetail, i as TreeCollapseEvent, j as TreeTickleEvent, k as TreeSelectEvent, n as TreeActivateEvent, r as TreeCollapseDetail, t as TreeActivateDetail, v as TreeExpandDetail, x as TreeItemClickEvent, y as TreeExpandEvent } from "./tree-component-DgfkxmVY.js";
2
2
  import { a as TreeItem, o as TreeNode } from "./types-Jky6oNAp.js";
3
- import { _ as MillerRebaseEvent, a as MillerBaseElementEventMap, c as MillerHeaderClickEvent, d as MillerItemDblClickDetail, f as MillerItemDblClickEvent, g as MillerRebaseDetail, h as MillerItemState, i as MillerBaseElement, l as MillerHeaderRightClickDetail, m as MillerItemRightClickEvent, n as MillerTreeControllerOptions, o as MillerListViewState, p as MillerItemRightClickDetail, r as MillerListElement, s as MillerHeaderClickDetail, t as MillerTreeController, u as MillerHeaderRightClickEvent, v as MillerSelectionMode } from "./index-DXDz60XH.js";
3
+ import { _ as MillerRebaseEvent, a as MillerBaseElementEventMap, c as MillerHeaderClickEvent, d as MillerItemDblClickDetail, f as MillerItemDblClickEvent, g as MillerRebaseDetail, h as MillerItemState, i as MillerBaseElement, l as MillerHeaderRightClickDetail, m as MillerItemRightClickEvent, n as MillerTreeControllerOptions, o as MillerListViewState, p as MillerItemRightClickDetail, r as MillerListElement, s as MillerHeaderClickDetail, t as MillerTreeController, u as MillerHeaderRightClickEvent, v as MillerSelectionMode } from "./index-DyaHA9Kk.js";
4
4
  export { type TreeActivateDetail as MillerActivateDetail, type TreeActivateEvent as MillerActivateEvent, MillerBaseElement, MillerBaseElementEventMap, type TreeCollapseDetail as MillerCollapseDetail, type TreeCollapseEvent as MillerCollapseEvent, type TreeExpandDetail as MillerExpandDetail, type TreeExpandEvent as MillerExpandEvent, MillerHeaderClickDetail, MillerHeaderClickEvent, MillerHeaderRightClickDetail, MillerHeaderRightClickEvent, type TreeItem as MillerItem, type TreeItemClickDetail as MillerItemClickDetail, type TreeItemClickEvent as MillerItemClickEvent, MillerItemDblClickDetail, MillerItemDblClickEvent, MillerItemRightClickDetail, MillerItemRightClickEvent, MillerItemState, MillerListElement, type MillerListViewState, type TreeNode as MillerNode, MillerRebaseDetail, MillerRebaseEvent, type TreeSelectDetail as MillerSelectDetail, type TreeSelectEvent as MillerSelectEvent, MillerSelectionMode, type TreeTickleDetail as MillerTickleDetail, type TreeTickleEvent as MillerTickleEvent, MillerTreeController, MillerTreeControllerOptions };
package/dist/miller.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as MillerListElement, r as MillerBaseElement, t as MillerTreeController } from "./miller-BfrTcujx.js";
1
+ import { n as MillerListElement, r as MillerBaseElement, t as MillerTreeController } from "./miller-Be7x4ufN.js";
2
2
  export { MillerBaseElement, MillerListElement, MillerTreeController };
@@ -3,7 +3,7 @@ import { t as TickledController } from "./tickled-controller-D-HZymaZ.js";
3
3
  import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrAHEj1q.js";
4
4
  import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
5
5
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
6
- import { m as createIncrSearch } from "./incr-search-2YaxUUA9.js";
6
+ import { m as createIncrSearch } from "./incr-search-Dc6gYpJG.js";
7
7
  import "./interaction-E-uMGHkJ.js";
8
8
  import { LitElement, css, html, nothing } from "lit";
9
9
  import { property, query, state } from "lit/decorators.js";
package/dist/panel.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as TitlebarToggleDetail, c as TitlebarVariant, i as TitlebarOrientation, o as TitlebarToggleEvent, s as TitlebarToggleInteraction, t as TitlebarCloseEvent } from "./titlebar-B5zSTZnF.js";
1
+ import { a as TitlebarToggleDetail, c as TitlebarVariant, i as TitlebarOrientation, o as TitlebarToggleEvent, s as TitlebarToggleInteraction, t as TitlebarCloseEvent } from "./titlebar-Tqu-VvMU.js";
2
2
  import { LitElement } from "lit";
3
3
  //#region src/panel/panel.d.ts
4
4
  /** Backwards-compatible aliases: canonical types now live in `../titlebar/titlebar.js`. */
@@ -29,32 +29,4 @@ function applyPartialAttributes(el, partial) {
29
29
  } else if (el.getAttribute(`aria-description`) === PARTIAL_DESCRIPTION) el.removeAttribute(`aria-description`);
30
30
  }
31
31
  //#endregion
32
- //#region src/common/item-appearance.ts
33
- /**
34
- * Shared helpers for the list components' per-item appearance hooks — the
35
- * per-item icon colour / text colour / badge that miller-list, detail-list,
36
- * grid-list, data-grid and vertical-list all accept.
37
- *
38
- * Every component takes these three features in its own idiom (plain fields
39
- * on a `TreeItem`, a property-name lookup, an adapter function, a nominated
40
- * column) but they all agree on what "not supplied" means, and on never
41
- * emitting an empty slot for an absent value.
42
- */
43
- /**
44
- * Whether a per-item appearance value counts as "not supplied". `false` and
45
- * `''` are included so a consumer can clear a feature without rebuilding the
46
- * collection — e.g. `badge: flags && tagChip(flags.colour)`.
47
- */
48
- function appearanceAbsent(value) {
49
- return value === void 0 || value === null || value === false || value === ``;
50
- }
51
- /**
52
- * A usable CSS colour from a per-item value, or `undefined`. Non-strings and
53
- * empty strings are ignored rather than stringified, so a stray number or
54
- * `0` never lands in a `style` attribute.
55
- */
56
- function appearanceColor(value) {
57
- return typeof value === `string` && value.length > 0 ? value : void 0;
58
- }
59
- //#endregion
60
- export { isPartialKey as a, applyPartialAttributes as i, appearanceColor as n, sameKeySet as o, PARTIAL_DESCRIPTION as r, appearanceAbsent as t };
32
+ export { sameKeySet as i, applyPartialAttributes as n, isPartialKey as r, PARTIAL_DESCRIPTION as t };
@@ -194,7 +194,7 @@ declare class SplitLayoutElement extends LitElement {
194
194
  private _onPointerUp;
195
195
  private _emitResize;
196
196
  private _emitChange;
197
- protected render(): import("lit").TemplateResult<1> | typeof nothing;
197
+ protected render(): typeof nothing | import("lit").TemplateResult<1>;
198
198
  private _getTrackSizes;
199
199
  private _resolveTracks;
200
200
  private _renderGutter;
@@ -1,2 +1,2 @@
1
- import { t as SplitLayoutElement } from "./split-layout-ChZ0Glrs.js";
1
+ import { t as SplitLayoutElement } from "./split-layout-CophkNeU.js";
2
2
  export { SplitLayoutElement };
@@ -1,2 +1,2 @@
1
- import { a as SunburstViewState, i as SunburstZoomEvent, n as SunburstTreeListElementEventMap, r as SunburstZoomDetail, t as SunburstTreeListElement } from "./sunbursttree-list-BAS0KrDG.js";
1
+ import { a as SunburstViewState, i as SunburstZoomEvent, n as SunburstTreeListElementEventMap, r as SunburstZoomDetail, t as SunburstTreeListElement } from "./sunbursttree-list-Bk20giTF.js";
2
2
  export { SunburstTreeListElement, SunburstTreeListElementEventMap, type SunburstViewState, SunburstZoomDetail, SunburstZoomEvent };
@@ -1,2 +1,2 @@
1
- import { t as SunburstTreeListElement } from "./sunbursttree-list-906G33ME.js";
1
+ import { t as SunburstTreeListElement } from "./sunbursttree-list-DQF6DcsS.js";
2
2
  export { SunburstTreeListElement };
@@ -2,7 +2,7 @@ import { C as TreeItemDblClickEvent, E as TreeSearchHost, M as TreeDataModel, a
2
2
  import { a as TreeItem, n as TreeExclusivity, o as TreeNode, r as TreeFilterPredicate, s as TreeSelectionFilter, t as LoadChildrenCallback } from "./types-Jky6oNAp.js";
3
3
  import { a as ViewStateBase, t as GetViewStateOptions } from "./types-LU1u0CB8.js";
4
4
  import "./index-9ttcdwlL.js";
5
- import { S as ListSearchController } from "./index-BjRoPrwj.js";
5
+ import { S as ListSearchController } from "./index-Bm9a9S3_.js";
6
6
  import { LitElement, PropertyValues } from "lit";
7
7
  import { CommandRegistry } from "@clinth/ui-commands";
8
8
  //#region src/sunburst-tree/types.d.ts
@@ -1,7 +1,7 @@
1
1
  import { t as TickledController } from "./tickled-controller-D-HZymaZ.js";
2
2
  import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
3
3
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
4
- import { i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, t as createTreeListSearchAdapter } from "./incr-search-2YaxUUA9.js";
4
+ import { i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, t as createTreeListSearchAdapter } from "./incr-search-Dc6gYpJG.js";
5
5
  import { a as capKeys, l as keysToArray, n as EMPTY_KEYS } from "./pending-BGidHppL.js";
6
6
  import { t as collectDataResult } from "./data-provider-35TyWclX.js";
7
7
  import { t as ViewStateController } from "./view-state-controller-BdyXWUUM.js";
@@ -1,4 +1,4 @@
1
- import "./icon-DR_3rSyZ.js";
1
+ import "./icon-CDGprSdE.js";
2
2
  import { LitElement, PropertyValues } from "lit";
3
3
  import { CommandRegistry } from "@clinth/ui-commands";
4
4
  //#region src/tabs/tab-list-item.d.ts
package/dist/tabs.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as TabListReorderDetail, i as TabListElement, n as TabListChangeEvent, o as TabListReorderEvent, r as TabListDragMode, t as TabListChangeDetail } from "./tab-list-wC0xNz1b.js";
1
+ import { a as TabListReorderDetail, i as TabListElement, n as TabListChangeEvent, o as TabListReorderEvent, r as TabListDragMode, t as TabListChangeDetail } from "./tab-list-Df371rqw.js";
2
2
  export { TabListChangeDetail, TabListChangeEvent, TabListDragMode, TabListElement, TabListReorderDetail, TabListReorderEvent };
@@ -1,2 +1,2 @@
1
- import { A as TimelineTrackReorderEvent, C as TimelineEventResizeEvent, D as TimelineTickleChangeEvent, E as TimelineTickleChangeDetail, F as TrackHeightMode, I as TrackLayout, L as UserScale, M as TimelineTrackResizeEvent, N as TimelineTrackSelectDetail, O as TimelineTrack, P as TimelineTrackSelectEvent, R as ViewRange, S as TimelineEventResizeDetail, T as TimelineSelectionChangeEvent, _ as TimelineDraggingEvent, a as CssVars, b as TimelineEventMoveDetail, c as resolveGrid, d as DragSnappingFn, f as DragTarget, g as TimelineDraggingDetail, h as TimelineDraggingCallbackDetail, i as TimelineTrackTabElement, j as TimelineTrackResizeDetail, k as TimelineTrackReorderDetail, l as TimelineController, m as GridResolution, n as attachTimelineInteractions, o as Rect, p as GridMode, r as IxfxTimelineElement, s as resolveCssVars, t as timelineStyles, u as TimelineControllerConfig, v as TimelineElementEventMap, w as TimelineSelectionChangeDetail, x as TimelineEventMoveEvent, y as TimelineEvent } from "./index-DV3iaUBW.js";
1
+ import { A as TimelineTrackReorderEvent, C as TimelineEventResizeEvent, D as TimelineTickleChangeEvent, E as TimelineTickleChangeDetail, F as TrackHeightMode, I as TrackLayout, L as UserScale, M as TimelineTrackResizeEvent, N as TimelineTrackSelectDetail, O as TimelineTrack, P as TimelineTrackSelectEvent, R as ViewRange, S as TimelineEventResizeDetail, T as TimelineSelectionChangeEvent, _ as TimelineDraggingEvent, a as CssVars, b as TimelineEventMoveDetail, c as resolveGrid, d as DragSnappingFn, f as DragTarget, g as TimelineDraggingDetail, h as TimelineDraggingCallbackDetail, i as TimelineTrackTabElement, j as TimelineTrackResizeDetail, k as TimelineTrackReorderDetail, l as TimelineController, m as GridResolution, n as attachTimelineInteractions, o as Rect, p as GridMode, r as IxfxTimelineElement, s as resolveCssVars, t as timelineStyles, u as TimelineControllerConfig, v as TimelineElementEventMap, w as TimelineSelectionChangeDetail, x as TimelineEventMoveEvent, y as TimelineEvent } from "./index-DV3iaUBW2.js";
2
2
  export { type CssVars, DragSnappingFn, DragTarget, GridMode, GridResolution, IxfxTimelineElement, type Rect, TimelineController, TimelineControllerConfig, TimelineDraggingCallbackDetail, TimelineDraggingDetail, TimelineDraggingEvent, TimelineElementEventMap, TimelineEvent, TimelineEventMoveDetail, TimelineEventMoveEvent, TimelineEventResizeDetail, TimelineEventResizeEvent, TimelineSelectionChangeDetail, TimelineSelectionChangeEvent, TimelineTickleChangeDetail, TimelineTickleChangeEvent, TimelineTrack, TimelineTrackReorderDetail, TimelineTrackReorderEvent, TimelineTrackResizeDetail, TimelineTrackResizeEvent, TimelineTrackSelectDetail, TimelineTrackSelectEvent, TimelineTrackTabElement, TrackHeightMode, TrackLayout, UserScale, ViewRange, attachTimelineInteractions, resolveCssVars, resolveGrid, timelineStyles };
@@ -1,4 +1,4 @@
1
- import "./icon-DR_3rSyZ.js";
1
+ import "./icon-CDGprSdE.js";
2
2
  import { LitElement } from "lit";
3
3
  //#region src/titlebar/titlebar.d.ts
4
4
  type TitlebarOrientation = `horizontal` | `vertical`;
@@ -1,2 +1,2 @@
1
- import { a as TitlebarToggleDetail, c as TitlebarVariant, i as TitlebarOrientation, n as TitlebarElement, o as TitlebarToggleEvent, r as TitlebarElementEventMap, s as TitlebarToggleInteraction, t as TitlebarCloseEvent } from "./titlebar-B5zSTZnF.js";
1
+ import { a as TitlebarToggleDetail, c as TitlebarVariant, i as TitlebarOrientation, n as TitlebarElement, o as TitlebarToggleEvent, r as TitlebarElementEventMap, s as TitlebarToggleInteraction, t as TitlebarCloseEvent } from "./titlebar-Tqu-VvMU.js";
2
2
  export { TitlebarCloseEvent, TitlebarElement, TitlebarElementEventMap, TitlebarOrientation, TitlebarToggleDetail, TitlebarToggleEvent, TitlebarToggleInteraction, TitlebarVariant };
@@ -2,9 +2,10 @@ 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 { i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, t as createTreeListSearchAdapter } from "./incr-search-2YaxUUA9.js";
5
+ import { i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, t as createTreeListSearchAdapter } from "./incr-search-Dc6gYpJG.js";
6
6
  import { i as animateListItemOut, o as prefersReducedMotion, r as animateListItemIn, t as ListNativeDragController } from "./list-native-drag-controller-CcXoS0YX.js";
7
7
  import { a as capKeys, c as keysAsFlags, f as withoutFlag, i as capFlags, l as keysToArray, n as EMPTY_KEYS, o as flagsFromRecord, s as flagsToRecord, t as EMPTY_FLAGS } from "./pending-BGidHppL.js";
8
+ import { i as sameKeySet, r as isPartialKey, t as PARTIAL_DESCRIPTION } from "./partial-keys-Ck6CiprB.js";
8
9
  import { n as createScrollHoverGuard } from "./scroll-hover-guard-Cjw6179Q.js";
9
10
  import "./interaction-E-uMGHkJ.js";
10
11
  import { t as collectDataResult } from "./data-provider-35TyWclX.js";
@@ -1320,7 +1321,12 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
1320
1321
  if (nodes.length === 0) return;
1321
1322
  if ((event.ctrlKey || event.metaKey) && event.key === `a`) {
1322
1323
  event.preventDefault();
1323
- this.selectAll({ visibleOnly: true });
1324
+ if (this.#intercepted({
1325
+ kind: `all`,
1326
+ keys: [],
1327
+ source: `keyboard`
1328
+ })) return;
1329
+ this.#applySelectAll({ visibleOnly: true });
1324
1330
  return;
1325
1331
  }
1326
1332
  if ([
@@ -1402,7 +1408,10 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
1402
1408
  event.preventDefault();
1403
1409
  const current = nodes[currentIdx];
1404
1410
  if (current) {
1405
- if (this.interactionMode !== `manual` && this.interactionMode !== `checked`) this.select(current.node);
1411
+ if (this.interactionMode !== `manual` && this.interactionMode !== `checked`) {
1412
+ this.#requestReplace(current.node, `keyboard`, false);
1413
+ this.requestUpdate();
1414
+ }
1406
1415
  this.dispatchEvent(new CustomEvent(`activate`, {
1407
1416
  detail: {
1408
1417
  node: current.node,
@@ -1419,7 +1428,7 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
1419
1428
  event.preventDefault();
1420
1429
  const current = nodes[currentIdx];
1421
1430
  if (!current) break;
1422
- if (this.interactionMode === `checked`) this._handleCheckboxClick(new MouseEvent(`click`), current.node, current.depth);
1431
+ if (this.interactionMode === `checked`) this._handleCheckboxClick(new MouseEvent(`click`), current.node, current.depth, `keyboard`);
1423
1432
  else if (this.interactionMode === `standard` || this.interactionMode === `vscode` || this.interactionMode === `manual`) this.#toggleSelection(current.node, current.depth);
1424
1433
  break;
1425
1434
  }
@@ -2699,6 +2708,14 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
2699
2708
  * descendants, so `visibleOnly` makes no difference there.
2700
2709
  */
2701
2710
  selectAll(options = {}) {
2711
+ if (this.#intercepted({
2712
+ kind: `all`,
2713
+ keys: [],
2714
+ source: `api`
2715
+ })) return;
2716
+ this.#applySelectAll(options);
2717
+ }
2718
+ #applySelectAll(options) {
2702
2719
  const prev = new Set(this._selectedNodes);
2703
2720
  for (const node of this.#bulkSelectionScope(options)) if (this.#canSelect(node)) this._selectedNodes.add(node);
2704
2721
  if (this.selectedNode === void 0 || !this._selectedNodes.has(this.selectedNode)) this.selectedNode = [...this._selectedNodes].at(-1);
@@ -2912,6 +2929,15 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
2912
2929
  bubbles: true,
2913
2930
  composed: true
2914
2931
  }));
2932
+ this.dispatchEvent(new CustomEvent(`list-select`, {
2933
+ detail: {
2934
+ selectedKeys: new Set([...this._selectedNodes].map((n) => n.item.key)),
2935
+ previousKeys: new Set([...previous].map((n) => n.item.key)),
2936
+ previous
2937
+ },
2938
+ bubbles: true,
2939
+ composed: true
2940
+ }));
2915
2941
  }
2916
2942
  #findNodePath(nodes, predicate, prefix = []) {
2917
2943
  for (const node of nodes) {
@@ -2976,8 +3002,56 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
2976
3002
  if (!(target instanceof Element)) return false;
2977
3003
  return target.closest(`.tree-caret`) !== null;
2978
3004
  }
3005
+ /** Report an intent before changing the selection; `true` when the caller took over. */
3006
+ #intercepted(intent) {
3007
+ return !this.dispatchEvent(new CustomEvent(`list-select-intent`, {
3008
+ detail: intent,
3009
+ bubbles: true,
3010
+ composed: true,
3011
+ cancelable: true
3012
+ }));
3013
+ }
3014
+ /** The anchor node's key and the selectable keys in the flat range anchor..`node`, when there is an anchor. */
3015
+ #rangeIntent(node) {
3016
+ const flat = this.#getFlat();
3017
+ const anchorIdx = this.#anchor ? flat.indexByKey.get(this.#anchor.node.item.key) ?? -1 : -1;
3018
+ const targetIdx = flat.indexByKey.get(node.item.key) ?? -1;
3019
+ const keys = anchorIdx >= 0 && targetIdx >= 0 ? flat.rows.slice(Math.min(anchorIdx, targetIdx), Math.max(anchorIdx, targetIdx) + 1).map((r) => r.node).filter((n) => this.#canSelect(n)).map((n) => n.item.key) : [node.item.key];
3020
+ return {
3021
+ ...this.#anchor ? { anchorKey: this.#anchor.node.item.key } : {},
3022
+ targetKey: node.item.key,
3023
+ keys
3024
+ };
3025
+ }
3026
+ /** Replace-select `node` (a plain click / Enter) unless the caller takes over; the anchor moves either way. */
3027
+ #requestReplace(node, source, setAnchor = true) {
3028
+ if (!this.#canSelect(node)) return;
3029
+ const intercepted = this.#intercepted({
3030
+ kind: `replace`,
3031
+ keys: [node.item.key],
3032
+ source
3033
+ });
3034
+ if (setAnchor) this.#anchor = {
3035
+ node,
3036
+ flatIndex: this.#getFlatIndexOf(node)
3037
+ };
3038
+ if (intercepted) return;
3039
+ const prev = new Set(this._selectedNodes);
3040
+ this._selectedNodes.clear();
3041
+ this._selectedNodes.add(node);
3042
+ this.selectedNode = node;
3043
+ if (!prev.has(node) || prev.size !== 1) this.#dispatchSelect(prev);
3044
+ }
2979
3045
  #handleImplicitClick(node, depth, event) {
2980
3046
  if (!this.#clickedOnCaret(node, event) && this.#canSelect(node)) {
3047
+ if (this.#intercepted({
3048
+ kind: `replace`,
3049
+ keys: [node.item.key],
3050
+ source: `pointer`
3051
+ })) {
3052
+ this.#toggleExpand(node, depth);
3053
+ return;
3054
+ }
2981
3055
  const prev = new Set(this._selectedNodes);
2982
3056
  this._selectedNodes.clear();
2983
3057
  this._selectedNodes.add(node);
@@ -2990,51 +3064,60 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
2990
3064
  const isMeta = event ? event.metaKey || event.ctrlKey : false;
2991
3065
  const isShift = event ? event.shiftKey : false;
2992
3066
  if (isMeta) {
2993
- if (this.#canSelect(node)) {
2994
- const prev = new Set(this._selectedNodes);
2995
- if (this._selectedNodes.has(node)) {
2996
- this._selectedNodes.delete(node);
2997
- if (this.selectedNode === node) this.selectedNode = [...this._selectedNodes].at(-1);
2998
- } else {
2999
- this._selectedNodes.add(node);
3000
- this.selectedNode = node;
3001
- this.#anchor = {
3002
- node,
3003
- flatIndex: this.#getFlatIndexOf(node)
3004
- };
3005
- }
3006
- this.#dispatchSelect(prev);
3007
- }
3067
+ this.#applyToggleClick(node);
3008
3068
  return;
3009
3069
  }
3010
3070
  if (isShift && this.#anchor) {
3011
- const flat = this.#getFlat();
3012
- const visible = flat.rows;
3013
- const anchorIdx = flat.indexByKey.get(this.#anchor.node.item.key) ?? -1;
3014
- const targetIdx = flat.indexByKey.get(node.item.key) ?? -1;
3015
- if (anchorIdx >= 0 && targetIdx >= 0) {
3016
- const prev = new Set(this._selectedNodes);
3017
- const from = Math.min(anchorIdx, targetIdx);
3018
- const to = Math.max(anchorIdx, targetIdx);
3019
- const rangeNodes = visible.slice(from, to + 1).map((n) => n.node).filter((n) => this.#canSelect(n));
3020
- this._selectedNodes = new Set(rangeNodes);
3021
- this.selectedNode = node;
3022
- this.#dispatchSelect(prev);
3023
- }
3071
+ this.#applyExtendClick(node);
3024
3072
  return;
3025
3073
  }
3026
- if (!this.#clickedOnCaret(node, event) && this.#canSelect(node)) {
3027
- const prev = new Set(this._selectedNodes);
3028
- this._selectedNodes.clear();
3074
+ if (!this.#clickedOnCaret(node, event)) this.#requestReplace(node, `pointer`);
3075
+ this.#toggleExpand(node, depth);
3076
+ }
3077
+ /** Ctrl/Cmd+click: flip `node`. */
3078
+ #applyToggleClick(node) {
3079
+ if (!this.#canSelect(node)) return;
3080
+ if (this.#intercepted({
3081
+ kind: `toggle`,
3082
+ keys: [node.item.key],
3083
+ source: `pointer`
3084
+ })) {
3085
+ this.#anchor = {
3086
+ node,
3087
+ flatIndex: this.#getFlatIndexOf(node)
3088
+ };
3089
+ return;
3090
+ }
3091
+ const prev = new Set(this._selectedNodes);
3092
+ if (this._selectedNodes.has(node)) {
3093
+ this._selectedNodes.delete(node);
3094
+ if (this.selectedNode === node) this.selectedNode = [...this._selectedNodes].at(-1);
3095
+ } else {
3029
3096
  this._selectedNodes.add(node);
3030
3097
  this.selectedNode = node;
3031
3098
  this.#anchor = {
3032
3099
  node,
3033
3100
  flatIndex: this.#getFlatIndexOf(node)
3034
3101
  };
3035
- if (!prev.has(node) || prev.size !== 1) this.#dispatchSelect(prev);
3036
3102
  }
3037
- this.#toggleExpand(node, depth);
3103
+ this.#dispatchSelect(prev);
3104
+ }
3105
+ /** Shift+click: select the flat range from the anchor to `node`. */
3106
+ #applyExtendClick(node) {
3107
+ const flat = this.#getFlat();
3108
+ const anchorIdx = this.#anchor ? flat.indexByKey.get(this.#anchor.node.item.key) ?? -1 : -1;
3109
+ const targetIdx = flat.indexByKey.get(node.item.key) ?? -1;
3110
+ if (anchorIdx < 0 || targetIdx < 0) return;
3111
+ if (this.#intercepted({
3112
+ kind: `extend`,
3113
+ ...this.#rangeIntent(node),
3114
+ source: `pointer`
3115
+ })) return;
3116
+ const prev = new Set(this._selectedNodes);
3117
+ const rangeNodes = flat.rows.slice(Math.min(anchorIdx, targetIdx), Math.max(anchorIdx, targetIdx) + 1).map((n) => n.node).filter((n) => this.#canSelect(n));
3118
+ this._selectedNodes = new Set(rangeNodes);
3119
+ this.selectedNode = node;
3120
+ this.#dispatchSelect(prev);
3038
3121
  }
3039
3122
  #handleExpandOnly(node, depth) {
3040
3123
  this.#toggleExpand(node, depth);
@@ -3043,43 +3126,27 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
3043
3126
  const isMeta = event ? event.metaKey || event.ctrlKey : false;
3044
3127
  const isShift = event ? event.shiftKey : false;
3045
3128
  if (isMeta) {
3046
- if (this.#canSelect(node)) {
3047
- const prev = new Set(this._selectedNodes);
3048
- if (this._selectedNodes.has(node)) {
3049
- this._selectedNodes.delete(node);
3050
- if (this.selectedNode === node) this.selectedNode = [...this._selectedNodes].at(-1);
3051
- } else {
3052
- this._selectedNodes.add(node);
3053
- this.selectedNode = node;
3054
- this.#anchor = {
3055
- node,
3056
- flatIndex: this.#getFlatIndexOf(node)
3057
- };
3058
- }
3059
- this.#dispatchSelect(prev);
3060
- }
3129
+ this.#applyToggleClick(node);
3061
3130
  return;
3062
3131
  }
3063
3132
  if (isShift && this.#anchor) {
3064
- const flat = this.#getFlat();
3065
- const visible = flat.rows;
3066
- const anchorIdx = flat.indexByKey.get(this.#anchor.node.item.key) ?? -1;
3067
- const targetIdx = flat.indexByKey.get(node.item.key) ?? -1;
3068
- if (anchorIdx >= 0 && targetIdx >= 0) {
3069
- const prev = new Set(this._selectedNodes);
3070
- const from = Math.min(anchorIdx, targetIdx);
3071
- const to = Math.max(anchorIdx, targetIdx);
3072
- const rangeNodes = visible.slice(from, to + 1).map((n) => n.node).filter((n) => this.#canSelect(n));
3073
- this._selectedNodes = new Set(rangeNodes);
3074
- this.selectedNode = node;
3075
- this.#dispatchSelect(prev);
3076
- }
3133
+ this.#applyExtendClick(node);
3077
3134
  return;
3078
3135
  }
3136
+ if (!this.#clickedOnCaret(node, event) && this.#canSelect(node)) this.#intercepted({
3137
+ kind: `replace`,
3138
+ keys: [node.item.key],
3139
+ source: `pointer`
3140
+ });
3079
3141
  this.#toggleExpand(node, depth);
3080
3142
  }
3081
3143
  #toggleSelection(node, _depth) {
3082
3144
  if (!this.#canSelect(node)) return;
3145
+ if (this.#intercepted({
3146
+ kind: `toggle`,
3147
+ keys: [node.item.key],
3148
+ source: `keyboard`
3149
+ })) return;
3083
3150
  const prev = new Set(this._selectedNodes);
3084
3151
  if (this._selectedNodes.has(node)) {
3085
3152
  this._selectedNodes.delete(node);
@@ -3094,10 +3161,23 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
3094
3161
  }
3095
3162
  this.#dispatchSelect(prev);
3096
3163
  }
3097
- _handleCheckboxClick(event, node, _depth) {
3164
+ _handleCheckboxClick(event, node, _depth, source = `pointer`) {
3098
3165
  event.stopPropagation();
3099
3166
  const prev = new Set(this._selectedNodes);
3100
3167
  const allSelected = this.#allSelectableDescendantsSelected(node);
3168
+ const affected = [];
3169
+ const collect = (n) => {
3170
+ if (this.#canSelect(n)) affected.push(n.item.key);
3171
+ n.children?.forEach(collect);
3172
+ };
3173
+ collect(node);
3174
+ if (this.#intercepted({
3175
+ kind: `toggle`,
3176
+ keys: affected,
3177
+ descendants: true,
3178
+ checked: !allSelected,
3179
+ source
3180
+ })) return;
3101
3181
  this.#applyCheckedToggle(node, !allSelected);
3102
3182
  if (this.selectedNode === void 0 || !this._selectedNodes.has(this.selectedNode)) this.selectedNode = [...this._selectedNodes].at(-1);
3103
3183
  this.#dispatchSelect(prev);
@@ -3164,6 +3244,12 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
3164
3244
  if (anchorIdx < 0) return;
3165
3245
  const from = Math.min(anchorIdx, toIdx);
3166
3246
  const to = Math.max(anchorIdx, toIdx);
3247
+ const targetNode = nodes[toIdx]?.node;
3248
+ if (targetNode && this.#intercepted({
3249
+ kind: `extend`,
3250
+ ...this.#rangeIntent(targetNode),
3251
+ source: `keyboard`
3252
+ })) return;
3167
3253
  if (this.interactionMode === `vscode`) {
3168
3254
  if (!this.#anchor.selectionSnapshot) this.#anchor = {
3169
3255
  ...this.#anchor,
@@ -3371,7 +3457,7 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
3371
3457
  }
3372
3458
  /** Move the cursor to `nextIdx`, applying the interaction mode's selection side effects. */
3373
3459
  #navigateToIndex(nodes, currentIdx, nextIdx, shiftKey) {
3374
- if (this.interactionMode === `implicit`) this.select(nodes[nextIdx].node);
3460
+ if (this.interactionMode === `implicit`) this.#requestReplace(nodes[nextIdx].node, `keyboard`, false);
3375
3461
  this.#setFocusedIndex(nextIdx);
3376
3462
  if (shiftKey && (this.interactionMode === `standard` || this.interactionMode === `vscode`)) this.#extendRangeSelection(nodes, currentIdx, nextIdx);
3377
3463
  else if (this.interactionMode === `vscode`) this.#anchor = void 0;
@@ -3826,6 +3912,22 @@ let TreeListElement = class TreeListElement extends TreeBaseElement {
3826
3912
  constructor(..._args) {
3827
3913
  super(..._args);
3828
3914
  this.alignCheckboxes = false;
3915
+ this._partialKeys = /* @__PURE__ */ new Set();
3916
+ }
3917
+ /**
3918
+ * Nodes shown as *partially* selected (a part of the resource is selected):
3919
+ * `data-partial`, an indeterminate checkbox in `checked` mode, and an
3920
+ * accessible description otherwise. Independent of the selection — a key in
3921
+ * both counts as selected. In `checked` mode it combines with the state
3922
+ * derived from loaded descendants: a node is indeterminate if either says so.
3923
+ * Replace-on-set.
3924
+ */
3925
+ get partialKeys() {
3926
+ return this._partialKeys;
3927
+ }
3928
+ set partialKeys(keys) {
3929
+ const next = new Set(keys);
3930
+ if (!sameKeySet(next, this._partialKeys)) this._partialKeys = next;
3829
3931
  }
3830
3932
  /** Checkbox tri-states for the whole loaded tree, rebuilt only when the structure or selection changes. */
3831
3933
  #checkboxCache;
@@ -3865,11 +3967,15 @@ let TreeListElement = class TreeListElement extends TreeBaseElement {
3865
3967
  `;
3866
3968
  if (this.interactionMode === `checked`) {
3867
3969
  if (node.item.selectable === false) return this.alignCheckboxes ? html`<span class="tree-checkbox-spacer" aria-hidden="true"></span>${caretAndLabel}` : caretAndLabel;
3868
- const state = this.#checkboxCache?.states.get(node.item.key) ?? `unchecked`;
3970
+ const derived = this.#checkboxCache?.states.get(node.item.key) ?? `unchecked`;
3971
+ const state = derived === `unchecked` && this.#isPartial(node) ? `indeterminate` : derived;
3869
3972
  return html`${this.#renderCheckbox(node, depth, state)}${caretAndLabel}`;
3870
3973
  }
3871
3974
  return caretAndLabel;
3872
3975
  }
3976
+ #isPartial(node) {
3977
+ return isPartialKey(node.item.key, this._partialKeys, this._isSelected(node));
3978
+ }
3873
3979
  #renderCheckbox(node, depth, state) {
3874
3980
  const onClick = (e) => this._handleCheckboxClick(e, node, depth);
3875
3981
  if (this.checkboxRenderer) return html`
@@ -3895,6 +4001,7 @@ let TreeListElement = class TreeListElement extends TreeBaseElement {
3895
4001
  }
3896
4002
  _renderNode(node, depth) {
3897
4003
  const selected = this._isSelected(node);
4004
+ const partial = this.#isPartial(node);
3898
4005
  const tickled = this._isFocused(node);
3899
4006
  const isBranch = node.item.isLeaf !== true;
3900
4007
  const isExpanded = this._isExpanded(node, depth);
@@ -3904,10 +4011,12 @@ let TreeListElement = class TreeListElement extends TreeBaseElement {
3904
4011
  const dnd = this._dndRowState(node);
3905
4012
  return html`
3906
4013
  <li
3907
- class="item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${hasIconAtDepth ? `has-icon-at-depth` : ``} ${isLeaving ? `leaving` : ``} ${dnd.dragging ? `dragging` : ``} ${dnd.dropTarget && dnd.dropPosition === `inside` ? `drop-into` : ``}"
4014
+ class="item ${selected ? `selected` : ``} ${partial ? `partial` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${hasIconAtDepth ? `has-icon-at-depth` : ``} ${isLeaving ? `leaving` : ``} ${dnd.dragging ? `dragging` : ``} ${dnd.dropTarget && dnd.dropPosition === `inside` ? `drop-into` : ``}"
3908
4015
  data-key=${node.item.key}
3909
4016
  role="treeitem"
3910
4017
  aria-selected=${selected}
4018
+ aria-description=${partial && this.interactionMode !== `checked` ? PARTIAL_DESCRIPTION : nothing}
4019
+ ?data-partial=${partial}
3911
4020
  aria-expanded=${isBranch ? isExpanded : nothing}
3912
4021
  aria-hidden=${isLeaving ? `true` : nothing}
3913
4022
  aria-level=${depth + 1}
@@ -3955,6 +4064,12 @@ let TreeListElement = class TreeListElement extends TreeBaseElement {
3955
4064
  transition: transform var(--transition, 0.15s ease-out);
3956
4065
  }
3957
4066
 
4067
+ .item.partial:not(.selected) {
4068
+ background: var(--item-bg-partial, color-mix(in srgb, var(--item-bg-selected, var(--accent)) 35%, transparent));
4069
+ outline: 1px dashed var(--item-border-partial, var(--border));
4070
+ outline-offset: -1px;
4071
+ }
4072
+
3958
4073
  .item.selected .caret-icon {
3959
4074
  color: var(--accent-text);
3960
4075
  }
@@ -4032,6 +4147,7 @@ __decorate([property({
4032
4147
  reflect: true,
4033
4148
  attribute: `align-checkboxes`
4034
4149
  })], TreeListElement.prototype, "alignCheckboxes", void 0);
4150
+ __decorate([state()], TreeListElement.prototype, "_partialKeys", void 0);
4035
4151
  TreeListElement = __decorate([safeCustomElement(`ixfx-tree-list`)], TreeListElement);
4036
4152
  //#endregion
4037
4153
  //#region src/tree/tree-controller.ts