@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
|
@@ -2,24 +2,29 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Sidebar as MenuIcon } from '@phosphor-icons/react';
|
|
6
5
|
import { untracked } from '@preact/signals-core';
|
|
7
6
|
import React, { useCallback, useEffect, useMemo, useRef, type UIEvent, Fragment } from 'react';
|
|
8
7
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
8
|
+
import {
|
|
9
|
+
LayoutAction,
|
|
10
|
+
createIntent,
|
|
11
|
+
Surface,
|
|
12
|
+
useCapability,
|
|
13
|
+
useIntentDispatcher,
|
|
14
|
+
usePluginManager,
|
|
15
|
+
} from '@dxos/app-framework';
|
|
16
|
+
import { AttentionCapabilities } from '@dxos/plugin-attention';
|
|
11
17
|
import {
|
|
12
18
|
AlertDialog,
|
|
13
|
-
Button,
|
|
14
19
|
Dialog as NaturalDialog,
|
|
15
20
|
Main,
|
|
16
21
|
Popover,
|
|
17
22
|
useOnTransition,
|
|
18
|
-
useTranslation,
|
|
19
23
|
type MainProps,
|
|
24
|
+
useMediaQuery,
|
|
20
25
|
} from '@dxos/react-ui';
|
|
21
26
|
import { Stack, StackContext, DEFAULT_HORIZONTAL_SIZE } from '@dxos/react-ui-stack';
|
|
22
|
-
import {
|
|
27
|
+
import { mainPaddingTransitions } from '@dxos/react-ui-theme';
|
|
23
28
|
|
|
24
29
|
import { ActiveNode } from './ActiveNode';
|
|
25
30
|
import { ComplementarySidebar, type ComplementarySidebarProps } from './ComplementarySidebar';
|
|
@@ -27,17 +32,16 @@ import { ContentEmpty } from './ContentEmpty';
|
|
|
27
32
|
import { Fullscreen } from './Fullscreen';
|
|
28
33
|
import { Plank } from './Plank';
|
|
29
34
|
import { Sidebar } from './Sidebar';
|
|
35
|
+
import { ToggleComplementarySidebarButton, ToggleSidebarButton } from './SidebarButton';
|
|
30
36
|
import { StatusBar } from './StatusBar';
|
|
31
37
|
import { Toast } from './Toast';
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
38
|
+
import { Topbar } from './Topbar';
|
|
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';
|
|
37
43
|
|
|
38
44
|
export type DeckLayoutProps = {
|
|
39
|
-
layoutParts: LayoutParts;
|
|
40
|
-
toasts: ToastSchema[];
|
|
41
45
|
overscroll: Overscroll;
|
|
42
46
|
showHints: boolean;
|
|
43
47
|
onDismissToast: (id: string) => void;
|
|
@@ -46,12 +50,13 @@ export type DeckLayoutProps = {
|
|
|
46
50
|
const PlankSeparator = ({ index }: { index: number }) =>
|
|
47
51
|
index > 0 ? <span role='separator' className='row-span-2 bg-deck is-4' style={{ gridColumn: index * 2 }} /> : null;
|
|
48
52
|
|
|
49
|
-
export const DeckLayout = ({
|
|
50
|
-
const
|
|
53
|
+
export const DeckLayout = ({ overscroll, showHints, panels, onDismissToast }: DeckLayoutProps) => {
|
|
54
|
+
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
55
|
+
const context = useCapability(DeckCapabilities.MutableDeckState);
|
|
51
56
|
const {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
sidebarState,
|
|
58
|
+
complementarySidebarState,
|
|
59
|
+
complementarySidebarPanel,
|
|
55
60
|
dialogOpen,
|
|
56
61
|
dialogContent,
|
|
57
62
|
dialogBlockAlign,
|
|
@@ -59,22 +64,26 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
59
64
|
popoverOpen,
|
|
60
65
|
popoverContent,
|
|
61
66
|
popoverAnchorId,
|
|
67
|
+
deck,
|
|
68
|
+
toasts,
|
|
62
69
|
} = context;
|
|
63
|
-
const {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
const
|
|
70
|
+
const { active, fullscreen, solo, plankSizing } = deck;
|
|
71
|
+
const breakpoint = useBreakpoints();
|
|
72
|
+
const topbar = layoutAppliesTopbar(breakpoint);
|
|
73
|
+
const hoistStatusbar = useHoistStatusbar(breakpoint);
|
|
74
|
+
const pluginManager = usePluginManager();
|
|
68
75
|
|
|
69
76
|
const scrollLeftRef = useRef<number | null>();
|
|
70
77
|
const deckRef = useRef<HTMLDivElement>(null);
|
|
71
78
|
|
|
72
|
-
const isSoloModeLoaded = layoutMode === 'solo' && Boolean(layoutParts.solo?.[0]);
|
|
73
|
-
|
|
74
79
|
// Ensure the first plank is attended when the deck is first rendered.
|
|
75
80
|
useEffect(() => {
|
|
76
|
-
|
|
77
|
-
const
|
|
81
|
+
// NOTE: Not `useAttended` so that the layout component is not re-rendered when the attended list changes.
|
|
82
|
+
const attended = untracked(() => {
|
|
83
|
+
const attention = pluginManager.context.requestCapability(AttentionCapabilities.Attention);
|
|
84
|
+
return attention.current;
|
|
85
|
+
});
|
|
86
|
+
const firstId = solo ?? active[0];
|
|
78
87
|
if (attended.length === 0 && firstId) {
|
|
79
88
|
// TODO(wittjosiah): Focusing the type button is a workaround.
|
|
80
89
|
// If the plank is directly focused on first load the focus ring appears.
|
|
@@ -82,6 +91,27 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
82
91
|
}
|
|
83
92
|
}, []);
|
|
84
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
|
+
|
|
85
115
|
/**
|
|
86
116
|
* Clear scroll restoration state if the window is resized
|
|
87
117
|
*/
|
|
@@ -100,6 +130,7 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
100
130
|
}
|
|
101
131
|
}, []);
|
|
102
132
|
|
|
133
|
+
const layoutMode = getMode(deck);
|
|
103
134
|
useOnTransition(layoutMode, (mode) => mode !== 'deck', 'deck', restoreScroll);
|
|
104
135
|
|
|
105
136
|
/**
|
|
@@ -107,21 +138,30 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
107
138
|
*/
|
|
108
139
|
const handleScroll = useCallback(
|
|
109
140
|
(event: UIEvent) => {
|
|
110
|
-
if (
|
|
141
|
+
if (!solo && event.currentTarget === event.target) {
|
|
111
142
|
scrollLeftRef.current = (event.target as HTMLDivElement).scrollLeft;
|
|
112
143
|
}
|
|
113
144
|
},
|
|
114
|
-
[
|
|
145
|
+
[solo],
|
|
115
146
|
);
|
|
116
147
|
|
|
117
|
-
const isEmpty =
|
|
148
|
+
const isEmpty = !solo && active.length === 0;
|
|
118
149
|
|
|
119
150
|
const padding = useMemo(() => {
|
|
120
|
-
if (
|
|
121
|
-
return calculateOverscroll(
|
|
151
|
+
if (!solo && overscroll === 'centering') {
|
|
152
|
+
return calculateOverscroll(active.length);
|
|
122
153
|
}
|
|
123
154
|
return {};
|
|
124
|
-
}, [
|
|
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
|
+
);
|
|
125
165
|
|
|
126
166
|
const Dialog = dialogType === 'alert' ? AlertDialog : NaturalDialog;
|
|
127
167
|
|
|
@@ -140,37 +180,27 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
140
180
|
>
|
|
141
181
|
<ActiveNode />
|
|
142
182
|
|
|
143
|
-
{
|
|
183
|
+
{fullscreen && <Fullscreen id={solo} />}
|
|
144
184
|
|
|
145
|
-
{
|
|
185
|
+
{!fullscreen && (
|
|
146
186
|
<Main.Root
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
187
|
+
navigationSidebarState={context.sidebarState}
|
|
188
|
+
onNavigationSidebarStateChange={(next) => (context.sidebarState = next)}
|
|
189
|
+
complementarySidebarState={context.complementarySidebarState}
|
|
190
|
+
onComplementarySidebarStateChange={(next) => (context.complementarySidebarState = next)}
|
|
151
191
|
>
|
|
152
|
-
{/* Notch */}
|
|
153
|
-
<Main.Notch classNames='z-[21]'>
|
|
154
|
-
<Surface role='notch-start' />
|
|
155
|
-
<Button onClick={() => (context.sidebarOpen = !context.sidebarOpen)} variant='ghost' classNames='p-1'>
|
|
156
|
-
<span className='sr-only'>{t('open navigation sidebar label')}</span>
|
|
157
|
-
<MenuIcon weight='light' className={getSize(5)} />
|
|
158
|
-
</Button>
|
|
159
|
-
<Surface role='notch-end' />
|
|
160
|
-
</Main.Notch>
|
|
161
|
-
|
|
162
192
|
{/* Left sidebar. */}
|
|
163
|
-
<Sidebar
|
|
193
|
+
<Sidebar />
|
|
164
194
|
|
|
165
195
|
{/* Right sidebar. */}
|
|
166
|
-
<ComplementarySidebar panels={panels} current={
|
|
196
|
+
<ComplementarySidebar panels={panels} current={complementarySidebarPanel} />
|
|
167
197
|
|
|
168
198
|
{/* Dialog overlay to dismiss dialogs. */}
|
|
169
199
|
<Main.Overlay />
|
|
170
200
|
|
|
171
201
|
{/* No content. */}
|
|
172
202
|
{isEmpty && (
|
|
173
|
-
<Main.Content handlesFocus>
|
|
203
|
+
<Main.Content bounce handlesFocus classNames={mainPosition}>
|
|
174
204
|
<ContentEmpty />
|
|
175
205
|
</Main.Content>
|
|
176
206
|
)}
|
|
@@ -179,78 +209,81 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
179
209
|
{!isEmpty && (
|
|
180
210
|
<Main.Content
|
|
181
211
|
bounce
|
|
182
|
-
classNames=
|
|
212
|
+
classNames={mainPosition}
|
|
183
213
|
handlesFocus
|
|
184
214
|
style={
|
|
185
215
|
{
|
|
186
|
-
'--dx-main-sidebarWidth':
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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`,
|
|
192
230
|
} as MainProps['style']
|
|
193
231
|
}
|
|
194
232
|
>
|
|
195
233
|
<div
|
|
196
234
|
role='none'
|
|
197
|
-
className={!
|
|
198
|
-
{...(
|
|
235
|
+
className={!solo ? 'relative bg-deck overflow-hidden' : 'sr-only'}
|
|
236
|
+
{...(solo && { inert: '' })}
|
|
199
237
|
>
|
|
238
|
+
{!topbar && <ToggleSidebarButton classNames={fixedSidebarToggleStyles} />}
|
|
239
|
+
{!topbar && <ToggleComplementarySidebarButton classNames={fixedComplementarySidebarToggleStyles} />}
|
|
200
240
|
<Stack
|
|
201
|
-
separators={false}
|
|
202
241
|
orientation='horizontal'
|
|
203
242
|
size='contain'
|
|
204
243
|
classNames={['absolute inset-block-0 -inset-inline-px', mainPaddingTransitions]}
|
|
205
244
|
onScroll={handleScroll}
|
|
206
|
-
itemsCount={2 * (
|
|
245
|
+
itemsCount={2 * (active.length ?? 0) - 1}
|
|
207
246
|
style={padding}
|
|
208
247
|
ref={deckRef}
|
|
209
248
|
>
|
|
210
|
-
{
|
|
211
|
-
<Fragment key={
|
|
249
|
+
{active.map((entryId, index) => (
|
|
250
|
+
<Fragment key={entryId}>
|
|
212
251
|
<PlankSeparator index={index} />
|
|
213
|
-
<Plank
|
|
214
|
-
entry={layoutEntry}
|
|
215
|
-
layoutParts={layoutParts}
|
|
216
|
-
part='main'
|
|
217
|
-
layoutMode={layoutMode}
|
|
218
|
-
order={index * 2 + 1}
|
|
219
|
-
/>
|
|
252
|
+
<Plank id={entryId} part='deck' order={index * 2 + 1} active={active} layoutMode={layoutMode} />
|
|
220
253
|
</Fragment>
|
|
221
254
|
))}
|
|
222
255
|
</Stack>
|
|
223
256
|
</div>
|
|
224
257
|
<div
|
|
225
258
|
role='none'
|
|
226
|
-
className={
|
|
227
|
-
{...(!
|
|
259
|
+
className={solo ? 'relative bg-deck overflow-hidden' : 'sr-only'}
|
|
260
|
+
{...(!solo && { inert: '' })}
|
|
228
261
|
>
|
|
229
|
-
<
|
|
230
|
-
|
|
231
|
-
>
|
|
232
|
-
<Plank
|
|
262
|
+
{!topbar && <ToggleSidebarButton classNames={fixedSidebarToggleStyles} />}
|
|
263
|
+
{!topbar && <ToggleComplementarySidebarButton classNames={fixedComplementarySidebarToggleStyles} />}
|
|
264
|
+
<StackContext.Provider value={{ size: 'contain', orientation: 'horizontal', rail: true }}>
|
|
265
|
+
<Plank id={solo} part='solo' layoutMode={layoutMode} />
|
|
233
266
|
</StackContext.Provider>
|
|
234
267
|
</div>
|
|
235
268
|
</Main.Content>
|
|
236
269
|
)}
|
|
237
270
|
|
|
238
|
-
{/*
|
|
239
|
-
<
|
|
271
|
+
{/* Status bar. */}
|
|
272
|
+
{topbar && <Topbar />}
|
|
273
|
+
{hoistStatusbar && <StatusBar showHints={showHints} />}
|
|
240
274
|
</Main.Root>
|
|
241
275
|
)}
|
|
242
276
|
|
|
243
277
|
{/* Global popovers. */}
|
|
244
278
|
<Popover.Portal>
|
|
245
279
|
<Popover.Content
|
|
246
|
-
classNames='z-[60]'
|
|
247
280
|
onEscapeKeyDown={() => {
|
|
248
281
|
context.popoverOpen = false;
|
|
249
282
|
context.popoverAnchorId = undefined;
|
|
250
283
|
}}
|
|
251
284
|
>
|
|
252
285
|
<Popover.Viewport>
|
|
253
|
-
<Surface role='popover' data={popoverContent} />
|
|
286
|
+
<Surface role='popover' data={popoverContent} limit={1} />
|
|
254
287
|
</Popover.Viewport>
|
|
255
288
|
<Popover.Arrow />
|
|
256
289
|
</Popover.Content>
|
|
@@ -259,7 +292,7 @@ export const DeckLayout = ({ layoutParts, toasts, overscroll, showHints, panels,
|
|
|
259
292
|
{/* Global dialog. */}
|
|
260
293
|
<Dialog.Root open={dialogOpen} onOpenChange={(nextOpen) => (context.dialogOpen = nextOpen)}>
|
|
261
294
|
<Dialog.Overlay blockAlign={dialogBlockAlign}>
|
|
262
|
-
<Surface role='dialog' data={dialogContent} />
|
|
295
|
+
<Surface role='dialog' data={dialogContent} limit={1} />
|
|
263
296
|
</Dialog.Overlay>
|
|
264
297
|
</Dialog.Root>
|
|
265
298
|
|
|
@@ -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 (
|
|
@@ -23,7 +22,7 @@ export const Fullscreen = ({ id }: { id?: string }) => {
|
|
|
23
22
|
limit={1}
|
|
24
23
|
fallback={Fallback}
|
|
25
24
|
data={{
|
|
26
|
-
|
|
25
|
+
subject: fullScreenNode?.data,
|
|
27
26
|
component: id?.startsWith(SURFACE_PREFIX) ? id.slice(SURFACE_PREFIX.length) : undefined,
|
|
28
27
|
}}
|
|
29
28
|
/>
|
|
@@ -2,27 +2,23 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { Fragment, memo, useEffect, useMemo } from 'react';
|
|
5
|
+
import React, { Fragment, memo, useCallback, useEffect, useMemo } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
SLUG_PATH_SEPARATOR,
|
|
11
|
-
Surface,
|
|
12
|
-
useIntentDispatcher,
|
|
13
|
-
type LayoutCoordinate,
|
|
14
|
-
} from '@dxos/app-framework';
|
|
15
|
-
import { type Node, useGraph } from '@dxos/plugin-graph';
|
|
16
|
-
import { Icon, Popover, toLocalizedString, useMediaQuery, useTranslation, IconButton } from '@dxos/react-ui';
|
|
7
|
+
import { createIntent, LayoutAction, Surface, useAppGraph, useIntentDispatcher } from '@dxos/app-framework';
|
|
8
|
+
import { type Node } from '@dxos/plugin-graph';
|
|
9
|
+
import { Icon, Popover, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
17
10
|
import { StackItem, type StackItemSigilAction } from '@dxos/react-ui-stack';
|
|
18
11
|
import { TextTooltip } from '@dxos/react-ui-text-tooltip';
|
|
19
12
|
|
|
20
13
|
import { PlankControls } from './PlankControls';
|
|
21
14
|
import { DECK_PLUGIN } from '../../meta';
|
|
22
|
-
import {
|
|
15
|
+
import { DeckAction, SLUG_PATH_SEPARATOR } from '../../types';
|
|
16
|
+
import { useBreakpoints } from '../../util';
|
|
17
|
+
import { soloInlinePadding } from '../fragments';
|
|
23
18
|
|
|
24
19
|
export type NodePlankHeadingProps = {
|
|
25
|
-
|
|
20
|
+
id: string;
|
|
21
|
+
part: 'solo' | 'deck' | 'complementary';
|
|
26
22
|
node?: Node;
|
|
27
23
|
canIncrementStart?: boolean;
|
|
28
24
|
canIncrementEnd?: boolean;
|
|
@@ -33,7 +29,8 @@ export type NodePlankHeadingProps = {
|
|
|
33
29
|
|
|
34
30
|
export const NodePlankHeading = memo(
|
|
35
31
|
({
|
|
36
|
-
|
|
32
|
+
id,
|
|
33
|
+
part,
|
|
37
34
|
node,
|
|
38
35
|
canIncrementStart,
|
|
39
36
|
canIncrementEnd,
|
|
@@ -41,16 +38,15 @@ export const NodePlankHeading = memo(
|
|
|
41
38
|
pending,
|
|
42
39
|
actions = [],
|
|
43
40
|
}: NodePlankHeadingProps) => {
|
|
44
|
-
const layoutContext = useLayout();
|
|
45
41
|
const { t } = useTranslation(DECK_PLUGIN);
|
|
46
|
-
const { graph } =
|
|
42
|
+
const { graph } = useAppGraph();
|
|
43
|
+
const breakpoint = useBreakpoints();
|
|
47
44
|
const icon = node?.properties?.icon ?? 'ph--placeholder--regular';
|
|
48
45
|
const label = pending
|
|
49
46
|
? t('pending heading')
|
|
50
47
|
: toLocalizedString(node?.properties?.label ?? ['plank heading fallback label', { ns: DECK_PLUGIN }], t);
|
|
51
|
-
const dispatch = useIntentDispatcher();
|
|
48
|
+
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
52
49
|
const ActionRoot = node && popoverAnchorId === `dxos.org/ui/${DECK_PLUGIN}/${node.id}` ? Popover.Anchor : Fragment;
|
|
53
|
-
const [isNotMobile] = useMediaQuery('md');
|
|
54
50
|
|
|
55
51
|
useEffect(() => {
|
|
56
52
|
const frame = requestAnimationFrame(() => {
|
|
@@ -61,33 +57,67 @@ export const NodePlankHeading = memo(
|
|
|
61
57
|
return () => cancelAnimationFrame(frame);
|
|
62
58
|
}, [node]);
|
|
63
59
|
|
|
64
|
-
const layoutPart = coordinate.part;
|
|
65
60
|
// NOTE(Zan): Node ids may now contain a path like `${space}:${id}~comments`
|
|
66
|
-
const attendableId =
|
|
61
|
+
const attendableId = id.split(SLUG_PATH_SEPARATOR).at(0);
|
|
67
62
|
const capabilities = useMemo(
|
|
68
63
|
() => ({
|
|
69
|
-
solo: (
|
|
64
|
+
solo: breakpoint !== 'mobile' && (part === 'solo' || part === 'deck'),
|
|
70
65
|
incrementStart: canIncrementStart,
|
|
71
66
|
incrementEnd: canIncrementEnd,
|
|
72
67
|
}),
|
|
73
|
-
[
|
|
68
|
+
[breakpoint, part, canIncrementStart, canIncrementEnd],
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const sigilActions = useMemo(
|
|
72
|
+
() => node && [actions, graph.actions(node)].filter((a) => a.length > 0),
|
|
73
|
+
[actions, node, graph],
|
|
74
|
+
);
|
|
75
|
+
const handleAction = useCallback((action: StackItemSigilAction) => {
|
|
76
|
+
typeof action.data === 'function' && action.data?.({ node: action as Node, caller: DECK_PLUGIN });
|
|
77
|
+
}, []);
|
|
78
|
+
|
|
79
|
+
const handlePlankAction = useCallback(
|
|
80
|
+
(eventType: DeckAction.PartAdjustment) => {
|
|
81
|
+
if (eventType === 'solo') {
|
|
82
|
+
return dispatch(createIntent(DeckAction.Adjust, { type: eventType, id }));
|
|
83
|
+
} else if (eventType === 'close') {
|
|
84
|
+
if (part === 'complementary') {
|
|
85
|
+
return dispatch(
|
|
86
|
+
createIntent(LayoutAction.UpdateComplementary, {
|
|
87
|
+
part: 'complementary',
|
|
88
|
+
options: { state: 'collapsed' },
|
|
89
|
+
}),
|
|
90
|
+
);
|
|
91
|
+
} else {
|
|
92
|
+
return dispatch(
|
|
93
|
+
createIntent(LayoutAction.Close, { part: 'main', subject: [id], options: { state: false } }),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
return dispatch(createIntent(DeckAction.Adjust, { type: eventType, id }));
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
[dispatch, id, part],
|
|
74
101
|
);
|
|
75
102
|
|
|
76
103
|
return (
|
|
77
|
-
<StackItem.Heading
|
|
104
|
+
<StackItem.Heading
|
|
105
|
+
classNames={[
|
|
106
|
+
'plb-1 border-be border-separator items-stretch gap-1 sticky inline-start-12 app-drag',
|
|
107
|
+
part === 'solo' ? soloInlinePadding : 'pli-1',
|
|
108
|
+
]}
|
|
109
|
+
>
|
|
78
110
|
<ActionRoot>
|
|
79
|
-
{node ? (
|
|
111
|
+
{node && sigilActions ? (
|
|
80
112
|
<StackItem.Sigil
|
|
81
113
|
icon={icon}
|
|
82
|
-
related={
|
|
114
|
+
related={part === 'complementary'}
|
|
83
115
|
attendableId={attendableId}
|
|
84
116
|
triggerLabel={t('actions menu label')}
|
|
85
|
-
actions={
|
|
86
|
-
onAction={
|
|
87
|
-
typeof action.data === 'function' && action.data?.({ node: action as Node, caller: DECK_PLUGIN })
|
|
88
|
-
}
|
|
117
|
+
actions={sigilActions}
|
|
118
|
+
onAction={handleAction}
|
|
89
119
|
>
|
|
90
|
-
<Surface role='menu-footer' data={{
|
|
120
|
+
<Surface role='menu-footer' data={{ subject: node.data }} />
|
|
91
121
|
</StackItem.Sigil>
|
|
92
122
|
) : (
|
|
93
123
|
<StackItem.SigilButton>
|
|
@@ -99,76 +129,19 @@ export const NodePlankHeading = memo(
|
|
|
99
129
|
<TextTooltip text={label} onlyWhenTruncating>
|
|
100
130
|
<StackItem.HeadingLabel
|
|
101
131
|
attendableId={attendableId}
|
|
102
|
-
related={
|
|
132
|
+
related={part === 'complementary'}
|
|
103
133
|
{...(pending && { classNames: 'text-description' })}
|
|
104
134
|
>
|
|
105
135
|
{label}
|
|
106
136
|
</StackItem.HeadingLabel>
|
|
107
137
|
</TextTooltip>
|
|
108
|
-
{node &&
|
|
109
|
-
// TODO(Zan): What are we doing with layout coordinate here?
|
|
110
|
-
<Surface role='navbar-end' direction='inline-reverse' data={{ object: node.data }} />
|
|
111
|
-
)}
|
|
112
|
-
{/* NOTE(thure): Pinning & unpinning are temporarily disabled */}
|
|
138
|
+
{node && part !== 'complementary' && <Surface role='navbar-end' data={{ subject: node.data }} />}
|
|
113
139
|
<PlankControls
|
|
114
140
|
capabilities={capabilities}
|
|
115
|
-
isSolo={
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// TODO(Zan): Update this to use the new layout actions.
|
|
123
|
-
if (eventType === 'solo') {
|
|
124
|
-
return dispatch([
|
|
125
|
-
{
|
|
126
|
-
action: NavigationAction.ADJUST,
|
|
127
|
-
data: { type: eventType, layoutCoordinate: { part: 'main', entryId: coordinate.entryId } },
|
|
128
|
-
},
|
|
129
|
-
]);
|
|
130
|
-
} else if (eventType === 'close') {
|
|
131
|
-
if (layoutPart === 'complementary') {
|
|
132
|
-
return dispatch({
|
|
133
|
-
action: LayoutAction.SET_LAYOUT,
|
|
134
|
-
data: {
|
|
135
|
-
element: 'complementary',
|
|
136
|
-
state: false,
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
} else {
|
|
140
|
-
return dispatch({
|
|
141
|
-
action: NavigationAction.CLOSE,
|
|
142
|
-
data: {
|
|
143
|
-
activeParts: {
|
|
144
|
-
[layoutPart]: [coordinate.entryId],
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
} else {
|
|
150
|
-
return dispatch({
|
|
151
|
-
action: NavigationAction.ADJUST,
|
|
152
|
-
data: { type: eventType, layoutCoordinate: coordinate },
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}}
|
|
156
|
-
close={layoutPart === 'complementary' ? 'minify-end' : true}
|
|
157
|
-
>
|
|
158
|
-
{/* TODO(wittjosiah): This doesn't behave exactly the same as the rest of the button group. */}
|
|
159
|
-
{layoutPart !== 'complementary' && (
|
|
160
|
-
<IconButton
|
|
161
|
-
iconOnly
|
|
162
|
-
onClick={() => (layoutContext.complementarySidebarOpen = !layoutContext.complementarySidebarOpen)}
|
|
163
|
-
variant='ghost'
|
|
164
|
-
label={t('open complementary sidebar label')}
|
|
165
|
-
classNames='!pli-2 !plb-3 [&>svg]:-scale-x-100'
|
|
166
|
-
icon='ph--sidebar-simple--regular'
|
|
167
|
-
size={4}
|
|
168
|
-
tooltipZIndex='70'
|
|
169
|
-
/>
|
|
170
|
-
)}
|
|
171
|
-
</PlankControls>
|
|
141
|
+
isSolo={part === 'solo'}
|
|
142
|
+
onClick={handlePlankAction}
|
|
143
|
+
close={part === 'complementary' ? 'minify-end' : true}
|
|
144
|
+
/>
|
|
172
145
|
</StackItem.Heading>
|
|
173
146
|
);
|
|
174
147
|
},
|