@ixfx/components 0.16.2 → 0.16.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.d.ts +61 -7
- package/bundle/index.js +151 -143
- package/dist/ac-text.d.ts +1 -1
- package/dist/{ac-token-Cq7lsYf-.d.ts → ac-token-qEs3FsQv.d.ts} +1 -1
- package/dist/ac-token.d.ts +1 -1
- package/dist/ac-token.js +1 -1
- package/dist/{button-D1sPDUCM.d.ts → button-N92DKoWb.d.ts} +1 -1
- package/dist/button.d.ts +1 -1
- package/dist/colour-picker.d.ts +1 -1
- package/dist/{crumb-navigation-nnr881n-.d.ts → crumb-navigation-BbqfmkYs.d.ts} +1 -1
- package/dist/crumbs.d.ts +1 -1
- package/dist/{data-grid-CaPLWt5E.js → data-grid-8TsiF2ES.js} +7 -6
- package/dist/{data-grid-BAEpfTkb.d.ts → data-grid-CslzF16R.d.ts} +4 -4
- package/dist/data-grid.d.ts +1 -1
- package/dist/data-grid.js +1 -1
- package/dist/{detail-list-DK49TsJd.d.ts → detail-list-n1MbNbhF.d.ts} +4 -4
- package/dist/{detail-list-C3XKTRmE.js → detail-list-w3GXKO2k.js} +4 -3
- package/dist/detail-list.d.ts +2 -2
- package/dist/detail-list.js +1 -1
- package/dist/{flat-list-Bv4-qfjp.d.ts → flat-list-D_4y3wgn.d.ts} +4 -4
- package/dist/flat-list.d.ts +1 -1
- package/dist/flat-list.js +2 -2
- package/dist/{grid-list-DaeSHv9P.d.ts → grid-list-CqYS28NY.d.ts} +4 -2
- package/dist/{grid-list-51XsR2X2.js → grid-list-Cz2tKcNZ.js} +4 -3
- package/dist/grid-list.d.ts +2 -2
- package/dist/grid-list.js +1 -1
- package/dist/{grouped-item-lister-DZIjo9nO.d.ts → grouped-item-lister-CS4yInuw.d.ts} +2 -2
- package/dist/grouped-item-lister.d.ts +1 -1
- package/dist/{icon-DR_3rSyZ.d.ts → icon-CDGprSdE.d.ts} +1 -1
- package/dist/icons.d.ts +2 -2
- package/dist/{incr-search-2YaxUUA9.js → incr-search-Dc6gYpJG.js} +24 -4
- package/dist/incr-search.d.ts +1 -1
- package/dist/incr-search.js +1 -1
- package/dist/{index-BjRoPrwj.d.ts → index-Bm9a9S3_.d.ts} +3 -2
- package/dist/{index-garxxqgV.d.ts → index-CYndvTWH.d.ts} +1 -1
- package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +1 -1
- package/dist/{index-Bz3loIAf.d.ts → index-DN2BWctP.d.ts} +1 -1
- package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +1 -1
- package/dist/{index-vdbbGE7N.d.ts → index-VAs9akt4.d.ts} +18 -2
- package/dist/{index-DXDz60XH.d.ts → index-YCDugjdu.d.ts} +4 -4
- package/dist/{index-DM9OLgTH.d.ts → index-ZaA90u09.d.ts} +2 -2
- package/dist/index.d.ts +37 -26
- package/dist/index.js +88 -13
- package/dist/item-appearance-BjcMyauw.js +29 -0
- package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +1 -1
- package/dist/labelled-radial-input.d.ts +2 -2
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/labelled-slider-input.d.ts +1 -1
- package/dist/list-group-header.d.ts +1 -1
- package/dist/{list-selection-controller-CJDdjH7E.js → list-selection-controller-D4iIrvJH.js} +12 -8
- package/dist/{list-selection-types-hj9Njei3.d.ts → list-selection-types-Dnamh2Lu.d.ts} +29 -3
- package/dist/{menu-item-B0zqw2xp.d.ts → menu-item-bF6narIz.d.ts} +1 -1
- package/dist/menu.d.ts +2 -2
- package/dist/{miller-BfrTcujx.js → miller-BrmBywNZ.js} +20 -9
- package/dist/miller.d.ts +1 -1
- package/dist/miller.js +1 -1
- package/dist/narrowed-text.js +1 -1
- package/dist/panel.d.ts +1 -1
- package/dist/{item-appearance-Bl6rMIID.js → partial-keys-Ck6CiprB.js} +1 -29
- package/dist/{split-layout-ChZ0Glrs.d.ts → split-layout-CophkNeU.d.ts} +1 -1
- package/dist/split-layout.d.ts +1 -1
- package/dist/sunburst-tree.d.ts +1 -1
- package/dist/sunburst-tree.js +1 -1
- package/dist/{sunbursttree-list-BAS0KrDG.d.ts → sunbursttree-list-Bk20giTF.d.ts} +1 -1
- package/dist/{sunbursttree-list-906G33ME.js → sunbursttree-list-DQF6DcsS.js} +1 -1
- package/dist/{tab-list-wC0xNz1b.d.ts → tab-list-Df371rqw.d.ts} +1 -1
- package/dist/tabs.d.ts +1 -1
- package/dist/timeline.d.ts +1 -1
- package/dist/{titlebar-B5zSTZnF.d.ts → titlebar-Tqu-VvMU.d.ts} +1 -1
- package/dist/titlebar.d.ts +1 -1
- package/dist/{tree-C_H1COTf.js → tree-BaXYyt5U.js} +185 -69
- package/dist/tree.d.ts +1 -1
- package/dist/tree.js +1 -1
- package/dist/{vertical-list-od4050Bo.d.ts → vertical-list-DtHX26JO.d.ts} +2 -2
- package/dist/{vertical-list-qMRIxZIT.js → vertical-list-o5hfqH87.js} +4 -3
- package/dist/vertical-list.d.ts +2 -2
- package/dist/vertical-list.js +1 -1
- package/docs-user/README.md +6 -0
- package/docs-user/bottom-drawer.md +2 -2
- package/docs-user/crumbs.md +1 -1
- package/docs-user/data-grid.md +3 -3
- package/docs-user/detail-list.md +3 -3
- package/docs-user/dock.md +3 -3
- package/docs-user/flat-list.md +7 -7
- package/docs-user/grid-list.md +4 -4
- package/docs-user/hyperbolic-tree.md +6 -6
- package/docs-user/icicle-tree.md +2 -2
- package/docs-user/incr-search.md +1 -1
- package/docs-user/index.json +26 -2
- package/docs-user/infra-handle.md +122 -0
- package/docs-user/infra-incremental.md +154 -0
- package/docs-user/infra-theming.md +510 -0
- package/docs-user/infra-view-state.md +210 -0
- package/docs-user/list-state.md +656 -0
- package/docs-user/llms.txt +6 -0
- package/docs-user/miller.md +5 -1
- package/docs-user/multicol-list.md +6 -0
- package/docs-user/panel.md +3 -3
- package/docs-user/select-horiz.md +1 -1
- package/docs-user/split-layout.md +2 -2
- package/docs-user/sunburst-tree.md +3 -3
- package/docs-user/titlebar.md +2 -2
- package/docs-user/tree.md +8 -2
- package/docs-user/treemap.md +2 -2
- package/docs-user/twosplit-layout.md +3 -3
- package/docs-user/user-selection-intents.md +86 -0
- package/docs-user/user-theming.md +1 -1
- package/docs-user/vertical-list.md +3 -3
- package/llms.txt +6 -0
- package/package.json +1 -1
- /package/dist/{index-DV3iaUBW.d.ts → index-DV3iaUBW2.d.ts} +0 -0
|
@@ -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-
|
|
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
|
|
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`)
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
3027
|
-
|
|
3028
|
-
|
|
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.#
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
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-
|
|
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-VAs9akt4.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-
|
|
1
|
+
import { a as TreeDataModel, i as TreeDropController, n as TreeListElement, r as TreeBaseElement, t as TreeController } from "./tree-BaXYyt5U.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 {
|
|
6
|
-
import { S as ListSearchController } from "./index-
|
|
5
|
+
import { h as ListSelectionMode, i as ListInteractionMode, r as ListElementEventMap } from "./list-selection-types-Dnamh2Lu.js";
|
|
6
|
+
import { S as ListSearchController } from "./index-Bm9a9S3_.js";
|
|
7
7
|
import "./editable-label-rzXkjf1H.js";
|
|
8
8
|
import { LitElement, PropertyValues } from "lit";
|
|
9
9
|
import { CommandId, CommandRegistry } from "@clinth/ui-commands";
|
|
@@ -1,13 +1,14 @@
|
|
|
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, d as keysOfElements, i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, u as keyForElement } from "./incr-search-
|
|
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-Dc6gYpJG.js";
|
|
5
5
|
import { i as animateListItemOut, r as animateListItemIn, t as ListNativeDragController } from "./list-native-drag-controller-CcXoS0YX.js";
|
|
6
|
-
import { i as ListDragSelectController, n as gestureOf, t as ListSelectionController } from "./list-selection-controller-
|
|
6
|
+
import { i as ListDragSelectController, n as gestureOf, t as ListSelectionController } from "./list-selection-controller-D4iIrvJH.js";
|
|
7
7
|
import { l as keysToArray } from "./pending-BGidHppL.js";
|
|
8
|
-
import {
|
|
8
|
+
import { i as sameKeySet, n as applyPartialAttributes, r as isPartialKey } from "./partial-keys-Ck6CiprB.js";
|
|
9
9
|
import { t as scrollFadeStyles } from "./scroll-fade-Xx28D7mH.js";
|
|
10
10
|
import { a as restoreElementScroll, n as anchorFromRow, 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 "./editable-label.js";
|
|
12
13
|
import { LitElement, css, html, render } from "lit";
|
|
13
14
|
import { property } from "lit/decorators.js";
|
package/dist/vertical-list.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { B as ListNativeDragStartDetail, F as ListDragPreview, I as ListDragPreviewContext, L as ListDragPreviewRenderer, P as ListDragEntry, V as ListNativeDragStartEvent, z as ListDragSource } from "./tree-component-DgfkxmVY.js";
|
|
2
2
|
import { n as ListViewportChangeEvent, t as ListViewportChangeDetail } from "./list-viewport-types-BRZsLcvp.js";
|
|
3
|
-
import { a as ListItemClickDetail, c as
|
|
4
|
-
import { a as VerticalListViewState, c as ListDragLeaveDetail, d as ListDropDetail, f as ListDropEvent, g as ListEditCommitEvent, h as ListEditCommitDetail, i as VerticalListElementEventMap, l as ListDragLeaveEvent, m as ListEditCancelEvent, n as CustomCheckboxOptions, o as ListContextMenuDetail, p as ListEditCancelDetail, r as VerticalListElement, s as ListContextMenuEvent, t as AddItemOptions, u as ListDragOverEvent } from "./vertical-list-
|
|
3
|
+
import { _ as ListTickleEvent, a as ListItemClickDetail, c as ListSelectDetail, g as ListTickleDetail, h as ListSelectionMode, i as ListInteractionMode, l as ListSelectEvent, n as ListActivateEvent, o as ListItemClickEvent, r as ListElementEventMap, t as ListActivateDetail } from "./list-selection-types-Dnamh2Lu.js";
|
|
4
|
+
import { a as VerticalListViewState, c as ListDragLeaveDetail, d as ListDropDetail, f as ListDropEvent, g as ListEditCommitEvent, h as ListEditCommitDetail, i as VerticalListElementEventMap, l as ListDragLeaveEvent, m as ListEditCancelEvent, n as CustomCheckboxOptions, o as ListContextMenuDetail, p as ListEditCancelDetail, r as VerticalListElement, s as ListContextMenuEvent, t as AddItemOptions, u as ListDragOverEvent } from "./vertical-list-DtHX26JO.js";
|
|
5
5
|
export { AddItemOptions, CustomCheckboxOptions, type ListActivateDetail, type ListActivateEvent, type ListContextMenuDetail, type ListContextMenuEvent, type ListDragEntry, type ListDragLeaveDetail, type ListDragLeaveEvent, type ListDragOverEvent, type ListDragPreview, type ListDragPreviewContext, type ListDragPreviewRenderer, type ListDragSource, type ListDropDetail, type ListDropEvent, type ListEditCancelDetail, type ListEditCancelEvent, type ListEditCommitDetail, type ListEditCommitEvent, type ListElementEventMap, type ListInteractionMode, type ListItemClickDetail, type ListItemClickEvent, type ListNativeDragStartDetail, type ListNativeDragStartEvent, type ListSelectDetail, type ListSelectEvent, type ListSelectionMode, type ListTickleDetail, type ListTickleEvent, type ListViewportChangeDetail, type ListViewportChangeEvent, VerticalListElement, VerticalListElementEventMap, type VerticalListViewState };
|
package/dist/vertical-list.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as VerticalListElement } from "./vertical-list-
|
|
1
|
+
import { t as VerticalListElement } from "./vertical-list-o5hfqH87.js";
|
|
2
2
|
export { VerticalListElement };
|
package/docs-user/README.md
CHANGED
|
@@ -67,6 +67,12 @@ This directory contains documentation for each component and some architectural
|
|
|
67
67
|
|
|
68
68
|
## Architectural Overviews
|
|
69
69
|
|
|
70
|
+
- [infra-handle.md](infra-handle.md)
|
|
71
|
+
- [infra-incremental.md](infra-incremental.md)
|
|
72
|
+
- [infra-theming.md](infra-theming.md)
|
|
70
73
|
- [infra-tickled.md](infra-tickled.md)
|
|
74
|
+
- [infra-view-state.md](infra-view-state.md)
|
|
75
|
+
- [list-state.md](list-state.md)
|
|
71
76
|
- [user-catalog.md](user-catalog.md)
|
|
77
|
+
- [user-selection-intents.md](user-selection-intents.md)
|
|
72
78
|
- [user-theming.md](user-theming.md)
|
|
@@ -146,5 +146,5 @@ import type { BottomDrawerElement, BottomDrawerResizeDetail, BottomDrawerCloseEv
|
|
|
146
146
|
|
|
147
147
|
## See also
|
|
148
148
|
|
|
149
|
-
- [`ixfx-titlebar`](
|
|
150
|
-
- [`ixfx-icon`](
|
|
149
|
+
- [`ixfx-titlebar`](./titlebar.md) — Header component used by the drawer
|
|
150
|
+
- [`ixfx-icon`](./icons.md) — Icon component for header icons
|
package/docs-user/crumbs.md
CHANGED
|
@@ -63,7 +63,7 @@ nav.model = {
|
|
|
63
63
|
### View state
|
|
64
64
|
|
|
65
65
|
The current location as plain JSON, for the host to persist (see
|
|
66
|
-
[docs/infra-view-state.md](
|
|
66
|
+
[docs/infra-view-state.md](./infra-view-state.md)):
|
|
67
67
|
|
|
68
68
|
```ts
|
|
69
69
|
{ v: 1, kind: 'crumb-navigation', path: ['dev', 'workspace'] } // keys below the root; [] = root
|
package/docs-user/data-grid.md
CHANGED
|
@@ -52,7 +52,7 @@ type DataGridColumn = {
|
|
|
52
52
|
};
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
* `width` defaults to `150`. Drag the handle between headers to resize; double-click handle to auto-size to content. Drag the grip handle (shared `dimpled` spot handle — see [docs/infra-handle.md](
|
|
55
|
+
* `width` defaults to `150`. Drag the handle between headers to resize; double-click handle to auto-size to content. Drag the grip handle (shared `dimpled` spot handle — see [docs/infra-handle.md](./infra-handle.md)) to reorder.
|
|
56
56
|
* `align` controls cell content justification. Numeric columns should use `right` (or `center` for Age) – cells use `font-variant-numeric: tabular-nums` so decimal points align when paired with a fixed formatter.
|
|
57
57
|
* `renderer` overrides default `String(value)` display. Use `html` from `lit`.
|
|
58
58
|
|
|
@@ -227,7 +227,7 @@ The setter fires `datagrid-select` `{ selectedKeys, previous }` (and `list-selec
|
|
|
227
227
|
only when the selection actually changes. A cancelable `list-select-intent` fires
|
|
228
228
|
before every selection gesture, and `partialKeys` marks partially selected rows
|
|
229
229
|
(`data-partial`, indeterminate checkbox in `checked` mode).
|
|
230
|
-
See [Selection intents, partial rows, unloaded keys](
|
|
230
|
+
See [Selection intents, partial rows, unloaded keys](./user-selection-intents.md): `list-select-intent`, `partialKeys`, and keys that arrive later.
|
|
231
231
|
|
|
232
232
|
Selected rows that leave `rows` are deselected silently, and reselected if they
|
|
233
233
|
return. See [View state](#view-state). In `checked` mode the row checkbox toggles
|
|
@@ -527,7 +527,7 @@ Matched characters in the search column are highlighted under the
|
|
|
527
527
|
against a custom `rowSearchText` aren't highlighted, since they can't be
|
|
528
528
|
mapped onto a cell, and neither are cells drawn by a column `renderer`. `filterPredicate`
|
|
529
529
|
(a `(row) => boolean` property) filters rows directly. `search-modes` limits the
|
|
530
|
-
offered modes. Full model: [`docs/infra-incremental.md`](
|
|
530
|
+
offered modes. Full model: [`docs/infra-incremental.md`](./infra-incremental.md).
|
|
531
531
|
|
|
532
532
|
---
|
|
533
533
|
|
package/docs-user/detail-list.md
CHANGED
|
@@ -464,7 +464,7 @@ With wrapping:
|
|
|
464
464
|
|
|
465
465
|
## Incremental search
|
|
466
466
|
|
|
467
|
-
A built-in type-ahead popover with **navigate** / **select** / **filter** modes — see [`docs/infra-incremental.md`](
|
|
467
|
+
A built-in type-ahead popover with **navigate** / **select** / **filter** modes — see [`docs/infra-incremental.md`](./infra-incremental.md). No default shortcut; open it with `list.registry.invoke('list.search.filter')` (or `.navigate` / `.select`). A filter change re-runs the column geometry automatically.
|
|
468
468
|
|
|
469
469
|
Search matches against `data-search-label` (or `textContent` as fallback). Use `data-search-label` to match against a different string than what's displayed:
|
|
470
470
|
|
|
@@ -489,7 +489,7 @@ Matched characters are highlighted with the `detail-list-search` highlight key.
|
|
|
489
489
|
|
|
490
490
|
## Grouping
|
|
491
491
|
|
|
492
|
-
Group rows under collapsible headers, following `ixfx-data-grid` (see its [Grouping](
|
|
492
|
+
Group rows under collapsible headers, following `ixfx-data-grid` (see its [Grouping](./data-grid.md#grouping) section).
|
|
493
493
|
|
|
494
494
|
```ts
|
|
495
495
|
list.groupBy = 'kind'; // object items: property · declarative <li>: data-kind
|
|
@@ -607,7 +607,7 @@ replaced) falls back to a full rebuild.
|
|
|
607
607
|
|
|
608
608
|
Snapshot and restore *how* the list is showing its data, separately from the
|
|
609
609
|
data, as plain JSON keyed by item / group key. See
|
|
610
|
-
[`docs/infra-view-state.md`](
|
|
610
|
+
[`docs/infra-view-state.md`](./infra-view-state.md) for the shared
|
|
611
611
|
contract.
|
|
612
612
|
|
|
613
613
|
```ts
|
package/docs-user/dock.md
CHANGED
|
@@ -98,7 +98,7 @@ wrapped in a new split. `Escape` or `pointercancel` cancels with no mutation.
|
|
|
98
98
|
|
|
99
99
|
Where a parent gutter line meets a nested split's gutter (T and + crossings
|
|
100
100
|
of three or four panels), the host renders a small hover-revealed handle — the
|
|
101
|
-
shared `dimpled` spot handle ([docs/infra-handle.md](
|
|
101
|
+
shared `dimpled` spot handle ([docs/infra-handle.md](./infra-handle.md)),
|
|
102
102
|
`var(--accent)` tinted. Dragging it
|
|
103
103
|
starts the vertical and horizontal gutter drags at once via
|
|
104
104
|
`ixfx-split-layout`'s `beginGutterDrag()`, resizing all adjacent panels with
|
|
@@ -434,7 +434,7 @@ the target host (adopt / focus it yourself instead).
|
|
|
434
434
|
## View state
|
|
435
435
|
|
|
436
436
|
The dock implements the shared view-state API
|
|
437
|
-
([docs/infra-view-state.md](
|
|
437
|
+
([docs/infra-view-state.md](./infra-view-state.md)). The component
|
|
438
438
|
never persists anything; the host does, e.g. with `bindViewState()`:
|
|
439
439
|
|
|
440
440
|
```ts
|
|
@@ -498,7 +498,7 @@ The dock layout is close to structure, so the saved state *is* the tree
|
|
|
498
498
|
| `--dock-leaf-body-padding` | padding inside leaf body | `var(--space-s)` |
|
|
499
499
|
|
|
500
500
|
The junction resize handle is the shared handle primitive — theme it with
|
|
501
|
-
`--ixfx-handle-*` (see [docs/infra-handle.md](
|
|
501
|
+
`--ixfx-handle-*` (see [docs/infra-handle.md](./infra-handle.md)).
|
|
502
502
|
|
|
503
503
|
Splitter styling delegates to `ixfx-split-layout` (`--split-*`); solo panel
|
|
504
504
|
chrome delegates to `ixfx-titlebar`, and the leaf body is the docked panel
|
package/docs-user/flat-list.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# `ixfx-flat-list`
|
|
2
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`](
|
|
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.md) above the scroll area shows the path and jumps to any ancestor.
|
|
4
4
|
|
|
5
|
-
It wraps [`ixfx-vertical-list`](
|
|
5
|
+
It wraps [`ixfx-vertical-list`](./vertical-list.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
6
|
|
|
7
7
|
```html
|
|
8
8
|
<ixfx-flat-list style="height: 280px"></ixfx-flat-list>
|
|
@@ -32,7 +32,7 @@ list.addEventListener('flat-list-activate', ({ detail }) => open(detail.node));
|
|
|
32
32
|
| `canDrop` | `(node, dataTransfer) => boolean` | | Refuse a drag up front. `node` is the row, or the current level's node over empty space |
|
|
33
33
|
| `validateEdit` | `(value, node) => boolean` | | Opts in to [rename](#rename) and validates the typed text |
|
|
34
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](
|
|
35
|
+
| `virtualize`, `itemHeight` / `item-height` | `boolean`, `number` | `false`, `0` | Render only visible rows; needs a fixed row height. See [virtualisation](./vertical-list.md#virtualisation) |
|
|
36
36
|
| `withUp` / `with-up` | `boolean` | `true` | Up button in the crumb bar |
|
|
37
37
|
| `hideRoot` / `hide-root` | `boolean` | `false` | Hide the root crumb |
|
|
38
38
|
| `emptyText` / `empty-text` | `string` | `'Empty'` | Shown for a level with no children |
|
|
@@ -74,14 +74,14 @@ The inner list's `list-*` events also cross the shadow boundary, with row elemen
|
|
|
74
74
|
| Click the chevron, double-click, `Enter`, `Arrow Right` on a branch | Enter it |
|
|
75
75
|
| `Arrow Left`, `Backspace` | Go up. The cursor lands on the branch you came from |
|
|
76
76
|
| Crumb, caret menu, Up button | Jump to that node. Choosing a leaf from a caret menu shows its level and selects it |
|
|
77
|
-
| Everything else | See [vertical-list keyboard navigation](
|
|
77
|
+
| Everything else | See [vertical-list keyboard navigation](./vertical-list.md#keyboard-navigation) |
|
|
78
78
|
|
|
79
79
|
Selection is cleared on every level change. Arrow Left and Backspace are ignored while the search field is focused.
|
|
80
80
|
|
|
81
81
|
## View state
|
|
82
82
|
|
|
83
83
|
The level shown and its selection, cursor and scroll, as plain JSON for the
|
|
84
|
-
host to persist (see [docs/infra-view-state.md](
|
|
84
|
+
host to persist (see [docs/infra-view-state.md](./infra-view-state.md)):
|
|
85
85
|
|
|
86
86
|
```ts
|
|
87
87
|
{ v: 1, kind: 'flat-list', path: ['docs', 'work'], selected: ['a.txt'], focus: 'a.txt', scroll: { top: 0 } }
|
|
@@ -106,7 +106,7 @@ as its rows arrive (see the vertical-list README).
|
|
|
106
106
|
|
|
107
107
|
## Drops
|
|
108
108
|
|
|
109
|
-
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](
|
|
109
|
+
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.md#drop-targets).
|
|
110
110
|
|
|
111
111
|
## Context menu
|
|
112
112
|
|
|
@@ -126,7 +126,7 @@ list.beginEdit('set:2'); // e.g. from your own context menu
|
|
|
126
126
|
|
|
127
127
|
## Incremental search
|
|
128
128
|
|
|
129
|
-
Navigate / select / filter search works over the current level, as in [`ixfx-vertical-list`](
|
|
129
|
+
Navigate / select / filter search works over the current level, as in [`ixfx-vertical-list`](./vertical-list.md#incremental-search) — see [`docs/infra-incremental.md`](./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.
|
|
130
130
|
|
|
131
131
|
## CSS variables
|
|
132
132
|
|