@ixfx/components 0.16.1 → 0.16.2

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 (89) hide show
  1. package/bundle/index.d.ts +216 -56
  2. package/bundle/index.js +370 -315
  3. package/dist/ac-text.d.ts +1 -1
  4. package/dist/{ac-token-qEs3FsQv.d.ts → ac-token-Cq7lsYf-.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-N92DKoWb.d.ts → button-D1sPDUCM.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-YnFVFqrx.js → crumb-navigation-D3ndPgFg.js} +2 -2
  11. package/dist/{crumb-navigation-BbqfmkYs.d.ts → crumb-navigation-nnr881n-.d.ts} +1 -1
  12. package/dist/crumbs.d.ts +1 -1
  13. package/dist/crumbs.js +1 -1
  14. package/dist/{data-grid-Csh5EJW9.d.ts → data-grid-BAEpfTkb.d.ts} +22 -4
  15. package/dist/{data-grid-Cqxuwgbb.js → data-grid-CaPLWt5E.js} +138 -57
  16. package/dist/data-grid.d.ts +2 -2
  17. package/dist/data-grid.js +1 -1
  18. package/dist/{detail-list-Bo5ze3SN.js → detail-list-C3XKTRmE.js} +71 -20
  19. package/dist/{detail-list-DSZ1DDor.d.ts → detail-list-DK49TsJd.d.ts} +12 -4
  20. package/dist/detail-list.d.ts +2 -2
  21. package/dist/detail-list.js +1 -1
  22. package/dist/{flat-list-CT9kX3TQ.d.ts → flat-list-Bv4-qfjp.d.ts} +9 -4
  23. package/dist/flat-list.d.ts +1 -1
  24. package/dist/flat-list.js +6 -3
  25. package/dist/{grid-list-D0dJNVEF.js → grid-list-51XsR2X2.js} +55 -18
  26. package/dist/{grid-list-DDLrWRxm.d.ts → grid-list-DaeSHv9P.d.ts} +58 -14
  27. package/dist/grid-list.d.ts +2 -2
  28. package/dist/grid-list.js +1 -1
  29. package/dist/{grouped-item-lister-DETte0Dh.d.ts → grouped-item-lister-DZIjo9nO.d.ts} +2 -2
  30. package/dist/grouped-item-lister.d.ts +1 -1
  31. package/dist/{icon-CDGprSdE.d.ts → icon-DR_3rSyZ.d.ts} +1 -1
  32. package/dist/icons.d.ts +2 -2
  33. package/dist/{incr-search-CgbL-OlS.js → incr-search-2YaxUUA9.js} +10 -1
  34. package/dist/incr-search.d.ts +1 -1
  35. package/dist/incr-search.js +1 -1
  36. package/dist/{index-CoqtMSd9.d.ts → index-BUB5SICW.d.ts} +1 -1
  37. package/dist/{index-CUErGhCg.d.ts → index-BjRoPrwj.d.ts} +1 -1
  38. package/dist/{index-DN2BWctP.d.ts → index-Bz3loIAf.d.ts} +1 -1
  39. package/dist/{index-UvnoZUAo.d.ts → index-CJ5fshD3.d.ts} +1 -1
  40. package/dist/{index-DxyyVqzA.d.ts → index-DM9OLgTH.d.ts} +3 -2
  41. package/dist/{index-Bnm-kKGC.d.ts → index-DXDz60XH.d.ts} +20 -1
  42. package/dist/{index-CYndvTWH.d.ts → index-garxxqgV.d.ts} +1 -1
  43. package/dist/{index-D-lZNlHa.d.ts → index-vdbbGE7N.d.ts} +1 -1
  44. package/dist/index.d.ts +45 -25
  45. package/dist/index.js +15 -14
  46. package/dist/item-appearance-Bl6rMIID.js +60 -0
  47. package/dist/{labelled-input-base-DiTme1JO.d.ts → labelled-input-base-Dp_9KP0G.d.ts} +1 -1
  48. package/dist/labelled-radial-input.d.ts +2 -2
  49. package/dist/labelled-range-input.d.ts +1 -1
  50. package/dist/labelled-slider-input.d.ts +1 -1
  51. package/dist/list-group-header.d.ts +1 -1
  52. package/dist/{list-selection-controller-5L0Nj9tR.js → list-selection-controller-CJDdjH7E.js} +192 -54
  53. package/dist/list-selection-types-hj9Njei3.d.ts +83 -0
  54. package/dist/{menu-CU9KAm8s.js → menu-BX1FHxY8.js} +16 -1
  55. package/dist/{menu-item-bF6narIz.d.ts → menu-item-B0zqw2xp.d.ts} +1 -1
  56. package/dist/{menu-item-BUv8An2k.js → menu-item-oxU1VKiJ.js} +34 -9
  57. package/dist/menu.d.ts +2 -2
  58. package/dist/menu.js +2 -2
  59. package/dist/{miller-DUqiUAWQ.js → miller-BfrTcujx.js} +142 -11
  60. package/dist/miller.d.ts +1 -1
  61. package/dist/miller.js +1 -1
  62. package/dist/narrowed-text.js +1 -1
  63. package/dist/panel.d.ts +1 -1
  64. package/dist/{split-layout-CophkNeU.d.ts → split-layout-ChZ0Glrs.d.ts} +1 -1
  65. package/dist/split-layout.d.ts +1 -1
  66. package/dist/sunburst-tree.d.ts +1 -1
  67. package/dist/sunburst-tree.js +1 -1
  68. package/dist/{sunbursttree-list-B_M0YTEA.js → sunbursttree-list-906G33ME.js} +1 -1
  69. package/dist/{sunbursttree-list-DePuFYlU.d.ts → sunbursttree-list-BAS0KrDG.d.ts} +1 -1
  70. package/dist/{tab-list-Df371rqw.d.ts → tab-list-wC0xNz1b.d.ts} +1 -1
  71. package/dist/tabs.d.ts +1 -1
  72. package/dist/{titlebar-Tqu-VvMU.d.ts → titlebar-B5zSTZnF.d.ts} +1 -1
  73. package/dist/titlebar.d.ts +1 -1
  74. package/dist/{tree-DAlgvaHB.js → tree-C_H1COTf.js} +1 -1
  75. package/dist/tree.d.ts +1 -1
  76. package/dist/tree.js +1 -1
  77. package/dist/{vertical-list-SAx56U-l.d.ts → vertical-list-od4050Bo.d.ts} +11 -2
  78. package/dist/{vertical-list-DyKPKGxK.js → vertical-list-qMRIxZIT.js} +54 -20
  79. package/dist/vertical-list.d.ts +2 -2
  80. package/dist/vertical-list.js +1 -1
  81. package/docs-user/data-grid.md +10 -3
  82. package/docs-user/detail-list.md +1 -1
  83. package/docs-user/grid-list.md +4 -1
  84. package/docs-user/index.json +2 -2
  85. package/docs-user/menu.md +11 -1
  86. package/docs-user/vertical-list.md +9 -1
  87. package/package.json +1 -1
  88. package/dist/item-appearance-BjcMyauw.js +0 -29
  89. package/dist/list-selection-types-PjKdhF-a.d.ts +0 -45
