@dxos/plugin-deck 0.6.13-staging.1e988a3 → 0.6.14-main.2b6a0f3

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 (53) 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 +331 -264
  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/ActiveNode.d.ts +1 -3
  9. package/dist/types/src/components/DeckLayout/ActiveNode.d.ts.map +1 -1
  10. package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts +2 -4
  11. package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts.map +1 -1
  12. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts +3 -4
  13. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
  14. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts +9 -7
  15. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts.map +1 -1
  16. package/dist/types/src/components/DeckLayout/Plank.d.ts +1 -1
  17. package/dist/types/src/components/DeckLayout/Plank.d.ts.map +1 -1
  18. package/dist/types/src/components/DeckLayout/PlankError.d.ts +1 -2
  19. package/dist/types/src/components/DeckLayout/PlankError.d.ts.map +1 -1
  20. package/dist/types/src/components/DeckLayout/Sidebar.d.ts +2 -3
  21. package/dist/types/src/components/DeckLayout/Sidebar.d.ts.map +1 -1
  22. package/dist/types/src/components/DeckLayout/StatusBar.d.ts +3 -1
  23. package/dist/types/src/components/DeckLayout/StatusBar.d.ts.map +1 -1
  24. package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
  25. package/dist/types/src/components/LayoutSettings.d.ts.map +1 -1
  26. package/dist/types/src/hooks/useNode.d.ts.map +1 -1
  27. package/dist/types/src/layout.d.ts.map +1 -1
  28. package/dist/types/src/meta.d.ts.map +1 -1
  29. package/dist/types/src/translations.d.ts +5 -3
  30. package/dist/types/src/translations.d.ts.map +1 -1
  31. package/dist/types/src/types.d.ts +1 -1
  32. package/dist/types/src/types.d.ts.map +1 -1
  33. package/dist/types/src/util/overscroll.d.ts +1 -1
  34. package/dist/types/src/util/overscroll.d.ts.map +1 -1
  35. package/package.json +31 -29
  36. package/src/DeckPlugin.tsx +93 -71
  37. package/src/components/DeckLayout/ActiveNode.tsx +4 -1
  38. package/src/components/DeckLayout/ComplementarySidebar.tsx +70 -28
  39. package/src/components/DeckLayout/DeckLayout.tsx +64 -96
  40. package/src/components/DeckLayout/NodePlankHeading.tsx +130 -127
  41. package/src/components/DeckLayout/Plank.tsx +31 -22
  42. package/src/components/DeckLayout/PlankError.tsx +1 -9
  43. package/src/components/DeckLayout/Sidebar.tsx +6 -5
  44. package/src/components/DeckLayout/StatusBar.tsx +12 -3
  45. package/src/components/DeckLayout/Toast.tsx +3 -3
  46. package/src/components/LayoutSettings.tsx +5 -8
  47. package/src/hooks/useNode.ts +5 -1
  48. package/src/layout.ts +1 -0
  49. package/src/meta.ts +3 -1
  50. package/src/translations.ts +7 -3
  51. package/src/types.ts +1 -1
  52. package/src/util/overscroll.ts +5 -5
  53. package/dist/lib/browser/chunk-YVHGFQQR.mjs.map +0 -7
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Plus } from '@phosphor-icons/react';
6
- import React, { type KeyboardEvent, useCallback, useLayoutEffect, useRef } from 'react';
6
+ import React, { type KeyboardEvent, memo, useCallback, useLayoutEffect, useMemo, useRef } from 'react';
7
7
 
