react-arborist 2.0.0-rc → 2.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,31 +23,36 @@ export declare class NodeApi<T extends IdObj = IdObj> {
23
23
  isDroppable: boolean;
24
24
  rowIndex: number | null;
25
25
  constructor(params: Params<T>);
26
- get next(): NodeApi<T> | null;
27
- get prev(): NodeApi<T> | null;
28
- get nextSibling(): NodeApi<T> | null;
29
26
  get isRoot(): boolean;
30
27
  get isLeaf(): boolean;
31
28
  get isInternal(): boolean;
32
29
  get isOpen(): boolean;
30
+ get isClosed(): boolean;
33
31
  get isEditing(): boolean;
34
32
  get isSelected(): boolean;
33
+ get isOnlySelection(): boolean;
35
34
  get isSelectedStart(): boolean;
36
35
  get isSelectedEnd(): boolean;
37
36
  get isFocused(): boolean;
38
- get childIndex(): number;
39
37
  get isDragging(): boolean;
40
38
  get willReceiveDrop(): boolean;
41
39
  get state(): {
42
- isEditing: boolean;
40
+ isClosed: boolean;
43
41
  isDragging: boolean;
44
- isSelected: boolean;
45
- isSelectedStart: boolean;
46
- isSelectedEnd: boolean;
42
+ isEditing: boolean;
47
43
  isFocused: boolean;
44
+ isInternal: boolean;
45
+ isLeaf: boolean;
48
46
  isOpen: boolean;
47
+ isSelected: boolean;
48
+ isSelectedEnd: boolean;
49
+ isSelectedStart: boolean;
49
50
  willReceiveDrop: boolean;
50
51
  };
52
+ get childIndex(): number;
53
+ get next(): NodeApi<T> | null;
54
+ get prev(): NodeApi<T> | null;
55
+ get nextSibling(): NodeApi<T> | null;
51
56
  select(): void;
52
57
  deselect(): void;
53
58
  selectMulti(): void;
@@ -44,7 +44,8 @@ export declare class TreeApi<T extends IdObj> {
44
44
  get rowHeight(): number;
45
45
  get searchTerm(): string;
46
46
  get matchFn(): (node: NodeApi<T>) => boolean;
47
- getChildren(data: T): T[] | null;
47
+ accessChildren(data: T): T[] | null;
48
+ accessId(data: T): string;
48
49
  get firstNode(): NodeApi<T>;
49
50
  get lastNode(): NodeApi<T>;
50
51
  get focusedNode(): NodeApi<T> | null;
@@ -58,7 +59,11 @@ export declare class TreeApi<T extends IdObj> {
58
59
  get editingId(): string | null;
59
60
  createInternal(): Promise<void>;
60
61
  createLeaf(): Promise<void>;
61
- private create;
62
+ create(opts?: {
63
+ type?: "internal" | "leaf";
64
+ parentId?: null | string;
65
+ index?: null | number;
66
+ }): Promise<void>;
62
67
  delete(node: string | IdObj | null | string[] | IdObj[]): Promise<void>;
63
68
  edit(node: string | IdObj): Promise<EditResult>;
64
69
  submit(node: Identity, value: string): Promise<void>;
@@ -78,7 +83,7 @@ export declare class TreeApi<T extends IdObj> {
78
83
  deselect(node: Identity): void;
79
84
  selectMulti(identity: Identity): void;
80
85
  selectContiguous(identity: Identity): void;
81
- selectNone(): void;
86
+ deselectAll(): void;
82
87
  selectAll(): void;
83
88
  get cursorParentId(): string | null;
84
89
  get cursorOverFolder(): boolean;
@@ -89,10 +94,15 @@ export declare class TreeApi<T extends IdObj> {
89
94
  toggle(identity: Identity): void;
90
95
  openParents(identity: Identity): void;
91
96
  openSiblings(node: NodeApi<T>): void;
97
+ openAll(): void;
98
+ closeAll(): void;
92
99
  scrollTo(identity: Identity, align?: Align): Promise<void> | undefined;
93
100
  get isEditing(): boolean;
94
101
  get isFiltered(): boolean;
95
102
  get hasFocus(): boolean;
103
+ get hasNoSelection(): boolean;
104
+ get hasOneSelection(): boolean;
105
+ get hasMultipleSelections(): boolean;
96
106
  isSelected(id?: string): boolean;
97
107
  isOpen(id?: string): boolean;
98
108
  isDraggable(data: T): boolean;
@@ -108,5 +118,5 @@ export declare class TreeApi<T extends IdObj> {
108
118
  get renderRow(): import("react").ElementType<import("..").RowRendererProps<T>> | typeof DefaultRow;
109
119
  get renderNode(): import("react").ElementType<import("..").NodeRendererProps<T>> | typeof DefaultNode;
110
120
  get renderDragPreview(): import("react").ComponentType<import("..").DragPreviewProps> | typeof DefaultDragPreview;
111
- get renderCursor(): import("react").ComponentType<import("..").DropCursorProps> | import("react").NamedExoticComponent<import("..").DropCursorProps>;
121
+ get renderCursor(): import("react").ComponentType<import("..").CursorProps> | import("react").NamedExoticComponent<import("..").CursorProps>;
112
122
  }
package/dist/module.js CHANGED
@@ -51,6 +51,7 @@ $parcel$export($0e6083160f4b36ed$exports, "isDecendent", () => $0e6083160f4b36ed
51
51
  $parcel$export($0e6083160f4b36ed$exports, "indexOf", () => $0e6083160f4b36ed$export$305f7d4e9d4624f2);
52
52
  $parcel$export($0e6083160f4b36ed$exports, "noop", () => $0e6083160f4b36ed$export$8793edee2d425525);
53
53
  $parcel$export($0e6083160f4b36ed$exports, "dfs", () => $0e6083160f4b36ed$export$51b654aff22fc5a6);
54
+ $parcel$export($0e6083160f4b36ed$exports, "walk", () => $0e6083160f4b36ed$export$588732934346abbf);
54
55
  $parcel$export($0e6083160f4b36ed$exports, "focusNextElement", () => $0e6083160f4b36ed$export$3b0237e8566c8d65);
55
56
  $parcel$export($0e6083160f4b36ed$exports, "focusPrevElement", () => $0e6083160f4b36ed$export$33b47db07a82b2fb);
56
57
  $parcel$export($0e6083160f4b36ed$exports, "access", () => $0e6083160f4b36ed$export$9bb0e144ba4929ca);
@@ -59,6 +60,8 @@ $parcel$export($0e6083160f4b36ed$exports, "identify", () => $0e6083160f4b36ed$ex
59
60
  $parcel$export($0e6083160f4b36ed$exports, "mergeRefs", () => $0e6083160f4b36ed$export$c9058316764c140e);
60
61
  $parcel$export($0e6083160f4b36ed$exports, "safeRun", () => $0e6083160f4b36ed$export$c6d63370cef03886);
61
62
  $parcel$export($0e6083160f4b36ed$exports, "waitFor", () => $0e6083160f4b36ed$export$9bbfceb27f687c1b);
63
+ $parcel$export($0e6083160f4b36ed$exports, "getInsertIndex", () => $0e6083160f4b36ed$export$e12bf2314d0bc2a9);
64
+ $parcel$export($0e6083160f4b36ed$exports, "getInsertParentId", () => $0e6083160f4b36ed$export$58fe32731f07ed56);
62
65
  function $0e6083160f4b36ed$export$adf7c0fe6059d774(n, min, max) {
63
66
  return Math.max(Math.min(n, max), min);
64
67
  }
@@ -90,6 +93,10 @@ function $0e6083160f4b36ed$export$51b654aff22fc5a6(node, id) {
90
93
  }
91
94
  return null;
92
95
  }
96
+ function $0e6083160f4b36ed$export$588732934346abbf(node, fn) {
97
+ fn(node);
98
+ if (node.children) for (let child of node.children)$0e6083160f4b36ed$export$588732934346abbf(child, fn);
99
+ }
93
100
  function $0e6083160f4b36ed$export$3b0237e8566c8d65(target) {
94
101
  const elements = $0e6083160f4b36ed$var$getFocusable(target);
95
102
  let next;
@@ -162,6 +169,20 @@ function $0e6083160f4b36ed$export$9bbfceb27f687c1b(fn) {
162
169
  check();
163
170
  });
164
171
  }
172
+ function $0e6083160f4b36ed$export$e12bf2314d0bc2a9(tree) {
173
+ const focus = tree.focusedNode;
174
+ if (!focus) return tree.root.children?.length ?? 0;
175
+ if (focus.isOpen) return 0;
176
+ if (focus.parent) return focus.childIndex + 1;
177
+ return 0;
178
+ }
179
+ function $0e6083160f4b36ed$export$58fe32731f07ed56(tree) {
180
+ const focus = tree.focusedNode;
181
+ if (!focus) return null;
182
+ if (focus.isOpen) return focus.id;
183
+ if (focus.parent) return focus.parent.id;
184
+ return null;
185
+ }
165
186
 
166
187
 
167
188
 
@@ -227,16 +248,51 @@ function $164e874d21fcd87e$export$f9c541e71856c524({ node: node , attrs: attrs ,
227
248
 
228
249
 
229
250
 
230
- function $c4edd692d5290432$export$909e23cbfbbd3351({ style: style , node: node , dragHandle: dragHandle }) {
251
+ function $c4edd692d5290432$export$909e23cbfbbd3351(props) {
231
252
  return /*#__PURE__*/ (0, $g00cZ$jsxs)("div", {
232
- style: style,
233
- ref: dragHandle,
253
+ ref: props.dragHandle,
254
+ style: props.style,
234
255
  children: [
235
- "ID: ",
236
- node.data.id
256
+ /*#__PURE__*/ (0, $g00cZ$jsx)("span", {
257
+ onClick: (e)=>{
258
+ e.stopPropagation();
259
+ props.node.toggle();
260
+ },
261
+ children: props.node.isLeaf ? "\uD83C\uDF33" : props.node.isOpen ? "\uD83D\uDDC1" : "\uD83D\uDDC0"
262
+ }),
263
+ " ",
264
+ props.node.isEditing ? /*#__PURE__*/ (0, $g00cZ$jsx)($c4edd692d5290432$var$Edit, {
265
+ ...props
266
+ }) : /*#__PURE__*/ (0, $g00cZ$jsx)($c4edd692d5290432$var$Show, {
267
+ ...props
268
+ })
237
269
  ]
238
270
  });
239
271
  }
272
+ function $c4edd692d5290432$var$Show(props) {
273
+ return /*#__PURE__*/ (0, $g00cZ$jsx)((0, $g00cZ$Fragment), {
274
+ children: /*#__PURE__*/ (0, $g00cZ$jsx)("span", {
275
+ children: props.node.data.name
276
+ })
277
+ });
278
+ }
279
+ function $c4edd692d5290432$var$Edit({ node: node }) {
280
+ const input = (0, $g00cZ$useRef)();
281
+ (0, $g00cZ$useEffect)(()=>{
282
+ input.current?.focus();
283
+ input.current?.select();
284
+ }, []);
285
+ return /*#__PURE__*/ (0, $g00cZ$jsx)("input", {
286
+ ref: input,
287
+ // @ts-ignore
288
+ defaultValue: node.data.name,
289
+ onBlur: ()=>node.reset(),
290
+ onKeyDown: (e)=>{
291
+ if (e.key === "Escape") node.reset();
292
+ if (e.key === "Enter") node.submit(input.current?.value || "");
293
+ }
294
+ });
295
+ }
240
296
 
241
297
 
242
298
  function $21783d2b0251be67$export$e1a8e267487c59d1(id) {
@@ -300,18 +356,6 @@ class $096e74084443e9a3$export$d4b903da0f522dc8 {
300
356
  this.isDroppable = params.isDroppable;
301
357
  this.rowIndex = params.rowIndex;
302
358
  }
303
- get next() {
304
- if (this.rowIndex === null) return null;
305
- return this.tree.at(this.rowIndex + 1);
306
- }
307
- get prev() {
308
- if (this.rowIndex === null) return null;
309
- return this.tree.at(this.rowIndex - 1);
310
- }
311
- get nextSibling() {
312
- const i = this.childIndex;
313
- return this.parent?.children[i + 1] ?? null;
314
- }
315
359
  get isRoot() {
316
360
  return this.id === (0, $81080a351c006222$export$ec71a3379b43ae5c);
317
361
  }
@@ -324,12 +368,18 @@ class $096e74084443e9a3$export$d4b903da0f522dc8 {
324
368
  get isOpen() {
325
369
  return this.isLeaf ? false : this.tree.isOpen(this.id);
326
370
  }
371
+ get isClosed() {
372
+ return this.isLeaf ? false : !this.tree.isOpen(this.id);
373
+ }
327
374
  get isEditing() {
328
375
  return this.tree.editingId === this.id;
329
376
  }
330
377
  get isSelected() {
331
378
  return this.tree.isSelected(this.id);
332
379
  }
380
+ get isOnlySelection() {
381
+ return this.isSelected && this.tree.hasOneSelection;
382
+ }
333
383
  get isSelectedStart() {
334
384
  return this.isSelected && !this.prev?.isSelected;
335
385
  }
@@ -339,10 +389,6 @@ class $096e74084443e9a3$export$d4b903da0f522dc8 {
339
389
  get isFocused() {
340
390
  return this.tree.isFocused(this.id);
341
391
  }
342
- get childIndex() {
343
- if (this.parent && this.parent.children) return this.parent.children.findIndex((child)=>child.id === this.id);
344
- else return -1;
345
- }
346
392
  get isDragging() {
347
393
  return this.tree.isDragging(this.id);
348
394
  }
@@ -351,16 +397,35 @@ class $096e74084443e9a3$export$d4b903da0f522dc8 {
351
397
  }
352
398
  get state() {
353
399
  return {
354
- isEditing: this.isEditing,
400
+ isClosed: this.isClosed,
355
401
  isDragging: this.isDragging,
356
- isSelected: this.isSelected,
357
- isSelectedStart: this.isSelectedStart,
358
- isSelectedEnd: this.isSelectedEnd,
402
+ isEditing: this.isEditing,
359
403
  isFocused: this.isFocused,
404
+ isInternal: this.isInternal,
405
+ isLeaf: this.isLeaf,
360
406
  isOpen: this.isOpen,
407
+ isSelected: this.isSelected,
408
+ isSelectedEnd: this.isSelectedEnd,
409
+ isSelectedStart: this.isSelectedStart,
361
410
  willReceiveDrop: this.willReceiveDrop
362
411
  };
363
412
  }
413
+ get childIndex() {
414
+ if (this.parent && this.parent.children) return this.parent.children.findIndex((child)=>child.id === this.id);
415
+ else return -1;
416
+ }
417
+ get next() {
418
+ if (this.rowIndex === null) return null;
419
+ return this.tree.at(this.rowIndex + 1);
420
+ }
421
+ get prev() {
422
+ if (this.rowIndex === null) return null;
423
+ return this.tree.at(this.rowIndex - 1);
424
+ }
425
+ get nextSibling() {
426
+ const i = this.childIndex;
427
+ return this.parent?.children[i + 1] ?? null;
428
+ }
364
429
  select() {
365
430
  this.tree.select(this);
366
431
  }
@@ -419,18 +484,19 @@ class $096e74084443e9a3$export$d4b903da0f522dc8 {
419
484
  const $81080a351c006222$export$ec71a3379b43ae5c = "__REACT_ARBORIST_INTERNAL_ROOT__";
420
485
  function $81080a351c006222$export$882461b6382ed46c(tree) {
421
486
  function visitSelfAndChildren(data, level, parent) {
487
+ const id = tree.accessId(data);
422
488
  const node = new (0, $096e74084443e9a3$export$d4b903da0f522dc8)({
423
489
  tree: tree,
424
490
  data: data,
425
491
  level: level,
426
492
  parent: parent,
427
- id: data.id,
493
+ id: id,
428
494
  children: null,
429
495
  isDraggable: tree.isDraggable(data),
430
496
  isDroppable: tree.isDroppable(data),
431
497
  rowIndex: null
432
498
  });
433
- const children = tree.getChildren(data);
499
+ const children = tree.accessChildren(data);
434
500
  if (children) node.children = children.map((child)=>visitSelfAndChildren(child, level + 1, node));
435
501
  return node;
436
502
  }
@@ -776,7 +842,7 @@ const $77d34d95e44d2f58$var$PreviewNode = /*#__PURE__*/ (0, $g00cZ$memo)(functio
776
842
 
777
843
 
778
844
 
779
- function $f608be224a71d6f5$export$ef961593063b03e8() {
845
+ function $f608be224a71d6f5$export$b6a79797ad180576() {
780
846
  const tree = (0, $89e93131aae74bd9$export$367b0f2231a90ba0)();
781
847
  const state = (0, $89e93131aae74bd9$export$4930f6bf413be70e)();
782
848
  const cursor = state.cursor;
@@ -801,7 +867,7 @@ const $05f64c7ebcbad8b5$export$70c2b8898b86d3ad = /*#__PURE__*/ (0, $g00cZ$forwa
801
867
  ref: ref,
802
868
  ...rest,
803
869
  onClick: (e)=>{
804
- if (e.currentTarget === e.target) tree.selectNone();
870
+ if (e.currentTarget === e.target) tree.deselectAll();
805
871
  },
806
872
  children: [
807
873
  /*#__PURE__*/ (0, $g00cZ$jsx)($05f64c7ebcbad8b5$var$DropContainer, {}),
@@ -819,10 +885,7 @@ const $05f64c7ebcbad8b5$var$DropContainer = ()=>{
819
885
  left: "0",
820
886
  right: "0"
821
887
  },
822
- onClick: (e)=>{
823
- console.log(e.currentTarget, e.target);
824
- },
825
- children: /*#__PURE__*/ (0, $g00cZ$jsx)((0, $f608be224a71d6f5$export$ef961593063b03e8), {})
888
+ children: /*#__PURE__*/ (0, $g00cZ$jsx)((0, $f608be224a71d6f5$export$b6a79797ad180576), {})
826
889
  });
827
890
  };
828
891
 
@@ -1171,7 +1234,8 @@ const $8c3aed0a01f84486$export$a9754b3c8daa5172 = /*#__PURE__*/ (0, $g00cZ$react
1171
1234
  "aria-level": node.level,
1172
1235
  "aria-selected": node.isSelected,
1173
1236
  style: rowStyle,
1174
- tabIndex: -1
1237
+ tabIndex: -1,
1238
+ className: tree.props.rowClassName
1175
1239
  };
1176
1240
  (0, $g00cZ$useEffect)(()=>{
1177
1241
  if (!node.isEditing && node.isFocused) el.current?.focus();
@@ -1220,6 +1284,7 @@ function $065a164934293bf2$export$ff4858a4110d9246() {
1220
1284
  onKeyDown: (e)=>{
1221
1285
  if (tree.isEditing) return;
1222
1286
  if (e.key === "Backspace") {
1287
+ if (!tree.props.onDelete) return;
1223
1288
  const ids = Array.from(tree.selectedIds);
1224
1289
  if (ids.length > 1) {
1225
1290
  let nextFocus = tree.mostRecentNode;
@@ -1303,10 +1368,12 @@ function $065a164934293bf2$export$ff4858a4110d9246() {
1303
1368
  return;
1304
1369
  }
1305
1370
  if (e.key === "a" && !e.metaKey) {
1371
+ if (!tree.props.onCreate) return;
1306
1372
  tree.createLeaf();
1307
1373
  return;
1308
1374
  }
1309
1375
  if (e.key === "A" && !e.metaKey) {
1376
+ if (!tree.props.onCreate) return;
1310
1377
  tree.createInternal();
1311
1378
  return;
1312
1379
  }
@@ -1323,6 +1390,7 @@ function $065a164934293bf2$export$ff4858a4110d9246() {
1323
1390
  return;
1324
1391
  }
1325
1392
  if (e.key === "Enter") {
1393
+ if (!tree.props.onRename) return;
1326
1394
  setTimeout(()=>{
1327
1395
  if (tree.focusedNode) tree.edit(tree.focusedNode);
1328
1396
  });
@@ -1469,16 +1537,16 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1469
1537
  return this.state.nodes.open.unfiltered;
1470
1538
  }
1471
1539
  /* Tree Props */ get width() {
1472
- return this.props.width || 300;
1540
+ return this.props.width ?? 300;
1473
1541
  }
1474
1542
  get height() {
1475
- return this.props.height || 500;
1543
+ return this.props.height ?? 500;
1476
1544
  }
1477
1545
  get indent() {
1478
- return this.props.indent || 24;
1546
+ return this.props.indent ?? 24;
1479
1547
  }
1480
1548
  get rowHeight() {
1481
- return this.props.rowHeight || 24;
1549
+ return this.props.rowHeight ?? 24;
1482
1550
  }
1483
1551
  get searchTerm() {
1484
1552
  return (this.props.searchTerm || "").trim();
@@ -1490,10 +1558,16 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1490
1558
  });
1491
1559
  return (node)=>match(node, this.searchTerm);
1492
1560
  }
1493
- getChildren(data) {
1494
- const get = this.props.getChildren || "children";
1561
+ accessChildren(data) {
1562
+ const get = this.props.childrenAccessor || "children";
1495
1563
  return $0e6083160f4b36ed$exports.access(data, get) ?? null;
1496
1564
  }
1565
+ accessId(data) {
1566
+ const get = this.props.idAccessor || "id";
1567
+ const id = $0e6083160f4b36ed$exports.access(data, get);
1568
+ if (!id) throw new Error("Data must contain an 'id' property or props.idAccessor must return a string");
1569
+ return id;
1570
+ }
1497
1571
  /* Node Access */ get firstNode() {
1498
1572
  return this.visibleNodes[0] ?? null;
1499
1573
  }
@@ -1542,31 +1616,20 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1542
1616
  return this.state.nodes.edit.id;
1543
1617
  }
1544
1618
  createInternal() {
1545
- return this.create("internal");
1619
+ return this.create({
1620
+ type: "internal"
1621
+ });
1546
1622
  }
1547
1623
  createLeaf() {
1548
- return this.create("leaf");
1549
- }
1550
- async create(type) {
1551
- let index;
1552
- let parentId;
1553
- const focus = this.focusedNode;
1554
- if (focus && focus.parent) {
1555
- if (focus.isInternal && focus.isOpen) {
1556
- parentId = focus.id;
1557
- index = 0;
1558
- } else {
1559
- index = focus.childIndex + 1;
1560
- parentId = focus.parent.isRoot ? null : focus.parent.id;
1561
- }
1562
- } else {
1563
- index = this.root?.children?.length || -1;
1564
- parentId = null;
1565
- }
1624
+ return this.create({
1625
+ type: "leaf"
1626
+ });
1627
+ }
1628
+ async create(opts = {}) {
1566
1629
  const data = await $bfece7c4aed4e9c4$var$safeRun(this.props.onCreate, {
1567
- parentId: parentId,
1568
- index: index,
1569
- type: type
1630
+ type: opts.type ?? "leaf",
1631
+ parentId: opts.parentId === undefined ? $0e6083160f4b36ed$exports.getInsertParentId(this) : opts.parentId,
1632
+ index: opts.index ?? $0e6083160f4b36ed$exports.getInsertIndex(this)
1570
1633
  });
1571
1634
  if (data) {
1572
1635
  this.focus(data);
@@ -1649,6 +1712,7 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1649
1712
  else {
1650
1713
  this.dispatch((0, $c27b8e9863235052$export$d7ddd398f22d79ef)($bfece7c4aed4e9c4$var$identify(node)));
1651
1714
  if (opts.scroll !== false) this.scrollTo(node);
1715
+ if (this.focusedNode) $bfece7c4aed4e9c4$var$safeRun(this.props.onFocus, this.focusedNode);
1652
1716
  }
1653
1717
  }
1654
1718
  pageUp() {
@@ -1677,6 +1741,7 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1677
1741
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).anchor(id));
1678
1742
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).mostRecent(id));
1679
1743
  this.scrollTo(id, opts.align);
1744
+ if (this.focusedNode) $bfece7c4aed4e9c4$var$safeRun(this.props.onFocus, this.focusedNode);
1680
1745
  $bfece7c4aed4e9c4$var$safeRun(this.props.onSelect, this.selectedNodes);
1681
1746
  }
1682
1747
  deselect(node) {
@@ -1692,6 +1757,7 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1692
1757
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).anchor(node.id));
1693
1758
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).mostRecent(node.id));
1694
1759
  this.scrollTo(node);
1760
+ if (this.focusedNode) $bfece7c4aed4e9c4$var$safeRun(this.props.onFocus, this.focusedNode);
1695
1761
  $bfece7c4aed4e9c4$var$safeRun(this.props.onSelect, this.selectedNodes);
1696
1762
  }
1697
1763
  selectContiguous(identity) {
@@ -1703,9 +1769,10 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1703
1769
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).add(this.nodesBetween(anchor, $bfece7c4aed4e9c4$var$identifyNull(id))));
1704
1770
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).mostRecent(id));
1705
1771
  this.scrollTo(id);
1772
+ if (this.focusedNode) $bfece7c4aed4e9c4$var$safeRun(this.props.onFocus, this.focusedNode);
1706
1773
  $bfece7c4aed4e9c4$var$safeRun(this.props.onSelect, this.selectedNodes);
1707
1774
  }
1708
- selectNone() {
1775
+ deselectAll() {
1709
1776
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).clear());
1710
1777
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).anchor(null));
1711
1778
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).mostRecent(null));
@@ -1716,6 +1783,7 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1716
1783
  this.dispatch((0, $c27b8e9863235052$export$d7ddd398f22d79ef)(this.lastNode?.id));
1717
1784
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).anchor(this.firstNode));
1718
1785
  this.dispatch((0, $37bc167debff36d2$export$e324594224ef24da).mostRecent(this.lastNode));
1786
+ if (this.focusedNode) $bfece7c4aed4e9c4$var$safeRun(this.props.onFocus, this.focusedNode);
1719
1787
  $bfece7c4aed4e9c4$var$safeRun(this.props.onSelect, this.selectedNodes);
1720
1788
  }
1721
1789
  /* Drag and Drop */ get cursorParentId() {
@@ -1741,12 +1809,16 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1741
1809
  /* Visibility */ open(identity) {
1742
1810
  const id = $bfece7c4aed4e9c4$var$identifyNull(identity);
1743
1811
  if (!id) return;
1812
+ if (this.isOpen(id)) return;
1744
1813
  this.dispatch((0, $3c0bad2888bcd4bc$export$e324594224ef24da).open(id, this.isFiltered));
1814
+ $bfece7c4aed4e9c4$var$safeRun(this.props.onToggle, id);
1745
1815
  }
1746
1816
  close(identity) {
1747
1817
  const id = $bfece7c4aed4e9c4$var$identifyNull(identity);
1748
1818
  if (!id) return;
1819
+ if (!this.isOpen(id)) return;
1749
1820
  this.dispatch((0, $3c0bad2888bcd4bc$export$e324594224ef24da).close(id, this.isFiltered));
1821
+ $bfece7c4aed4e9c4$var$safeRun(this.props.onToggle, id);
1750
1822
  }
1751
1823
  toggle(identity) {
1752
1824
  const id = $bfece7c4aed4e9c4$var$identifyNull(identity);
@@ -1772,6 +1844,16 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1772
1844
  this.scrollTo(this.focusedNode);
1773
1845
  }
1774
1846
  }
1847
+ openAll() {
1848
+ $0e6083160f4b36ed$exports.walk(this.root, (node)=>{
1849
+ if (node.isInternal) node.open();
1850
+ });
1851
+ }
1852
+ closeAll() {
1853
+ $0e6083160f4b36ed$exports.walk(this.root, (node)=>{
1854
+ if (node.isInternal) node.close();
1855
+ });
1856
+ }
1775
1857
  /* Scrolling */ scrollTo(identity, align = "smart") {
1776
1858
  if (!identity) return;
1777
1859
  const id = $bfece7c4aed4e9c4$var$identify(identity);
@@ -1793,6 +1875,15 @@ class $bfece7c4aed4e9c4$export$e2da3477247342d1 {
1793
1875
  get hasFocus() {
1794
1876
  return this.state.nodes.focus.treeFocused;
1795
1877
  }
1878
+ get hasNoSelection() {
1879
+ return this.state.nodes.selection.ids.size === 0;
1880
+ }
1881
+ get hasOneSelection() {
1882
+ return this.state.nodes.selection.ids.size === 1;
1883
+ }
1884
+ get hasMultipleSelections() {
1885
+ return this.state.nodes.selection.ids.size > 1;
1886
+ }
1796
1887
  isSelected(id) {
1797
1888
  if (!id) return false;
1798
1889
  return this.state.nodes.selection.ids.has(id);
@@ -1932,7 +2023,7 @@ function $dac24389e46ba09d$export$c49dab5eb1b4ce0c({ treeProps: treeProps , impe
1932
2023
  /* Expose the tree api */ (0, $g00cZ$useImperativeHandle)(imperativeHandle, ()=>api);
1933
2024
  /* Change selection based on props */ (0, $g00cZ$useEffect)(()=>{
1934
2025
  if (api.props.selection) api.select(api.props.selection);
1935
- else api.selectNone();
2026
+ else api.deselectAll();
1936
2027
  }, [
1937
2028
  api.props.selection
1938
2029
  ]);
@@ -1966,6 +2057,7 @@ function $dac24389e46ba09d$export$c49dab5eb1b4ce0c({ treeProps: treeProps , impe
1966
2057
 
1967
2058
 
1968
2059
 
2060
+
1969
2061
  function $e739455e59c6aed3$export$5a6c424b1725f44f() {
1970
2062
  const tree = (0, $89e93131aae74bd9$export$367b0f2231a90ba0)();
1971
2063
  // In case we drop an item at the bottom of the list
@@ -1975,9 +2067,28 @@ function $e739455e59c6aed3$export$5a6c424b1725f44f() {
1975
2067
  if (!m.isOver({
1976
2068
  shallow: true
1977
2069
  })) return;
2070
+ if (m.canDrop()) {
2071
+ const offset = m.getClientOffset();
2072
+ if (!tree.listEl.current || !offset) return;
2073
+ const { cursor: cursor } = (0, $2db980bfed6822da$export$f502ca02ebb85a1c)({
2074
+ element: tree.listEl.current,
2075
+ offset: offset,
2076
+ indent: tree.indent,
2077
+ node: null,
2078
+ prevNode: tree.visibleNodes[tree.visibleNodes.length - 1],
2079
+ nextNode: null
2080
+ });
2081
+ if (cursor) tree.showCursor(cursor);
2082
+ } else tree.hideCursor();
2083
+ },
2084
+ canDrop: (item, m)=>{
2085
+ if (!m.isOver({
2086
+ shallow: true
2087
+ })) return false;
2088
+ if (tree.isFiltered) return false;
1978
2089
  const offset = m.getClientOffset();
1979
- if (!tree.listEl.current || !offset) return;
1980
- const { cursor: cursor } = (0, $2db980bfed6822da$export$f502ca02ebb85a1c)({
2090
+ if (!tree.listEl.current || !offset) return false;
2091
+ const { drop: drop } = (0, $2db980bfed6822da$export$f502ca02ebb85a1c)({
1981
2092
  element: tree.listEl.current,
1982
2093
  offset: offset,
1983
2094
  indent: tree.indent,
@@ -1985,12 +2096,15 @@ function $e739455e59c6aed3$export$5a6c424b1725f44f() {
1985
2096
  prevNode: tree.visibleNodes[tree.visibleNodes.length - 1],
1986
2097
  nextNode: null
1987
2098
  });
1988
- if (cursor) tree.showCursor(cursor);
1989
- },
1990
- canDrop: (item, m)=>{
1991
- return m.isOver({
1992
- shallow: true
1993
- });
2099
+ if (!drop) return false;
2100
+ const dropParent = tree.get(drop.parentId) ?? tree.root;
2101
+ for (let id of item.dragIds){
2102
+ const drag = tree.get(id);
2103
+ if (!drag) return false;
2104
+ if (!dropParent) return false;
2105
+ if (drag.isInternal && (0, $0e6083160f4b36ed$export$1e38f72c6c546f70)(dropParent, drag)) return false;
2106
+ }
2107
+ return true;
1994
2108
  },
1995
2109
  drop: (item, m)=>{
1996
2110
  if (m.didDrop()) return;