@@ -2,12 +2,12 @@ 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-CgbL-OlS.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";
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
8
  import "./interaction-E-uMGHkJ.js";
8
9
  import { t as collectDataResult } from "./data-provider-35TyWclX.js";
9
10
  import { a as restoreElementScroll, i as onUserScrollIntent, o as scrollToOffset, r as captureElementScroll, t as ViewStateController } from "./view-state-controller-BdyXWUUM.js";
10
- import { n as appearanceColor, t as appearanceAbsent } from "./item-appearance-BjcMyauw.js";
11
11
  import { LitElement, css, html, nothing } from "lit";
12
12
  import { property, state } from "lit/decorators.js";
13
13
  import { createCommandRegistry } from "@clinth/ui-commands";
@@ -278,6 +278,8 @@ let MillerBaseElement = class MillerBaseElement extends LitElement {
278
278
  this.#onColumnScroll = (event) => {
279
279
  if (this.#pendingColumnScroll.size === 0 && event.target.classList?.contains(`column-content`)) this.#viewState.notify();
280
280
  };
281
+ this._partialKeys = /* @__PURE__ */ new Set();
282
+ this._partialDescription = PARTIAL_DESCRIPTION;
281
283
  this.#selectOrigin = `user`;
282
284
  this.#selectSilent = false;
283
285
  this.#onKeyDown = (event) => {
@@ -781,6 +783,24 @@ let MillerBaseElement = class MillerBaseElement extends LitElement {
781
783
  }
782
784
  /** Not implemented on miller-list. */
783
785
  selectAll() {}
786
+ /**
787
+ * Nodes shown as *partially* selected (a part of the resource is selected):
788
+ * an indeterminate checkbox in `checked` mode, `.partial` and an accessible
789
+ * description otherwise. Independent of the selection — a key in both counts
790
+ * as selected. In `checked` mode this overrides the state derived from
791
+ * loaded descendants. Replace-on-set.
792
+ */
793
+ get partialKeys() {
794
+ return this._partialKeys;
795
+ }
796
+ set partialKeys(keys) {
797
+ const next = new Set(keys);
798
+ if (!sameKeySet(next, this._partialKeys)) this._partialKeys = next;
799
+ }
800
+ /** Whether `node` is shown as partial (and, being selected, not). */
801
+ _isPartial(node, depth) {
802
+ return isPartialKey(node.item.key, this._partialKeys, this._isSelected(node, depth));
803
+ }
784
804
  /** Not implemented on miller-list. */
785
805
  deselectAll() {}
786
806
  /**
@@ -1171,6 +1191,58 @@ let MillerBaseElement = class MillerBaseElement extends LitElement {
1171
1191
  bubbles: true,
1172
1192
  composed: true
1173
1193
  }));
1194
+ this.dispatchEvent(new CustomEvent(`list-select`, {
1195
+ detail: {
1196
+ selectedKeys: new Set(this._selectedKeys),
1197
+ previousKeys: new Set([...previous].map((n) => n.item.key)),
1198
+ previous
1199
+ },
1200
+ bubbles: true,
1201
+ composed: true
1202
+ }));
1203
+ }
1204
+ /** Report an intent before changing the selection; `true` when the caller took over. */
1205
+ #intercepted(intent) {
1206
+ return !this.dispatchEvent(new CustomEvent(`list-select-intent`, {
1207
+ detail: intent,
1208
+ bubbles: true,
1209
+ composed: true,
1210
+ cancelable: true
1211
+ }));
1212
+ }
1213
+ /** The anchor..`index` range in `col` when `depth` holds the range anchor, else `undefined`. */
1214
+ #rangeNodes(col, depth, index) {
1215
+ if (!this.#anchor || this.#anchor.depth !== depth || !col || index < 0) return void 0;
1216
+ return col.slice(Math.min(this.#anchor.index, index), Math.max(this.#anchor.index, index) + 1);
1217
+ }
1218
+ /** `manual` mode: nothing is selected here, but the caller is told what the click meant. */
1219
+ #reportManualClick(node, depth, event, source) {
1220
+ const key = node.item.key;
1221
+ if (event && (event.metaKey || event.ctrlKey)) {
1222
+ this.#intercepted({
1223
+ kind: `toggle`,
1224
+ keys: [key],
1225
+ source
1226
+ });
1227
+ return;
1228
+ }
1229
+ const col = this._columns[depth];
1230
+ const range = event?.shiftKey ? this.#rangeNodes(col, depth, col ? col.indexOf(node) : -1) : void 0;
1231
+ if (range && this.#anchor) {
1232
+ this.#intercepted({
1233
+ kind: `extend`,
1234
+ keys: range.map((n) => n.item.key),
1235
+ anchorKey: this.#anchor.key,
1236
+ targetKey: key,
1237
+ source
1238
+ });
1239
+ return;
1240
+ }
1241
+ this.#intercepted({
1242
+ kind: `replace`,
1243
+ keys: [key],
1244
+ source
1245
+ });
1174
1246
  }
