@ixfx/components 0.8.8 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.d.ts +252 -43
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +1177 -39
- package/bundle/index.js.map +1 -1
- package/dist/crumbs.d.ts +1 -1
- package/dist/{data-grid-BKa9i86q.d.ts → data-grid-C588pTgt.d.ts} +3 -3
- package/dist/{data-grid-BKa9i86q.d.ts.map → data-grid-C588pTgt.d.ts.map} +1 -1
- package/dist/data-grid.d.ts +2 -2
- package/dist/data-grid.js +1 -1
- package/dist/{detail-list-CHTomlbR.d.ts → detail-list-IKl76Wnp.d.ts} +4 -4
- package/dist/{detail-list-CHTomlbR.d.ts.map → detail-list-IKl76Wnp.d.ts.map} +1 -1
- package/dist/detail-list.d.ts +3 -3
- package/dist/detail-list.js +1 -1
- package/dist/{grid-list-CsZcXxMC.d.ts → grid-list-C1zq5U1W.d.ts} +20 -56
- package/dist/grid-list-C1zq5U1W.d.ts.map +1 -0
- package/dist/{grid-list-C8oMxLl-.js → grid-list-zUZRI8hk.js} +39 -3
- package/dist/grid-list-zUZRI8hk.js.map +1 -0
- package/dist/grid-list.d.ts +2 -2
- package/dist/grid-list.js +1 -1
- package/dist/incr-search.d.ts +1 -1
- package/dist/{index-Dgrx-DIA.d.ts → index--qnhBWZJ.d.ts} +2 -2
- package/dist/{index-Dgrx-DIA.d.ts.map → index--qnhBWZJ.d.ts.map} +1 -1
- package/dist/index.d.ts +30 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/{labelled-slider-input-BCH9968c.js → labelled-slider-input-aEYDvW2S.js} +2 -2
- package/dist/{labelled-slider-input-BCH9968c.js.map → labelled-slider-input-aEYDvW2S.js.map} +1 -1
- package/dist/labelled-slider-input.js +1 -1
- package/dist/list-native-drag-controller-Cmpx7jnx.d.ts +68 -0
- package/dist/list-native-drag-controller-Cmpx7jnx.d.ts.map +1 -0
- package/dist/{list-native-drag-controller-DrY3qeJM.js → list-native-drag-controller-DaBNcjgG.js} +28 -2
- package/dist/list-native-drag-controller-DaBNcjgG.js.map +1 -0
- package/dist/miller.d.ts +2 -2
- package/dist/plots.js +1 -1
- package/dist/slider-input-BxURAAmD.d.ts.map +1 -1
- package/dist/{slider-input-WR8_RwHg.js → slider-input-Cb5uSV42.js} +78 -11
- package/dist/slider-input-Cb5uSV42.js.map +1 -0
- package/dist/slider-input.js +1 -1
- package/dist/{split-layout-CA5jbNbG.js → split-layout-Bx0g8k8-.js} +24 -1
- package/dist/{split-layout-CA5jbNbG.js.map → split-layout-Bx0g8k8-.js.map} +1 -1
- package/dist/split-layout-JK3xWVX2.d.ts.map +1 -1
- package/dist/split-layout.js +1 -1
- package/dist/{tree-DSMn566I.js → tree-CwifXCzR.js} +1006 -19
- package/dist/tree-CwifXCzR.js.map +1 -0
- package/dist/{tree-component-nPP5Y-WS.d.ts → tree-component-BW2iCFq9.d.ts} +107 -3
- package/dist/tree-component-BW2iCFq9.d.ts.map +1 -0
- package/dist/tree.d.ts +102 -4
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +2 -2
- package/dist/{vertical-list-A6oWfivZ.d.ts → vertical-list-CHrXmmQ3.d.ts} +3 -3
- package/dist/{vertical-list-A6oWfivZ.d.ts.map → vertical-list-CHrXmmQ3.d.ts.map} +1 -1
- package/dist/vertical-list.d.ts +2 -2
- package/dist/vertical-list.js +1 -1
- package/dist/{xy-axis-CrrVdDFe.js → xy-axis-COKw338Q.js} +2 -2
- package/dist/xy-axis-COKw338Q.js.map +1 -0
- package/dist/xy-axis-DQqd2yXJ.d.ts.map +1 -1
- package/docs-user/index.json +2 -2
- package/docs-user/tree.md +75 -0
- package/package.json +1 -1
- package/dist/grid-list-C8oMxLl-.js.map +0 -1
- package/dist/grid-list-CsZcXxMC.d.ts.map +0 -1
- package/dist/list-drag-types-kpaXz2pZ.d.ts +0 -42
- package/dist/list-drag-types-kpaXz2pZ.d.ts.map +0 -1
- package/dist/list-native-drag-controller-DrY3qeJM.js.map +0 -1
- package/dist/slider-input-WR8_RwHg.js.map +0 -1
- package/dist/tree-DSMn566I.js.map +0 -1
- package/dist/tree-component-nPP5Y-WS.d.ts.map +0 -1
- package/dist/xy-axis-CrrVdDFe.js.map +0 -1
package/bundle/index.js
CHANGED
|
@@ -6049,7 +6049,7 @@ const DEFAULT_THRESHOLD = 4;
|
|
|
6049
6049
|
/** Pointer distance (px) from an edge that triggers auto-scroll. */
|
|
6050
6050
|
const EDGE_ZONE = 28;
|
|
6051
6051
|
/** Max auto-scroll speed in px per frame. */
|
|
6052
|
-
const MAX_SCROLL_SPEED = 16;
|
|
6052
|
+
const MAX_SCROLL_SPEED$1 = 16;
|
|
6053
6053
|
/**
|
|
6054
6054
|
* Shared pointer-drag (marquee / rubber-band) selection for list components.
|
|
6055
6055
|
*
|
|
@@ -6315,10 +6315,10 @@ var ListDragSelectController = class {
|
|
|
6315
6315
|
const py = this.#currentClientY - box.top;
|
|
6316
6316
|
let dx = 0;
|
|
6317
6317
|
let dy = 0;
|
|
6318
|
-
if (px < EDGE_ZONE) dx = -Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, px) / EDGE_ZONE));
|
|
6319
|
-
else if (px > box.width - EDGE_ZONE) dx = Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, box.width - px) / EDGE_ZONE));
|
|
6320
|
-
if (py < EDGE_ZONE) dy = -Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, py) / EDGE_ZONE));
|
|
6321
|
-
else if (py > box.height - EDGE_ZONE) dy = Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, box.height - py) / EDGE_ZONE));
|
|
6318
|
+
if (px < EDGE_ZONE) dx = -Math.ceil(MAX_SCROLL_SPEED$1 * (1 - Math.max(0, px) / EDGE_ZONE));
|
|
6319
|
+
else if (px > box.width - EDGE_ZONE) dx = Math.ceil(MAX_SCROLL_SPEED$1 * (1 - Math.max(0, box.width - px) / EDGE_ZONE));
|
|
6320
|
+
if (py < EDGE_ZONE) dy = -Math.ceil(MAX_SCROLL_SPEED$1 * (1 - Math.max(0, py) / EDGE_ZONE));
|
|
6321
|
+
else if (py > box.height - EDGE_ZONE) dy = Math.ceil(MAX_SCROLL_SPEED$1 * (1 - Math.max(0, box.height - py) / EDGE_ZONE));
|
|
6322
6322
|
if (dx === 0 && dy === 0) return;
|
|
6323
6323
|
const autoScroll = this.#config.autoScroll;
|
|
6324
6324
|
if (!autoScroll) return;
|
|
@@ -6521,6 +6521,10 @@ var ListNativeDragController = class {
|
|
|
6521
6521
|
} catch {}
|
|
6522
6522
|
this.refreshDraggable();
|
|
6523
6523
|
}
|
|
6524
|
+
/** `renderRoot` does not exist yet at `hostConnected` for a shadow-DOM host — rebind once it does. */
|
|
6525
|
+
hostUpdated() {
|
|
6526
|
+
this.#bind();
|
|
6527
|
+
}
|
|
6524
6528
|
hostDisconnected() {
|
|
6525
6529
|
this.#unbind();
|
|
6526
6530
|
try {
|
|
@@ -6558,7 +6562,20 @@ var ListNativeDragController = class {
|
|
|
6558
6562
|
#onDragStart = (event) => {
|
|
6559
6563
|
if (!(event instanceof DragEvent)) return;
|
|
6560
6564
|
if (this.#seenDragStarts.has(event)) return;
|
|
6561
|
-
this.#
|
|
6565
|
+
if (this.#config.shouldStart) {
|
|
6566
|
+
let ok = true;
|
|
6567
|
+
try {
|
|
6568
|
+
ok = this.#config.shouldStart(event);
|
|
6569
|
+
} catch {
|
|
6570
|
+
ok = false;
|
|
6571
|
+
}
|
|
6572
|
+
if (!ok) {
|
|
6573
|
+
try {
|
|
6574
|
+
event.preventDefault();
|
|
6575
|
+
} catch {}
|
|
6576
|
+
return;
|
|
6577
|
+
}
|
|
6578
|
+
}
|
|
6562
6579
|
let enabled = false;
|
|
6563
6580
|
try {
|
|
6564
6581
|
enabled = this.#config.isEnabled();
|
|
@@ -6572,6 +6589,7 @@ var ListNativeDragController = class {
|
|
|
6572
6589
|
} catch {
|
|
6573
6590
|
return;
|
|
6574
6591
|
}
|
|
6592
|
+
if (originKey) this.#seenDragStarts.add(event);
|
|
6575
6593
|
if (!originKey) return;
|
|
6576
6594
|
let prepared;
|
|
6577
6595
|
try {
|
|
@@ -6630,6 +6648,14 @@ var ListNativeDragController = class {
|
|
|
6630
6648
|
notCancelled = true;
|
|
6631
6649
|
}
|
|
6632
6650
|
if (notCancelled) {
|
|
6651
|
+
if (event.dataTransfer) {
|
|
6652
|
+
try {
|
|
6653
|
+
if (event.dataTransfer.effectAllowed === `none` || event.dataTransfer.effectAllowed === `uninitialized`) event.dataTransfer.effectAllowed = `copyMove`;
|
|
6654
|
+
} catch {}
|
|
6655
|
+
try {
|
|
6656
|
+
this.#config.writeDataTransfer?.(event.dataTransfer, detail);
|
|
6657
|
+
} catch {}
|
|
6658
|
+
}
|
|
6633
6659
|
const hotspot = preview.hotspot ?? {
|
|
6634
6660
|
x: 16,
|
|
6635
6661
|
y: 16
|
|
@@ -9736,15 +9762,138 @@ async function collectDataResult(result, signal) {
|
|
|
9736
9762
|
return result;
|
|
9737
9763
|
}
|
|
9738
9764
|
//#endregion
|
|
9739
|
-
//#region src/common/tree-
|
|
9765
|
+
//#region src/common/tree-drop-apply.ts
|
|
9740
9766
|
function findNode$1(root, key) {
|
|
9741
9767
|
if (root.item.key === key) return root;
|
|
9742
|
-
|
|
9743
|
-
for (const child of root.children) {
|
|
9768
|
+
for (const child of root.children ?? []) {
|
|
9744
9769
|
const found = findNode$1(child, key);
|
|
9745
9770
|
if (found) return found;
|
|
9746
9771
|
}
|
|
9747
9772
|
}
|
|
9773
|
+
function findParent(root, key, parent = void 0) {
|
|
9774
|
+
for (const child of root.children ?? []) {
|
|
9775
|
+
if (child.item.key === key) return parent === void 0 ? root : parent;
|
|
9776
|
+
const found = findParent(child, key, child);
|
|
9777
|
+
if (found) return found;
|
|
9778
|
+
}
|
|
9779
|
+
}
|
|
9780
|
+
/** True when `key` is `ancestorKey`, or a descendant of it. */
|
|
9781
|
+
function isSelfOrDescendant(root, ancestorKey, key) {
|
|
9782
|
+
const ancestor = findNode$1(root, ancestorKey);
|
|
9783
|
+
return ancestor !== void 0 && findNode$1(ancestor, key) !== void 0;
|
|
9784
|
+
}
|
|
9785
|
+
/** Remove every node whose key is in `keys` (with its whole subtree), in one pass. */
|
|
9786
|
+
function removeKeys(node, keys) {
|
|
9787
|
+
if (!node.children) return node;
|
|
9788
|
+
return {
|
|
9789
|
+
...node,
|
|
9790
|
+
children: node.children.filter((c) => !keys.has(c.item.key)).map((c) => removeKeys(c, keys))
|
|
9791
|
+
};
|
|
9792
|
+
}
|
|
9793
|
+
function childrenOf(root, parentKey) {
|
|
9794
|
+
if (parentKey === void 0) return root.children ?? [];
|
|
9795
|
+
return findNode$1(root, parentKey)?.children ?? [];
|
|
9796
|
+
}
|
|
9797
|
+
/** Return a new root with `parentKey`'s children replaced (root itself when `parentKey` is undefined). */
|
|
9798
|
+
function withChildren(node, parentKey, children) {
|
|
9799
|
+
if (parentKey === void 0) return {
|
|
9800
|
+
...node,
|
|
9801
|
+
children
|
|
9802
|
+
};
|
|
9803
|
+
if (node.item.key === parentKey) return {
|
|
9804
|
+
...node,
|
|
9805
|
+
children
|
|
9806
|
+
};
|
|
9807
|
+
if (!node.children) return node;
|
|
9808
|
+
return {
|
|
9809
|
+
...node,
|
|
9810
|
+
children: node.children.map((c) => withChildren(c, parentKey, children))
|
|
9811
|
+
};
|
|
9812
|
+
}
|
|
9813
|
+
function clamp$5(n, min, max) {
|
|
9814
|
+
return Math.max(min, Math.min(max, n));
|
|
9815
|
+
}
|
|
9816
|
+
/**
|
|
9817
|
+
* Drop keys whose ancestor is also being dragged — only the top-most selected
|
|
9818
|
+
* nodes move; their subtrees travel with them. Preserves input order.
|
|
9819
|
+
*/
|
|
9820
|
+
function pruneDraggedDescendants(root, keys) {
|
|
9821
|
+
const set = new Set(keys);
|
|
9822
|
+
return keys.filter((key) => {
|
|
9823
|
+
let parent = findParent(root, key);
|
|
9824
|
+
while (parent) {
|
|
9825
|
+
if (set.has(parent.item.key)) return false;
|
|
9826
|
+
parent = findParent(root, parent.item.key);
|
|
9827
|
+
}
|
|
9828
|
+
return true;
|
|
9829
|
+
});
|
|
9830
|
+
}
|
|
9831
|
+
/**
|
|
9832
|
+
* Framework-agnostic drop application. Given the current immutable `root` and a
|
|
9833
|
+
* resolved drop context, returns a **new** root with the drop applied, or the
|
|
9834
|
+
* unchanged `root` when the drop is invalid (dragged node into its own subtree,
|
|
9835
|
+
* missing reference, empty payload). Never throws, never mutates.
|
|
9836
|
+
*
|
|
9837
|
+
* The insertion point is re-derived from `target.referenceKey` + `target.position`
|
|
9838
|
+
* against the post-removal tree, so same-parent reorders are off-by-one-safe and
|
|
9839
|
+
* multi-node drops land as siblings in drag order. `target.index` is honoured only
|
|
9840
|
+
* for `position: 'inside'` (0 = first child, large = append).
|
|
9841
|
+
*/
|
|
9842
|
+
function applyTreeDrop(root, ctx) {
|
|
9843
|
+
const { target, source } = ctx;
|
|
9844
|
+
let nodes;
|
|
9845
|
+
let removeSet = /* @__PURE__ */ new Set();
|
|
9846
|
+
if (source === `internal`) {
|
|
9847
|
+
const keys = pruneDraggedDescendants(root, [...ctx.draggedKeys]);
|
|
9848
|
+
if (keys.length === 0) return root;
|
|
9849
|
+
if (target.parentKey !== void 0) {
|
|
9850
|
+
for (const key of keys) if (isSelfOrDescendant(root, key, target.parentKey)) return root;
|
|
9851
|
+
}
|
|
9852
|
+
if (target.position !== `inside`) {
|
|
9853
|
+
for (const key of keys) if (isSelfOrDescendant(root, key, target.referenceKey)) return root;
|
|
9854
|
+
}
|
|
9855
|
+
const resolved = keys.map((k) => findNode$1(root, k));
|
|
9856
|
+
if (resolved.includes(void 0)) return root;
|
|
9857
|
+
nodes = resolved;
|
|
9858
|
+
removeSet = new Set(keys);
|
|
9859
|
+
} else {
|
|
9860
|
+
nodes = (ctx.dragged ?? []).map((n) => ({ ...n }));
|
|
9861
|
+
if (nodes.length === 0) return root;
|
|
9862
|
+
}
|
|
9863
|
+
const afterRemoval = removeSet.size > 0 ? removeKeys(root, removeSet) : root;
|
|
9864
|
+
let parentKey;
|
|
9865
|
+
let index;
|
|
9866
|
+
if (target.position === `inside`) {
|
|
9867
|
+
if (findNode$1(afterRemoval, target.referenceKey) === void 0) return root;
|
|
9868
|
+
parentKey = target.referenceKey;
|
|
9869
|
+
const kids = childrenOf(afterRemoval, parentKey);
|
|
9870
|
+
index = clamp$5(target.index, 0, kids.length);
|
|
9871
|
+
} else {
|
|
9872
|
+
parentKey = findParent(afterRemoval, target.referenceKey)?.item.key;
|
|
9873
|
+
const refIdx = childrenOf(afterRemoval, parentKey).findIndex((c) => c.item.key === target.referenceKey);
|
|
9874
|
+
if (refIdx < 0) return root;
|
|
9875
|
+
index = target.position === `before` ? refIdx : refIdx + 1;
|
|
9876
|
+
}
|
|
9877
|
+
const kids = [...childrenOf(afterRemoval, parentKey)];
|
|
9878
|
+
const next = [
|
|
9879
|
+
...kids.slice(0, index),
|
|
9880
|
+
...nodes,
|
|
9881
|
+
...kids.slice(index)
|
|
9882
|
+
];
|
|
9883
|
+
return withChildren(afterRemoval, parentKey, next);
|
|
9884
|
+
}
|
|
9885
|
+
/** Build a synthetic `TreeDropTarget` for programmatic moves (see `TreeDataModel`). */
|
|
9886
|
+
function dropTargetFor(referenceKey, position, index = position === `inside` ? Number.MAX_SAFE_INTEGER : 0) {
|
|
9887
|
+
return {
|
|
9888
|
+
referenceKey,
|
|
9889
|
+
position,
|
|
9890
|
+
index,
|
|
9891
|
+
parentKey: position === `inside` ? referenceKey : void 0,
|
|
9892
|
+
depth: 0
|
|
9893
|
+
};
|
|
9894
|
+
}
|
|
9895
|
+
//#endregion
|
|
9896
|
+
//#region src/common/tree-data-model.ts
|
|
9748
9897
|
/** Return a new root with the node at `key` replaced by `replacer(node)`. */
|
|
9749
9898
|
function mapNode(root, key, replacer) {
|
|
9750
9899
|
if (root.item.key === key) return replacer(root);
|
|
@@ -9769,11 +9918,23 @@ function removeNodeFrom(root, key) {
|
|
|
9769
9918
|
children: root.children.filter((c) => c.item.key !== key).map((c) => removeNodeFrom(c, key))
|
|
9770
9919
|
};
|
|
9771
9920
|
}
|
|
9772
|
-
/** Return a new root with
|
|
9773
|
-
function
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
|
|
9921
|
+
/** Return a new root with `newChild` inserted at `index` among the children of `parentKey`. */
|
|
9922
|
+
function insertChildAt(root, parentKey, newChild, index) {
|
|
9923
|
+
return mapNode(root, parentKey, (parent) => {
|
|
9924
|
+
const children = parent.children ?? [];
|
|
9925
|
+
const clampedIndex = Math.max(0, Math.min(index, children.length));
|
|
9926
|
+
return {
|
|
9927
|
+
item: parent.item,
|
|
9928
|
+
children: [
|
|
9929
|
+
...children.slice(0, clampedIndex),
|
|
9930
|
+
newChild,
|
|
9931
|
+
...children.slice(clampedIndex)
|
|
9932
|
+
]
|
|
9933
|
+
};
|
|
9934
|
+
});
|
|
9935
|
+
}
|
|
9936
|
+
function getRootChildren(root) {
|
|
9937
|
+
return root.children ?? [];
|
|
9777
9938
|
}
|
|
9778
9939
|
/**
|
|
9779
9940
|
* Manages tree data for tree-like components.
|
|
@@ -9901,10 +10062,80 @@ var TreeDataModel = class {
|
|
|
9901
10062
|
}
|
|
9902
10063
|
/**
|
|
9903
10064
|
* Moves the node with the given key to become a child of `newParentKey`.
|
|
10065
|
+
* When `index` is provided, inserts at that position; otherwise appends.
|
|
9904
10066
|
* Returns the new root (connected components are notified automatically).
|
|
9905
10067
|
*/
|
|
9906
|
-
moveNode(key, newParentKey) {
|
|
9907
|
-
|
|
10068
|
+
moveNode(key, newParentKey, index) {
|
|
10069
|
+
const next = applyTreeDrop(this.#root, {
|
|
10070
|
+
source: `internal`,
|
|
10071
|
+
draggedKeys: [key],
|
|
10072
|
+
target: dropTargetFor(newParentKey, `inside`, index ?? Number.MAX_SAFE_INTEGER)
|
|
10073
|
+
});
|
|
10074
|
+
if (next !== this.#root) {
|
|
10075
|
+
this.#root = next;
|
|
10076
|
+
this.#notify({
|
|
10077
|
+
type: `root`,
|
|
10078
|
+
root: this.#root
|
|
10079
|
+
});
|
|
10080
|
+
}
|
|
10081
|
+
return this.#root;
|
|
10082
|
+
}
|
|
10083
|
+
/**
|
|
10084
|
+
* Moves the node with the given key to become a sibling of `referenceKey`,
|
|
10085
|
+
* positioned `before` or `after` it. A no-op (returns the unchanged root) when
|
|
10086
|
+
* `key` is `referenceKey`, an ancestor of it, or either is missing.
|
|
10087
|
+
* Returns the new root (connected components are notified automatically).
|
|
10088
|
+
*/
|
|
10089
|
+
moveNodeRelative(key, referenceKey, position) {
|
|
10090
|
+
const next = applyTreeDrop(this.#root, {
|
|
10091
|
+
source: `internal`,
|
|
10092
|
+
draggedKeys: [key],
|
|
10093
|
+
target: dropTargetFor(referenceKey, position)
|
|
10094
|
+
});
|
|
10095
|
+
if (next !== this.#root) {
|
|
10096
|
+
this.#root = next;
|
|
10097
|
+
this.#notify({
|
|
10098
|
+
type: `root`,
|
|
10099
|
+
root: this.#root
|
|
10100
|
+
});
|
|
10101
|
+
}
|
|
10102
|
+
return this.#root;
|
|
10103
|
+
}
|
|
10104
|
+
/**
|
|
10105
|
+
* Applies a resolved drop (from `ixfx-tree-list`'s `tree-drop` event or a
|
|
10106
|
+
* hand-built context) to the current root. No-op when the drop is invalid.
|
|
10107
|
+
* Returns the new root (connected components are notified automatically).
|
|
10108
|
+
*/
|
|
10109
|
+
applyDrop(ctx) {
|
|
10110
|
+
const next = applyTreeDrop(this.#root, ctx);
|
|
10111
|
+
if (next !== this.#root) {
|
|
10112
|
+
this.#root = next;
|
|
10113
|
+
this.#notify({
|
|
10114
|
+
type: `root`,
|
|
10115
|
+
root: this.#root
|
|
10116
|
+
});
|
|
10117
|
+
}
|
|
10118
|
+
return this.#root;
|
|
10119
|
+
}
|
|
10120
|
+
/**
|
|
10121
|
+
* Inserts `node` as a child of `parentKey` (or at the root level when `parentKey` is undefined).
|
|
10122
|
+
* When `index` is provided, inserts at that position; otherwise appends.
|
|
10123
|
+
* Returns the new root (connected components are notified automatically).
|
|
10124
|
+
*/
|
|
10125
|
+
insertNode(parentKey, node, index) {
|
|
10126
|
+
if (parentKey === void 0) {
|
|
10127
|
+
const children = getRootChildren(this.#root);
|
|
10128
|
+
const clampedIndex = Math.max(0, Math.min(index ?? children.length, children.length));
|
|
10129
|
+
this.#root = {
|
|
10130
|
+
...this.#root,
|
|
10131
|
+
children: [
|
|
10132
|
+
...children.slice(0, clampedIndex),
|
|
10133
|
+
node,
|
|
10134
|
+
...children.slice(clampedIndex)
|
|
10135
|
+
]
|
|
10136
|
+
};
|
|
10137
|
+
} else if (index !== void 0) this.#root = insertChildAt(this.#root, parentKey, node, index);
|
|
10138
|
+
else this.#root = addChildTo(this.#root, parentKey, node);
|
|
9908
10139
|
this.#notify({
|
|
9909
10140
|
type: `root`,
|
|
9910
10141
|
root: this.#root
|
|
@@ -15244,6 +15475,7 @@ let DataTableElement = class DataTableElement extends i {
|
|
|
15244
15475
|
this.styles = [
|
|
15245
15476
|
tickledStyles,
|
|
15246
15477
|
tickledItemStyles,
|
|
15478
|
+
popupSurfaceStyles,
|
|
15247
15479
|
i$3`
|
|
15248
15480
|
:host {
|
|
15249
15481
|
display: block;
|
|
@@ -15383,7 +15615,6 @@ let DataTableElement = class DataTableElement extends i {
|
|
|
15383
15615
|
width: max-content;
|
|
15384
15616
|
max-width: 100cqi;
|
|
15385
15617
|
padding: var(--space-xs);
|
|
15386
|
-
background: var(--surface-2);
|
|
15387
15618
|
visibility: hidden;
|
|
15388
15619
|
transform: translateY(-4px);
|
|
15389
15620
|
pointer-events: none;
|
|
@@ -15462,7 +15693,7 @@ let DataTableElement = class DataTableElement extends i {
|
|
|
15462
15693
|
?data-full=${r.fullWidth}
|
|
15463
15694
|
@pointerenter=${() => this.#handlePointerEnter(i)}
|
|
15464
15695
|
@click=${() => this.#select(i)}
|
|
15465
|
-
><div class="key">${r.label}</div><div class="value"><span class="value-text">${typeof r.value === `boolean` ? r.value ? `Yes` : `No` : r.value}</span>${r.detail === void 0 ? A : b`<div class="detail" part="detail">${r.detail}</div>`}</div></div>`)}</div>`;
|
|
15696
|
+
><div class="key">${r.label}</div><div class="value"><span class="value-text">${typeof r.value === `boolean` ? r.value ? `Yes` : `No` : r.value}</span>${r.detail === void 0 ? A : b`<div class="detail popup-surface" part="detail">${r.detail}</div>`}</div></div>`)}</div>`;
|
|
15466
15697
|
}
|
|
15467
15698
|
};
|
|
15468
15699
|
__decorate([property({
|
|
@@ -18289,6 +18520,7 @@ let SplitLayoutElement = class SplitLayoutElement extends i {
|
|
|
18289
18520
|
width: 100%;
|
|
18290
18521
|
height: 100%;
|
|
18291
18522
|
--split-gutter-size: 6px;
|
|
18523
|
+
--split-gutter-hit-size: 12px;
|
|
18292
18524
|
--split-gutter-color: transparent;
|
|
18293
18525
|
--split-gutter-hover-color: var(--surface-6);
|
|
18294
18526
|
--split-gutter-active-color: var(--accent);
|
|
@@ -18331,6 +18563,14 @@ let SplitLayoutElement = class SplitLayoutElement extends i {
|
|
|
18331
18563
|
display: flex;
|
|
18332
18564
|
align-items: center;
|
|
18333
18565
|
justify-content: center;
|
|
18566
|
+
position: relative;
|
|
18567
|
+
}
|
|
18568
|
+
|
|
18569
|
+
.gutter::before {
|
|
18570
|
+
content: '';
|
|
18571
|
+
position: absolute;
|
|
18572
|
+
pointer-events: auto;
|
|
18573
|
+
background: transparent;
|
|
18334
18574
|
}
|
|
18335
18575
|
|
|
18336
18576
|
:host([direction="row"]) .gutter {
|
|
@@ -18339,12 +18579,26 @@ let SplitLayoutElement = class SplitLayoutElement extends i {
|
|
|
18339
18579
|
min-height: 100%;
|
|
18340
18580
|
}
|
|
18341
18581
|
|
|
18582
|
+
:host([direction="row"]) .gutter::before {
|
|
18583
|
+
width: var(--split-gutter-hit-size, 12px);
|
|
18584
|
+
height: 100%;
|
|
18585
|
+
left: 50%;
|
|
18586
|
+
transform: translateX(-50%);
|
|
18587
|
+
}
|
|
18588
|
+
|
|
18342
18589
|
:host([direction="column"]) .gutter {
|
|
18343
18590
|
height: var(--split-gutter-size);
|
|
18344
18591
|
cursor: ns-resize;
|
|
18345
18592
|
min-width: 100%;
|
|
18346
18593
|
}
|
|
18347
18594
|
|
|
18595
|
+
:host([direction="column"]) .gutter::before {
|
|
18596
|
+
height: var(--split-gutter-hit-size, 12px);
|
|
18597
|
+
width: 100%;
|
|
18598
|
+
top: 50%;
|
|
18599
|
+
transform: translateY(-50%);
|
|
18600
|
+
}
|
|
18601
|
+
|
|
18348
18602
|
.gutter:hover,
|
|
18349
18603
|
.gutter[data-active] {
|
|
18350
18604
|
background: var(--split-gutter-hover-color);
|
|
@@ -20645,7 +20899,7 @@ let DockHostElement = class DockHostElement extends i {
|
|
|
20645
20899
|
class="split"
|
|
20646
20900
|
direction=${node.direction}
|
|
20647
20901
|
size=${size === void 0 ? A : String(size)}
|
|
20648
|
-
style=${`--split-gutter-size: var(--dock-split-bar-size, 2px)`}
|
|
20902
|
+
style=${`--split-gutter-size: var(--dock-split-bar-size, 2px); --split-collapsed-size: var(--dock-collapsed-size, 40px)`}
|
|
20649
20903
|
data-dock-path=${pathStr}
|
|
20650
20904
|
@ixfx-split-resize=${this._onSplitWeightsChanged}
|
|
20651
20905
|
@ixfx-split-change=${this._onSplitWeightsChanged}
|
|
@@ -22662,6 +22916,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
22662
22916
|
this.captionHeight = 24;
|
|
22663
22917
|
this.itemWrap = `stop`;
|
|
22664
22918
|
this.itemsDraggable = false;
|
|
22919
|
+
this.marqueeFromCellBlank = false;
|
|
22665
22920
|
this.items = [];
|
|
22666
22921
|
this._scrollTop = 0;
|
|
22667
22922
|
this._scrollLeft = 0;
|
|
@@ -22745,7 +23000,8 @@ let GridListElement = class GridListElement extends i {
|
|
|
22745
23000
|
},
|
|
22746
23001
|
syncLightDomDraggable: () => {
|
|
22747
23002
|
for (const child of this.children) if (child instanceof HTMLElement) child.draggable = this.itemsDraggable;
|
|
22748
|
-
}
|
|
23003
|
+
},
|
|
23004
|
+
shouldStart: (event) => !(this.marqueeFromCellBlank && this.#isCellBlankPress(event))
|
|
22749
23005
|
});
|
|
22750
23006
|
this.#activeCaptionPan = null;
|
|
22751
23007
|
this.#dragSelect = new ListDragSelectController(this, {
|
|
@@ -22777,6 +23033,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
22777
23033
|
}
|
|
22778
23034
|
},
|
|
22779
23035
|
shouldStart: (event) => {
|
|
23036
|
+
if (this.marqueeFromCellBlank && this.#isCellBlankPress(event)) return true;
|
|
22780
23037
|
for (const node of event.composedPath()) if (node instanceof Element && node.classList.contains(`cell`)) return false;
|
|
22781
23038
|
return true;
|
|
22782
23039
|
}
|
|
@@ -22883,6 +23140,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
22883
23140
|
--grid-list-item-bg: var(--item-bg);
|
|
22884
23141
|
--grid-list-radius: var(--radius-m);
|
|
22885
23142
|
--grid-list-gap: var(--space-xs);
|
|
23143
|
+
--grid-list-padding: var(--space-xs);
|
|
22886
23144
|
position: relative;
|
|
22887
23145
|
display: block;
|
|
22888
23146
|
height: 100%;
|
|
@@ -22903,6 +23161,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
22903
23161
|
height: 100%;
|
|
22904
23162
|
overflow-y: auto;
|
|
22905
23163
|
overflow-x: hidden;
|
|
23164
|
+
padding: var(--grid-list-padding);
|
|
22906
23165
|
/* Consumer control over the native scrollbar (both orientations): set
|
|
22907
23166
|
--grid-list-scrollbar-width to "none" to hide it or "thin" to slim it.
|
|
22908
23167
|
The container is also exposed as ::part(viewport). */
|
|
@@ -23053,6 +23312,11 @@ let GridListElement = class GridListElement extends i {
|
|
|
23053
23312
|
border-top: 1px solid var(--border, rgba(128, 128, 128, 0.3));
|
|
23054
23313
|
background: var(--surface-4, transparent);
|
|
23055
23314
|
}
|
|
23315
|
+
:host([caption-style="under"][caption-position="top"]) .caption {
|
|
23316
|
+
order: -1;
|
|
23317
|
+
border-top: none;
|
|
23318
|
+
border-bottom: 1px solid var(--border, rgba(128, 128, 128, 0.3));
|
|
23319
|
+
}
|
|
23056
23320
|
|
|
23057
23321
|
/* overlaid: caption floats over the content */
|
|
23058
23322
|
:host([caption-style="overlaid"]) .caption {
|
|
@@ -23119,6 +23383,11 @@ let GridListElement = class GridListElement extends i {
|
|
|
23119
23383
|
}
|
|
23120
23384
|
:host([caption-style="separate"][caption-align="left"]) .caption { align-self: flex-start; }
|
|
23121
23385
|
:host([caption-style="separate"][caption-align="right"]) .caption { align-self: flex-end; }
|
|
23386
|
+
:host([caption-style="separate"][caption-position="top"]) .caption {
|
|
23387
|
+
order: -1;
|
|
23388
|
+
margin-top: 0;
|
|
23389
|
+
margin-bottom: 4px;
|
|
23390
|
+
}
|
|
23122
23391
|
/* Inset the selection ring (negative offset) so it is never clipped by the
|
|
23123
23392
|
scroll viewport's overflow when the cell sits against an edge. */
|
|
23124
23393
|
:host([caption-style="separate"]) .cell.selected .thumb {
|
|
@@ -23265,6 +23534,22 @@ let GridListElement = class GridListElement extends i {
|
|
|
23265
23534
|
#activeCaptionPan;
|
|
23266
23535
|
#dragSelect;
|
|
23267
23536
|
/**
|
|
23537
|
+
* True when a pointer / drag event landed on a cell's blank well: the composed
|
|
23538
|
+
* path reaches `.thumb` without first crossing a slotted node (the item's own
|
|
23539
|
+
* content), the `.caption`, or an interactive control.
|
|
23540
|
+
*/
|
|
23541
|
+
#isCellBlankPress(event) {
|
|
23542
|
+
for (const node of event.composedPath()) {
|
|
23543
|
+
if (!(node instanceof Element)) continue;
|
|
23544
|
+
if (node.assignedSlot) return false;
|
|
23545
|
+
if (node.matches?.(`input,button,a,select,textarea,[contenteditable]`)) return false;
|
|
23546
|
+
if (node.classList.contains(`caption`)) return false;
|
|
23547
|
+
if (node.classList.contains(`thumb`)) return true;
|
|
23548
|
+
if (node.classList.contains(`cell`)) return false;
|
|
23549
|
+
}
|
|
23550
|
+
return false;
|
|
23551
|
+
}
|
|
23552
|
+
/**
|
|
23268
23553
|
* Map a surface-relative (viewport-visible) rect to covered item keys using
|
|
23269
23554
|
* the same `computeGridWindow` geometry the renderer uses — pure arithmetic,
|
|
23270
23555
|
* so virtualized off-screen items are covered without DOM measurement.
|
|
@@ -24157,6 +24442,11 @@ __decorate([property({
|
|
|
24157
24442
|
attribute: `items-draggable`,
|
|
24158
24443
|
reflect: true
|
|
24159
24444
|
})], GridListElement.prototype, "itemsDraggable", void 0);
|
|
24445
|
+
__decorate([property({
|
|
24446
|
+
type: Boolean,
|
|
24447
|
+
attribute: `marquee-from-cell-blank`,
|
|
24448
|
+
reflect: true
|
|
24449
|
+
})], GridListElement.prototype, "marqueeFromCellBlank", void 0);
|
|
24160
24450
|
__decorate([property({ attribute: false })], GridListElement.prototype, "dragPreviewRenderer", void 0);
|
|
24161
24451
|
__decorate([property({
|
|
24162
24452
|
type: String,
|
|
@@ -24552,6 +24842,360 @@ __decorate([property({
|
|
|
24552
24842
|
})], GroupedItemListerElement.prototype, "crossGroupSelection", void 0);
|
|
24553
24843
|
GroupedItemListerElement = __decorate([safeCustomElement(`ixfx-grouped-item-lister`)], GroupedItemListerElement);
|
|
24554
24844
|
//#endregion
|
|
24845
|
+
//#region src/tree/tree-drag-registry.ts
|
|
24846
|
+
const TREE_DRAG_MIME = `application/x-ixfx-tree`;
|
|
24847
|
+
const registry = /* @__PURE__ */ new Map();
|
|
24848
|
+
const weakRefs = /* @__PURE__ */ new Map();
|
|
24849
|
+
/**
|
|
24850
|
+
* The source id of the drag currently in flight, if any. There is only ever one
|
|
24851
|
+
* native drag at a time, so a drop target can resolve the dragged nodes during
|
|
24852
|
+
* `dragover` — when `DataTransfer.getData()` is unreadable (protected mode) — by
|
|
24853
|
+
* looking this up in the registry.
|
|
24854
|
+
*/
|
|
24855
|
+
let currentSourceId;
|
|
24856
|
+
let sourceIdCounter = 0;
|
|
24857
|
+
function treeDragGenerateSourceId() {
|
|
24858
|
+
return `tree-drag-${++sourceIdCounter}-${Date.now()}`;
|
|
24859
|
+
}
|
|
24860
|
+
function treeDragRegister(sourceId, element, nodes, keys) {
|
|
24861
|
+
registry.set(sourceId, {
|
|
24862
|
+
sourceId,
|
|
24863
|
+
nodes,
|
|
24864
|
+
keys
|
|
24865
|
+
});
|
|
24866
|
+
weakRefs.set(sourceId, new WeakRef(element));
|
|
24867
|
+
currentSourceId = sourceId;
|
|
24868
|
+
}
|
|
24869
|
+
function treeDragUnregister(sourceId) {
|
|
24870
|
+
registry.delete(sourceId);
|
|
24871
|
+
weakRefs.delete(sourceId);
|
|
24872
|
+
if (currentSourceId === sourceId) currentSourceId = void 0;
|
|
24873
|
+
}
|
|
24874
|
+
/** The in-flight drag's `{ keys, nodes, element }`, or `undefined` when nothing is dragging. */
|
|
24875
|
+
function treeDragCurrent() {
|
|
24876
|
+
if (currentSourceId === void 0) return void 0;
|
|
24877
|
+
const entry = registry.get(currentSourceId);
|
|
24878
|
+
if (!entry) return void 0;
|
|
24879
|
+
return {
|
|
24880
|
+
sourceId: currentSourceId,
|
|
24881
|
+
keys: entry.keys,
|
|
24882
|
+
nodes: entry.nodes,
|
|
24883
|
+
element: weakRefs.get(currentSourceId)?.deref()
|
|
24884
|
+
};
|
|
24885
|
+
}
|
|
24886
|
+
//#endregion
|
|
24887
|
+
//#region src/tree/tree-drop-controller.ts
|
|
24888
|
+
const EDGE_ZONE_PX$1 = 24;
|
|
24889
|
+
const MAX_SCROLL_SPEED = 16;
|
|
24890
|
+
function clamp$4(value, min, max) {
|
|
24891
|
+
return Math.max(min, Math.min(max, value));
|
|
24892
|
+
}
|
|
24893
|
+
var TreeDropController = class {
|
|
24894
|
+
#host;
|
|
24895
|
+
#config;
|
|
24896
|
+
#active = false;
|
|
24897
|
+
#current;
|
|
24898
|
+
#source = `internal`;
|
|
24899
|
+
#dragKeys = [];
|
|
24900
|
+
#dragNodes = [];
|
|
24901
|
+
#expandTimer;
|
|
24902
|
+
#expandPendingKey;
|
|
24903
|
+
#scrollRaf = 0;
|
|
24904
|
+
#pointerX = 0;
|
|
24905
|
+
#pointerY = 0;
|
|
24906
|
+
#boundContainer;
|
|
24907
|
+
constructor(host, config) {
|
|
24908
|
+
this.#host = host;
|
|
24909
|
+
this.#config = config;
|
|
24910
|
+
host.addController(this);
|
|
24911
|
+
}
|
|
24912
|
+
/** A drag is currently over this tree. */
|
|
24913
|
+
get isDragging() {
|
|
24914
|
+
return this.#active;
|
|
24915
|
+
}
|
|
24916
|
+
/** A drag is over this tree but the current position is not a valid drop. */
|
|
24917
|
+
get isRejected() {
|
|
24918
|
+
return this.#active && this.#current === void 0;
|
|
24919
|
+
}
|
|
24920
|
+
get dropState() {
|
|
24921
|
+
return this.#current;
|
|
24922
|
+
}
|
|
24923
|
+
hostConnected() {
|
|
24924
|
+
this.#bind();
|
|
24925
|
+
}
|
|
24926
|
+
/** Bind once the shadow `#container` exists (it does not yet at `hostConnected`). */
|
|
24927
|
+
hostUpdated() {
|
|
24928
|
+
this.#bind();
|
|
24929
|
+
}
|
|
24930
|
+
#bind() {
|
|
24931
|
+
const container = this.#config.getScrollContainer();
|
|
24932
|
+
if (!container || container === this.#boundContainer) return;
|
|
24933
|
+
this.#unbind();
|
|
24934
|
+
this.#boundContainer = container;
|
|
24935
|
+
container.addEventListener(`dragenter`, this.#onDragEnter);
|
|
24936
|
+
container.addEventListener(`dragover`, this.#onDragOver);
|
|
24937
|
+
container.addEventListener(`dragleave`, this.#onDragLeave);
|
|
24938
|
+
container.addEventListener(`drop`, this.#onDrop);
|
|
24939
|
+
}
|
|
24940
|
+
#unbind() {
|
|
24941
|
+
const c = this.#boundContainer;
|
|
24942
|
+
if (!c) return;
|
|
24943
|
+
c.removeEventListener(`dragenter`, this.#onDragEnter);
|
|
24944
|
+
c.removeEventListener(`dragover`, this.#onDragOver);
|
|
24945
|
+
c.removeEventListener(`dragleave`, this.#onDragLeave);
|
|
24946
|
+
c.removeEventListener(`drop`, this.#onDrop);
|
|
24947
|
+
this.#boundContainer = void 0;
|
|
24948
|
+
}
|
|
24949
|
+
hostDisconnected() {
|
|
24950
|
+
this.#unbind();
|
|
24951
|
+
this.#clearExpand();
|
|
24952
|
+
this.#stopScroll();
|
|
24953
|
+
this.#active = false;
|
|
24954
|
+
this.#current = void 0;
|
|
24955
|
+
}
|
|
24956
|
+
#onDragEnter = (event) => {
|
|
24957
|
+
if (this.#config.getDndMode() === `none` || !event.dataTransfer) return;
|
|
24958
|
+
if (this.#config.resolveDrag(event.dataTransfer, `hover`) === void 0) return;
|
|
24959
|
+
event.preventDefault();
|
|
24960
|
+
if (!this.#active) {
|
|
24961
|
+
this.#active = true;
|
|
24962
|
+
this.#config.onActiveChange(true);
|
|
24963
|
+
}
|
|
24964
|
+
};
|
|
24965
|
+
#onDragOver = (event) => {
|
|
24966
|
+
if (this.#config.getDndMode() === `none` || !event.dataTransfer) return;
|
|
24967
|
+
this.#pointerX = event.clientX;
|
|
24968
|
+
this.#pointerY = event.clientY;
|
|
24969
|
+
const drag = this.#config.resolveDrag(event.dataTransfer, `hover`);
|
|
24970
|
+
if (!drag) {
|
|
24971
|
+
this.#reject(event);
|
|
24972
|
+
return;
|
|
24973
|
+
}
|
|
24974
|
+
if (!this.#active) {
|
|
24975
|
+
this.#active = true;
|
|
24976
|
+
this.#config.onActiveChange(true);
|
|
24977
|
+
}
|
|
24978
|
+
this.#source = drag.source;
|
|
24979
|
+
this.#dragKeys = drag.keys;
|
|
24980
|
+
this.#dragNodes = drag.nodes;
|
|
24981
|
+
const rows = this.#config.getVisibleRows();
|
|
24982
|
+
this.#handleExpandHover(this.#rowAtPointer(rows, event.clientY));
|
|
24983
|
+
this.#kickScroll();
|
|
24984
|
+
const target = this.#resolveIntent(event, rows, drag.source);
|
|
24985
|
+
if (!target) {
|
|
24986
|
+
this.#reject(event, false);
|
|
24987
|
+
return;
|
|
24988
|
+
}
|
|
24989
|
+
const ctx = {
|
|
24990
|
+
source: drag.source,
|
|
24991
|
+
dragged: drag.nodes.length > 0 ? drag.nodes : void 0,
|
|
24992
|
+
draggedKeys: drag.keys,
|
|
24993
|
+
target,
|
|
24994
|
+
dataTransfer: event.dataTransfer
|
|
24995
|
+
};
|
|
24996
|
+
if (!this.#config.vet(ctx)) {
|
|
24997
|
+
this.#reject(event, false);
|
|
24998
|
+
return;
|
|
24999
|
+
}
|
|
25000
|
+
event.preventDefault();
|
|
25001
|
+
event.dataTransfer.dropEffect = drag.source === `internal` ? `move` : `copy`;
|
|
25002
|
+
this.#setDropState(target);
|
|
25003
|
+
};
|
|
25004
|
+
/** Not a valid drop here: keep the drag active for feedback but accept nothing. */
|
|
25005
|
+
#reject(event, clearHover = true) {
|
|
25006
|
+
if (event.dataTransfer) event.dataTransfer.dropEffect = `none`;
|
|
25007
|
+
this.#setDropState(void 0);
|
|
25008
|
+
if (clearHover) this.#clearExpand();
|
|
25009
|
+
}
|
|
25010
|
+
#onDragLeave = (event) => {
|
|
25011
|
+
const container = this.#config.getScrollContainer();
|
|
25012
|
+
const related = event.relatedTarget;
|
|
25013
|
+
if (container && related && container.contains(related)) return;
|
|
25014
|
+
this.#endHover();
|
|
25015
|
+
};
|
|
25016
|
+
#onDrop = (event) => {
|
|
25017
|
+
if (!event.dataTransfer) {
|
|
25018
|
+
this.#endHover();
|
|
25019
|
+
return;
|
|
25020
|
+
}
|
|
25021
|
+
event.preventDefault();
|
|
25022
|
+
this.#stopScroll();
|
|
25023
|
+
this.#clearExpand();
|
|
25024
|
+
const finish = (dropped) => {
|
|
25025
|
+
this.#current = void 0;
|
|
25026
|
+
this.#active = false;
|
|
25027
|
+
this.#config.onDropStateChange(void 0);
|
|
25028
|
+
this.#config.onActiveChange(false);
|
|
25029
|
+
this.#config.onDragEnd(dropped);
|
|
25030
|
+
};
|
|
25031
|
+
if (this.#config.getDndMode() === `none`) {
|
|
25032
|
+
finish(false);
|
|
25033
|
+
return;
|
|
25034
|
+
}
|
|
25035
|
+
const drag = this.#config.resolveDrag(event.dataTransfer, `drop`);
|
|
25036
|
+
if (!drag) {
|
|
25037
|
+
finish(false);
|
|
25038
|
+
return;
|
|
25039
|
+
}
|
|
25040
|
+
this.#dragKeys = drag.keys;
|
|
25041
|
+
this.#dragNodes = drag.nodes;
|
|
25042
|
+
const target = this.#resolveIntent(event, this.#config.getVisibleRows(), drag.source);
|
|
25043
|
+
if (!target) {
|
|
25044
|
+
finish(false);
|
|
25045
|
+
return;
|
|
25046
|
+
}
|
|
25047
|
+
const ctx = {
|
|
25048
|
+
source: drag.source,
|
|
25049
|
+
dragged: drag.nodes.length > 0 ? drag.nodes : void 0,
|
|
25050
|
+
draggedKeys: drag.keys,
|
|
25051
|
+
target,
|
|
25052
|
+
dataTransfer: event.dataTransfer
|
|
25053
|
+
};
|
|
25054
|
+
if (!this.#config.vet(ctx)) {
|
|
25055
|
+
finish(false);
|
|
25056
|
+
return;
|
|
25057
|
+
}
|
|
25058
|
+
const detail = {
|
|
25059
|
+
...ctx,
|
|
25060
|
+
external: drag.source === `external` ? drag.nodes : void 0
|
|
25061
|
+
};
|
|
25062
|
+
finish(this.#config.commitDrop(detail));
|
|
25063
|
+
};
|
|
25064
|
+
#endHover() {
|
|
25065
|
+
this.#clearExpand();
|
|
25066
|
+
this.#stopScroll();
|
|
25067
|
+
if (this.#current !== void 0) {
|
|
25068
|
+
this.#current = void 0;
|
|
25069
|
+
this.#config.onDropStateChange(void 0);
|
|
25070
|
+
}
|
|
25071
|
+
if (this.#active) {
|
|
25072
|
+
this.#active = false;
|
|
25073
|
+
this.#config.onActiveChange(false);
|
|
25074
|
+
}
|
|
25075
|
+
}
|
|
25076
|
+
#rowAtPointer(rows, clientY) {
|
|
25077
|
+
if (rows.length === 0) return void 0;
|
|
25078
|
+
if (clientY < rows[0].rect.top) return rows[0];
|
|
25079
|
+
if (clientY > rows[rows.length - 1].rect.bottom) return rows[rows.length - 1];
|
|
25080
|
+
return rows.find((r) => clientY >= r.rect.top && clientY <= r.rect.bottom) ?? rows[rows.length - 1];
|
|
25081
|
+
}
|
|
25082
|
+
#parentRow(rows, index) {
|
|
25083
|
+
const target = rows[index];
|
|
25084
|
+
for (let i = index - 1; i >= 0; i--) if (rows[i].depth === target.depth - 1) return rows[i];
|
|
25085
|
+
}
|
|
25086
|
+
#resolveIntent(event, rows, source) {
|
|
25087
|
+
if (rows.length === 0) return void 0;
|
|
25088
|
+
const row = this.#rowAtPointer(rows, event.clientY);
|
|
25089
|
+
if (!row) return void 0;
|
|
25090
|
+
const rowIndex = rows.indexOf(row);
|
|
25091
|
+
const f = clamp$4((event.clientY - row.rect.top) / row.rect.height, 0, 1);
|
|
25092
|
+
let position = f < .25 ? `before` : f > .75 ? `after` : `inside`;
|
|
25093
|
+
const isLeaf = row.node.item.isLeaf === true;
|
|
25094
|
+
if (position === `inside` && isLeaf) position = `after`;
|
|
25095
|
+
let insideFromExpandedAfter = false;
|
|
25096
|
+
if (position === `after` && !isLeaf && this.#config.isExpanded(row.key)) {
|
|
25097
|
+
position = `inside`;
|
|
25098
|
+
insideFromExpandedAfter = true;
|
|
25099
|
+
}
|
|
25100
|
+
let parentKey;
|
|
25101
|
+
let referenceKey;
|
|
25102
|
+
let depth;
|
|
25103
|
+
let index;
|
|
25104
|
+
if (position === `inside`) {
|
|
25105
|
+
parentKey = row.key;
|
|
25106
|
+
referenceKey = row.key;
|
|
25107
|
+
depth = row.depth + 1;
|
|
25108
|
+
index = insideFromExpandedAfter ? 0 : row.node.children?.length ?? 0;
|
|
25109
|
+
} else {
|
|
25110
|
+
const indent = this.#config.getIndentPx() || 1;
|
|
25111
|
+
const treeLeft = rows[0].rect.left;
|
|
25112
|
+
const effDepth = clamp$4(Math.round((event.clientX - treeLeft) / indent), 0, row.depth);
|
|
25113
|
+
let anchorIndex = rowIndex;
|
|
25114
|
+
for (let up = row.depth - effDepth; up > 0; up--) {
|
|
25115
|
+
const parent = this.#parentRow(rows, anchorIndex);
|
|
25116
|
+
if (!parent) break;
|
|
25117
|
+
anchorIndex = rows.indexOf(parent);
|
|
25118
|
+
}
|
|
25119
|
+
const anchor = rows[anchorIndex];
|
|
25120
|
+
referenceKey = anchor.key;
|
|
25121
|
+
depth = anchor.depth;
|
|
25122
|
+
const parent = this.#parentRow(rows, anchorIndex);
|
|
25123
|
+
parentKey = parent?.key;
|
|
25124
|
+
const refIdx = (parent ? parent.node.children ?? [] : rows.filter((r) => r.depth === 0).map((r) => r.node)).findIndex((n) => n.item.key === anchor.key);
|
|
25125
|
+
index = (refIdx < 0 ? 0 : refIdx) + (position === `after` ? 1 : 0);
|
|
25126
|
+
}
|
|
25127
|
+
if (source === `internal`) {
|
|
25128
|
+
for (const key of this.#dragKeys) {
|
|
25129
|
+
if (key === parentKey || key === referenceKey) return void 0;
|
|
25130
|
+
if (parentKey !== void 0 && this.#config.isSelfOrDescendant(key, parentKey)) return void 0;
|
|
25131
|
+
if (position !== `inside` && this.#config.isSelfOrDescendant(key, referenceKey)) return void 0;
|
|
25132
|
+
}
|
|
25133
|
+
if (this.#dragKeys.length > 0 && !this.#config.isReorderAllowed()) {
|
|
25134
|
+
if (!this.#dragKeys.some((k) => this.#config.getParentKey(k) !== parentKey)) return void 0;
|
|
25135
|
+
}
|
|
25136
|
+
}
|
|
25137
|
+
return {
|
|
25138
|
+
parentKey,
|
|
25139
|
+
index,
|
|
25140
|
+
referenceKey,
|
|
25141
|
+
position,
|
|
25142
|
+
depth
|
|
25143
|
+
};
|
|
25144
|
+
}
|
|
25145
|
+
#handleExpandHover(row) {
|
|
25146
|
+
if (!row || row.node.item.isLeaf === true || this.#config.isExpanded(row.key)) {
|
|
25147
|
+
this.#clearExpand();
|
|
25148
|
+
return;
|
|
25149
|
+
}
|
|
25150
|
+
if (row.key === this.#expandPendingKey) return;
|
|
25151
|
+
this.#clearExpand();
|
|
25152
|
+
const key = this.#expandPendingKey = row.key;
|
|
25153
|
+
this.#expandTimer = setTimeout(() => {
|
|
25154
|
+
this.#expandTimer = void 0;
|
|
25155
|
+
if (this.#expandPendingKey === key) {
|
|
25156
|
+
this.#expandPendingKey = void 0;
|
|
25157
|
+
this.#config.expandKey(key);
|
|
25158
|
+
}
|
|
25159
|
+
}, Math.max(0, this.#config.getExpandHoverMs()));
|
|
25160
|
+
}
|
|
25161
|
+
#clearExpand() {
|
|
25162
|
+
if (this.#expandTimer !== void 0) {
|
|
25163
|
+
clearTimeout(this.#expandTimer);
|
|
25164
|
+
this.#expandTimer = void 0;
|
|
25165
|
+
}
|
|
25166
|
+
this.#expandPendingKey = void 0;
|
|
25167
|
+
}
|
|
25168
|
+
#kickScroll() {
|
|
25169
|
+
if (this.#scrollRaf === 0) this.#scrollRaf = requestAnimationFrame(this.#scrollTick);
|
|
25170
|
+
}
|
|
25171
|
+
#scrollTick = () => {
|
|
25172
|
+
this.#scrollRaf = 0;
|
|
25173
|
+
if (!this.#active) return;
|
|
25174
|
+
const container = this.#config.getScrollContainer();
|
|
25175
|
+
if (!container) return;
|
|
25176
|
+
const rect = container.getBoundingClientRect();
|
|
25177
|
+
const y = this.#pointerY - rect.top;
|
|
25178
|
+
let dy = 0;
|
|
25179
|
+
if (y < EDGE_ZONE_PX$1) dy = -Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, y) / EDGE_ZONE_PX$1));
|
|
25180
|
+
else if (y > rect.height - EDGE_ZONE_PX$1) dy = Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, rect.height - y) / EDGE_ZONE_PX$1));
|
|
25181
|
+
if (dy !== 0 && this.#pointerX >= rect.left && this.#pointerX <= rect.right) {
|
|
25182
|
+
container.scrollTop += dy;
|
|
25183
|
+
this.#kickScroll();
|
|
25184
|
+
}
|
|
25185
|
+
};
|
|
25186
|
+
#stopScroll() {
|
|
25187
|
+
if (this.#scrollRaf !== 0) {
|
|
25188
|
+
cancelAnimationFrame(this.#scrollRaf);
|
|
25189
|
+
this.#scrollRaf = 0;
|
|
25190
|
+
}
|
|
25191
|
+
}
|
|
25192
|
+
#setDropState(state) {
|
|
25193
|
+
const unchanged = state === void 0 ? this.#current === void 0 : state.referenceKey === this.#current?.referenceKey && state.position === this.#current?.position && state.depth === this.#current?.depth && state.index === this.#current?.index;
|
|
25194
|
+
this.#current = state;
|
|
25195
|
+
if (!unchanged || this.#active) this.#config.onDropStateChange(state);
|
|
25196
|
+
}
|
|
25197
|
+
};
|
|
25198
|
+
//#endregion
|
|
24555
25199
|
//#region src/tree/tree-base.ts
|
|
24556
25200
|
/** Above this many rows entering / leaving at once, skip the animation entirely. */
|
|
24557
25201
|
const MAX_ANIMATED_ROWS = 50;
|
|
@@ -24564,6 +25208,10 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24564
25208
|
this._selectedNodes = /* @__PURE__ */ new Set();
|
|
24565
25209
|
this.disableKeyboardNavigation = false;
|
|
24566
25210
|
this.registry = void 0;
|
|
25211
|
+
this.itemDnd = `none`;
|
|
25212
|
+
this.dndExpandHoverMs = 500;
|
|
25213
|
+
this.reorderable = true;
|
|
25214
|
+
this.applyInternalDrop = true;
|
|
24567
25215
|
this._expandedKeys = /* @__PURE__ */ new Set();
|
|
24568
25216
|
this.tickled = new TickledController(this, {
|
|
24569
25217
|
getItems: () => {
|
|
@@ -24572,6 +25220,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24572
25220
|
enabled: true
|
|
24573
25221
|
}));
|
|
24574
25222
|
},
|
|
25223
|
+
hoverDisabled: () => this.#drop?.isDragging === true || this.#nativeDrag?.isDragging === true,
|
|
24575
25224
|
onStateChange: () => {
|
|
24576
25225
|
this.setAttribute(`data-input-mode`, this.tickled.inputMode);
|
|
24577
25226
|
}
|
|
@@ -24588,6 +25237,12 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24588
25237
|
this.#leaving = /* @__PURE__ */ new Map();
|
|
24589
25238
|
this.#leavingAnimations = /* @__PURE__ */ new Map();
|
|
24590
25239
|
this.#treeAnimReady = false;
|
|
25240
|
+
this.#dragSourceId = ``;
|
|
25241
|
+
this.#nativeDragKeys = /* @__PURE__ */ new Set();
|
|
25242
|
+
this.#internalDropHandled = false;
|
|
25243
|
+
this.#onContainerScroll = () => {
|
|
25244
|
+
this.#rowsCache = void 0;
|
|
25245
|
+
};
|
|
24591
25246
|
this.#onKeyDown = (event) => {
|
|
24592
25247
|
if (this.search.isOpen) return;
|
|
24593
25248
|
const nodes = this.#getAllNodes();
|
|
@@ -24741,6 +25396,28 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24741
25396
|
#leaving;
|
|
24742
25397
|
#leavingAnimations;
|
|
24743
25398
|
#treeAnimReady;
|
|
25399
|
+
#dragSourceId;
|
|
25400
|
+
#postDragSuppressTimer;
|
|
25401
|
+
#dropState;
|
|
25402
|
+
#drop;
|
|
25403
|
+
#nativeDrag;
|
|
25404
|
+
/** Keys of the nodes currently being dragged out (for `.dragging` styling). */
|
|
25405
|
+
#nativeDragKeys;
|
|
25406
|
+
/** Set by `commitDrop` for a same-tree internal drop, read by the native `onEnd` to avoid a duplicate `tree-drag-end`. */
|
|
25407
|
+
#internalDropHandled;
|
|
25408
|
+
/** Per-drag cache of measured rows; invalidated on scroll / update. */
|
|
25409
|
+
#rowsCache;
|
|
25410
|
+
#onContainerScroll;
|
|
25411
|
+
get nativeDrag() {
|
|
25412
|
+
return this.#nativeDrag;
|
|
25413
|
+
}
|
|
25414
|
+
get dropState() {
|
|
25415
|
+
return this.#dropState;
|
|
25416
|
+
}
|
|
25417
|
+
/** Keys of the nodes currently being dragged out of this tree. */
|
|
25418
|
+
get nativeDragKeys() {
|
|
25419
|
+
return this.#nativeDragKeys;
|
|
25420
|
+
}
|
|
24744
25421
|
#cancelLeavingAnimation(key) {
|
|
24745
25422
|
this.#leavingAnimations.get(key)?.cancel();
|
|
24746
25423
|
this.#leavingAnimations.delete(key);
|
|
@@ -24852,6 +25529,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24852
25529
|
this.#treeAnimReady = true;
|
|
24853
25530
|
}
|
|
24854
25531
|
updated(changedProps) {
|
|
25532
|
+
this.#rowsCache = void 0;
|
|
24855
25533
|
if (changedProps.has(`root`) && this.root) {
|
|
24856
25534
|
this.#abortPending();
|
|
24857
25535
|
this._expandedKeys.clear();
|
|
@@ -24908,6 +25586,291 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24908
25586
|
});
|
|
24909
25587
|
this.registry = registry;
|
|
24910
25588
|
this.#syncSearchCommands();
|
|
25589
|
+
this.#initDnd();
|
|
25590
|
+
}
|
|
25591
|
+
#initDnd() {
|
|
25592
|
+
this.#dragSourceId = treeDragGenerateSourceId();
|
|
25593
|
+
this.#nativeDrag = new ListNativeDragController(this, {
|
|
25594
|
+
source: `tree-list`,
|
|
25595
|
+
isEnabled: () => this.itemDnd !== `none` && this.#anyRowDraggable(),
|
|
25596
|
+
resolveEventToKey: (target) => {
|
|
25597
|
+
if (!(target instanceof Element)) return void 0;
|
|
25598
|
+
return target.closest(`li[data-key]`)?.getAttribute(`data-key`) ?? void 0;
|
|
25599
|
+
},
|
|
25600
|
+
prepareSelection: (originKey) => {
|
|
25601
|
+
const allNodes = this.#getAllNodes();
|
|
25602
|
+
const originEntry = allNodes.find((n) => n.node.item.key === originKey);
|
|
25603
|
+
if (!originEntry) return void 0;
|
|
25604
|
+
const selectedNodes = new Set(this._selectedNodes);
|
|
25605
|
+
if (!selectedNodes.has(originEntry.node)) selectedNodes.clear();
|
|
25606
|
+
selectedNodes.add(originEntry.node);
|
|
25607
|
+
const orderedKeys = allNodes.filter((n) => selectedNodes.has(n.node)).map((n) => n.node.item.key);
|
|
25608
|
+
const topKeys = new Set(this.root ? pruneDraggedDescendants(this.root, orderedKeys) : orderedKeys);
|
|
25609
|
+
const selected = allNodes.filter((n) => topKeys.has(n.node.item.key)).map((n, i) => ({
|
|
25610
|
+
key: n.node.item.key,
|
|
25611
|
+
index: i,
|
|
25612
|
+
item: n.node,
|
|
25613
|
+
element: this.shadowRoot?.querySelector(`li[data-key="${CSS.escape(n.node.item.key)}"]`) ?? void 0
|
|
25614
|
+
}));
|
|
25615
|
+
const origin = selected.find((e) => e.key === originKey) ?? {
|
|
25616
|
+
key: originKey,
|
|
25617
|
+
index: 0,
|
|
25618
|
+
item: originEntry.node,
|
|
25619
|
+
element: void 0
|
|
25620
|
+
};
|
|
25621
|
+
if (!selected.some((e) => e.key === origin.key)) selected.unshift(origin);
|
|
25622
|
+
return {
|
|
25623
|
+
origin,
|
|
25624
|
+
selected
|
|
25625
|
+
};
|
|
25626
|
+
},
|
|
25627
|
+
getMetrics: () => ({ rowHeight: this.#getItemHeight() }),
|
|
25628
|
+
getRenderer: () => this.dragPreviewRenderer,
|
|
25629
|
+
dispatch: (detail) => {
|
|
25630
|
+
const keys = detail.selected.map((e) => e.key);
|
|
25631
|
+
const nodes = detail.selected.map((e) => e.item);
|
|
25632
|
+
const evt = new CustomEvent(`list-native-drag-start`, {
|
|
25633
|
+
detail,
|
|
25634
|
+
bubbles: true,
|
|
25635
|
+
composed: true,
|
|
25636
|
+
cancelable: true
|
|
25637
|
+
});
|
|
25638
|
+
const notCancelled = this.dispatchEvent(evt);
|
|
25639
|
+
if (notCancelled) {
|
|
25640
|
+
this.#nativeDragKeys = new Set(keys);
|
|
25641
|
+
this.#internalDropHandled = false;
|
|
25642
|
+
if (this.itemDnd === `internal` || this.itemDnd === `both`) treeDragRegister(this.#dragSourceId, this, nodes, keys);
|
|
25643
|
+
this.dispatchEvent(new CustomEvent(`tree-drag-start`, {
|
|
25644
|
+
detail: {
|
|
25645
|
+
nodes,
|
|
25646
|
+
keys
|
|
25647
|
+
},
|
|
25648
|
+
bubbles: true,
|
|
25649
|
+
composed: true
|
|
25650
|
+
}));
|
|
25651
|
+
}
|
|
25652
|
+
return notCancelled;
|
|
25653
|
+
},
|
|
25654
|
+
writeDataTransfer: (dataTransfer, detail) => {
|
|
25655
|
+
if (this.itemDnd !== `internal` && this.itemDnd !== `both`) return;
|
|
25656
|
+
const keys = detail.selected.map((e) => e.key);
|
|
25657
|
+
const nodes = detail.selected.map((e) => e.item);
|
|
25658
|
+
try {
|
|
25659
|
+
dataTransfer.setData(TREE_DRAG_MIME, JSON.stringify({
|
|
25660
|
+
sourceId: this.#dragSourceId,
|
|
25661
|
+
keys,
|
|
25662
|
+
nodes
|
|
25663
|
+
}));
|
|
25664
|
+
dataTransfer.setData(`text/plain`, nodes.map((n) => n.item.label).join(`\n`));
|
|
25665
|
+
} catch {}
|
|
25666
|
+
},
|
|
25667
|
+
onActiveChange: (active) => {
|
|
25668
|
+
this.toggleAttribute(`data-native-dragging`, active);
|
|
25669
|
+
if (!active) this.#nativeDragKeys = /* @__PURE__ */ new Set();
|
|
25670
|
+
this.requestUpdate();
|
|
25671
|
+
},
|
|
25672
|
+
onEnd: () => {
|
|
25673
|
+
treeDragUnregister(this.#dragSourceId);
|
|
25674
|
+
this.#nativeDragKeys = /* @__PURE__ */ new Set();
|
|
25675
|
+
this.#postDragSuppressTimer = setTimeout(() => {
|
|
25676
|
+
this.#postDragSuppressTimer = void 0;
|
|
25677
|
+
}, 150);
|
|
25678
|
+
if (!this.#internalDropHandled) this.dispatchEvent(new CustomEvent(`tree-drag-end`, {
|
|
25679
|
+
detail: { dropped: false },
|
|
25680
|
+
bubbles: true,
|
|
25681
|
+
composed: true
|
|
25682
|
+
}));
|
|
25683
|
+
this.#internalDropHandled = false;
|
|
25684
|
+
}
|
|
25685
|
+
});
|
|
25686
|
+
this.#drop = new TreeDropController(this, {
|
|
25687
|
+
getDndMode: () => this.itemDnd,
|
|
25688
|
+
getExpandHoverMs: () => this.dndExpandHoverMs,
|
|
25689
|
+
getVisibleRows: () => this.#getVisibleRows(),
|
|
25690
|
+
getIndentPx: () => this.#getIndentPx(),
|
|
25691
|
+
getScrollContainer: () => this.#container(),
|
|
25692
|
+
isSelfOrDescendant: (ancestorKey, key) => this.#isSelfOrDescendant(ancestorKey, key),
|
|
25693
|
+
isExpanded: (key) => this._expandedKeys.has(key),
|
|
25694
|
+
isReorderAllowed: () => this.reorderable,
|
|
25695
|
+
getParentKey: (key) => this.#findParentByKey(key)?.item.key,
|
|
25696
|
+
resolveDrag: (dataTransfer, phase) => this.#resolveDrag(dataTransfer, phase),
|
|
25697
|
+
vet: (ctx) => {
|
|
25698
|
+
if (this.canDrop && !this.canDrop(ctx)) return false;
|
|
25699
|
+
const evt = new CustomEvent(`tree-drag-over`, {
|
|
25700
|
+
detail: ctx,
|
|
25701
|
+
bubbles: true,
|
|
25702
|
+
composed: true,
|
|
25703
|
+
cancelable: true
|
|
25704
|
+
});
|
|
25705
|
+
return this.dispatchEvent(evt);
|
|
25706
|
+
},
|
|
25707
|
+
expandKey: (key) => this.#springLoadExpand(key),
|
|
25708
|
+
onDropStateChange: (state) => {
|
|
25709
|
+
this.#dropState = state;
|
|
25710
|
+
this.toggleAttribute(`data-drop-rejected`, this.#drop.isDragging && state === void 0);
|
|
25711
|
+
this.requestUpdate();
|
|
25712
|
+
},
|
|
25713
|
+
onActiveChange: (active) => {
|
|
25714
|
+
if (active) {
|
|
25715
|
+
this.#rowsCache = void 0;
|
|
25716
|
+
this.#container()?.addEventListener(`scroll`, this.#onContainerScroll, { passive: true });
|
|
25717
|
+
} else {
|
|
25718
|
+
this.#container()?.removeEventListener(`scroll`, this.#onContainerScroll);
|
|
25719
|
+
this.#rowsCache = void 0;
|
|
25720
|
+
this.toggleAttribute(`data-drop-rejected`, false);
|
|
25721
|
+
}
|
|
25722
|
+
this.requestUpdate();
|
|
25723
|
+
},
|
|
25724
|
+
commitDrop: (detail) => {
|
|
25725
|
+
if (!this.dispatchEvent(new CustomEvent(`tree-drop`, {
|
|
25726
|
+
detail,
|
|
25727
|
+
bubbles: true,
|
|
25728
|
+
composed: true,
|
|
25729
|
+
cancelable: true
|
|
25730
|
+
}))) return false;
|
|
25731
|
+
if (this.applyInternalDrop && detail.source === `internal` && this.model) this.model.applyDrop({
|
|
25732
|
+
source: `internal`,
|
|
25733
|
+
draggedKeys: detail.draggedKeys,
|
|
25734
|
+
target: detail.target
|
|
25735
|
+
});
|
|
25736
|
+
this.#internalDropHandled = true;
|
|
25737
|
+
return true;
|
|
25738
|
+
},
|
|
25739
|
+
onDragEnd: (dropped) => {
|
|
25740
|
+
this.#dropState = void 0;
|
|
25741
|
+
this.toggleAttribute(`data-drop-rejected`, false);
|
|
25742
|
+
this.requestUpdate();
|
|
25743
|
+
this.dispatchEvent(new CustomEvent(`tree-drag-end`, {
|
|
25744
|
+
detail: { dropped },
|
|
25745
|
+
bubbles: true,
|
|
25746
|
+
composed: true
|
|
25747
|
+
}));
|
|
25748
|
+
}
|
|
25749
|
+
});
|
|
25750
|
+
}
|
|
25751
|
+
#container() {
|
|
25752
|
+
return this.shadowRoot?.querySelector(`#container`) ?? void 0;
|
|
25753
|
+
}
|
|
25754
|
+
#getIndentPx() {
|
|
25755
|
+
const parsed = Number.parseInt(getComputedStyle(this).getPropertyValue(`--tree-indent`), 10);
|
|
25756
|
+
return Number.isNaN(parsed) ? 20 : parsed;
|
|
25757
|
+
}
|
|
25758
|
+
#getItemHeight() {
|
|
25759
|
+
const parsed = Number.parseInt(getComputedStyle(this).getPropertyValue(`--tree-item-height`), 10);
|
|
25760
|
+
return Number.isNaN(parsed) ? 30 : parsed;
|
|
25761
|
+
}
|
|
25762
|
+
/** Measured rows, cached for the duration of a drag and invalidated on scroll / update. */
|
|
25763
|
+
#getVisibleRows() {
|
|
25764
|
+
if (this.#rowsCache) return this.#rowsCache;
|
|
25765
|
+
const rows = [];
|
|
25766
|
+
for (const { node, depth } of this.#getAllNodes()) {
|
|
25767
|
+
const li = this.shadowRoot?.querySelector(`li[data-key="${CSS.escape(node.item.key)}"]`);
|
|
25768
|
+
if (li) rows.push({
|
|
25769
|
+
key: node.item.key,
|
|
25770
|
+
node,
|
|
25771
|
+
depth,
|
|
25772
|
+
rect: li.getBoundingClientRect()
|
|
25773
|
+
});
|
|
25774
|
+
}
|
|
25775
|
+
this.#rowsCache = rows;
|
|
25776
|
+
return rows;
|
|
25777
|
+
}
|
|
25778
|
+
/** Route spring-load through the real expand path so lazy children load and `expand` fires with the right depth. */
|
|
25779
|
+
#springLoadExpand(key) {
|
|
25780
|
+
if (this._expandedKeys.has(key)) return;
|
|
25781
|
+
const entry = this.#getAllNodes().find((n) => n.node.item.key === key);
|
|
25782
|
+
if (!entry || entry.node.item.isLeaf === true) return;
|
|
25783
|
+
this.#toggleExpand(entry.node, entry.depth);
|
|
25784
|
+
this.#rowsCache = void 0;
|
|
25785
|
+
this.requestUpdate();
|
|
25786
|
+
}
|
|
25787
|
+
#isSelfOrDescendant(ancestorKey, key) {
|
|
25788
|
+
if (ancestorKey === key) return true;
|
|
25789
|
+
let node = this.#getAllNodes().find((n) => n.node.item.key === key)?.node;
|
|
25790
|
+
let parent = node ? this.#findParentByKey(node.item.key) : void 0;
|
|
25791
|
+
while (parent) {
|
|
25792
|
+
if (parent.item.key === ancestorKey) return true;
|
|
25793
|
+
node = parent;
|
|
25794
|
+
parent = this.#findParentByKey(node.item.key);
|
|
25795
|
+
}
|
|
25796
|
+
return false;
|
|
25797
|
+
}
|
|
25798
|
+
#findParentByKey(key) {
|
|
25799
|
+
for (const { node } of this.#getAllNodes()) if (node.children?.some((c) => c.item.key === key)) return node;
|
|
25800
|
+
}
|
|
25801
|
+
/**
|
|
25802
|
+
* Decide whether a DataTransfer is acceptable and resolve the dragged set.
|
|
25803
|
+
* During `hover` the DataTransfer is read-protected, so an internal drag is
|
|
25804
|
+
* recovered from the module-level drag registry (there is only one at a time).
|
|
25805
|
+
*/
|
|
25806
|
+
#resolveDrag(dataTransfer, phase) {
|
|
25807
|
+
const mode = this.itemDnd;
|
|
25808
|
+
if (mode === `none`) return void 0;
|
|
25809
|
+
const canInternal = mode === `internal` || mode === `both`;
|
|
25810
|
+
const canExternal = mode === `external` || mode === `both`;
|
|
25811
|
+
let types = [];
|
|
25812
|
+
try {
|
|
25813
|
+
types = Array.from(dataTransfer.types);
|
|
25814
|
+
} catch {}
|
|
25815
|
+
const current = treeDragCurrent();
|
|
25816
|
+
const looksInternal = types.includes(TREE_DRAG_MIME) || current !== void 0;
|
|
25817
|
+
if (canInternal && looksInternal) {
|
|
25818
|
+
if (current && current.keys.length > 0) {
|
|
25819
|
+
const keys = this.root ? pruneDraggedDescendants(this.root, current.keys) : current.keys;
|
|
25820
|
+
return {
|
|
25821
|
+
source: `internal`,
|
|
25822
|
+
keys,
|
|
25823
|
+
nodes: keys.map((k) => this.#getAllNodes().find((n) => n.node.item.key === k)?.node).filter((n) => n !== void 0)
|
|
25824
|
+
};
|
|
25825
|
+
}
|
|
25826
|
+
if (phase === `drop`) try {
|
|
25827
|
+
const raw = dataTransfer.getData(TREE_DRAG_MIME);
|
|
25828
|
+
if (raw) {
|
|
25829
|
+
const payload = JSON.parse(raw);
|
|
25830
|
+
return {
|
|
25831
|
+
source: `internal`,
|
|
25832
|
+
keys: payload.keys ?? [],
|
|
25833
|
+
nodes: payload.nodes ?? []
|
|
25834
|
+
};
|
|
25835
|
+
}
|
|
25836
|
+
} catch {}
|
|
25837
|
+
return {
|
|
25838
|
+
source: `internal`,
|
|
25839
|
+
keys: [],
|
|
25840
|
+
nodes: []
|
|
25841
|
+
};
|
|
25842
|
+
}
|
|
25843
|
+
if (canExternal && !looksInternal) {
|
|
25844
|
+
if (this.acceptDropTypes !== void 0) {
|
|
25845
|
+
const accepted = this.acceptDropTypes.trim().split(/\s+/).filter(Boolean);
|
|
25846
|
+
const present = Array.from(dataTransfer.types);
|
|
25847
|
+
if (accepted.length > 0 && !accepted.some((t) => present.includes(t))) return void 0;
|
|
25848
|
+
}
|
|
25849
|
+
if (phase === `drop`) {
|
|
25850
|
+
const nodes = this.parseExternalDrop?.(dataTransfer);
|
|
25851
|
+
if (!nodes || nodes.length === 0) return void 0;
|
|
25852
|
+
return {
|
|
25853
|
+
source: `external`,
|
|
25854
|
+
keys: nodes.map((n) => n.item.key),
|
|
25855
|
+
nodes
|
|
25856
|
+
};
|
|
25857
|
+
}
|
|
25858
|
+
return this.parseExternalDrop ? {
|
|
25859
|
+
source: `external`,
|
|
25860
|
+
keys: [],
|
|
25861
|
+
nodes: []
|
|
25862
|
+
} : void 0;
|
|
25863
|
+
}
|
|
25864
|
+
}
|
|
25865
|
+
#anyRowDraggable() {
|
|
25866
|
+
if (this.itemDnd === `none`) return false;
|
|
25867
|
+
const allNodes = this.#getAllNodes();
|
|
25868
|
+
if (allNodes.length === 0) return false;
|
|
25869
|
+
if (!this.canDrag) return true;
|
|
25870
|
+
return allNodes.some(({ node }) => this.canDrag({
|
|
25871
|
+
nodes: [node],
|
|
25872
|
+
keys: [node.item.key]
|
|
25873
|
+
}));
|
|
24911
25874
|
}
|
|
24912
25875
|
disconnectedCallback() {
|
|
24913
25876
|
super.disconnectedCallback();
|
|
@@ -24918,6 +25881,12 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24918
25881
|
this.#modelUnsubscribe = void 0;
|
|
24919
25882
|
this.#unregisterSearchCommands?.();
|
|
24920
25883
|
this.#unregisterSearchCommands = void 0;
|
|
25884
|
+
if (this.#postDragSuppressTimer !== void 0) {
|
|
25885
|
+
clearTimeout(this.#postDragSuppressTimer);
|
|
25886
|
+
this.#postDragSuppressTimer = void 0;
|
|
25887
|
+
}
|
|
25888
|
+
this.#container()?.removeEventListener(`scroll`, this.#onContainerScroll);
|
|
25889
|
+
treeDragUnregister(this.#dragSourceId);
|
|
24921
25890
|
if (this.#ownedRegistry) {
|
|
24922
25891
|
this.#ownedRegistry.unregister(`select-all`);
|
|
24923
25892
|
this.#ownedRegistry.unregister(`deselect-all`);
|
|
@@ -25092,6 +26061,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
25092
26061
|
`;
|
|
25093
26062
|
}
|
|
25094
26063
|
_handleItemClick(node, depth, event) {
|
|
26064
|
+
if (this.#drop?.isDragging || this.#nativeDrag?.isDragging || this.#postDragSuppressTimer !== void 0) return;
|
|
25095
26065
|
if (event && event.detail >= 2) return;
|
|
25096
26066
|
if (this.#pendingNode && this._expandedKeys.has(this.#pendingNode.item.key)) this.#abortPending();
|
|
25097
26067
|
this.tickled.handlePointerEnter(node.item.key);
|
|
@@ -25526,6 +26496,23 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
25526
26496
|
</ul>
|
|
25527
26497
|
`;
|
|
25528
26498
|
}
|
|
26499
|
+
/** Shared drag-and-drop render state for a row, used by every `_renderNode` variant. */
|
|
26500
|
+
_dndRowState(node) {
|
|
26501
|
+
const draggable = this.itemDnd !== `none` && (this.root?.children?.length ?? 0) > 0 && (this.itemDnd === `internal` || this.itemDnd === `both` || this.itemDnd === `external`) && (this.canDrag?.({
|
|
26502
|
+
nodes: [node],
|
|
26503
|
+
keys: [node.item.key]
|
|
26504
|
+
}) ?? true);
|
|
26505
|
+
const dragging = this.#nativeDragKeys.has(node.item.key);
|
|
26506
|
+
const state = this.#dropState;
|
|
26507
|
+
const dropTarget = state !== void 0 && state.referenceKey === node.item.key;
|
|
26508
|
+
return {
|
|
26509
|
+
draggable,
|
|
26510
|
+
dragging,
|
|
26511
|
+
dropTarget,
|
|
26512
|
+
dropPosition: dropTarget ? state.position : void 0,
|
|
26513
|
+
dropDepth: dropTarget ? state.depth : void 0
|
|
26514
|
+
};
|
|
26515
|
+
}
|
|
25529
26516
|
_renderNode(node, depth) {
|
|
25530
26517
|
const selected = this._isSelected(node);
|
|
25531
26518
|
const tickled = this._isFocused(node);
|
|
@@ -25534,9 +26521,10 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
25534
26521
|
const isPending = this.#pendingNode === node;
|
|
25535
26522
|
const isFiltered = this._isFilteredOut(node, depth);
|
|
25536
26523
|
const isLeaving = this._isLeaving(node);
|
|
26524
|
+
const dnd = this._dndRowState(node);
|
|
25537
26525
|
return b`
|
|
25538
26526
|
<li
|
|
25539
|
-
class="item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${isFiltered ? `filtered` : ``} ${isLeaving ? `leaving` : ``}"
|
|
26527
|
+
class="item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${isFiltered ? `filtered` : ``} ${isLeaving ? `leaving` : ``} ${dnd.dragging ? `dragging` : ``} ${dnd.dropTarget && dnd.dropPosition === `inside` ? `drop-into` : ``}"
|
|
25540
26528
|
role="treeitem"
|
|
25541
26529
|
aria-selected=${selected}
|
|
25542
26530
|
aria-expanded=${isBranch ? isExpanded : A}
|
|
@@ -25544,6 +26532,8 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
25544
26532
|
aria-level=${depth + 1}
|
|
25545
26533
|
data-key=${node.item.key}
|
|
25546
26534
|
style=${`--depth: ${depth}`}
|
|
26535
|
+
draggable=${dnd.draggable ? `true` : A}
|
|
26536
|
+
part=${dnd.dropTarget ? `drop-target` : A}
|
|
25547
26537
|
@click=${(e) => this._handleItemClick(node, depth, e)}
|
|
25548
26538
|
@pointerenter=${() => {
|
|
25549
26539
|
this.tickled.handlePointerEnter(node.item.key);
|
|
@@ -25557,6 +26547,11 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
25557
26547
|
}));
|
|
25558
26548
|
}}
|
|
25559
26549
|
>
|
|
26550
|
+
${dnd.dropTarget && (dnd.dropPosition === `before` || dnd.dropPosition === `after`) ? b`<div
|
|
26551
|
+
class="drop-line drop-line-${dnd.dropPosition}"
|
|
26552
|
+
style="--drop-depth: ${dnd.dropDepth ?? depth}"
|
|
26553
|
+
part="drop-indicator"
|
|
26554
|
+
></div>` : A}
|
|
25560
26555
|
${this.renderNodeContent(node, depth)}
|
|
25561
26556
|
${isPending ? this.renderLoadingIndicator() : A}
|
|
25562
26557
|
</li>
|
|
@@ -25577,6 +26572,10 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
25577
26572
|
--tree-item-height: 30px;
|
|
25578
26573
|
--tree-caret-size: 30px;
|
|
25579
26574
|
--tree-radius: var(--radius-s);
|
|
26575
|
+
--tree-drop-line: var(--accent);
|
|
26576
|
+
--tree-drop-nub-size: 5px;
|
|
26577
|
+
--tree-drop-into-outline: 2px solid var(--accent);
|
|
26578
|
+
--tree-drop-into-bg: color-mix(in srgb, var(--accent) 14%, transparent);
|
|
25580
26579
|
|
|
25581
26580
|
position: relative;
|
|
25582
26581
|
display: block;
|
|
@@ -25604,6 +26603,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
25604
26603
|
}
|
|
25605
26604
|
|
|
25606
26605
|
.item {
|
|
26606
|
+
position: relative; /* anchor for the .drop-line before/after indicator */
|
|
25607
26607
|
display: flex;
|
|
25608
26608
|
align-items: center;
|
|
25609
26609
|
height: var(--tree-item-height);
|
|
@@ -25679,11 +26679,49 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
25679
26679
|
overflow: hidden;
|
|
25680
26680
|
}
|
|
25681
26681
|
|
|
25682
|
-
|
|
25683
|
-
|
|
25684
|
-
|
|
25685
|
-
|
|
25686
|
-
|
|
26682
|
+
/* Drag and drop styles */
|
|
26683
|
+
.item.dragging {
|
|
26684
|
+
opacity: 0.4;
|
|
26685
|
+
}
|
|
26686
|
+
|
|
26687
|
+
.item.drop-into {
|
|
26688
|
+
outline: var(--tree-drop-into-outline);
|
|
26689
|
+
outline-offset: -2px;
|
|
26690
|
+
background: var(--tree-drop-into-bg);
|
|
26691
|
+
}
|
|
26692
|
+
|
|
26693
|
+
.drop-line {
|
|
26694
|
+
position: absolute;
|
|
26695
|
+
left: calc(var(--tree-indent) * var(--drop-depth, 0) + var(--space-xs));
|
|
26696
|
+
right: var(--space-xs);
|
|
26697
|
+
height: 2px;
|
|
26698
|
+
background: var(--tree-drop-line);
|
|
26699
|
+
pointer-events: none;
|
|
26700
|
+
z-index: 10;
|
|
26701
|
+
}
|
|
26702
|
+
|
|
26703
|
+
/* Nub at the left end of the insertion line (VS Code style). */
|
|
26704
|
+
.drop-line::before {
|
|
26705
|
+
content: "";
|
|
26706
|
+
position: absolute;
|
|
26707
|
+
left: calc(-1 * var(--tree-drop-nub-size) / 2);
|
|
26708
|
+
top: calc(50% - var(--tree-drop-nub-size) / 2);
|
|
26709
|
+
width: var(--tree-drop-nub-size);
|
|
26710
|
+
height: var(--tree-drop-nub-size);
|
|
26711
|
+
border-radius: 50%;
|
|
26712
|
+
background: var(--tree-drop-line);
|
|
26713
|
+
}
|
|
26714
|
+
|
|
26715
|
+
.drop-line-before {
|
|
26716
|
+
top: -1px;
|
|
26717
|
+
}
|
|
26718
|
+
|
|
26719
|
+
.drop-line-after {
|
|
26720
|
+
bottom: -1px;
|
|
26721
|
+
}
|
|
26722
|
+
|
|
26723
|
+
:host([data-drop-rejected]) {
|
|
26724
|
+
cursor: not-allowed;
|
|
25687
26725
|
}
|
|
25688
26726
|
`
|
|
25689
26727
|
];
|
|
@@ -25717,6 +26755,31 @@ __decorate([property({
|
|
|
25717
26755
|
attribute: `search-modes`,
|
|
25718
26756
|
reflect: true
|
|
25719
26757
|
})], TreeBaseElement.prototype, "searchModes", void 0);
|
|
26758
|
+
__decorate([property({
|
|
26759
|
+
reflect: true,
|
|
26760
|
+
attribute: `item-dnd`
|
|
26761
|
+
})], TreeBaseElement.prototype, "itemDnd", void 0);
|
|
26762
|
+
__decorate([property({
|
|
26763
|
+
type: String,
|
|
26764
|
+
attribute: `accept-drop-types`
|
|
26765
|
+
})], TreeBaseElement.prototype, "acceptDropTypes", void 0);
|
|
26766
|
+
__decorate([property({
|
|
26767
|
+
type: Number,
|
|
26768
|
+
attribute: `dnd-expand-hover-ms`
|
|
26769
|
+
})], TreeBaseElement.prototype, "dndExpandHoverMs", void 0);
|
|
26770
|
+
__decorate([property({
|
|
26771
|
+
reflect: true,
|
|
26772
|
+
attribute: `reorderable`,
|
|
26773
|
+
converter: {
|
|
26774
|
+
fromAttribute: (value) => value !== `false`,
|
|
26775
|
+
toAttribute: (value) => value ? null : `false`
|
|
26776
|
+
}
|
|
26777
|
+
})], TreeBaseElement.prototype, "reorderable", void 0);
|
|
26778
|
+
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "dragPreviewRenderer", void 0);
|
|
26779
|
+
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "canDrag", void 0);
|
|
26780
|
+
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "canDrop", void 0);
|
|
26781
|
+
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "parseExternalDrop", void 0);
|
|
26782
|
+
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "applyInternalDrop", void 0);
|
|
25720
26783
|
__decorate([state()], TreeBaseElement.prototype, "_expandedKeys", void 0);
|
|
25721
26784
|
__decorate([state()], TreeBaseElement.prototype, "_focusedDepth", void 0);
|
|
25722
26785
|
TreeBaseElement = __decorate([safeCustomElement(`ixfx-tree-base`)], TreeBaseElement);
|
|
@@ -25798,9 +26861,10 @@ let TreeListElement = class TreeListElement extends TreeBaseElement {
|
|
|
25798
26861
|
const hasIconAtDepth = this.#depthsWithIcons.has(depth);
|
|
25799
26862
|
const isLeaving = this._isLeaving(node);
|
|
25800
26863
|
const isFiltered = this._isFilteredOut(node, depth);
|
|
26864
|
+
const dnd = this._dndRowState(node);
|
|
25801
26865
|
return b`
|
|
25802
26866
|
<li
|
|
25803
|
-
class="item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${hasIconAtDepth ? `has-icon-at-depth` : ``} ${isLeaving ? `leaving` : ``} ${isFiltered ? `filtered` : ``}"
|
|
26867
|
+
class="item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${hasIconAtDepth ? `has-icon-at-depth` : ``} ${isLeaving ? `leaving` : ``} ${isFiltered ? `filtered` : ``} ${dnd.dragging ? `dragging` : ``} ${dnd.dropTarget && dnd.dropPosition === `inside` ? `drop-into` : ``}"
|
|
25804
26868
|
data-key=${node.item.key}
|
|
25805
26869
|
role="treeitem"
|
|
25806
26870
|
aria-selected=${selected}
|
|
@@ -25808,9 +26872,16 @@ let TreeListElement = class TreeListElement extends TreeBaseElement {
|
|
|
25808
26872
|
aria-hidden=${isLeaving ? `true` : A}
|
|
25809
26873
|
aria-level=${depth + 1}
|
|
25810
26874
|
style=${`--depth: ${depth}`}
|
|
26875
|
+
draggable=${dnd.draggable ? `true` : A}
|
|
26876
|
+
part=${dnd.dropTarget ? `drop-target` : A}
|
|
25811
26877
|
@click=${(e) => this._handleItemClick(node, depth, e)}
|
|
25812
26878
|
@pointerenter=${() => this.tickled.handlePointerEnter(node.item.key)}
|
|
25813
26879
|
>
|
|
26880
|
+
${dnd.dropTarget && (dnd.dropPosition === `before` || dnd.dropPosition === `after`) ? b`<div
|
|
26881
|
+
class="drop-line drop-line-${dnd.dropPosition}"
|
|
26882
|
+
style="--drop-depth: ${dnd.dropDepth ?? depth}"
|
|
26883
|
+
part="drop-indicator"
|
|
26884
|
+
></div>` : A}
|
|
25814
26885
|
${this.renderNodeContent(node, depth)}
|
|
25815
26886
|
${isPending ? this.renderLoadingIndicator() : A}
|
|
25816
26887
|
</li>
|
|
@@ -29348,6 +30419,77 @@ function valueToRelative(value, min, max) {
|
|
|
29348
30419
|
const HANDLE_HIT_RADIUS = .06;
|
|
29349
30420
|
const DEFAULT_VALUE_MIN_FRACTION = .01;
|
|
29350
30421
|
const CHANGE_DEBOUNCE_MS = 150;
|
|
30422
|
+
/**
|
|
30423
|
+
* Evaluate a simple arithmetic expression (decimal numbers, `+ - * /` and
|
|
30424
|
+
* parentheses). Returns `undefined` when the string contains anything else.
|
|
30425
|
+
* Used for CSS `calc()`-derived values — a safe substitute for `new Function`.
|
|
30426
|
+
*/
|
|
30427
|
+
function evaluateArithmetic(source) {
|
|
30428
|
+
let pos = 0;
|
|
30429
|
+
const skipSpaces = () => {
|
|
30430
|
+
while (pos < source.length) {
|
|
30431
|
+
const c = source[pos];
|
|
30432
|
+
if (c !== ` ` && c !== `\t` && c !== `\n` && c !== `\r`) break;
|
|
30433
|
+
pos++;
|
|
30434
|
+
}
|
|
30435
|
+
};
|
|
30436
|
+
function parseNumber() {
|
|
30437
|
+
skipSpaces();
|
|
30438
|
+
const match = /^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/i.exec(source.slice(pos));
|
|
30439
|
+
if (!match) return void 0;
|
|
30440
|
+
pos += match[0].length;
|
|
30441
|
+
return Number.parseFloat(match[0]);
|
|
30442
|
+
}
|
|
30443
|
+
function parseFactor() {
|
|
30444
|
+
skipSpaces();
|
|
30445
|
+
const c = source[pos];
|
|
30446
|
+
if (c === `+` || c === `-`) {
|
|
30447
|
+
pos++;
|
|
30448
|
+
const value = parseFactor();
|
|
30449
|
+
return value === void 0 ? void 0 : c === `-` ? -value : value;
|
|
30450
|
+
}
|
|
30451
|
+
if (c === `(`) {
|
|
30452
|
+
pos++;
|
|
30453
|
+
const value = parseSum();
|
|
30454
|
+
if (value === void 0) return void 0;
|
|
30455
|
+
skipSpaces();
|
|
30456
|
+
if (source[pos] !== `)`) return void 0;
|
|
30457
|
+
pos++;
|
|
30458
|
+
return value;
|
|
30459
|
+
}
|
|
30460
|
+
return parseNumber();
|
|
30461
|
+
}
|
|
30462
|
+
function parseProduct() {
|
|
30463
|
+
let value = parseFactor();
|
|
30464
|
+
if (value === void 0) return void 0;
|
|
30465
|
+
while (true) {
|
|
30466
|
+
skipSpaces();
|
|
30467
|
+
const op = source[pos];
|
|
30468
|
+
if (op !== `*` && op !== `/`) return value;
|
|
30469
|
+
pos++;
|
|
30470
|
+
const rhs = parseFactor();
|
|
30471
|
+
if (rhs === void 0) return void 0;
|
|
30472
|
+
value = op === `*` ? value * rhs : value / rhs;
|
|
30473
|
+
}
|
|
30474
|
+
}
|
|
30475
|
+
function parseSum() {
|
|
30476
|
+
let value = parseProduct();
|
|
30477
|
+
if (value === void 0) return void 0;
|
|
30478
|
+
while (true) {
|
|
30479
|
+
skipSpaces();
|
|
30480
|
+
const op = source[pos];
|
|
30481
|
+
if (op !== `+` && op !== `-`) return value;
|
|
30482
|
+
pos++;
|
|
30483
|
+
const rhs = parseProduct();
|
|
30484
|
+
if (rhs === void 0) return void 0;
|
|
30485
|
+
value = op === `+` ? value + rhs : value - rhs;
|
|
30486
|
+
}
|
|
30487
|
+
}
|
|
30488
|
+
const value = parseSum();
|
|
30489
|
+
if (value === void 0) return void 0;
|
|
30490
|
+
skipSpaces();
|
|
30491
|
+
return pos === source.length ? value : void 0;
|
|
30492
|
+
}
|
|
29351
30493
|
let SliderInputElement = class SliderInputElement extends WheelNudgeMixin(i) {
|
|
29352
30494
|
#lanes;
|
|
29353
30495
|
/** Raw pole values: independent of which is "low" or "high". */
|
|
@@ -30261,14 +31403,10 @@ let SliderInputElement = class SliderInputElement extends WheelNudgeMixin(i) {
|
|
|
30261
31403
|
const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));
|
|
30262
31404
|
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
30263
31405
|
}
|
|
30264
|
-
const
|
|
30265
|
-
|
|
30266
|
-
|
|
30267
|
-
|
|
30268
|
-
} catch {
|
|
30269
|
-
const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));
|
|
30270
|
-
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
30271
|
-
}
|
|
31406
|
+
const result = evaluateArithmetic(val.replace(/var\(--value-relative\)/g, valueRelative).replace(/calc\s*\(([^)]+)\)/g, `$1`));
|
|
31407
|
+
if (result !== void 0) return Number.isNaN(result) ? defaultValue : result;
|
|
31408
|
+
const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));
|
|
31409
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
30272
31410
|
}
|
|
30273
31411
|
const parsed = Number.parseFloat(val);
|
|
30274
31412
|
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
@@ -30345,10 +31483,10 @@ let SliderInputElement = class SliderInputElement extends WheelNudgeMixin(i) {
|
|
|
30345
31483
|
proposedHigh = clamp$1(proposedHigh, this.min, this.max);
|
|
30346
31484
|
}
|
|
30347
31485
|
const lowKey = this.#lengthDragLowKey ?? this.#lowKey();
|
|
30348
|
-
this.#lengthDragHighKey ?? this.#highKey();
|
|
31486
|
+
const highKey = this.#lengthDragHighKey ?? this.#highKey();
|
|
30349
31487
|
const previous = this.#poles();
|
|
30350
31488
|
const newPoleA = lowKey === `a` ? proposedLow : proposedHigh;
|
|
30351
|
-
const newPoleB =
|
|
31489
|
+
const newPoleB = highKey === `b` ? proposedHigh : proposedLow;
|
|
30352
31490
|
this.#poleA = newPoleA;
|
|
30353
31491
|
this.#poleB = newPoleB;
|
|
30354
31492
|
if (this.valueMode === `triple` && this.#poleC !== void 0) {
|
|
@@ -33967,7 +35105,7 @@ function getScaleSteps(palette) {
|
|
|
33967
35105
|
function resolveCssVariable(el, prop) {
|
|
33968
35106
|
const style = getComputedStyle(el);
|
|
33969
35107
|
let value = style.getPropertyValue(prop).trim();
|
|
33970
|
-
const varRegex = /var\((--[\w-]+)(
|
|
35108
|
+
const varRegex = /var\((--[\w-]+)(?:,(.*))?\)/g;
|
|
33971
35109
|
for (let i = 0; i < 5 && value.includes(`var(`); i++) value = value.replace(varRegex, (_, varName, fallback) => {
|
|
33972
35110
|
const resolved = style.getPropertyValue(varName).trim();
|
|
33973
35111
|
if (resolved) return resolved;
|
|
@@ -43393,6 +44531,6 @@ function init() {
|
|
|
43393
44531
|
console.log(`Init`);
|
|
43394
44532
|
}
|
|
43395
44533
|
//#endregion
|
|
43396
|
-
export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GridListElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListNativeDragController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SplitPanelElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TickledController, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeKeyboardNavController, TreeListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applySnapshot, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, captionForEntry, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, computeColour, computeLeafGeoms, createAcCompletionProvider, createDataListSearchAdapter, createDefaultListDragPreview, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, distribute, extractStack, findNode, findParentOf, findStackOf, findStackPathByName, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, iconBus, init, insertBeside, isDragging, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, normalise, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, pointerOverAnyHost, prefersReducedMotion, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveLeafPath, resolveTracks, serializeLayout, setActive, setIconFont, startListItemOutAnimation, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toSnapshot, walk, wrapRoot };
|
|
44534
|
+
export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GridListElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListNativeDragController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SplitPanelElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TickledController, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeDropController, TreeKeyboardNavController, TreeListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applySnapshot, applyTreeDrop, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, captionForEntry, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, computeColour, computeLeafGeoms, createAcCompletionProvider, createDataListSearchAdapter, createDefaultListDragPreview, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, distribute, dropTargetFor, extractStack, findNode, findParentOf, findStackOf, findStackPathByName, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, iconBus, init, insertBeside, isDragging, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, normalise, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, pointerOverAnyHost, prefersReducedMotion, pruneDraggedDescendants, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveLeafPath, resolveTracks, serializeLayout, setActive, setIconFont, startListItemOutAnimation, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toSnapshot, walk, wrapRoot };
|
|
43397
44535
|
|
|
43398
44536
|
//# sourceMappingURL=index.js.map
|