@dxos/plugin-deck 0.6.13-staging.1e988a3 → 0.6.14-main.1366248
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/{chunk-YVHGFQQR.mjs → chunk-GVOGPULO.mjs} +1 -1
- package/dist/lib/browser/chunk-GVOGPULO.mjs.map +7 -0
- package/dist/lib/browser/chunk-NIRHDTX4.mjs +17 -0
- package/dist/lib/browser/chunk-NIRHDTX4.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +334 -314
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +1 -1
- package/dist/lib/browser/types.mjs +11 -0
- package/dist/lib/browser/types.mjs.map +7 -0
- package/dist/types/src/DeckPlugin.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/ActiveNode.d.ts +1 -3
- package/dist/types/src/components/DeckLayout/ActiveNode.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts +4 -4
- package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/DeckLayout.d.ts +5 -5
- package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts +9 -7
- package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Plank.d.ts +2 -2
- package/dist/types/src/components/DeckLayout/Plank.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/PlankError.d.ts +1 -2
- package/dist/types/src/components/DeckLayout/PlankError.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Sidebar.d.ts +2 -3
- package/dist/types/src/components/DeckLayout/Sidebar.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/StatusBar.d.ts +3 -1
- package/dist/types/src/components/DeckLayout/StatusBar.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
- package/dist/types/src/components/LayoutSettings.d.ts.map +1 -1
- package/dist/types/src/hooks/useNode.d.ts.map +1 -1
- package/dist/types/src/layout.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +1 -3
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +14 -2
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util/overscroll.d.ts +1 -1
- package/dist/types/src/util/overscroll.d.ts.map +1 -1
- package/package.json +42 -33
- package/src/DeckPlugin.tsx +104 -80
- package/src/components/DeckLayout/ActiveNode.tsx +4 -1
- package/src/components/DeckLayout/ComplementarySidebar.tsx +59 -28
- package/src/components/DeckLayout/DeckLayout.tsx +67 -98
- package/src/components/DeckLayout/NodePlankHeading.tsx +130 -127
- package/src/components/DeckLayout/Plank.tsx +48 -32
- package/src/components/DeckLayout/PlankError.tsx +1 -9
- package/src/components/DeckLayout/Sidebar.tsx +7 -8
- package/src/components/DeckLayout/StatusBar.tsx +12 -3
- package/src/components/DeckLayout/Toast.tsx +3 -3
- package/src/components/LayoutSettings.tsx +17 -20
- package/src/hooks/useNode.ts +5 -1
- package/src/layout.ts +1 -0
- package/src/meta.ts +3 -1
- package/src/translations.ts +1 -3
- package/src/types.ts +16 -1
- package/src/util/overscroll.ts +5 -5
- package/dist/lib/browser/chunk-YVHGFQQR.mjs.map +0 -7
package/package.json
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-deck",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.14-main.1366248",
|
|
4
4
|
"description": "DXOS Surface plugin for the main application layout.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": "DXOS.org",
|
|
9
|
+
"sideEffects": true,
|
|
9
10
|
"exports": {
|
|
10
11
|
".": {
|
|
11
|
-
"
|
|
12
|
-
"
|
|
12
|
+
"types": "./dist/types/src/index.d.ts",
|
|
13
|
+
"browser": "./dist/lib/browser/index.mjs"
|
|
13
14
|
},
|
|
14
15
|
"./meta": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
16
|
+
"types": "./dist/types/src/meta.d.ts",
|
|
17
|
+
"browser": "./dist/lib/browser/meta.mjs"
|
|
18
|
+
},
|
|
19
|
+
"./types": {
|
|
20
|
+
"types": "./dist/types/src/types.d.ts",
|
|
21
|
+
"browser": "./dist/lib/browser/types.mjs"
|
|
17
22
|
}
|
|
18
23
|
},
|
|
19
24
|
"types": "dist/types/src/index.d.ts",
|
|
@@ -21,6 +26,9 @@
|
|
|
21
26
|
"*": {
|
|
22
27
|
"meta": [
|
|
23
28
|
"dist/types/src/meta.d.ts"
|
|
29
|
+
],
|
|
30
|
+
"types": [
|
|
31
|
+
"dist/types/src/types.d.ts"
|
|
24
32
|
]
|
|
25
33
|
}
|
|
26
34
|
},
|
|
@@ -32,26 +40,27 @@
|
|
|
32
40
|
"@fluentui/react-tabster": "^9.19.0",
|
|
33
41
|
"@preact/signals-core": "^1.6.0",
|
|
34
42
|
"immer": "^10.1.1",
|
|
35
|
-
"@dxos/app-framework": "0.6.
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/
|
|
39
|
-
"@dxos/
|
|
40
|
-
"@dxos/
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/plugin-
|
|
46
|
-
"@dxos/plugin-graph": "0.6.
|
|
47
|
-
"@dxos/plugin-
|
|
48
|
-
"@dxos/plugin-theme": "0.6.
|
|
49
|
-
"@dxos/react-client": "0.6.
|
|
50
|
-
"@dxos/react-ui-attention": "0.6.
|
|
51
|
-
"@dxos/react-ui-deck": "0.6.
|
|
52
|
-
"@dxos/react-ui-
|
|
53
|
-
"@dxos/react-ui-text-tooltip": "0.6.
|
|
54
|
-
"@dxos/util": "0.6.
|
|
43
|
+
"@dxos/app-framework": "0.6.14-main.1366248",
|
|
44
|
+
"@dxos/debug": "0.6.14-main.1366248",
|
|
45
|
+
"@dxos/echo-schema": "0.6.14-main.1366248",
|
|
46
|
+
"@dxos/async": "0.6.14-main.1366248",
|
|
47
|
+
"@dxos/echo-signals": "0.6.14-main.1366248",
|
|
48
|
+
"@dxos/invariant": "0.6.14-main.1366248",
|
|
49
|
+
"@dxos/keyboard": "0.6.14-main.1366248",
|
|
50
|
+
"@dxos/local-storage": "0.6.14-main.1366248",
|
|
51
|
+
"@dxos/plugin-attention": "0.6.14-main.1366248",
|
|
52
|
+
"@dxos/log": "0.6.14-main.1366248",
|
|
53
|
+
"@dxos/plugin-client": "0.6.14-main.1366248",
|
|
54
|
+
"@dxos/plugin-graph": "0.6.14-main.1366248",
|
|
55
|
+
"@dxos/plugin-observability": "0.6.14-main.1366248",
|
|
56
|
+
"@dxos/plugin-theme": "0.6.14-main.1366248",
|
|
57
|
+
"@dxos/react-client": "0.6.14-main.1366248",
|
|
58
|
+
"@dxos/react-ui-attention": "0.6.14-main.1366248",
|
|
59
|
+
"@dxos/react-ui-deck": "0.6.14-main.1366248",
|
|
60
|
+
"@dxos/react-ui-data": "0.6.14-main.1366248",
|
|
61
|
+
"@dxos/react-ui-text-tooltip": "0.6.14-main.1366248",
|
|
62
|
+
"@dxos/util": "0.6.14-main.1366248",
|
|
63
|
+
"@dxos/react-ui-mosaic": "0.6.14-main.1366248"
|
|
55
64
|
},
|
|
56
65
|
"devDependencies": {
|
|
57
66
|
"@phosphor-icons/react": "^2.1.5",
|
|
@@ -59,17 +68,17 @@
|
|
|
59
68
|
"@types/react-dom": "~18.2.0",
|
|
60
69
|
"react": "~18.2.0",
|
|
61
70
|
"react-dom": "~18.2.0",
|
|
62
|
-
"vite": "
|
|
63
|
-
"@dxos/react-ui": "0.6.
|
|
64
|
-
"@dxos/react-ui-theme": "0.6.
|
|
65
|
-
"@dxos/storybook-utils": "0.6.
|
|
71
|
+
"vite": "5.4.7",
|
|
72
|
+
"@dxos/react-ui": "0.6.14-main.1366248",
|
|
73
|
+
"@dxos/react-ui-theme": "0.6.14-main.1366248",
|
|
74
|
+
"@dxos/storybook-utils": "0.6.14-main.1366248"
|
|
66
75
|
},
|
|
67
76
|
"peerDependencies": {
|
|
68
77
|
"@phosphor-icons/react": "^2.0.5",
|
|
69
|
-
"react": "
|
|
70
|
-
"react-dom": "
|
|
71
|
-
"@dxos/react-ui
|
|
72
|
-
"@dxos/react-ui": "0.6.
|
|
78
|
+
"react": "~18.2.0",
|
|
79
|
+
"react-dom": "~18.2.0",
|
|
80
|
+
"@dxos/react-ui": "0.6.14-main.1366248",
|
|
81
|
+
"@dxos/react-ui-theme": "0.6.14-main.1366248"
|
|
73
82
|
},
|
|
74
83
|
"publishConfig": {
|
|
75
84
|
"access": "public"
|
package/src/DeckPlugin.tsx
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import { batch, effect } from '@preact/signals-core';
|
|
5
|
+
import { batch } from '@preact/signals-core';
|
|
7
6
|
import { setAutoFreeze } from 'immer';
|
|
8
7
|
import React, { type PropsWithChildren } from 'react';
|
|
9
8
|
|
|
@@ -30,9 +29,11 @@ import {
|
|
|
30
29
|
openIds,
|
|
31
30
|
type LayoutMode,
|
|
32
31
|
type IntentData,
|
|
32
|
+
filterPlugins,
|
|
33
33
|
} from '@dxos/app-framework';
|
|
34
34
|
import { type UnsubscribeCallback } from '@dxos/async';
|
|
35
35
|
import { create, getTypename, isReactiveObject } from '@dxos/echo-schema';
|
|
36
|
+
import { scheduledEffect } from '@dxos/echo-signals/core';
|
|
36
37
|
import { LocalStorageStore } from '@dxos/local-storage';
|
|
37
38
|
import { log } from '@dxos/log';
|
|
38
39
|
import { parseAttentionPlugin, type AttentionPluginProvides } from '@dxos/plugin-attention';
|
|
@@ -41,7 +42,6 @@ import { createExtension, type Node } from '@dxos/plugin-graph';
|
|
|
41
42
|
import { ObservabilityAction } from '@dxos/plugin-observability/meta';
|
|
42
43
|
import { fullyQualifiedId } from '@dxos/react-client/echo';
|
|
43
44
|
import { translations as deckTranslations } from '@dxos/react-ui-deck';
|
|
44
|
-
import { Mosaic } from '@dxos/react-ui-mosaic';
|
|
45
45
|
|
|
46
46
|
import {
|
|
47
47
|
DeckLayout,
|
|
@@ -63,7 +63,14 @@ import {
|
|
|
63
63
|
} from './layout';
|
|
64
64
|
import meta, { DECK_PLUGIN } from './meta';
|
|
65
65
|
import translations from './translations';
|
|
66
|
-
import {
|
|
66
|
+
import {
|
|
67
|
+
type NewPlankPositioning,
|
|
68
|
+
type DeckPluginProvides,
|
|
69
|
+
type DeckSettingsProps,
|
|
70
|
+
type Overscroll,
|
|
71
|
+
type Panel,
|
|
72
|
+
parsePanelPlugin,
|
|
73
|
+
} from './types';
|
|
67
74
|
import { checkAppScheme, getEffectivePart } from './util';
|
|
68
75
|
|
|
69
76
|
const isSocket = !!(globalThis as any).__args;
|
|
@@ -71,7 +78,7 @@ const isSocket = !!(globalThis as any).__args;
|
|
|
71
78
|
// TODO(mjamesderocher): Can we get this directly from Socket?
|
|
72
79
|
const appScheme = 'composer://';
|
|
73
80
|
|
|
74
|
-
// TODO(burdon): Evolve into customizable prefs
|
|
81
|
+
// TODO(burdon): Evolve into customizable prefs.
|
|
75
82
|
const customSlots: DeckLayoutProps['slots'] = {
|
|
76
83
|
wallpaper: {
|
|
77
84
|
classNames:
|
|
@@ -110,9 +117,10 @@ export const DeckPlugin = ({
|
|
|
110
117
|
const unsubscriptionCallbacks = [] as (UnsubscribeCallback | undefined)[];
|
|
111
118
|
let currentUndoId: string | undefined;
|
|
112
119
|
let handleNavigation: () => Promise<void> | undefined;
|
|
120
|
+
const panels: Panel[] = [];
|
|
113
121
|
|
|
114
122
|
const settings = new LocalStorageStore<DeckSettingsProps>('dxos.org/settings/layout', {
|
|
115
|
-
|
|
123
|
+
showHints: false,
|
|
116
124
|
customSlots: false,
|
|
117
125
|
flatDeck: false,
|
|
118
126
|
enableNativeRedirect: false,
|
|
@@ -190,6 +198,28 @@ export const DeckPlugin = ({
|
|
|
190
198
|
}
|
|
191
199
|
};
|
|
192
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Update the active state and ensure that attention is on an active element.
|
|
203
|
+
*/
|
|
204
|
+
const handleSetLocation = (next: LayoutParts) => {
|
|
205
|
+
if (attentionPlugin) {
|
|
206
|
+
const attended = attentionPlugin.provides.attention.attended;
|
|
207
|
+
const [attendedId] = Array.from(attended);
|
|
208
|
+
const ids = (layout.values.layoutMode === 'deck' ? next.main : next.solo)?.map(({ id }) => id) ?? [];
|
|
209
|
+
const isAttendedAvailable = !!attendedId && ids.includes(attendedId);
|
|
210
|
+
if (!isAttendedAvailable) {
|
|
211
|
+
// Allow new plank to render before focusing.
|
|
212
|
+
requestAnimationFrame(() => {
|
|
213
|
+
const nextAttended = layout.values.layoutMode === 'solo' ? next.solo?.[0].id : next.main?.[0]?.id;
|
|
214
|
+
const article = document.querySelector<HTMLElement>(`article[data-attendable-id="${nextAttended}"]`);
|
|
215
|
+
article?.focus();
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
location.values.active = next;
|
|
221
|
+
};
|
|
222
|
+
|
|
193
223
|
return {
|
|
194
224
|
meta,
|
|
195
225
|
ready: async (plugins) => {
|
|
@@ -198,19 +228,20 @@ export const DeckPlugin = ({
|
|
|
198
228
|
attentionPlugin = resolvePlugin(plugins, parseAttentionPlugin);
|
|
199
229
|
clientPlugin = resolvePlugin(plugins, parseClientPlugin);
|
|
200
230
|
|
|
201
|
-
// prettier-ignore
|
|
202
231
|
layout
|
|
203
|
-
.prop({ key: 'layoutMode',
|
|
204
|
-
.prop({ key: 'sidebarOpen',
|
|
205
|
-
.prop({ key: 'complementarySidebarOpen',
|
|
232
|
+
.prop({ key: 'layoutMode', type: LocalStorageStore.enum<LayoutMode>() })
|
|
233
|
+
.prop({ key: 'sidebarOpen', type: LocalStorageStore.bool() })
|
|
234
|
+
.prop({ key: 'complementarySidebarOpen', type: LocalStorageStore.bool() });
|
|
206
235
|
|
|
207
|
-
|
|
208
|
-
deck.prop({ key: 'plankSizing', storageKey: 'plank-sizing', type: LocalStorageStore.json<Record<string, number>>() });
|
|
236
|
+
deck.prop({ key: 'plankSizing', type: LocalStorageStore.json<Record<string, number>>() });
|
|
209
237
|
|
|
210
|
-
// prettier-ignore
|
|
211
238
|
location
|
|
212
|
-
.prop({ key: 'active',
|
|
213
|
-
.prop({ key: 'closed',
|
|
239
|
+
.prop({ key: 'active', type: LocalStorageStore.json<LayoutParts>() })
|
|
240
|
+
.prop({ key: 'closed', type: LocalStorageStore.json<string[]>() });
|
|
241
|
+
|
|
242
|
+
panels.push(
|
|
243
|
+
...filterPlugins(plugins, parsePanelPlugin).flatMap((plugin) => plugin.provides.complementary.panels),
|
|
244
|
+
);
|
|
214
245
|
|
|
215
246
|
unsubscriptionCallbacks.push(
|
|
216
247
|
clientPlugin?.provides.client.shell.onReset(() => {
|
|
@@ -220,15 +251,14 @@ export const DeckPlugin = ({
|
|
|
220
251
|
}),
|
|
221
252
|
);
|
|
222
253
|
|
|
223
|
-
// prettier-ignore
|
|
224
254
|
settings
|
|
225
|
-
.prop({ key: '
|
|
226
|
-
.prop({ key: 'customSlots',
|
|
227
|
-
.prop({ key: 'flatDeck',
|
|
228
|
-
.prop({ key: 'enableNativeRedirect',
|
|
229
|
-
.prop({ key: 'disableDeck',
|
|
230
|
-
.prop({ key: 'newPlankPositioning',
|
|
231
|
-
.prop({ key: 'overscroll',
|
|
255
|
+
.prop({ key: 'showHints', type: LocalStorageStore.bool() })
|
|
256
|
+
.prop({ key: 'customSlots', type: LocalStorageStore.bool() })
|
|
257
|
+
.prop({ key: 'flatDeck', type: LocalStorageStore.bool() })
|
|
258
|
+
.prop({ key: 'enableNativeRedirect', type: LocalStorageStore.bool() })
|
|
259
|
+
.prop({ key: 'disableDeck', type: LocalStorageStore.bool() }) // Deprecated.
|
|
260
|
+
.prop({ key: 'newPlankPositioning', type: LocalStorageStore.enum<NewPlankPositioning>() })
|
|
261
|
+
.prop({ key: 'overscroll', type: LocalStorageStore.enum<Overscroll>() });
|
|
232
262
|
|
|
233
263
|
if (!isSocket && settings.values.enableNativeRedirect) {
|
|
234
264
|
checkAppScheme(appScheme);
|
|
@@ -237,7 +267,7 @@ export const DeckPlugin = ({
|
|
|
237
267
|
handleNavigation = async () => {
|
|
238
268
|
const pathname = window.location.pathname;
|
|
239
269
|
if (pathname === '/reset') {
|
|
240
|
-
|
|
270
|
+
handleSetLocation({ sidebar: [{ id: NAV_ID }] });
|
|
241
271
|
location.values.closed = [];
|
|
242
272
|
layout.values.layoutMode = 'solo';
|
|
243
273
|
window.location.pathname = '/';
|
|
@@ -250,7 +280,7 @@ export const DeckPlugin = ({
|
|
|
250
280
|
}
|
|
251
281
|
|
|
252
282
|
const startingLayout = removePart(location.values.active, 'solo');
|
|
253
|
-
|
|
283
|
+
handleSetLocation(mergeLayoutParts(layoutFromUri, startingLayout));
|
|
254
284
|
layout.values.layoutMode = 'solo';
|
|
255
285
|
};
|
|
256
286
|
|
|
@@ -258,23 +288,13 @@ export const DeckPlugin = ({
|
|
|
258
288
|
window.addEventListener('popstate', handleNavigation);
|
|
259
289
|
|
|
260
290
|
unsubscriptionCallbacks.push(
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
unsubscriptionCallbacks.push(
|
|
269
|
-
effect(() => {
|
|
270
|
-
const soloId = location.values.active.solo?.[0].id;
|
|
271
|
-
if (layout.values.layoutMode === 'solo' && soloId && layout.values.scrollIntoView !== soloId) {
|
|
272
|
-
void intentPlugin?.provides.intent.dispatch({
|
|
273
|
-
action: LayoutAction.SCROLL_INTO_VIEW,
|
|
274
|
-
data: { id: soloId },
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
}),
|
|
291
|
+
scheduledEffect(
|
|
292
|
+
() => ({ selectedPath: soloPartToUri(location.values.active) }),
|
|
293
|
+
({ selectedPath }) => {
|
|
294
|
+
// TODO(thure): In some browsers, this only preserves the most recent state change, even though this is not `history.replace`…
|
|
295
|
+
history.pushState(null, '', `/${selectedPath}${window.location.search}`);
|
|
296
|
+
},
|
|
297
|
+
),
|
|
278
298
|
);
|
|
279
299
|
|
|
280
300
|
layoutModeHistory.values.push(`${layout.values.layoutMode}`);
|
|
@@ -310,8 +330,7 @@ export const DeckPlugin = ({
|
|
|
310
330
|
},
|
|
311
331
|
properties: {
|
|
312
332
|
label: ['toggle fullscreen label', { ns: DECK_PLUGIN }],
|
|
313
|
-
icon:
|
|
314
|
-
iconSymbol: 'ph--arrows-out--regular',
|
|
333
|
+
icon: 'ph--arrows-out--regular',
|
|
315
334
|
keyBinding: {
|
|
316
335
|
macos: 'ctrl+meta+f',
|
|
317
336
|
windows: 'shift+ctrl+f',
|
|
@@ -329,31 +348,28 @@ export const DeckPlugin = ({
|
|
|
329
348
|
),
|
|
330
349
|
root: () => {
|
|
331
350
|
return (
|
|
332
|
-
<
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
/>
|
|
355
|
-
<Mosaic.DragOverlay />
|
|
356
|
-
</Mosaic.Root>
|
|
351
|
+
<DeckLayout
|
|
352
|
+
layoutParts={location.values.active}
|
|
353
|
+
showHints={settings.values.showHints}
|
|
354
|
+
overscroll={settings.values.overscroll}
|
|
355
|
+
flatDeck={settings.values.flatDeck}
|
|
356
|
+
slots={settings.values.customSlots ? customSlots : undefined}
|
|
357
|
+
toasts={layout.values.toasts}
|
|
358
|
+
panels={panels}
|
|
359
|
+
onDismissToast={(id) => {
|
|
360
|
+
const index = layout.values.toasts.findIndex((toast) => toast.id === id);
|
|
361
|
+
if (index !== -1) {
|
|
362
|
+
// Allow time for the toast to animate out.
|
|
363
|
+
// TODO(burdon): Factor out and unregister timeout.
|
|
364
|
+
setTimeout(() => {
|
|
365
|
+
if (layout.values.toasts[index].id === currentUndoId) {
|
|
366
|
+
currentUndoId = undefined;
|
|
367
|
+
}
|
|
368
|
+
layout.values.toasts.splice(index, 1);
|
|
369
|
+
}, 1_000);
|
|
370
|
+
}
|
|
371
|
+
}}
|
|
372
|
+
/>
|
|
357
373
|
);
|
|
358
374
|
},
|
|
359
375
|
surface: {
|
|
@@ -472,7 +488,7 @@ export const DeckPlugin = ({
|
|
|
472
488
|
}
|
|
473
489
|
});
|
|
474
490
|
|
|
475
|
-
|
|
491
|
+
handleSetLocation(newLayout);
|
|
476
492
|
});
|
|
477
493
|
|
|
478
494
|
const ids = openIds(location.values.active);
|
|
@@ -522,10 +538,12 @@ export const DeckPlugin = ({
|
|
|
522
538
|
const layoutEntry = { id: data.id };
|
|
523
539
|
const effectivePart = getEffectivePart(data.part, layout.values.layoutMode);
|
|
524
540
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
541
|
+
handleSetLocation(
|
|
542
|
+
openEntry(location.values.active, effectivePart, layoutEntry, {
|
|
543
|
+
positioning: data.positioning ?? settings.values.newPlankPositioning,
|
|
544
|
+
pivotId: data.pivotId,
|
|
545
|
+
}),
|
|
546
|
+
);
|
|
529
547
|
|
|
530
548
|
const intents = [];
|
|
531
549
|
if (data.scrollIntoView && layout.values.layoutMode === 'deck') {
|
|
@@ -561,7 +579,11 @@ export const DeckPlugin = ({
|
|
|
561
579
|
}
|
|
562
580
|
});
|
|
563
581
|
|
|
564
|
-
|
|
582
|
+
handleSetLocation(newLayout);
|
|
583
|
+
// TODO(wittjosiah): This needs to also set the closed state.
|
|
584
|
+
// The closed state should be the existing closed state plus the newly closed ids.
|
|
585
|
+
// The closed state should also be updated when opening entries to remove the id from closed.
|
|
586
|
+
// When SET is called the closed ids should also be calculated and set.
|
|
565
587
|
return { data: true };
|
|
566
588
|
});
|
|
567
589
|
}
|
|
@@ -570,7 +592,7 @@ export const DeckPlugin = ({
|
|
|
570
592
|
case NavigationAction.SET: {
|
|
571
593
|
return batch(() => {
|
|
572
594
|
if (isLayoutParts(intent.data?.activeParts)) {
|
|
573
|
-
|
|
595
|
+
handleSetLocation(intent.data!.activeParts);
|
|
574
596
|
}
|
|
575
597
|
return { data: true };
|
|
576
598
|
});
|
|
@@ -581,10 +603,12 @@ export const DeckPlugin = ({
|
|
|
581
603
|
if (isLayoutAdjustment(intent.data)) {
|
|
582
604
|
const adjustment = intent.data;
|
|
583
605
|
if (adjustment.type === 'increment-end' || adjustment.type === 'increment-start') {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
606
|
+
handleSetLocation(
|
|
607
|
+
incrementPlank(location.values.active, {
|
|
608
|
+
type: adjustment.type,
|
|
609
|
+
layoutCoordinate: adjustment.layoutCoordinate,
|
|
610
|
+
}),
|
|
611
|
+
);
|
|
588
612
|
}
|
|
589
613
|
|
|
590
614
|
if (adjustment.type === 'solo') {
|
|
@@ -6,10 +6,13 @@ import React from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework';
|
|
8
8
|
import { useGraph } from '@dxos/plugin-graph';
|
|
9
|
+
import { useAttended } from '@dxos/react-ui-attention';
|
|
9
10
|
|
|
10
11
|
import { useNode, useNodeActionExpander } from '../../hooks';
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
// TODO(burdon): Factor out to effect in plugin set document title.
|
|
14
|
+
export const ActiveNode = () => {
|
|
15
|
+
const [id] = useAttended();
|
|
13
16
|
const { graph } = useGraph();
|
|
14
17
|
const activeNode = useNode(graph, id);
|
|
15
18
|
useNodeActionExpander(activeNode);
|
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React from 'react';
|
|
5
|
+
import React, { useMemo } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
type LayoutCoordinate,
|
|
9
|
+
NavigationAction,
|
|
10
|
+
SLUG_PATH_SEPARATOR,
|
|
11
|
+
Surface,
|
|
12
|
+
useIntentDispatcher,
|
|
13
|
+
} from '@dxos/app-framework';
|
|
8
14
|
import { useGraph } from '@dxos/plugin-graph';
|
|
9
15
|
import { Main } from '@dxos/react-ui';
|
|
10
|
-
import {
|
|
16
|
+
import { useAttended } from '@dxos/react-ui-attention';
|
|
11
17
|
import { deckGrid } from '@dxos/react-ui-deck';
|
|
12
18
|
import { mx } from '@dxos/react-ui-theme';
|
|
13
19
|
|
|
@@ -15,44 +21,69 @@ import { NodePlankHeading } from './NodePlankHeading';
|
|
|
15
21
|
import { PlankContentError } from './PlankError';
|
|
16
22
|
import { PlankLoading } from './PlankLoading';
|
|
17
23
|
import { useNode, useNodeActionExpander } from '../../hooks';
|
|
24
|
+
import { type Panel } from '../../types';
|
|
18
25
|
import { useLayout } from '../LayoutContext';
|
|
19
26
|
|
|
20
27
|
export type ComplementarySidebarProps = {
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
panels: Panel[];
|
|
29
|
+
current?: string;
|
|
23
30
|
flatDeck?: boolean;
|
|
24
31
|
};
|
|
25
32
|
|
|
26
|
-
export const ComplementarySidebar = ({
|
|
33
|
+
export const ComplementarySidebar = ({ panels, current, flatDeck }: ComplementarySidebarProps) => {
|
|
27
34
|
const { popoverAnchorId } = useLayout();
|
|
35
|
+
const attended = useAttended();
|
|
36
|
+
const panel = (panels.find((p) => p.id === current) ?? panels[0])?.id;
|
|
37
|
+
const id = attended[0] ? `${attended[0]}${SLUG_PATH_SEPARATOR}${panel}` : undefined;
|
|
28
38
|
const { graph } = useGraph();
|
|
29
39
|
const node = useNode(graph, id);
|
|
30
|
-
|
|
31
|
-
const complementaryAttrs = createAttendableAttributes(id?.split(SLUG_PATH_SEPARATOR)[0] ?? 'never');
|
|
32
|
-
|
|
40
|
+
const dispatch = useIntentDispatcher();
|
|
33
41
|
useNodeActionExpander(node);
|
|
34
42
|
|
|
43
|
+
const actions = useMemo(
|
|
44
|
+
() =>
|
|
45
|
+
panels.map(({ id, label, icon }) => ({
|
|
46
|
+
id: `complementary-${id}`,
|
|
47
|
+
data: () => {
|
|
48
|
+
void dispatch({ action: NavigationAction.OPEN, data: { activeParts: { complementary: id } } });
|
|
49
|
+
},
|
|
50
|
+
properties: {
|
|
51
|
+
label,
|
|
52
|
+
icon,
|
|
53
|
+
menuItemType: 'toggle',
|
|
54
|
+
isChecked: panel === id,
|
|
55
|
+
},
|
|
56
|
+
})),
|
|
57
|
+
[panel],
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// TODO(wittjosiah): Ensure that id is always defined.
|
|
61
|
+
const coordinate: LayoutCoordinate = useMemo(() => ({ entryId: id ?? 'unknown', part: 'complementary' }), [id]);
|
|
62
|
+
|
|
63
|
+
// TODO(burdon): Debug panel doesn't change when switching even though id has chagned.
|
|
35
64
|
return (
|
|
36
|
-
<Main.ComplementarySidebar
|
|
37
|
-
{
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
65
|
+
<Main.ComplementarySidebar>
|
|
66
|
+
<div role='none' className={mx(deckGrid, 'grid-cols-1 bs-full')}>
|
|
67
|
+
<NodePlankHeading
|
|
68
|
+
coordinate={coordinate}
|
|
69
|
+
node={node}
|
|
70
|
+
popoverAnchorId={popoverAnchorId}
|
|
71
|
+
flatDeck={flatDeck}
|
|
72
|
+
actions={actions}
|
|
73
|
+
/>
|
|
74
|
+
<div className='row-span-2 divide-y divide-separator overflow-x-hidden overflow-y-scroll'>
|
|
75
|
+
{node && (
|
|
76
|
+
<Surface
|
|
77
|
+
key={id}
|
|
78
|
+
role={`complementary--${panel}`}
|
|
79
|
+
limit={1}
|
|
80
|
+
data={{ id, subject: node.properties.object ?? node.properties.space, popoverAnchorId }}
|
|
81
|
+
fallback={PlankContentError}
|
|
82
|
+
placeholder={<PlankLoading />}
|
|
83
|
+
/>
|
|
84
|
+
)}
|
|
54
85
|
</div>
|
|
55
|
-
|
|
86
|
+
</div>
|
|
56
87
|
</Main.ComplementarySidebar>
|
|
57
88
|
);
|
|
58
89
|
};
|