@dxos/react-ui-list 0.8.4-main.bc674ce → 0.8.4-main.c351d160a8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/lib/browser/index.mjs +216 -185
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +216 -185
  5. package/dist/lib/node-esm/index.mjs.map +3 -3
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/List/List.d.ts +4 -4
  8. package/dist/types/src/components/List/List.d.ts.map +1 -1
  9. package/dist/types/src/components/List/ListItem.d.ts +8 -6
  10. package/dist/types/src/components/List/ListItem.d.ts.map +1 -1
  11. package/dist/types/src/components/Tree/Tree.d.ts +6 -5
  12. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  13. package/dist/types/src/components/Tree/Tree.stories.d.ts +1 -1
  14. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/Tree/TreeContext.d.ts +21 -10
  16. package/dist/types/src/components/Tree/TreeContext.d.ts.map +1 -1
  17. package/dist/types/src/components/Tree/TreeItem.d.ts +8 -0
  18. package/dist/types/src/components/Tree/TreeItem.d.ts.map +1 -1
  19. package/dist/types/src/components/Tree/TreeItemHeading.d.ts.map +1 -1
  20. package/dist/types/src/components/Tree/index.d.ts +2 -0
  21. package/dist/types/src/components/Tree/index.d.ts.map +1 -1
  22. package/dist/types/tsconfig.tsbuildinfo +1 -1
  23. package/package.json +19 -18
  24. package/src/components/Accordion/Accordion.stories.tsx +3 -3
  25. package/src/components/Accordion/AccordionItem.tsx +1 -1
  26. package/src/components/List/List.stories.tsx +9 -9
  27. package/src/components/List/List.tsx +2 -2
  28. package/src/components/List/ListItem.tsx +55 -35
  29. package/src/components/Tree/Tree.stories.tsx +102 -26
  30. package/src/components/Tree/Tree.tsx +30 -40
  31. package/src/components/Tree/TreeContext.tsx +18 -9
  32. package/src/components/Tree/TreeItem.tsx +166 -99
  33. package/src/components/Tree/TreeItemHeading.tsx +5 -3
  34. package/src/components/Tree/TreeItemToggle.tsx +1 -1
  35. package/src/components/Tree/index.ts +2 -0
