@dxos/plugin-navtree 0.7.1-staging.8709ba7 → 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 (37) hide show
  1. package/dist/lib/browser/index.mjs +226 -200
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
  5. package/dist/types/src/components/NavTree.d.ts +7 -5
  6. package/dist/types/src/components/NavTree.d.ts.map +1 -1
  7. package/dist/types/src/components/NavTree.stories.d.ts.map +1 -1
  8. package/dist/types/src/components/NavTreeContainer.d.ts +2 -6
  9. package/dist/types/src/components/NavTreeContainer.d.ts.map +1 -1
  10. package/dist/types/src/components/NavTreeItemAction.stories.d.ts +1 -0
  11. package/dist/types/src/components/NavTreeItemAction.stories.d.ts.map +1 -1
  12. package/dist/types/src/stories/Graph.stories.d.ts +2 -1
  13. package/dist/types/src/stories/Graph.stories.d.ts.map +1 -1
  14. package/dist/types/src/testing/generator.d.ts +0 -1
  15. package/dist/types/src/testing/generator.d.ts.map +1 -1
  16. package/dist/types/src/testing/index.d.ts +1 -1
  17. package/dist/types/src/testing/index.d.ts.map +1 -1
  18. package/dist/types/src/testing/update-state.d.ts +10 -0
  19. package/dist/types/src/testing/update-state.d.ts.map +1 -0
  20. package/dist/types/src/types.d.ts +12 -3
  21. package/dist/types/src/types.d.ts.map +1 -1
  22. package/dist/types/src/util.d.ts +1 -20
  23. package/dist/types/src/util.d.ts.map +1 -1
  24. package/package.json +28 -28
  25. package/src/NavTreePlugin.tsx +103 -90
  26. package/src/components/NavTree.stories.tsx +73 -69
  27. package/src/components/NavTree.tsx +30 -20
  28. package/src/components/NavTreeContainer.tsx +97 -56
  29. package/src/stories/Graph.stories.tsx +68 -96
  30. package/src/testing/generator.ts +2 -7
  31. package/src/testing/index.ts +1 -1
  32. package/src/testing/update-state.ts +70 -0
  33. package/src/types.ts +18 -3
  34. package/src/util.ts +2 -94
  35. package/dist/types/src/testing/visitor.d.ts +0 -18
  36. package/dist/types/src/testing/visitor.d.ts.map +0 -1
  37. package/src/testing/visitor.ts +0 -152
package/src/util.ts CHANGED
@@ -11,26 +11,9 @@ import {
11
11
  ACTION_GROUP_TYPE,
12
12
  isAction,
13
13
  } from '@dxos/app-graph';
14
- import { Path } from '@dxos/react-ui-mosaic';
15
- import { type MaybePromise, nonNullable } from '@dxos/util';
14
+ import { nonNullable } from '@dxos/util';
16
15
 
17
- import { type NodeProperties, type NavTreeItem } from './types';
18
-
19
- export type NavTreeItemGraphNode = Node<
20
- any,
21
- Partial<
22
- NodeProperties & {
23
- persistenceClass: string;
24
- persistenceKey: string;
25
- acceptPersistenceClass: Set<string>;
26
- acceptPersistenceKey: Set<string>;
27
- onRearrangeChildren: (nextOrder: NavTreeItemGraphNode[]) => MaybePromise<void>;
28
- onCopy: (activeNode: NavTreeItemGraphNode, index?: number) => MaybePromise<void>;
29
- onTransferStart: (activeNode: NavTreeItemGraphNode, index?: number) => MaybePromise<void>;
30
- onTransferEnd: (activeNode: NavTreeItemGraphNode, destinationParent: NavTreeItemGraphNode) => MaybePromise<void>;
31
- }
32
- >
33
- >;
16
+ import { type FlattenedActions, type NavTreeItemGraphNode } from './types';
34
17
 
35
18
  export const getParent = (
36
19
  graph: Graph,
@@ -98,16 +81,6 @@ export const sortActions = (actions: Action[]): Action[] =>
98
81
  return 1;
99
82
  });
100
83
 
