@dxos/plugin-navtree 0.8.4-main.c85a9c8dae → 0.8.4-main.d9fc60f731
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/LICENSE +102 -5
- package/PLUGIN.mdl +376 -0
- package/README.md +1 -1
- package/dist/lib/{browser/CommandsDialogContent-A27AKTHH.mjs → neutral/CommandsDialogContent-UBGIQ5FI.mjs} +24 -23
- package/dist/lib/neutral/CommandsDialogContent-UBGIQ5FI.mjs.map +7 -0
- package/dist/lib/{browser/CommandsTrigger-HBZYQCGV.mjs → neutral/CommandsTrigger-BH5WLMHK.mjs} +8 -14
- package/dist/lib/neutral/CommandsTrigger-BH5WLMHK.mjs.map +7 -0
- package/dist/lib/neutral/NavTreeContainer-6AR4BFDD.mjs +12 -0
- package/dist/lib/neutral/NavTreeContainer-6AR4BFDD.mjs.map +7 -0
- package/dist/lib/{browser/NavTreeDocumentTitle-GEE3URWH.mjs → neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs} +5 -9
- package/dist/lib/neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs.map +7 -0
- package/dist/lib/neutral/NavTreePlugin.mjs +68 -0
- package/dist/lib/neutral/NavTreePlugin.mjs.map +7 -0
- package/dist/lib/neutral/NavTreePlugin.node.mjs +18 -0
- package/dist/lib/neutral/NavTreePlugin.node.mjs.map +7 -0
- package/dist/lib/neutral/NavTreePlugin.workerd.mjs +16 -0
- package/dist/lib/neutral/NavTreePlugin.workerd.mjs.map +7 -0
- package/dist/lib/{browser/app-graph-builder-XGA4GPGL.mjs → neutral/app-graph-builder-Z347LKSF.mjs} +10 -12
- package/dist/lib/neutral/app-graph-builder-Z347LKSF.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/index.mjs +17 -0
- package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
- package/dist/lib/neutral/chunk-5OPDKH6B.mjs +273 -0
- package/dist/lib/neutral/chunk-5OPDKH6B.mjs.map +7 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/neutral/chunk-JOSNCOV4.mjs +79 -0
- package/dist/lib/neutral/chunk-JOSNCOV4.mjs.map +7 -0
- package/dist/lib/neutral/chunk-MDGKDQMZ.mjs +37 -0
- package/dist/lib/neutral/chunk-MDGKDQMZ.mjs.map +7 -0
- package/dist/lib/neutral/chunk-T7QS2EFI.mjs +8 -0
- package/dist/lib/neutral/chunk-T7QS2EFI.mjs.map +7 -0
- package/dist/lib/neutral/chunk-ZSWYB7JW.mjs +27 -0
- package/dist/lib/neutral/chunk-ZSWYB7JW.mjs.map +7 -0
- package/dist/lib/neutral/components/index.mjs +807 -0
- package/dist/lib/neutral/components/index.mjs.map +7 -0
- package/dist/lib/neutral/containers/index.mjs +20 -0
- package/dist/lib/neutral/containers/index.mjs.map +7 -0
- package/dist/lib/neutral/expose-26FV4W5D.mjs +38 -0
- package/dist/lib/neutral/expose-26FV4W5D.mjs.map +7 -0
- package/dist/lib/neutral/hooks/index.mjs +178 -0
- package/dist/lib/neutral/hooks/index.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +34 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/{browser/keyboard-OJZC54PK.mjs → neutral/keyboard-EJ65BVTC.mjs} +8 -6
- package/dist/lib/neutral/keyboard-EJ65BVTC.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/meta.mjs +12 -0
- package/dist/lib/neutral/meta.mjs.map +7 -0
- package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs +13 -0
- package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs.map +7 -0
- package/dist/lib/neutral/operations/index.mjs +8 -0
- package/dist/lib/neutral/operations/index.mjs.map +7 -0
- package/dist/lib/neutral/plugin.mjs +16 -0
- package/dist/lib/neutral/plugin.mjs.map +7 -0
- package/dist/lib/{browser/react-surface-AYHOAJ4I.mjs → neutral/react-surface-Q5XMAG7Z.mjs} +11 -20
- package/dist/lib/neutral/react-surface-Q5XMAG7Z.mjs.map +7 -0
- package/dist/lib/{browser/state-AC3EETN7.mjs → neutral/state-VVITVXWM.mjs} +7 -11
- package/dist/lib/neutral/state-VVITVXWM.mjs.map +7 -0
- package/dist/lib/neutral/testing/index.mjs +439 -0
- package/dist/lib/neutral/testing/index.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +23 -0
- package/dist/lib/neutral/translations.mjs.map +7 -0
- package/dist/lib/neutral/types/index.mjs +10 -0
- package/dist/lib/neutral/types/index.mjs.map +7 -0
- package/dist/types/src/NavTreePlugin.d.ts +1 -0
- package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
- package/dist/types/src/NavTreePlugin.node.d.ts +4 -0
- package/dist/types/src/NavTreePlugin.node.d.ts.map +1 -0
- package/dist/types/src/NavTreePlugin.test.d.ts +2 -0
- package/dist/types/src/NavTreePlugin.test.d.ts.map +1 -0
- package/dist/types/src/NavTreePlugin.workerd.d.ts +4 -0
- package/dist/types/src/NavTreePlugin.workerd.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +7 -5
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/keyboard.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/state.d.ts +6 -0
- package/dist/types/src/capabilities/state.d.ts.map +1 -0
- package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
- package/dist/types/src/components/NavTree/NavTree.stories.d.ts +9 -11
- 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 +7 -3
- 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/NavTreeItemAction.stories.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -1
- package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.d.ts.map +1 -1
- package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
- package/dist/types/src/components/types.d.ts +1 -2
- package/dist/types/src/components/types.d.ts.map +1 -1
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -1
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts +28 -0
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts.map +1 -0
- package/dist/types/src/containers/CommandsDialogContent/index.d.ts +1 -2
- package/dist/types/src/containers/CommandsDialogContent/index.d.ts.map +1 -1
- package/dist/types/src/containers/CommandsTrigger/CommandsTrigger.d.ts.map +1 -1
- package/dist/types/src/containers/CommandsTrigger/index.d.ts +1 -2
- package/dist/types/src/containers/CommandsTrigger/index.d.ts.map +1 -1
- package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -1
- package/dist/types/src/containers/NavTreeContainer/index.d.ts +2 -2
- package/dist/types/src/containers/NavTreeContainer/index.d.ts.map +1 -1
- package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -1
- package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +1 -2
- package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts.map +1 -1
- package/dist/types/src/containers/index.d.ts +1 -1
- package/dist/types/src/containers/index.d.ts.map +1 -1
- package/dist/types/src/experimental/Tree.d.ts +2 -2
- package/dist/types/src/experimental/Tree.d.ts.map +1 -1
- package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useActions.d.ts +6 -2
- package/dist/types/src/hooks/useActions.d.ts.map +1 -1
- package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -1
- package/dist/types/src/hooks/useNavTreeModel.d.ts +1 -1
- package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -1
- package/dist/types/src/hooks/useNavTreeState.d.ts +2 -6
- package/dist/types/src/hooks/useNavTreeState.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +3 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/operations/expose.d.ts +5 -0
- package/dist/types/src/operations/expose.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +3 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/plugin.d.ts +4 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/testing/update-state.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +8 -11
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/NavTreeCapabilities.d.ts +13 -0
- package/dist/types/src/types/NavTreeCapabilities.d.ts.map +1 -0
- package/dist/types/src/types/NavTreeEvents.d.ts +3 -0
- package/dist/types/src/types/NavTreeEvents.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -2
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +4 -0
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +2 -2
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +110 -50
- package/src/NavTreePlugin.node.ts +17 -0
- package/src/NavTreePlugin.test.ts +27 -0
- package/src/NavTreePlugin.tsx +16 -27
- package/src/NavTreePlugin.workerd.ts +16 -0
- package/src/capabilities/{app-graph-builder/app-graph-builder.ts → app-graph-builder.ts} +7 -7
- package/src/capabilities/index.ts +11 -5
- package/src/capabilities/{keyboard/keyboard.ts → keyboard.ts} +2 -2
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +9 -9
- package/src/capabilities/{state/state.ts → state.ts} +14 -10
- package/src/components/NavTree/NavTree.stories.tsx +23 -24
- package/src/components/NavTree/NavTree.tsx +5 -4
- 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 +8 -10
- package/src/components/NavTreeItem/NavTreeItemAction.tsx +66 -48
- package/src/components/NavTreeItem/NavTreeItemColumns.tsx +22 -63
- package/src/components/Sidebar/L0Menu.tsx +62 -81
- package/src/components/Sidebar/L1Panel.tsx +99 -158
- package/src/components/Sidebar/L1Tabs.tsx +0 -1
- package/src/components/types.ts +1 -2
- package/src/containers/CommandsDialogContent/CommandsDialogContent.stories.tsx +46 -0
- package/src/containers/CommandsDialogContent/CommandsDialogContent.tsx +52 -58
- package/src/containers/CommandsDialogContent/index.ts +1 -3
- package/src/containers/CommandsTrigger/CommandsTrigger.tsx +7 -5
- package/src/containers/CommandsTrigger/index.ts +1 -3
- package/src/containers/NavTreeContainer/NavTreeContainer.tsx +28 -27
- package/src/containers/NavTreeContainer/index.ts +2 -3
- package/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.tsx +2 -2
- package/src/containers/NavTreeDocumentTitle/index.ts +1 -3
- package/src/containers/index.ts +1 -1
- package/src/experimental/Tree.stories.tsx +27 -27
- package/src/experimental/Tree.tsx +2 -2
- package/src/hooks/useActions.ts +26 -20
- package/src/hooks/useNavTreeModel.ts +13 -5
- package/src/hooks/useNavTreeState.ts +2 -9
- package/src/index.ts +1 -2
- package/src/meta.ts +22 -7
- package/src/operations/expose.ts +42 -0
- package/src/operations/index.ts +7 -0
- package/src/plugin.ts +11 -0
- package/src/testing/app-graph-builder.ts +47 -41
- package/src/testing/generator.ts +23 -28
- package/src/translations.ts +8 -10
- package/src/types/NavTreeCapabilities.ts +21 -0
- package/src/types/NavTreeEvents.ts +12 -0
- package/src/types/index.ts +3 -2
- package/src/types/schema.ts +4 -0
- package/src/util.ts +2 -2
- package/src/vite-env.d.ts +10 -0
- package/dist/lib/browser/CommandsDialogContent-A27AKTHH.mjs.map +0 -7
- package/dist/lib/browser/CommandsTrigger-HBZYQCGV.mjs.map +0 -7
- package/dist/lib/browser/NavTreeContainer-B5K4FUJS.mjs +0 -12
- package/dist/lib/browser/NavTreeContainer-B5K4FUJS.mjs.map +0 -7
- package/dist/lib/browser/NavTreeDocumentTitle-GEE3URWH.mjs.map +0 -7
- package/dist/lib/browser/app-graph-builder-XGA4GPGL.mjs.map +0 -7
- package/dist/lib/browser/chunk-DQCYMXEU.mjs +0 -1426
- package/dist/lib/browser/chunk-DQCYMXEU.mjs.map +0 -7
- package/dist/lib/browser/chunk-H3OJ4WLF.mjs +0 -14
- package/dist/lib/browser/chunk-H3OJ4WLF.mjs.map +0 -7
- package/dist/lib/browser/chunk-X2HDG62A.mjs +0 -23
- package/dist/lib/browser/chunk-X2HDG62A.mjs.map +0 -7
- package/dist/lib/browser/chunk-YKTYPINZ.mjs +0 -19
- package/dist/lib/browser/chunk-YKTYPINZ.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -141
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/keyboard-OJZC54PK.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/operation-resolver-BNAMYOHF.mjs +0 -53
- package/dist/lib/browser/operation-resolver-BNAMYOHF.mjs.map +0 -7
- package/dist/lib/browser/react-surface-AYHOAJ4I.mjs.map +0 -7
- package/dist/lib/browser/state-AC3EETN7.mjs.map +0 -7
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/keyboard/index.d.ts +0 -3
- package/dist/types/src/capabilities/keyboard/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/keyboard/keyboard.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
- package/dist/types/src/capabilities/state/index.d.ts +0 -3
- package/dist/types/src/capabilities/state/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/state/state.d.ts +0 -6
- package/dist/types/src/capabilities/state/state.d.ts.map +0 -1
- package/dist/types/src/components/NavTreeContext.d.ts.map +0 -1
- package/dist/types/src/types/capabilities.d.ts +0 -16
- package/dist/types/src/types/capabilities.d.ts.map +0 -1
- package/dist/types/src/types/events.d.ts +0 -5
- package/dist/types/src/types/events.d.ts.map +0 -1
- package/src/capabilities/app-graph-builder/index.ts +0 -7
- package/src/capabilities/keyboard/index.ts +0 -7
- package/src/capabilities/operation-resolver/index.ts +0 -7
- package/src/capabilities/operation-resolver/operation-resolver.ts +0 -44
- package/src/capabilities/react-surface/index.ts +0 -7
- package/src/capabilities/state/index.ts +0 -7
- package/src/types/capabilities.ts +0 -21
- package/src/types/events.ts +0 -12
- /package/dist/types/src/capabilities/{app-graph-builder/app-graph-builder.d.ts → app-graph-builder.d.ts} +0 -0
- /package/dist/types/src/capabilities/{keyboard/keyboard.d.ts → keyboard.d.ts} +0 -0
- /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
|
|
6
|
-
import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
7
|
-
import { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';
|
|
8
|
-
import { scrollJustEnoughIntoView } from '@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view';
|
|
9
5
|
import {
|
|
10
6
|
type Edge,
|
|
11
7
|
attachClosestEdge,
|
|
12
8
|
extractClosestEdge,
|
|
13
9
|
} from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
|
10
|
+
import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
|
|
11
|
+
import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
12
|
+
import { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';
|
|
13
|
+
import { scrollJustEnoughIntoView } from '@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view';
|
|
14
14
|
import { useAtomValue } from '@effect-atom/atom-react';
|
|
15
15
|
import React, {
|
|
16
16
|
type MouseEvent,
|
|
@@ -29,6 +29,7 @@ import { DxAvatar } from '@dxos/lit-ui/react';
|
|
|
29
29
|
import { useActionRunner } from '@dxos/plugin-graph';
|
|
30
30
|
import {
|
|
31
31
|
Icon,
|
|
32
|
+
IconButton,
|
|
32
33
|
ListItem,
|
|
33
34
|
ScrollArea,
|
|
34
35
|
type ThemedClassName,
|
|
@@ -43,8 +44,9 @@ import { Tabs } from '@dxos/react-ui-tabs';
|
|
|
43
44
|
import { mx } from '@dxos/ui-theme';
|
|
44
45
|
import { arrayMove } from '@dxos/util';
|
|
45
46
|
|
|
46
|
-
import { useNavTreeState } from '
|
|
47
|
-
import { meta } from '
|
|
47
|
+
import { useNavTreeState } from '#hooks';
|
|
48
|
+
import { meta } from '#meta';
|
|
49
|
+
|
|
48
50
|
import { l0ItemType } from '../../util';
|
|
49
51
|
import { useNavTreeContext } from '../NavTreeContext';
|
|
50
52
|
import { UserAccountAvatar } from '../UserAccountAvatar';
|
|
@@ -85,12 +87,10 @@ const useL0ItemClick = ({ item, parent, path }: L0ItemProps, type: string) => {
|
|
|
85
87
|
switch (type) {
|
|
86
88
|
case 'action': {
|
|
87
89
|
const { properties: { caller } = {} } = item;
|
|
88
|
-
return void runAction(item as Node.Action, caller ? { parent, caller } : { parent });
|
|
90
|
+
return void runAction(item as Node.Action, caller ? { parent, path, caller } : { parent, path });
|
|
89
91
|
}
|
|
90
|
-
|
|
91
92
|
case 'tab':
|
|
92
93
|
return onTabChange?.(item);
|
|
93
|
-
|
|
94
94
|
case 'link':
|
|
95
95
|
return onSelect?.({ item, path, current: !getItem(path).current, option: event.altKey });
|
|
96
96
|
}
|
|
@@ -103,36 +103,34 @@ const l0Breakpoints: Record<string, string> = {
|
|
|
103
103
|
lg: 'hidden lg:grid',
|
|
104
104
|
};
|
|
105
105
|
|
|
106
|
-
const l0ItemRoot =
|
|
107
|
-
'group/l0item flex w-full justify-center items-center relative data[type!="collection"]:cursor-pointer dx-app-no-drag dx-focus-ring-group';
|
|
108
|
-
|
|
109
|
-
const l0ItemContent = 'flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm';
|
|
110
|
-
|
|
111
106
|
const L0ItemRoot = memo(
|
|
112
|
-
forwardRef<
|
|
107
|
+
forwardRef<HTMLButtonElement, PropsWithChildren<L0ItemRootProps>>(
|
|
113
108
|
({ item, parent, path, onMouseEnter, children }, forwardedRef) => {
|
|
109
|
+
const { t } = useTranslation(meta.id);
|
|
114
110
|
const { model } = useNavTreeContext();
|
|
115
111
|
const itemPath = useMemo(() => [...path, item.id], [item.id, path]);
|
|
116
112
|
const { id, testId } = useAtomValue(model.itemProps(itemPath));
|
|
117
|
-
const type = l0ItemType(item);
|
|
118
|
-
|
|
119
|
-
const { t } = useTranslation(meta.id);
|
|
120
113
|
const localizedString = toLocalizedString(item.properties.label, t);
|
|
121
114
|
|
|
115
|
+
const type = l0ItemType(item);
|
|
122
116
|
const handleClick = useL0ItemClick({ item, parent, path: itemPath }, type);
|
|
123
|
-
const rootProps =
|
|
124
|
-
type === 'tab'
|
|
125
|
-
? { value: item.id, tabIndex: 0, onClick: handleClick, 'data-testid': testId, 'data-object-id': id }
|
|
126
|
-
: { onClick: handleClick, 'data-testid': testId, 'data-object-id': id };
|
|
127
117
|
|
|
128
118
|
return (
|
|
129
119
|
<Tooltip.Trigger asChild delayDuration={0} side='right' content={localizedString}>
|
|
130
120
|
<Tabs.TabPrimitive
|
|
131
|
-
{
|
|
121
|
+
className={mx(
|
|
122
|
+
'group/l0item flex w-full justify-center items-center relative',
|
|
123
|
+
'dx-app-no-drag dx-focus-ring-group data[type!="collection"]:cursor-pointer',
|
|
124
|
+
l0Breakpoints[item.properties.l0Breakpoint],
|
|
125
|
+
)}
|
|
126
|
+
tabIndex={type === 'tab' ? 0 : undefined}
|
|
132
127
|
data-type={type}
|
|
133
|
-
|
|
134
|
-
|
|
128
|
+
data-testid={testId}
|
|
129
|
+
data-object-id={id}
|
|
130
|
+
value={item.id}
|
|
131
|
+
onClick={handleClick}
|
|
135
132
|
onMouseEnter={onMouseEnter}
|
|
133
|
+
ref={forwardedRef}
|
|
136
134
|
>
|
|
137
135
|
{children}
|
|
138
136
|
</Tabs.TabPrimitive>
|
|
@@ -144,9 +142,8 @@ const L0ItemRoot = memo(
|
|
|
144
142
|
|
|
145
143
|
export const L0ItemActiveTabIndicator = ({ classNames }: ThemedClassName<{}>) => (
|
|
146
144
|
<div
|
|
147
|
-
role='none'
|
|
148
145
|
className={mx(
|
|
149
|
-
'hidden group-aria-selected/l0item:block absolute start-0
|
|
146
|
+
'hidden group-aria-selected/l0item:block absolute start-0 h-6 w-1.5 bg-accent-bg rounded-sm',
|
|
150
147
|
classNames,
|
|
151
148
|
)}
|
|
152
149
|
/>
|
|
@@ -155,13 +152,12 @@ export const L0ItemActiveTabIndicator = ({ classNames }: ThemedClassName<{}>) =>
|
|
|
155
152
|
// TODO(burdon): Factor out pinned (non-draggable) items.
|
|
156
153
|
const L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L0ItemProps) => {
|
|
157
154
|
const { t } = useTranslation(meta.id);
|
|
158
|
-
const itemElement = useRef<
|
|
155
|
+
const itemElement = useRef<HTMLButtonElement | null>(null);
|
|
159
156
|
const [closestEdge, setEdge] = useState<Edge | null>(null);
|
|
160
157
|
const localizedString = toLocalizedString(item.properties.label, t);
|
|
161
158
|
const hue = item.properties.hue ?? null;
|
|
162
159
|
|
|
163
160
|
useLayoutEffect(() => {
|
|
164
|
-
// NOTE(thure): This is copied from StackItem, perhaps this should be DRYed out.
|
|
165
161
|
if (!itemElement.current || !onRearrange) {
|
|
166
162
|
return;
|
|
167
163
|
}
|
|
@@ -221,14 +217,13 @@ const L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L
|
|
|
221
217
|
return (
|
|
222
218
|
<L0ItemRoot ref={itemElement} item={item} parent={parent} path={path} onMouseEnter={handleMouseEnter}>
|
|
223
219
|
<div
|
|
224
|
-
role='none'
|
|
225
220
|
data-frame={true}
|
|
226
221
|
{...(hue && { style: { background: `var(--color-${hue}-surface)` } })}
|
|
227
222
|
className={mx(
|
|
228
|
-
|
|
223
|
+
'flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm',
|
|
229
224
|
pinned
|
|
230
|
-
? 'p-2 group-hover/l0item:bg-
|
|
231
|
-
: 'w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-
|
|
225
|
+
? 'p-2 group-hover/l0item:bg-current-surface'
|
|
226
|
+
: 'w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-current-surface',
|
|
232
227
|
)}
|
|
233
228
|
>
|
|
234
229
|
<ItemAvatar item={item} />
|
|
@@ -244,13 +239,15 @@ const L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L
|
|
|
244
239
|
|
|
245
240
|
const ItemAvatar = ({ item }: Pick<L0ItemProps, 'item'>) => {
|
|
246
241
|
const { t } = useTranslation(meta.id);
|
|
247
|
-
|
|
242
|
+
|
|
243
|
+
// Actions.
|
|
248
244
|
if (item.properties.icon) {
|
|
249
245
|
const hue = item.properties.hue ?? null;
|
|
250
|
-
const hueFgStyle = hue && { style: { color: `var(--color-${hue}-
|
|
246
|
+
const hueFgStyle = hue && { style: { color: `var(--color-${hue}-fg)` } };
|
|
251
247
|
return <Icon icon={item.properties.icon} size={6} {...hueFgStyle} />;
|
|
252
248
|
}
|
|
253
249
|
|
|
250
|
+
const type = l0ItemType(item);
|
|
254
251
|
if (type === 'tab' && item.properties.disposition !== 'pin-end') {
|
|
255
252
|
const hue = item.properties.hue ?? null;
|
|
256
253
|
const localizedString = toLocalizedString(item.properties.label, t);
|
|
@@ -317,74 +314,58 @@ export const L0Menu = ({
|
|
|
317
314
|
|
|
318
315
|
return (
|
|
319
316
|
<Tabs.Tablist
|
|
317
|
+
data-tauri-drag-region
|
|
320
318
|
classNames={[
|
|
321
319
|
'group/l0 absolute z-[1] inset-y-0 start-0 rounded-is',
|
|
322
320
|
'grid grid-cols-[var(--dx-l0-size)] grid-rows-[var(--dx-rail-size)_1fr_min-content_var(--dx-l0-size)] dx-contain-layout',
|
|
323
|
-
'
|
|
321
|
+
'w-(--dx-l0-size) bg-l0-surface dx-app-drag pb-[env(safe-area-inset-bottom)]',
|
|
322
|
+
'[body[data-platform="macos"]_&]:pt-[30px]',
|
|
323
|
+
'[body[data-platform="ios"]_&]:pt-[max(env(safe-area-inset-top),0.25rem)]',
|
|
324
324
|
]}
|
|
325
325
|
>
|
|
326
326
|
{/* TODO(wittjosiah): Use L0Item trigger. */}
|
|
327
327
|
<Menu.Root onAction={handleAction}>
|
|
328
|
-
<Menu.Trigger
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
role='none'
|
|
341
|
-
className={mx(
|
|
342
|
-
l0ItemContent,
|
|
343
|
-
'h-(--dx-rail-action) w-(--dx-rail-action) group-hover/l0item:bg-hover-surface',
|
|
344
|
-
)}
|
|
345
|
-
>
|
|
346
|
-
<Icon icon='ph--list--regular' size={5} />
|
|
347
|
-
</div>
|
|
348
|
-
</Tabs.TabPrimitive>
|
|
349
|
-
</Tooltip.Trigger>
|
|
328
|
+
<Menu.Trigger asChild data-testid='spacePlugin.addSpace'>
|
|
329
|
+
<div className='grid place-items-center'>
|
|
330
|
+
<IconButton
|
|
331
|
+
density='lg'
|
|
332
|
+
variant='ghost'
|
|
333
|
+
size={5}
|
|
334
|
+
icon='ph--list--regular'
|
|
335
|
+
iconOnly
|
|
336
|
+
square
|
|
337
|
+
label={t('app-menu.label')}
|
|
338
|
+
/>
|
|
339
|
+
</div>
|
|
350
340
|
</Menu.Trigger>
|
|
351
341
|
<Menu.Content group={parent} items={menuActions} />
|
|
352
342
|
</Menu.Root>
|
|
353
343
|
|
|
354
344
|
{/* Space list. */}
|
|
355
|
-
<ScrollArea.Root thin orientation='vertical'>
|
|
356
|
-
<ScrollArea.Viewport>
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
key={item.id}
|
|
368
|
-
item={item}
|
|
369
|
-
parent={parent}
|
|
370
|
-
path={path}
|
|
371
|
-
onItemHover={onItemHover}
|
|
372
|
-
{...(hasRearrangeableItems && { onRearrange: handleRearrange })}
|
|
373
|
-
/>
|
|
374
|
-
))}
|
|
375
|
-
</div>
|
|
345
|
+
<ScrollArea.Root centered thin orientation='vertical'>
|
|
346
|
+
<ScrollArea.Viewport classNames='flex flex-col gap-2 py-1'>
|
|
347
|
+
{topLevelItems.map((item) => (
|
|
348
|
+
<L0Item
|
|
349
|
+
key={item.id}
|
|
350
|
+
item={item}
|
|
351
|
+
parent={parent}
|
|
352
|
+
path={path}
|
|
353
|
+
onItemHover={onItemHover}
|
|
354
|
+
{...(hasRearrangeableItems && { onRearrange: handleRearrange })}
|
|
355
|
+
/>
|
|
356
|
+
))}
|
|
376
357
|
</ScrollArea.Viewport>
|
|
377
358
|
</ScrollArea.Root>
|
|
378
359
|
|
|
379
360
|
{/* Actions. */}
|
|
380
|
-
<div
|
|
361
|
+
<div className='grid grid-cols-1 auto-rows-(--dx-rail-action) pt-2'>
|
|
381
362
|
{pinnedItems.map((item) => (
|
|
382
363
|
<L0Item key={item.id} item={item} parent={parent} path={path} pinned />
|
|
383
364
|
))}
|
|
384
365
|
</div>
|
|
385
366
|
|
|
386
367
|
{userAccountItem && (
|
|
387
|
-
<div
|
|
368
|
+
<div className='grid dx-app-no-drag'>
|
|
388
369
|
<L0ItemRoot key={userAccountItem.id} item={userAccountItem} parent={parent} path={path}>
|
|
389
370
|
<UserAccountAvatar
|
|
390
371
|
userId={userAccountItem.properties.userId}
|
|
@@ -2,24 +2,25 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import * as Effect from 'effect/Effect';
|
|
6
5
|
import * as Option from 'effect/Option';
|
|
7
6
|
import React, { memo, useCallback, useMemo } from 'react';
|
|
8
7
|
|
|
9
8
|
import { Node } from '@dxos/app-graph';
|
|
9
|
+
import { isPinnedWorkspace } from '@dxos/app-toolkit';
|
|
10
10
|
import { useAppGraph } from '@dxos/app-toolkit/ui';
|
|
11
|
-
import { Graph, useActionRunner,
|
|
11
|
+
import { Graph, useActionRunner, useEdges } from '@dxos/plugin-graph';
|
|
12
12
|
import { DensityProvider, IconButton, ScrollArea, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
13
13
|
import { Tree } from '@dxos/react-ui-list';
|
|
14
14
|
import { Menu, type MenuItem } from '@dxos/react-ui-menu';
|
|
15
15
|
import { Tabs } from '@dxos/react-ui-tabs';
|
|
16
16
|
import { hoverableControlItem, hoverableOpenControlItem } from '@dxos/ui-theme';
|
|
17
17
|
|
|
18
|
-
import {
|
|
19
|
-
import { meta } from '
|
|
18
|
+
import { getListActions, useActions, useLoadDescendents } from '#hooks';
|
|
19
|
+
import { meta } from '#meta';
|
|
20
|
+
|
|
20
21
|
import { NAV_TREE_ITEM } from '../NavTree';
|
|
21
22
|
import { useNavTreeContext } from '../NavTreeContext';
|
|
22
|
-
import {
|
|
23
|
+
import { NavTreeItemColumns } from '../NavTreeItem/NavTreeItemColumns';
|
|
23
24
|
|
|
24
25
|
export type L1PanelProps = {
|
|
25
26
|
open?: boolean;
|
|
@@ -39,7 +40,7 @@ const L1Panel$ = ({ open, path, item, isCurrent, onBack }: L1PanelProps) => {
|
|
|
39
40
|
const shouldRenderContent = isCurrent || isActivated;
|
|
40
41
|
|
|
41
42
|
return (
|
|
42
|
-
<Tabs.
|
|
43
|
+
<Tabs.Panel
|
|
43
44
|
key={item.id}
|
|
44
45
|
value={item.id}
|
|
45
46
|
classNames={[
|
|
@@ -54,7 +55,7 @@ const L1Panel$ = ({ open, path, item, isCurrent, onBack }: L1PanelProps) => {
|
|
|
54
55
|
{...(!open && { inert: true })}
|
|
55
56
|
>
|
|
56
57
|
{shouldRenderContent && <L1PanelContent open={open} path={path} item={item} onBack={onBack} />}
|
|
57
|
-
</Tabs.
|
|
58
|
+
</Tabs.Panel>
|
|
58
59
|
);
|
|
59
60
|
};
|
|
60
61
|
|
|
@@ -81,49 +82,28 @@ const useIsActivatedWorkspace = (item: Node.Node): boolean => {
|
|
|
81
82
|
const L1PanelContent = ({ path, item, onBack }: Pick<L1PanelProps, 'open' | 'path' | 'item' | 'onBack'>) => {
|
|
82
83
|
const navTreeContext = useNavTreeContext();
|
|
83
84
|
|
|
84
|
-
const alternateTree = useAlternateTreeItem(item);
|
|
85
|
-
const alternatePath = useMemo(() => [...path, item.id], [item.id, path]);
|
|
86
|
-
const isAlternate = useIsAlternateTree(alternatePath, item);
|
|
87
|
-
|
|
88
85
|
return (
|
|
89
|
-
<DensityProvider density='
|
|
86
|
+
<DensityProvider density='md'>
|
|
90
87
|
<L1PanelHeader path={path} item={item} onBack={onBack} />
|
|
91
88
|
<ScrollArea.Root thin orientation='vertical'>
|
|
92
89
|
<ScrollArea.Viewport>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
<Tree
|
|
111
|
-
model={navTreeContext.model}
|
|
112
|
-
id={item.id}
|
|
113
|
-
rootId={item.id}
|
|
114
|
-
path={path}
|
|
115
|
-
levelOffset={5}
|
|
116
|
-
gridTemplateColumns='[tree-row-start] 1fr min-content min-content min-content [tree-row-end]'
|
|
117
|
-
draggable
|
|
118
|
-
renderColumns={NavTreeItemColumns}
|
|
119
|
-
blockInstruction={navTreeContext.blockInstruction}
|
|
120
|
-
canDrop={navTreeContext.canDrop}
|
|
121
|
-
canSelect={navTreeContext.canSelect}
|
|
122
|
-
onOpenChange={navTreeContext.onOpenChange}
|
|
123
|
-
onSelect={navTreeContext.onSelect}
|
|
124
|
-
onItemHover={navTreeContext.onItemHover}
|
|
125
|
-
/>
|
|
126
|
-
)}
|
|
90
|
+
<Tree
|
|
91
|
+
classNames='pt-[2px]'
|
|
92
|
+
model={navTreeContext.model}
|
|
93
|
+
id={item.id}
|
|
94
|
+
rootId={item.id}
|
|
95
|
+
path={path}
|
|
96
|
+
levelOffset={5}
|
|
97
|
+
draggable
|
|
98
|
+
gridTemplateColumns='[tree-row-start] minmax(0, 1fr) min-content min-content [tree-row-end]'
|
|
99
|
+
renderColumns={NavTreeItemColumns}
|
|
100
|
+
blockInstruction={navTreeContext.blockInstruction}
|
|
101
|
+
canDrop={navTreeContext.canDrop}
|
|
102
|
+
canSelect={navTreeContext.canSelect}
|
|
103
|
+
onOpenChange={navTreeContext.onOpenChange}
|
|
104
|
+
onSelect={navTreeContext.onSelect}
|
|
105
|
+
onItemHover={navTreeContext.onItemHover}
|
|
106
|
+
/>
|
|
127
107
|
</ScrollArea.Viewport>
|
|
128
108
|
</ScrollArea.Root>
|
|
129
109
|
</DensityProvider>
|
|
@@ -137,152 +117,113 @@ const L1PanelHeader = ({ item, path, onBack }: Pick<L1PanelProps, 'item' | 'path
|
|
|
137
117
|
const { t } = useTranslation(meta.id);
|
|
138
118
|
const { renderItemEnd: ItemEnd } = useNavTreeContext();
|
|
139
119
|
const title = toLocalizedString(item.properties.label, t);
|
|
140
|
-
const backCapableWorkspace = item.id
|
|
120
|
+
const backCapableWorkspace = isPinnedWorkspace(item.id);
|
|
141
121
|
|
|
142
|
-
const {
|
|
122
|
+
const { menuActions, onAction } = useL1MenuActions({ item, path });
|
|
143
123
|
useLoadDescendents(item);
|
|
144
124
|
|
|
145
125
|
return (
|
|
146
|
-
<div
|
|
126
|
+
<div
|
|
127
|
+
data-tauri-drag-region
|
|
128
|
+
className='grid grid-cols-[28px_1fr_min-content_min-content] w-full items-center dx-app-drag dx-density-lg'
|
|
129
|
+
>
|
|
147
130
|
{backCapableWorkspace ? (
|
|
148
131
|
<IconButton
|
|
149
|
-
|
|
150
|
-
density='coarse'
|
|
151
|
-
classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
|
|
132
|
+
classNames={[hoverableControlItem, hoverableOpenControlItem]}
|
|
152
133
|
variant='ghost'
|
|
153
134
|
icon='ph--caret-left--regular'
|
|
154
135
|
iconOnly
|
|
155
|
-
|
|
136
|
+
size={4}
|
|
137
|
+
label={t('button-back.button')}
|
|
156
138
|
data-testid='treeView.primaryTreeButton'
|
|
157
139
|
onClick={() => onBack?.()}
|
|
158
140
|
/>
|
|
159
141
|
) : (
|
|
160
|
-
<div
|
|
142
|
+
<div />
|
|
161
143
|
)}
|
|
162
|
-
<h2 className='flex-1 truncate min-w-0'>
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
testId={primaryAction.properties?.testId}
|
|
168
|
-
label={toLocalizedString(primaryAction.properties?.label, t)}
|
|
169
|
-
icon={primaryAction.properties?.icon ?? 'ph--placeholder--regular'}
|
|
170
|
-
parent={item}
|
|
171
|
-
monolithic={Node.isAction(primaryAction)}
|
|
172
|
-
menuActions={Node.isAction(primaryAction) ? [primaryAction] : groupedActions[primaryAction?.id ?? '']}
|
|
173
|
-
menuType={primaryAction.properties?.menuType}
|
|
174
|
-
caller={NAV_TREE_ITEM}
|
|
175
|
-
/>
|
|
176
|
-
)}
|
|
177
|
-
{menuActions.length === 1 && (
|
|
178
|
-
<IconButton
|
|
179
|
-
size={5}
|
|
180
|
-
density='coarse'
|
|
181
|
-
classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
|
|
182
|
-
variant='ghost'
|
|
183
|
-
icon={menuActions[0].properties?.icon ?? 'ph--placeholder--regular'}
|
|
184
|
-
iconOnly
|
|
185
|
-
label={toLocalizedString(menuActions[0].properties?.label, t)}
|
|
186
|
-
data-testid={menuActions[0].properties?.testId}
|
|
187
|
-
onClick={() => onAction(menuActions[0] as Node.Action)}
|
|
188
|
-
/>
|
|
189
|
-
)}
|
|
190
|
-
{menuActions.length > 1 && (
|
|
191
|
-
<Menu.Root caller={NAV_TREE_ITEM} onAction={onAction}>
|
|
192
|
-
<Menu.Trigger asChild>
|
|
193
|
-
<IconButton
|
|
194
|
-
size={5}
|
|
195
|
-
density='coarse'
|
|
196
|
-
classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
|
|
197
|
-
variant='ghost'
|
|
198
|
-
icon='ph--dots-three-vertical--regular'
|
|
199
|
-
iconOnly
|
|
200
|
-
label={t('tree item actions label')}
|
|
201
|
-
data-testid='navtree.treeItem.actionsLevel0'
|
|
202
|
-
/>
|
|
203
|
-
</Menu.Trigger>
|
|
204
|
-
<Menu.Content group={item} items={menuActions as MenuItem[]} />
|
|
205
|
-
</Menu.Root>
|
|
206
|
-
)}
|
|
144
|
+
<h2 data-tauri-drag-region className='flex-1 truncate min-w-0'>
|
|
145
|
+
{title}
|
|
146
|
+
</h2>
|
|
147
|
+
<div className='contents dx-app-no-drag'>
|
|
148
|
+
<MenuActions item={item} menuActions={menuActions} onAction={onAction} />
|
|
207
149
|
{ItemEnd && <ItemEnd node={item} open />}
|
|
208
150
|
</div>
|
|
209
151
|
</div>
|
|
210
152
|
);
|
|
211
153
|
};
|
|
212
154
|
|
|
155
|
+
type L1MenuActions = {
|
|
156
|
+
menuActions: Node.Action[];
|
|
157
|
+
onAction: (action: Node.Action, params?: Node.InvokeProps) => void;
|
|
158
|
+
};
|
|
159
|
+
|
|
213
160
|
/**
|
|
214
|
-
*
|
|
161
|
+
* Header menu actions for an L1 workspace tab. Renders nothing for an empty
|
|
162
|
+
* `menuActions`, a single inline icon button for one action, and a
|
|
163
|
+
* `…`-menu trigger for multiple.
|
|
215
164
|
*/
|
|
216
|
-
const
|
|
165
|
+
const MenuActions = ({
|
|
166
|
+
item,
|
|
167
|
+
menuActions,
|
|
168
|
+
onAction,
|
|
169
|
+
}: {
|
|
170
|
+
item: Node.Node;
|
|
171
|
+
} & Pick<L1MenuActions, 'menuActions' | 'onAction'>) => {
|
|
217
172
|
const { t } = useTranslation(meta.id);
|
|
218
|
-
const { setAlternateTree } = useNavTreeContext();
|
|
219
|
-
const { graph } = useAppGraph();
|
|
220
|
-
const runAction = useActionRunner();
|
|
221
173
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
174
|
+
if (menuActions.length === 0) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (menuActions.length === 1) {
|
|
179
|
+
return (
|
|
180
|
+
<IconButton
|
|
181
|
+
classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
|
|
182
|
+
variant='ghost'
|
|
183
|
+
icon={menuActions[0].properties?.icon ?? 'ph--circle-dashed--regular'}
|
|
184
|
+
iconOnly
|
|
185
|
+
size={4}
|
|
186
|
+
label={toLocalizedString(menuActions[0].properties?.label, t)}
|
|
187
|
+
data-testid={menuActions[0].properties?.testId}
|
|
188
|
+
onClick={() => onAction(menuActions[0] as Node.Action)}
|
|
189
|
+
/>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
225
192
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
193
|
+
return (
|
|
194
|
+
<Menu.Root caller={NAV_TREE_ITEM} onAction={onAction}>
|
|
195
|
+
<Menu.Trigger asChild>
|
|
196
|
+
<IconButton
|
|
197
|
+
classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
|
|
198
|
+
variant='ghost'
|
|
199
|
+
icon='ph--dots-three-vertical--regular'
|
|
200
|
+
iconOnly
|
|
201
|
+
size={4}
|
|
202
|
+
label={t('tree-item-actions.label')}
|
|
203
|
+
data-testid='navtree.treeItem.actionsLevel0'
|
|
204
|
+
/>
|
|
205
|
+
</Menu.Trigger>
|
|
206
|
+
<Menu.Content group={item} items={menuActions as MenuItem[]} />
|
|
207
|
+
</Menu.Root>
|
|
230
208
|
);
|
|
209
|
+
};
|
|
231
210
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
// Synthetic settings/back action.
|
|
239
|
-
const settingsActionId = `${item.id}~settings`;
|
|
240
|
-
const settingsAction = useMemo((): Node.Action | undefined => {
|
|
241
|
-
if (!alternateTree) {
|
|
242
|
-
return undefined;
|
|
243
|
-
}
|
|
244
|
-
return {
|
|
245
|
-
id: settingsActionId,
|
|
246
|
-
type: Node.ActionType,
|
|
247
|
-
data: () => Effect.void,
|
|
248
|
-
properties: {
|
|
249
|
-
label: isAlternate ? ['button back', { ns: meta.id }] : (alternateTree.properties.label ?? alternateTree.id),
|
|
250
|
-
icon: isAlternate
|
|
251
|
-
? 'ph--arrow-u-down-left--regular'
|
|
252
|
-
: (alternateTree.properties.icon ?? 'ph--placeholder--regular'),
|
|
253
|
-
disposition: 'list-item',
|
|
254
|
-
testId: isAlternate ? 'navtree.backToSpace' : 'navtree.spaceSettings',
|
|
255
|
-
},
|
|
256
|
-
} as Node.Action;
|
|
257
|
-
}, [alternateTree, isAlternate, settingsActionId, t]);
|
|
211
|
+
/**
|
|
212
|
+
* Builds the menu actions for the L1 panel header.
|
|
213
|
+
*/
|
|
214
|
+
const useL1MenuActions = ({ item, path }: Pick<L1PanelProps, 'item' | 'path'>): L1MenuActions => {
|
|
215
|
+
const runAction = useActionRunner();
|
|
258
216
|
|
|
259
|
-
const menuActions =
|
|
260
|
-
() => [...graphMenuActions, ...(settingsAction ? [settingsAction] : [])],
|
|
261
|
-
[graphMenuActions, settingsAction],
|
|
262
|
-
);
|
|
217
|
+
const menuActions = getListActions(useActions(item));
|
|
263
218
|
|
|
264
219
|
const onAction = useCallback(
|
|
265
220
|
(action: Node.Action, params?: Node.InvokeProps) => {
|
|
266
|
-
|
|
267
|
-
if (alternateTree && !isAlternate) {
|
|
268
|
-
Graph.expand(graph, alternateTree.id, 'child');
|
|
269
|
-
}
|
|
270
|
-
setAlternateTree?.(alternatePath, !isAlternate);
|
|
271
|
-
} else {
|
|
272
|
-
void runAction(action, params);
|
|
273
|
-
}
|
|
221
|
+
void runAction(action, { ...params, path });
|
|
274
222
|
},
|
|
275
|
-
[
|
|
223
|
+
[runAction, path],
|
|
276
224
|
);
|
|
277
225
|
|
|
278
|
-
return {
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
/** Finds the first child with disposition 'alternate-tree' using graph connections directly. */
|
|
282
|
-
const useAlternateTreeItem = (item: Node.Node): Node.Node | undefined => {
|
|
283
|
-
const { graph } = useAppGraph();
|
|
284
|
-
const connections = useConnections(graph, item.id, 'child');
|
|
285
|
-
return connections.find((node) => node.properties.disposition === 'alternate-tree');
|
|
226
|
+
return { menuActions, onAction };
|
|
286
227
|
};
|
|
287
228
|
|
|
288
229
|
export const L1Panel = memo(L1Panel$);
|
package/src/components/types.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { type Node } from '@dxos/app-graph';
|
|
|
8
8
|
import type { Density } from '@dxos/react-ui';
|
|
9
9
|
import type { TreeModel, TreeProps } from '@dxos/react-ui-list';
|
|
10
10
|
|
|
11
|
-
import type { NavTreeItemGraphNode } from '
|
|
11
|
+
import type { NavTreeItemGraphNode } from '#types';
|
|
12
12
|
|
|
13
13
|
import type { L1PanelProps } from './Sidebar';
|
|
14
14
|
|
|
@@ -16,7 +16,6 @@ export type NavTreeContextValue = {
|
|
|
16
16
|
model: TreeModel<NavTreeItemGraphNode>;
|
|
17
17
|
popoverAnchorId?: string;
|
|
18
18
|
renderItemEnd?: FC<{ node: Node.Node; open: boolean }>;
|
|
19
|
-
setAlternateTree?: (path: string[], open: boolean) => void;
|
|
20
19
|
onTabChange?: (node: NavTreeItemGraphNode) => void;
|
|
21
20
|
} & Pick<
|
|
22
21
|
TreeProps<NavTreeItemGraphNode>,
|