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