@dxos/plugin-deck 0.8.2-main.f11618f → 0.8.2-staging.7ac8446
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/{check-app-scheme-O7JPE4TM.mjs → check-app-scheme-SEYECDHI.mjs} +3 -2
- package/dist/lib/browser/check-app-scheme-SEYECDHI.mjs.map +7 -0
- package/dist/lib/browser/{chunk-6HJZL3WT.mjs → chunk-6ZSOFCPP.mjs} +7 -8
- package/dist/lib/browser/{chunk-6HJZL3WT.mjs.map → chunk-6ZSOFCPP.mjs.map} +3 -3
- package/dist/lib/browser/chunk-B4LOJUWW.mjs +24 -0
- package/dist/lib/browser/{chunk-RBJ6DLAC.mjs.map → chunk-B4LOJUWW.mjs.map} +3 -3
- package/dist/lib/browser/{chunk-RDFJGGGX.mjs → chunk-FJBMNSUC.mjs} +162 -207
- package/dist/lib/browser/chunk-FJBMNSUC.mjs.map +7 -0
- package/dist/lib/browser/{chunk-ZMJMCN7O.mjs → chunk-RJNCG4ND.mjs} +6 -9
- package/dist/lib/browser/chunk-RJNCG4ND.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +3 -5
- package/dist/lib/browser/index.mjs.map +2 -2
- package/dist/lib/browser/{intent-resolver-JKWXWUV6.mjs → intent-resolver-UDYKO2QW.mjs} +34 -59
- package/dist/lib/browser/intent-resolver-UDYKO2QW.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-root-S6ZAKNZA.mjs → react-root-XLXN2VEW.mjs} +5 -5
- package/dist/lib/browser/{react-surface-I7WZBOGM.mjs → react-surface-WNGMZL7I.mjs} +5 -5
- package/dist/lib/browser/{settings-6NU7CF2B.mjs → settings-HMDGSBGO.mjs} +4 -4
- package/dist/lib/browser/settings-HMDGSBGO.mjs.map +7 -0
- package/dist/lib/browser/{state-Z6UY2Z3M.mjs → state-7TN26M42.mjs} +5 -6
- package/dist/lib/browser/state-7TN26M42.mjs.map +7 -0
- package/dist/lib/browser/{tools-VDVQTJMD.mjs → tools-SC6QEN7R.mjs} +2 -2
- package/dist/lib/browser/types.mjs +1 -1
- package/dist/lib/browser/{url-handler-3CARFXQK.mjs → url-handler-ODG4B6NX.mjs} +2 -2
- package/dist/types/src/capabilities/capabilities.d.ts +6 -8
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/check-app-scheme.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +2 -2
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/state.d.ts +4 -5
- package/dist/types/src/capabilities/state.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.map +1 -1
- package/dist/types/src/components/DeckLayout/Fullscreen.d.ts +5 -0
- package/dist/types/src/components/DeckLayout/Fullscreen.d.ts.map +1 -0
- package/dist/types/src/components/Plank/Plank.d.ts.map +1 -1
- package/dist/types/src/components/Plank/PlankControls.d.ts +2 -2
- package/dist/types/src/components/Plank/PlankControls.d.ts.map +1 -1
- package/dist/types/src/components/Plank/PlankError.d.ts.map +1 -1
- package/dist/types/src/components/Plank/PlankHeading.d.ts +2 -3
- package/dist/types/src/components/Plank/PlankHeading.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/ComplementarySidebar.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/Sidebar.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +0 -2
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +9 -11
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util/layoutAppliesTopbar.d.ts +1 -2
- package/dist/types/src/util/layoutAppliesTopbar.d.ts.map +1 -1
- package/dist/types/src/util/useHoistStatusbar.d.ts +1 -2
- package/dist/types/src/util/useHoistStatusbar.d.ts.map +1 -1
- package/package.json +28 -29
- package/src/capabilities/check-app-scheme.ts +5 -3
- package/src/capabilities/index.ts +2 -2
- package/src/capabilities/intent-resolver.ts +65 -89
- package/src/capabilities/settings.ts +2 -2
- package/src/capabilities/state.ts +2 -3
- package/src/components/DeckLayout/ContentEmpty.tsx +2 -6
- package/src/components/DeckLayout/DeckLayout.tsx +181 -114
- package/src/components/DeckLayout/Fullscreen.tsx +31 -0
- package/src/components/Plank/Plank.tsx +3 -6
- package/src/components/Plank/PlankControls.tsx +34 -40
- package/src/components/Plank/PlankError.tsx +6 -2
- package/src/components/Plank/PlankHeading.tsx +5 -12
- package/src/components/Sidebar/ComplementarySidebar.tsx +20 -30
- package/src/components/Sidebar/Sidebar.tsx +3 -5
- package/src/translations.ts +0 -2
- package/src/types.ts +6 -9
- package/src/util/layoutAppliesTopbar.ts +2 -8
- package/src/util/useHoistStatusbar.ts +4 -9
- package/dist/lib/browser/check-app-scheme-O7JPE4TM.mjs.map +0 -7
- package/dist/lib/browser/chunk-RBJ6DLAC.mjs +0 -24
- package/dist/lib/browser/chunk-RDFJGGGX.mjs.map +0 -7
- package/dist/lib/browser/chunk-ZMJMCN7O.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-JKWXWUV6.mjs.map +0 -7
- package/dist/lib/browser/settings-6NU7CF2B.mjs.map +0 -7
- package/dist/lib/browser/state-Z6UY2Z3M.mjs.map +0 -7
- package/dist/types/src/components/DeckLayout/Dialog.d.ts +0 -3
- package/dist/types/src/components/DeckLayout/Dialog.d.ts.map +0 -1
- package/dist/types/src/components/DeckLayout/Popover.d.ts +0 -5
- package/dist/types/src/components/DeckLayout/Popover.d.ts.map +0 -1
- package/src/components/DeckLayout/Dialog.tsx +0 -36
- package/src/components/DeckLayout/Popover.tsx +0 -104
- /package/dist/lib/browser/{react-root-S6ZAKNZA.mjs.map → react-root-XLXN2VEW.mjs.map} +0 -0
- /package/dist/lib/browser/{react-surface-I7WZBOGM.mjs.map → react-surface-WNGMZL7I.mjs.map} +0 -0
- /package/dist/lib/browser/{tools-VDVQTJMD.mjs.map → tools-SC6QEN7R.mjs.map} +0 -0
- /package/dist/lib/browser/{url-handler-3CARFXQK.mjs.map → url-handler-ODG4B6NX.mjs.map} +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { batch } from '@preact/signals-core';
|
|
6
|
-
import {
|
|
6
|
+
import { pipe } from 'effect';
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
Capabilities,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from '@dxos/app-framework';
|
|
18
18
|
import { getTypename, S } from '@dxos/echo-schema';
|
|
19
19
|
import { invariant } from '@dxos/invariant';
|
|
20
|
-
import {
|
|
20
|
+
import { isReactiveObject } from '@dxos/live-object';
|
|
21
21
|
import { log } from '@dxos/log';
|
|
22
22
|
import { AttentionCapabilities } from '@dxos/plugin-attention';
|
|
23
23
|
import { type Node } from '@dxos/plugin-graph';
|
|
@@ -121,14 +121,9 @@ export default (context: PluginsContext) =>
|
|
|
121
121
|
resolve: ({ subject, options }) => {
|
|
122
122
|
const layout = context.requestCapability(DeckCapabilities.MutableDeckState);
|
|
123
123
|
layout.popoverOpen = options.state ?? Boolean(subject);
|
|
124
|
-
layout.popoverContent =
|
|
125
|
-
|
|
124
|
+
layout.popoverContent = subject ? { component: subject, props: options.props } : null;
|
|
125
|
+
layout.popoverAnchorId = options.anchorId;
|
|
126
126
|
layout.popoverSide = options.side;
|
|
127
|
-
if (options.variant === 'virtual') {
|
|
128
|
-
layout.popoverAnchor = options.anchor;
|
|
129
|
-
} else {
|
|
130
|
-
layout.popoverAnchorId = options.anchorId;
|
|
131
|
-
}
|
|
132
127
|
},
|
|
133
128
|
}),
|
|
134
129
|
createResolver({
|
|
@@ -179,8 +174,10 @@ export default (context: PluginsContext) =>
|
|
|
179
174
|
deck.initialized = true;
|
|
180
175
|
}
|
|
181
176
|
|
|
182
|
-
if (mode === '
|
|
183
|
-
deck.fullscreen =
|
|
177
|
+
if (mode === 'fullscreen' && !deck.fullscreen) {
|
|
178
|
+
deck.fullscreen = true;
|
|
179
|
+
} else if (mode !== 'fullscreen' && deck.fullscreen) {
|
|
180
|
+
deck.fullscreen = false;
|
|
184
181
|
}
|
|
185
182
|
};
|
|
186
183
|
|
|
@@ -241,63 +238,55 @@ export default (context: PluginsContext) =>
|
|
|
241
238
|
intent: LayoutAction.UpdateLayout,
|
|
242
239
|
filter: (data): data is S.Schema.Type<typeof LayoutAction.Open.fields.input> =>
|
|
243
240
|
S.is(LayoutAction.Open.fields.input)(data),
|
|
244
|
-
resolve: ({ subject, options }) =>
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
?.getStore<DeckSettingsProps>(DECK_PLUGIN)?.value;
|
|
252
|
-
|
|
253
|
-
if (options?.workspace && state.activeDeck !== options?.workspace) {
|
|
254
|
-
const { dispatch } = context.requestCapability(Capabilities.IntentDispatcher);
|
|
255
|
-
yield* dispatch(
|
|
256
|
-
createIntent(LayoutAction.SwitchWorkspace, { part: 'workspace', subject: options.workspace }),
|
|
257
|
-
);
|
|
258
|
-
}
|
|
241
|
+
resolve: ({ subject, options }) => {
|
|
242
|
+
const { graph } = context.requestCapability(Capabilities.AppGraph);
|
|
243
|
+
const state = context.requestCapability(DeckCapabilities.MutableDeckState);
|
|
244
|
+
const attention = context.requestCapability(AttentionCapabilities.Attention);
|
|
245
|
+
const settings = context
|
|
246
|
+
.requestCapabilities(Capabilities.SettingsStore)[0]
|
|
247
|
+
?.getStore<DeckSettingsProps>(DECK_PLUGIN)?.value;
|
|
259
248
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
249
|
+
const previouslyOpenIds = new Set<string>(state.deck.solo ? [state.deck.solo] : state.deck.active);
|
|
250
|
+
batch(() => {
|
|
251
|
+
const next = state.deck.solo
|
|
252
|
+
? (subject as string[]).map((id) => createEntryId(id, options?.variant))
|
|
253
|
+
: subject.reduce(
|
|
254
|
+
(acc, entryId) =>
|
|
255
|
+
openEntry(acc, entryId, {
|
|
256
|
+
key: options?.key,
|
|
257
|
+
positioning: options?.positioning ?? settings?.newPlankPositioning,
|
|
258
|
+
pivotId: options?.pivotId,
|
|
259
|
+
variant: options?.variant,
|
|
260
|
+
}),
|
|
261
|
+
state.deck.active,
|
|
262
|
+
);
|
|
274
263
|
|
|
275
|
-
|
|
276
|
-
|
|
264
|
+
return setActive({ next, state, attention });
|
|
265
|
+
});
|
|
277
266
|
|
|
278
|
-
|
|
279
|
-
|
|
267
|
+
const ids = state.deck.solo ? [state.deck.solo] : state.deck.active;
|
|
268
|
+
const newlyOpen = ids.filter((i) => !previouslyOpenIds.has(i));
|
|
280
269
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
270
|
+
return {
|
|
271
|
+
intents: [
|
|
272
|
+
...(options?.scrollIntoView !== false
|
|
273
|
+
? [createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: newlyOpen[0] ?? subject[0] })]
|
|
274
|
+
: []),
|
|
275
|
+
createIntent(LayoutAction.Expose, { part: 'navigation', subject: newlyOpen[0] ?? subject[0] }),
|
|
276
|
+
...newlyOpen.map((subjectId) => {
|
|
277
|
+
const active = graph?.findNode(subjectId)?.data;
|
|
278
|
+
const typename = isReactiveObject(active) ? getTypename(active) : undefined;
|
|
279
|
+
return createIntent(ObservabilityAction.SendEvent, {
|
|
280
|
+
name: 'navigation.activate',
|
|
281
|
+
properties: {
|
|
282
|
+
subjectId,
|
|
283
|
+
typename,
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
}),
|
|
287
|
+
],
|
|
288
|
+
};
|
|
289
|
+
},
|
|
301
290
|
}),
|
|
302
291
|
createResolver({
|
|
303
292
|
intent: LayoutAction.UpdateLayout,
|
|
@@ -401,7 +390,7 @@ export default (context: PluginsContext) =>
|
|
|
401
390
|
}
|
|
402
391
|
}
|
|
403
392
|
|
|
404
|
-
if (adjustment.type
|
|
393
|
+
if (adjustment.type === 'solo') {
|
|
405
394
|
const entryId = adjustment.id;
|
|
406
395
|
if (!state.deck.solo) {
|
|
407
396
|
// Solo the entry.
|
|
@@ -410,34 +399,21 @@ export default (context: PluginsContext) =>
|
|
|
410
399
|
createIntent(LayoutAction.SetLayoutMode, {
|
|
411
400
|
part: 'mode',
|
|
412
401
|
subject: entryId,
|
|
413
|
-
options: { mode:
|
|
402
|
+
options: { mode: 'solo' },
|
|
414
403
|
}),
|
|
415
404
|
],
|
|
416
405
|
};
|
|
417
406
|
} else {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
};
|
|
429
|
-
} else if (adjustment.type === 'solo') {
|
|
430
|
-
// Un-solo the current entry.
|
|
431
|
-
return {
|
|
432
|
-
intents: [
|
|
433
|
-
// NOTE: The order of these is important.
|
|
434
|
-
pipe(
|
|
435
|
-
createIntent(LayoutAction.SetLayoutMode, { part: 'mode', options: { mode: 'deck' } }),
|
|
436
|
-
chain(LayoutAction.Open, { part: 'main', subject: [entryId] }),
|
|
437
|
-
),
|
|
438
|
-
],
|
|
439
|
-
};
|
|
440
|
-
}
|
|
407
|
+
// Un-solo the current entry.
|
|
408
|
+
return {
|
|
409
|
+
intents: [
|
|
410
|
+
// NOTE: The order of these is important.
|
|
411
|
+
pipe(
|
|
412
|
+
createIntent(LayoutAction.SetLayoutMode, { part: 'mode', options: { mode: 'deck' } }),
|
|
413
|
+
chain(LayoutAction.Open, { part: 'main', subject: [entryId] }),
|
|
414
|
+
),
|
|
415
|
+
],
|
|
416
|
+
};
|
|
441
417
|
}
|
|
442
418
|
}
|
|
443
419
|
});
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Capabilities, contributes } from '@dxos/app-framework';
|
|
6
|
-
import {
|
|
6
|
+
import { create } from '@dxos/live-object';
|
|
7
7
|
|
|
8
8
|
import { DECK_PLUGIN } from '../meta';
|
|
9
9
|
import { DeckSettingsSchema, type DeckSettingsProps } from '../types';
|
|
10
10
|
|
|
11
11
|
export default () => {
|
|
12
|
-
const settings =
|
|
12
|
+
const settings = create<DeckSettingsProps>({
|
|
13
13
|
showHints: false,
|
|
14
14
|
enableDeck: true,
|
|
15
15
|
enableNativeRedirect: false,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Capabilities, contributes } from '@dxos/app-framework';
|
|
6
6
|
import { invariant } from '@dxos/invariant';
|
|
7
|
-
import {
|
|
7
|
+
import { create } from '@dxos/live-object';
|
|
8
8
|
import { LocalStorageStore } from '@dxos/local-storage';
|
|
9
9
|
import { type SidebarState } from '@dxos/react-ui';
|
|
10
10
|
|
|
@@ -41,7 +41,6 @@ export default () => {
|
|
|
41
41
|
dialogBlockAlign: undefined,
|
|
42
42
|
dialogType: undefined,
|
|
43
43
|
popoverContent: null,
|
|
44
|
-
popoverAnchor: undefined,
|
|
45
44
|
popoverAnchorId: undefined,
|
|
46
45
|
popoverOpen: false,
|
|
47
46
|
toasts: [],
|
|
@@ -68,7 +67,7 @@ export default () => {
|
|
|
68
67
|
.prop({ key: 'activeDeck', type: LocalStorageStore.string() })
|
|
69
68
|
.prop({ key: 'previousDeck', type: LocalStorageStore.string() });
|
|
70
69
|
|
|
71
|
-
const layout =
|
|
70
|
+
const layout = create<Capabilities.Layout>({
|
|
72
71
|
get mode() {
|
|
73
72
|
return getMode(state.values.deck);
|
|
74
73
|
},
|
|
@@ -4,19 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
|
-
import { Surface
|
|
7
|
+
import { Surface } from '@dxos/app-framework';
|
|
8
8
|
|
|
9
|
-
import { DeckCapabilities } from '../../capabilities';
|
|
10
|
-
import { getMode } from '../../types';
|
|
11
9
|
import { layoutAppliesTopbar, useBreakpoints } from '../../util';
|
|
12
10
|
import { ToggleSidebarButton } from '../Sidebar';
|
|
13
11
|
import { fixedSidebarToggleStyles } from '../fragments';
|
|
14
12
|
|
|
15
13
|
export const ContentEmpty = () => {
|
|
16
14
|
const breakpoint = useBreakpoints();
|
|
17
|
-
const
|
|
18
|
-
const layoutMode = getMode(deck);
|
|
19
|
-
const topbar = layoutAppliesTopbar(breakpoint, layoutMode);
|
|
15
|
+
const topbar = layoutAppliesTopbar(breakpoint);
|
|
20
16
|
return (
|
|
21
17
|
<div
|
|
22
18
|
role='none'
|
|
@@ -3,25 +3,33 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { untracked } from '@preact/signals-core';
|
|
6
|
-
import React, { useCallback, useEffect, useMemo, useRef, type UIEvent, Fragment } from 'react';
|
|
6
|
+
import React, { useCallback, useEffect, useMemo, useRef, type UIEvent, Fragment, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
Capabilities,
|
|
10
10
|
LayoutAction,
|
|
11
|
+
Surface,
|
|
11
12
|
createIntent,
|
|
12
13
|
useCapability,
|
|
13
14
|
useIntentDispatcher,
|
|
14
15
|
usePluginManager,
|
|
15
16
|
} from '@dxos/app-framework';
|
|
16
17
|
import { AttentionCapabilities } from '@dxos/plugin-attention';
|
|
17
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
AlertDialog,
|
|
20
|
+
Dialog as NaturalDialog,
|
|
21
|
+
Main,
|
|
22
|
+
Popover,
|
|
23
|
+
type MainProps,
|
|
24
|
+
useMediaQuery,
|
|
25
|
+
useOnTransition,
|
|
26
|
+
} from '@dxos/react-ui';
|
|
18
27
|
import { Stack, StackContext, DEFAULT_HORIZONTAL_SIZE } from '@dxos/react-ui-stack';
|
|
19
28
|
import { mainPaddingTransitions } from '@dxos/react-ui-theme';
|
|
20
29
|
|
|
21
30
|
import { ActiveNode } from './ActiveNode';
|
|
22
31
|
import { ContentEmpty } from './ContentEmpty';
|
|
23
|
-
import {
|
|
24
|
-
import { PopoverContent, PopoverRoot } from './Popover';
|
|
32
|
+
import { Fullscreen } from './Fullscreen';
|
|
25
33
|
import { StatusBar } from './StatusBar';
|
|
26
34
|
import { Toast } from './Toast';
|
|
27
35
|
import { Topbar } from './Topbar';
|
|
@@ -29,7 +37,7 @@ import { DeckCapabilities } from '../../capabilities';
|
|
|
29
37
|
import { DECK_PLUGIN } from '../../meta';
|
|
30
38
|
import { type DeckSettingsProps, getMode } from '../../types';
|
|
31
39
|
import { calculateOverscroll, layoutAppliesTopbar, useBreakpoints, useHoistStatusbar } from '../../util';
|
|
32
|
-
import { Plank } from '../Plank';
|
|
40
|
+
import { Plank, PlankContentError } from '../Plank';
|
|
33
41
|
import { ComplementarySidebar, Sidebar, ToggleComplementarySidebarButton, ToggleSidebarButton } from '../Sidebar';
|
|
34
42
|
import { fixedComplementarySidebarToggleStyles, fixedSidebarToggleStyles } from '../fragments';
|
|
35
43
|
|
|
@@ -44,17 +52,36 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
44
52
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
45
53
|
const settings = useCapability(Capabilities.SettingsStore).getStore<DeckSettingsProps>(DECK_PLUGIN)!.value;
|
|
46
54
|
const context = useCapability(DeckCapabilities.MutableDeckState);
|
|
47
|
-
const {
|
|
55
|
+
const {
|
|
56
|
+
sidebarState,
|
|
57
|
+
complementarySidebarState,
|
|
58
|
+
complementarySidebarPanel,
|
|
59
|
+
dialogOpen,
|
|
60
|
+
dialogContent,
|
|
61
|
+
dialogBlockAlign,
|
|
62
|
+
dialogType,
|
|
63
|
+
popoverOpen,
|
|
64
|
+
popoverContent,
|
|
65
|
+
popoverAnchorId,
|
|
66
|
+
deck,
|
|
67
|
+
toasts,
|
|
68
|
+
} = context;
|
|
48
69
|
const { active, activeCompanions, fullscreen, solo, plankSizing } = deck;
|
|
49
70
|
const breakpoint = useBreakpoints();
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const hoistStatusbar = useHoistStatusbar(breakpoint, layoutMode);
|
|
71
|
+
const topbar = layoutAppliesTopbar(breakpoint);
|
|
72
|
+
const hoistStatusbar = useHoistStatusbar(breakpoint);
|
|
53
73
|
const pluginManager = usePluginManager();
|
|
54
74
|
|
|
55
75
|
const scrollLeftRef = useRef<number | null>();
|
|
56
76
|
const deckRef = useRef<HTMLDivElement>(null);
|
|
57
77
|
|
|
78
|
+
// TODO(thure): This is a workaround for the difference in `React`ion time between displaying a Popover and rendering
|
|
79
|
+
// the anchor further down the tree. Refactor to use VirtualTrigger or some other approach which does not cause a lag.
|
|
80
|
+
const [delayedPopoverVisibility, setDelayedPopoverVisibility] = useState(false);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
popoverOpen ? setTimeout(() => setDelayedPopoverVisibility(true), 40) : setDelayedPopoverVisibility(false);
|
|
83
|
+
}, [popoverOpen]);
|
|
84
|
+
|
|
58
85
|
// Ensure the first plank is attended when the deck is first rendered.
|
|
59
86
|
useEffect(() => {
|
|
60
87
|
// NOTE: Not `useAttended` so that the layout component is not re-rendered when the attended list changes.
|
|
@@ -117,6 +144,8 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
117
144
|
deckRef.current.scrollLeft = scrollLeftRef.current;
|
|
118
145
|
}
|
|
119
146
|
}, []);
|
|
147
|
+
|
|
148
|
+
const layoutMode = getMode(deck);
|
|
120
149
|
useOnTransition(layoutMode, (mode) => mode !== 'deck', 'deck', restoreScroll);
|
|
121
150
|
|
|
122
151
|
/**
|
|
@@ -149,6 +178,22 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
149
178
|
[topbar, hoistStatusbar],
|
|
150
179
|
);
|
|
151
180
|
|
|
181
|
+
const Dialog = dialogType === 'alert' ? AlertDialog : NaturalDialog;
|
|
182
|
+
|
|
183
|
+
const handlePopoverOpenChange = useCallback(
|
|
184
|
+
(nextOpen: boolean) => {
|
|
185
|
+
if (nextOpen && popoverAnchorId) {
|
|
186
|
+
context.popoverOpen = true;
|
|
187
|
+
} else {
|
|
188
|
+
context.popoverOpen = false;
|
|
189
|
+
context.popoverAnchorId = undefined;
|
|
190
|
+
context.popoverSide = undefined;
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
[context],
|
|
194
|
+
);
|
|
195
|
+
const handlePopoverClose = useCallback(() => handlePopoverOpenChange(false), [handlePopoverOpenChange]);
|
|
196
|
+
|
|
152
197
|
const { order, itemsCount }: { order: Record<string, number>; itemsCount: number } = useMemo(() => {
|
|
153
198
|
return active.reduce(
|
|
154
199
|
(acc: { order: Record<string, number>; itemsCount: number }, entryId) => {
|
|
@@ -161,124 +206,146 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
161
206
|
}, [active, activeCompanions]);
|
|
162
207
|
|
|
163
208
|
return (
|
|
164
|
-
<
|
|
209
|
+
<Popover.Root modal open={!!(popoverAnchorId && delayedPopoverVisibility)} onOpenChange={handlePopoverOpenChange}>
|
|
165
210
|
<ActiveNode />
|
|
166
211
|
|
|
167
|
-
<
|
|
168
|
-
navigationSidebarState={fullscreen ? 'closed' : context.sidebarState}
|
|
169
|
-
onNavigationSidebarStateChange={(next) => (context.sidebarState = next)}
|
|
170
|
-
complementarySidebarState={fullscreen ? 'closed' : context.complementarySidebarState}
|
|
171
|
-
onComplementarySidebarStateChange={(next) => (context.complementarySidebarState = next)}
|
|
172
|
-
>
|
|
173
|
-
{/* Left sidebar. */}
|
|
174
|
-
<Sidebar />
|
|
212
|
+
{fullscreen && <Fullscreen id={solo} />}
|
|
175
213
|
|
|
176
|
-
|
|
177
|
-
<
|
|
214
|
+
{!fullscreen && (
|
|
215
|
+
<Main.Root
|
|
216
|
+
navigationSidebarState={context.sidebarState}
|
|
217
|
+
onNavigationSidebarStateChange={(next) => (context.sidebarState = next)}
|
|
218
|
+
complementarySidebarState={context.complementarySidebarState}
|
|
219
|
+
onComplementarySidebarStateChange={(next) => (context.complementarySidebarState = next)}
|
|
220
|
+
>
|
|
221
|
+
{/* Left sidebar. */}
|
|
222
|
+
<Sidebar />
|
|
178
223
|
|
|
179
|
-
|
|
180
|
-
|
|
224
|
+
{/* Right sidebar. */}
|
|
225
|
+
<ComplementarySidebar current={complementarySidebarPanel} />
|
|
181
226
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
<Main.Content bounce handlesFocus classNames={mainPosition}>
|
|
185
|
-
<ContentEmpty />
|
|
186
|
-
</Main.Content>
|
|
187
|
-
)}
|
|
227
|
+
{/* Dialog overlay to dismiss dialogs. */}
|
|
228
|
+
<Main.Overlay />
|
|
188
229
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
230
|
+
{/* No content. */}
|
|
231
|
+
{isEmpty && (
|
|
232
|
+
<Main.Content bounce handlesFocus classNames={mainPosition}>
|
|
233
|
+
<ContentEmpty />
|
|
234
|
+
</Main.Content>
|
|
235
|
+
)}
|
|
236
|
+
|
|
237
|
+
{/* Solo/deck mode. */}
|
|
238
|
+
{!isEmpty && (
|
|
239
|
+
<Main.Content
|
|
240
|
+
bounce
|
|
241
|
+
classNames={mainPosition}
|
|
242
|
+
handlesFocus
|
|
243
|
+
style={
|
|
244
|
+
{
|
|
245
|
+
'--dx-main-sidebarWidth':
|
|
246
|
+
sidebarState === 'expanded'
|
|
247
|
+
? 'var(--nav-sidebar-size)'
|
|
248
|
+
: sidebarState === 'collapsed'
|
|
249
|
+
? 'var(--l0-size)'
|
|
250
|
+
: '0',
|
|
251
|
+
'--dx-main-complementaryWidth':
|
|
252
|
+
complementarySidebarState === 'expanded'
|
|
253
|
+
? 'var(--complementary-sidebar-size)'
|
|
254
|
+
: complementarySidebarState === 'collapsed'
|
|
255
|
+
? 'var(--rail-size)'
|
|
256
|
+
: '0',
|
|
257
|
+
'--dx-main-contentFirstWidth': `${plankSizing[active[0] ?? 'never'] ?? DEFAULT_HORIZONTAL_SIZE}rem`,
|
|
258
|
+
'--dx-main-contentLastWidth': `${plankSizing[active[(active.length ?? 1) - 1] ?? 'never'] ?? DEFAULT_HORIZONTAL_SIZE}rem`,
|
|
259
|
+
} as MainProps['style']
|
|
260
|
+
}
|
|
218
261
|
>
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
<Stack
|
|
224
|
-
ref={deckRef}
|
|
225
|
-
orientation='horizontal'
|
|
226
|
-
size='contain'
|
|
227
|
-
classNames={['absolute inset-block-0 -inset-inline-px', mainPaddingTransitions]}
|
|
228
|
-
itemsCount={itemsCount - 1}
|
|
229
|
-
style={padding}
|
|
230
|
-
onScroll={handleScroll}
|
|
262
|
+
<div
|
|
263
|
+
role='none'
|
|
264
|
+
className={!solo ? 'relative bg-deck overflow-hidden' : 'sr-only'}
|
|
265
|
+
{...(solo && { inert: '' })}
|
|
231
266
|
>
|
|
232
|
-
{
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
/>
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
267
|
+
{!topbar && <ToggleSidebarButton classNames={fixedSidebarToggleStyles} />}
|
|
268
|
+
{!topbar && <ToggleComplementarySidebarButton classNames={fixedComplementarySidebarToggleStyles} />}
|
|
269
|
+
<Stack
|
|
270
|
+
ref={deckRef}
|
|
271
|
+
orientation='horizontal'
|
|
272
|
+
size='contain'
|
|
273
|
+
classNames={['absolute inset-block-0 -inset-inline-px', mainPaddingTransitions]}
|
|
274
|
+
itemsCount={itemsCount - 1}
|
|
275
|
+
style={padding}
|
|
276
|
+
onScroll={handleScroll}
|
|
277
|
+
>
|
|
278
|
+
{active.map((entryId) => (
|
|
279
|
+
<Fragment key={entryId}>
|
|
280
|
+
<PlankSeparator order={order[entryId] - 1} />
|
|
281
|
+
<Plank
|
|
282
|
+
id={entryId}
|
|
283
|
+
companionId={activeCompanions?.[entryId]}
|
|
284
|
+
part='deck'
|
|
285
|
+
order={order[entryId]}
|
|
286
|
+
active={active}
|
|
287
|
+
layoutMode={layoutMode}
|
|
288
|
+
settings={settings}
|
|
289
|
+
/>
|
|
290
|
+
</Fragment>
|
|
291
|
+
))}
|
|
292
|
+
</Stack>
|
|
293
|
+
</div>
|
|
294
|
+
<div
|
|
295
|
+
role='none'
|
|
296
|
+
className={solo ? 'relative bg-deck overflow-hidden' : 'sr-only'}
|
|
297
|
+
{...(!solo && { inert: '' })}
|
|
298
|
+
>
|
|
299
|
+
{!topbar && <ToggleSidebarButton classNames={fixedSidebarToggleStyles} />}
|
|
300
|
+
{!topbar && <ToggleComplementarySidebarButton classNames={fixedComplementarySidebarToggleStyles} />}
|
|
301
|
+
<StackContext.Provider value={{ size: 'contain', orientation: 'horizontal', rail: true }}>
|
|
302
|
+
<Plank
|
|
303
|
+
id={solo}
|
|
304
|
+
companionId={solo ? activeCompanions?.[solo] : undefined}
|
|
305
|
+
part='solo'
|
|
306
|
+
layoutMode={layoutMode}
|
|
307
|
+
settings={settings}
|
|
308
|
+
/>
|
|
309
|
+
</StackContext.Provider>
|
|
310
|
+
</div>
|
|
311
|
+
</Main.Content>
|
|
312
|
+
)}
|
|
269
313
|
|
|
270
|
-
|
|
271
|
-
|
|
314
|
+
{/* Topbar. */}
|
|
315
|
+
{topbar && <Topbar />}
|
|
272
316
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
317
|
+
{/* Status bar. */}
|
|
318
|
+
{hoistStatusbar && <StatusBar showHints={settings.showHints} />}
|
|
319
|
+
</Main.Root>
|
|
320
|
+
)}
|
|
276
321
|
|
|
277
322
|
{/* Global popovers. */}
|
|
278
|
-
<
|
|
323
|
+
<Popover.Portal>
|
|
324
|
+
<Popover.Content side={context.popoverSide} onEscapeKeyDown={handlePopoverClose}>
|
|
325
|
+
<Popover.Viewport>
|
|
326
|
+
<Surface role='popover' data={popoverContent} limit={1} />
|
|
327
|
+
</Popover.Viewport>
|
|
328
|
+
<Popover.Arrow />
|
|
329
|
+
</Popover.Content>
|
|
330
|
+
</Popover.Portal>
|
|
279
331
|
|
|
280
332
|
{/* Global dialog. */}
|
|
281
|
-
|
|
333
|
+
{/* TODO(thure): End block alignment affecting `modal` and whether the surface renders in an overlay is tailored
|
|
334
|
+
to the needs of the ambient chat dialog. As the feature matures, consider separating concerns. */}
|
|
335
|
+
<Dialog.Root
|
|
336
|
+
modal={dialogBlockAlign !== 'end'}
|
|
337
|
+
open={dialogOpen}
|
|
338
|
+
onOpenChange={(nextOpen) => (context.dialogOpen = nextOpen)}
|
|
339
|
+
>
|
|
340
|
+
{dialogBlockAlign === 'end' ? (
|
|
341
|
+
// TODO(burdon): Placeholder creates a suspense boundary; replace with defaults.
|
|
342
|
+
<Surface role='dialog' data={dialogContent} limit={1} fallback={PlankContentError} placeholder={<div />} />
|
|
343
|
+
) : (
|
|
344
|
+
<Dialog.Overlay blockAlign={dialogBlockAlign}>
|
|
345
|
+
<Surface role='dialog' data={dialogContent} limit={1} fallback={PlankContentError} />
|
|
346
|
+
</Dialog.Overlay>
|
|
347
|
+
)}
|
|
348
|
+
</Dialog.Root>
|
|
282
349
|
|
|
283
350
|
{/* Global toasts. */}
|
|
284
351
|
{toasts?.map((toast) => (
|
|
@@ -294,6 +361,6 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
294
361
|
}}
|
|
295
362
|
/>
|
|
296
363
|
))}
|
|
297
|
-
</
|
|
364
|
+
</Popover.Root>
|
|
298
365
|
);
|
|
299
366
|
};
|