@@ -44,7 +44,7 @@ var AccordionItemHeader = ({ classNames, children, ...props }) => {
44
44
  ...props,
45
45
  className: mx2(classNames)
46
46
  }, /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Trigger, {
47
- className: "group flex items-center p-2 dx-focus-ring-inset is-full text-start"
47
+ className: "group flex items-center p-2 dx-focus-ring-inset w-full text-start"
48
48
  }, children, /* @__PURE__ */ React2.createElement(Icon, {
49
49
  icon: "ph--caret-right--regular",
50
50
  size: 4,
@@ -74,6 +74,7 @@ import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-d
74
74
  import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
75
75
  import { attachClosestEdge, extractClosestEdge as extractClosestEdge2 } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
76
76
  import { createContext as createContext4 } from "@radix-ui/react-context";
77
+ import { Slot } from "@radix-ui/react-slot";
77
78
  import React4, { useEffect as useEffect2, useRef, useState as useState2 } from "react";
78
79
  import { createPortal } from "react-dom";
79
80
  import { invariant } from "@dxos/invariant";
@@ -160,16 +161,17 @@ var stateStyles = {
160
161
  var defaultContext = {};
161
162
  var LIST_ITEM_NAME = "ListItem";
162
163
  var [ListItemProvider, useListItemContext] = createContext4(LIST_ITEM_NAME, defaultContext);
163
- var ListItem = ({ children, classNames, item, ...props }) => {
164
+ var ListItem = ({ children, classNames, item, asChild, selected, ...props }) => {
165
+ const Comp = asChild ? Slot : "div";
164
166
  const { isItem, readonly, dragPreview, setState: setRootState } = useListContext(LIST_ITEM_NAME);
165
- const ref = useRef(null);
167
+ const rootRef = useRef(null);
166
168
  const dragHandleRef = useRef(null);
167
169
  const [state, setState] = useState2(idle);
168
170
  useEffect2(() => {
169
- const element = ref.current;
171
+ const element = rootRef.current;
170
172
  invariant(element, void 0, {
171
173
  F: __dxlog_file,
172
- L: 98,
174
+ L: 109,
173
175
  S: void 0,
174
176
  A: [
175
177
  "element",
@@ -278,40 +280,41 @@ var ListItem = ({ children, classNames, item, ...props }) => {
278
280
  return /* @__PURE__ */ React4.createElement(ListItemProvider, {
279
281
  item,
280
282
  dragHandleRef
281
- }, /* @__PURE__ */ React4.createElement("div", {
282
- ref,
283
+ }, /* @__PURE__ */ React4.createElement(Comp, {
284
+ ...props,
283
285
  role: "listitem",
284
- className: mx3("flex relative", classNames, stateStyles[state.type]),
285
- ...props
286
- }, children, state.type === "is-dragging-over" && state.closestEdge && /* @__PURE__ */ React4.createElement(NaturalListItem.DropIndicator, {
286
+ "aria-selected": selected,
287
+ className: mx3("relative p-1 dx-selected dx-hover", classNames, stateStyles[state.type]),
288
+ ref: rootRef
289
+ }, children), state.type === "is-dragging-over" && state.closestEdge && /* @__PURE__ */ React4.createElement(NaturalListItem.DropIndicator, {
287
290
  edge: state.closestEdge
288
- })));
291
+ }));
289
292
  };
290
- var ListItemDeleteButton = ({ autoHide = true, classNames, disabled, icon = "ph--x--regular", label, ...props }) => {
291
- const { state } = useListContext("DELETE_BUTTON");
293
+ var ListItemIconButton = ({ autoHide = true, iconOnly = true, variant = "ghost", classNames, disabled, ...props }) => {
294
+ const { state } = useListContext("ITEM_BUTTON");
292
295
  const isDisabled = state.type !== "idle" || disabled;
293
- const { t } = useTranslation(osTranslations);
294
296
  return /* @__PURE__ */ React4.createElement(IconButton, {
295
- iconOnly: true,
296
- variant: "ghost",
297
297
  ...props,
298
- icon,
299
298
  disabled: isDisabled,
300
- label: label ?? t("delete label"),
299
+ iconOnly,
300
+ variant,
301
301
  classNames: [
302
302
  classNames,
303
303
  autoHide && disabled && "hidden"
304
304
  ]
305
305
  });
306
306
  };
307
- var ListItemButton = ({ autoHide = true, iconOnly = true, variant = "ghost", classNames, disabled, ...props }) => {
308
- const { state } = useListContext("ITEM_BUTTON");
307
+ var ListItemDeleteButton = ({ autoHide = true, classNames, disabled, icon = "ph--x--regular", label, ...props }) => {
308
+ const { state } = useListContext("DELETE_BUTTON");
309
309
  const isDisabled = state.type !== "idle" || disabled;
310
+ const { t } = useTranslation(osTranslations);
310
311
  return /* @__PURE__ */ React4.createElement(IconButton, {
311
312
  ...props,
313
+ variant: "ghost",
312
314
  disabled: isDisabled,
313
- iconOnly,
314
- variant,
315
+ icon,
316
+ iconOnly: true,
317
+ label: label ?? t("delete label"),
315
318
  classNames: [
316
319
  classNames,
317
320
  autoHide && disabled && "hidden"
@@ -322,12 +325,12 @@ var ListItemDragHandle = ({ disabled }) => {
322
325
  const { dragHandleRef } = useListItemContext("DRAG_HANDLE");
323
326
  const { t } = useTranslation(osTranslations);
324
327
  return /* @__PURE__ */ React4.createElement(IconButton, {
325
- iconOnly: true,
326
328
  variant: "ghost",
327
- label: t("drag handle label"),
328
- ref: dragHandleRef,
329
+ disabled,
329
330
  icon: "ph--dots-six-vertical--regular",
330
- disabled
331
+ iconOnly: true,
332
+ label: t("drag handle label"),
333
+ ref: dragHandleRef
331
334
  });
332
335
  };
333
336
  var ListItemDragPreview = ({ children }) => {
@@ -337,9 +340,11 @@ var ListItemDragPreview = ({ children }) => {
337
340
  }), state.container) : null;
338
341
  };
339
342
  var ListItemWrapper = ({ classNames, children }) => /* @__PURE__ */ React4.createElement("div", {
340
- className: mx3("flex is-full gap-2", classNames)
343
+ role: "none",
344
+ className: mx3("flex w-full gap-2", classNames)
341
345
  }, children);
342
346
  var ListItemTitle = ({ classNames, children, ...props }) => /* @__PURE__ */ React4.createElement("div", {
347
+ role: "none",
343
348
  className: mx3("flex grow items-center truncate", classNames),
344
349
  ...props
345
350
  }, children);
@@ -351,12 +356,13 @@ var List = {
351
356
  ItemDragPreview: ListItemDragPreview,
352
357
  ItemWrapper: ListItemWrapper,
353
358
  ItemDragHandle: ListItemDragHandle,
359
+ ItemIconButton: ListItemIconButton,
354
360
  ItemDeleteButton: ListItemDeleteButton,
355
- ItemButton: ListItemButton,
356
361
  ItemTitle: ListItemTitle
357
362
  };
358
363
 
359
364
  // src/components/Tree/Tree.tsx
365
+ import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
360
366
  import React8, { useMemo as useMemo2 } from "react";
361
367
  import { Treegrid as Treegrid2 } from "@dxos/react-ui";
362
368
 
@@ -371,11 +377,12 @@ var useTree = () => useContext(TreeContext) ?? raise(new Error("TreeContext not
371
377
  import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
372
378
  import { draggable as draggable2, dropTargetForElements as dropTargetForElements2 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
373
379
  import { attachInstruction, extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
380
+ import { useAtomValue } from "@effect-atom/atom-react";
374
381
  import * as Schema from "effect/Schema";
375
382
  import React7, { memo as memo3, useCallback as useCallback3, useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState3 } from "react";
376
383
  import { invariant as invariant2 } from "@dxos/invariant";
377
384
  import { TreeItem as NaturalTreeItem, Treegrid } from "@dxos/react-ui";
378
- import { ghostFocusWithin, ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls } from "@dxos/ui-theme";
385
+ import { ghostFocusWithin, ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, mx as mx4 } from "@dxos/ui-theme";
379
386
 
380
387
  // src/components/Tree/helpers.ts
381
388
  var DEFAULT_INDENTATION = 8;
@@ -417,7 +424,7 @@ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label,
417
424
  variant: "ghost",
418
425
  density: "fine",
419
426
  classNames: [
420
- "grow gap-2 pis-0.5 hover:bg-transparent dark:hover:bg-transparent",
427
+ "grow gap-2 ps-0.5 hover:bg-transparent dark:hover:bg-transparent",
421
428
  "disabled:cursor-default disabled:opacity-100",
422
429
  className
423
430
  ],
@@ -431,11 +438,11 @@ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label,
431
438
  icon: icon ?? "ph--placeholder--regular",
432
439
  size: 5,
433
440
  classNames: [
434
- "mlb-1",
435
- styles?.icon
441
+ "my-1",
442
+ styles?.surfaceText
436
443
  ]
437
444
  }), /* @__PURE__ */ React5.createElement("span", {
438
- className: "flex-1 is-0 truncate text-start text-sm font-normal",
445
+ className: "flex-1 w-0 truncate text-start font-normal",
439
446
  "data-tooltip": true
440
447
  }, toLocalizedString(label, t))));
441
448
  }));
@@ -451,7 +458,7 @@ var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef2(({ open,
451
458
  variant: "ghost",
452
459
  density: "fine",
453
460
  classNames: [
454
- "bs-full is-6 pli-0",
461
+ "h-full w-6 px-0",
455
462
  "[&_svg]:transition-[transform] [&_svg]:duration-200",
456
463
  open && "[&_svg]:rotate-90",
457
464
  hidden ? "hidden" : !isBranch && "invisible",
@@ -476,7 +483,7 @@ var TreeDataSchema = Schema.Struct({
476
483
  item: Schema.Any
477
484
  });
478
485
  var isTreeData = (data) => Schema.is(TreeDataSchema)(data);
479
- var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _draggable, renderColumns: Columns, blockInstruction, canDrop, canSelect, onOpenChange, onSelect }) => {
486
+ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: draggableProp, renderColumns: Columns, blockInstruction, canDrop, canSelect, onOpenChange, onSelect, onItemHover }) => {
480
487
  const rowRef = useRef2(null);
481
488
  const buttonRef = useRef2(null);
482
489
  const openRef = useRef2(false);
@@ -484,18 +491,18 @@ var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _dragg
484
491
  const [_state, setState] = useState3("idle");
485
492
  const [instruction, setInstruction] = useState3(null);
486
493
  const [menuOpen, setMenuOpen] = useState3(false);
487
- const { useItems, getProps, useIsOpen, useIsCurrent } = useTree();
488
- const items = useItems(item);
489
- const { id, parentOf, label, className, headingClassName, icon, iconHue, disabled, testId } = getProps(item, _path);
494
+ const { itemProps: itemPropsAtom, childIds: childIdsAtom, itemOpen: itemOpenAtom, itemCurrent: itemCurrentAtom } = useTree();
490
495
  const path = useMemo(() => [
491
- ..._path,
492
- id
496
+ ...pathProp,
497
+ item.id
493
498
  ], [
494
- _path,
495
- id
499
+ pathProp,
500
+ item.id
496
501
  ]);
497
- const open = useIsOpen(path, item);
498
- const current = useIsCurrent(path, item);
502
+ const { id, parentOf, draggable: itemDraggable, droppable: itemDroppable, label, className, headingClassName, icon, iconHue, disabled, testId } = useAtomValue(itemPropsAtom(path));
503
+ const childIds = useAtomValue(childIdsAtom(item.id));
504
+ const open = useAtomValue(itemOpenAtom(path));
505
+ const current = useAtomValue(itemCurrentAtom(path));
499
506
  const level = path.length - levelOffset;
500
507
  const isBranch = !!parentOf;
501
508
  const mode = last ? "last-in-group" : open ? "expanded" : "standard";
@@ -503,122 +510,130 @@ var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _dragg
503
510
  item,
504
511
  path
505
512
  }) ?? true;
513
+ const data = {
514
+ id,
515
+ path,
516
+ item
517
+ };
506
518
  const cancelExpand = useCallback3(() => {
507
519
  if (cancelExpandRef.current) {
508
520
  clearTimeout(cancelExpandRef.current);
509
521
  cancelExpandRef.current = null;
510
522
  }
511
523
  }, []);
524
+ const isItemDraggable = draggableProp && itemDraggable !== false;
525
+ const isItemDroppable = itemDroppable !== false;
512
526
  useEffect3(() => {
513
- if (!_draggable) {
527
+ if (!draggableProp) {
514
528
  return;
515
529
  }
516
530
  invariant2(buttonRef.current, void 0, {
517
531
  F: __dxlog_file2,
518
- L: 111,
532
+ L: 148,
519
533
  S: void 0,
520
534
  A: [
521
535
  "buttonRef.current",
522
536
  ""
523
537
  ]
524
538
  });
525
- const data = {
526
- id,
527
- path,
528
- item
529
- };
530
- return combine2(
531
- draggable2({
532
- element: buttonRef.current,
533
- getInitialData: () => data,
534
- onDragStart: () => {
535
- setState("dragging");
536
- if (open) {
537
- openRef.current = true;
538
- onOpenChange?.({
539
- item,
540
- path,
541
- open: false
542
- });
543
- }
544
- },
545
- onDrop: () => {
546
- setState("idle");
547
- if (openRef.current) {
548
- onOpenChange?.({
549
- item,
550
- path,
551
- open: true
552
- });
553
- }
554
- }
555
- }),
556
- // https://github.com/atlassian/pragmatic-drag-and-drop/blob/main/packages/hitbox/constellation/index/about.mdx
557
- dropTargetForElements2({
558
- element: buttonRef.current,
559
- getData: ({ input, element }) => {
560
- return attachInstruction(data, {
561
- input,
562
- element,
563
- indentPerLevel: DEFAULT_INDENTATION,
564
- currentLevel: level,
565
- mode,
566
- block: isBranch ? [] : [
567
- "make-child"
568
- ]
539
+ const makeDraggable = () => draggable2({
540
+ element: buttonRef.current,
541
+ getInitialData: () => data,
542
+ onDragStart: () => {
543
+ setState("dragging");
544
+ if (open) {
545
+ openRef.current = true;
546
+ onOpenChange?.({
547
+ item,
548
+ path,
549
+ open: false
569
550
  });
570
- },
571
- canDrop: ({ source }) => {
572
- const _canDrop = canDrop ?? (() => true);
573
- return source.element !== buttonRef.current && _canDrop({
574
- source: source.data,
575
- target: data
576
- });
577
- },
578
- getIsSticky: () => true,
579
- onDrag: ({ self, source }) => {
580
- const desired = extractInstruction(self.data);
581
- const block = desired && blockInstruction?.({
582
- instruction: desired,
583
- source: source.data,
584
- target: data
551
+ }
552
+ },
553
+ onDrop: () => {
554
+ setState("idle");
555
+ if (openRef.current) {
556
+ onOpenChange?.({
557
+ item,
558
+ path,
559
+ open: true
585
560
  });
586
- const instruction2 = block && desired.type !== "instruction-blocked" ? {
587
- type: "instruction-blocked",
588
- desired
589
- } : desired;
590
- if (source.data.id !== id) {
591
- if (instruction2?.type === "make-child" && isBranch && !open && !cancelExpandRef.current) {
592
- cancelExpandRef.current = setTimeout(() => {
593
- onOpenChange?.({
594
- item,
595
- path,
596
- open: true
597
- });
598
- }, 500);
599
- }
600
- if (instruction2?.type !== "make-child") {
601
- cancelExpand();
602
- }
603
- setInstruction(instruction2);
604
- } else if (instruction2?.type === "reparent") {
605
- setInstruction(instruction2);
606
- } else {
607
- setInstruction(null);
561
+ }
562
+ }
563
+ });
564
+ if (!isItemDroppable) {
565
+ return isItemDraggable ? makeDraggable() : void 0;
566
+ }
567
+ const dropTarget = dropTargetForElements2({
568
+ element: buttonRef.current,
569
+ getData: ({ input, element }) => {
570
+ return attachInstruction(data, {
571
+ input,
572
+ element,
573
+ indentPerLevel: DEFAULT_INDENTATION,
574
+ currentLevel: level,
575
+ mode,
576
+ block: isBranch ? [] : [
577
+ "make-child"
578
+ ]
579
+ });
580
+ },
581
+ canDrop: ({ source }) => {
582
+ const _canDrop = canDrop ?? (() => true);
583
+ return source.element !== buttonRef.current && _canDrop({
584
+ source: source.data,
585
+ target: data
586
+ });
587
+ },
588
+ getIsSticky: () => true,
589
+ onDrag: ({ self, source }) => {
590
+ const desired = extractInstruction(self.data);
591
+ const block = desired && blockInstruction?.({
592
+ instruction: desired,
593
+ source: source.data,
594
+ target: data
595
+ });
596
+ const instruction2 = block && desired.type !== "instruction-blocked" ? {
597
+ type: "instruction-blocked",
598
+ desired
599
+ } : desired;
600
+ if (source.data.id !== id) {
601
+ if (instruction2?.type === "make-child" && isBranch && !open && !cancelExpandRef.current) {
602
+ cancelExpandRef.current = setTimeout(() => {
603
+ onOpenChange?.({
604
+ item,
605
+ path,
606
+ open: true
607
+ });
608
+ }, 500);
608
609
  }
609
- },
610
- onDragLeave: () => {
611
- cancelExpand();
612
- setInstruction(null);
613
- },
614
- onDrop: () => {
615
- cancelExpand();
610
+ if (instruction2?.type !== "make-child") {
611
+ cancelExpand();
612
+ }
613
+ setInstruction(instruction2);
614
+ } else if (instruction2?.type === "reparent") {
615
+ setInstruction(instruction2);
616
+ } else {
616
617
  setInstruction(null);
617
618
  }
618
- })
619
- );
619
+ },
620
+ onDragLeave: () => {
621
+ cancelExpand();
622
+ setInstruction(null);
623
+ },
624
+ onDrop: () => {
625
+ cancelExpand();
626
+ setInstruction(null);
627
+ }
628
+ });
629
+ if (!isItemDraggable) {
630
+ return dropTarget;
631
+ }
632
+ return combine2(makeDraggable(), dropTarget);
620
633
  }, [
621
- _draggable,
634
+ draggableProp,
635
+ isItemDraggable,
636
+ isItemDroppable,
622
637
  item,
623
638
  id,
624
639
  mode,
@@ -678,33 +693,46 @@ var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _dragg
678
693
  handleOpenToggle,
679
694
  handleSelect
680
695
  ]);
696
+ const handleItemHover = useCallback3(() => {
697
+ onItemHover?.({
698
+ item
699
+ });
700
+ }, [
701
+ onItemHover,
702
+ item
703
+ ]);
704
+ const handleContextMenu = useCallback3((event) => {
705
+ event.preventDefault();
706
+ setMenuOpen(true);
707
+ }, [
708
+ setMenuOpen
709
+ ]);
710
+ const childProps = {
711
+ draggable: draggableProp,
712
+ renderColumns: Columns,
713
+ blockInstruction,
714
+ canDrop,
715
+ canSelect,
716
+ onItemHover,
717
+ onOpenChange,
718
+ onSelect
719
+ };
681
720
  return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Treegrid.Row, {
682
721
  ref: rowRef,
683
722
  key: id,
684
723
  id,
685
724
  "aria-labelledby": `${id}__label`,
686
725
  parentOf: parentOf?.join(Treegrid.PARENT_OF_SEPARATOR),
687
- classNames: [
688
- "grid grid-cols-subgrid col-[tree-row] mbs-0.5 aria-[current]:bg-activeSurface",
689
- hoverableControls,
690
- hoverableFocusedKeyboardControls,
691
- hoverableFocusedWithinControls,
692
- hoverableDescriptionIcons,
693
- ghostHover,
694
- ghostFocusWithin,
695
- className
696
- ],
697
726
  "data-object-id": id,
698
727
  "data-testid": testId,
699
728
  // NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
700
729
  // without alerting the user (except for in the correct link element). See also:
701
730
  // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
702
731
  "aria-current": current ? "" : void 0,
732
+ classNames: mx4("grid grid-cols-subgrid col-[tree-row] mt-0.5 is-current:bg-active-surface", hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, hoverableDescriptionIcons, ghostFocusWithin, ghostHover, className),
703
733
  onKeyDown: handleKeyDown,
704
- onContextMenu: (event) => {
705
- event.preventDefault();
706
- setMenuOpen(true);
707
- }
734
+ onMouseEnter: handleItemHover,
735
+ onContextMenu: handleContextMenu
708
736
  }, /* @__PURE__ */ React7.createElement("div", {
709
737
  role: "none",
710
738
  className: "indent relative grid grid-cols-subgrid col-[tree-row]",
@@ -733,36 +761,31 @@ var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _dragg
733
761
  }), instruction && /* @__PURE__ */ React7.createElement(NaturalTreeItem.DropIndicator, {
734
762
  instruction,
735
763
  gap: 2
736
- }))), open && items.map((item2, index) => /* @__PURE__ */ React7.createElement(TreeItem, {
737
- key: item2.id,
738
- item: item2,
764
+ }))), open && childIds.map((childId, index) => /* @__PURE__ */ React7.createElement(TreeItemById, {
765
+ key: childId,
766
+ id: childId,
739
767
  path,
740
- last: index === items.length - 1,
741
- draggable: _draggable,
742
- renderColumns: Columns,
743
- blockInstruction,
744
- canDrop,
745
- canSelect,
746
- onOpenChange,
747
- onSelect
768
+ last: index === childIds.length - 1,
769
+ ...childProps
748
770
  })));
749
771
  };
750
772
  var TreeItem = /* @__PURE__ */ memo3(RawTreeItem);
773
+ var RawTreeItemById = ({ id, ...props }) => {
774
+ const { item: itemAtom } = useTree();
775
+ const item = useAtomValue(itemAtom(id));
776
+ if (!item) {
777
+ return null;
778
+ }
779
+ return /* @__PURE__ */ React7.createElement(TreeItem, {
780
+ item,
781
+ ...props
782
+ });
783
+ };
784
+ var TreeItemById = /* @__PURE__ */ memo3(RawTreeItemById);
751
785
 
752
786
  // src/components/Tree/Tree.tsx
753
- var Tree = ({ root, path, id, useItems, getProps, useIsOpen, useIsCurrent, draggable: draggable3 = false, gridTemplateColumns = "[tree-row-start] 1fr min-content [tree-row-end]", classNames, levelOffset, renderColumns, blockInstruction, canDrop, canSelect, onOpenChange, onSelect }) => {
754
- const context = useMemo2(() => ({
755
- useItems,
756
- getProps,
757
- useIsOpen,
758
- useIsCurrent
759
- }), [
760
- useItems,
761
- getProps,
762
- useIsOpen,
763
- useIsCurrent
764
- ]);
765
- const items = useItems(root);
787
+ var Tree = ({ model, rootId, path, id, draggable: draggable3 = false, gridTemplateColumns = "[tree-row-start] 1fr min-content [tree-row-end]", classNames, levelOffset, renderColumns, blockInstruction, canDrop, canSelect, onOpenChange, onSelect, onItemHover }) => {
788
+ const childIds = useAtomValue2(model.childIds(rootId));
766
789
  const treePath = useMemo2(() => path ? [
767
790
  ...path,
768
791
  id
@@ -772,15 +795,7 @@ var Tree = ({ root, path, id, useItems, getProps, useIsOpen, useIsCurrent, dragg
772
795
  id,
773
796
  path
774
797
  ]);
775
- return /* @__PURE__ */ React8.createElement(Treegrid2.Root, {
776
- gridTemplateColumns,
777
- classNames
778
- }, /* @__PURE__ */ React8.createElement(TreeProvider, {
779
- value: context
780
- }, items.map((item, index) => /* @__PURE__ */ React8.createElement(TreeItem, {
781
- key: item.id,
782
- item,
783
- last: index === items.length - 1,
798
+ const childProps = {
784
799
  path: treePath,
785
800
  levelOffset,
786
801
  draggable: draggable3,
@@ -789,7 +804,19 @@ var Tree = ({ root, path, id, useItems, getProps, useIsOpen, useIsCurrent, dragg
789
804
  canDrop,
790
805
  canSelect,
791
806
  onOpenChange,
792
- onSelect
807
+ onSelect,
808
+ onItemHover
809
+ };
810
+ return /* @__PURE__ */ React8.createElement(Treegrid2.Root, {
811
+ gridTemplateColumns,
812
+ classNames
813
+ }, /* @__PURE__ */ React8.createElement(TreeProvider, {
814
+ value: model
815
+ }, childIds.map((childId, index) => /* @__PURE__ */ React8.createElement(TreeItemById, {
816
+ key: childId,
817
+ id: childId,
818
+ last: index === childIds.length - 1,
819
+ ...childProps
793
820
  }))));
794
821
  };
795
822
 
@@ -810,13 +837,17 @@ var Path = {
810
837
  };
811
838
  export {
812
839
  Accordion,
840
+ DEFAULT_INDENTATION,
813
841
  List,
814
842
  Path,
815
843
  Tree,
816
844
  TreeDataSchema,
817
845
  TreeItem,
846
+ TreeItemById,
847
+ TreeItemToggle,
818
848
  TreeProvider,
819
849
  isTreeData,
850
+ paddingIndentation,
820
851
  useTree
821
852
  };
822
853
  //# sourceMappingURL=index.mjs.map