@dxos/plugin-deck 0.6.12-staging.e11e696 → 0.6.13-main.09887cd

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.
Files changed (36) hide show
  1. package/dist/lib/browser/{chunk-YVHGFQQR.mjs → chunk-GVOGPULO.mjs} +1 -1
  2. package/dist/lib/browser/chunk-GVOGPULO.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +149 -95
  4. package/dist/lib/browser/index.mjs.map +3 -3
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/meta.mjs +1 -1
  7. package/dist/types/src/DeckPlugin.d.ts.map +1 -1
  8. package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts +1 -1
  9. package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts.map +1 -1
  10. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts +2 -2
  11. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
  12. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts +3 -1
  13. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts.map +1 -1
  14. package/dist/types/src/components/DeckLayout/StatusBar.d.ts +3 -1
  15. package/dist/types/src/components/DeckLayout/StatusBar.d.ts.map +1 -1
  16. package/dist/types/src/components/LayoutSettings.d.ts.map +1 -1
  17. package/dist/types/src/meta.d.ts.map +1 -1
  18. package/dist/types/src/translations.d.ts +3 -1
  19. package/dist/types/src/translations.d.ts.map +1 -1
  20. package/dist/types/src/types.d.ts +1 -1
  21. package/dist/types/src/types.d.ts.map +1 -1
  22. package/dist/types/src/util/overscroll.d.ts +1 -1
  23. package/dist/types/src/util/overscroll.d.ts.map +1 -1
  24. package/package.json +27 -26
  25. package/src/DeckPlugin.tsx +18 -24
  26. package/src/components/DeckLayout/ComplementarySidebar.tsx +51 -8
  27. package/src/components/DeckLayout/DeckLayout.tsx +25 -35
  28. package/src/components/DeckLayout/NodePlankHeading.tsx +4 -2
  29. package/src/components/DeckLayout/Plank.tsx +1 -1
  30. package/src/components/DeckLayout/StatusBar.tsx +12 -3
  31. package/src/components/LayoutSettings.tsx +5 -8
  32. package/src/meta.ts +3 -1
  33. package/src/translations.ts +3 -1
  34. package/src/types.ts +1 -1
  35. package/src/util/overscroll.ts +5 -5
  36. package/dist/lib/browser/chunk-YVHGFQQR.mjs.map +0 -7
