@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.
- package/dist/lib/browser/index.mjs +56 -44
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +56 -44
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/Accordion/Accordion.stories.d.ts +0 -1
- package/dist/types/src/components/Accordion/Accordion.stories.d.ts.map +1 -1
- package/dist/types/src/components/List/List.stories.d.ts +3 -1
- package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
- package/dist/types/src/components/List/testing.d.ts +1 -1
- package/dist/types/src/components/List/testing.d.ts.map +1 -1
- package/dist/types/src/components/Tree/Tree.d.ts +3 -3
- package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
- package/dist/types/src/components/Tree/Tree.stories.d.ts +2 -3
- package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
- package/dist/types/src/components/Tree/TreeContext.d.ts +3 -2
- package/dist/types/src/components/Tree/TreeContext.d.ts.map +1 -1
- package/dist/types/src/components/Tree/TreeItem.d.ts +6 -2
- package/dist/types/src/components/Tree/TreeItem.d.ts.map +1 -1
- package/dist/types/src/components/Tree/TreeItemHeading.d.ts +4 -3
- package/dist/types/src/components/Tree/TreeItemHeading.d.ts.map +1 -1
- package/dist/types/src/components/Tree/TreeItemToggle.d.ts +3 -3
- package/dist/types/src/components/Tree/TreeItemToggle.d.ts.map +1 -1
- package/dist/types/src/components/Tree/testing.d.ts +2 -2
- package/dist/types/src/components/Tree/testing.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -24
- package/src/components/Accordion/Accordion.stories.tsx +2 -4
- package/src/components/List/List.stories.tsx +6 -5
- package/src/components/List/testing.ts +2 -2
- package/src/components/Tree/Tree.stories.tsx +3 -4
- package/src/components/Tree/Tree.tsx +7 -2
- package/src/components/Tree/TreeContext.tsx +3 -2
- package/src/components/Tree/TreeItem.tsx +38 -29
- package/src/components/Tree/TreeItemHeading.tsx +6 -5
- package/src/components/Tree/TreeItemToggle.tsx +29 -18
- 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.
|
|
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.
|
|
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.
|
|
34
|
-
"@dxos/invariant": "0.8.4-main.
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
39
|
-
"@dxos/react-ui-
|
|
40
|
-
"@dxos/react-ui-
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/
|
|
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": "~
|
|
46
|
-
"@types/react-dom": "~
|
|
47
|
-
"effect": "3.
|
|
48
|
-
"react": "~
|
|
49
|
-
"react-dom": "~
|
|
50
|
-
"vite": "7.1.
|
|
51
|
-
"@dxos/storybook-utils": "0.8.4-main.
|
|
52
|
-
"@dxos/random": "0.8.4-main.
|
|
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": "
|
|
57
|
-
"react-dom": "
|
|
58
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
59
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
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/
|
|
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({
|
|
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
|
|
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
|
|
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
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
6
|
|
|
7
|
-
import { ObjectId } from '@dxos/echo
|
|
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 {
|
|
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
|
|
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<
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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,
|
|
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 &&
|
|
209
|
-
break;
|
|
210
|
-
case ' ':
|
|
211
|
-
handleSelect(event.altKey);
|
|
217
|
+
isBranch && handleOpenToggle();
|
|
212
218
|
break;
|
|
213
219
|
}
|
|
214
220
|
},
|
|
215
|
-
[isBranch, open,
|
|
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
|
-
<
|
|
248
|
-
|
|
249
|
-
|
|
254
|
+
<div
|
|
255
|
+
role='none'
|
|
256
|
+
className='indent relative grid grid-cols-subgrid col-[tree-row]'
|
|
250
257
|
style={paddingIndentation(level)}
|
|
251
258
|
>
|
|
252
|
-
<
|
|
253
|
-
<TreeItemToggle isBranch={isBranch} open={open}
|
|
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
|
-
</
|
|
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
|
-
</
|
|
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
|
|
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,
|
|
23
|
-
({ label, icon,
|
|
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 {
|
|
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>(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
|
6
|
+
import * as Schema from 'effect/Schema';
|
|
7
7
|
|
|
8
|
-
import { type HasId, ObjectId } from '@dxos/echo
|
|
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
|
|