8
8
  import {
9
9
  LayoutAction,
@@ -15,11 +15,13 @@ import {
15
15
  Surface,
16
16
  useIntentDispatcher,
17
17
  type Layout,
18
+ indexInPart,
19
+ partLength,
18
20
  } from '@dxos/app-framework';
19
21
  import { debounce } from '@dxos/async';
20
22
  import { useGraph } from '@dxos/plugin-graph';
21
23
  import { Button, Tooltip, useTranslation } from '@dxos/react-ui';
22
- import { createAttendableAttributes } from '@dxos/react-ui-attention';
24
+ import { useAttendableAttributes } from '@dxos/react-ui-attention';
23
25
  import { Plank as NaturalPlank } from '@dxos/react-ui-deck';
24
26
  import { mainIntrinsicSize } from '@dxos/react-ui-theme';
25
27
 
@@ -42,7 +44,7 @@ export type PlankProps = {
42
44
  searchEnabled?: boolean;
43
45
  };
44
46
 
45
- export const Plank = ({ entry, layoutParts, part, flatDeck, searchEnabled, layoutMode }: PlankProps) => {
47
+ export const Plank = memo(({ entry, layoutParts, part, flatDeck, searchEnabled, layoutMode }: PlankProps) => {
46
48
  const { t } = useTranslation(DECK_PLUGIN);
47
49
  const dispatch = useIntentDispatcher();
48
50
  const { popoverAnchorId, scrollIntoView } = useLayout();
@@ -52,8 +54,12 @@ export const Plank = ({ entry, layoutParts, part, flatDeck, searchEnabled, layou
52
54
  const rootElement = useRef<HTMLDivElement | null>(null);
53
55
  const resizeable = layoutMode === 'deck';
54
56
 
55
- const attendableAttrs = createAttendableAttributes(entry.id);
56
- const coordinate: LayoutCoordinate = { part, entryId: entry.id };
57
+ const attendableAttrs = useAttendableAttributes(entry.id);
58
+ const coordinate: LayoutCoordinate = useMemo(() => ({ part, entryId: entry.id }), [entry.id, part]);
59
+ const index = indexInPart(layoutParts, coordinate);
60
+ const length = partLength(layoutParts, part);
61
+ const canIncrementStart = part === 'main' && index !== undefined && index > 0 && length !== undefined && length > 1;
62
+ const canIncrementEnd = part === 'main' && index !== undefined && index < length - 1 && length !== undefined;
57
63
 
58
64
  const size = plankSizing?.[entry.id] as number | undefined;
59
65
  const setSize = useCallback(
@@ -78,10 +84,23 @@ export const Plank = ({ entry, layoutParts, part, flatDeck, searchEnabled, layou
78
84
  }, [scrollIntoView, layoutMode]);
79
85
 
80
86
  const isSolo = layoutMode === 'solo' && part === 'solo';
81
- const isSuppressed = layoutMode === 'solo' && part !== 'solo';
87
+ const isSuppressed = (layoutMode === 'solo' && part !== 'solo') || (layoutMode === 'deck' && part === 'solo');
82
88
 
83
89
  const sizeAttrs = useMainSize();
84
90
 
91
+ const data = useMemo(
92
+ () =>
93
+ node && {
94
+ ...(entry.path ? { subject: node.data, path: entry.path } : { object: node.data }),
95
+ coordinate,
96
+ popoverAnchorId,
97
+ },
98
+ [node],
99
+ );
100
+
101
+ // TODO(wittjosiah): Change prop to accept a component.
102
+ const placeholder = useMemo(() => <PlankLoading />, []);
103
+
85
104
  return (
86
105
  <NaturalPlank.Root
87
106
  size={size}
@@ -100,27 +119,17 @@ export const Plank = ({ entry, layoutParts, part, flatDeck, searchEnabled, layou
100
119
  {node ? (
101
120
  <>
102
121
  <NodePlankHeading
103
- id={entry.id}
122
+ coordinate={coordinate}
104
123
  node={node}
105
- layoutPart={coordinate.part}
106
- layoutParts={layoutParts}
124
+ canIncrementStart={canIncrementStart}
125
+ canIncrementEnd={canIncrementEnd}
107
126
  popoverAnchorId={popoverAnchorId}
108
127
  flatDeck={flatDeck}
109
128
  />
110
- <Surface
111
- role='article'
112
- data={{
113
- ...(entry.path ? { subject: node.data, path: entry.path } : { object: node.data }),
114
- coordinate,
115
- popoverAnchorId,
116
- }}
117
- limit={1}
118
- fallback={PlankContentError}
119
- placeholder={<PlankLoading />}
120
- />
129
+ <Surface role='article' data={data} limit={1} fallback={PlankContentError} placeholder={placeholder} />
121
130
  </>
122
131
  ) : (
123
- <PlankError layoutCoordinate={coordinate} id={entry.id} flatDeck={flatDeck} />
132
+ <PlankError layoutCoordinate={coordinate} flatDeck={flatDeck} />
124
133
  )}
125
134
  </NaturalPlank.Content>
126
135
  {searchEnabled && resizeable ? (
@@ -166,4 +175,4 @@ export const Plank = ({ entry, layoutParts, part, flatDeck, searchEnabled, layou
166
175
  ) : null}
167
176
  </NaturalPlank.Root>
168
177
  );
169
- };
178
+ });
@@ -34,13 +34,11 @@ export const PlankContentError = ({ error }: { error?: Error }) => {
34
34
 
35
35
  export const PlankError = ({
36
36
  layoutCoordinate,
37
- id,
38
37
  node,
39
38
  error,
40
39
  flatDeck,
41
40
  }: {
42
41
  layoutCoordinate: LayoutCoordinate;
43
- id: string;
44
42
  node?: Node;
45
43
  error?: Error;
46
44
  flatDeck?: boolean;
@@ -51,13 +49,7 @@ export const PlankError = ({
51
49
  }, []);
52
50
  return (
53
51
  <>
54
- <NodePlankHeading
55
- node={node}
56
- id={id}
57
- layoutPart={layoutCoordinate.part}
58
- pending={!timedOut}
59
- flatDeck={flatDeck}
60
- />
52
+ <NodePlankHeading coordinate={layoutCoordinate} node={node} pending={!timedOut} flatDeck={flatDeck} />
61
53
  {timedOut ? <PlankContentError error={error} /> : <PlankLoading />}
62
54
  </>
63
55
  );
@@ -4,18 +4,19 @@
4
4
 
5
5
  import React, { useMemo } from 'react';
6
6
 
7
- import { type Attention, type LayoutParts, openIds, Surface } from '@dxos/app-framework';
7
+ import { type LayoutParts, openIds, Surface } from '@dxos/app-framework';
8
8
  import { Main } from '@dxos/react-ui';
9
+ import { useAttended } from '@dxos/react-ui-attention';
9
10
 
10
11
  import { useLayout } from '../LayoutContext';
11
12
 
12
13
  export type SidebarProps = {
13
- attention: Attention;
14
14
  layoutParts: LayoutParts;
15
15
  };
16
16
 
17
- export const Sidebar = ({ attention, layoutParts }: SidebarProps) => {
17
+ export const Sidebar = ({ layoutParts }: SidebarProps) => {
18
18
  const { layoutMode, popoverAnchorId } = useLayout();
19
+ const attended = useAttended();
19
20
 
20
21
  const activeIds = useMemo(() => {
21
22
  if (layoutMode === 'solo') {
@@ -31,9 +32,9 @@ export const Sidebar = ({ attention, layoutParts }: SidebarProps) => {
31
32
  () => ({
32
33
  popoverAnchorId,
33
34
  activeIds,
34
- attended: attention.attended,
35
+ attended,
35
36
  }),
36
- [popoverAnchorId, activeIds, attention.attended],
37
+ [popoverAnchorId, activeIds, attended],
37
38
  );
38
39
  return (
39
40
  <Main.NavigationSidebar>
@@ -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
  );
@@ -5,7 +5,7 @@
5
5
  import React from 'react';
6
6
 
7
7
  import type { Toast as ToastProps } from '@dxos/app-framework';
8
- import { Button, Toast as NaturalToast, type ToastRootProps } from '@dxos/react-ui';
8
+ import { Button, Icon, Toast as NaturalToast, type ToastRootProps } from '@dxos/react-ui';
9
9
 
10
10
  // TODO(wittjosiah): Render remaining duration as a progress bar within the toast.
11
11
  export const Toast = ({
@@ -23,8 +23,8 @@ export const Toast = ({
23
23
  return (
24
24
  <NaturalToast.Root data-testid={id} defaultOpen duration={duration} onOpenChange={onOpenChange}>
25
25
  <NaturalToast.Body>
26
- <NaturalToast.Title>
27
- {icon?.({ className: 'inline mr-1' })}
26
+ <NaturalToast.Title classNames='items-center'>
27
+ <Icon icon={icon} size={5} classNames='inline mr-1' />
28
28
  <span>{title}</span>
29
29
  </NaturalToast.Title>
30
30
  {description && <NaturalToast.Description>{description}</NaturalToast.Description>}
@@ -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
  );
@@ -16,9 +16,13 @@ import { type Graph, type Node } from '@dxos/plugin-graph';
16
16
  */
17
17
  // TODO(wittjosiah): Factor out.
18
18
  export const useNode = <T = any>(graph: Graph, id?: string, timeout?: number): Node<T> | undefined => {
19
- const [nodeState, setNodeState] = useState<Node<T> | undefined>(id ? graph.findNode(id) : undefined);
19
+ const [nodeState, setNodeState] = useState<Node<T> | undefined>(id ? graph.findNode(id, false) : undefined);
20
20
 
21
21
  useEffect(() => {
22
+ if (!id && nodeState) {
23
+ setNodeState(undefined);
24
+ }
25
+
22
26
  if (nodeState?.id === id || !id) {
23
27
  return;
24
28
  }
package/src/layout.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  //
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
+
4
5
  import { produce } from 'immer';
5
6
 
6
7
  import {
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;
@@ -10,13 +10,12 @@ export default [
10
10
  'main header label': 'Main header',
11
11
  'open navigation sidebar label': 'Open navigation sidebar.',
12
12
  'open complementary sidebar label': 'Open complementary sidebar.',
13
- 'open settings label': 'Show settings',
14
13
  'plugin error message': 'Content failed to render.',
15
14
  'content fallback message': 'Unsupported',
16
15
  'content fallback description':
17
16
  '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
17
  'toggle fullscreen label': 'Toggle fullscreen',
19
- 'settings show footer label': 'Show footer (experimental)',
18
+ 'settings show hints label': 'Show hints',
20
19
  'settings native redirect label': 'Enable native url redirect (experimental)',
21
20
  'settings custom slots': 'Theme option (experimental)',
22
21
  'settings new plank position start label': 'Start',
@@ -27,7 +26,6 @@ export default [
27
26
  'undo action label': 'Undo',
28
27
  'undo action alt': 'Undo previous action',
29
28
  'undo close label': 'Dismiss',
30
- 'open comments label': 'Open comments',
31
29
  'error fallback message': 'Unable to open this item',
32
30
  'plank heading fallback label': 'Untitled',
33
31
  'actions menu label': 'Options',
@@ -41,6 +39,12 @@ export default [
41
39
  'settings overscroll centering label': 'Centering',
42
40
  'settings overscroll none label': 'None',
43
41
  'settings flat deck': 'Flatten deck appearance',
42
+
43
+ // ComplementarySidebar
44
+ 'open settings label': 'Show settings',
45
+ 'open comments label': 'Show Comments',
46
+ 'open automation label': 'Show Automation',
47
+ 'open debug label': 'Show Debug',
44
48
  },
45
49
  },
46
50
  },
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
- }