@@ -2,9 +2,15 @@
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 { type LayoutParts, SLUG_PATH_SEPARATOR, Surface } from '@dxos/app-framework';
7
+ import {
8
+ type LayoutParts,
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
16
  import { useAttended } from '@dxos/react-ui-attention';
@@ -15,6 +21,7 @@ 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 { DECK_PLUGIN } from '../../meta';
18
25
  import { useLayout } from '../LayoutContext';
19
26
 
20
27
  export type ComplementarySidebarProps = {
@@ -23,15 +30,50 @@ export type ComplementarySidebarProps = {
23
30
  flatDeck?: boolean;
24
31
  };
25
32
 
26
- export const ComplementarySidebar = ({ context, layoutParts, flatDeck }: ComplementarySidebarProps) => {
33
+ const panels = ['comments', 'settings', 'debug'] as const;
34
+
35
+ const nodes = [
36
+ { id: 'comments', icon: 'ph--chat-text--regular' },
37
+ { id: 'settings', icon: 'ph--gear--regular' },
38
+ { id: 'debug', icon: 'ph--bug--regular' },
39
+ ];
40
+
41
+ type Panel = (typeof panels)[number];
42
+ const getPanel = (part?: string): Panel => {
43
+ if (part && panels.findIndex((panel) => panel === part) !== -1) {
44
+ return part as Panel;
45
+ } else {
46
+ return 'settings';
47
+ }
48
+ };
49
+
50
+ export const ComplementarySidebar = ({ layoutParts, flatDeck }: ComplementarySidebarProps) => {
27
51
  const { popoverAnchorId } = useLayout();
28
52
  const attended = useAttended();
29
- const id = attended[0] ? `${attended[0]}${SLUG_PATH_SEPARATOR}${context}` : undefined;
53
+ const part = getPanel(layoutParts.complementary?.[0].id);
54
+ const id = attended[0] ? `${attended[0]}${SLUG_PATH_SEPARATOR}${part}` : undefined;
30
55
  const { graph } = useGraph();
31
56
  const node = useNode(graph, id);
32
-
57
+ const dispatch = useIntentDispatcher();
33
58
  useNodeActionExpander(node);
34
59
 
60
+ const actions = useMemo(
61
+ () =>
62
+ nodes.map(({ id, icon }) => ({
63
+ id: `complementary-${id}`,
64
+ data: () => {
65
+ void dispatch({ action: NavigationAction.OPEN, data: { activeParts: { complementary: id } } });
66
+ },
67
+ properties: {
68
+ label: [`${id} label`, { ns: DECK_PLUGIN }],
69
+ icon,
70
+ menuItemType: 'toggle',
71
+ isChecked: part === id,
72
+ },
73
+ })),
74
+ [part],
75
+ );
76
+
35
77
  return (
36
78
  <Main.ComplementarySidebar>
37
79
  <div role='none' className={mx(deckGrid, 'grid-cols-1 bs-full')}>
@@ -42,12 +84,13 @@ export const ComplementarySidebar = ({ context, layoutParts, flatDeck }: Complem
42
84
  layoutPart='complementary'
43
85
  popoverAnchorId={popoverAnchorId}
44
86
  flatDeck={flatDeck}
87
+ actions={actions}
45
88
  />
46
- {/* TODO(wittjosiah): Render some placeholder when node is undefined. */}
89
+ {/* TODO(wittjosiah): Render placeholder when node is undefined. */}
47
90
  {node && (
48
91
  <Surface
49
- role='article'
50
- data={{ subject: node.properties.object, part: 'complementary', popoverAnchorId }}
92
+ role={`complementary--${part}`}
93
+ data={{ subject: node.properties.object, popoverAnchorId }}
51
94
  limit={1}
52
95
  fallback={PlankContentError}
53
96
  placeholder={<PlankLoading />}
@@ -5,18 +5,11 @@
5
5
  import { Sidebar as MenuIcon } from '@phosphor-icons/react';
6
6
  import React, { useCallback, useEffect, useMemo, useRef, type UIEvent } from 'react';
7
7
 
8
- import {
9
- type LayoutEntry,
10
- type LayoutParts,
11
- Surface,
12
- type Toast as ToastSchema,
13
- firstIdInPart,
14
- usePlugin,
15
- } from '@dxos/app-framework';
8
+ import { type LayoutParts, Surface, type Toast as ToastSchema, firstIdInPart, usePlugin } from '@dxos/app-framework';
16
9
  import { Button, Dialog, Main, Popover, useOnTransition, useTranslation } from '@dxos/react-ui';
17
10
  import { useAttended } from '@dxos/react-ui-attention';
18
11
  import { Deck } from '@dxos/react-ui-deck';
19
- import { getSize } from '@dxos/react-ui-theme';
12
+ import { getSize, mainPaddingTransitions } from '@dxos/react-ui-theme';
20
13
 
21
14
  import { ActiveNode } from './ActiveNode';
22
15
  import { ComplementarySidebar } from './ComplementarySidebar';
@@ -37,7 +30,7 @@ export type DeckLayoutProps = {
37
30
  toasts: ToastSchema[];
38
31
  flatDeck?: boolean;
39
32
  overscroll: Overscroll;
40
- showHintsFooter: boolean;
33
+ showHints: boolean;
41
34
  slots?: {
42
35
  wallpaper?: { classNames?: string };
43
36
  };
@@ -49,7 +42,7 @@ export const DeckLayout = ({
49
42
  toasts,
50
43
  flatDeck,
51
44
  overscroll,
52
- showHintsFooter,
45
+ showHints,
53
46
  slots,
54
47
  onDismissToast,
55
48
  }: DeckLayoutProps) => {
@@ -128,16 +121,7 @@ export const DeckLayout = ({
128
121
  }
129
122
  }, [layoutMode, firstAttendedId]);
130
123
 
131
- // TODO(burdon): Needs cleaning up.
132
- const parts: LayoutEntry[] = useMemo(() => {
133
- const parts = [...(layoutParts.main ?? [])];
134
- for (const part of layoutParts.solo ?? []) {
135
- if (!parts.find((entry) => entry.id === part.id)) {
136
- parts.push(part);
137
- }
138
- }
139
- return parts;
140
- }, [layoutParts.main, layoutParts.solo]);
124
+ const isEmpty = layoutParts.main?.length === 0 && layoutParts.solo?.length === 0;
141
125
 
142
126
  const padding = useMemo(() => {
143
127
  if (layoutMode === 'deck' && overscroll === 'centering') {
@@ -201,29 +185,42 @@ export const DeckLayout = ({
201
185
  <Main.Overlay />
202
186
 
203
187
  {/* No content. */}
204
- {parts.length === 0 && (
188
+ {isEmpty && (
205
189
  <Main.Content handlesFocus>
206
190
  <ContentEmpty />
207
191
  </Main.Content>
208
192
  )}
209
193
 
210
194
  {/* Solo/deck mode. */}
211
- {parts.length !== 0 && (
195
+ {!isEmpty && (
212
196
  <Main.Content bounce classNames='grid block-end-[--statusbar-size]' handlesFocus>
213
197
  <div role='none' className='relative'>
214
198
  <Deck.Root
215
199
  style={padding}
216
- classNames={[!flatDeck && 'bg-deck', 'absolute inset-0', slots?.wallpaper?.classNames]}
200
+ classNames={[
201
+ !flatDeck && 'bg-deck',
202
+ mainPaddingTransitions,
203
+ 'absolute inset-0',
204
+ slots?.wallpaper?.classNames,
205
+ ]}
217
206
  solo={layoutMode === 'solo'}
218
207
  onScroll={handleScroll}
219
208
  ref={deckRef}
220
209
  >
221
- {parts.map((layoutEntry) => (
210
+ <Plank
211
+ entry={layoutParts.solo?.[0] ?? { id: 'unknown-solo' }}
212
+ layoutParts={layoutParts}
213
+ part='solo'
214
+ layoutMode={layoutMode}
215
+ flatDeck={flatDeck}
216
+ searchEnabled={!!searchPlugin}
217
+ />
218
+ {layoutParts.main?.map((layoutEntry) => (
222
219
  <Plank
223
220
  key={layoutEntry.id}
224
221
  entry={layoutEntry}
225
222
  layoutParts={layoutParts}
226
- part={layoutMode === 'solo' && layoutEntry.id === layoutParts.solo?.[0]?.id ? 'solo' : 'main'}
223
+ part='main'
227
224
  layoutMode={layoutMode}
228
225
  flatDeck={flatDeck}
229
226
  searchEnabled={!!searchPlugin}
@@ -234,15 +231,8 @@ export const DeckLayout = ({
234
231
  </Main.Content>
235
232
  )}
236
233
 
237
- <StatusBar />
238
-
239
- {/* Help hints. */}
240
- {/* TODO(burdon): Need to make room for this in status bar. */}
241
- {showHintsFooter && (
242
- <div className='fixed bottom-0 left-0 right-0 h-[32px] z-[1] flex justify-center'>
243
- <Surface role='hints' limit={1} />
244
- </div>
245
- )}
234
+ {/* Footer status. */}
235
+ <StatusBar showHints={showHints} />
246
236
 
247
237
  {/* Global popovers. */}
248
238
  <Popover.Portal>
@@ -17,7 +17,7 @@ import {
17
17
  } from '@dxos/app-framework';
18
18
  import { type Node, useGraph } from '@dxos/plugin-graph';
19
19
  import { Icon, Popover, toLocalizedString, useMediaQuery, useTranslation } from '@dxos/react-ui';
20
- import { PlankHeading } from '@dxos/react-ui-deck';
20
+ import { PlankHeading, type PlankHeadingAction } from '@dxos/react-ui-deck';
21
21
  import { TextTooltip } from '@dxos/react-ui-text-tooltip';
22
22
 
23
23
  import { DECK_PLUGIN } from '../../meta';
@@ -30,6 +30,7 @@ export const NodePlankHeading = ({
30
30
  popoverAnchorId,
31
31
  pending,
32
32
  flatDeck,
33
+ actions = [],
33
34
  }: {
34
35
  node?: Node;
35
36
  id?: string;
@@ -38,6 +39,7 @@ export const NodePlankHeading = ({
38
39
  popoverAnchorId?: string;
39
40
  pending?: boolean;
40
41
  flatDeck?: boolean;
42
+ actions?: PlankHeadingAction[];
41
43
  }) => {
42
44
  const { t } = useTranslation(DECK_PLUGIN);
43
45
  const { graph } = useGraph();
@@ -78,7 +80,7 @@ export const NodePlankHeading = ({
78
80
  related={layoutPart === 'complementary'}
79
81
  attendableId={attendableId}
80
82
  triggerLabel={t('actions menu label')}
81
- actions={graph.actions(node)}
83
+ actions={[actions, graph.actions(node)].filter((a) => a.length > 0)}
82
84
  onAction={(action) =>
83
85
  typeof action.data === 'function' && action.data?.({ node: action as Node, caller: DECK_PLUGIN })
84
86
  }
@@ -78,7 +78,7 @@ export const Plank = ({ entry, layoutParts, part, flatDeck, searchEnabled, layou
78
78
  }, [scrollIntoView, layoutMode]);
79
79
 
80
80
  const isSolo = layoutMode === 'solo' && part === 'solo';
81
- const isSuppressed = layoutMode === 'solo' && part !== 'solo';
81
+ const isSuppressed = (layoutMode === 'solo' && part !== 'solo') || (layoutMode === 'deck' && part === 'solo');
82
82
 
83
83
  const sizeAttrs = useMainSize();
84
84
 
@@ -5,14 +5,23 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { Surface } from '@dxos/app-framework';
8
- import { mainPadding, mx } from '@dxos/react-ui-theme';
8
+ import { mainPadding, mainPaddingTransitions, mx } from '@dxos/react-ui-theme';
9
9
 
10
10
  import { useMainSize } from '../../hooks';
11
11
 
12
- export const StatusBar = () => {
12
+ export const StatusBar = ({ showHints }: { showHints?: boolean }) => {
13
13
  const sizeAttrs = useMainSize();
14
14
  return (
15
- <div role='none' {...sizeAttrs} className={mx('fixed block-end-0 inset-inline-0 z-[2]', mainPadding)}>
15
+ <div
16
+ role='none'
17
+ {...sizeAttrs}
18
+ className={mx(
19
+ 'fixed flex justify-between block-end-0 inset-inline-0 items-center border-bs border-separator z-[2]',
20
+ mainPadding,
21
+ mainPaddingTransitions,
22
+ )}
23
+ >
24
+ <div role='none'>{showHints && <Surface role='hints' limit={1} />}</div>
16
25
  <Surface role='status-bar' limit={1} />
17
26
  </div>
18
27
  );
@@ -61,25 +61,22 @@ export const LayoutSettings = ({ settings }: { settings: DeckSettingsProps }) =>
61
61
  </Select.Portal>
62
62
  </Select.Root>
63
63
  </SettingsValue>
64
- <SettingsValue label={t('settings show footer label')}>
65
- <Input.Switch checked={settings.showFooter} onCheckedChange={(checked) => (settings.showFooter = !!checked)} />
64
+ <SettingsValue label={t('settings show hints label')}>
65
+ <Input.Switch checked={settings.showHints} onCheckedChange={(checked) => (settings.showHints = checked)} />
66
66
  </SettingsValue>
67
67
  {!isSocket && (
68
68
  <SettingsValue label={t('settings native redirect label')}>
69
69
  <Input.Switch
70
70
  checked={settings.enableNativeRedirect}
71
- onCheckedChange={(checked) => (settings.enableNativeRedirect = !!checked)}
71
+ onCheckedChange={(checked) => (settings.enableNativeRedirect = checked)}
72
72
  />
73
73
  </SettingsValue>
74
74
  )}
75
75
  <SettingsValue label={t('settings custom slots')}>
76
- <Input.Switch
77
- checked={settings.customSlots}
78
- onCheckedChange={(checked) => (settings.customSlots = !!checked)}
79
- />
76
+ <Input.Switch checked={settings.customSlots} onCheckedChange={(checked) => (settings.customSlots = checked)} />
80
77
  </SettingsValue>
81
78
  <SettingsValue label={t('settings flat deck')}>
82
- <Input.Switch checked={settings.flatDeck} onCheckedChange={(checked) => (settings.flatDeck = !!checked)} />
79
+ <Input.Switch checked={settings.flatDeck} onCheckedChange={(checked) => (settings.flatDeck = checked)} />
83
80
  </SettingsValue>
84
81
  </>
85
82
  );
package/src/meta.ts CHANGED
@@ -2,9 +2,11 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { type PluginMeta } from '@dxos/app-framework';
6
+
5
7
  export const DECK_PLUGIN = 'dxos.org/plugin/deck';
6
8
 
7
9
  export default {
8
10
  id: DECK_PLUGIN,
9
11
  name: 'Deck',
10
- };
12
+ } satisfies PluginMeta;
@@ -16,7 +16,7 @@ export default [
16
16
  'content fallback description':
17
17
  'No plugin had a response for the address you navigated to. Double-check the URL, and ensure you’ve enabled a plugin that supports the object.',
18
18
  'toggle fullscreen label': 'Toggle fullscreen',
19
- 'settings show footer label': 'Show footer (experimental)',
19
+ 'settings show hints label': 'Show hints',
20
20
  'settings native redirect label': 'Enable native url redirect (experimental)',
21
21
  'settings custom slots': 'Theme option (experimental)',
22
22
  'settings new plank position start label': 'Start',
@@ -41,6 +41,8 @@ export default [
41
41
  'settings overscroll centering label': 'Centering',
42
42
  'settings overscroll none label': 'None',
43
43
  'settings flat deck': 'Flatten deck appearance',
44
+ 'comments label': 'Show Comments',
45
+ 'settings label': 'Show Settings',
44
46
  },
45
47
  },
46
48
  },
package/src/types.ts CHANGED
@@ -20,7 +20,7 @@ export const OverscrollOptions = ['none', 'centering'] as const;
20
20
  export type Overscroll = (typeof OverscrollOptions)[number];
21
21
 
22
22
  export type DeckSettingsProps = {
23
- showFooter: boolean;
23
+ showHints: boolean;
24
24
  customSlots: boolean;
25
25
  flatDeck: boolean;
26
26
  enableNativeRedirect: boolean;
@@ -56,9 +56,9 @@ export const calculateOverscroll = (
56
56
  plankSizing: Record<string, number>,
57
57
  sidebarOpen: boolean,
58
58
  complementarySidebarOpen: boolean,
59
- ): Pick<CSSProperties, 'paddingLeft' | 'paddingRight'> | undefined => {
59
+ ): Pick<CSSProperties, 'paddingInlineStart' | 'paddingInlineEnd'> | undefined => {
60
60
  if (!planks?.length) {
61
- return;
61
+ return { paddingInlineStart: 0, paddingInlineEnd: 0 };
62
62
  }
63
63
 
64
64
  // TODO(Zan): Move complementary sidebar size (360px), sidebar size (270px), plank resize handle size (20px) to CSS variables.
@@ -73,7 +73,7 @@ export const calculateOverscroll = (
73
73
  const plankSize = getPlankSize(plank.id);
74
74
  const overscrollPadding = `max(0px, calc(((100dvw - ${sidebarWidth} - ${complementarySidebarWidth} - (${plankSize} + 20px)) / 2)))`;
75
75
 
76
- return { paddingLeft: overscrollPadding, paddingRight: overscrollPadding };
76
+ return { paddingInlineStart: overscrollPadding, paddingInlineEnd: overscrollPadding };
77
77
  } else {
78
78
  // Center the plank on the screen.
79
79
  const first = planks[0];
@@ -83,8 +83,8 @@ export const calculateOverscroll = (
83
83
  const lastSize = getPlankSize(last.id);
84
84
 
85
85
  return {
86
- paddingLeft: `max(0px, calc(((100dvw - (${firstSize} + 20px)) / 2) - ${sidebarWidth}))`,
87
- paddingRight: `max(0px, calc(((100dvw - (${lastSize} + 20px)) / 2) - ${complementarySidebarWidth}))`,
86
+ paddingInlineStart: `max(0px, calc(((100dvw - (${firstSize} + 20px)) / 2) - ${sidebarWidth}))`,
87
+ paddingInlineEnd: `max(0px, calc(((100dvw - (${lastSize} + 20px)) / 2) - ${complementarySidebarWidth}))`,
88
88
  };
89
89
  }
90
90
  };
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/meta.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nexport const DECK_PLUGIN = 'dxos.org/plugin/deck';\n\nexport default {\n id: DECK_PLUGIN,\n name: 'Deck',\n};\n"],
5
- "mappings": ";AAIO,IAAMA,cAAc;AAE3B,IAAA,eAAe;EACbC,IAAID;EACJE,MAAM;AACR;",
6
- "names": ["DECK_PLUGIN", "id", "name"]
7
- }