@dxos/react-ui-list 0.8.4-main.dedc0f3 → 0.8.4-main.ead640a

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 (38) hide show
  1. package/dist/lib/browser/index.mjs +56 -44
  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 +56 -44
  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/Accordion/Accordion.stories.d.ts +0 -1
  8. package/dist/types/src/components/Accordion/Accordion.stories.d.ts.map +1 -1
  9. package/dist/types/src/components/List/List.stories.d.ts +3 -1
  10. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/List/testing.d.ts +1 -1
  12. package/dist/types/src/components/List/testing.d.ts.map +1 -1
  13. package/dist/types/src/components/Tree/Tree.d.ts +3 -3
  14. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  15. package/dist/types/src/components/Tree/Tree.stories.d.ts +2 -3
  16. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Tree/TreeContext.d.ts +3 -2
  18. package/dist/types/src/components/Tree/TreeContext.d.ts.map +1 -1
  19. package/dist/types/src/components/Tree/TreeItem.d.ts +6 -2
  20. package/dist/types/src/components/Tree/TreeItem.d.ts.map +1 -1
  21. package/dist/types/src/components/Tree/TreeItemHeading.d.ts +4 -3
  22. package/dist/types/src/components/Tree/TreeItemHeading.d.ts.map +1 -1
  23. package/dist/types/src/components/Tree/TreeItemToggle.d.ts +3 -3
  24. package/dist/types/src/components/Tree/TreeItemToggle.d.ts.map +1 -1
  25. package/dist/types/src/components/Tree/testing.d.ts +2 -2
  26. package/dist/types/src/components/Tree/testing.d.ts.map +1 -1
  27. package/dist/types/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +24 -24
  29. package/src/components/Accordion/Accordion.stories.tsx +2 -4
  30. package/src/components/List/List.stories.tsx +6 -5
  31. package/src/components/List/testing.ts +2 -2
  32. package/src/components/Tree/Tree.stories.tsx +3 -4
  33. package/src/components/Tree/Tree.tsx +7 -2
  34. package/src/components/Tree/TreeContext.tsx +3 -2
  35. package/src/components/Tree/TreeItem.tsx +38 -29
  36. package/src/components/Tree/TreeItemHeading.tsx +6 -5
  37. package/src/components/Tree/TreeItemToggle.tsx +29 -18
  38. package/src/components/Tree/testing.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-list",
3
- "version": "0.8.4-main.dedc0f3",
3
+ "version": "0.8.4-main.ead640a",
4
4
  "description": "A list component.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -27,36 +27,36 @@
27
27
  "@atlaskit/pragmatic-drag-and-drop": "^1.4.0",
28
28
  "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
29
29
  "@preact-signals/safe-react": "^0.9.0",
30
- "@preact/signals-core": "^1.9.0",
30
+ "@preact/signals-core": "^1.12.1",
31
31
  "@radix-ui/react-accordion": "1.2.3",
32
32
  "@radix-ui/react-context": "1.1.1",
33
- "@dxos/debug": "0.8.4-main.dedc0f3",
34
- "@dxos/invariant": "0.8.4-main.dedc0f3",
35
- "@dxos/echo-schema": "0.8.4-main.dedc0f3",
36
- "@dxos/live-object": "0.8.4-main.dedc0f3",
37
- "@dxos/log": "0.8.4-main.dedc0f3",
38
- "@dxos/react-ui": "0.8.4-main.dedc0f3",
39
- "@dxos/react-ui-text-tooltip": "0.8.4-main.dedc0f3",
40
- "@dxos/react-ui-theme": "0.8.4-main.dedc0f3",
41
- "@dxos/util": "0.8.4-main.dedc0f3",
42
- "@dxos/react-ui-types": "0.8.4-main.dedc0f3"
33
+ "@dxos/debug": "0.8.4-main.ead640a",
34
+ "@dxos/invariant": "0.8.4-main.ead640a",
35
+ "@dxos/react-ui": "0.8.4-main.ead640a",
36
+ "@dxos/log": "0.8.4-main.ead640a",
37
+ "@dxos/live-object": "0.8.4-main.ead640a",
38
+ "@dxos/react-ui-text-tooltip": "0.8.4-main.ead640a",
39
+ "@dxos/react-ui-theme": "0.8.4-main.ead640a",
40
+ "@dxos/react-ui-types": "0.8.4-main.ead640a",
41
+ "@dxos/echo": "0.8.4-main.ead640a",
42
+ "@dxos/util": "0.8.4-main.ead640a"
43
43
  },