1175
1247
  #abortPending() {
1176
1248
  if (this.#expandTimer !== void 0) {
@@ -1241,11 +1313,22 @@ let MillerBaseElement = class MillerBaseElement extends LitElement {
1241
1313
  case `vscode`:
1242
1314
  this.#handleStandardClick(node, depth, event);
1243
1315
  break;
1244
- case `manual`: break;
1316
+ case `manual`:
1317
+ this.#reportManualClick(node, depth, event, `pointer`);
1318
+ break;
1245
1319
  case `checked`: this.#expandNode(node, depth, true);
1246
1320
  }
1247
1321
  }
1248
1322
  #handleImplicitClick(node, depth) {
1323
+ if (this.#intercepted({
1324
+ kind: `replace`,
1325
+ keys: [node.item.key],
1326
+ source: `pointer`
1327
+ })) {
1328
+ this.#lastSelectedNode = node;
1329
+ this.#expandNode(node, depth, true);
1330
+ return;
1331
+ }
1249
1332
  const previous = new Set(this._selectedNodes);
1250
1333
  this._selectedByDepth.set(depth, node);
1251
1334
  this.#lastSelectedNode = node;
@@ -1261,6 +1344,18 @@ let MillerBaseElement = class MillerBaseElement extends LitElement {
1261
1344
  const isMeta = event ? event.metaKey || event.ctrlKey : false;
1262
1345
  const isShift = event ? event.shiftKey : false;
1263
1346
  if (isMeta) {
1347
+ if (this.#intercepted({
1348
+ kind: `toggle`,
1349
+ keys: [node.item.key],
1350
+ source: `pointer`
1351
+ })) {
1352
+ this.#anchor = index >= 0 ? {
1353
+ key: node.item.key,
1354
+ depth,
1355
+ index
1356
+ } : this.#anchor;
1357
+ return;
1358
+ }
1264
1359
  if (this._selectedKeys.has(node.item.key)) {
1265
1360
  this._selectedKeys.delete(node.item.key);
1266
1361
  this._selectedNodes.delete(node);
@@ -1278,23 +1373,38 @@ let MillerBaseElement = class MillerBaseElement extends LitElement {
1278
1373
  return;
1279
1374
  }
1280
1375
  if (isShift && this.#anchor && this.#anchor.depth === depth && col) {
1281
- const from = Math.min(this.#anchor.index, index);
1282
- const to = Math.max(this.#anchor.index, index);
1283
- const rangeNodes = col.slice(from, to + 1);
1376
+ const rangeNodes = this.#rangeNodes(col, depth, index) ?? [];
1377
+ if (this.#intercepted({
1378
+ kind: `extend`,
1379
+ keys: rangeNodes.map((n) => n.item.key),
1380
+ anchorKey: this.#anchor.key,
1381
+ targetKey: node.item.key,
1382
+ source: `pointer`
1383
+ })) return;
1284
1384
  this._selectedKeys = new Set(rangeNodes.map((n) => n.item.key));
1285
1385
  this._selectedNodes = new Set(rangeNodes);
1286
1386
  this.#selectionChanged();
1287
1387
  this.requestUpdate();
1288
1388
  return;
1289
1389
  }
1390
+ const intercepted = this.#intercepted({
1391
+ kind: `replace`,
1392
+ keys: [node.item.key],
1393
+ source: `pointer`
1394
+ });
1290
1395
  const previous = new Set(this._selectedNodes);
1291
- this._selectedKeys = /* @__PURE__ */ new Set([node.item.key]);
1292
- this._selectedNodes = /* @__PURE__ */ new Set([node]);
1293
1396
  this.#anchor = index >= 0 ? {
