@dxos/plugin-deck 0.7.5-main.9d2a38b → 0.7.5-main.e9bb01b
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-67VRUD5K.mjs → app-graph-builder-CI6ZFMNL.mjs} +57 -31
- package/dist/lib/browser/app-graph-builder-CI6ZFMNL.mjs.map +7 -0
- package/dist/lib/browser/{check-app-scheme-GEX6W2R5.mjs → check-app-scheme-S3EYUPMF.mjs} +3 -3
- package/dist/lib/browser/{check-app-scheme-GEX6W2R5.mjs.map → check-app-scheme-S3EYUPMF.mjs.map} +2 -2
- package/dist/lib/browser/chunk-M2L53AIH.mjs +126 -0
- package/dist/lib/browser/chunk-M2L53AIH.mjs.map +7 -0
- package/dist/lib/browser/{chunk-JQJ5UWVB.mjs → chunk-N7TEPFVR.mjs} +3 -2
- package/dist/lib/browser/{chunk-JQJ5UWVB.mjs.map → chunk-N7TEPFVR.mjs.map} +3 -3
- package/dist/lib/browser/chunk-NYZJCVAU.mjs +22 -0
- package/dist/lib/browser/chunk-NYZJCVAU.mjs.map +7 -0
- package/dist/lib/browser/chunk-WXNLVMK2.mjs +1119 -0
- package/dist/lib/browser/chunk-WXNLVMK2.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5VFDMW5M.mjs → chunk-YQ2GWTDU.mjs} +2 -2
- package/dist/lib/browser/chunk-YQ2GWTDU.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +32 -78
- 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-UL7ZDRVZ.mjs → react-root-ECDQZYQT.mjs} +10 -14
- package/dist/lib/browser/react-root-ECDQZYQT.mjs.map +7 -0
- package/dist/lib/browser/react-surface-4WIQZW2S.mjs +38 -0
- package/dist/lib/browser/react-surface-4WIQZW2S.mjs.map +7 -0
- package/dist/lib/browser/{settings-FNWW6WIJ.mjs → settings-WACNLCPB.mjs} +6 -7
- 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/types.mjs +16 -4
- 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.map +1 -1
- package/dist/types/src/capabilities/{layout/app-graph-builder.d.ts → app-graph-builder.d.ts} +22 -22
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/capabilities.d.ts +132 -3
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/check-app-scheme.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +187 -3
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-root.d.ts.map +1 -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.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/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/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.map +1 -1
- package/dist/types/src/components/DeckLayout/SidebarButton.d.ts +5 -3
- package/dist/types/src/components/DeckLayout/SidebarButton.d.ts.map +1 -1
- 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/fragments.d.ts +2 -0
- package/dist/types/src/components/fragments.d.ts.map +1 -1
- 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/hooks/useMainSize.d.ts +2 -2
- 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 +1 -0
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +3 -3
- package/dist/types/src/types.d.ts +107 -2
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +2 -1
- 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/useHoistStatusbar.d.ts.map +1 -1
- package/package.json +30 -30
- package/src/DeckPlugin.ts +12 -58
- package/src/capabilities/{layout/app-graph-builder.ts → app-graph-builder.ts} +36 -28
- package/src/capabilities/capabilities.ts +4 -3
- package/src/capabilities/{navigation/check-app-scheme.ts → check-app-scheme.ts} +2 -2
- package/src/capabilities/index.ts +11 -3
- package/src/capabilities/intent-resolver.ts +350 -0
- package/src/capabilities/{layout/react-root.tsx → react-root.tsx} +7 -11
- package/src/capabilities/react-surface.tsx +31 -0
- package/src/capabilities/set-active.ts +43 -0
- package/src/capabilities/{settings/settings.ts → settings.ts} +4 -5
- package/src/capabilities/state.ts +102 -0
- package/src/capabilities/url-handler.ts +63 -0
- package/src/components/DeckLayout/ActiveNode.tsx +2 -3
- package/src/components/DeckLayout/ComplementarySidebar.tsx +118 -67
- package/src/components/DeckLayout/ContentEmpty.tsx +7 -10
- package/src/components/DeckLayout/DeckLayout.tsx +103 -61
- package/src/components/DeckLayout/Fullscreen.tsx +2 -3
- package/src/components/DeckLayout/NodePlankHeading.tsx +57 -65
- package/src/components/DeckLayout/Plank.tsx +32 -41
- package/src/components/DeckLayout/PlankControls.tsx +11 -10
- package/src/components/DeckLayout/PlankError.tsx +6 -5
- package/src/components/DeckLayout/Sidebar.tsx +17 -20
- package/src/components/DeckLayout/SidebarButton.tsx +25 -31
- package/src/components/DeckLayout/StatusBar.tsx +5 -11
- package/src/components/DeckLayout/Toast.tsx +2 -2
- package/src/components/LayoutSettings.tsx +8 -8
- package/src/components/fragments.ts +8 -0
- package/src/components/index.ts +0 -2
- package/src/hooks/useMainSize.ts +3 -3
- package/src/layout.ts +43 -212
- package/src/meta.ts +1 -0
- package/src/translations.ts +8 -8
- package/src/types.ts +88 -2
- package/src/util/index.ts +2 -1
- package/src/util/layoutAppliesTopbar.ts +7 -0
- package/src/util/useHoistStatusbar.ts +17 -8
- package/dist/lib/browser/app-graph-builder-67VRUD5K.mjs.map +0 -7
- package/dist/lib/browser/chunk-2M4PXYNB.mjs +0 -1052
- package/dist/lib/browser/chunk-2M4PXYNB.mjs.map +0 -7
- package/dist/lib/browser/chunk-2PJNBVCY.mjs +0 -39
- package/dist/lib/browser/chunk-2PJNBVCY.mjs.map +0 -7
- package/dist/lib/browser/chunk-4C2AFTET.mjs +0 -186
- package/dist/lib/browser/chunk-4C2AFTET.mjs.map +0 -7
- package/dist/lib/browser/chunk-5VFDMW5M.mjs.map +0 -7
- package/dist/lib/browser/chunk-KY5WXIXY.mjs +0 -44
- package/dist/lib/browser/chunk-KY5WXIXY.mjs.map +0 -7
- package/dist/lib/browser/deck-PLCSKPGL.mjs +0 -26
- package/dist/lib/browser/deck-PLCSKPGL.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-FVOQSTBX.mjs +0 -152
- package/dist/lib/browser/intent-resolver-FVOQSTBX.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-K7GW4A2I.mjs +0 -249
- package/dist/lib/browser/intent-resolver-K7GW4A2I.mjs.map +0 -7
- package/dist/lib/browser/location-QHRBQBQN.mjs +0 -35
- package/dist/lib/browser/location-QHRBQBQN.mjs.map +0 -7
- package/dist/lib/browser/react-context-3BDW7W2N.mjs +0 -32
- package/dist/lib/browser/react-context-3BDW7W2N.mjs.map +0 -7
- package/dist/lib/browser/react-root-UL7ZDRVZ.mjs.map +0 -7
- package/dist/lib/browser/react-surface-VPNOGGNN.mjs +0 -28
- package/dist/lib/browser/react-surface-VPNOGGNN.mjs.map +0 -7
- package/dist/lib/browser/settings-FNWW6WIJ.mjs.map +0 -7
- package/dist/lib/browser/state-7I5BD7SE.mjs +0 -34
- package/dist/lib/browser/state-7I5BD7SE.mjs.map +0 -7
- package/dist/lib/browser/url-handler-Z5B7LD3N.mjs +0 -76
- package/dist/lib/browser/url-handler-Z5B7LD3N.mjs.map +0 -7
- package/dist/types/src/capabilities/layout/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/capabilities/layout/deck.d.ts +0 -4
- package/dist/types/src/capabilities/layout/deck.d.ts.map +0 -1
- package/dist/types/src/capabilities/layout/index.d.ts +0 -229
- package/dist/types/src/capabilities/layout/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/layout/intent-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/layout/react-context.d.ts +0 -8
- package/dist/types/src/capabilities/layout/react-context.d.ts.map +0 -1
- package/dist/types/src/capabilities/layout/react-root.d.ts.map +0 -1
- package/dist/types/src/capabilities/layout/state.d.ts +0 -42
- package/dist/types/src/capabilities/layout/state.d.ts.map +0 -1
- package/dist/types/src/capabilities/navigation/check-app-scheme.d.ts.map +0 -1
- package/dist/types/src/capabilities/navigation/index.d.ts +0 -5
- package/dist/types/src/capabilities/navigation/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/navigation/intent-resolver.d.ts +0 -4
- package/dist/types/src/capabilities/navigation/intent-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/navigation/location.d.ts +0 -4
- package/dist/types/src/capabilities/navigation/location.d.ts.map +0 -1
- package/dist/types/src/capabilities/navigation/set-location.d.ts +0 -10
- package/dist/types/src/capabilities/navigation/set-location.d.ts.map +0 -1
- package/dist/types/src/capabilities/navigation/url-handler.d.ts.map +0 -1
- package/dist/types/src/capabilities/settings/index.d.ts +0 -3
- package/dist/types/src/capabilities/settings/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/settings/react-surface.d.ts.map +0 -1
- package/dist/types/src/capabilities/settings/settings.d.ts.map +0 -1
- package/dist/types/src/components/DeckContext.d.ts +0 -11
- 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/layout-parts.d.ts +0 -7
- package/dist/types/src/util/layout-parts.d.ts.map +0 -1
- package/src/capabilities/layout/deck.ts +0 -25
- package/src/capabilities/layout/index.ts +0 -12
- package/src/capabilities/layout/intent-resolver.ts +0 -128
- package/src/capabilities/layout/react-context.tsx +0 -26
- package/src/capabilities/layout/state.ts +0 -32
- package/src/capabilities/navigation/index.ts +0 -10
- package/src/capabilities/navigation/intent-resolver.ts +0 -216
- package/src/capabilities/navigation/location.ts +0 -28
- package/src/capabilities/navigation/set-location.ts +0 -38
- package/src/capabilities/navigation/url-handler.ts +0 -67
- package/src/capabilities/settings/index.ts +0 -8
- package/src/capabilities/settings/react-surface.tsx +0 -23
- package/src/components/DeckContext.ts +0 -19
- package/src/components/LayoutContext.ts +0 -12
- package/src/layout.test.ts +0 -380
- package/src/util/layout-parts.ts +0 -12
- /package/dist/types/src/capabilities/{navigation/check-app-scheme.d.ts → check-app-scheme.d.ts} +0 -0
- /package/dist/types/src/capabilities/{layout/intent-resolver.d.ts → intent-resolver.d.ts} +0 -0
- /package/dist/types/src/capabilities/{layout/react-root.d.ts → react-root.d.ts} +0 -0
- /package/dist/types/src/capabilities/{settings/react-surface.d.ts → react-surface.d.ts} +0 -0
- /package/dist/types/src/capabilities/{settings/settings.d.ts → settings.d.ts} +0 -0
- /package/dist/types/src/capabilities/{navigation/url-handler.d.ts → url-handler.d.ts} +0 -0
|
@@ -2,23 +2,28 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
5
|
+
import React, { useCallback, useEffect, useMemo, useState, type MouseEvent } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
import {
|
|
8
|
+
createIntent,
|
|
9
|
+
LayoutAction,
|
|
10
|
+
Surface,
|
|
11
|
+
useAppGraph,
|
|
12
|
+
useCapability,
|
|
13
|
+
useIntentDispatcher,
|
|
14
|
+
} from '@dxos/app-framework';
|
|
15
|
+
import { Main, useTranslation, toLocalizedString, IconButton, ScrollArea } from '@dxos/react-ui';
|
|
10
16
|
import { useAttended } from '@dxos/react-ui-attention';
|
|
11
|
-
import { railGridHorizontal, StackContext, StackItem } from '@dxos/react-ui-stack';
|
|
12
17
|
import { Tabs } from '@dxos/react-ui-tabs';
|
|
13
|
-
import { mx } from '@dxos/react-ui-theme';
|
|
14
18
|
|
|
15
19
|
import { PlankContentError } from './PlankError';
|
|
16
20
|
import { PlankLoading } from './PlankLoading';
|
|
17
|
-
import {
|
|
21
|
+
import { ToggleComplementarySidebarButton } from './SidebarButton';
|
|
22
|
+
import { DeckCapabilities } from '../../capabilities';
|
|
18
23
|
import { useNode, useNodeActionExpander } from '../../hooks';
|
|
19
24
|
import { DECK_PLUGIN } from '../../meta';
|
|
20
|
-
import { type Panel } from '../../types';
|
|
21
|
-
import {
|
|
25
|
+
import { SLUG_PATH_SEPARATOR, type Panel } from '../../types';
|
|
26
|
+
import { layoutAppliesTopbar, useBreakpoints, useHoistStatusbar } from '../../util';
|
|
22
27
|
|
|
23
28
|
export type ComplementarySidebarProps = {
|
|
24
29
|
panels: Panel[];
|
|
@@ -26,16 +31,19 @@ export type ComplementarySidebarProps = {
|
|
|
26
31
|
};
|
|
27
32
|
|
|
28
33
|
export const ComplementarySidebar = ({ panels, current }: ComplementarySidebarProps) => {
|
|
29
|
-
const
|
|
34
|
+
const layout = useCapability(DeckCapabilities.MutableDeckState);
|
|
30
35
|
const attended = useAttended();
|
|
31
36
|
const panelIds = useMemo(() => panels.map((p) => p.id), [panels]);
|
|
32
37
|
const activePanelId = panelIds.find((p) => p === current) ?? panels[0].id;
|
|
33
38
|
const activeEntryId = attended[0] ? `${attended[0]}${SLUG_PATH_SEPARATOR}${activePanelId}` : undefined;
|
|
34
|
-
const { graph } =
|
|
39
|
+
const { graph } = useAppGraph();
|
|
35
40
|
const node = useNode(graph, activeEntryId);
|
|
36
41
|
const { t } = useTranslation(DECK_PLUGIN);
|
|
37
42
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
38
43
|
useNodeActionExpander(node);
|
|
44
|
+
const breakpoint = useBreakpoints();
|
|
45
|
+
const topbar = layoutAppliesTopbar(breakpoint);
|
|
46
|
+
const hoistStatusbar = useHoistStatusbar(breakpoint);
|
|
39
47
|
|
|
40
48
|
const [internalValue, setInternalValue] = useState(activePanelId);
|
|
41
49
|
|
|
@@ -43,70 +51,113 @@ export const ComplementarySidebar = ({ panels, current }: ComplementarySidebarPr
|
|
|
43
51
|
setInternalValue(activePanelId);
|
|
44
52
|
}, [activePanelId]);
|
|
45
53
|
|
|
46
|
-
const
|
|
47
|
-
(
|
|
48
|
-
|
|
49
|
-
|
|
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
|
+
}
|
|
50
64
|
},
|
|
51
|
-
[dispatch],
|
|
65
|
+
[layout, activePanelId, dispatch],
|
|
52
66
|
);
|
|
53
67
|
|
|
54
68
|
// TODO(burdon): Scroll area should be controlled by surface.
|
|
55
69
|
return (
|
|
56
|
-
<Main.ComplementarySidebar
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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}
|
|
105
|
+
/>
|
|
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>
|
|
117
|
+
</div>
|
|
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' })}
|
|
65
124
|
>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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'>
|
|
77
145
|
<ScrollArea.Thumb />
|
|
78
146
|
</ScrollArea.Scrollbar>
|
|
79
|
-
</ScrollArea.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
subject: node.properties.object ?? node.properties.space,
|
|
94
|
-
popoverAnchorId,
|
|
95
|
-
}}
|
|
96
|
-
fallback={PlankContentError}
|
|
97
|
-
placeholder={<PlankLoading />}
|
|
98
|
-
/>
|
|
99
|
-
)}
|
|
100
|
-
</Tabs.Tabpanel>
|
|
101
|
-
))}
|
|
102
|
-
<ScrollArea.Scrollbar orientation='vertical'>
|
|
103
|
-
<ScrollArea.Thumb />
|
|
104
|
-
</ScrollArea.Scrollbar>
|
|
105
|
-
</ScrollArea.Viewport>
|
|
106
|
-
</ScrollArea.Root>
|
|
107
|
-
</Tabs.Root>
|
|
108
|
-
</div>
|
|
109
|
-
</StackContext.Provider>
|
|
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>
|
|
110
161
|
</Main.ComplementarySidebar>
|
|
111
162
|
);
|
|
112
163
|
};
|
|
@@ -5,25 +5,22 @@
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework';
|
|
8
|
-
import { mx } from '@dxos/react-ui-theme';
|
|
9
8
|
|
|
10
9
|
import { ToggleSidebarButton } from './SidebarButton';
|
|
11
|
-
import {
|
|
10
|
+
import { layoutAppliesTopbar, useBreakpoints } from '../../util';
|
|
11
|
+
import { fixedSidebarToggleStyles } from '../fragments';
|
|
12
12
|
|
|
13
13
|
export const ContentEmpty = () => {
|
|
14
|
+
const breakpoint = useBreakpoints();
|
|
15
|
+
const topbar = layoutAppliesTopbar(breakpoint);
|
|
14
16
|
return (
|
|
15
17
|
<div
|
|
16
18
|
role='none'
|
|
17
|
-
className='
|
|
19
|
+
className='grid place-items-center p-8 relative bg-deck'
|
|
18
20
|
data-testid='layoutPlugin.firstRunMessage'
|
|
19
21
|
>
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
<span role='none' className='grow' />
|
|
23
|
-
</div>
|
|
24
|
-
<div role='none' className='grid place-items-center'>
|
|
25
|
-
<Surface role='keyshortcuts' />
|
|
26
|
-
</div>
|
|
22
|
+
<Surface role='keyshortcuts' />
|
|
23
|
+
{!topbar && <ToggleSidebarButton variant='default' classNames={fixedSidebarToggleStyles} />}
|
|
27
24
|
</div>
|
|
28
25
|
);
|
|
29
26
|
};
|
|
@@ -6,14 +6,23 @@ import { untracked } from '@preact/signals-core';
|
|
|
6
6
|
import React, { useCallback, useEffect, useMemo, useRef, type UIEvent, Fragment } from 'react';
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
|
-
|
|
9
|
+
LayoutAction,
|
|
10
|
+
createIntent,
|
|
10
11
|
Surface,
|
|
12
|
+
useCapability,
|
|
13
|
+
useIntentDispatcher,
|
|
11
14
|
usePluginManager,
|
|
12
|
-
type LayoutParts,
|
|
13
|
-
type Toast as ToastSchema,
|
|
14
15
|
} from '@dxos/app-framework';
|
|
15
16
|
import { AttentionCapabilities } from '@dxos/plugin-attention';
|
|
16
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
AlertDialog,
|
|
19
|
+
Dialog as NaturalDialog,
|
|
20
|
+
Main,
|
|
21
|
+
Popover,
|
|
22
|
+
useOnTransition,
|
|
23
|
+
type MainProps,
|
|
24
|
+
useMediaQuery,
|
|
25
|
+
} from '@dxos/react-ui';
|
|
17
26
|
import { Stack, StackContext, DEFAULT_HORIZONTAL_SIZE } from '@dxos/react-ui-stack';
|
|
18
27
|
import { mainPaddingTransitions } from '@dxos/react-ui-theme';
|
|
19
28
|
|
|
@@ -23,18 +32,16 @@ import { ContentEmpty } from './ContentEmpty';
|
|
|
23
32
|
import { Fullscreen } from './Fullscreen';
|
|
24
33
|
import { Plank } from './Plank';
|
|
25
34
|
import { Sidebar } from './Sidebar';
|
|
35
|
+
import { ToggleComplementarySidebarButton, ToggleSidebarButton } from './SidebarButton';
|
|
26
36
|
import { StatusBar } from './StatusBar';
|
|
27
37
|
import { Toast } from './Toast';
|
|
28
38
|
import { Topbar } from './Topbar';
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import { useHoistStatusbar } from '../../util
|
|
32
|
-
import {
|
|
33
|
-
import { useLayout } from '../LayoutContext';
|
|
39
|
+
import { DeckCapabilities } from '../../capabilities';
|
|
40
|
+
import { getMode, type Overscroll } from '../../types';
|
|
41
|
+
import { calculateOverscroll, layoutAppliesTopbar, useBreakpoints, useHoistStatusbar } from '../../util';
|
|
42
|
+
import { fixedComplementarySidebarToggleStyles, fixedSidebarToggleStyles } from '../fragments';
|
|
34
43
|
|
|
35
44
|
export type DeckLayoutProps = {
|
|
36
|
-
layoutParts: LayoutParts;
|
|
37
|
-
toasts: ToastSchema[];
|
|
38
45
|
overscroll: Overscroll;
|
|
39
46
|
showHints: boolean;
|
|
40
47
|
onDismissToast: (id: string) => void;
|
|
@@ -43,12 +50,13 @@ export type DeckLayoutProps = {
|
|
|
43
50
|
const PlankSeparator = ({ index }: { index: number }) =>
|
|
44
51
|
index > 0 ? <span role='separator' className='row-span-2 bg-deck is-4' style={{ gridColumn: index * 2 }} /> : null;
|
|
45
52
|
|
|
46
|
-
export const DeckLayout = ({
|
|
47
|
-
const
|
|
53
|
+
export const DeckLayout = ({ overscroll, showHints, panels, onDismissToast }: DeckLayoutProps) => {
|
|
54
|
+
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
55
|
+
const context = useCapability(DeckCapabilities.MutableDeckState);
|
|
48
56
|
const {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
sidebarState,
|
|
58
|
+
complementarySidebarState,
|
|
59
|
+
complementarySidebarPanel,
|
|
52
60
|
dialogOpen,
|
|
53
61
|
dialogContent,
|
|
54
62
|
dialogBlockAlign,
|
|
@@ -56,18 +64,18 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
56
64
|
popoverOpen,
|
|
57
65
|
popoverContent,
|
|
58
66
|
popoverAnchorId,
|
|
67
|
+
deck,
|
|
68
|
+
toasts,
|
|
59
69
|
} = context;
|
|
70
|
+
const { active, fullscreen, solo, plankSizing } = deck;
|
|
60
71
|
const breakpoint = useBreakpoints();
|
|
72
|
+
const topbar = layoutAppliesTopbar(breakpoint);
|
|
61
73
|
const hoistStatusbar = useHoistStatusbar(breakpoint);
|
|
62
|
-
const { plankSizing } = useDeckContext();
|
|
63
74
|
const pluginManager = usePluginManager();
|
|
64
|
-
const fullScreenSlug = useMemo(() => firstIdInPart(layoutParts, 'fullScreen'), [layoutParts]);
|
|
65
75
|
|
|
66
76
|
const scrollLeftRef = useRef<number | null>();
|
|
67
77
|
const deckRef = useRef<HTMLDivElement>(null);
|
|
68
78
|
|
|
69
|
-
const isSoloModeLoaded = layoutMode === 'solo' && Boolean(layoutParts.solo?.[0]);
|
|
70
|
-
|
|
71
79
|
// Ensure the first plank is attended when the deck is first rendered.
|
|
72
80
|
useEffect(() => {
|
|
73
81
|
// NOTE: Not `useAttended` so that the layout component is not re-rendered when the attended list changes.
|
|
@@ -75,7 +83,7 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
75
83
|
const attention = pluginManager.context.requestCapability(AttentionCapabilities.Attention);
|
|
76
84
|
return attention.current;
|
|
77
85
|
});
|
|
78
|
-
const firstId =
|
|
86
|
+
const firstId = solo ?? active[0];
|
|
79
87
|
if (attended.length === 0 && firstId) {
|
|
80
88
|
// TODO(wittjosiah): Focusing the type button is a workaround.
|
|
81
89
|
// If the plank is directly focused on first load the focus ring appears.
|
|
@@ -83,6 +91,27 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
83
91
|
}
|
|
84
92
|
}, []);
|
|
85
93
|
|
|
94
|
+
// Not using `breakpoint` to avoid firing when breakpoint changes between tablet and desktop.
|
|
95
|
+
// `ssr: false` to avoid using fallback values and flashing into solo mode on startup.
|
|
96
|
+
const [isNotMobile] = useMediaQuery('md', { ssr: false });
|
|
97
|
+
const shouldRevert = useRef(false);
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
if (!isNotMobile && getMode(deck) === 'deck') {
|
|
100
|
+
// NOTE: Not `useAttended` so that the layout component is not re-rendered when the attended list changes.
|
|
101
|
+
const attended = untracked(() => {
|
|
102
|
+
const attention = pluginManager.context.requestCapability(AttentionCapabilities.Attention);
|
|
103
|
+
return attention.current;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
shouldRevert.current = true;
|
|
107
|
+
void dispatch(
|
|
108
|
+
createIntent(LayoutAction.SetLayoutMode, { part: 'mode', subject: attended[0], options: { mode: 'solo' } }),
|
|
109
|
+
);
|
|
110
|
+
} else if (isNotMobile && getMode(deck) === 'solo' && shouldRevert.current) {
|
|
111
|
+
void dispatch(createIntent(LayoutAction.SetLayoutMode, { part: 'mode', options: { revert: true } }));
|
|
112
|
+
}
|
|
113
|
+
}, [isNotMobile, deck, dispatch]);
|
|
114
|
+
|
|
86
115
|
/**
|
|
87
116
|
* Clear scroll restoration state if the window is resized
|
|
88
117
|
*/
|
|
@@ -101,6 +130,7 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
101
130
|
}
|
|
102
131
|
}, []);
|
|
103
132
|
|
|
133
|
+
const layoutMode = getMode(deck);
|
|
104
134
|
useOnTransition(layoutMode, (mode) => mode !== 'deck', 'deck', restoreScroll);
|
|
105
135
|
|
|
106
136
|
/**
|
|
@@ -108,21 +138,30 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
108
138
|
*/
|
|
109
139
|
const handleScroll = useCallback(
|
|
110
140
|
(event: UIEvent) => {
|
|
111
|
-
if (
|
|
141
|
+
if (!solo && event.currentTarget === event.target) {
|
|
112
142
|
scrollLeftRef.current = (event.target as HTMLDivElement).scrollLeft;
|
|
113
143
|
}
|
|
114
144
|
},
|
|
115
|
-
[
|
|
145
|
+
[solo],
|
|
116
146
|
);
|
|
117
147
|
|
|
118
|
-
const isEmpty =
|
|
148
|
+
const isEmpty = !solo && active.length === 0;
|
|
119
149
|
|
|
120
150
|
const padding = useMemo(() => {
|
|
121
|
-
if (
|
|
122
|
-
return calculateOverscroll(
|
|
151
|
+
if (!solo && overscroll === 'centering') {
|
|
152
|
+
return calculateOverscroll(active.length);
|
|
123
153
|
}
|
|
124
154
|
return {};
|
|
125
|
-
}, [
|
|
155
|
+
}, [solo, overscroll, deck]);
|
|
156
|
+
|
|
157
|
+
const mainPosition = useMemo(
|
|
158
|
+
() => [
|
|
159
|
+
'grid !block-start-[env(safe-area-inset-top)]',
|
|
160
|
+
topbar && '!block-start-[calc(env(safe-area-inset-top)+var(--rail-size))]',
|
|
161
|
+
hoistStatusbar && 'lg:block-end-[--statusbar-size]',
|
|
162
|
+
],
|
|
163
|
+
[topbar, hoistStatusbar],
|
|
164
|
+
);
|
|
126
165
|
|
|
127
166
|
const Dialog = dialogType === 'alert' ? AlertDialog : NaturalDialog;
|
|
128
167
|
|
|
@@ -141,27 +180,27 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
141
180
|
>
|
|
142
181
|
<ActiveNode />
|
|
143
182
|
|
|
144
|
-
{
|
|
183
|
+
{fullscreen && <Fullscreen id={solo} />}
|
|
145
184
|
|
|
146
|
-
{
|
|
185
|
+
{!fullscreen && (
|
|
147
186
|
<Main.Root
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
187
|
+
navigationSidebarState={context.sidebarState}
|
|
188
|
+
onNavigationSidebarStateChange={(next) => (context.sidebarState = next)}
|
|
189
|
+
complementarySidebarState={context.complementarySidebarState}
|
|
190
|
+
onComplementarySidebarStateChange={(next) => (context.complementarySidebarState = next)}
|
|
152
191
|
>
|
|
153
192
|
{/* Left sidebar. */}
|
|
154
193
|
<Sidebar />
|
|
155
194
|
|
|
156
195
|
{/* Right sidebar. */}
|
|
157
|
-
<ComplementarySidebar panels={panels} current={
|
|
196
|
+
<ComplementarySidebar panels={panels} current={complementarySidebarPanel} />
|
|
158
197
|
|
|
159
198
|
{/* Dialog overlay to dismiss dialogs. */}
|
|
160
199
|
<Main.Overlay />
|
|
161
200
|
|
|
162
201
|
{/* No content. */}
|
|
163
202
|
{isEmpty && (
|
|
164
|
-
<Main.Content handlesFocus>
|
|
203
|
+
<Main.Content bounce handlesFocus classNames={mainPosition}>
|
|
165
204
|
<ContentEmpty />
|
|
166
205
|
</Main.Content>
|
|
167
206
|
)}
|
|
@@ -170,64 +209,67 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
170
209
|
{!isEmpty && (
|
|
171
210
|
<Main.Content
|
|
172
211
|
bounce
|
|
173
|
-
classNames={
|
|
174
|
-
'grid !block-start-[env(safe-area-inset-top)] lg:!block-start-[calc(env(safe-area-inset-top)+var(--rail-size))]',
|
|
175
|
-
hoistStatusbar && 'lg:block-end-[--statusbar-size]',
|
|
176
|
-
]}
|
|
212
|
+
classNames={mainPosition}
|
|
177
213
|
handlesFocus
|
|
178
214
|
style={
|
|
179
215
|
{
|
|
180
|
-
'--dx-main-sidebarWidth':
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
216
|
+
'--dx-main-sidebarWidth':
|
|
217
|
+
sidebarState === 'expanded'
|
|
218
|
+
? 'var(--nav-sidebar-size)'
|
|
219
|
+
: sidebarState === 'collapsed'
|
|
220
|
+
? 'var(--l0-size)'
|
|
221
|
+
: '0',
|
|
222
|
+
'--dx-main-complementaryWidth':
|
|
223
|
+
complementarySidebarState === 'expanded'
|
|
224
|
+
? 'var(--complementary-sidebar-size)'
|
|
225
|
+
: complementarySidebarState === 'collapsed'
|
|
226
|
+
? 'var(--rail-size)'
|
|
227
|
+
: '0',
|
|
228
|
+
'--dx-main-contentFirstWidth': `${plankSizing[active[0] ?? 'never'] ?? DEFAULT_HORIZONTAL_SIZE}rem`,
|
|
229
|
+
'--dx-main-contentLastWidth': `${plankSizing[active[(active.length ?? 1) - 1] ?? 'never'] ?? DEFAULT_HORIZONTAL_SIZE}rem`,
|
|
186
230
|
} as MainProps['style']
|
|
187
231
|
}
|
|
188
232
|
>
|
|
189
233
|
<div
|
|
190
234
|
role='none'
|
|
191
|
-
className={!
|
|
192
|
-
{...(
|
|
235
|
+
className={!solo ? 'relative bg-deck overflow-hidden' : 'sr-only'}
|
|
236
|
+
{...(solo && { inert: '' })}
|
|
193
237
|
>
|
|
238
|
+
{!topbar && <ToggleSidebarButton classNames={fixedSidebarToggleStyles} />}
|
|
239
|
+
{!topbar && <ToggleComplementarySidebarButton classNames={fixedComplementarySidebarToggleStyles} />}
|
|
194
240
|
<Stack
|
|
195
241
|
orientation='horizontal'
|
|
196
242
|
size='contain'
|
|
197
243
|
classNames={['absolute inset-block-0 -inset-inline-px', mainPaddingTransitions]}
|
|
198
244
|
onScroll={handleScroll}
|
|
199
|
-
itemsCount={2 * (
|
|
245
|
+
itemsCount={2 * (active.length ?? 0) - 1}
|
|
200
246
|
style={padding}
|
|
201
247
|
ref={deckRef}
|
|
202
248
|
>
|
|
203
|
-
{
|
|
204
|
-
<Fragment key={
|
|
249
|
+
{active.map((entryId, index) => (
|
|
250
|
+
<Fragment key={entryId}>
|
|
205
251
|
<PlankSeparator index={index} />
|
|
206
|
-
<Plank
|
|
207
|
-
entry={layoutEntry}
|
|
208
|
-
layoutParts={layoutParts}
|
|
209
|
-
part='main'
|
|
210
|
-
layoutMode={layoutMode}
|
|
211
|
-
order={index * 2 + 1}
|
|
212
|
-
/>
|
|
252
|
+
<Plank id={entryId} part='deck' order={index * 2 + 1} active={active} layoutMode={layoutMode} />
|
|
213
253
|
</Fragment>
|
|
214
254
|
))}
|
|
215
255
|
</Stack>
|
|
216
256
|
</div>
|
|
217
257
|
<div
|
|
218
258
|
role='none'
|
|
219
|
-
className={
|
|
220
|
-
{...(!
|
|
259
|
+
className={solo ? 'relative bg-deck overflow-hidden' : 'sr-only'}
|
|
260
|
+
{...(!solo && { inert: '' })}
|
|
221
261
|
>
|
|
262
|
+
{!topbar && <ToggleSidebarButton classNames={fixedSidebarToggleStyles} />}
|
|
263
|
+
{!topbar && <ToggleComplementarySidebarButton classNames={fixedComplementarySidebarToggleStyles} />}
|
|
222
264
|
<StackContext.Provider value={{ size: 'contain', orientation: 'horizontal', rail: true }}>
|
|
223
|
-
<Plank
|
|
265
|
+
<Plank id={solo} part='solo' layoutMode={layoutMode} />
|
|
224
266
|
</StackContext.Provider>
|
|
225
267
|
</div>
|
|
226
268
|
</Main.Content>
|
|
227
269
|
)}
|
|
228
270
|
|
|
229
271
|
{/* Status bar. */}
|
|
230
|
-
{
|
|
272
|
+
{topbar && <Topbar />}
|
|
231
273
|
{hoistStatusbar && <StatusBar showHints={showHints} />}
|
|
232
274
|
</Main.Root>
|
|
233
275
|
)}
|
|
@@ -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 { fixedInsetFlexLayout } from '@dxos/react-ui-theme';
|
|
10
9
|
|
|
11
10
|
import { Fallback } from './Fallback';
|
|
@@ -13,7 +12,7 @@ import { SURFACE_PREFIX } from './constants';
|
|
|
13
12
|
import { useNode } from '../../hooks';
|
|
14
13
|
|
|
15
14
|
export const Fullscreen = ({ id }: { id?: string }) => {
|
|
16
|
-
const { graph } =
|
|
15
|
+
const { graph } = useAppGraph();
|
|
17
16
|
const fullScreenNode = useNode(graph, id);
|
|
18
17
|
|
|
19
18
|
return (
|