101
- export const getTreeItemNode = (treeItems: NavTreeItem[], path?: string[]): NavTreeItem | undefined => {
102
- if (!path) {
103
- return undefined;
104
- }
105
-
106
- return treeItems.find((treeItem) => {
107
- return treeItem.path && !treeItem.path.find((id, index) => path[index] !== id);
108
- });
109
- };
110
-
111
84
  export const getChildren = (
112
85
  graph: Graph,
113
86
  node: NavTreeItemGraphNode,
@@ -124,8 +97,6 @@ export const getChildren = (
124
97
  .filter(nonNullable) as NavTreeItemGraphNode[];
125
98
  };
126
99
 
127
- type FlattenedActions = Required<Pick<NavTreeItem, 'actions' | 'groupedActions'>>;
128
-
129
100
  export const getActions = (graph: Graph, node: Node): FlattenedActions => {
130
101
  return graph.actions(node).reduce(
131
102
  (acc: FlattenedActions, arg) => {
@@ -155,66 +126,3 @@ export const expandChildren = (graph: Graph, node: Node) => {
155
126
  export const expandActions = (graph: Graph, node: Node) => {
156
127
  return Promise.all([graph.expand(node, 'outbound', ACTION_TYPE), graph.expand(node, 'outbound', ACTION_GROUP_TYPE)]);
157
128
  };
158
-
159
- function* navTreeItemVisitor({
160
- graph,
161
- node,
162
- open,
163
- getItem,
164
- path = [],
165
- filter,
166
- }: {
167
- graph: Graph;
168
- node: NavTreeItemGraphNode;
169
- open: string[];
170
- getItem: (node: NavTreeItemGraphNode, parent: readonly string[], filter?: NodeFilter) => NavTreeItem;
171
- path?: readonly string[];
172
- filter?: NodeFilter;
173
- }): Generator<NavTreeItem> {
174
- const stack: NavTreeItem[] = [getItem(node, path, filter)];
175
- while (stack.length > 0) {
176
- const nextItem = stack.pop()!;
177
- if (nextItem.path.length > 1) {
178
- yield nextItem;
179
- }
180
- const { node, path } = nextItem;
181
- const children = getChildren(graph, node, filter, path);
182
- const actions = graph.actions(node);
183
- if (path.length === 1 || open.includes(Path.create(...path))) {
184
- for (let i = actions.length - 1; i >= 0; i--) {
185
- if (actions[i].properties.disposition === 'item') {
186
- stack.push(getItem(actions[i], path, filter));
187
- }
188
- }
189
- for (let i = children.length - 1; i >= 0; i--) {
190
- const child = children[i] as NavTreeItemGraphNode;
191
- stack.push(getItem(child, path, filter));
192
- }
193
- }
194
- }
195
- }
196
-
197
- /**
198
- * Get a reactive tree node from a graph node.
199
- */
200
- export const treeItemsFromRootNode = (
201
- graph: Graph,
202
- rootNode: NavTreeItemGraphNode,
203
- open: string[],
204
- getItem: (node: NavTreeItemGraphNode, parent: readonly string[]) => NavTreeItem,
205
- path?: readonly string[],
206
- filter?: NodeFilter,
207
- ): NavTreeItem[] => {
208
- return Array.from(navTreeItemVisitor({ graph, node: rootNode, open, getItem, path, filter }));
209
- };
210
-
211
- export const expandOpenGraphNodes = (graph: Graph, open: string[]) => {
212
- return Promise.all(
213
- open
214
- .map((id) => {
215
- const node = graph.findNode(Path.last(id));
216
- return node && expandChildrenAndActions(graph, node as NavTreeItemGraphNode);
217
- })
218
- .filter(nonNullable),
219
- );
220
- };
@@ -1,18 +0,0 @@
1
- import { type Instruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
2
- import { type NodeArg } from '@dxos/app-graph';
3
- import { type NavTreeItem } from '../types';
4
- export declare const flattenTree: (tree: NodeArg<any>, open: string[]) => NavTreeItem[];
5
- export declare function visitor({ node, getItem, isOpen, }: {
6
- node: NodeArg<any>;
7
- getItem: (node: NodeArg<any>, parent?: readonly string[]) => NavTreeItem;
8
- isOpen?: (node: NavTreeItem) => boolean;
9
- }): Generator<NavTreeItem>;
10
- export declare const getItem: (arg: NodeArg<any>, parent?: readonly string[]) => NavTreeItem;
11
- export declare const invalidateCache: (id: string) => void;
12
- export declare const updateState: ({ state, instruction, source, target, }: {
13
- state: NodeArg<any>;
14
- instruction: Instruction;
15
- source: NavTreeItem;
16
- target: NavTreeItem;
17
- }) => void;
18
- //# sourceMappingURL=visitor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"visitor.d.ts","sourceRoot":"","sources":["../../../../src/testing/visitor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,oDAAoD,CAAC;AAEtF,OAAO,EAA2B,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAIxE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,eAAO,MAAM,WAAW,SAAU,OAAO,CAAC,GAAG,CAAC,QAAQ,MAAM,EAAE,KAAG,WAAW,EAQ3E,CAAC;AAEF,wBAAiB,OAAO,CAAC,EACvB,IAAI,EACJ,OAAO,EACP,MAAM,GACP,EAAE;IACD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,KAAK,WAAW,CAAC;IACzE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC;CACzC,GAAG,SAAS,CAAC,WAAW,CAAC,CAgBzB;AAKD,eAAO,MAAM,OAAO,QAAS,OAAO,CAAC,GAAG,CAAC,WAAW,SAAS,MAAM,EAAE,KAAG,WA6BvE,CAAC;AAEF,eAAO,MAAM,eAAe,OAAQ,MAAM,SAEzC,CAAC;AAmBF,eAAO,MAAM,WAAW,4CAKrB;IACD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;CACrB,SAsCA,CAAC"}
@@ -1,152 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { type Instruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
6
-
7
- import { isActionLike, type Node, type NodeArg } from '@dxos/app-graph';
8
- import { log } from '@dxos/log';
9
- import { Path } from '@dxos/react-ui-mosaic';
10
-
11
- import { type NavTreeItem } from '../types';
12
-
13
- export const flattenTree = (tree: NodeArg<any>, open: string[]): NavTreeItem[] => {
14
- return Array.from(
15
- visitor({
16
- node: tree,
17
- getItem,
18
- isOpen: ({ path }) => open.includes(Path.create(...path)),
19
- }),
20
- );
21
- };
22
-
23
- export function* visitor({
24
- node,
25
- getItem,
26
- isOpen,
27
- }: {
28
- node: NodeArg<any>;
29
- getItem: (node: NodeArg<any>, parent?: readonly string[]) => NavTreeItem;
30
- isOpen?: (node: NavTreeItem) => boolean;
31
- }): Generator<NavTreeItem> {
32
- const stack: [NodeArg<any>, NavTreeItem][] = [[node, getItem(node)]];
33
- while (stack.length > 0) {
34
- const [node, item] = stack.pop()!;
35
- if (item.path.length > 1) {
36
- yield item;
37
- }
38
-
39
- const children = Array.from(node.nodes ?? []);
40
- if (item.path.length === 1 || isOpen?.(item)) {
41
- for (let i = children.length - 1; i >= 0; i--) {
42
- const child = children[i];
43
- stack.push([child, getItem(child, item.path)]);
44
- }
45
- }
46
- }
47
- }
48
-
49
- // Ensures that the same item is not created multiple times, causing the tree to be re-rendered.
50
- const itemsCache: Record<string, NavTreeItem> = {};
51
-
52
- export const getItem = (arg: NodeArg<any>, parent?: readonly string[]): NavTreeItem => {
53
- const cachedItem = itemsCache[arg.id];
54
- if (cachedItem) {
55
- return cachedItem;
56
- }
57
-
58
- const children = arg.nodes?.filter((node) => !isActionLike(node)) ?? [];
59
- const actions = arg.nodes?.filter((node) => isActionLike(node)) ?? [];
60
- const node: Node = {
61
- id: arg.id,
62
- type: arg.type,
63
- properties: arg.properties ?? {},
64
- data: arg.data ?? null,
65
- };
66
-
67
- const item = {
68
- id: arg.id,
69
- label: arg.properties!.label,
70
- icon: arg.properties!.icon,
71
- path: parent ? [...parent, arg.id] : [arg.id],
72
- ...(children.length > 0 && {
73
- parentOf: children.map(({ id }) => id),
74
- }),
75
- node,
76
- actions,
77
- groupedActions: {},
78
- };
79
- itemsCache[node.id] = item;
80
- return item;
81
- };
82
-
83
- export const invalidateCache = (id: string) => {
84
- delete itemsCache[id];
85
- };
86
-
87
- const removeItem = (tree: NodeArg<any>, source: NavTreeItem) => {
88
- const parent = getNode(tree, source.path.slice(1, -1));
89
- const index = parent.nodes!.findIndex(({ id }) => id === source.id);
90
- const item = parent.nodes![index];
91
- parent.nodes!.splice(index, 1);
92
- return item;
93
- };
94
-
95
- const getNode = (tree: NodeArg<any>, path: string[]) => {
96
- let node = tree;
97
- for (const part of path) {
98
- node = node.nodes!.find(({ id }) => id === part)!;
99
- }
100
- return node;
101
- };
102
-
103
- // TODO(wittjosiah): Reconcile with react-ui-list/Tree/testing.
104
- export const updateState = ({
105
- state,
106
- instruction,
107
- source,
108
- target,
109
- }: {
110
- state: NodeArg<any>;
111
- instruction: Instruction;
112
- source: NavTreeItem;
113
- target: NavTreeItem;
114
- }) => {
115
- switch (instruction.type) {
116
- case 'reorder-above': {
117
- invalidateCache(source.id);
118
- const item = removeItem(state, source);
119
- const parent = getNode(state, target.path.slice(1, -1));
120
- const index = parent.nodes!.findIndex(({ id }) => id === target.id);
121
- invalidateCache(target.id);
122
- parent.nodes!.splice(index, 0, item);
123
- break;
124
- }
125
-
126
- case 'reorder-below': {
127
- invalidateCache(source.id);
128
- const item = removeItem(state, source);
129
- const parent = getNode(state, target.path.slice(1, -1));
130
- const index = parent.nodes!.findIndex(({ id }) => id === target.id);
131
- invalidateCache(target.id);
132
- parent.nodes!.splice(index + 1, 0, item);
133
- break;
134
- }
135
-
136
- case 'make-child': {
137
- invalidateCache(source.id);
138
- const item = removeItem(state, source);
139
- const parent = getNode(state, target.path.slice(1));
140
- invalidateCache(target.id);
141
- parent.nodes!.push(item);
142
- break;
143
- }
144
-
145
- case 'instruction-blocked':
146
- break;
147
-
148
- default:
149
- log.warn('Unsupported instruction', instruction);
150
- break;
151
- }
152
- };