1294
1397
  key: node.item.key,
1295
1398
  depth,
1296
1399
  index
1297
1400
  } : void 0;
1401
+ if (intercepted) {
1402
+ this.#lastSelectedNode = node;
1403
+ this.#expandNode(node, depth, true);
1404
+ return;
1405
+ }
1406
+ this._selectedKeys = /* @__PURE__ */ new Set([node.item.key]);
1407
+ this._selectedNodes = /* @__PURE__ */ new Set([node]);
1298
1408
  this._selectedByDepth.set(depth, node);
1299
1409
  this.#lastSelectedNode = node;
1300
1410
  this.#expandNode(node, depth, true);
@@ -1399,6 +1509,11 @@ let MillerBaseElement = class MillerBaseElement extends LitElement {
1399
1509
  }
1400
1510
  }
1401
1511
  #onCheckboxClick(node) {
1512
+ if (this.#intercepted({
1513
+ kind: `toggle`,
1514
+ keys: [node.item.key],
1515
+ source: `pointer`
1516
+ })) return;
1402
1517
  const previous = new Set(this._selectedNodes);
1403
1518
  const currentlySelected = this._selectedKeys.has(node.item.key);
1404
1519
  if (!!node.children?.length ? this.#allDescendantsSelected(node) : currentlySelected) this.#applyCheckedToggle(node, false);
@@ -1519,7 +1634,13 @@ let MillerBaseElement = class MillerBaseElement extends LitElement {
1519
1634
  const from = Math.min(this.#anchor.index, targetIndex);
1520
1635
  const to = Math.max(this.#anchor.index, targetIndex);
1521
1636
  const rangeKeys = col.slice(from, to + 1).map((n) => n.item.key);
1522
- if (this.interactionMode === `vscode`) {
1637
+ if (this.#intercepted({
1638
+ kind: `extend`,
1639
+ keys: rangeKeys,
1640
+ anchorKey: this.#anchor.key,
1641
+ targetKey: targetNode.item.key,
1642
+ source: `keyboard`
1643
+ })) {} else if (this.interactionMode === `vscode`) {
1523
1644
  const snap = this.#anchor.selectionSnapshot;
1524
1645
  for (const k of rangeKeys) if (snap.has(k)) this._selectedKeys.delete(k);
1525
1646
  else this._selectedKeys.add(k);
@@ -1803,6 +1924,7 @@ __decorate([state()], MillerBaseElement.prototype, "_columns", void 0);
1803
1924
  __decorate([state()], MillerBaseElement.prototype, "_loadingDepth", void 0);
1804
1925
  __decorate([state()], MillerBaseElement.prototype, "_selectedNodes", void 0);
1805
1926
  __decorate([property({ attribute: false })], MillerBaseElement.prototype, "restoreLoads", void 0);
1927
+ __decorate([state()], MillerBaseElement.prototype, "_partialKeys", void 0);
1806
1928
  MillerBaseElement = __decorate([safeCustomElement(`ixfx-miller-base`)], MillerBaseElement);
1807
1929
  //#endregion
1808
1930
  //#region src/miller/miller-list.ts
@@ -1854,6 +1976,7 @@ let MillerListElement = class MillerListElement extends MillerBaseElement {
1854
1976
  }
1855
1977
  #renderListItem(node, depth) {
1856
1978
  const selected = this._isSelected(node, depth);
1979
+ const partial = this._isPartial(node, depth);
1857
1980
  const tickled = this._isFocused(node, depth);
1858
1981
  const open = this._isOpen(node, depth);
1859
1982
  const isBranch = node.item.isLeaf !== true;
@@ -1865,13 +1988,14 @@ let MillerListElement = class MillerListElement extends MillerBaseElement {
1865
1988
  const isCheckedMode = this.interactionMode === `checked`;
1866
1989
  let checkboxTpl = nothing;
1867
1990
  if (isCheckedMode) {
1868
- const state = computeCheckboxState(node, this._selectedKeys);
1991
+ const state = partial ? `indeterminate` : computeCheckboxState(node, this._selectedKeys);
1869
1992
  checkboxTpl = html`
1870
1993
  <input
1871
1994
  type="checkbox"
1872
1995
  class="item-checkbox"
1873
1996
  .checked=${state === `checked`}
1874
1997
  .indeterminate=${state === `indeterminate`}
1998
+ aria-checked=${state === `indeterminate` ? `mixed` : String(state === `checked`)}
1875
1999
  aria-label="Select ${node.item.label}"
1876
2000
  @click=${(e) => this._handleCheckboxClick(e, node, depth)}
1877
2001
  />
@@ -1879,9 +2003,10 @@ let MillerListElement = class MillerListElement extends MillerBaseElement {
1879
2003
  }
1880
2004
  return html`
1881
2005
  <li
1882
- class="item ${selected ? `selected` : ``} ${open ? `open` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`}"
2006
+ class="item ${selected ? `selected` : ``} ${partial ? `partial` : ``} ${open ? `open` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`}"
1883
2007
  role="option"
1884
2008
  aria-selected=${selected}
2009
+ aria-description=${partial && !isCheckedMode ? this._partialDescription : nothing}
1885
2010
  @click=${(e) => this._handleItemClick(node, depth, e)}
1886
2011
  @dblclick=${(e) => this._handleItemDblClick(node, depth, e)}
1887
2012
  @contextmenu=${(e) => this._handleItemRightClick(node, depth, e)}
@@ -1914,6 +2039,12 @@ let MillerListElement = class MillerListElement extends MillerBaseElement {
1914
2039
  justify-content: space-between;
1915
2040
  }
1916
2041
 
2042
+ .item.partial:not(.selected) {
2043
+ background: var(--item-bg-partial, color-mix(in srgb, var(--item-selected-bg) 35%, transparent));
2044
+ outline: 1px dashed var(--item-border-partial, var(--border, #555));
2045
+ outline-offset: -1px;
2046
+ }
2047
+
1917
2048
  .item.selected {
1918
2049
  background: var(--item-selected-bg);
1919
2050
  color: var(--item-selected-text, #fff);
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-Bnm-kKGC.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";
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-DUqiUAWQ.js";
1
+ import { n as MillerListElement, r as MillerBaseElement, t as MillerTreeController } from "./miller-BfrTcujx.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 { p as createIncrSearch } from "./incr-search-CgbL-OlS.js";
6
+ import { m as createIncrSearch } from "./incr-search-2YaxUUA9.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-Tqu-VvMU.js";
1
+ import { a as TitlebarToggleDetail, c as TitlebarVariant, i as TitlebarOrientation, o as TitlebarToggleEvent, s as TitlebarToggleInteraction, t as TitlebarCloseEvent } from "./titlebar-B5zSTZnF.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`. */
@@ -194,7 +194,7 @@ declare class SplitLayoutElement extends LitElement {
194
194
  private _onPointerUp;
195
195
  private _emitResize;
196
196
  private _emitChange;
197
- protected render(): typeof nothing | import("lit").TemplateResult<1>;
197
+ protected render(): import("lit").TemplateResult<1> | typeof nothing;
198
198
  private _getTrackSizes;
199
199
  private _resolveTracks;
200
200
  private _renderGutter;
@@ -1,2 +1,2 @@
1
- import { t as SplitLayoutElement } from "./split-layout-CophkNeU.js";
1
+ import { t as SplitLayoutElement } from "./split-layout-ChZ0Glrs.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-DePuFYlU.js";
1
+ import { a as SunburstViewState, i as SunburstZoomEvent, n as SunburstTreeListElementEventMap, r as SunburstZoomDetail, t as SunburstTreeListElement } from "./sunbursttree-list-BAS0KrDG.js";
2
2
  export { SunburstTreeListElement, SunburstTreeListElementEventMap, type SunburstViewState, SunburstZoomDetail, SunburstZoomEvent };
@@ -1,2 +1,2 @@
1
- import { t as SunburstTreeListElement } from "./sunbursttree-list-B_M0YTEA.js";
1
+ import { t as SunburstTreeListElement } from "./sunbursttree-list-906G33ME.js";
2
2
  export { SunburstTreeListElement };
@@ -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-CgbL-OlS.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";
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";
@@ -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-CUErGhCg.js";
5
+ import { S as ListSearchController } from "./index-BjRoPrwj.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,4 +1,4 @@
1
- import "./icon-CDGprSdE.js";
1
+ import "./icon-DR_3rSyZ.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-Df371rqw.js";
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";
2
2
  export { TabListChangeDetail, TabListChangeEvent, TabListDragMode, TabListElement, TabListReorderDetail, TabListReorderEvent };
@@ -1,4 +1,4 @@
1
- import "./icon-CDGprSdE.js";
1
+ import "./icon-DR_3rSyZ.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-Tqu-VvMU.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-B5zSTZnF.js";
2
2
  export { TitlebarCloseEvent, TitlebarElement, TitlebarElementEventMap, TitlebarOrientation, TitlebarToggleDetail, TitlebarToggleEvent, TitlebarToggleInteraction, TitlebarVariant };
@@ -2,7 +2,7 @@ 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-CgbL-OlS.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";
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
8
  import { n as createScrollHoverGuard } from "./scroll-hover-guard-Cjw6179Q.js";
package/dist/tree.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { A as TreeTickleDetail, M as TreeDataModel, N as TreeDataModelOptions, O as TreeSelectDetail, T as TreeRevealMode, _ as TreeDropTarget, b as TreeItemClickDetail, c as TreeDragContext, d as TreeDragStartEvent, g as TreeDropPosition, h as TreeDropEvent, i as TreeCollapseEvent, j as TreeTickleEvent, k as TreeSelectEvent, l as TreeDragEndEvent, m as TreeDropDetail, n as TreeActivateEvent, o as TreeComponentEventMap, p as TreeDropContext, r as TreeCollapseDetail, s as TreeDndMode, t as TreeActivateDetail, u as TreeDragOverEvent, v as TreeExpandDetail, w as TreeNavigateOptions, x as TreeItemClickEvent, y as TreeExpandEvent } from "./tree-component-DgfkxmVY.js";
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
- import { a as TreeDropVisibleRow, c as TreeListElement, d as TreeBaseElement, f as TreeBaseElementEventMap, h as TreeConfig, i as TreeDropRowInfo, l as TreeCheckboxState, m as TreeListViewState, n as TreeDropControllerConfig, o as TreeController, p as TreeVirtualize, r as TreeDropResolvedDrag, s as TreeControllerOptions, t as TreeDropController, u as TreeAnimation } from "./index-D-lZNlHa.js";
3
+ import { a as TreeDropVisibleRow, c as TreeListElement, d as TreeBaseElement, f as TreeBaseElementEventMap, h as TreeConfig, i as TreeDropRowInfo, l as TreeCheckboxState, m as TreeListViewState, n as TreeDropControllerConfig, o as TreeController, p as TreeVirtualize, r as TreeDropResolvedDrag, s as TreeControllerOptions, t as TreeDropController, u as TreeAnimation } from "./index-vdbbGE7N.js";
4
4
  export { type LoadChildrenCallback, type TreeActivateDetail, type TreeActivateEvent, TreeAnimation, TreeBaseElement, TreeBaseElementEventMap, type TreeCheckboxState, type TreeCollapseDetail, type TreeCollapseEvent, type TreeComponentEventMap, TreeConfig, TreeController, TreeControllerOptions, TreeDataModel, type TreeDataModelOptions, type TreeDndMode, type TreeDragContext, type TreeDragEndEvent, type TreeDragOverEvent, type TreeDragStartEvent, type TreeDropContext, TreeDropController, TreeDropControllerConfig, type TreeDropDetail, type TreeDropEvent, type TreeDropPosition, TreeDropResolvedDrag, TreeDropRowInfo, type TreeDropTarget, TreeDropVisibleRow, type TreeExclusivity, type TreeExpandDetail, type TreeExpandEvent, type TreeFilterPredicate, type TreeItem, type TreeItemClickDetail, type TreeItemClickEvent, TreeListElement, type TreeListViewState, type TreeNavigateOptions, type TreeNode, type TreeRevealMode, type TreeSelectDetail, type TreeSelectEvent, type TreeSelectionFilter, type TreeTickleDetail, type TreeTickleEvent, TreeVirtualize };
package/dist/tree.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as TreeDataModel, i as TreeDropController, n as TreeListElement, r as TreeBaseElement, t as TreeController } from "./tree-DAlgvaHB.js";
1
+ import { a as TreeDataModel, i as TreeDropController, n as TreeListElement, r as TreeBaseElement, t as TreeController } from "./tree-C_H1COTf.js";
2
2
  export { TreeBaseElement, TreeController, TreeDataModel, TreeDropController, TreeListElement };
@@ -2,8 +2,8 @@ import { L as ListDragPreviewRenderer, R as ListDragPreviewSourceResolver, V as
2
2
  import { a as ViewStateBase, t as GetViewStateOptions } from "./types-LU1u0CB8.js";
3
3
  import "./index-9ttcdwlL.js";
4
4
  import { n as ListViewportChangeEvent } from "./list-viewport-types-BRZsLcvp.js";
5
- import { S as ListSearchController } from "./index-CUErGhCg.js";
6
- import { i as ListInteractionMode, l as ListSelectionMode, r as ListElementEventMap } from "./list-selection-types-PjKdhF-a.js";
5
+ import { i as ListInteractionMode, m as ListSelectionMode, r as ListElementEventMap } from "./list-selection-types-hj9Njei3.js";
6
+ import { S as ListSearchController } from "./index-BjRoPrwj.js";
7
7
  import "./editable-label-rzXkjf1H.js";
8
8
  import { LitElement, PropertyValues } from "lit";
9
9
  import { CommandId, CommandRegistry } from "@clinth/ui-commands";
@@ -262,6 +262,15 @@ declare class VerticalListElement extends LitElement {
262
262
  selectAll(): void;
263
263
  /** The selection as stable `data-key` / `data-value` strings. */
264
264
  get selectedKeys(): ReadonlySet<string>;
265
+ /**
266
+ * Rows shown as *partially* selected (a part of the resource is selected):
267
+ * `data-partial`, an indeterminate checkbox in `checked` mode, and an
268
+ * accessible description. Independent of `selectedKeys` — a key in both
269
+ * counts as selected. Replace-on-set; keys without a row are kept for when
270
+ * the row appears.
271
+ */
272
+ get partialKeys(): ReadonlySet<string>;
273
+ set partialKeys(keys: Iterable<string>);
265
274
  /** The key of the item under the cursor, or `undefined`. */
266
275
  get tickledKey(): string | undefined;
267
276
  /** Replace the selection with the items carrying these keys (unknown keys ignored). */
@@ -1,13 +1,13 @@
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 { c as createElementListSearchAdapter, i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, u as keyForElement } from "./incr-search-CgbL-OlS.js";
4
+ import { c as createElementListSearchAdapter, d as keysOfElements, i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, u as keyForElement } from "./incr-search-2YaxUUA9.js";
5
5
  import { i as animateListItemOut, r as animateListItemIn, t as ListNativeDragController } from "./list-native-drag-controller-CcXoS0YX.js";
6
- import { r as ListDragSelectController, t as ListSelectionController } from "./list-selection-controller-5L0Nj9tR.js";
6
+ import { i as ListDragSelectController, n as gestureOf, t as ListSelectionController } from "./list-selection-controller-CJDdjH7E.js";
7
7
  import { l as keysToArray } from "./pending-BGidHppL.js";
8
- import { a as restoreElementScroll, n as anchorFromRow, o as scrollToOffset, r as captureElementScroll, t as ViewStateController } from "./view-state-controller-BdyXWUUM.js";
8
+ import { a as isPartialKey, i as applyPartialAttributes, n as appearanceColor, o as sameKeySet, t as appearanceAbsent } from "./item-appearance-Bl6rMIID.js";
9
9
  import { t as scrollFadeStyles } from "./scroll-fade-Xx28D7mH.js";
10
- import { n as appearanceColor, t as appearanceAbsent } from "./item-appearance-BjcMyauw.js";
10
+ import { a as restoreElementScroll, n as anchorFromRow, o as scrollToOffset, r as captureElementScroll, t as ViewStateController } from "./view-state-controller-BdyXWUUM.js";
11
11
  import "./editable-label.js";
12
12
  import { LitElement, css, html, render } from "lit";
13
13
  import { property } from "lit/decorators.js";
@@ -153,13 +153,15 @@ let VerticalListElement = class VerticalListElement extends LitElement {
153
153
  interactionMode: this.interactionMode
154
154
  }),
155
155
  getKey: keyForElement,
156
+ onIntent: (intent) => this._dispatchCancelable(`list-select-intent`, intent) === false,
156
157
  onChange: (selected, previous) => {
157
158
  this._syncItemStates();
158
159
  this.#viewState.notify();
159
160
  this._dispatch(`list-select`, {
160
161
  selected,
161
162
  previous,
162
- selectedKeys: this.selection.selectedKeys
163
+ selectedKeys: this.selection.selectedKeys,
164
+ previousKeys: keysOfElements(previous)
163
165
  });
164
166
  }
165
167
  });
@@ -245,6 +247,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
245
247
  getAllItems: () => this.#selectionOrder(),
246
248
  observeContainer: false
247
249
  }) });
250
+ this.#partialKeys = /* @__PURE__ */ new Set();
248
251
  this.#onScroll = () => {
249
252
  if (!this.#viewState.pendingScroll) this.#viewState.notify();
250
253
  if (this.#scrollRaf !== 0) return;
@@ -275,7 +278,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
275
278
  if ((e.ctrlKey || e.metaKey) && e.key === `a`) {
276
279
  if (this.selection.canSelectAll()) {
277
280
  e.preventDefault();
278
- this.selection.selectAll();
281
+ this.selection.selectAll(`keyboard`);
279
282
  }
280
283
  return;
281
284
  }
@@ -284,18 +287,18 @@ let VerticalListElement = class VerticalListElement extends LitElement {
284
287
  e.preventDefault();
285
288
  this.tickled.handleKeyboardNavigation(`next`);
286
289
  this.#revealCursor();
287
- if (e.shiftKey && this.interactionMode === `vscode`) {
290
+ if (e.shiftKey && (this.interactionMode === `vscode` || this.interactionMode === `manual`)) {
288
291
  const cur = this.tickled.tickledId;
289
- if (cur) this.selection.rangeTo(cur);
292
+ if (cur) this.selection.handleExtend(cur);
290
293
  }
291
294
  break;
292
295
  case `ArrowUp`:
293
296
  e.preventDefault();
294
297
  this.tickled.handleKeyboardNavigation(`previous`);
295
298
  this.#revealCursor();
296
- if (e.shiftKey && this.interactionMode === `vscode`) {
299
+ if (e.shiftKey && (this.interactionMode === `vscode` || this.interactionMode === `manual`)) {
297
300
  const cur = this.tickled.tickledId;
298
- if (cur) this.selection.rangeTo(cur);
301
+ if (cur) this.selection.handleExtend(cur);
299
302
  }
300
303
  break;
301
304
  case `Home`:
@@ -321,7 +324,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
321
324
  if (id) {
322
325
  e.preventDefault();
323
326
  this._dispatch(`list-item-click`, { item: id });
324
- this._activateItem(id);
327
+ this._activateItem(id, `keyboard`);
325
328
  }
326
329
  break;
327
330
  }
@@ -333,7 +336,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
333
336
  }
334
337
  break;
335
338
  }
336
- case `Escape`: this.selection.clear();
339
+ case `Escape`: this.selection.handleClear(`keyboard`);
337
340
  }
338
341
  };
339
342
  this._onClick = (e) => {
@@ -342,7 +345,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
342
345
  const item = this._findListItem(e.composedPath());
343
346
  if (!item) return;
344
347
  this._dispatch(`list-item-click`, { item });
345
- this.selection.handleClick(item, e);
348
+ this.selection.handleClick(item, gestureOf(e));
346
349
  };
347
350
  this._onDblClick = (e) => {
348
351
  if (this.#isEditEvent(e)) return;
@@ -773,6 +776,23 @@ let VerticalListElement = class VerticalListElement extends LitElement {
773
776
  get selectedKeys() {
774
777
  return this.selection.selectedKeys;
775
778
  }
779
+ #partialKeys;
780
+ /**
781
+ * Rows shown as *partially* selected (a part of the resource is selected):
782
+ * `data-partial`, an indeterminate checkbox in `checked` mode, and an
783
+ * accessible description. Independent of `selectedKeys` — a key in both
784
+ * counts as selected. Replace-on-set; keys without a row are kept for when
785
+ * the row appears.
786
+ */
787
+ get partialKeys() {
788
+ return this.#partialKeys;
789
+ }
790
+ set partialKeys(keys) {
791
+ const next = new Set(keys);
792
+ if (sameKeySet(next, this.#partialKeys)) return;
793
+ this.#partialKeys = next;
794
+ this._syncItemStates();
795
+ }
776
796
  /** The key of the item under the cursor, or `undefined`. */
777
797
  get tickledKey() {
778
798
  const id = this.tickled.tickledId;
@@ -1468,6 +1488,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
1468
1488
  const item = this.#customWrappers.get(el) ?? el;
1469
1489
  el.toggleAttribute(`data-tickled`, this.tickled.isTickled(el));
1470
1490
  el.toggleAttribute(`data-selected`, this.selection.selected.has(el));
1491
+ applyPartialAttributes(el, isPartialKey(keyForElement(el), this.#partialKeys, this.selection.selected.has(el)));
1471
1492
  if (el.hasAttribute(`data-aria-role`)) el.setAttribute(`aria-selected`, String(this.selection.selected.has(el)));
1472
1493
  if (this.interactionMode === `checked`) el.toggleAttribute(`data-checked`, !item.hasAttribute(`not-checked`) && this.selection.selected.has(el));
1473
1494
  else el.removeAttribute(`data-checked`);
@@ -1532,16 +1553,22 @@ let VerticalListElement = class VerticalListElement extends LitElement {
1532
1553
  el.prepend(cb);
1533
1554
  }
1534
1555
  const checked = this.selection.selected.has(el);
1556
+ const partial = isPartialKey(keyForElement(el), this.#partialKeys, checked);
1535
1557
  if (wantsCustom) {
1536
- cb.setAttribute(`aria-checked`, String(checked));
1558
+ cb.setAttribute(`aria-checked`, partial ? `mixed` : String(checked));
1537
1559
  cb.toggleAttribute(`data-checked`, checked);
1560
+ cb.toggleAttribute(`data-partial`, partial);
1538
1561
  if (this.checkboxRenderer) {
1539
1562
  const renderer = typeof this.checkboxRenderer === `function` ? this.checkboxRenderer : this.checkboxRenderer.renderer;
1540
1563
  render(renderer(checked), cb);
1541
1564
  }
1542
1565
  } else {
1543
1566
  const input = cb.querySelector(`input.ixfx-list-checkbox`);
1544
- if (input) input.checked = checked;
1567
+ if (input) {
1568
+ input.checked = checked;
1569
+ input.indeterminate = partial;
1570
+ }
1571
+ cb.setAttribute(`aria-checked`, partial ? `mixed` : String(checked));
1545
1572
  }
1546
1573
  }
1547
1574
  }
@@ -1560,7 +1587,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
1560
1587
  cell.setAttribute(`part`, `checkbox`);
1561
1588
  cell.addEventListener(`click`, (e) => {
1562
1589
  e.stopPropagation();
1563
- this.selection.toggle(el);
1590
+ this.selection.handleCheckbox(el);
1564
1591
  });
1565
1592
  const input = document.createElement(`input`);
1566
1593
  input.type = `checkbox`;
@@ -1582,7 +1609,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
1582
1609
  span.setAttribute(`part`, `checkbox`);
1583
1610
  span.addEventListener(`click`, (e) => {
1584
1611
  e.stopPropagation();
1585
- this.selection.toggle(el);
1612
+ this.selection.handleCheckbox(el);
1586
1613
  });
1587
1614
  return span;
1588
1615
  }
@@ -1608,13 +1635,13 @@ let VerticalListElement = class VerticalListElement extends LitElement {
1608
1635
  cancelable: true
1609
1636
  }));
1610
1637
  }
1611
- _activateItem(item) {
1612
- if (this.interactionMode !== `manual`) this.selection.replace(item);
1638
+ _activateItem(item, source = `pointer`) {
1639
+ this.selection.handleReplace(item, source);
1613
1640
  this._dispatch(`list-activate`, { item });
1614
1641
  }
1615
1642
  activateKey(key) {
1616
1643
  const item = this.#itemForKey(key);
1617
- if (item) this._activateItem(item);
1644
+ if (item) this._activateItem(item, `api`);
1618
1645
  }
1619
1646
  /** The row (or `undefined` for empty space) the last `list-drag-over` was fired for. */
1620
1647
  #dragOver;
@@ -1862,6 +1889,13 @@ let VerticalListElement = class VerticalListElement extends LitElement {
1862
1889
  outline: 1px solid transparent;
1863
1890
  }
1864
1891
 
1892
+ /* Partially selected: a dashed edge, lighter than a full selection. Hook: --item-bg-partial. */
1893
+ ::slotted([data-partial]) {
1894
+ background: var(--item-bg-partial, color-mix(in srgb, var(--item-bg-selected) 35%, transparent));
1895
+ outline: 1px dashed var(--item-border-partial, var(--border));
1896
+ outline-offset: -1px;
1897
+ }
1898
+
1865
1899
  ::slotted([data-selected][data-tickled]) {
1866
1900
  background: var(--item-bg-selected-tickled);
1867
1901
  outline: 2px dashed var(--surface-3);