@dxos/react-ui-list 0.7.1 → 0.7.2-main.f1adc9f

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 (42) hide show
  1. package/dist/lib/browser/index.mjs +149 -87
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +180 -116
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +149 -87
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/List/DropIndicator.d.ts +5 -4
  11. package/dist/types/src/components/List/DropIndicator.d.ts.map +1 -1
  12. package/dist/types/src/components/Tree/DropIndicator.d.ts +2 -1
  13. package/dist/types/src/components/Tree/DropIndicator.d.ts.map +1 -1
  14. package/dist/types/src/components/Tree/Tree.d.ts +4 -19
  15. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  16. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Tree/TreeContext.d.ts +20 -0
  18. package/dist/types/src/components/Tree/TreeContext.d.ts.map +1 -0
  19. package/dist/types/src/components/Tree/TreeItem.d.ts +26 -24
  20. package/dist/types/src/components/Tree/TreeItem.d.ts.map +1 -1
  21. package/dist/types/src/components/Tree/TreeItemHeading.d.ts +1 -1
  22. package/dist/types/src/components/Tree/TreeItemHeading.d.ts.map +1 -1
  23. package/dist/types/src/components/Tree/helpers.d.ts +0 -3
  24. package/dist/types/src/components/Tree/helpers.d.ts.map +1 -1
  25. package/dist/types/src/components/Tree/index.d.ts +1 -1
  26. package/dist/types/src/components/Tree/index.d.ts.map +1 -1
  27. package/dist/types/src/components/Tree/testing.d.ts +3 -6
  28. package/dist/types/src/components/Tree/testing.d.ts.map +1 -1
  29. package/package.json +16 -18
  30. package/src/components/List/DropIndicator.tsx +7 -2
  31. package/src/components/Tree/DropIndicator.tsx +7 -8
  32. package/src/components/Tree/Tree.stories.tsx +71 -70
  33. package/src/components/Tree/Tree.tsx +29 -24
  34. package/src/components/Tree/TreeContext.tsx +32 -0
  35. package/src/components/Tree/TreeItem.tsx +122 -83
  36. package/src/components/Tree/TreeItemHeading.tsx +14 -5
  37. package/src/components/Tree/helpers.ts +0 -16
  38. package/src/components/Tree/index.ts +1 -1
  39. package/src/components/Tree/testing.ts +4 -73
  40. package/dist/types/src/components/Tree/types.d.ts +0 -18
  41. package/dist/types/src/components/Tree/types.d.ts.map +0 -1
  42. package/src/components/Tree/types.ts +0 -34
@@ -3,7 +3,10 @@
3
3
  //
4
4
 
5
5
  import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
6
- import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
6
+ import {
7
+ draggable as pragmaticDraggable,
8
+ dropTargetForElements,
9
+ } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
7
10
  // https://github.com/atlassian/pragmatic-drag-and-drop/blob/main/packages/hitbox/constellation/index/about.mdx
