@dxos/plugin-navtree 0.8.4-main.69d29f4 → 0.8.4-main.6fa680abb7
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/CommandsDialogContent-2DKIOLJL.mjs +113 -0
- package/dist/lib/browser/CommandsDialogContent-2DKIOLJL.mjs.map +7 -0
- package/dist/lib/browser/CommandsTrigger-ABODVVMP.mjs +33 -0
- package/dist/lib/browser/CommandsTrigger-ABODVVMP.mjs.map +7 -0
- package/dist/lib/browser/NavTreeContainer-TLSYS4KK.mjs +12 -0
- package/dist/lib/browser/NavTreeContainer-TLSYS4KK.mjs.map +7 -0
- package/dist/lib/browser/NavTreeDocumentTitle-L6NLLWLD.mjs +26 -0
- package/dist/lib/browser/NavTreeDocumentTitle-L6NLLWLD.mjs.map +7 -0
- package/dist/lib/browser/{app-graph-builder-RSMA6I22.mjs → app-graph-builder-Z43OTNI2.mjs} +6 -5
- package/dist/lib/browser/app-graph-builder-Z43OTNI2.mjs.map +7 -0
- package/dist/lib/browser/{chunk-YKTYPINZ.mjs → chunk-A4VDCIJC.mjs} +3 -3
- package/dist/lib/browser/{chunk-YKTYPINZ.mjs.map → chunk-A4VDCIJC.mjs.map} +1 -1
- package/dist/lib/browser/chunk-AYF2TX65.mjs +14 -0
- package/dist/lib/browser/chunk-AYF2TX65.mjs.map +7 -0
- package/dist/lib/browser/chunk-JT37R5HS.mjs +1468 -0
- package/dist/lib/browser/chunk-JT37R5HS.mjs.map +7 -0
- package/dist/lib/browser/{chunk-AGQDZBPL.mjs → chunk-KF26WA4O.mjs} +5 -5
- package/dist/lib/browser/{chunk-AGQDZBPL.mjs.map → chunk-KF26WA4O.mjs.map} +3 -3
- package/dist/lib/browser/index.mjs +35 -31
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{keyboard-32EH3N4K.mjs → keyboard-HYGFQO7T.mjs} +11 -6
- package/dist/lib/browser/keyboard-HYGFQO7T.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/operation-resolver-VDWVUII5.mjs +49 -0
- package/dist/lib/browser/operation-resolver-VDWVUII5.mjs.map +7 -0
- package/dist/lib/browser/{react-surface-F6CVMS3Y.mjs → react-surface-D2RLMV4Z.mjs} +15 -14
- package/dist/lib/browser/react-surface-D2RLMV4Z.mjs.map +7 -0
- package/dist/lib/browser/{state-EVYQOUI3.mjs → state-CWMNNF7K.mjs} +34 -23
- package/dist/lib/browser/state-CWMNNF7K.mjs.map +7 -0
- package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +1 -1
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/keyboard/keyboard.d.ts +1 -1
- package/dist/types/src/capabilities/keyboard/keyboard.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +1 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +2 -2
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/state/state.d.ts +1 -1
- package/dist/types/src/capabilities/state/state.d.ts.map +1 -1
- package/dist/types/src/components/NavTree/NavTree.d.ts +10 -32
- package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
- package/dist/types/src/components/NavTree/NavTree.stories.d.ts +2 -5
- package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
- package/dist/types/src/components/{NavTreeContext.d.ts → NavTreeContext/NavTreeContext.d.ts} +1 -1
- package/dist/types/src/components/NavTreeContext/NavTreeContext.d.ts.map +1 -0
- package/dist/types/src/components/NavTreeContext/index.d.ts +2 -0
- package/dist/types/src/components/NavTreeContext/index.d.ts.map +1 -0
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +4 -2
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L0Menu.d.ts +4 -1
- package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Panel.d.ts +3 -6
- package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Tabs.d.ts +3 -2
- package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -1
- package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +0 -3
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/types.d.ts +5 -13
- package/dist/types/src/components/types.d.ts.map +1 -1
- package/dist/types/src/{components/CommandsDialog/CommandsDialog.d.ts → containers/CommandsDialogContent/CommandsDialogContent.d.ts} +1 -1
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -0
- package/dist/types/src/containers/CommandsDialogContent/index.d.ts +3 -0
- package/dist/types/src/containers/CommandsDialogContent/index.d.ts.map +1 -0
- package/dist/types/src/containers/CommandsTrigger/CommandsTrigger.d.ts.map +1 -0
- package/dist/types/src/containers/CommandsTrigger/index.d.ts +3 -0
- package/dist/types/src/containers/CommandsTrigger/index.d.ts.map +1 -0
- package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts +9 -0
- package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -0
- package/dist/types/src/containers/NavTreeContainer/index.d.ts +3 -0
- package/dist/types/src/containers/NavTreeContainer/index.d.ts.map +1 -0
- package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -0
- package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +3 -0
- package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +7 -0
- package/dist/types/src/containers/index.d.ts.map +1 -0
- package/dist/types/src/experimental/Tree.stories.d.ts +18 -4
- package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +5 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useActions.d.ts +5 -0
- package/dist/types/src/hooks/useActions.d.ts.map +1 -0
- package/dist/types/src/hooks/useLoadDescendents.d.ts +6 -0
- package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -0
- package/dist/types/src/hooks/useNavTreeModel.d.ts +7 -0
- package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -0
- package/dist/types/src/{hooks.d.ts → hooks/useNavTreeState.d.ts} +2 -14
- package/dist/types/src/hooks/useNavTreeState.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +3 -3
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/types/events.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +5 -1
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +43 -42
- package/src/NavTreePlugin.tsx +22 -24
- package/src/capabilities/app-graph-builder/app-graph-builder.ts +4 -3
- package/src/capabilities/keyboard/keyboard.ts +6 -5
- package/src/capabilities/operation-resolver/operation-resolver.ts +23 -19
- package/src/capabilities/react-surface/react-surface.tsx +12 -13
- package/src/capabilities/state/state.ts +41 -13
- package/src/components/NavTree/NavTree.stories.tsx +21 -19
- package/src/components/NavTree/NavTree.tsx +61 -20
- package/src/components/{NavTreeContext.tsx → NavTreeContext/NavTreeContext.tsx} +1 -1
- package/src/components/NavTreeContext/index.ts +5 -0
- package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +2 -2
- package/src/components/NavTreeItem/NavTreeItemAction.tsx +40 -23
- package/src/components/NavTreeItem/NavTreeItemColumns.tsx +40 -14
- package/src/components/Sidebar/L0Menu.tsx +90 -74
- package/src/components/Sidebar/L1Panel.tsx +244 -90
- package/src/components/Sidebar/L1Tabs.tsx +13 -3
- package/src/components/UserAccountAvatar/UserAccountAvatar.stories.tsx +2 -3
- package/src/components/UserAccountAvatar/UserAccountAvatar.tsx +1 -1
- package/src/components/index.ts +0 -3
- package/src/components/types.ts +12 -17
- package/src/{components/CommandsDialog/CommandsDialog.tsx → containers/CommandsDialogContent/CommandsDialogContent.tsx} +19 -13
- package/src/containers/CommandsDialogContent/index.ts +7 -0
- package/src/{components/CommandsDialog → containers/CommandsTrigger}/CommandsTrigger.tsx +4 -4
- package/src/containers/CommandsTrigger/index.ts +7 -0
- package/src/{components → containers/NavTreeContainer}/NavTreeContainer.tsx +75 -141
- package/src/containers/NavTreeContainer/index.ts +6 -0
- package/src/{components → containers/NavTreeDocumentTitle}/NavTreeDocumentTitle.tsx +1 -1
- package/src/containers/NavTreeDocumentTitle/index.ts +7 -0
- package/src/containers/index.ts +12 -0
- package/src/experimental/Tree.stories.tsx +54 -57
- package/src/experimental/Tree.tsx +3 -3
- package/src/hooks/index.ts +8 -0
- package/src/hooks/useActions.ts +34 -0
- package/src/hooks/useLoadDescendents.ts +23 -0
- package/src/hooks/useNavTreeModel.ts +118 -0
- package/src/{hooks.ts → hooks/useNavTreeState.ts} +3 -34
- package/src/meta.ts +2 -2
- package/src/testing/app-graph-builder.ts +5 -5
- package/src/testing/generator.ts +4 -4
- package/src/types/capabilities.ts +1 -1
- package/src/types/events.ts +3 -2
- package/src/util.ts +18 -4
- package/dist/lib/browser/app-graph-builder-RSMA6I22.mjs.map +0 -7
- package/dist/lib/browser/chunk-6YPQ625I.mjs +0 -1293
- package/dist/lib/browser/chunk-6YPQ625I.mjs.map +0 -7
- package/dist/lib/browser/keyboard-32EH3N4K.mjs.map +0 -7
- package/dist/lib/browser/operation-resolver-IB75DC5O.mjs +0 -52
- package/dist/lib/browser/operation-resolver-IB75DC5O.mjs.map +0 -7
- package/dist/lib/browser/react-surface-F6CVMS3Y.mjs.map +0 -7
- package/dist/lib/browser/state-EVYQOUI3.mjs.map +0 -7
- package/dist/types/src/components/CommandsDialog/CommandsDialog.d.ts.map +0 -1
- package/dist/types/src/components/CommandsDialog/CommandsTrigger.d.ts.map +0 -1
- package/dist/types/src/components/CommandsDialog/index.d.ts +0 -3
- package/dist/types/src/components/CommandsDialog/index.d.ts.map +0 -1
- package/dist/types/src/components/NavTreeContainer.d.ts +0 -16
- package/dist/types/src/components/NavTreeContainer.d.ts.map +0 -1
- package/dist/types/src/components/NavTreeContext.d.ts.map +0 -1
- package/dist/types/src/components/NavTreeDocumentTitle.d.ts.map +0 -1
- package/dist/types/src/hooks.d.ts.map +0 -1
- package/src/components/CommandsDialog/index.ts +0 -6
- /package/dist/types/src/{components/CommandsDialog → containers/CommandsTrigger}/CommandsTrigger.d.ts +0 -0
- /package/dist/types/src/{components → containers/NavTreeDocumentTitle}/NavTreeDocumentTitle.d.ts +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Atom } from '@effect-atom/atom-react';
|
|
6
|
+
import * as Option from 'effect/Option';
|
|
7
|
+
import { useMemo } from 'react';
|
|
8
|
+
|
|
9
|
+
import { useAppGraph } from '@dxos/app-toolkit/ui';
|
|
10
|
+
import { PLANK_COMPANION_TYPE } from '@dxos/plugin-deck/types';
|
|
11
|
+
import { type Node } from '@dxos/plugin-graph';
|
|
12
|
+
import { Path, type TreeModel } from '@dxos/react-ui-list';
|
|
13
|
+
import { mx } from '@dxos/ui-theme';
|
|
14
|
+
|
|
15
|
+
import { type NavTreeItemGraphNode } from '../types';
|
|
16
|
+
import { filterItems } from '../util';
|
|
17
|
+
|
|
18
|
+
import { useNavTreeState } from './useNavTreeState';
|
|
19
|
+
|
|
20
|
+
// TODO(wittjosiah): Move companion/hidden nodes to their own edge categories so this filter is unnecessary.
|
|
21
|
+
const isVisibleChild = (node: Node.Node): boolean =>
|
|
22
|
+
node.type !== PLANK_COMPANION_TYPE && node.properties.disposition !== 'hidden';
|
|
23
|
+
|
|
24
|
+
/** Create an atom family for item display props keyed by path. */
|
|
25
|
+
const createItemPropsFamily = (graph: ReturnType<typeof useAppGraph>['graph']) =>
|
|
26
|
+
Atom.family((pathKey: string) => {
|
|
27
|
+
const path = Path.parts(pathKey);
|
|
28
|
+
const id = Path.last(pathKey);
|
|
29
|
+
return Atom.make((get) => {
|
|
30
|
+
const nodeOpt = get(graph.node(id));
|
|
31
|
+
const node = Option.getOrElse(nodeOpt, () => undefined);
|
|
32
|
+
if (!node) {
|
|
33
|
+
return { id, label: id };
|
|
34
|
+
}
|
|
35
|
+
const safeChildren = get(graph.connections(node.id, 'child')).filter((child) => !path.includes(child.id));
|
|
36
|
+
const visibleChildren = safeChildren.filter(isVisibleChild);
|
|
37
|
+
const parentOf =
|
|
38
|
+
visibleChildren.length > 0
|
|
39
|
+
? visibleChildren.map((child) => child.id)
|
|
40
|
+
: node.properties.role === 'branch'
|
|
41
|
+
? []
|
|
42
|
+
: undefined;
|
|
43
|
+
const parentId = path.length >= 2 ? path[path.length - 2] : undefined;
|
|
44
|
+
const parentNode = parentId ? Option.getOrElse(get(graph.node(parentId)), () => undefined) : undefined;
|
|
45
|
+
const droppable =
|
|
46
|
+
node.properties.droppable === false || parentNode?.properties.childrenDroppable === false ? false : undefined;
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
id: node.id,
|
|
50
|
+
parentOf,
|
|
51
|
+
disabled: node.properties.disabled,
|
|
52
|
+
draggable: node.properties.draggable,
|
|
53
|
+
droppable,
|
|
54
|
+
label: node.properties.label ?? node.id,
|
|
55
|
+
className: mx(node.properties.className, node.properties.modified && 'italic'),
|
|
56
|
+
headingClassName: node.properties.headingClassName,
|
|
57
|
+
icon: node.properties.icon,
|
|
58
|
+
iconHue: node.properties.iconHue,
|
|
59
|
+
testId: node.properties.testId,
|
|
60
|
+
};
|
|
61
|
+
}).pipe(Atom.keepAlive);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
/** Create an atom family for outbound child IDs keyed by parent ID (pre-sorted by position on write). */
|
|
65
|
+
const createChildIdsFamily = (graph: ReturnType<typeof useAppGraph>['graph']) =>
|
|
66
|
+
Atom.family((id: string) =>
|
|
67
|
+
Atom.make((get) => get(graph.connections(id, 'child')).map((child) => child.id)).pipe(Atom.keepAlive),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
/** Create an atom family for item resolution keyed by ID. */
|
|
71
|
+
const createItemFamily = (graph: ReturnType<typeof useAppGraph>['graph']) =>
|
|
72
|
+
Atom.family((id: string) =>
|
|
73
|
+
Atom.make((get) => {
|
|
74
|
+
const node = Option.getOrElse(get(graph.node(id)), () => undefined);
|
|
75
|
+
return node && filterItems(node) ? node : undefined;
|
|
76
|
+
}).pipe(Atom.keepAlive),
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
/** Create an atom family for open state keyed by path. */
|
|
80
|
+
const createItemOpenFamily = (getItemAtom: ReturnType<typeof useNavTreeState>['getItemAtom']) =>
|
|
81
|
+
Atom.family((pathKey: string) => {
|
|
82
|
+
const path = Path.parts(pathKey);
|
|
83
|
+
const stateAtom = getItemAtom(path);
|
|
84
|
+
return Atom.make((get) => get(stateAtom).open).pipe(Atom.keepAlive);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
/** Create an atom family for current (selected) state keyed by path. */
|
|
88
|
+
const createItemCurrentFamily = (getItemAtom: ReturnType<typeof useNavTreeState>['getItemAtom']) =>
|
|
89
|
+
Atom.family((pathKey: string) => {
|
|
90
|
+
const path = Path.parts(pathKey);
|
|
91
|
+
const stateAtom = getItemAtom(path);
|
|
92
|
+
return Atom.make((get) => get(stateAtom).current).pipe(Atom.keepAlive);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Creates a TreeModel backed by the app graph and navtree state.
|
|
97
|
+
*/
|
|
98
|
+
export const useNavTreeModel = (rootId: string): TreeModel<NavTreeItemGraphNode> => {
|
|
99
|
+
const { graph } = useAppGraph();
|
|
100
|
+
const { getItemAtom } = useNavTreeState();
|
|
101
|
+
|
|
102
|
+
const itemPropsFamily = useMemo(() => createItemPropsFamily(graph), [graph]);
|
|
103
|
+
const childIdsFamily = useMemo(() => createChildIdsFamily(graph), [graph]);
|
|
104
|
+
const itemFamily = useMemo(() => createItemFamily(graph), [graph]);
|
|
105
|
+
const itemOpenFamily = useMemo(() => createItemOpenFamily(getItemAtom), [getItemAtom]);
|
|
106
|
+
const itemCurrentFamily = useMemo(() => createItemCurrentFamily(getItemAtom), [getItemAtom]);
|
|
107
|
+
|
|
108
|
+
return useMemo(
|
|
109
|
+
() => ({
|
|
110
|
+
item: (id: string) => itemFamily(id),
|
|
111
|
+
itemProps: (path: string[]) => itemPropsFamily(Path.create(...path)),
|
|
112
|
+
itemOpen: (path: string[]) => itemOpenFamily(Path.create(...path)),
|
|
113
|
+
itemCurrent: (path: string[]) => itemCurrentFamily(Path.create(...path)),
|
|
114
|
+
childIds: (parentId?: string) => childIdsFamily(parentId ?? rootId),
|
|
115
|
+
}),
|
|
116
|
+
[itemFamily, itemPropsFamily, itemOpenFamily, itemCurrentFamily, childIdsFamily, rootId],
|
|
117
|
+
);
|
|
118
|
+
};
|
|
@@ -3,25 +3,11 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Atom, useAtomValue } from '@effect-atom/atom-react';
|
|
6
|
-
import {
|
|
6
|
+
import { useMemo } from 'react';
|
|
7
7
|
|
|
8
|
-
import { useCapability } from '@dxos/app-framework/
|
|
9
|
-
import { type Node } from '@dxos/app-graph';
|
|
8
|
+
import { useCapability } from '@dxos/app-framework/ui';
|
|
10
9
|
|
|
11
|
-
import {
|
|
12
|
-
import { NavTreeCapabilities } from './types';
|
|
13
|
-
|
|
14
|
-
export const useLoadDescendents = (root?: Node.Node) => {
|
|
15
|
-
const { loadDescendents } = useNavTreeContext();
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
const frame = requestAnimationFrame(() => {
|
|
18
|
-
if (root) {
|
|
19
|
-
void loadDescendents?.(root);
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
return () => cancelAnimationFrame(frame);
|
|
23
|
-
}, [root]);
|
|
24
|
-
};
|
|
10
|
+
import { NavTreeCapabilities } from '../types';
|
|
25
11
|
|
|
26
12
|
export type UseNavTreeStateResult = {
|
|
27
13
|
getItem: (path: string[]) => NavTreeCapabilities.NavTreeItemState;
|
|
@@ -43,28 +29,11 @@ export const useNavTreeState = (): UseNavTreeStateResult => {
|
|
|
43
29
|
*/
|
|
44
30
|
export const useNavTreeItemState = (path: string[]): NavTreeCapabilities.NavTreeItemState => {
|
|
45
31
|
const { getItemAtom } = useCapability(NavTreeCapabilities.State);
|
|
46
|
-
// Memoize the path to avoid creating new atoms on every render.
|
|
47
32
|
const pathKey = useMemo(() => path.join('~'), [path]);
|
|
48
33
|
const atom = useMemo(() => getItemAtom(path), [getItemAtom, pathKey]);
|
|
49
34
|
return useAtomValue(atom);
|
|
50
35
|
};
|
|
51
36
|
|
|
52
|
-
/**
|
|
53
|
-
* Hook that subscribes to the open state for a tree item.
|
|
54
|
-
* Designed to be passed to Tree component as useIsOpen prop.
|
|
55
|
-
*/
|
|
56
|
-
export const useIsOpen = (path: string[], _item?: any): boolean => {
|
|
57
|
-
return useNavTreeItemState(path).open;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Hook that subscribes to the current state for a tree item.
|
|
62
|
-
* Designed to be passed to Tree component as useIsCurrent prop.
|
|
63
|
-
*/
|
|
64
|
-
export const useIsCurrent = (path: string[], _item?: any): boolean => {
|
|
65
|
-
return useNavTreeItemState(path).current;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
37
|
/**
|
|
69
38
|
* Hook that subscribes to the alternateTree state for a tree item.
|
|
70
39
|
*/
|
package/src/meta.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { type Plugin } from '@dxos/app-framework';
|
|
|
6
6
|
import { trim } from '@dxos/util';
|
|
7
7
|
|
|
8
8
|
export const meta: Plugin.Meta = {
|
|
9
|
-
id: 'dxos.
|
|
9
|
+
id: 'org.dxos.plugin.navtree',
|
|
10
10
|
name: 'Navtree',
|
|
11
11
|
description: trim`
|
|
12
12
|
Hierarchical navigation tree for browsing spaces, folders, and objects.
|
|
@@ -17,4 +17,4 @@ export const meta: Plugin.Meta = {
|
|
|
17
17
|
// TODO(wittjosiah): Factor out.
|
|
18
18
|
export const KEY_BINDING = 'KeyBinding';
|
|
19
19
|
// TODO(wittjosiah): Factor out.
|
|
20
|
-
export const COMMANDS_DIALOG = `${meta.id}
|
|
20
|
+
export const COMMANDS_DIALOG = `${meta.id}.commands-dialog`;
|
|
@@ -31,7 +31,7 @@ export const storybookGraphBuilders = (): BuilderExtensions => {
|
|
|
31
31
|
actions: () =>
|
|
32
32
|
Effect.succeed(
|
|
33
33
|
Array.from({ length: 5 }, (_, i) => ({
|
|
34
|
-
id: `
|
|
34
|
+
id: `action-${i}`,
|
|
35
35
|
data: Effect.fnUntraced(function* () {
|
|
36
36
|
log.info('action', { id: 'app-menu', index: i });
|
|
37
37
|
}),
|
|
@@ -130,11 +130,11 @@ export const storybookGraphBuilders = (): BuilderExtensions => {
|
|
|
130
130
|
actions: () =>
|
|
131
131
|
Effect.succeed(
|
|
132
132
|
Array.from({ length: 5 }, (_, i) => ({
|
|
133
|
-
id: `
|
|
133
|
+
id: `action-${i}`,
|
|
134
134
|
data: Effect.fnUntraced(function* () {
|
|
135
135
|
log.info('action', { id: 'space-actions', index: i });
|
|
136
136
|
}),
|
|
137
|
-
properties: getProperties(`
|
|
137
|
+
properties: getProperties(`action-${i}`, {
|
|
138
138
|
label: `Action ${i}`,
|
|
139
139
|
icon: faker.properties.icon(),
|
|
140
140
|
}),
|
|
@@ -179,11 +179,11 @@ export const storybookGraphBuilders = (): BuilderExtensions => {
|
|
|
179
179
|
actions: () =>
|
|
180
180
|
Effect.succeed(
|
|
181
181
|
Array.from({ length: 5 }, (_, i) => ({
|
|
182
|
-
id: `
|
|
182
|
+
id: `action-${i}`,
|
|
183
183
|
data: Effect.fnUntraced(function* () {
|
|
184
184
|
log.info('action', { id: 'object-actions', index: i });
|
|
185
185
|
}),
|
|
186
|
-
properties: getProperties(`
|
|
186
|
+
properties: getProperties(`action-${i}`, {
|
|
187
187
|
label: `Action ${i}`,
|
|
188
188
|
icon: faker.properties.icon(),
|
|
189
189
|
}),
|
package/src/testing/generator.ts
CHANGED
|
@@ -17,12 +17,12 @@ import { range } from '@dxos/util';
|
|
|
17
17
|
export type TestItem = { id: string; type: string } & Record<string, any>;
|
|
18
18
|
|
|
19
19
|
type ObjectDataGenerator = {
|
|
20
|
-
createSchema?: () => Type.
|
|
20
|
+
createSchema?: () => Type.AnyObj;
|
|
21
21
|
createData: () => any;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
type ObjectFactory<T> = {
|
|
25
|
-
schema?: Type.
|
|
25
|
+
schema?: Type.AnyObj; // TODO(burdon): Support both typed and expando schema.
|
|
26
26
|
createObject: () => T;
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -65,7 +65,7 @@ export const defaultGenerators: { [type: string]: ObjectDataGenerator } = {
|
|
|
65
65
|
priority: Schema.Number,
|
|
66
66
|
}).pipe(
|
|
67
67
|
Type.object({
|
|
68
|
-
typename: 'example.
|
|
68
|
+
typename: 'com.example.type.project',
|
|
69
69
|
version: '0.1.0',
|
|
70
70
|
}),
|
|
71
71
|
),
|
|
@@ -94,7 +94,7 @@ export class TestObjectGenerator {
|
|
|
94
94
|
}, {});
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
get schema(): Type.
|
|
97
|
+
get schema(): Type.AnyObj[] {
|
|
98
98
|
return Object.values(this.factories).map((f) => f.schema!);
|
|
99
99
|
}
|
|
100
100
|
|
|
@@ -17,5 +17,5 @@ export namespace NavTreeCapabilities {
|
|
|
17
17
|
setItem: (path: string[], key: 'open' | 'current' | 'alternateTree', next: boolean) => void;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
export const State = Capability.make<NavTreeStateStore>(`${meta.id}
|
|
20
|
+
export const State = Capability.make<NavTreeStateStore>(`${meta.id}.capability.state`);
|
|
21
21
|
}
|
package/src/types/events.ts
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type ActivationEvent
|
|
5
|
+
import { type ActivationEvent } from '@dxos/app-framework';
|
|
6
|
+
import { AppActivationEvents } from '@dxos/app-toolkit';
|
|
6
7
|
|
|
7
8
|
import { meta } from '../meta';
|
|
8
9
|
|
|
9
10
|
export namespace NavTreeEvents {
|
|
10
|
-
export const StateReady: ActivationEvent.ActivationEvent =
|
|
11
|
+
export const StateReady: ActivationEvent.ActivationEvent = AppActivationEvents.createStateEvent(meta.id);
|
|
11
12
|
}
|
package/src/util.ts
CHANGED
|
@@ -13,9 +13,9 @@ export const getParent = (
|
|
|
13
13
|
path: string[],
|
|
14
14
|
): NavTreeItemGraphNode | undefined => {
|
|
15
15
|
const parentId = path[path.length - 2];
|
|
16
|
-
return Graph.getConnections(graph, node.id, 'inbound').find(
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
return Graph.getConnections(graph, node.id, Node.childRelation('inbound')).find(
|
|
17
|
+
(n: Node.Node) => n.id === parentId,
|
|
18
|
+
) as NavTreeItemGraphNode | undefined;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
export const getPersistenceParent = (
|
|
@@ -80,7 +80,7 @@ export const getChildren = (
|
|
|
80
80
|
node: NavTreeItemGraphNode,
|
|
81
81
|
path: readonly string[] = [],
|
|
82
82
|
): NavTreeItemGraphNode[] => {
|
|
83
|
-
return Graph.getConnections(graph, node.id, '
|
|
83
|
+
return Graph.getConnections(graph, node.id, 'child')
|
|
84
84
|
.map((n: Node.Node) => {
|
|
85
85
|
// Break cycles.
|
|
86
86
|
const nextPath = [...path, node.id];
|
|
@@ -89,6 +89,20 @@ export const getChildren = (
|
|
|
89
89
|
.filter(isNonNullable) as NavTreeItemGraphNode[];
|
|
90
90
|
};
|
|
91
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Determines whether a node should be visible based on its disposition.
|
|
94
|
+
*/
|
|
95
|
+
export const filterItems = (node: Node.Node, disposition?: string) => {
|
|
96
|
+
if (!disposition && (node.properties.disposition === 'hidden' || node.properties.disposition === 'alternate-tree')) {
|
|
97
|
+
return false;
|
|
98
|
+
} else if (!disposition) {
|
|
99
|
+
const action = Node.isAction(node);
|
|
100
|
+
return !action || node.properties.disposition === 'item';
|
|
101
|
+
} else {
|
|
102
|
+
return node.properties.disposition === disposition;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
92
106
|
export const l0ItemType = (item: Node.Node) => {
|
|
93
107
|
if (Node.isActionLike(item)) {
|
|
94
108
|
return 'action';
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/app-graph-builder/app-graph-builder.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability, Common } from '@dxos/app-framework';\nimport { Operation } from '@dxos/operation';\nimport { GraphBuilder, NodeMatcher } from '@dxos/plugin-graph';\n\nimport { COMMANDS_DIALOG, meta } from '../../meta';\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n const extensions = yield* GraphBuilder.createExtension({\n id: meta.id,\n match: NodeMatcher.whenRoot,\n actions: () =>\n Effect.succeed([\n {\n id: COMMANDS_DIALOG,\n data: () =>\n Operation.invoke(Common.LayoutOperation.UpdateDialog, {\n subject: COMMANDS_DIALOG,\n blockAlign: 'start',\n }),\n properties: {\n label: ['open commands label', { ns: meta.id }],\n icon: 'ph--magnifying-glass--regular',\n keyBinding: {\n macos: 'meta+k',\n windows: 'ctrl+k',\n },\n },\n },\n ]),\n });\n\n return Capability.contributes(Common.Capability.AppGraphBuilder, extensions);\n }),\n);\n"],
|
|
5
|
-
"mappings": ";;;;;;AAIA,YAAYA,YAAY;AAExB,SAASC,YAAYC,cAAc;AACnC,SAASC,iBAAiB;AAC1B,SAASC,cAAcC,mBAAmB;AAI1C,IAAA,4BAAeC,WAAWC,WACjBC,kBAAW,aAAA;AAChB,QAAMC,aAAa,OAAOC,aAAaC,gBAAgB;IACrDC,IAAIC,KAAKD;IACTE,OAAOC,YAAYC;IACnBC,SAAS,MACAC,eAAQ;MACb;QACEN,IAAIO;QACJC,MAAM,MACJC,UAAUC,OAAOC,OAAOC,gBAAgBC,cAAc;UACpDC,SAASP;UACTQ,YAAY;QACd,CAAA;QACFC,YAAY;UACVC,OAAO;YAAC;YAAuB;cAAEC,IAAIjB,KAAKD;YAAG;;UAC7CmB,MAAM;UACNC,YAAY;YACVC,OAAO;YACPC,SAAS;UACX;QACF;MACF;KACD;EACL,CAAA;AAEA,SAAO5B,WAAW6B,YAAYZ,OAAOjB,WAAW8B,iBAAiB3B,UAAAA;AACnE,CAAA,CAAA;",
|
|
6
|
-
"names": ["Effect", "Capability", "Common", "Operation", "GraphBuilder", "NodeMatcher", "Capability", "makeModule", "fnUntraced", "extensions", "GraphBuilder", "createExtension", "id", "meta", "match", "NodeMatcher", "whenRoot", "actions", "succeed", "COMMANDS_DIALOG", "data", "Operation", "invoke", "Common", "LayoutOperation", "UpdateDialog", "subject", "blockAlign", "properties", "label", "ns", "icon", "keyBinding", "macos", "windows", "contributes", "AppGraphBuilder"]
|
|
7
|
-
}
|