@dxos/plugin-navtree 0.7.5-main.9cb18ac → 0.7.5-main.9d2a38b
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/app-graph-builder-OF4MMBLH.mjs +42 -0
- package/dist/lib/browser/app-graph-builder-OF4MMBLH.mjs.map +7 -0
- package/dist/lib/browser/chunk-IMGT2LAL.mjs +658 -0
- package/dist/lib/browser/chunk-IMGT2LAL.mjs.map +7 -0
- package/dist/lib/browser/{chunk-VAXG4OAG.mjs → chunk-KOXMEAOS.mjs} +3 -3
- package/dist/lib/browser/{chunk-VAXG4OAG.mjs.map → chunk-KOXMEAOS.mjs.map} +3 -3
- package/dist/lib/browser/chunk-OI7AAA6Q.mjs +15 -0
- package/dist/lib/browser/chunk-OI7AAA6Q.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +105 -1191
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/intent-resolver-74JPWYBP.mjs +42 -0
- package/dist/lib/browser/intent-resolver-74JPWYBP.mjs.map +7 -0
- package/dist/lib/browser/keyboard-MUBRTPI5.mjs +46 -0
- package/dist/lib/browser/keyboard-MUBRTPI5.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-surface-6QWXI53A.mjs +189 -0
- package/dist/lib/browser/react-surface-6QWXI53A.mjs.map +7 -0
- package/dist/lib/browser/state-HT65TAYL.mjs +111 -0
- package/dist/lib/browser/state-HT65TAYL.mjs.map +7 -0
- package/dist/types/src/NavTreePlugin.d.ts +1 -3
- package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/capabilities.d.ts +17 -0
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +195 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/keyboard.d.ts +4 -0
- package/dist/types/src/capabilities/keyboard.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +4 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/state.d.ts +17 -0
- package/dist/types/src/capabilities/state.d.ts.map +1 -0
- package/dist/types/src/components/NavTree.d.ts +0 -2
- package/dist/types/src/components/NavTree.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeContainer.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeFooter.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItemAction.d.ts +4 -8
- package/dist/types/src/components/NavTreeItemAction.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItemAction.stories.d.ts +0 -5
- package/dist/types/src/components/NavTreeItemAction.stories.d.ts.map +1 -1
- package/dist/types/src/components/NotchStart.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/events.d.ts +4 -0
- package/dist/types/src/events.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +0 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +1 -1
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +31 -38
- package/src/NavTreePlugin.tsx +70 -292
- package/src/capabilities/app-graph-builder.ts +40 -0
- package/src/capabilities/capabilities.ts +18 -0
- package/src/capabilities/index.ts +13 -0
- package/src/capabilities/intent-resolver.ts +30 -0
- package/src/capabilities/keyboard.ts +54 -0
- package/src/capabilities/react-surface.tsx +82 -0
- package/src/capabilities/state.ts +100 -0
- package/src/components/CommandsTrigger.tsx +1 -1
- package/src/components/NavTree.tsx +1 -9
- package/src/components/NavTreeContainer.tsx +15 -27
- package/src/components/NavTreeFooter.tsx +18 -16
- package/src/components/NavTreeItemAction.stories.tsx +0 -2
- package/src/components/NavTreeItemAction.tsx +51 -317
- package/src/components/NotchStart.tsx +5 -4
- package/src/components/index.ts +1 -0
- package/src/events.ts +11 -0
- package/src/index.ts +3 -4
- package/src/meta.ts +1 -1
- package/src/translations.ts +0 -1
- package/src/types.ts +1 -1
- package/dist/lib/browser/meta.mjs +0 -13
- package/dist/lib/browser/meta.mjs.map +0 -7
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { effect } from '@preact/signals-core';
|
|
6
|
+
|
|
7
|
+
import { Capabilities, contributes, type PluginsContext } from '@dxos/app-framework';
|
|
8
|
+
import { type ReactiveObject, create } from '@dxos/live-object';
|
|
9
|
+
import { Path } from '@dxos/react-ui-mosaic';
|
|
10
|
+
|
|
11
|
+
import { NavTreeCapabilities } from './capabilities';
|
|
12
|
+
import { NAVTREE_PLUGIN } from '../meta';
|
|
13
|
+
|
|
14
|
+
const KEY = `${NAVTREE_PLUGIN}/state`;
|
|
15
|
+
|
|
16
|
+
const getInitialState = () => {
|
|
17
|
+
const stringified = localStorage.getItem(KEY);
|
|
18
|
+
if (!stringified) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const cached: [string, { open: boolean; current: boolean }][] = JSON.parse(stringified);
|
|
24
|
+
return cached.map(
|
|
25
|
+
([key, value]): [
|
|
26
|
+
string,
|
|
27
|
+
ReactiveObject<{
|
|
28
|
+
open: boolean;
|
|
29
|
+
current: boolean;
|
|
30
|
+
}>,
|
|
31
|
+
] => [key, create({ open: value.open, current: false })],
|
|
32
|
+
);
|
|
33
|
+
} catch {}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default (context: PluginsContext) => {
|
|
37
|
+
// TODO(wittjosiah): This currently needs to be not a ReactiveObject at the root.
|
|
38
|
+
// If it is a ReactiveObject then React errors when initializing new paths because of state change during render.
|
|
39
|
+
// Ideally this could be a ReactiveObject but be able to access and update the root level without breaking render.
|
|
40
|
+
// Wrapping accesses and updates in `untracked` didn't seem to work in all cases.
|
|
41
|
+
const state = new Map<string, ReactiveObject<{ open: boolean; current: boolean }>>(
|
|
42
|
+
getInitialState() ?? [
|
|
43
|
+
// TODO(thure): Initialize these dynamically.
|
|
44
|
+
['root', create({ open: true, current: false })],
|
|
45
|
+
['root~dxos.org/plugin/space-spaces', create({ open: true, current: false })],
|
|
46
|
+
['root~dxos.org/plugin/files', create({ open: true, current: false })],
|
|
47
|
+
],
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const getItem = (_path: string[]) => {
|
|
51
|
+
const path = Path.create(..._path);
|
|
52
|
+
const value = state.get(path) ?? create({ open: false, current: false });
|
|
53
|
+
if (!state.has(path)) {
|
|
54
|
+
state.set(path, value);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return value;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const setItem = (path: string[], key: 'open' | 'current', next: boolean) => {
|
|
61
|
+
const value = getItem(path);
|
|
62
|
+
value[key] = next;
|
|
63
|
+
|
|
64
|
+
localStorage.setItem(KEY, JSON.stringify(Array.from(state.entries())));
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const isOpen = (path: string[]) => getItem(path).open;
|
|
68
|
+
const isCurrent = (path: string[]) => getItem(path).current;
|
|
69
|
+
|
|
70
|
+
const location = context.requestCapability(Capabilities.Location);
|
|
71
|
+
const layout = context.requestCapability(Capabilities.Layout);
|
|
72
|
+
|
|
73
|
+
let previous: string[] = [];
|
|
74
|
+
const unsubscribe = effect(() => {
|
|
75
|
+
const part = layout.layoutMode === 'solo' ? 'solo' : 'main';
|
|
76
|
+
const current = location.active[part]?.map(({ id }) => id) ?? [];
|
|
77
|
+
const removed = previous.filter((id) => !current.includes(id));
|
|
78
|
+
previous = current;
|
|
79
|
+
|
|
80
|
+
// TODO(wittjosiah): This is setTimeout because there's a race between the keys be initialized.
|
|
81
|
+
// This could be avoided if the location was a path as well and not just an id.
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
removed.forEach((id) => {
|
|
84
|
+
const keys = Array.from(state.keys()).filter((key) => Path.last(key) === id);
|
|
85
|
+
keys.forEach((key) => {
|
|
86
|
+
setItem(Path.parts(key), 'current', false);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
current.forEach((id) => {
|
|
91
|
+
const keys = Array.from(new Set([...state.keys(), id])).filter((key) => Path.last(key) === id);
|
|
92
|
+
keys.forEach((key) => {
|
|
93
|
+
setItem(Path.parts(key), 'current', true);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return contributes(NavTreeCapabilities.State, { state, getItem, setItem, isOpen, isCurrent }, () => unsubscribe());
|
|
100
|
+
};
|
|
@@ -17,7 +17,7 @@ export const CommandsTrigger = () => {
|
|
|
17
17
|
const { t } = useTranslation(NAVTREE_PLUGIN);
|
|
18
18
|
return (
|
|
19
19
|
<Button
|
|
20
|
-
classNames='
|
|
20
|
+
classNames='m-1 !pli-1 lg:!pli-2'
|
|
21
21
|
onClick={() =>
|
|
22
22
|
dispatch(
|
|
23
23
|
createIntent(LayoutAction.SetLayout, {
|
|
@@ -23,15 +23,13 @@ export type NavTreeProps = Omit<
|
|
|
23
23
|
|
|
24
24
|
export const NavTree = ({ getActions, loadDescendents, renderItemEnd, popoverAnchorId, ...props }: NavTreeProps) => {
|
|
25
25
|
const renderColumns = useCallback<NonNullable<TreeProps<NavTreeItemGraphNode>['renderColumns']>>(
|
|
26
|
-
({ item, path, open
|
|
26
|
+
({ item, path, open }) => {
|
|
27
27
|
return (
|
|
28
28
|
<NavTreeColumns
|
|
29
29
|
path={path}
|
|
30
30
|
node={item}
|
|
31
31
|
getActions={getActions}
|
|
32
32
|
open={open}
|
|
33
|
-
menuOpen={menuOpen}
|
|
34
|
-
setMenuOpen={setMenuOpen}
|
|
35
33
|
loadDescendents={loadDescendents}
|
|
36
34
|
renderItemEnd={renderItemEnd}
|
|
37
35
|
popoverAnchorId={popoverAnchorId}
|
|
@@ -56,8 +54,6 @@ type NavTreeColumnsProps = {
|
|
|
56
54
|
node: Node;
|
|
57
55
|
getActions: (node: Node) => FlattenedActions;
|
|
58
56
|
open: boolean;
|
|
59
|
-
menuOpen: boolean;
|
|
60
|
-
setMenuOpen: (open: boolean) => void;
|
|
61
57
|
loadDescendents?: (node: Node) => MaybePromise<void>;
|
|
62
58
|
renderItemEnd?: FC<{ node: Node; open: boolean }>;
|
|
63
59
|
popoverAnchorId?: string;
|
|
@@ -68,8 +64,6 @@ const NavTreeColumns = ({
|
|
|
68
64
|
node,
|
|
69
65
|
getActions,
|
|
70
66
|
open,
|
|
71
|
-
menuOpen,
|
|
72
|
-
setMenuOpen,
|
|
73
67
|
loadDescendents,
|
|
74
68
|
renderItemEnd: ItemEnd,
|
|
75
69
|
popoverAnchorId,
|
|
@@ -126,8 +120,6 @@ const NavTreeColumns = ({
|
|
|
126
120
|
menuActions={actions}
|
|
127
121
|
menuType='dropdown'
|
|
128
122
|
caller={NAV_TREE_ITEM}
|
|
129
|
-
menuOpen={menuOpen}
|
|
130
|
-
onChangeMenuOpen={setMenuOpen}
|
|
131
123
|
/>
|
|
132
124
|
) : (
|
|
133
125
|
<Treegrid.Cell />
|
|
@@ -7,7 +7,7 @@ import { extractInstruction, type Instruction } from '@atlaskit/pragmatic-drag-a
|
|
|
7
7
|
import { untracked } from '@preact/signals-core';
|
|
8
8
|
import React, { memo, useCallback, useEffect } from 'react';
|
|
9
9
|
|
|
10
|
-
import { createIntent, LayoutAction, NavigationAction,
|
|
10
|
+
import { createIntent, LayoutAction, NavigationAction, useIntentDispatcher, Surface } from '@dxos/app-framework';
|
|
11
11
|
import { isAction, isActionLike, type Node } from '@dxos/app-graph';
|
|
12
12
|
import { useGraph } from '@dxos/plugin-graph';
|
|
13
13
|
import { isEchoObject, isSpace } from '@dxos/react-client/echo';
|
|
@@ -17,7 +17,6 @@ import { mx } from '@dxos/react-ui-theme';
|
|
|
17
17
|
import { arrayMove } from '@dxos/util';
|
|
18
18
|
|
|
19
19
|
import { NAV_TREE_ITEM, NavTree, type NavTreeProps } from './NavTree';
|
|
20
|
-
import { NavTreeFooter } from './NavTreeFooter';
|
|
21
20
|
import { NAVTREE_PLUGIN } from '../meta';
|
|
22
21
|
import { type NavTreeItemGraphNode } from '../types';
|
|
23
22
|
import {
|
|
@@ -202,31 +201,20 @@ export const NavTreeContainer = memo(({ isCurrent, popoverAnchorId, ...props }:
|
|
|
202
201
|
});
|
|
203
202
|
}, [graph]);
|
|
204
203
|
|
|
204
|
+
// TODO(thure): What gives this an inline `overflow: initial`?
|
|
205
205
|
return (
|
|
206
|
-
<
|
|
207
|
-
{
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
{
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
isCurrent={isCurrent}
|
|
220
|
-
loadDescendents={loadDescendents}
|
|
221
|
-
renderItemEnd={renderItemEnd}
|
|
222
|
-
popoverAnchorId={popoverAnchorId}
|
|
223
|
-
canDrop={canDrop}
|
|
224
|
-
onSelect={handleSelect}
|
|
225
|
-
{...props}
|
|
226
|
-
/>
|
|
227
|
-
</div>
|
|
228
|
-
|
|
229
|
-
<NavTreeFooter />
|
|
230
|
-
</div>
|
|
206
|
+
<NavTree
|
|
207
|
+
id={graph.root.id}
|
|
208
|
+
getActions={getActions}
|
|
209
|
+
getItems={getItems}
|
|
210
|
+
getProps={getProps}
|
|
211
|
+
isCurrent={isCurrent}
|
|
212
|
+
loadDescendents={loadDescendents}
|
|
213
|
+
renderItemEnd={renderItemEnd}
|
|
214
|
+
popoverAnchorId={popoverAnchorId}
|
|
215
|
+
canDrop={canDrop}
|
|
216
|
+
onSelect={handleSelect}
|
|
217
|
+
{...props}
|
|
218
|
+
/>
|
|
231
219
|
);
|
|
232
220
|
});
|
|
@@ -2,17 +2,15 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { ArrowSquareOut, GearSix, Warning } from '@phosphor-icons/react';
|
|
6
5
|
import { formatDistance } from 'date-fns/formatDistance';
|
|
7
6
|
import React from 'react';
|
|
8
7
|
|
|
9
8
|
import {
|
|
10
9
|
type LayoutPart,
|
|
11
10
|
SettingsAction,
|
|
12
|
-
parseNavigationPlugin,
|
|
13
|
-
useResolvePlugin,
|
|
14
11
|
useIntentDispatcher,
|
|
15
12
|
createIntent,
|
|
13
|
+
usePluginManager,
|
|
16
14
|
} from '@dxos/app-framework';
|
|
17
15
|
import { useConfig } from '@dxos/react-client';
|
|
18
16
|
import {
|
|
@@ -25,13 +23,15 @@ import {
|
|
|
25
23
|
useDefaultValue,
|
|
26
24
|
useSidebars,
|
|
27
25
|
useTranslation,
|
|
26
|
+
Icon,
|
|
27
|
+
IconButton,
|
|
28
28
|
} from '@dxos/react-ui';
|
|
29
29
|
import { LayoutControls } from '@dxos/react-ui-stack';
|
|
30
|
-
import {
|
|
30
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
31
31
|
|
|
32
32
|
import { NAVTREE_PLUGIN } from '../meta';
|
|
33
33
|
|
|
34
|
-
const buttonStyles = 'pli-1.5 text-xs font-normal';
|
|
34
|
+
const buttonStyles = '!pli-1.5 text-xs font-normal';
|
|
35
35
|
|
|
36
36
|
const repo = 'https://github.com/dxos/dxos';
|
|
37
37
|
|
|
@@ -44,7 +44,7 @@ export const NavTreeFooter = (props: { layoutPart?: LayoutPart }) => {
|
|
|
44
44
|
const { navigationSidebarOpen } = useSidebars(NAVTREE_PLUGIN);
|
|
45
45
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
46
46
|
const { version, timestamp, commitHash } = config.values.runtime?.app?.build ?? {};
|
|
47
|
-
const
|
|
47
|
+
const manager = usePluginManager();
|
|
48
48
|
const [_, v] = version?.match(VERSION_REGEX) ?? [];
|
|
49
49
|
|
|
50
50
|
const releaseUrl =
|
|
@@ -58,7 +58,7 @@ export const NavTreeFooter = (props: { layoutPart?: LayoutPart }) => {
|
|
|
58
58
|
<div
|
|
59
59
|
role='none'
|
|
60
60
|
className={mx(
|
|
61
|
-
'flex
|
|
61
|
+
'flex pbe-[env(safe-area-inset-bottom)] box-content justify-end',
|
|
62
62
|
layoutPart === 'complementary' && 'md:justify-end flex-row-reverse',
|
|
63
63
|
)}
|
|
64
64
|
>
|
|
@@ -76,7 +76,7 @@ export const NavTreeFooter = (props: { layoutPart?: LayoutPart }) => {
|
|
|
76
76
|
>
|
|
77
77
|
<Message.Root valence='warning' className='rounded-be-none p-5'>
|
|
78
78
|
<Message.Title>
|
|
79
|
-
<
|
|
79
|
+
<Icon icon='ph--warning--duotone' size={6} classNames='inline mie-2' />
|
|
80
80
|
<span>{t('warning title')}</span>
|
|
81
81
|
</Message.Title>
|
|
82
82
|
<Message.Body>
|
|
@@ -84,7 +84,7 @@ export const NavTreeFooter = (props: { layoutPart?: LayoutPart }) => {
|
|
|
84
84
|
<br />
|
|
85
85
|
<Link href={previewUrl} target='_blank' rel='noreferrer' variant='neutral'>
|
|
86
86
|
{t('learn more label')}
|
|
87
|
-
<
|
|
87
|
+
<Icon icon='ph--arrow-square-out--bold' classNames='inline mis-1' />
|
|
88
88
|
</Link>
|
|
89
89
|
</Message.Body>
|
|
90
90
|
</Message.Root>
|
|
@@ -97,7 +97,7 @@ export const NavTreeFooter = (props: { layoutPart?: LayoutPart }) => {
|
|
|
97
97
|
<br />
|
|
98
98
|
<Link href={releaseUrl} target='_blank' rel='noreferrer' variant='neutral'>
|
|
99
99
|
{t('see release label')}
|
|
100
|
-
<
|
|
100
|
+
<Icon icon='ph--arrow-square-out--bold' classNames='inline mis-1' />
|
|
101
101
|
</Link>
|
|
102
102
|
</p>
|
|
103
103
|
)}
|
|
@@ -121,17 +121,19 @@ export const NavTreeFooter = (props: { layoutPart?: LayoutPart }) => {
|
|
|
121
121
|
<Tooltip.Root>
|
|
122
122
|
<Tooltip.Trigger asChild>
|
|
123
123
|
{/* TODO(burdon): Reconcile with action created by LayoutPlugin. */}
|
|
124
|
-
<
|
|
124
|
+
<IconButton
|
|
125
|
+
icon='ph--gear-six--regular'
|
|
126
|
+
iconOnly
|
|
127
|
+
label={t('open settings label')}
|
|
128
|
+
size={4}
|
|
125
129
|
variant='ghost'
|
|
126
130
|
classNames={buttonStyles}
|
|
127
131
|
data-testid='treeView.openSettings'
|
|
128
132
|
data-joyride='welcome/settings'
|
|
129
133
|
{...(!navigationSidebarOpen && { tabIndex: -1 })}
|
|
134
|
+
iconClassNames='rotate-90'
|
|
130
135
|
onClick={() => dispatch(createIntent(SettingsAction.Open))}
|
|
131
|
-
|
|
132
|
-
<span className='sr-only'>{t('open settings label')}</span>
|
|
133
|
-
<GearSix className={mx(getSize(5), 'rotate-90')} />
|
|
134
|
-
</Button>
|
|
136
|
+
/>
|
|
135
137
|
</Tooltip.Trigger>
|
|
136
138
|
<Tooltip.Portal>
|
|
137
139
|
<Tooltip.Content classNames='z-[12]'>
|
|
@@ -142,7 +144,7 @@ export const NavTreeFooter = (props: { layoutPart?: LayoutPart }) => {
|
|
|
142
144
|
</Tooltip.Root>
|
|
143
145
|
|
|
144
146
|
{/* NOTE(thure): Unpinning from the NavTree’s default position in Deck is temporarily disabled. */}
|
|
145
|
-
{
|
|
147
|
+
{manager.enabled.includes('dxos.org/plugin/deck') && (
|
|
146
148
|
<LayoutControls
|
|
147
149
|
variant='hide-disabled'
|
|
148
150
|
capabilities={{
|