@dxos/plugin-navtree 0.8.4-main.fffef41 → 0.9.0
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/neutral/CommandsDialogContent-UBGIQ5FI.mjs +112 -0
- package/dist/lib/neutral/CommandsDialogContent-UBGIQ5FI.mjs.map +7 -0
- package/dist/lib/neutral/CommandsTrigger-BH5WLMHK.mjs +27 -0
- 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/neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs +22 -0
- 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/neutral/app-graph-builder-Z347LKSF.mjs +42 -0
- 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 +805 -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-YYTYJW4M.mjs → neutral/keyboard-EJ65BVTC.mjs} +25 -20
- 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/neutral/react-surface-Q5XMAG7Z.mjs +50 -0
- package/dist/lib/neutral/react-surface-Q5XMAG7Z.mjs.map +7 -0
- package/dist/lib/neutral/state-VVJEWUHM.mjs +126 -0
- package/dist/lib/neutral/state-VVJEWUHM.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 +3 -1
- 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 +4 -2
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +7 -108
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/keyboard.d.ts +3 -2
- package/dist/types/src/capabilities/keyboard.d.ts.map +1 -1
- 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 +3 -2
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/state.d.ts +4 -18
- package/dist/types/src/capabilities/state.d.ts.map +1 -1
- package/dist/types/src/components/NavTree/NavTree.d.ts +11 -4
- package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
- package/dist/types/src/components/NavTree/NavTree.stories.d.ts +10 -12
- 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 +13 -9
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +3 -2
- 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 +8 -5
- package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Panel.d.ts +4 -7
- package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Tabs.d.ts +5 -4
- 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/index.d.ts +0 -3
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/types.d.ts +8 -17
- package/dist/types/src/components/types.d.ts.map +1 -1
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts +6 -0
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -0
- 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 +2 -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 +2 -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/{components → containers/NavTreeDocumentTitle}/NavTreeDocumentTitle.d.ts +1 -1
- package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -0
- package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +2 -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.d.ts +2 -2
- package/dist/types/src/experimental/Tree.d.ts.map +1 -1
- 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 +11 -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/useNavTreeState.d.ts +18 -0
- package/dist/types/src/hooks/useNavTreeState.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +4 -3
- 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 +2 -3
- package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +5 -6
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/testing/update-state.d.ts +2 -2
- 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 +4 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/{types.d.ts → types/schema.d.ts} +10 -6
- package/dist/types/src/types/schema.d.ts.map +1 -0
- package/dist/types/src/util.d.ts +12 -8
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +124 -62
- package/src/NavTreePlugin.node.ts +17 -0
- package/src/NavTreePlugin.test.ts +27 -0
- package/src/NavTreePlugin.tsx +46 -76
- package/src/NavTreePlugin.workerd.ts +16 -0
- package/src/capabilities/app-graph-builder.ts +34 -45
- package/src/capabilities/index.ts +10 -8
- package/src/capabilities/keyboard.ts +58 -51
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/capabilities/react-surface.tsx +46 -38
- package/src/capabilities/state.ts +132 -84
- package/src/components/NavTree/NavTree.stories.tsx +55 -63
- package/src/components/NavTree/NavTree.tsx +65 -33
- 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 +23 -15
- package/src/components/NavTreeItem/NavTreeItemAction.tsx +75 -52
- package/src/components/NavTreeItem/NavTreeItemColumns.tsx +25 -42
- package/src/components/Sidebar/L0Menu.tsx +155 -184
- package/src/components/Sidebar/L1Panel.tsx +181 -101
- package/src/components/Sidebar/L1Tabs.tsx +18 -34
- package/src/components/UserAccountAvatar/UserAccountAvatar.stories.tsx +2 -3
- package/src/components/UserAccountAvatar/UserAccountAvatar.tsx +1 -1
- package/src/components/index.ts +1 -3
- package/src/components/types.ts +13 -19
- package/src/containers/CommandsDialogContent/CommandsDialogContent.stories.tsx +46 -0
- package/src/containers/CommandsDialogContent/CommandsDialogContent.tsx +127 -0
- package/src/containers/CommandsDialogContent/index.ts +5 -0
- package/src/containers/CommandsTrigger/CommandsTrigger.tsx +28 -0
- package/src/containers/CommandsTrigger/index.ts +5 -0
- package/src/containers/NavTreeContainer/NavTreeContainer.tsx +271 -0
- package/src/containers/NavTreeContainer/index.ts +6 -0
- package/src/{components → containers/NavTreeDocumentTitle}/NavTreeDocumentTitle.tsx +4 -3
- package/src/containers/NavTreeDocumentTitle/index.ts +5 -0
- package/src/containers/index.ts +12 -0
- package/src/experimental/Tree.stories.tsx +82 -85
- package/src/experimental/Tree.tsx +5 -5
- package/src/hooks/index.ts +8 -0
- package/src/hooks/useActions.ts +44 -0
- package/src/hooks/useLoadDescendents.ts +23 -0
- package/src/hooks/useNavTreeModel.ts +120 -0
- package/src/hooks/useNavTreeState.ts +35 -0
- package/src/index.ts +1 -3
- 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 +168 -238
- package/src/testing/generator.ts +35 -38
- package/src/testing/update-state.ts +6 -6
- 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 +8 -0
- package/src/{types.ts → types/schema.ts} +9 -5
- package/src/util.ts +28 -17
- package/src/vite-env.d.ts +10 -0
- package/dist/lib/browser/app-graph-builder-OHSCN3GX.mjs +0 -46
- package/dist/lib/browser/app-graph-builder-OHSCN3GX.mjs.map +0 -7
- package/dist/lib/browser/chunk-5VLWX4PK.mjs +0 -15
- package/dist/lib/browser/chunk-5VLWX4PK.mjs.map +0 -7
- package/dist/lib/browser/chunk-7D2MPHXV.mjs +0 -1483
- package/dist/lib/browser/chunk-7D2MPHXV.mjs.map +0 -7
- package/dist/lib/browser/chunk-E6MZBCU5.mjs +0 -19
- package/dist/lib/browser/chunk-E6MZBCU5.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -146
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-YUVXVPHG.mjs +0 -47
- package/dist/lib/browser/intent-resolver-YUVXVPHG.mjs.map +0 -7
- package/dist/lib/browser/keyboard-YYTYJW4M.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/react-surface-J7MWWAGD.mjs +0 -51
- package/dist/lib/browser/react-surface-J7MWWAGD.mjs.map +0 -7
- package/dist/lib/browser/state-EUSVT6BI.mjs +0 -117
- package/dist/lib/browser/state-EUSVT6BI.mjs.map +0 -7
- package/dist/types/src/capabilities/capabilities.d.ts +0 -21
- package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
- package/dist/types/src/components/CommandsDialog/CommandsDialog.d.ts +0 -5
- 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 -9
- 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/events.d.ts +0 -4
- package/dist/types/src/events.d.ts.map +0 -1
- package/dist/types/src/hooks.d.ts +0 -3
- package/dist/types/src/hooks.d.ts.map +0 -1
- package/dist/types/src/types.d.ts.map +0 -1
- package/src/capabilities/capabilities.ts +0 -20
- package/src/capabilities/intent-resolver.ts +0 -37
- package/src/components/CommandsDialog/CommandsDialog.tsx +0 -126
- package/src/components/CommandsDialog/CommandsTrigger.tsx +0 -36
- package/src/components/CommandsDialog/index.ts +0 -6
- package/src/components/NavTreeContainer.tsx +0 -369
- package/src/events.ts +0 -11
- package/src/hooks.ts +0 -21
- /package/dist/types/src/{components/CommandsDialog → containers/CommandsTrigger}/CommandsTrigger.d.ts +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { useOperationInvoker } from '@dxos/app-framework/ui';
|
|
8
|
+
import { LayoutOperation } from '@dxos/app-toolkit';
|
|
9
|
+
import { Button, Icon, useTranslation } from '@dxos/react-ui';
|
|
10
|
+
|
|
11
|
+
import { COMMANDS_DIALOG, meta } from '#meta';
|
|
12
|
+
|
|
13
|
+
// TODO(thure): Refactor to be handled by a more appropriate plugin.
|
|
14
|
+
export const CommandsTrigger = () => {
|
|
15
|
+
const { invokePromise } = useOperationInvoker();
|
|
16
|
+
const { t } = useTranslation(meta.id);
|
|
17
|
+
return (
|
|
18
|
+
<Button
|
|
19
|
+
classNames='m-1 px-1 lg:px-2'
|
|
20
|
+
onClick={() =>
|
|
21
|
+
void invokePromise(LayoutOperation.UpdateDialog, { subject: COMMANDS_DIALOG, blockAlign: 'start' })
|
|
22
|
+
}
|
|
23
|
+
>
|
|
24
|
+
<span className='text-description font-normal grow text-start'>{t('command-list-input.placeholder')}</span>
|
|
25
|
+
<Icon icon='ph--magnifying-glass--regular' />
|
|
26
|
+
</Button>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Instruction, extractInstruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
|
|
6
|
+
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
7
|
+
import React, { forwardRef, memo, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
8
|
+
|
|
9
|
+
import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
|
|
10
|
+
import { LayoutOperation } from '@dxos/app-toolkit';
|
|
11
|
+
import { useAppGraph, useLayout } from '@dxos/app-toolkit/ui';
|
|
12
|
+
import { Graph, Node, useActionRunner } from '@dxos/plugin-graph';
|
|
13
|
+
import { useMediaQuery, useSidebars } from '@dxos/react-ui';
|
|
14
|
+
import { type TreeData, isTreeData } from '@dxos/react-ui-list';
|
|
15
|
+
import { arrayMove } from '@dxos/util';
|
|
16
|
+
|
|
17
|
+
import { NAV_TREE_ITEM, NavTree, NavTreeContext } from '#components';
|
|
18
|
+
import { useNavTreeModel, useNavTreeState } from '#hooks';
|
|
19
|
+
import { meta } from '#meta';
|
|
20
|
+
import { type NavTreeItemGraphNode } from '#types';
|
|
21
|
+
|
|
22
|
+
import { filterItems, getParent, resolveMigrationOperation } from '../../util';
|
|
23
|
+
|
|
24
|
+
// TODO(thure): Is NavTree truly authoritative in this regard?
|
|
25
|
+
export const NODE_TYPE = 'dxos/app-graph/node';
|
|
26
|
+
|
|
27
|
+
// TODO(wittjosiah): Avoid using Surface within the navtree, prefer declarative data flow.
|
|
28
|
+
const NavTreeItemEnd = ({ node, open }: { node: Node.Node; open: boolean }) => {
|
|
29
|
+
const data = useMemo(() => ({ id: node.id, subject: node.data, open }), [node.id, node.data, open]);
|
|
30
|
+
return <Surface.Surface role='navtree-item-end' data={data} limit={1} />;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const getItems = (graph: Graph.ReadableGraph, node?: Node.Node, disposition?: string) => {
|
|
34
|
+
return Graph.getConnections(graph, node?.id ?? Node.RootId, 'child').filter((node) => filterItems(node, disposition));
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type NavTreeContainerProps = {
|
|
38
|
+
popoverAnchorId?: string;
|
|
39
|
+
tab: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProps>(
|
|
43
|
+
({ tab, popoverAnchorId }, forwardedRef) => {
|
|
44
|
+
const [isLg] = useMediaQuery('lg');
|
|
45
|
+
const { invokePromise } = useOperationInvoker();
|
|
46
|
+
const runAction = useActionRunner();
|
|
47
|
+
const { graph } = useAppGraph();
|
|
48
|
+
const { getItem, setItem } = useNavTreeState();
|
|
49
|
+
const layout = useLayout();
|
|
50
|
+
const model = useNavTreeModel(Node.RootId);
|
|
51
|
+
const { navigationSidebarState } = useSidebars(meta.id);
|
|
52
|
+
const latestRef = useRef({
|
|
53
|
+
tab,
|
|
54
|
+
activeItems: layout.active,
|
|
55
|
+
navigationSidebarState,
|
|
56
|
+
isLg,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
latestRef.current = {
|
|
61
|
+
tab,
|
|
62
|
+
activeItems: layout.active,
|
|
63
|
+
navigationSidebarState,
|
|
64
|
+
isLg,
|
|
65
|
+
};
|
|
66
|
+
}, [tab, layout.active, navigationSidebarState, isLg]);
|
|
67
|
+
|
|
68
|
+
const handleOpenChange = useCallback(
|
|
69
|
+
({ item: { id }, path, open }: { item: Node.Node; path: string[]; open: boolean }) => {
|
|
70
|
+
// TODO(thure): This might become a localstorage leak; openItemIds that no longer exist should be removed from this map.
|
|
71
|
+
setItem(path, 'open', open);
|
|
72
|
+
Graph.expand(graph, id, 'child');
|
|
73
|
+
},
|
|
74
|
+
[graph, setItem],
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const handleTabChange = useCallback(
|
|
78
|
+
(node: NavTreeItemGraphNode) => {
|
|
79
|
+
Graph.expand(graph, node.id, 'child');
|
|
80
|
+
|
|
81
|
+
const {
|
|
82
|
+
tab: activeTab,
|
|
83
|
+
activeItems,
|
|
84
|
+
navigationSidebarState: currentSidebarState,
|
|
85
|
+
isLg: latestIsLg,
|
|
86
|
+
} = latestRef.current;
|
|
87
|
+
void invokePromise(LayoutOperation.UpdateSidebar, {
|
|
88
|
+
state:
|
|
89
|
+
node.id === activeTab
|
|
90
|
+
? currentSidebarState === 'expanded'
|
|
91
|
+
? latestIsLg
|
|
92
|
+
? 'collapsed'
|
|
93
|
+
: 'closed'
|
|
94
|
+
: 'expanded'
|
|
95
|
+
: 'expanded',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
void invokePromise(LayoutOperation.SwitchWorkspace, { subject: node.id });
|
|
99
|
+
|
|
100
|
+
// Open the first item if the workspace is empty.
|
|
101
|
+
if (activeItems.length === 0) {
|
|
102
|
+
const [item] = getItems(graph, node).filter((node) => !Node.isActionLike(node));
|
|
103
|
+
if (item && item.data) {
|
|
104
|
+
if (layout.mode === 'multi') {
|
|
105
|
+
void invokePromise(LayoutOperation.Set, { subject: [item.id] });
|
|
106
|
+
} else {
|
|
107
|
+
void invokePromise(LayoutOperation.Open, { subject: [item.id] });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
[invokePromise, graph, layout.mode],
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
const blockInstruction = useCallback(
|
|
116
|
+
({ instruction, source, target }: { instruction: Instruction; source: TreeData; target: TreeData }) => {
|
|
117
|
+
return target.item.properties.blockInstruction?.(source, instruction) ?? false;
|
|
118
|
+
},
|
|
119
|
+
[],
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const canDrop = useCallback(({ source, target }: { source: TreeData; target: TreeData }) => {
|
|
123
|
+
return target.item.properties.canDrop?.(source) ?? false;
|
|
124
|
+
}, []);
|
|
125
|
+
|
|
126
|
+
const canSelect = useCallback(({ item }: { item: Node.Node }) => {
|
|
127
|
+
return item.properties.selectable ?? true;
|
|
128
|
+
}, []);
|
|
129
|
+
|
|
130
|
+
const handleSelect = useCallback(
|
|
131
|
+
({ item: node, path, option }: { item: Node.Node; path: string[]; option: boolean }) => {
|
|
132
|
+
if (!node.data) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (Node.isAction(node)) {
|
|
137
|
+
const [parent] = Graph.getConnections(graph, node.id, Node.childRelation('inbound'));
|
|
138
|
+
if (parent) {
|
|
139
|
+
void runAction(node, { parent, path, caller: NAV_TREE_ITEM });
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const current = getItem(path).current;
|
|
145
|
+
if (!current) {
|
|
146
|
+
if (layout.mode === 'multi') {
|
|
147
|
+
void invokePromise(LayoutOperation.Set, { subject: [node.id] });
|
|
148
|
+
} else {
|
|
149
|
+
void invokePromise(LayoutOperation.Open, { subject: [node.id], key: node.properties.key });
|
|
150
|
+
}
|
|
151
|
+
} else if (option) {
|
|
152
|
+
void invokePromise(LayoutOperation.Close, { subject: [node.id] });
|
|
153
|
+
} else {
|
|
154
|
+
void invokePromise(LayoutOperation.ScrollIntoView, { subject: node.id });
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const defaultAction = Graph.getActions(graph, node.id).find(
|
|
158
|
+
(action) => action.properties?.disposition === 'default',
|
|
159
|
+
);
|
|
160
|
+
if (Node.isAction(defaultAction)) {
|
|
161
|
+
void runAction(defaultAction);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (!isLg) {
|
|
165
|
+
void invokePromise(LayoutOperation.UpdateSidebar, { state: 'closed' });
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
[graph, invokePromise, getItem, runAction, isLg, layout.mode],
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const handleBack = useCallback(() => void invokePromise(LayoutOperation.RevertWorkspace), [invokePromise]);
|
|
172
|
+
|
|
173
|
+
// TODO(wittjosiah): Factor out hook.
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
return monitorForElements({
|
|
176
|
+
canMonitor: ({ source }) => isTreeData(source.data),
|
|
177
|
+
onDrop: ({ location, source }) => {
|
|
178
|
+
// Didn't drop on anything.
|
|
179
|
+
if (!location.current.dropTargets.length) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const target = location.current.dropTargets[0];
|
|
183
|
+
const instruction: Instruction | null = extractInstruction(target.data);
|
|
184
|
+
if (instruction !== null && instruction.type !== 'instruction-blocked') {
|
|
185
|
+
const sourceNode = source.data.item as NavTreeItemGraphNode;
|
|
186
|
+
const targetNode = target.data.item as NavTreeItemGraphNode;
|
|
187
|
+
const sourcePath = source.data.path as string[];
|
|
188
|
+
const targetPath = target.data.path as string[];
|
|
189
|
+
const sameParent = sourcePath.slice(0, -1).join() === targetPath.slice(0, -1).join();
|
|
190
|
+
const operation =
|
|
191
|
+
sameParent && instruction.type !== 'make-child'
|
|
192
|
+
? 'rearrange'
|
|
193
|
+
: resolveMigrationOperation(graph, sourceNode, targetPath, targetNode);
|
|
194
|
+
const sourceParent = getParent(graph, sourceNode, sourcePath);
|
|
195
|
+
const targetParent = getParent(graph, targetNode, targetPath);
|
|
196
|
+
const sourceItems = getItems(graph, sourceParent);
|
|
197
|
+
const targetItems = getItems(graph, targetParent);
|
|
198
|
+
const sourceIndex = sourceItems.findIndex(({ id }) => id === sourceNode.id);
|
|
199
|
+
const targetIndex = targetItems.findIndex(({ id }) => id === targetNode.id);
|
|
200
|
+
const migrationIndex =
|
|
201
|
+
instruction.type === 'make-child'
|
|
202
|
+
? undefined
|
|
203
|
+
: instruction.type === 'reorder-below'
|
|
204
|
+
? targetIndex + 1
|
|
205
|
+
: targetIndex;
|
|
206
|
+
switch (operation) {
|
|
207
|
+
case 'rearrange': {
|
|
208
|
+
const nextItems = sourceItems.map(({ data }) => data);
|
|
209
|
+
arrayMove(nextItems, sourceIndex, targetIndex);
|
|
210
|
+
void sourceNode.properties.onRearrange?.(nextItems);
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case 'copy': {
|
|
214
|
+
const target = instruction.type === 'make-child' ? targetNode : targetParent;
|
|
215
|
+
void target?.properties.onCopy?.(sourceNode, migrationIndex);
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case 'transfer': {
|
|
219
|
+
const target = instruction.type === 'make-child' ? targetNode : targetParent;
|
|
220
|
+
if (!target?.properties.onTransferStart || target?.id === sourceParent?.id) {
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
void target?.properties.onTransferStart(sourceNode, migrationIndex);
|
|
224
|
+
void sourceParent?.properties.onTransferEnd?.(sourceNode, target);
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
}, [graph]);
|
|
232
|
+
|
|
233
|
+
const onItemHover = useCallback(({ item }: { item: Node.Node }) => Graph.expand(graph, item.id, 'child'), [graph]);
|
|
234
|
+
|
|
235
|
+
const navTreeContextValue = useMemo(
|
|
236
|
+
() => ({
|
|
237
|
+
model,
|
|
238
|
+
popoverAnchorId,
|
|
239
|
+
renderItemEnd: NavTreeItemEnd,
|
|
240
|
+
blockInstruction,
|
|
241
|
+
canDrop,
|
|
242
|
+
canSelect,
|
|
243
|
+
onBack: handleBack,
|
|
244
|
+
onOpenChange: handleOpenChange,
|
|
245
|
+
onSelect: handleSelect,
|
|
246
|
+
onTabChange: handleTabChange,
|
|
247
|
+
onItemHover,
|
|
248
|
+
}),
|
|
249
|
+
[
|
|
250
|
+
model,
|
|
251
|
+
popoverAnchorId,
|
|
252
|
+
blockInstruction,
|
|
253
|
+
canDrop,
|
|
254
|
+
canSelect,
|
|
255
|
+
handleBack,
|
|
256
|
+
handleOpenChange,
|
|
257
|
+
handleSelect,
|
|
258
|
+
handleTabChange,
|
|
259
|
+
onItemHover,
|
|
260
|
+
],
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
return (
|
|
264
|
+
<NavTreeContext.Provider value={navTreeContextValue}>
|
|
265
|
+
<NavTree id={Node.RootId} root={Graph.getRoot(graph)} tab={tab} open={layout.sidebarOpen} ref={forwardedRef} />
|
|
266
|
+
</NavTreeContext.Provider>
|
|
267
|
+
);
|
|
268
|
+
},
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
export const NavTreeContainer = memo(NavTreeContainer$);
|
|
@@ -5,13 +5,14 @@ import { useEffect } from 'react';
|
|
|
5
5
|
|
|
6
6
|
import { type Node } from '@dxos/app-graph';
|
|
7
7
|
import { toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
8
|
+
import { osTranslations } from '@dxos/ui-theme';
|
|
8
9
|
|
|
9
|
-
import { meta } from '
|
|
10
|
+
import { meta } from '#meta';
|
|
10
11
|
|
|
11
|
-
export const NavTreeDocumentTitle = ({ node }: { node?: Node }) => {
|
|
12
|
+
export const NavTreeDocumentTitle = ({ node }: { node?: Node.Node }) => {
|
|
12
13
|
const { t } = useTranslation(meta.id);
|
|
13
14
|
useEffect(() => {
|
|
14
|
-
document.title = node ? toLocalizedString(node.properties.label, t) : t('current
|
|
15
|
+
document.title = node ? toLocalizedString(node.properties.label, t) : t('current-app.name', { ns: osTranslations });
|
|
15
16
|
}, [node?.properties?.label]);
|
|
16
17
|
return null;
|
|
17
18
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentType, lazy } from 'react';
|
|
6
|
+
|
|
7
|
+
export { NODE_TYPE } from './NavTreeContainer';
|
|
8
|
+
|
|
9
|
+
export const CommandsDialogContent: ComponentType<any> = lazy(() => import('./CommandsDialogContent'));
|
|
10
|
+
export const CommandsTrigger: ComponentType<any> = lazy(() => import('./CommandsTrigger'));
|
|
11
|
+
export const NavTreeContainer: ComponentType<any> = lazy(() => import('./NavTreeContainer'));
|
|
12
|
+
export const NavTreeDocumentTitle: ComponentType<any> = lazy(() => import('./NavTreeDocumentTitle'));
|
|
@@ -3,38 +3,16 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Meta } from '@storybook/react-vite';
|
|
6
|
-
import React, {
|
|
6
|
+
import React, { useEffect, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import { Icon, IconButton } from '@dxos/react-ui';
|
|
8
|
+
import { random } from '@dxos/random';
|
|
9
|
+
import { Icon, IconButton, Panel, ScrollArea } from '@dxos/react-ui';
|
|
10
10
|
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
11
|
-
import { mx } from '@dxos/
|
|
11
|
+
import { mx } from '@dxos/ui-theme';
|
|
12
12
|
|
|
13
13
|
import { type ItemMap, Tree, type TreeNodeData, type TreeProps, visitNodes, visitor } from './Tree';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Space:
|
|
19
|
-
* - Space panels are separated from each other to give them more weight than folders.
|
|
20
|
-
* - Private space isn't different (just first, different icon).
|
|
21
|
-
* - Edit titles in place.
|
|
22
|
-
*
|
|
23
|
-
* Navigation:
|
|
24
|
-
* - up/down across spaces/folder peers
|
|
25
|
-
* - right to enter space/folder children
|
|
26
|
-
* - left to parent
|
|
27
|
-
*/
|
|
28
|
-
const Container = ({ children, sidebar }: PropsWithChildren<{ sidebar: JSX.Element }>) => {
|
|
29
|
-
return (
|
|
30
|
-
<div className='flex'>
|
|
31
|
-
{/* TODO(burdon): Custom thin scrollbar. */}
|
|
32
|
-
{/* TODO(burdon): Horizontal scrolling within navtree? */}
|
|
33
|
-
<div className='flex flex-col overflow-y-auto is-[300px] bg-neutral-100 dark:bg-neutral-950'>{sidebar}</div>
|
|
34
|
-
<div className='flex flex-col grow overflow-hidden'>{children}</div>
|
|
35
|
-
</div>
|
|
36
|
-
);
|
|
37
|
-
};
|
|
15
|
+
random.seed(1234);
|
|
38
16
|
|
|
39
17
|
// TODO(burdon): Generate.
|
|
40
18
|
const data: TreeNodeData[] = [
|
|
@@ -43,34 +21,34 @@ const data: TreeNodeData[] = [
|
|
|
43
21
|
title: 'plugins/Root',
|
|
44
22
|
children: [
|
|
45
23
|
{
|
|
46
|
-
id:
|
|
24
|
+
id: random.string.uuid(),
|
|
47
25
|
title: 'plugins/Personal Space',
|
|
48
26
|
color: 'text-green-400',
|
|
49
27
|
iconName: 'ph--house--regular',
|
|
50
28
|
children: [
|
|
51
29
|
{
|
|
52
|
-
id:
|
|
53
|
-
title:
|
|
30
|
+
id: random.string.uuid(),
|
|
31
|
+
title: random.commerce.productName(),
|
|
54
32
|
},
|
|
55
33
|
{
|
|
56
|
-
id:
|
|
57
|
-
title:
|
|
34
|
+
id: random.string.uuid(),
|
|
35
|
+
title: random.commerce.productName(),
|
|
58
36
|
},
|
|
59
37
|
{
|
|
60
|
-
id:
|
|
61
|
-
title:
|
|
38
|
+
id: random.string.uuid(),
|
|
39
|
+
title: random.commerce.productName(),
|
|
62
40
|
children: [
|
|
63
41
|
{
|
|
64
|
-
id:
|
|
65
|
-
title:
|
|
42
|
+
id: random.string.uuid(),
|
|
43
|
+
title: random.commerce.productName(),
|
|
66
44
|
children: [
|
|
67
45
|
{
|
|
68
|
-
id:
|
|
69
|
-
title:
|
|
46
|
+
id: random.string.uuid(),
|
|
47
|
+
title: random.commerce.productName(),
|
|
70
48
|
},
|
|
71
49
|
{
|
|
72
|
-
id:
|
|
73
|
-
title:
|
|
50
|
+
id: random.string.uuid(),
|
|
51
|
+
title: random.commerce.productName(),
|
|
74
52
|
},
|
|
75
53
|
],
|
|
76
54
|
},
|
|
@@ -79,24 +57,24 @@ const data: TreeNodeData[] = [
|
|
|
79
57
|
],
|
|
80
58
|
},
|
|
81
59
|
{
|
|
82
|
-
id:
|
|
83
|
-
title:
|
|
60
|
+
id: random.string.uuid(),
|
|
61
|
+
title: random.commerce.productName(),
|
|
84
62
|
iconName: 'ph--planet--regular',
|
|
85
63
|
children: [
|
|
86
64
|
{
|
|
87
|
-
id:
|
|
88
|
-
title:
|
|
65
|
+
id: random.string.uuid(),
|
|
66
|
+
title: random.commerce.productName(),
|
|
89
67
|
},
|
|
90
68
|
],
|
|
91
69
|
},
|
|
92
70
|
{
|
|
93
|
-
id:
|
|
94
|
-
title:
|
|
71
|
+
id: random.string.uuid(),
|
|
72
|
+
title: random.commerce.productName(),
|
|
95
73
|
iconName: 'ph--sailboat--regular',
|
|
96
74
|
},
|
|
97
75
|
{
|
|
98
|
-
id:
|
|
99
|
-
title:
|
|
76
|
+
id: random.string.uuid(),
|
|
77
|
+
title: random.commerce.productName(),
|
|
100
78
|
iconName: 'ph--planet--regular',
|
|
101
79
|
},
|
|
102
80
|
],
|
|
@@ -134,7 +112,7 @@ const Sidebar = ({ mutate }: { mutate?: boolean }) => {
|
|
|
134
112
|
}
|
|
135
113
|
}, []);
|
|
136
114
|
|
|
137
|
-
const handleCreateItem: TreeProps['onMenuAction'] = (id
|
|
115
|
+
const handleCreateItem: TreeProps['onMenuAction'] = (id) => {
|
|
138
116
|
setItems((items) => {
|
|
139
117
|
let parent: TreeNodeData | undefined;
|
|
140
118
|
visitNodes(root, (node) => {
|
|
@@ -144,8 +122,8 @@ const Sidebar = ({ mutate }: { mutate?: boolean }) => {
|
|
|
144
122
|
});
|
|
145
123
|
|
|
146
124
|
(parent!.children ??= []).push({
|
|
147
|
-
id:
|
|
148
|
-
title:
|
|
125
|
+
id: random.string.uuid(),
|
|
126
|
+
title: random.commerce.productName(),
|
|
149
127
|
});
|
|
150
128
|
|
|
151
129
|
setOpenItems((open) => ({ ...open, [parent!.id]: true }));
|
|
@@ -157,9 +135,9 @@ const Sidebar = ({ mutate }: { mutate?: boolean }) => {
|
|
|
157
135
|
const handleCreateSpace = () => {
|
|
158
136
|
setItems((items) => {
|
|
159
137
|
items[0].children?.push({
|
|
160
|
-
id:
|
|
138
|
+
id: random.string.uuid(),
|
|
161
139
|
iconName: 'ph--planet--regular',
|
|
162
|
-
title:
|
|
140
|
+
title: random.commerce.productName(),
|
|
163
141
|
});
|
|
164
142
|
|
|
165
143
|
return { ...items };
|
|
@@ -167,49 +145,68 @@ const Sidebar = ({ mutate }: { mutate?: boolean }) => {
|
|
|
167
145
|
};
|
|
168
146
|
|
|
169
147
|
return (
|
|
170
|
-
<
|
|
171
|
-
<
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
148
|
+
<Panel.Root>
|
|
149
|
+
<Panel.Content asChild>
|
|
150
|
+
<ScrollArea.Root orientation='vertical' thin>
|
|
151
|
+
<ScrollArea.Viewport>
|
|
152
|
+
<Tree
|
|
153
|
+
className='p-0.5 gap-1'
|
|
154
|
+
node={root}
|
|
155
|
+
open={openItems}
|
|
156
|
+
selected={selectedItems}
|
|
157
|
+
active={activeItems}
|
|
158
|
+
onChangeOpen={(id, open) => setOpenItems((items) => ({ ...items, [id]: open }))}
|
|
159
|
+
onChangeSelected={(id, open) => setSelectedItems((items) => ({ ...items, [id]: open }))}
|
|
160
|
+
onMenuAction={handleCreateItem}
|
|
161
|
+
getSlots={(node, open, depth) => {
|
|
162
|
+
if (depth === 1) {
|
|
163
|
+
return {
|
|
164
|
+
root: 'rounded-sm bg-white dark:bg-neutral-850',
|
|
165
|
+
header: mx('rounded-t bg-neutral-50 dark:bg-neutral-900', !open && 'rounded-b'),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}}
|
|
169
|
+
/>
|
|
170
|
+
</ScrollArea.Viewport>
|
|
171
|
+
</ScrollArea.Root>
|
|
172
|
+
</Panel.Content>
|
|
173
|
+
<Panel.Statusbar>
|
|
174
|
+
<div className='flex items-center my-2 px-2 gap-2'>
|
|
175
|
+
<IconButton icon='ph--plus-circle--regular' iconOnly label='Create space' onClick={handleCreateSpace} />
|
|
176
|
+
<span className='grow text-sm' onClick={handleCreateSpace}>
|
|
177
|
+
New space
|
|
178
|
+
</span>
|
|
179
|
+
<Icon icon='ph--list--regular' />
|
|
180
|
+
</div>
|
|
181
|
+
</Panel.Statusbar>
|
|
182
|
+
</Panel.Root>
|
|
200
183
|
);
|
|
201
184
|
};
|
|
202
185
|
|
|
203
186
|
const meta = {
|
|
204
187
|
title: 'plugins/plugin-navtree/experimental/Tree',
|
|
205
188
|
component: Tree,
|
|
206
|
-
decorators: [withTheme, withLayout({
|
|
189
|
+
decorators: [withTheme(), withLayout({ layout: 'column', classNames: 'w-[20rem]' })],
|
|
190
|
+
parameters: {
|
|
191
|
+
layout: 'fullscreen',
|
|
192
|
+
},
|
|
207
193
|
} satisfies Meta<typeof Tree>;
|
|
208
194
|
|
|
209
195
|
export default meta;
|
|
210
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Space:
|
|
199
|
+
* - Space panels are separated from each other to give them more weight than folders.
|
|
200
|
+
* - Private space isn't different (just first, different icon).
|
|
201
|
+
* - Edit titles in place.
|
|
202
|
+
*
|
|
203
|
+
* Navigation:
|
|
204
|
+
* - up/down across spaces/folder peers
|
|
205
|
+
* - right to enter space/folder children
|
|
206
|
+
* - left to parent
|
|
207
|
+
*/
|
|
211
208
|
export const Default = () => {
|
|
212
|
-
return <
|
|
209
|
+
return <Sidebar mutate />;
|
|
213
210
|
};
|
|
214
211
|
|
|
215
212
|
export const Visitor = () => {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import React, { type HTMLAttributes, type PropsWithChildren } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type ClassNameValue, Icon, type Size } from '@dxos/react-ui';
|
|
8
|
-
import { mx } from '@dxos/
|
|
8
|
+
import { mx } from '@dxos/ui-theme';
|
|
9
9
|
|
|
10
10
|
export const IconButton = ({
|
|
11
11
|
iconName,
|
|
@@ -19,7 +19,7 @@ export const IconButton = ({
|
|
|
19
19
|
} & Pick<HTMLAttributes<HTMLDivElement>, 'onClick'>) => {
|
|
20
20
|
// TODO(burdon): Density aware.
|
|
21
21
|
return (
|
|
22
|
-
<div className={mx('flex
|
|
22
|
+
<div className={mx('flex w-6 h-6 items-center justify-center select-none', classNames)} onClick={onClick}>
|
|
23
23
|
<Icon icon={iconName} classNames='cursor-pointer' size={size} />
|
|
24
24
|
</div>
|
|
25
25
|
);
|
|
@@ -193,9 +193,9 @@ export const TreeNodeRow = (props: TreeNodeProps & { className?: string }) => {
|
|
|
193
193
|
<Grid
|
|
194
194
|
style={{ paddingLeft: `${(depth - 1) * 24}px` }}
|
|
195
195
|
className={mx(
|
|
196
|
-
'group
|
|
196
|
+
'group w-full items-center cursor-pointer bg-hover-surface',
|
|
197
197
|
// TODO(burdon): Use data-active.
|
|
198
|
-
selected?.[id] && 'bg-
|
|
198
|
+
selected?.[id] && 'bg-current-surface',
|
|
199
199
|
className,
|
|
200
200
|
)}
|
|
201
201
|
onClick={() => selected && onChangeSelected?.(id, !selected[id])}
|
|
@@ -220,7 +220,7 @@ export const TreeNode = (props: TreeNodeProps & { ancestors?: TreeNodeData[] })
|
|
|
220
220
|
const { root, header } = getSlots?.(props.node, open?.[id] ?? false, depth, ancestors) ?? {};
|
|
221
221
|
|
|
222
222
|
return (
|
|
223
|
-
<div
|
|
223
|
+
<div className={mx('flex flex-col', root)}>
|
|
224
224
|
<TreeNodeRow {...props} className={header} />
|
|
225
225
|
{(children?.length ?? 0) > 0 && open?.[id] && <TreeChildNodes {...props} ancestors={ancestors} />}
|
|
226
226
|
</div>
|