44
44
  "devDependencies": {
45
- "@types/react": "~18.2.0",
46
- "@types/react-dom": "~18.2.0",
47
- "effect": "3.17.7",
48
- "react": "~18.2.0",
49
- "react-dom": "~18.2.0",
50
- "vite": "7.1.1",
51
- "@dxos/storybook-utils": "0.8.4-main.dedc0f3",
52
- "@dxos/random": "0.8.4-main.dedc0f3"
45
+ "@types/react": "~19.2.2",
46
+ "@types/react-dom": "~19.2.1",
47
+ "effect": "3.18.3",
48
+ "react": "~19.2.0",
49
+ "react-dom": "~19.2.0",
50
+ "vite": "7.1.9",
51
+ "@dxos/storybook-utils": "0.8.4-main.ead640a",
52
+ "@dxos/random": "0.8.4-main.ead640a"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "effect": "^3.13.3",
56
- "react": "~18.2.0",
57
- "react-dom": "~18.2.0",
58
- "@dxos/react-ui": "0.8.4-main.dedc0f3",
59
- "@dxos/react-ui-theme": "0.8.4-main.dedc0f3"
56
+ "react": "^19.0.0",
57
+ "react-dom": "^19.0.0",
58
+ "@dxos/react-ui": "0.8.4-main.ead640a",
59
+ "@dxos/react-ui-theme": "0.8.4-main.ead640a"
60
60
  },
