@dxos/plugin-deck 0.7.4 → 0.7.5-labs.071a3e2
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-CI6ZFMNL.mjs +147 -0
- package/dist/lib/browser/app-graph-builder-CI6ZFMNL.mjs.map +7 -0
- package/dist/lib/browser/check-app-scheme-S3EYUPMF.mjs +33 -0
- package/dist/lib/browser/check-app-scheme-S3EYUPMF.mjs.map +7 -0
- package/dist/lib/browser/chunk-BTDY6SES.mjs +1119 -0
- package/dist/lib/browser/chunk-BTDY6SES.mjs.map +7 -0
- package/dist/lib/browser/chunk-FZOBKOA2.mjs +24 -0
- package/dist/lib/browser/chunk-FZOBKOA2.mjs.map +7 -0
- package/dist/lib/browser/chunk-M2L53AIH.mjs +126 -0
- package/dist/lib/browser/chunk-M2L53AIH.mjs.map +7 -0
- package/dist/lib/browser/{chunk-GVOGPULO.mjs → chunk-N7TEPFVR.mjs} +5 -4
- package/dist/lib/browser/chunk-N7TEPFVR.mjs.map +7 -0
- package/dist/lib/browser/chunk-YQ2GWTDU.mjs +17 -0
- package/dist/lib/browser/chunk-YQ2GWTDU.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +100 -1807
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/intent-resolver-CSXFDKTC.mjs +494 -0
- package/dist/lib/browser/intent-resolver-CSXFDKTC.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-root-HIHLRMCW.mjs +46 -0
- package/dist/lib/browser/react-root-HIHLRMCW.mjs.map +7 -0
- package/dist/lib/browser/react-surface-4QVWKQYY.mjs +38 -0
- package/dist/lib/browser/react-surface-4QVWKQYY.mjs.map +7 -0
- package/dist/lib/browser/settings-WACNLCPB.mjs +28 -0
- package/dist/lib/browser/settings-WACNLCPB.mjs.map +7 -0
- package/dist/lib/browser/state-VPOYUKK6.mjs +117 -0
- package/dist/lib/browser/state-VPOYUKK6.mjs.map +7 -0
- package/dist/lib/browser/tools-5LDJNU56.mjs +51 -0
- package/dist/lib/browser/tools-5LDJNU56.mjs.map +7 -0
- package/dist/lib/browser/types.mjs +20 -3
- package/dist/lib/browser/url-handler-HLF42IHP.mjs +70 -0
- package/dist/lib/browser/url-handler-HLF42IHP.mjs.map +7 -0
- package/dist/types/src/DeckPlugin.d.ts +1 -14
- package/dist/types/src/DeckPlugin.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 +142 -0
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
- package/dist/types/src/capabilities/check-app-scheme.d.ts +4 -0
- package/dist/types/src/capabilities/check-app-scheme.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +190 -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/react-root.d.ts +7 -0
- package/dist/types/src/capabilities/react-root.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/set-active.d.ts +9 -0
- package/dist/types/src/capabilities/set-active.d.ts.map +1 -0
- package/dist/types/src/capabilities/settings.d.ts +4 -0
- package/dist/types/src/capabilities/settings.d.ts.map +1 -0
- package/dist/types/src/capabilities/state.d.ts +76 -0
- package/dist/types/src/capabilities/state.d.ts.map +1 -0
- package/dist/types/src/capabilities/tools.d.ts +10 -0
- package/dist/types/src/capabilities/tools.d.ts.map +1 -0
- package/dist/types/src/capabilities/url-handler.d.ts +4 -0
- package/dist/types/src/capabilities/url-handler.d.ts.map +1 -0
- package/dist/types/src/components/DeckLayout/ActiveNode.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Banner.d.ts +6 -0
- package/dist/types/src/components/DeckLayout/Banner.d.ts.map +1 -0
- package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/ContentEmpty.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/DeckLayout.d.ts +1 -4
- package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Fullscreen.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts +3 -3
- package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Plank.d.ts +8 -6
- package/dist/types/src/components/DeckLayout/Plank.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/PlankControls.d.ts +2 -2
- package/dist/types/src/components/DeckLayout/PlankControls.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/PlankError.d.ts +4 -3
- package/dist/types/src/components/DeckLayout/PlankError.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Sidebar.d.ts +1 -5
- package/dist/types/src/components/DeckLayout/Sidebar.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/SidebarButton.d.ts +8 -0
- package/dist/types/src/components/DeckLayout/SidebarButton.d.ts.map +1 -0
- package/dist/types/src/components/DeckLayout/StatusBar.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Toast.d.ts +2 -2
- package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Topbar.d.ts +3 -0
- package/dist/types/src/components/DeckLayout/Topbar.d.ts.map +1 -0
- package/dist/types/src/components/fragments.d.ts +4 -0
- package/dist/types/src/components/fragments.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +0 -2
- 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/hooks/useMainSize.d.ts +2 -2
- package/dist/types/src/index.d.ts +3 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/layout.d.ts +5 -19
- package/dist/types/src/layout.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +4 -4
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +7 -2
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +130 -17
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +3 -2
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/layoutAppliesTopbar.d.ts +2 -0
- package/dist/types/src/util/layoutAppliesTopbar.d.ts.map +1 -0
- package/dist/types/src/util/useBreakpoints.d.ts +2 -0
- package/dist/types/src/util/useBreakpoints.d.ts.map +1 -0
- package/dist/types/src/util/useHoistStatusbar.d.ts +2 -0
- package/dist/types/src/util/useHoistStatusbar.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +32 -36
- package/src/DeckPlugin.ts +83 -0
- package/src/capabilities/app-graph-builder.ts +109 -0
- package/src/capabilities/capabilities.ts +18 -0
- package/src/capabilities/check-app-scheme.ts +44 -0
- package/src/capabilities/index.ts +17 -0
- package/src/capabilities/intent-resolver.ts +350 -0
- package/src/capabilities/react-root.tsx +48 -0
- package/src/capabilities/react-surface.tsx +31 -0
- package/src/capabilities/set-active.ts +43 -0
- package/src/capabilities/settings.ts +21 -0
- package/src/capabilities/state.ts +102 -0
- package/src/capabilities/tools.ts +61 -0
- package/src/capabilities/url-handler.ts +63 -0
- package/src/components/DeckLayout/ActiveNode.tsx +3 -4
- package/src/components/DeckLayout/Banner.tsx +37 -0
- package/src/components/DeckLayout/ComplementarySidebar.tsx +130 -56
- package/src/components/DeckLayout/ContentEmpty.tsx +9 -4
- package/src/components/DeckLayout/DeckLayout.tsx +116 -83
- package/src/components/DeckLayout/Fullscreen.tsx +3 -4
- package/src/components/DeckLayout/NodePlankHeading.tsx +66 -93
- package/src/components/DeckLayout/Plank.tsx +36 -43
- package/src/components/DeckLayout/PlankControls.tsx +12 -13
- package/src/components/DeckLayout/PlankError.tsx +6 -5
- package/src/components/DeckLayout/Sidebar.tsx +19 -26
- package/src/components/DeckLayout/SidebarButton.tsx +68 -0
- package/src/components/DeckLayout/StatusBar.tsx +6 -12
- package/src/components/DeckLayout/Toast.tsx +21 -8
- package/src/components/DeckLayout/Topbar.tsx +11 -0
- package/src/components/LayoutSettings.tsx +8 -8
- package/src/components/fragments.ts +14 -0
- package/src/components/index.ts +0 -2
- package/src/events.ts +11 -0
- package/src/hooks/useMainSize.ts +3 -3
- package/src/index.ts +3 -4
- package/src/layout.ts +43 -212
- package/src/meta.ts +3 -2
- package/src/translations.ts +11 -6
- package/src/types.ts +110 -34
- package/src/util/index.ts +3 -2
- package/src/util/layoutAppliesTopbar.ts +7 -0
- package/src/util/useBreakpoints.ts +11 -0
- package/src/util/useHoistStatusbar.ts +24 -0
- package/dist/lib/browser/chunk-GVOGPULO.mjs.map +0 -7
- package/dist/lib/browser/chunk-NIRHDTX4.mjs +0 -17
- package/dist/lib/browser/chunk-NIRHDTX4.mjs.map +0 -7
- package/dist/lib/browser/meta.mjs +0 -9
- package/dist/lib/browser/meta.mjs.map +0 -7
- package/dist/types/src/components/DeckContext.d.ts +0 -8
- package/dist/types/src/components/DeckContext.d.ts.map +0 -1
- package/dist/types/src/components/LayoutContext.d.ts +0 -5
- package/dist/types/src/components/LayoutContext.d.ts.map +0 -1
- package/dist/types/src/layout.test.d.ts +0 -2
- package/dist/types/src/layout.test.d.ts.map +0 -1
- package/dist/types/src/util/check-app-scheme.d.ts +0 -2
- package/dist/types/src/util/check-app-scheme.d.ts.map +0 -1
- package/dist/types/src/util/layout-parts.d.ts +0 -7
- package/dist/types/src/util/layout-parts.d.ts.map +0 -1
- package/src/DeckPlugin.tsx +0 -657
- package/src/components/DeckContext.ts +0 -14
- package/src/components/LayoutContext.ts +0 -12
- package/src/layout.test.ts +0 -380
- package/src/util/check-app-scheme.ts +0 -21
- package/src/util/layout-parts.ts +0 -12
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
contributes,
|
|
7
|
+
createIntent,
|
|
8
|
+
Capabilities,
|
|
9
|
+
LayoutAction,
|
|
10
|
+
type PromiseIntentDispatcher,
|
|
11
|
+
} from '@dxos/app-framework';
|
|
12
|
+
import { defineTool, ToolResult } from '@dxos/artifact';
|
|
13
|
+
import { S } from '@dxos/echo-schema';
|
|
14
|
+
import { invariant } from '@dxos/invariant';
|
|
15
|
+
|
|
16
|
+
// TODO(burdon): Factor out.
|
|
17
|
+
declare global {
|
|
18
|
+
interface ToolContextExtensions {
|
|
19
|
+
dispatch?: PromiseIntentDispatcher;
|
|
20
|
+
pivotId?: string;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default () =>
|
|
25
|
+
contributes(Capabilities.Tools, [
|
|
26
|
+
defineTool({
|
|
27
|
+
name: 'show',
|
|
28
|
+
// TODO(ZaymonFC): We should update the prompt to teach the LLM the difference between object ids and fully qualified ids.
|
|
29
|
+
description:
|
|
30
|
+
'Show an item in the app. Use this tool to open an artifact. When supplying IDs to show, they must be fully qualified like space:object.',
|
|
31
|
+
// TODO(wittjosiah): Refactor Layout/Navigation/Deck actions so that they can be used directly.
|
|
32
|
+
schema: S.Struct({
|
|
33
|
+
id: S.String.annotations({
|
|
34
|
+
description: 'The ID of the item to show.',
|
|
35
|
+
}),
|
|
36
|
+
pivotId: S.optional(
|
|
37
|
+
S.String.annotations({
|
|
38
|
+
description: 'The ID of the chat. If provided, the item will be added after the pivot item.',
|
|
39
|
+
}),
|
|
40
|
+
),
|
|
41
|
+
}),
|
|
42
|
+
execute: async ({ id }, { extensions }) => {
|
|
43
|
+
invariant(extensions?.dispatch, 'No intent dispatcher');
|
|
44
|
+
const { data, error } = await extensions.dispatch(
|
|
45
|
+
createIntent(LayoutAction.Open, {
|
|
46
|
+
subject: [id],
|
|
47
|
+
part: 'main',
|
|
48
|
+
options: {
|
|
49
|
+
pivotId: extensions.pivotId,
|
|
50
|
+
positioning: 'end',
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
if (error) {
|
|
55
|
+
return ToolResult.Error(error.message);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return ToolResult.Success(data);
|
|
59
|
+
},
|
|
60
|
+
}),
|
|
61
|
+
]);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Capabilities, contributes, createIntent, LayoutAction, type PluginsContext } from '@dxos/app-framework';
|
|
6
|
+
import { scheduledEffect } from '@dxos/echo-signals/core';
|
|
7
|
+
|
|
8
|
+
import { DeckCapabilities } from './capabilities';
|
|
9
|
+
|
|
10
|
+
// TODO(wittjosiah): Cleanup the url handling. May justify introducing routing capabilities.
|
|
11
|
+
export default async (context: PluginsContext) => {
|
|
12
|
+
const { dispatchPromise: dispatch } = context.requestCapability(Capabilities.IntentDispatcher) ?? {};
|
|
13
|
+
const state = context.requestCapability(DeckCapabilities.MutableDeckState);
|
|
14
|
+
|
|
15
|
+
const handleNavigation = async () => {
|
|
16
|
+
const pathname = window.location.pathname;
|
|
17
|
+
if (pathname === '/reset') {
|
|
18
|
+
state.activeDeck = 'default';
|
|
19
|
+
state.decks = {
|
|
20
|
+
default: {
|
|
21
|
+
initialized: false,
|
|
22
|
+
active: [],
|
|
23
|
+
inactive: [],
|
|
24
|
+
fullscreen: false,
|
|
25
|
+
solo: undefined,
|
|
26
|
+
plankSizing: {},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
window.location.pathname = '/';
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const [_, nextDeck, nextSolo] = pathname.split('/');
|
|
34
|
+
if (nextDeck) {
|
|
35
|
+
await dispatch(createIntent(LayoutAction.SwitchWorkspace, { part: 'workspace', subject: nextDeck }));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (nextSolo) {
|
|
39
|
+
await dispatch(
|
|
40
|
+
createIntent(LayoutAction.SetLayoutMode, { part: 'mode', subject: nextSolo, options: { mode: 'solo' } }),
|
|
41
|
+
);
|
|
42
|
+
} else {
|
|
43
|
+
await dispatch(createIntent(LayoutAction.SetLayoutMode, { part: 'mode', options: { mode: 'deck' } }));
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
await handleNavigation();
|
|
48
|
+
window.addEventListener('popstate', handleNavigation);
|
|
49
|
+
|
|
50
|
+
const unsubscribe = scheduledEffect(
|
|
51
|
+
() => ({ solo: state.deck.solo, activeDeck: state.activeDeck }),
|
|
52
|
+
({ solo, activeDeck }) => {
|
|
53
|
+
const path = solo ? `/${activeDeck}/${solo}` : `/${activeDeck}`;
|
|
54
|
+
// TODO(thure): In some browsers, this only preserves the most recent state change, even though this is not `history.replace`…
|
|
55
|
+
history.pushState(null, '', `${path}${window.location.search}`);
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return contributes(Capabilities.Null, null, () => {
|
|
60
|
+
window.removeEventListener('popstate', handleNavigation);
|
|
61
|
+
unsubscribe();
|
|
62
|
+
});
|
|
63
|
+
};
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
|
-
import { Surface } from '@dxos/app-framework';
|
|
8
|
-
import { useGraph } from '@dxos/plugin-graph';
|
|
7
|
+
import { Surface, useAppGraph } from '@dxos/app-framework';
|
|
9
8
|
import { useAttended } from '@dxos/react-ui-attention';
|
|
10
9
|
|
|
11
10
|
import { useNode, useNodeActionExpander } from '../../hooks';
|
|
@@ -13,7 +12,7 @@ import { useNode, useNodeActionExpander } from '../../hooks';
|
|
|
13
12
|
// TODO(burdon): Factor out to effect in plugin set document title.
|
|
14
13
|
export const ActiveNode = () => {
|
|
15
14
|
const [id] = useAttended();
|
|
16
|
-
const { graph } =
|
|
15
|
+
const { graph } = useAppGraph();
|
|
17
16
|
const activeNode = useNode(graph, id);
|
|
18
17
|
useNodeActionExpander(activeNode);
|
|
19
18
|
|
|
@@ -21,7 +20,7 @@ export const ActiveNode = () => {
|
|
|
21
20
|
<div role='none' className='sr-only'>
|
|
22
21
|
{/* TODO(wittjosiah): Weird that this is a surface, feel like it's not really render logic.
|
|
23
22
|
Probably this lives in React-land currently in order to access translations? */}
|
|
24
|
-
<Surface role='document-title' data={{ activeNode }} limit={1} />
|
|
23
|
+
<Surface role='document-title' data={{ subject: activeNode }} limit={1} />
|
|
25
24
|
</div>
|
|
26
25
|
);
|
|
27
26
|
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { Surface } from '@dxos/app-framework';
|
|
8
|
+
import { type ThemedClassName } from '@dxos/react-ui';
|
|
9
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
10
|
+
|
|
11
|
+
import { CloseSidebarButton, ToggleSidebarButton } from './SidebarButton';
|
|
12
|
+
|
|
13
|
+
export const Banner = ({ variant, classNames }: ThemedClassName<{ variant?: 'topbar' | 'sidebar' }>) => {
|
|
14
|
+
return (
|
|
15
|
+
<header
|
|
16
|
+
className={mx(
|
|
17
|
+
'flex items-stretch relative plb-1 pis-1 pie-2',
|
|
18
|
+
variant === 'topbar' &&
|
|
19
|
+
'fixed inset-inline-0 block-start-[env(safe-area-inset-top)] bs-[--rail-size] border-be border-separator',
|
|
20
|
+
classNames,
|
|
21
|
+
)}
|
|
22
|
+
>
|
|
23
|
+
{variant === 'sidebar' ? <CloseSidebarButton /> : <ToggleSidebarButton />}
|
|
24
|
+
<span className='self-center grow mis-1'>Composer</span>
|
|
25
|
+
{variant === 'topbar' && (
|
|
26
|
+
<div role='none' className='absolute inset-0 pointer-events-none'>
|
|
27
|
+
<div role='none' className='grid bs-full pointer-fine:p-1 max-is-md mli-auto pointer-events-auto'>
|
|
28
|
+
<Surface role='search-input' limit={1} />
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
)}
|
|
32
|
+
<span role='none' className='grow' />
|
|
33
|
+
<Surface role='header-end' limit={1} />
|
|
34
|
+
<Surface role='notch-start' limit={1} />
|
|
35
|
+
</header>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
@@ -2,27 +2,28 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { useMemo } from 'react';
|
|
5
|
+
import React, { useCallback, useEffect, useMemo, useState, type MouseEvent } from 'react';
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
SLUG_PATH_SEPARATOR,
|
|
8
|
+
createIntent,
|
|
9
|
+
LayoutAction,
|
|
11
10
|
Surface,
|
|
11
|
+
useAppGraph,
|
|
12
|
+
useCapability,
|
|
12
13
|
useIntentDispatcher,
|
|
13
14
|
} from '@dxos/app-framework';
|
|
14
|
-
import {
|
|
15
|
-
import { Main, ScrollArea } from '@dxos/react-ui';
|
|
15
|
+
import { Main, useTranslation, toLocalizedString, IconButton, ScrollArea } from '@dxos/react-ui';
|
|
16
16
|
import { useAttended } from '@dxos/react-ui-attention';
|
|
17
|
-
import {
|
|
18
|
-
import { mx } from '@dxos/react-ui-theme';
|
|
17
|
+
import { Tabs } from '@dxos/react-ui-tabs';
|
|
19
18
|
|
|
20
|
-
import { NodePlankHeading } from './NodePlankHeading';
|
|
21
19
|
import { PlankContentError } from './PlankError';
|
|
22
20
|
import { PlankLoading } from './PlankLoading';
|
|
21
|
+
import { ToggleComplementarySidebarButton } from './SidebarButton';
|
|
22
|
+
import { DeckCapabilities } from '../../capabilities';
|
|
23
23
|
import { useNode, useNodeActionExpander } from '../../hooks';
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
24
|
+
import { DECK_PLUGIN } from '../../meta';
|
|
25
|
+
import { SLUG_PATH_SEPARATOR, type Panel } from '../../types';
|
|
26
|
+
import { layoutAppliesTopbar, useBreakpoints, useHoistStatusbar } from '../../util';
|
|
26
27
|
|
|
27
28
|
export type ComplementarySidebarProps = {
|
|
28
29
|
panels: Panel[];
|
|
@@ -30,60 +31,133 @@ export type ComplementarySidebarProps = {
|
|
|
30
31
|
};
|
|
31
32
|
|
|
32
33
|
export const ComplementarySidebar = ({ panels, current }: ComplementarySidebarProps) => {
|
|
33
|
-
const
|
|
34
|
+
const layout = useCapability(DeckCapabilities.MutableDeckState);
|
|
34
35
|
const attended = useAttended();
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
36
|
+
const panelIds = useMemo(() => panels.map((panel) => panel.id), [panels]);
|
|
37
|
+
const activePanelId = panelIds.find((panelId) => panelId === current) ?? panels[0].id;
|
|
38
|
+
const activeEntryId = attended[0] ? `${attended[0]}${SLUG_PATH_SEPARATOR}${activePanelId}` : undefined;
|
|
39
|
+
const { graph } = useAppGraph();
|
|
40
|
+
const node = useNode(graph, activeEntryId);
|
|
41
|
+
const { t } = useTranslation(DECK_PLUGIN);
|
|
42
|
+
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
40
43
|
useNodeActionExpander(node);
|
|
44
|
+
const breakpoint = useBreakpoints();
|
|
45
|
+
const topbar = layoutAppliesTopbar(breakpoint);
|
|
46
|
+
const hoistStatusbar = useHoistStatusbar(breakpoint);
|
|
41
47
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
void dispatch({ action: NavigationAction.OPEN, data: { activeParts: { complementary: id } } });
|
|
48
|
-
},
|
|
49
|
-
properties: {
|
|
50
|
-
label,
|
|
51
|
-
icon,
|
|
52
|
-
menuItemType: 'toggle',
|
|
53
|
-
isChecked: panel === id,
|
|
54
|
-
},
|
|
55
|
-
})),
|
|
56
|
-
[panel],
|
|
57
|
-
);
|
|
48
|
+
const [internalValue, setInternalValue] = useState(activePanelId);
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
setInternalValue(activePanelId);
|
|
52
|
+
}, [activePanelId]);
|
|
58
53
|
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
const handleTabClick = useCallback(
|
|
55
|
+
(event: MouseEvent) => {
|
|
56
|
+
const nextValue = event.currentTarget.getAttribute('data-value') as string;
|
|
57
|
+
if (nextValue === activePanelId) {
|
|
58
|
+
layout.complementarySidebarState = layout.complementarySidebarState === 'expanded' ? 'collapsed' : 'expanded';
|
|
59
|
+
} else {
|
|
60
|
+
setInternalValue(nextValue);
|
|
61
|
+
layout.complementarySidebarState = 'expanded';
|
|
62
|
+
void dispatch(createIntent(LayoutAction.UpdateComplementary, { part: 'complementary', subject: nextValue }));
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
[layout, activePanelId, dispatch],
|
|
66
|
+
);
|
|
61
67
|
|
|
62
68
|
// TODO(burdon): Scroll area should be controlled by surface.
|
|
63
69
|
return (
|
|
64
|
-
<Main.ComplementarySidebar
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
<Main.ComplementarySidebar
|
|
71
|
+
classNames={[
|
|
72
|
+
topbar && 'block-start-[calc(env(safe-area-inset-top)+var(--rail-size))]',
|
|
73
|
+
hoistStatusbar && 'block-end-[--statusbar-size]',
|
|
74
|
+
]}
|
|
75
|
+
>
|
|
76
|
+
<Tabs.Root
|
|
77
|
+
orientation='vertical'
|
|
78
|
+
verticalVariant='stateless'
|
|
79
|
+
value={internalValue}
|
|
80
|
+
attendableId={attended[0]}
|
|
81
|
+
classNames='contents'
|
|
82
|
+
>
|
|
83
|
+
<div
|
|
84
|
+
role='none'
|
|
85
|
+
className='absolute z-[1] inset-block-0 inline-end-0 !is-[--r0-size] border-is border-separator grid grid-cols-1 grid-rows-[1fr_min-content] bg-baseSurface contain-layout app-drag'
|
|
86
|
+
>
|
|
87
|
+
<Tabs.Tablist classNames='grid grid-cols-1 auto-rows-[--rail-action] p-1 gap-1 !overflow-y-auto'>
|
|
88
|
+
{panels.map((panel) => (
|
|
89
|
+
<Tabs.Tab key={panel.id} value={panel.id} asChild>
|
|
90
|
+
<IconButton
|
|
91
|
+
label={toLocalizedString(panel.label, t)}
|
|
92
|
+
icon={panel.icon}
|
|
93
|
+
size={5}
|
|
94
|
+
iconOnly
|
|
95
|
+
tooltipSide='left'
|
|
96
|
+
data-value={panel.id}
|
|
97
|
+
variant={
|
|
98
|
+
activePanelId === panel.id
|
|
99
|
+
? layout.complementarySidebarState === 'expanded'
|
|
100
|
+
? 'primary'
|
|
101
|
+
: 'default'
|
|
102
|
+
: 'ghost'
|
|
103
|
+
}
|
|
104
|
+
onClick={handleTabClick}
|
|
78
105
|
/>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
106
|
+
</Tabs.Tab>
|
|
107
|
+
))}
|
|
108
|
+
</Tabs.Tablist>
|
|
109
|
+
{!hoistStatusbar && (
|
|
110
|
+
<div role='none' className='grid grid-cols-1 auto-rows-[--rail-item] p-1 overflow-y-auto'>
|
|
111
|
+
<Surface role='status-bar--r0-footer' limit={1} />
|
|
112
|
+
</div>
|
|
113
|
+
)}
|
|
114
|
+
<div role='none' className='hidden lg:grid grid-cols-1 auto-rows-[--rail-action] p-1'>
|
|
115
|
+
<ToggleComplementarySidebarButton />
|
|
116
|
+
</div>
|
|
85
117
|
</div>
|
|
86
|
-
|
|
118
|
+
{panels.map((panel) => (
|
|
119
|
+
<Tabs.Tabpanel
|
|
120
|
+
key={panel.id}
|
|
121
|
+
value={panel.id}
|
|
122
|
+
classNames='absolute data-[state="inactive"]:-z-[1] inset-block-0 inline-start-0 is-[calc(100%-var(--r0-size))] lg:is-[--r1-size] grid grid-cols-1 grid-rows-[var(--rail-size)_1fr_min-content]'
|
|
123
|
+
{...(layout.complementarySidebarState !== 'expanded' && { inert: 'true' })}
|
|
124
|
+
>
|
|
125
|
+
{panel.id === activePanelId && node && (
|
|
126
|
+
<>
|
|
127
|
+
<h2 className='flex items-center pli-2 border-separator border-be'>
|
|
128
|
+
{toLocalizedString(panel.label, t)}
|
|
129
|
+
</h2>
|
|
130
|
+
<ScrollArea.Root>
|
|
131
|
+
<ScrollArea.Viewport>
|
|
132
|
+
<Surface
|
|
133
|
+
key={activeEntryId}
|
|
134
|
+
role={`complementary--${activePanelId}`}
|
|
135
|
+
data={{
|
|
136
|
+
id: activeEntryId,
|
|
137
|
+
subject: node.properties.object ?? node.properties.space,
|
|
138
|
+
popoverAnchorId: layout.popoverAnchorId,
|
|
139
|
+
}}
|
|
140
|
+
fallback={PlankContentError}
|
|
141
|
+
placeholder={<PlankLoading />}
|
|
142
|
+
/>
|
|
143
|
+
</ScrollArea.Viewport>
|
|
144
|
+
<ScrollArea.Scrollbar orientation='vertical'>
|
|
145
|
+
<ScrollArea.Thumb />
|
|
146
|
+
</ScrollArea.Scrollbar>
|
|
147
|
+
</ScrollArea.Root>
|
|
148
|
+
{!hoistStatusbar && (
|
|
149
|
+
<div
|
|
150
|
+
role='contentinfo'
|
|
151
|
+
className='flex flex-wrap justify-center items-center border-bs border-separator plb-1'
|
|
152
|
+
>
|
|
153
|
+
<Surface role='status-bar--r1-footer' limit={1} />
|
|
154
|
+
</div>
|
|
155
|
+
)}
|
|
156
|
+
</>
|
|
157
|
+
)}
|
|
158
|
+
</Tabs.Tabpanel>
|
|
159
|
+
))}
|
|
160
|
+
</Tabs.Root>
|
|
87
161
|
</Main.ComplementarySidebar>
|
|
88
162
|
);
|
|
89
163
|
};
|
|
@@ -6,16 +6,21 @@ import React from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework';
|
|
8
8
|
|
|
9
|
+
import { ToggleSidebarButton } from './SidebarButton';
|
|
10
|
+
import { layoutAppliesTopbar, useBreakpoints } from '../../util';
|
|
11
|
+
import { fixedSidebarToggleStyles } from '../fragments';
|
|
12
|
+
|
|
9
13
|
export const ContentEmpty = () => {
|
|
14
|
+
const breakpoint = useBreakpoints();
|
|
15
|
+
const topbar = layoutAppliesTopbar(breakpoint);
|
|
10
16
|
return (
|
|
11
17
|
<div
|
|
12
18
|
role='none'
|
|
13
|
-
className='
|
|
19
|
+
className='grid place-items-center p-8 relative bg-deck'
|
|
14
20
|
data-testid='layoutPlugin.firstRunMessage'
|
|
15
21
|
>
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
</div>
|
|
22
|
+
<Surface role='keyshortcuts' />
|
|
23
|
+
{!topbar && <ToggleSidebarButton variant='default' classNames={fixedSidebarToggleStyles} />}
|
|
19
24
|
</div>
|
|
20
25
|
);
|
|
21
26
|
};
|