@dxos/plugin-navtree 0.6.13 → 0.6.14-main.1366248
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/{chunk-U7MTKDFQ.mjs → chunk-PSVCPL4T.mjs} +1 -1
- package/dist/lib/browser/chunk-PSVCPL4T.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +611 -398
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +1 -1
- package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
- package/dist/types/src/components/CommandsDialog.d.ts.map +1 -1
- package/dist/types/src/components/HaloButton.stories.d.ts +5 -9
- package/dist/types/src/components/HaloButton.stories.d.ts.map +1 -1
- package/dist/types/src/components/NavBarStart.d.ts.map +1 -1
- package/dist/types/src/components/NavTree.d.ts +20 -0
- package/dist/types/src/components/NavTree.d.ts.map +1 -0
- package/dist/types/src/components/NavTree.stories.d.ts +7 -0
- package/dist/types/src/components/NavTree.stories.d.ts.map +1 -0
- package/dist/types/src/components/NavTreeContainer.d.ts +8 -8
- package/dist/types/src/components/NavTreeContainer.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItemAction.d.ts +23 -0
- package/dist/types/src/components/NavTreeItemAction.d.ts.map +1 -0
- package/dist/types/src/components/NavTreeItemAction.stories.d.ts +45 -0
- package/dist/types/src/components/NavTreeItemAction.stories.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/experimental/Tree.stories.d.ts +3 -7
- package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/stories/Graph.stories.d.ts +4 -12
- package/dist/types/src/stories/Graph.stories.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +86 -0
- package/dist/types/src/testing/generator.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +3 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/visitor.d.ts +18 -0
- package/dist/types/src/testing/visitor.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +5 -10
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +41 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/dist/types/src/util.d.ts +8 -9
- package/dist/types/src/util.d.ts.map +1 -1
- package/package.json +39 -34
- package/src/NavTreePlugin.tsx +99 -41
- package/src/components/CommandsDialog.tsx +2 -4
- package/src/components/HaloButton.stories.tsx +8 -6
- package/src/components/NavBarStart.tsx +2 -4
- package/src/components/NavTree.stories.tsx +104 -0
- package/src/components/NavTree.tsx +127 -0
- package/src/components/NavTreeContainer.tsx +132 -302
- package/src/components/NavTreeFooter.tsx +1 -1
- package/src/components/NavTreeItemAction.stories.tsx +57 -0
- package/src/components/NavTreeItemAction.tsx +367 -0
- package/src/components/index.ts +1 -0
- package/src/experimental/Tree.stories.tsx +11 -8
- package/src/experimental/Tree.tsx +2 -2
- package/src/meta.ts +3 -1
- package/src/stories/Graph.stories.tsx +111 -102
- package/src/testing/generator.ts +199 -0
- package/src/testing/index.ts +6 -0
- package/src/testing/visitor.ts +152 -0
- package/src/translations.ts +3 -3
- package/src/types.ts +50 -0
- package/src/util.ts +52 -63
- package/dist/lib/browser/chunk-U7MTKDFQ.mjs.map +0 -7
package/dist/types/src/util.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Action, type Node, type NodeFilter, type Graph } from '@dxos/app-graph';
|
|
2
|
-
import { type NavTreeItemNode, type NavTreeItemNodeProperties, type OpenItemIds } from '@dxos/react-ui-navtree';
|
|
3
2
|
import { type MaybePromise } from '@dxos/util';
|
|
4
|
-
|
|
3
|
+
import { type NodeProperties, type NavTreeItem } from './types';
|
|
4
|
+
export type NavTreeItemGraphNode = Node<any, Partial<NodeProperties & {
|
|
5
5
|
persistenceClass: string;
|
|
6
6
|
persistenceKey: string;
|
|
7
7
|
acceptPersistenceClass: Set<string>;
|
|
@@ -11,22 +11,21 @@ export type NavTreeItemGraphNode = Node<any, NavTreeItemNodeProperties & Partial
|
|
|
11
11
|
onTransferStart: (activeNode: NavTreeItemGraphNode, index?: number) => MaybePromise<void>;
|
|
12
12
|
onTransferEnd: (activeNode: NavTreeItemGraphNode, destinationParent: NavTreeItemGraphNode) => MaybePromise<void>;
|
|
13
13
|
}>>;
|
|
14
|
-
export type NavTreeItem = NavTreeItemNode<NavTreeItemGraphNode>;
|
|
15
14
|
export declare const getParent: (graph: Graph, node: NavTreeItemGraphNode, path: string[]) => NavTreeItemGraphNode | undefined;
|
|
16
15
|
export declare const getPersistenceParent: (graph: Graph, node: NavTreeItemGraphNode, path: string[], persistenceClass: string) => NavTreeItemGraphNode | null;
|
|
17
16
|
export declare const resolveMigrationOperation: (graph: Graph, activeNode: NavTreeItemGraphNode, destinationPath: string[], destinationRelatedNode?: NavTreeItemGraphNode) => "transfer" | "copy" | "reject";
|
|
18
17
|
export declare const sortActions: (actions: Action[]) => Action[];
|
|
19
|
-
export declare const getTreeItemNode: (treeItems:
|
|
20
|
-
export declare const getChildren: (graph: Graph, node: NavTreeItemGraphNode, filter?: NodeFilter, path?: string[]) => NavTreeItemGraphNode[];
|
|
21
|
-
type FlattenedActions = Required<Pick<
|
|
22
|
-
export declare const getActions: (graph: Graph, node:
|
|
18
|
+
export declare const getTreeItemNode: (treeItems: NavTreeItem[], path?: string[]) => NavTreeItem | undefined;
|
|
19
|
+
export declare const getChildren: (graph: Graph, node: NavTreeItemGraphNode, filter?: NodeFilter, path?: readonly string[]) => NavTreeItemGraphNode[];
|
|
20
|
+
type FlattenedActions = Required<Pick<NavTreeItem, 'actions' | 'groupedActions'>>;
|
|
21
|
+
export declare const getActions: (graph: Graph, node: Node) => FlattenedActions;
|
|
23
22
|
export declare const expandChildrenAndActions: (graph: Graph, node: Node) => Promise<[void, [void, void]]>;
|
|
24
23
|
export declare const expandChildren: (graph: Graph, node: Node) => Promise<void>;
|
|
25
24
|
export declare const expandActions: (graph: Graph, node: Node) => Promise<[void, void]>;
|
|
26
25
|
/**
|
|
27
26
|
* Get a reactive tree node from a graph node.
|
|
28
27
|
*/
|
|
29
|
-
export declare const treeItemsFromRootNode: (graph: Graph, rootNode: NavTreeItemGraphNode,
|
|
30
|
-
export declare const expandOpenGraphNodes: (graph: Graph,
|
|
28
|
+
export declare const treeItemsFromRootNode: (graph: Graph, rootNode: NavTreeItemGraphNode, open: string[], getItem: (node: NavTreeItemGraphNode, parent: readonly string[]) => NavTreeItem, path?: readonly string[], filter?: NodeFilter) => NavTreeItem[];
|
|
29
|
+
export declare const expandOpenGraphNodes: (graph: Graph, open: string[]) => Promise<[void, [void, void]][]>;
|
|
31
30
|
export {};
|
|
32
31
|
//# sourceMappingURL=util.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/util.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,UAAU,EACf,KAAK,KAAK,EAIX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/util.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,UAAU,EACf,KAAK,KAAK,EAIX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,KAAK,YAAY,EAAe,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAEhE,MAAM,MAAM,oBAAoB,GAAG,IAAI,CACrC,GAAG,EACH,OAAO,CACL,cAAc,GAAG;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,mBAAmB,EAAE,CAAC,SAAS,EAAE,oBAAoB,EAAE,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/E,MAAM,EAAE,CAAC,UAAU,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;IACjF,eAAe,EAAE,CAAC,UAAU,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;IAC1F,aAAa,EAAE,CAAC,UAAU,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,oBAAoB,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;CAClH,CACF,CACF,CAAC;AAEF,eAAO,MAAM,SAAS,UACb,KAAK,QACN,oBAAoB,QACpB,MAAM,EAAE,KACb,oBAAoB,GAAG,SAGzB,CAAC;AAEF,eAAO,MAAM,oBAAoB,UACxB,KAAK,QACN,oBAAoB,QACpB,MAAM,EAAE,oBACI,MAAM,KACvB,oBAAoB,GAAG,IAOzB,CAAC;AAEF,eAAO,MAAM,yBAAyB,UAC7B,KAAK,cACA,oBAAoB,mBACf,MAAM,EAAE,2BACA,oBAAoB,KAC5C,UAAU,GAAG,MAAM,GAAG,QAsBxB,CAAC;AAGF,eAAO,MAAM,WAAW,YAAa,MAAM,EAAE,KAAG,MAAM,EAWlD,CAAC;AAEL,eAAO,MAAM,eAAe,cAAe,WAAW,EAAE,SAAS,MAAM,EAAE,KAAG,WAAW,GAAG,SAQzF,CAAC;AAEF,eAAO,MAAM,WAAW,UACf,KAAK,QACN,oBAAoB,WACjB,UAAU,SACb,SAAS,MAAM,EAAE,KACtB,oBAAoB,EAStB,CAAC;AAEF,KAAK,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC;AAElF,eAAO,MAAM,UAAU,UAAW,KAAK,QAAQ,IAAI,KAAG,gBAgBrD,CAAC;AAEF,eAAO,MAAM,wBAAwB,UAAW,KAAK,QAAQ,IAAI,kCAEhE,CAAC;AAEF,eAAO,MAAM,cAAc,UAAW,KAAK,QAAQ,IAAI,kBAEtD,CAAC;AAEF,eAAO,MAAM,aAAa,UAAW,KAAK,QAAQ,IAAI,0BAErD,CAAC;AAwCF;;GAEG;AACH,eAAO,MAAM,qBAAqB,UACzB,KAAK,YACF,oBAAoB,QACxB,MAAM,EAAE,WACL,CAAC,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,KAAK,WAAW,SACxE,SAAS,MAAM,EAAE,WACf,UAAU,KAClB,WAAW,EAEb,CAAC;AAEF,eAAO,MAAM,oBAAoB,UAAW,KAAK,QAAQ,MAAM,EAAE,oCAShE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-navtree",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.14-main.1366248",
|
|
4
4
|
"description": "DXOS Surface plugin for a tree view visualization of the graph.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": "DXOS.org",
|
|
9
|
+
"sideEffects": true,
|
|
9
10
|
"exports": {
|
|
10
11
|
".": {
|
|
11
|
-
"
|
|
12
|
-
"
|
|
12
|
+
"types": "./dist/types/src/index.d.ts",
|
|
13
|
+
"browser": "./dist/lib/browser/index.mjs"
|
|
13
14
|
},
|
|
14
15
|
"./meta": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
16
|
+
"types": "./dist/types/src/meta.d.ts",
|
|
17
|
+
"browser": "./dist/lib/browser/meta.mjs"
|
|
17
18
|
}
|
|
18
19
|
},
|
|
19
20
|
"types": "dist/types/src/index.d.ts",
|
|
@@ -29,27 +30,31 @@
|
|
|
29
30
|
"src"
|
|
30
31
|
],
|
|
31
32
|
"dependencies": {
|
|
33
|
+
"@atlaskit/pragmatic-drag-and-drop": "^1.4.0",
|
|
34
|
+
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
|
|
32
35
|
"@preact/signals-core": "^1.6.0",
|
|
36
|
+
"@radix-ui/react-use-controllable-state": "^1.0.0",
|
|
33
37
|
"date-fns": "^3.3.1",
|
|
34
|
-
"@dxos/app-
|
|
35
|
-
"@dxos/app-
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/
|
|
39
|
-
"@dxos/
|
|
40
|
-
"@dxos/
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/plugin-client": "0.6.
|
|
43
|
-
"@dxos/plugin-graph": "0.6.
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/plugin-
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/
|
|
48
|
-
"@dxos/react-
|
|
49
|
-
"@dxos/react-
|
|
50
|
-
"@dxos/react-ui-
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/react-ui-searchlist": "0.6.
|
|
38
|
+
"@dxos/app-framework": "0.6.14-main.1366248",
|
|
39
|
+
"@dxos/app-graph": "0.6.14-main.1366248",
|
|
40
|
+
"@dxos/async": "0.6.14-main.1366248",
|
|
41
|
+
"@dxos/echo-schema": "0.6.14-main.1366248",
|
|
42
|
+
"@dxos/debug": "0.6.14-main.1366248",
|
|
43
|
+
"@dxos/local-storage": "0.6.14-main.1366248",
|
|
44
|
+
"@dxos/log": "0.6.14-main.1366248",
|
|
45
|
+
"@dxos/keyboard": "0.6.14-main.1366248",
|
|
46
|
+
"@dxos/plugin-client": "0.6.14-main.1366248",
|
|
47
|
+
"@dxos/plugin-graph": "0.6.14-main.1366248",
|
|
48
|
+
"@dxos/invariant": "0.6.14-main.1366248",
|
|
49
|
+
"@dxos/plugin-observability": "0.6.14-main.1366248",
|
|
50
|
+
"@dxos/plugin-theme": "0.6.14-main.1366248",
|
|
51
|
+
"@dxos/protocols": "0.6.14-main.1366248",
|
|
52
|
+
"@dxos/react-client": "0.6.14-main.1366248",
|
|
53
|
+
"@dxos/react-ui-list": "0.6.14-main.1366248",
|
|
54
|
+
"@dxos/react-ui-deck": "0.6.14-main.1366248",
|
|
55
|
+
"@dxos/react-ui-mosaic": "0.6.14-main.1366248",
|
|
56
|
+
"@dxos/react-ui-searchlist": "0.6.14-main.1366248",
|
|
57
|
+
"@dxos/util": "0.6.14-main.1366248"
|
|
53
58
|
},
|
|
54
59
|
"devDependencies": {
|
|
55
60
|
"@phosphor-icons/react": "^2.1.5",
|
|
@@ -57,19 +62,19 @@
|
|
|
57
62
|
"@types/react-dom": "~18.2.0",
|
|
58
63
|
"react": "~18.2.0",
|
|
59
64
|
"react-dom": "~18.2.0",
|
|
60
|
-
"vite": "
|
|
61
|
-
"@dxos/
|
|
62
|
-
"@dxos/react-ui": "0.6.
|
|
63
|
-
"@dxos/
|
|
64
|
-
"@dxos/
|
|
65
|
-
"@dxos/
|
|
65
|
+
"vite": "5.4.7",
|
|
66
|
+
"@dxos/random": "0.6.14-main.1366248",
|
|
67
|
+
"@dxos/react-ui": "0.6.14-main.1366248",
|
|
68
|
+
"@dxos/storybook-utils": "0.6.14-main.1366248",
|
|
69
|
+
"@dxos/react-ui-theme": "0.6.14-main.1366248",
|
|
70
|
+
"@dxos/echo-signals": "0.6.14-main.1366248"
|
|
66
71
|
},
|
|
67
72
|
"peerDependencies": {
|
|
68
73
|
"@phosphor-icons/react": "^2.1.5",
|
|
69
|
-
"react": "
|
|
70
|
-
"react-dom": "
|
|
71
|
-
"@dxos/react-ui": "0.6.
|
|
72
|
-
"@dxos/react-ui-theme": "0.6.
|
|
74
|
+
"react": "~18.2.0",
|
|
75
|
+
"react-dom": "~18.2.0",
|
|
76
|
+
"@dxos/react-ui": "0.6.14-main.1366248",
|
|
77
|
+
"@dxos/react-ui-theme": "0.6.14-main.1366248"
|
|
73
78
|
},
|
|
74
79
|
"publishConfig": {
|
|
75
80
|
"access": "public"
|
package/src/NavTreePlugin.tsx
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { MagnifyingGlass, type IconProps } from '@phosphor-icons/react';
|
|
6
5
|
import React from 'react';
|
|
7
6
|
|
|
8
7
|
import {
|
|
@@ -19,12 +18,14 @@ import {
|
|
|
19
18
|
type GraphProvides,
|
|
20
19
|
parseGraphPlugin,
|
|
21
20
|
NavigationAction,
|
|
21
|
+
parseNavigationPlugin,
|
|
22
22
|
} from '@dxos/app-framework';
|
|
23
|
-
import { createExtension, type Graph, isAction, isGraphNode, type Node } from '@dxos/app-graph';
|
|
23
|
+
import { createExtension, type Graph, isAction, isGraphNode, type Node, type NodeFilter } from '@dxos/app-graph';
|
|
24
|
+
import { invariant } from '@dxos/invariant';
|
|
24
25
|
import { Keyboard } from '@dxos/keyboard';
|
|
25
26
|
import { LocalStorageStore } from '@dxos/local-storage';
|
|
26
27
|
import { Path } from '@dxos/react-ui-mosaic';
|
|
27
|
-
import {
|
|
28
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
28
29
|
import { getHostPlatform } from '@dxos/util';
|
|
29
30
|
|
|
30
31
|
import {
|
|
@@ -38,7 +39,14 @@ import {
|
|
|
38
39
|
import { CommandsTrigger } from './components/CommandsTrigger';
|
|
39
40
|
import meta, { KEY_BINDING, NAVTREE_PLUGIN } from './meta';
|
|
40
41
|
import translations from './translations';
|
|
41
|
-
import {
|
|
42
|
+
import { type NavTreeItem } from './types';
|
|
43
|
+
import {
|
|
44
|
+
expandOpenGraphNodes,
|
|
45
|
+
getActions,
|
|
46
|
+
getChildren,
|
|
47
|
+
treeItemsFromRootNode,
|
|
48
|
+
type NavTreeItemGraphNode,
|
|
49
|
+
} from './util';
|
|
42
50
|
|
|
43
51
|
export type NavTreePluginProvides = SurfaceProvides &
|
|
44
52
|
MetadataRecordsProvides &
|
|
@@ -46,41 +54,99 @@ export type NavTreePluginProvides = SurfaceProvides &
|
|
|
46
54
|
TranslationsProvides &
|
|
47
55
|
IntentResolverProvides;
|
|
48
56
|
|
|
49
|
-
type NavTreeState = {
|
|
57
|
+
type NavTreeState = {
|
|
58
|
+
root?: NavTreeItemGraphNode;
|
|
59
|
+
flatTree: NavTreeItem[];
|
|
60
|
+
open: string[];
|
|
61
|
+
};
|
|
50
62
|
|
|
51
63
|
export const NavTreePlugin = (): PluginDefinition<NavTreePluginProvides> => {
|
|
64
|
+
let graphPlugin: Plugin<GraphProvides> | undefined;
|
|
65
|
+
let graph: Graph | undefined;
|
|
66
|
+
const itemCache = new Map<string, NavTreeItem>();
|
|
67
|
+
|
|
52
68
|
const state = new LocalStorageStore<NavTreeState>('dxos.org/settings/navtree', {
|
|
69
|
+
root: undefined,
|
|
70
|
+
get flatTree() {
|
|
71
|
+
if (!this.root || !graph) {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return treeItemsFromRootNode(graph, this.root, this.open, getItem);
|
|
76
|
+
},
|
|
53
77
|
// TODO(thure): Do this dynamically.
|
|
54
|
-
|
|
78
|
+
open: ['root', 'root~dxos.org/plugin/space-spaces', 'root~dxos.org/plugin/files'],
|
|
55
79
|
});
|
|
56
80
|
|
|
57
|
-
|
|
58
|
-
|
|
81
|
+
const getItem = (node: NavTreeItemGraphNode, parent: readonly string[], filter?: NodeFilter) => {
|
|
82
|
+
invariant(graph);
|
|
83
|
+
const path = [...parent, node.id];
|
|
84
|
+
const { actions, groupedActions } = getActions(graph, node);
|
|
85
|
+
const children = getChildren(graph, node, filter, path);
|
|
86
|
+
const parentOf =
|
|
87
|
+
children.length > 0 ? children.map(({ id }) => id) : node.properties.role === 'branch' ? [] : undefined;
|
|
88
|
+
const item = {
|
|
89
|
+
id: node.id,
|
|
90
|
+
label: node.properties.label ?? node.id,
|
|
91
|
+
icon: node.properties.icon,
|
|
92
|
+
disabled: node.properties.disabled,
|
|
93
|
+
testId: node.properties.testId,
|
|
94
|
+
className: mx(node.properties.modified && 'italic', node.properties.className),
|
|
95
|
+
headingClassName: node.properties.headingClassName,
|
|
96
|
+
path,
|
|
97
|
+
parentOf,
|
|
98
|
+
node,
|
|
99
|
+
actions,
|
|
100
|
+
groupedActions,
|
|
101
|
+
} satisfies NavTreeItem;
|
|
59
102
|
|
|
60
|
-
|
|
103
|
+
const cachedItem = itemCache.get(node.id);
|
|
104
|
+
// TODO(wittjosiah): This is not a good enough check.
|
|
105
|
+
// Consider better ways to doing reactive transformations which retain referential equality.
|
|
106
|
+
if (cachedItem && JSON.stringify(item) === JSON.stringify(cachedItem)) {
|
|
107
|
+
return cachedItem;
|
|
108
|
+
} else {
|
|
109
|
+
itemCache.set(node.id, item);
|
|
110
|
+
return item;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const handleOpenChange = (item: NavTreeItem, open: boolean) => {
|
|
115
|
+
const path = Path.create(...item.path);
|
|
61
116
|
// TODO(thure): This might become a localstorage leak; openItemIds that no longer exist should be removed from this map.
|
|
62
|
-
|
|
117
|
+
if (open) {
|
|
118
|
+
state.values.open.push(path);
|
|
119
|
+
} else {
|
|
120
|
+
const index = state.values.open.indexOf(path);
|
|
121
|
+
if (index > -1) {
|
|
122
|
+
state.values.open.splice(index, 1);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
63
126
|
if (graph) {
|
|
64
|
-
void expandOpenGraphNodes(graph,
|
|
127
|
+
void expandOpenGraphNodes(graph, state.values.open);
|
|
65
128
|
}
|
|
66
129
|
};
|
|
67
130
|
|
|
68
131
|
return {
|
|
69
132
|
meta,
|
|
70
133
|
ready: async (plugins) => {
|
|
134
|
+
state.prop({ key: 'open', type: LocalStorageStore.json<string[]>() });
|
|
135
|
+
|
|
71
136
|
graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
|
|
72
137
|
graph = graphPlugin?.provides.graph;
|
|
73
138
|
if (!graph) {
|
|
74
139
|
return;
|
|
75
140
|
}
|
|
76
141
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
142
|
+
const dispatch = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatch;
|
|
143
|
+
const soloPart = resolvePlugin(plugins, parseNavigationPlugin)?.provides.location.active.solo?.[0];
|
|
144
|
+
if (dispatch && soloPart) {
|
|
145
|
+
void dispatch({ plugin: NAVTREE_PLUGIN, action: NavigationAction.EXPOSE, data: { id: soloPart.id } });
|
|
146
|
+
}
|
|
82
147
|
|
|
83
|
-
|
|
148
|
+
state.values.root = graph.root as NavTreeItemGraphNode;
|
|
149
|
+
void expandOpenGraphNodes(graph, state.values.open);
|
|
84
150
|
|
|
85
151
|
// TODO(wittjosiah): Factor out.
|
|
86
152
|
// TODO(wittjosiah): Handle removal of actions.
|
|
@@ -148,19 +214,15 @@ export const NavTreePlugin = (): PluginDefinition<NavTreePluginProvides> => {
|
|
|
148
214
|
|
|
149
215
|
switch (role) {
|
|
150
216
|
case 'navigation':
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
/>
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
break;
|
|
217
|
+
return (
|
|
218
|
+
<NavTreeContainer
|
|
219
|
+
items={state.values.flatTree}
|
|
220
|
+
current={data.activeIds as string[]}
|
|
221
|
+
open={state.values.open}
|
|
222
|
+
onOpenChange={handleOpenChange}
|
|
223
|
+
popoverAnchorId={data.popoverAnchorId as string}
|
|
224
|
+
/>
|
|
225
|
+
);
|
|
164
226
|
|
|
165
227
|
case 'document-title': {
|
|
166
228
|
return <NavTreeDocumentTitle node={isGraphNode(data.activeNode) ? data.activeNode : undefined} />;
|
|
@@ -201,17 +263,14 @@ export const NavTreePlugin = (): PluginDefinition<NavTreePluginProvides> => {
|
|
|
201
263
|
if (graph && intent.data?.id) {
|
|
202
264
|
const path = graph.getPath({ target: intent.data.id });
|
|
203
265
|
if (Array.isArray(path)) {
|
|
204
|
-
const additionalOpenItems = [...Array(path.length
|
|
205
|
-
const itemId = Path.create(...path.slice(
|
|
206
|
-
if (itemId.length > 0) {
|
|
207
|
-
acc
|
|
266
|
+
const additionalOpenItems = [...Array(path.length)].reduce((acc: string[], _, index) => {
|
|
267
|
+
const itemId = Path.create(...path.slice(0, index));
|
|
268
|
+
if (itemId.length > 0 && !state.values.open.includes(itemId)) {
|
|
269
|
+
acc.push(itemId);
|
|
208
270
|
}
|
|
209
271
|
return acc;
|
|
210
|
-
},
|
|
211
|
-
state.values.
|
|
212
|
-
...additionalOpenItems,
|
|
213
|
-
...state.values.openItemIds,
|
|
214
|
-
};
|
|
272
|
+
}, []);
|
|
273
|
+
state.values.open.push(...additionalOpenItems);
|
|
215
274
|
}
|
|
216
275
|
}
|
|
217
276
|
break;
|
|
@@ -243,8 +302,7 @@ export const NavTreePlugin = (): PluginDefinition<NavTreePluginProvides> => {
|
|
|
243
302
|
},
|
|
244
303
|
properties: {
|
|
245
304
|
label: ['open commands label', { ns: NAVTREE_PLUGIN }],
|
|
246
|
-
icon:
|
|
247
|
-
iconSymbol: 'ph--magnifying-glass--regular',
|
|
305
|
+
icon: 'ph--magnifying-glass--regular',
|
|
248
306
|
keyBinding: {
|
|
249
307
|
macos: 'meta+k',
|
|
250
308
|
windows: 'ctrl+k',
|
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { DotOutline } from '@phosphor-icons/react';
|
|
6
5
|
import React, { useMemo, useState } from 'react';
|
|
7
6
|
|
|
8
7
|
import { useIntentDispatcher, LayoutAction } from '@dxos/app-framework';
|
|
9
8
|
import { type ActionLike, isActionGroup, isAction } from '@dxos/app-graph';
|
|
10
9
|
import { Keyboard, keySymbols } from '@dxos/keyboard';
|
|
11
10
|
import { useGraph } from '@dxos/plugin-graph';
|
|
12
|
-
import { Button, Dialog, useTranslation, toLocalizedString } from '@dxos/react-ui';
|
|
11
|
+
import { Button, Dialog, Icon, useTranslation, toLocalizedString } from '@dxos/react-ui';
|
|
13
12
|
import { SearchList } from '@dxos/react-ui-searchlist';
|
|
14
13
|
import { descriptionText, mx } from '@dxos/react-ui-theme';
|
|
15
14
|
import { getHostPlatform } from '@dxos/util';
|
|
@@ -70,7 +69,6 @@ export const CommandsDialogContent = ({ selected: initial }: { selected?: string
|
|
|
70
69
|
typeof action.properties.keyBinding === 'string'
|
|
71
70
|
? action.properties.keyBinding
|
|
72
71
|
: action.properties.keyBinding?.[getHostPlatform()];
|
|
73
|
-
const Icon = action.properties.icon ?? DotOutline;
|
|
74
72
|
return (
|
|
75
73
|
<SearchList.Item
|
|
76
74
|
value={label}
|
|
@@ -95,7 +93,7 @@ export const CommandsDialogContent = ({ selected: initial }: { selected?: string
|
|
|
95
93
|
disabled={action.properties.disabled}
|
|
96
94
|
{...(action.properties?.testId && { 'data-testid': action.properties.testId })}
|
|
97
95
|
>
|
|
98
|
-
<Icon
|
|
96
|
+
<Icon icon={action.properties.icon} size={4} />
|
|
99
97
|
<span className='grow truncate'>{label}</span>
|
|
100
98
|
{shortcut && <span className={mx('shrink-0', descriptionText)}>{keySymbols(shortcut).join('')}</span>}
|
|
101
99
|
</SearchList.Item>
|
|
@@ -4,16 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
|
+
import { type Meta } from '@storybook/react';
|
|
7
8
|
import React from 'react';
|
|
8
9
|
|
|
9
10
|
import { HaloButton } from './HaloButton';
|
|
10
11
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
component: HaloButton,
|
|
14
|
-
actions: { argTypesRegex: '^on.*' },
|
|
12
|
+
export const Default = (props: any) => {
|
|
13
|
+
return <HaloButton {...props} />;
|
|
15
14
|
};
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const meta: Meta<typeof HaloButton> = {
|
|
17
|
+
title: 'plugins/plugin-navtree/HaloButton',
|
|
18
|
+
component: HaloButton,
|
|
19
19
|
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { DotsThreeVertical } from '@phosphor-icons/react';
|
|
6
5
|
import React, { Fragment } from 'react';
|
|
7
6
|
|
|
8
7
|
import { getGraph, type Node } from '@dxos/app-graph';
|
|
@@ -22,7 +21,6 @@ export const NavBarStart = ({ activeNode, popoverAnchorId }: { activeNode: Node;
|
|
|
22
21
|
? Popover.Anchor
|
|
23
22
|
: Fragment;
|
|
24
23
|
|
|
25
|
-
const Icon = activeNode.properties?.icon ?? DotsThreeVertical;
|
|
26
24
|
const graph = getGraph(activeNode);
|
|
27
25
|
const actions = graph.actions(activeNode);
|
|
28
26
|
const label = toLocalizedString(activeNode.properties?.label, t);
|
|
@@ -33,10 +31,10 @@ export const NavBarStart = ({ activeNode, popoverAnchorId }: { activeNode: Node;
|
|
|
33
31
|
<>
|
|
34
32
|
<ActionRoot>
|
|
35
33
|
<PlankHeading.ActionsMenu
|
|
36
|
-
|
|
34
|
+
icon={activeNode.properties?.icon ?? 'ph--dots-three-vertical--regular'}
|
|
37
35
|
attendableId={activeNode.id}
|
|
38
36
|
triggerLabel={menuTriggerLabel}
|
|
39
|
-
actions={actions}
|
|
37
|
+
actions={[actions]}
|
|
40
38
|
onAction={(action) =>
|
|
41
39
|
typeof action.data === 'function' && action.data({ node: action as Node, caller: TREE_ITEM_MAIN_HEADING })
|
|
42
40
|
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxos-theme';
|
|
6
|
+
|
|
7
|
+
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
8
|
+
import { extractInstruction, type Instruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
|
|
9
|
+
import { type Meta } from '@storybook/react';
|
|
10
|
+
import React, { useEffect } from 'react';
|
|
11
|
+
|
|
12
|
+
import { type NodeArg } from '@dxos/app-graph';
|
|
13
|
+
import { create } from '@dxos/echo-schema';
|
|
14
|
+
import { faker } from '@dxos/random';
|
|
15
|
+
import { isItem } from '@dxos/react-ui-list';
|
|
16
|
+
import { Path } from '@dxos/react-ui-mosaic';
|
|
17
|
+
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
18
|
+
|
|
19
|
+
import { NavTree, type NavTreeProps } from './NavTree';
|
|
20
|
+
import { createTree, flattenTree, updateState } from '../testing';
|
|
21
|
+
import { type NavTreeItem } from '../types';
|
|
22
|
+
|
|
23
|
+
faker.seed(1234);
|
|
24
|
+
|
|
25
|
+
type State = {
|
|
26
|
+
tree: NodeArg<any>;
|
|
27
|
+
flatTree: NavTreeItem[];
|
|
28
|
+
open: string[];
|
|
29
|
+
current: string[];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const state = create<State>({
|
|
33
|
+
tree: createTree(),
|
|
34
|
+
get flatTree() {
|
|
35
|
+
return flattenTree(this.tree, this.open);
|
|
36
|
+
},
|
|
37
|
+
open: [],
|
|
38
|
+
current: [],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const Story = (args: Partial<NavTreeProps>) => {
|
|
42
|
+
// NOTE: If passed directly to args, this won't be reactive.
|
|
43
|
+
const items = state.flatTree;
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
return monitorForElements({
|
|
47
|
+
canMonitor: ({ source }) => isItem(source.data),
|
|
48
|
+
onDrop: ({ location, source }) => {
|
|
49
|
+
// Didn't drop on anything.
|
|
50
|
+
if (!location.current.dropTargets.length) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const target = location.current.dropTargets[0];
|
|
55
|
+
|
|
56
|
+
const instruction: Instruction | null = extractInstruction(target.data);
|
|
57
|
+
if (instruction !== null) {
|
|
58
|
+
updateState({
|
|
59
|
+
state: state.tree,
|
|
60
|
+
instruction,
|
|
61
|
+
source: source.data as NavTreeItem,
|
|
62
|
+
target: target.data as NavTreeItem,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}, []);
|
|
68
|
+
|
|
69
|
+
return <NavTree items={items} open={state.open} current={state.current} {...args} />;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const meta: Meta<typeof NavTree> = {
|
|
73
|
+
title: 'plugins/plugin-navtree/NavTree',
|
|
74
|
+
component: NavTree,
|
|
75
|
+
render: Story,
|
|
76
|
+
decorators: [withTheme, withLayout({ tooltips: true })],
|
|
77
|
+
args: {
|
|
78
|
+
onOpenChange: (item: NavTreeItem, open: boolean) => {
|
|
79
|
+
const path = Path.create(...item.path);
|
|
80
|
+
if (open) {
|
|
81
|
+
state.open.push(path);
|
|
82
|
+
} else {
|
|
83
|
+
const index = state.open.indexOf(path);
|
|
84
|
+
if (index > -1) {
|
|
85
|
+
state.open.splice(index, 1);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
onSelect: (item: NavTreeItem, current: boolean) => {
|
|
90
|
+
if (current) {
|
|
91
|
+
state.current.push(item.id);
|
|
92
|
+
} else {
|
|
93
|
+
const index = state.current.indexOf(item.id);
|
|
94
|
+
if (index > -1) {
|
|
95
|
+
state.current.splice(index, 1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export default meta;
|
|
103
|
+
|
|
104
|
+
export const Default = {};
|