61
61
  "publishConfig": {
62
62
  "access": "public"
@@ -2,13 +2,11 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React from 'react';
9
7
 
10
8
  import { faker } from '@dxos/random';
11
- import { withLayout, withTheme } from '@dxos/storybook-utils';
9
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
12
10
 
13
11
  import { Accordion } from './Accordion';
14
12
 
@@ -44,7 +42,7 @@ const DefaultStory = () => {
44
42
  const meta = {
45
43
  title: 'ui/react-ui-list/Accordion',
46
44
  render: DefaultStory,
47
- decorators: [withTheme, withLayout({ fullscreen: true, classNames: 'flex justify-center' })],
45
+ decorators: [withTheme, withLayout({ container: 'column' })],
48
46
  } satisfies Meta<typeof Accordion>;
49
47
 
50
48
  export default meta;
@@ -2,15 +2,13 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
- import { Schema } from 'effect';
6
+ import * as Schema from 'effect/Schema';
9
7
  import React from 'react';
10
8
 
11
9
  import { live } from '@dxos/live-object';
10
+ import { withTheme } from '@dxos/react-ui/testing';
12
11
  import { ghostHover, mx } from '@dxos/react-ui-theme';
13
- import { withLayout, withTheme } from '@dxos/storybook-utils';
14
12
  import { arrayMove } from '@dxos/util';
15
13
 
16
14
  import { List, type ListRootProps } from './List';
@@ -94,7 +92,10 @@ const list = live(createList(100));
94
92
  const meta = {
95
93
  title: 'ui/react-ui-list/List',
96
94
  component: List.Root,
97
- decorators: [withTheme, withLayout({ fullscreen: true })],
95
+ decorators: [withTheme],
96
+ parameters: {
97
+ layout: 'fullscreen',
98
+ },
98
99
  } satisfies Meta<typeof List.Root>;
99
100
 
100
101
  export default meta;
@@ -2,9 +2,9 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
- import { ObjectId } from '@dxos/echo-schema';
7
+ import { ObjectId } from '@dxos/echo/internal';
8
8
  import { faker } from '@dxos/random';
9
9
 
10
10
  export const TestItemSchema = Schema.Struct({
@@ -2,8 +2,6 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
8
6
  import { type Instruction, extractInstruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
9
7
  import { type Meta, type StoryObj } from '@storybook/react-vite';
@@ -12,7 +10,7 @@ import React, { useEffect } from 'react';
12
10
  import { type Live, live } from '@dxos/live-object';
13
11
  import { faker } from '@dxos/random';
14
12
  import { Icon } from '@dxos/react-ui';
15
- import { withLayout, withTheme } from '@dxos/storybook-utils';
13
+ import { withTheme } from '@dxos/react-ui/testing';
16
14
 
17
15
  import { Path } from '../../util';
18
16
 
@@ -54,9 +52,10 @@ const state = new Map<string, Live<{ open: boolean; current: boolean }>>();
54
52
 
55
53
  const meta = {
56
54
  title: 'ui/react-ui-list/Tree',
55
+
56
+ decorators: [withTheme],
57
57
  component: Tree,
58
58
  render: DefaultStory,
59
- decorators: [withTheme, withLayout()],
60
59
  args: {
61
60
  id: tree.id,
62
61
  useItems: (parent?: TestItem) => {
@@ -4,7 +4,7 @@
4
4
 
5
5
  import React, { useMemo } from 'react';
6
6
 
7
- import { type HasId } from '@dxos/echo-schema';
7
+ import { type HasId } from '@dxos/echo/internal';
8
8
  import { Treegrid, type TreegridRootProps } from '@dxos/react-ui';
9
9
 
10
10
  import { type TreeContextType, TreeProvider } from './TreeContext';
@@ -16,7 +16,10 @@ export type TreeProps<T extends HasId = any, O = any> = {
16
16
  id: string;
17
17
  } & TreeContextType<T, O> &
18
18
  Partial<Pick<TreegridRootProps, 'gridTemplateColumns' | 'classNames'>> &
19
- Pick<TreeItemProps<T>, 'draggable' | 'renderColumns' | 'canDrop' | 'onOpenChange' | 'onSelect' | 'levelOffset'>;
19
+ Pick<
20
+ TreeItemProps<T>,
21
+ 'draggable' | 'renderColumns' | 'canDrop' | 'canSelect' | 'onOpenChange' | 'onSelect' | 'levelOffset'
22
+ >;
20
23
 
21
24
  export const Tree = <T extends HasId = any, O = any>({
22
25
  root,
@@ -32,6 +35,7 @@ export const Tree = <T extends HasId = any, O = any>({
32
35
  levelOffset,
33
36
  renderColumns,
34
37
  canDrop,
38
+ canSelect,
35
39
  onOpenChange,
36
40
  onSelect,
37
41
  }: TreeProps<T, O>) => {
@@ -60,6 +64,7 @@ export const Tree = <T extends HasId = any, O = any>({
60
64
  draggable={draggable}
61
65
  renderColumns={renderColumns}
62
66
  canDrop={canDrop}
67
+ canSelect={canSelect}
63
68
  onOpenChange={onOpenChange}
64
69
  onSelect={onSelect}
65
70
  />
@@ -11,10 +11,11 @@ export type TreeItemDataProps = {
11
11
  id: string;
12
12
  label: Label;
13
13
  parentOf?: string[];
14
- icon?: string;
15
- disabled?: boolean;
16
14
  className?: string;
17
15
  headingClassName?: string;
16
+ icon?: string;
17
+ iconClassName?: string;
18
+ disabled?: boolean;
18
19
  testId?: string;
19
20
  };
20
21
 
@@ -10,13 +10,14 @@ import {
10
10
  attachInstruction,
11
11
  extractInstruction,
12
12
  } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
13
- import { Schema } from 'effect';
13
+ import * as Schema from 'effect/Schema';
14
14
  import React, { type FC, type KeyboardEvent, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
15
15
 
16
- import { type HasId } from '@dxos/echo-schema';
16
+ import { type HasId } from '@dxos/echo/internal';
17
17
  import { invariant } from '@dxos/invariant';
18
18
  import { TreeItem as NaturalTreeItem, Treegrid } from '@dxos/react-ui';
19
19
  import {
20
+ ghostFocusWithin,
20
21
  ghostHover,
21
22
  hoverableControls,
22
23
  hoverableFocusedKeyboardControls,
@@ -28,11 +29,11 @@ import { useTree } from './TreeContext';
28
29
  import { TreeItemHeading } from './TreeItemHeading';
29
30
  import { TreeItemToggle } from './TreeItemToggle';
30
31
 
31
- type TreeItemState = 'idle' | 'dragging' | 'preview' | 'parent-of-instruction';
32
-
33
32
  const hoverableDescriptionIcons =
34
33
  '[--icons-color:inherit] hover-hover:[--icons-color:var(--description-text)] hover-hover:hover:[--icons-color:inherit] focus-within:[--icons-color:inherit]';
35
34
 
35
+ type TreeItemState = 'idle' | 'dragging' | 'preview' | 'parent-of-instruction';
36
+
36
37
  export const TreeDataSchema = Schema.Struct({
37
38
  id: Schema.String,
38
39
  path: Schema.Array(Schema.String),
@@ -58,6 +59,7 @@ export type TreeItemProps<T extends HasId = any> = {
58
59
  draggable?: boolean;
59
60
  renderColumns?: ColumnRenderer<T>;
60
61
  canDrop?: (params: { source: TreeData; target: TreeData }) => boolean;
62
+ canSelect?: (params: { item: T; path: string[] }) => boolean;
61
63
  onOpenChange?: (params: { item: T; path: string[]; open: boolean }) => void;
62
64
  onSelect?: (params: { item: T; path: string[]; current: boolean; option: boolean }) => void;
63
65
  };
@@ -65,13 +67,14 @@ export type TreeItemProps<T extends HasId = any> = {
65
67
  const RawTreeItem = <T extends HasId = any>({
66
68
  item,
67
69
  path: _path,
70
+ levelOffset = 2,
68
71
  last,
69
72
  draggable: _draggable,
70
73
  renderColumns: Columns,
71
74
  canDrop,
75
+ canSelect,
72
76
  onOpenChange,
73
77
  onSelect,
74
- levelOffset = 2,
75
78
  }: TreeItemProps<T>) => {
76
79
  const rowRef = useRef<HTMLDivElement | null>(null);
77
80
  const buttonRef = useRef<HTMLButtonElement | null>(null);
@@ -83,13 +86,17 @@ const RawTreeItem = <T extends HasId = any>({
83
86
 
84
87
  const { useItems, getProps, isOpen, isCurrent } = useTree();
85
88
  const items = useItems(item);
86
- const { id, label, parentOf, icon, disabled, className, headingClassName, testId } = getProps(item, _path);
89
+ const { id, parentOf, label, className, headingClassName, icon, iconClassName, disabled, testId } = getProps(
90
+ item,
91
+ _path,
92
+ );
87
93
  const path = useMemo(() => [..._path, id], [_path, id]);
88
94
  const open = isOpen(path, item);
89
95
  const current = isCurrent(path, item);
90
96
  const level = path.length - levelOffset;
91
97
  const isBranch = !!parentOf;
92
98
  const mode: ItemMode = last ? 'last-in-group' : open ? 'expanded' : 'standard';
99
+ const canSelectItem = canSelect?.({ item, path }) ?? true;
93
100
 
94
101
  const cancelExpand = useCallback(() => {
95
102
  if (cancelExpandRef.current) {
@@ -181,38 +188,37 @@ const RawTreeItem = <T extends HasId = any>({
181
188
  // Cancel expand on unmount.
182
189
  useEffect(() => () => cancelExpand(), [cancelExpand]);
183
190
 
184
- const handleOpenChange = useCallback(
191
+ const handleOpenToggle = useCallback(
185
192
  () => onOpenChange?.({ item, path, open: !open }),
186
193
  [onOpenChange, item, path, open],
187
194
  );
188
195
 
189
196
  const handleSelect = useCallback(
190
197
  (option = false) => {
191
- if (isBranch) {
192
- handleOpenChange();
193
- } else {
198
+ // If the item is a branch, toggle it if:
199
+ // - also holding down the option key
200
+ // - or the item is currently selected
201
+ if (isBranch && (option || current)) {
202
+ handleOpenToggle();
203
+ } else if (canSelectItem) {
204
+ canSelect?.({ item, path });
194
205
  rowRef.current?.focus();
195
206
  onSelect?.({ item, path, current: !current, option });
196
207
  }
197
208
  },
198
- [item, path, current, isBranch, handleOpenChange, onSelect],
209
+ [item, path, current, isBranch, canSelectItem, handleOpenToggle, onSelect],
199
210
  );
200
211
 
201
212
  const handleKeyDown = useCallback(
202
213
  (event: KeyboardEvent) => {
203
214
  switch (event.key) {
204
215
  case 'ArrowRight':
205
- isBranch && !open && handleOpenChange();
206
- break;
207
216
  case 'ArrowLeft':
208
- isBranch && open && handleOpenChange();
209
- break;
210
- case ' ':
211
- handleSelect(event.altKey);
217
+ isBranch && handleOpenToggle();
212
218
  break;
213
219
  }
214
220
  },
215
- [isBranch, open, handleOpenChange, handleSelect],
221
+ [isBranch, open, handleOpenToggle, handleSelect],
216
222
  );
217
223
 
218
224
  return (
@@ -230,6 +236,7 @@ const RawTreeItem = <T extends HasId = any>({
230
236
  hoverableFocusedWithinControls,
231
237
  hoverableDescriptionIcons,
232
238
  ghostHover,
239
+ ghostFocusWithin,
233
240
  className,
234
241
  ]}
235
242
  data-itemid={id}
@@ -244,26 +251,27 @@ const RawTreeItem = <T extends HasId = any>({
244
251
  setMenuOpen(true);
245
252
  }}
246
253
  >
247
- <Treegrid.Cell
248
- indent
249
- classNames='relative grid grid-cols-subgrid col-[tree-row]'
254
+ <div
255
+ role='none'
256
+ className='indent relative grid grid-cols-subgrid col-[tree-row]'
250
257
  style={paddingIndentation(level)}
251
258
  >
252
- <div role='none' className='flex items-center'>
253
- <TreeItemToggle isBranch={isBranch} open={open} onToggle={handleOpenChange} />
259
+ <Treegrid.Cell classNames='flex items-center'>
260
+ <TreeItemToggle isBranch={isBranch} open={open} onClick={handleOpenToggle} />
254
261
  <TreeItemHeading
255
- ref={buttonRef}
256
- label={label}
257
- icon={icon}
258
- className={headingClassName}
259
262
  disabled={disabled}
260
263
  current={current}
264
+ label={label}
265
+ className={headingClassName}
266
+ icon={icon}
267
+ iconClassName={iconClassName}
261
268
  onSelect={handleSelect}
269
+ ref={buttonRef}
262
270
  />
263
- </div>
271
+ </Treegrid.Cell>
264
272
  {Columns && <Columns item={item} path={path} open={open} menuOpen={menuOpen} setMenuOpen={setMenuOpen} />}
265
273
  {instruction && <NaturalTreeItem.DropIndicator instruction={instruction} gap={2} />}
266
- </Treegrid.Cell>
274
+ </div>
267
275
  </Treegrid.Row>
268
276
  {open &&
269
277
  items.map((item, index) => (
@@ -275,6 +283,7 @@ const RawTreeItem = <T extends HasId = any>({
275
283
  draggable={_draggable}
276
284
  renderColumns={Columns}
277
285
  canDrop={canDrop}
286
+ canSelect={canSelect}
278
287
  onOpenChange={onOpenChange}
279
288
  onSelect={onSelect}
280
289
  />
@@ -9,18 +9,19 @@ import { TextTooltip } from '@dxos/react-ui-text-tooltip';
9
9
 
10
10
  // TODO(wittjosiah): Consider whether there should be a separate disabled prop which was visually distinct
11
11
  // rather than just making the item unselectable.
12
- export type NavTreeItemHeadingProps = {
12
+ export type TreeItemHeadingProps = {
13
13
  label: Label;
14
- icon?: string;
15
14
  className?: string;
15
+ icon?: string;
16
+ iconClassName?: string;
16
17
  disabled?: boolean;
17
18
  current?: boolean;
18
19
  onSelect?: (option: boolean) => void;
19
20
  };
20
21
 
21
22
  export const TreeItemHeading = memo(
22
- forwardRef<HTMLButtonElement, NavTreeItemHeadingProps>(
23
- ({ label, icon, className, disabled, current, onSelect }, forwardedRef) => {
23
+ forwardRef<HTMLButtonElement, TreeItemHeadingProps>(
24
+ ({ label, className, icon, iconClassName, disabled, current, onSelect }, forwardedRef) => {
24
25
  const { t } = useTranslation();
25
26
 
26
27
  const handleSelect = useCallback(
@@ -64,7 +65,7 @@ export const TreeItemHeading = memo(
64
65
  onKeyDown={handleButtonKeydown}
65
66
  {...(current && { 'aria-current': 'location' })}
66
67
  >
67
- {icon && <Icon icon={icon ?? 'ph--placeholder--regular'} size={5} classNames='mlb-1' />}
68
+ {icon && <Icon icon={icon ?? 'ph--placeholder--regular'} size={5} classNames={['mlb-1', iconClassName]} />}
68
69
  <span className='flex-1 is-0 truncate text-start text-sm font-normal' data-tooltip>
69
70
  {toLocalizedString(label, t)}
70
71
  </span>
@@ -4,29 +4,40 @@
4
4
 
5
5
  import React, { forwardRef, memo } from 'react';
6
6
 
7
- import { Button, Icon } from '@dxos/react-ui';
7
+ import { IconButton, type IconButtonProps } from '@dxos/react-ui';
8
8
 
9
- export type TreeItemToggleProps = {
9
+ export type TreeItemToggleProps = Omit<IconButtonProps, 'icon' | 'size' | 'label'> & {
10
10
  open?: boolean;
11
11
  isBranch?: boolean;
12
- onToggle?: () => void;
13
12
  hidden?: boolean;
14
13
  };
15
14
 
16
15
  export const TreeItemToggle = memo(
17
- forwardRef<HTMLButtonElement, TreeItemToggleProps>(({ open, isBranch, hidden, onToggle }, forwardedRef) => {
18
- return (
19
- <Button
20
- ref={forwardedRef}
21
- data-testid='treeItem.toggle'
22
- aria-expanded={open}
23
- variant='ghost'
24
- density='fine'
25
- classNames={['is-6 pli-0 dx-focus-ring-inset', hidden ? 'hidden' : !isBranch && 'invisible']}
26
- onClick={onToggle}
27
- >
28
- <Icon icon='ph--caret-right--bold' size={3} classNames={['transition duration-200', open && 'rotate-90']} />
29
- </Button>
30
- );
31
- }),
16
+ forwardRef<HTMLButtonElement, TreeItemToggleProps>(
17
+ ({ open, isBranch, hidden, classNames, ...props }, forwardedRef) => {
18
+ return (
19
+ <IconButton
20
+ ref={forwardedRef}
21
+ data-testid='treeItem.toggle'
22
+ aria-expanded={open}
23
+ variant='ghost'
24
+ density='fine'
25
+ classNames={[
26
+ 'bs-full is-6 pli-0',
27
+ '[&_svg]:transition-[transform] [&_svg]:duration-200',
28
+ open && '[&_svg]:rotate-90',
29
+ hidden ? 'hidden' : !isBranch && 'invisible',
30
+ classNames,
31
+ ]}
32
+ size={3}
33
+ icon='ph--caret-right--bold'
34
+ iconOnly
35
+ noTooltip
36
+ label={open ? 'Click to close' : 'Click to open'}
37
+ tabIndex={-1}
38
+ {...props}
39
+ />
40
+ );
41
+ },
42
+ ),
32
43
  );
@@ -3,9 +3,9 @@
3
3
  //
4
4
 
5
5
  import { type Instruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
6
- import { Schema } from 'effect';
6
+ import * as Schema from 'effect/Schema';
7
7
 
8
- import { type HasId, ObjectId } from '@dxos/echo-schema';
8
+ import { type HasId, ObjectId } from '@dxos/echo/internal';
9
9
  import { log } from '@dxos/log';
10
10
  import { faker } from '@dxos/random';
11
11