8
11
  import {
9
12
  attachInstruction,
@@ -11,8 +14,9 @@ import {
11
14
  type Instruction,
12
15
  type ItemMode,
13
16
  } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
14
- import React, { memo, useCallback, useEffect, useRef, useState, type FC, type KeyboardEvent } from 'react';
17
+ import React, { memo, useCallback, useEffect, useMemo, useRef, useState, type FC, type KeyboardEvent } from 'react';
15
18
 
19
+ import { S } from '@dxos/echo-schema';
16
20
  import { invariant } from '@dxos/invariant';
17
21
  import { Treegrid } from '@dxos/react-ui';
18
22
  import {
@@ -25,44 +29,57 @@ import {
25
29
  } from '@dxos/react-ui-theme';
26
30
 
27
31
  import { DropIndicator } from './DropIndicator';
32
+ import { useTree } from './TreeContext';
28
33
  import { TreeItemHeading } from './TreeItemHeading';
29
34
  import { TreeItemToggle } from './TreeItemToggle';
30
35
  import { DEFAULT_INDENTATION, paddingIndendation } from './helpers';
31
- import { type ItemType } from './types';
32
36
 
33
37
  type TreeItemState = 'idle' | 'dragging' | 'preview' | 'parent-of-instruction';
34
38
 
35
39
  const hoverableDescriptionIcons =
36
40
  '[--icons-color:inherit] hover-hover:[--icons-color:var(--description-text)] hover-hover:hover:[--icons-color:inherit] focus-within:[--icons-color:inherit]';
37
41
 
38
- // TODO(burdon): Make generic?
39
- export type TreeItemProps<T extends ItemType = ItemType> = {
42
+ export const TreeDataSchema = S.Struct({
43
+ id: S.String,
44
+ path: S.Array(S.String),
45
+ item: S.Any,
46
+ });
47
+
48
+ export type TreeData = S.Schema.Type<typeof TreeDataSchema>;
49
+
50
+ export const isTreeData = (data: unknown): data is TreeData => S.is(TreeDataSchema)(data);
51
+
52
+ export type TreeItemProps<T = any> = {
40
53
  item: T;
41
- mode: ItemMode;
42
- open: boolean;
43
- current: boolean;
54
+ path: string[];
55
+ last: boolean;
44
56
  draggable?: boolean;
45
- renderColumns?: FC<{ item: T; menuOpen: boolean; setMenuOpen: (open: boolean) => void }>;
46
- canDrop?: (source: T, target: T) => boolean;
47
- onOpenChange?: (item: T, nextOpen: boolean) => void;
48
- onSelect?: (item: T, nextState: boolean) => void;
57
+ renderColumns?: FC<{ item: T; path: string[]; menuOpen: boolean; setMenuOpen: (open: boolean) => void }>;
58
+ canDrop?: (source: TreeData, target: TreeData) => boolean;
59
+ onOpenChange?: (params: { item: T; path: string[]; open: boolean }) => void;
60
+ onSelect?: (params: { item: T; path: string[]; current: boolean; option: boolean }) => void;
49
61
  };
50
62
 
51
- // TODO(wittjosiah): Styles.
52
- export const RawTreeItem = <T extends ItemType = ItemType>({
63
+ export const RawTreeItem = <T = any,>({
53
64
  item,
54
- mode,
55
- open,
56
- current,
57
- draggable: _draggable,
65
+ path: _path,
66
+ last,
67
+ draggable,
58
68
  renderColumns: Columns,
59
69
  canDrop,
60
70
  onOpenChange,
61
71
  onSelect,
62
72
  }: TreeItemProps<T>) => {
63
- const { id, label, icon, className, headingClassName, disabled, path, parentOf } = item;
73
+ const { getItems, getProps, isOpen, isCurrent } = useTree();
74
+ const items = getItems(item);
75
+ const { id, label, parentOf, icon, disabled, className, headingClassName, testId } = getProps(item, _path);
76
+ const path = useMemo(() => [..._path, id], [_path, id]);
77
+ const open = isOpen(path, item);
78
+ const current = isCurrent(path, item);
64
79
  const level = path.length - 2;
65
80
  const isBranch = !!parentOf;
81
+ const mode: ItemMode = last ? 'last-in-group' : open ? 'expanded' : 'standard';
82
+ const data = useMemo(() => ({ id, path, item }) satisfies TreeData, [id, path, item]);
66
83
 
67
84
  const rowRef = useRef<HTMLDivElement | null>(null);
68
85
  const buttonRef = useRef<HTMLButtonElement | null>(null);
@@ -80,7 +97,7 @@ export const RawTreeItem = <T extends ItemType = ItemType>({
80
97
  }, []);
81
98
 
82
99
  useEffect(() => {
83
- if (!_draggable) {
100
+ if (!draggable) {
84
101
  return;
85
102
  }
86
103
 
@@ -88,27 +105,27 @@ export const RawTreeItem = <T extends ItemType = ItemType>({
88
105
 
89
106
  // https://atlassian.design/components/pragmatic-drag-and-drop/core-package/adapters/element/about
90
107
  return combine(
91
- draggable({
108
+ pragmaticDraggable({
92
109
  element: buttonRef.current,
93
- getInitialData: () => item,
110
+ getInitialData: () => data,
94
111
  onDragStart: () => {
95
112
  setState('dragging');
96
113
  if (open) {
97
114
  openRef.current = true;
98
- onOpenChange?.(item, false);
115
+ onOpenChange?.({ item, path, open: false });
99
116
  }
100
117
  },
101
118
  onDrop: () => {
102
119
  setState('idle');
103
120
  if (openRef.current) {
104
- onOpenChange?.(item, true);
121
+ onOpenChange?.({ item, path, open: true });
105
122
  }
106
123
  },
107
124
  }),
108
125
  dropTargetForElements({
109
126
  element: buttonRef.current,
110
127
  getData: ({ input, element }) => {
111
- return attachInstruction(item, {
128
+ return attachInstruction(data, {
112
129
  input,
113
130
  element,
114
131
  indentPerLevel: DEFAULT_INDENTATION,
@@ -119,16 +136,16 @@ export const RawTreeItem = <T extends ItemType = ItemType>({
119
136
  },
120
137
  canDrop: ({ source }) => {
121
138
  const _canDrop = canDrop ?? (() => true);
122
- return source.element !== buttonRef.current && _canDrop(source.data as T, item);
139
+ return source.element !== buttonRef.current && _canDrop(source.data as TreeData, data);
123
140
  },
124
141
  getIsSticky: () => true,
125
142
  onDrag: ({ self, source }) => {
126
143
  const instruction = extractInstruction(self.data);
127
144
 
128
- if (source.data.id !== item.id) {
145
+ if (source.data.id !== id) {
129
146
  if (instruction?.type === 'make-child' && isBranch && !open && !cancelExpandRef.current) {
130
147
  cancelExpandRef.current = setTimeout(() => {
131
- onOpenChange?.(item, true);
148
+ onOpenChange?.({ item, path, open: true });
132
149
  }, 500);
133
150
  }
134
151
 
@@ -154,17 +171,23 @@ export const RawTreeItem = <T extends ItemType = ItemType>({
154
171
  },
155
172
  }),
156
173
  );
157
- }, [draggable, item, mode, open, canDrop]);
174
+ }, [draggable, item, id, mode, path, open, canDrop]);
158
175
 
159
176
  // Cancel expand on unmount.
160
177
  useEffect(() => () => cancelExpand(), [cancelExpand]);
161
178
 
162
- const handleOpenChange = useCallback(() => onOpenChange?.(item, !open), [onOpenChange, item, open]);
179
+ const handleOpenChange = useCallback(
180
+ () => onOpenChange?.({ item, path, open: !open }),
181
+ [onOpenChange, item, path, open],
182
+ );
163
183
 
164
- const handleSelect = useCallback(() => {
165
- rowRef.current?.focus();
166
- onSelect?.(item, !current);
167
- }, [onSelect, item, current]);
184
+ const handleSelect = useCallback(
185
+ (option = false) => {
186
+ rowRef.current?.focus();
187
+ onSelect?.({ item, path, current: !current, option });
188
+ },
189
+ [onSelect, item, path, current],
190
+ );
168
191
 
169
192
  const handleKeyDown = useCallback(
170
193
  (event: KeyboardEvent) => {
@@ -176,7 +199,7 @@ export const RawTreeItem = <T extends ItemType = ItemType>({
176
199
  isBranch && open && handleOpenChange();
177
200
  break;
178
201
  case ' ':
179
- handleSelect();
202
+ handleSelect(event.altKey);
180
203
  break;
181
204
  }
182
205
  },
@@ -184,56 +207,72 @@ export const RawTreeItem = <T extends ItemType = ItemType>({
184
207
  );
185
208
 
186
209
  return (
187
- <Treegrid.Row
188
- ref={rowRef}
189
- key={id}
190
- id={id}
191
- aria-labelledby={`${id}__label`}
192
- parentOf={parentOf?.join(Treegrid.PARENT_OF_SEPARATOR)}
193
- classNames={mx(
194
- 'grid grid-cols-subgrid col-[tree-row] mt-[2px] aria-[current]:bg-input',
195
- hoverableControls,
196
- hoverableFocusedKeyboardControls,
197
- hoverableFocusedWithinControls,
198
- hoverableDescriptionIcons,
199
- ghostHover,
200
- focusRing,
201
- className,
202
- )}
203
- data-itemid={item.id}
204
- data-testid={item.testId}
205
- // NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
206
- // without alerting the user (except for in the correct link element). See also:
207
- // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
208
- aria-current={current ? ('' as 'page') : undefined}
209
- onKeyDown={handleKeyDown}
210
- onContextMenu={(event) => {
211
- event.preventDefault();
212
- setMenuOpen(true);
213
- }}
214
- >
215
- <Treegrid.Cell
216
- indent
217
- classNames='relative grid grid-cols-subgrid col-[tree-row]'
218
- style={paddingIndendation(level)}
210
+ <>
211
+ <Treegrid.Row
212
+ ref={rowRef}
213
+ key={id}
214
+ id={id}
215
+ aria-labelledby={`${id}__label`}
216
+ parentOf={parentOf?.join(Treegrid.PARENT_OF_SEPARATOR)}
217
+ classNames={mx(
218
+ 'grid grid-cols-subgrid col-[tree-row] mt-[2px] aria-[current]:bg-input',
219
+ hoverableControls,
220
+ hoverableFocusedKeyboardControls,
221
+ hoverableFocusedWithinControls,
222
+ hoverableDescriptionIcons,
223
+ ghostHover,
224
+ focusRing,
225
+ className,
226
+ )}
227
+ data-itemid={id}
228
+ data-testid={testId}
229
+ // NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
230
+ // without alerting the user (except for in the correct link element). See also:
231
+ // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
232
+ aria-current={current ? ('' as 'page') : undefined}
233
+ onKeyDown={handleKeyDown}
234
+ onContextMenu={(event) => {
235
+ event.preventDefault();
236
+ setMenuOpen(true);
237
+ }}
219
238
  >
220
- <div role='none' className='flex items-center'>
221
- <TreeItemToggle open={open} isBranch={isBranch} onToggle={handleOpenChange} />
222
- <TreeItemHeading
223
- ref={buttonRef}
224
- label={label}
225
- icon={icon}
226
- className={headingClassName}
227
- disabled={disabled}
228
- current={current}
229
- onSelect={handleSelect}
239
+ <Treegrid.Cell
240
+ indent
241
+ classNames='relative grid grid-cols-subgrid col-[tree-row]'
242
+ style={paddingIndendation(level)}
243
+ >
244
+ <div role='none' className='flex items-center'>
245
+ <TreeItemToggle open={open} isBranch={isBranch} onToggle={handleOpenChange} />
246
+ <TreeItemHeading
247
+ ref={buttonRef}
248
+ label={label}
249
+ icon={icon}
250
+ className={headingClassName}
251
+ disabled={disabled}
252
+ current={current}
253
+ onSelect={handleSelect}
254
+ />
255
+ </div>
256
+ {Columns && <Columns item={item} path={path} menuOpen={menuOpen} setMenuOpen={setMenuOpen} />}
257
+ {instruction && <DropIndicator instruction={instruction} gap={2} />}
258
+ </Treegrid.Cell>
259
+ </Treegrid.Row>
260
+ {open &&
261
+ items.map((item, index) => (
262
+ <TreeItem
263
+ key={item.id}
264
+ item={item}
265
+ path={path}
266
+ last={index === items.length - 1}
267
+ draggable={draggable}
268
+ renderColumns={Columns}
269
+ canDrop={canDrop}
270
+ onOpenChange={onOpenChange}
271
+ onSelect={onSelect}
230
272
  />
231
- </div>
232
- {Columns && <Columns item={item} menuOpen={menuOpen} setMenuOpen={setMenuOpen} />}
233
- {instruction && <DropIndicator instruction={instruction} />}
234
- </Treegrid.Cell>
235
- </Treegrid.Row>
273
+ ))}
274
+ </>
236
275
  );
237
276
  };
238
277
 
239
- export const TreeItem = memo(RawTreeItem) as <T extends ItemType = ItemType>(prosp: TreeItemProps<T>) => JSX.Element;
278
+ export const TreeItem = memo(RawTreeItem) as FC<TreeItemProps>;
@@ -2,7 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { type KeyboardEvent, forwardRef, memo, useCallback } from 'react';
5
+ import React, { type KeyboardEvent, type MouseEvent, forwardRef, memo, useCallback } from 'react';
6
6
 
7
7
  import { Button, Icon, toLocalizedString, useTranslation, type Label } from '@dxos/react-ui';
8
8
  import { TextTooltip } from '@dxos/react-ui-text-tooltip';
@@ -16,7 +16,7 @@ export type NavTreeItemHeadingProps = {
16
16
  className?: string;
17
17
  disabled?: boolean;
18
18
  current?: boolean;
19
- onSelect?: () => void;
19
+ onSelect?: (option: boolean) => void;
20
20
  };
21
21
 
22
22
  export const TreeItemHeading = memo(
@@ -24,12 +24,19 @@ export const TreeItemHeading = memo(
24
24
  ({ label, icon, className, disabled, current, onSelect }, forwardedRef) => {
25
25
  const { t } = useTranslation();
26
26
 
27
+ const handleSelect = useCallback(
28
+ (event: MouseEvent) => {
29
+ onSelect?.(event.altKey);
30
+ },
31
+ [onSelect],
32
+ );
33
+
27
34
  const handleButtonKeydown = useCallback(
28
35
  (event: KeyboardEvent) => {
29
36
  if (event.key === ' ' || event.key === 'Enter') {
30
37
  event.preventDefault();
31
38
  event.stopPropagation();
32
- onSelect?.();
39
+ onSelect?.(event.altKey);
33
40
  }
34
41
  },
35
42
  [onSelect],
@@ -55,12 +62,14 @@ export const TreeItemHeading = memo(
55
62
  className,
56
63
  )}
57
64
  disabled={disabled}
58
- onClick={onSelect}
65
+ onClick={handleSelect}
59
66
  onKeyDown={handleButtonKeydown}
60
67
  {...(current && { 'aria-current': 'location' })}
61
68
  >
62
69
  {icon && <Icon icon={icon ?? 'ph--placeholder--regular'} size={4} classNames='is-[1em] bs-[1em] mlb-1' />}
63
- <span className='flex-1 is-0 truncate text-start text-sm font-normal'>{toLocalizedString(label, t)}</span>
70
+ <span className='flex-1 is-0 truncate text-start text-sm font-normal' data-tooltip>
71
+ {toLocalizedString(label, t)}
72
+ </span>
64
73
  </Button>
65
74
  </TextTooltip>
66
75
  );
@@ -2,24 +2,8 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { type ItemMode } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
6
-
7
- import { type ItemType } from './types';
8
-
9
5
  export const DEFAULT_INDENTATION = 8;
10
6
 
11
7
  export const paddingIndendation = (level: number, indentation = DEFAULT_INDENTATION) => ({
12
8
  paddingInlineStart: `${(level - 1) * indentation}px`,
13
9
  });
14
-
15
- export const getMode = (items: ItemType[], index: number): ItemMode => {
16
- const item = items[index];
17
- const next = items[index + 1];
18
- if (!next || item.path.length > next.path.length) {
19
- return 'last-in-group';
20
- } else if (item.path.length < next.path.length) {
21
- return 'expanded';
22
- } else {
23
- return 'standard';
24
- }
25
- };
@@ -3,5 +3,5 @@
3
3
  //
4
4
 
5
5
  export * from './Tree';
6
+ export * from './TreeContext';
6
7
  export * from './TreeItem';
7
- export * from './types';
@@ -7,9 +7,8 @@ import { type Instruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-
7
7
  import { S } from '@dxos/echo-schema';
8
8
  import { log } from '@dxos/log';
9
9
  import { faker } from '@dxos/random';
10
- import { Path } from '@dxos/react-ui-mosaic';
11
10
 
12
- import { type ItemType } from './types';
11
+ import { type TreeData } from './TreeItem';
13
12
 
14
13
  export type TestItem = {
15
14
  id: string;
@@ -40,69 +39,7 @@ export const createTree = (n = 4, d = 4): TestItem => ({
40
39
  items: d > 0 ? faker.helpers.multiple(() => createTree(n, d - 1), { count: n }) : [],
41
40
  });
42
41
 
43
- function* visitor({
44
- testItem,
45
- getItem,
46
- isOpen,
47
- }: {
48
- testItem: TestItem;
49
- getItem: (testItem: TestItem, parent?: readonly string[]) => ItemType;
50
- isOpen?: (testItem: ItemType) => boolean;
51
- }): Generator<ItemType> {
52
- const stack: [TestItem, ItemType][] = [[testItem, getItem(testItem)]];
53
- while (stack.length > 0) {
54
- const [testItem, item] = stack.pop()!;
55
- if (item.path.length > 1) {
56
- yield item;
57
- }
58
-
59
- const children = Array.from(testItem.items ?? []);
60
- if (item.path.length === 1 || isOpen?.(item)) {
61
- for (let i = children.length - 1; i >= 0; i--) {
62
- const child = children[i];
63
- stack.push([child, getItem(child, item.path)]);
64
- }
65
- }
66
- }
67
- }
68
-
69
- export const flattenTree = (tree: TestItem, open: string[], getItem: (tree: TestItem) => ItemType): ItemType[] => {
70
- return Array.from(
71
- visitor({
72
- testItem: tree,
73
- getItem,
74
- isOpen: ({ path }) => open.includes(Path.create(...path)),
75
- }),
76
- );
77
- };
78
-
79
- // Ensures that the same item is not created multiple times, causing the tree to be re-rendered.
80
- const itemsCache: Record<string, ItemType> = {};
81
-
82
- export const getItem = (testItem: TestItem, parent?: string[]): ItemType => {
83
- const cachedItem = itemsCache[testItem.id];
84
- if (cachedItem) {
85
- return cachedItem;
86
- }
87
-
88
- const item = {
89
- id: testItem.id,
90
- label: testItem.name,
91
- icon: testItem.icon,
92
- path: parent ? [...parent, testItem.id] : [testItem.id],
93
- ...((testItem.items?.length ?? 0) > 0 && {
94
- parentOf: testItem.items!.map(({ id }) => id),
95
- }),
96
- };
97
- itemsCache[testItem.id] = item;
98
- return item;
99
- };
100
-
101
- export const invalidateCache = (id: string) => {
102
- delete itemsCache[id];
103
- };
104
-
105
- const removeItem = (tree: TestItem, source: ItemType) => {
42
+ const removeItem = (tree: TestItem, source: TreeData) => {
106
43
  const parent = getTestItem(tree, source.path.slice(1, -1));
107
44
  const index = parent.items!.findIndex(({ id }) => id === source.id);
108
45
  const item = parent.items[index];
@@ -127,35 +64,29 @@ export const updateState = ({
127
64
  }: {
128
65
  state: TestItem;
129
66
  instruction: Instruction;
130
- source: ItemType;
131
- target: ItemType;
67
+ source: TreeData;
68
+ target: TreeData;
132
69
  }) => {
133
70
  switch (instruction.type) {
134
71
  case 'reorder-above': {
135
- invalidateCache(source.id);
136
72
  const item = removeItem(state, source);
137
73
  const parent = getTestItem(state, target.path.slice(1, -1));
138
74
  const index = parent.items!.findIndex(({ id }) => id === target.id);
139
- invalidateCache(target.id);
140
75
  parent.items!.splice(index, 0, item);
141
76
  break;
142
77
  }
143
78
 
144
79
  case 'reorder-below': {
145
- invalidateCache(source.id);
146
80
  const item = removeItem(state, source);
147
81
  const parent = getTestItem(state, target.path.slice(1, -1));
148
82
  const index = parent.items!.findIndex(({ id }) => id === target.id);
149
- invalidateCache(target.id);
150
83
  parent.items!.splice(index + 1, 0, item);
151
84
  break;
152
85
  }
153
86
 
154
87
  case 'make-child': {
155
- invalidateCache(source.id);
156
88
  const item = removeItem(state, source);
157
89
  const parent = getTestItem(state, target.path.slice(1));
158
- invalidateCache(target.id);
159
90
  parent.items!.push(item);
160
91
  break;
161
92
  }
@@ -1,18 +0,0 @@
1
- import { S } from '@dxos/echo-schema';
2
- export declare const ItemSchema: S.mutable<S.Struct<{
3
- id: typeof S.String;
4
- label: S.mutable<S.Union<[typeof S.String, S.Tuple<[typeof S.String, S.Struct<{
5
- ns: typeof S.String;
6
- count: S.optional<typeof S.Number>;
7
- }>]>]>>;
8
- icon: S.optional<typeof S.String>;
9
- disabled: S.optional<typeof S.Boolean>;
10
- className: S.optional<typeof S.String>;
11
- headingClassName: S.optional<typeof S.String>;
12
- testId: S.optional<typeof S.String>;
13
- path: S.Array$<typeof S.String>;
14
- parentOf: S.optional<S.Array$<typeof S.String>>;
15
- }>>;
16
- export type ItemType = S.Schema.Type<typeof ItemSchema>;
17
- export declare const isItem: (item: unknown) => boolean;
18
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/components/Tree/types.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAatC,eAAO,MAAM,UAAU;;;;;;;;;;;;;GAYtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,UAAU,CAAC,CAAC;AAExD,eAAO,MAAM,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAA0B,CAAC"}
@@ -1,34 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { S } from '@dxos/echo-schema';
6
-
7
- const LabelSchema = S.Union(
8
- S.String,
9
- S.Tuple(
10
- S.String,
11
- S.Struct({
12
- ns: S.String,
13
- count: S.optional(S.Number),
14
- }),
15
- ),
16
- );
17
-
18
- export const ItemSchema = S.mutable(
19
- S.Struct({
20
- id: S.String,
21
- label: S.mutable(LabelSchema),
22
- icon: S.optional(S.String),
23
- disabled: S.optional(S.Boolean),
24
- className: S.optional(S.String),
25
- headingClassName: S.optional(S.String),
26
- testId: S.optional(S.String),
27
- path: S.Array(S.String),
28
- parentOf: S.optional(S.Array(S.String)),
29
- }),
30
- );
31
-
32
- export type ItemType = S.Schema.Type<typeof ItemSchema>;
33
-
34
- export const isItem: (item: unknown) => boolean = S.is(ItemSchema);