@dxos/plugin-deck 0.6.13 → 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.
Files changed (57) 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/chunk-NIRHDTX4.mjs +17 -0
  4. package/dist/lib/browser/chunk-NIRHDTX4.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +334 -314
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/meta.mjs +1 -1
  9. package/dist/lib/browser/types.mjs +11 -0
  10. package/dist/lib/browser/types.mjs.map +7 -0
  11. package/dist/types/src/DeckPlugin.d.ts.map +1 -1
  12. package/dist/types/src/components/DeckLayout/ActiveNode.d.ts +1 -3
  13. package/dist/types/src/components/DeckLayout/ActiveNode.d.ts.map +1 -1
  14. package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts +4 -4
  15. package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts.map +1 -1
  16. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts +5 -5
  17. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
  18. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts +9 -7
  19. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts.map +1 -1
  20. package/dist/types/src/components/DeckLayout/Plank.d.ts +2 -2
  21. package/dist/types/src/components/DeckLayout/Plank.d.ts.map +1 -1
  22. package/dist/types/src/components/DeckLayout/PlankError.d.ts +1 -2
  23. package/dist/types/src/components/DeckLayout/PlankError.d.ts.map +1 -1
  24. package/dist/types/src/components/DeckLayout/Sidebar.d.ts +2 -3
  25. package/dist/types/src/components/DeckLayout/Sidebar.d.ts.map +1 -1
  26. package/dist/types/src/components/DeckLayout/StatusBar.d.ts +3 -1
  27. package/dist/types/src/components/DeckLayout/StatusBar.d.ts.map +1 -1
  28. package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
  29. package/dist/types/src/components/LayoutSettings.d.ts.map +1 -1
  30. package/dist/types/src/hooks/useNode.d.ts.map +1 -1
  31. package/dist/types/src/layout.d.ts.map +1 -1
  32. package/dist/types/src/meta.d.ts.map +1 -1
  33. package/dist/types/src/translations.d.ts +1 -3
  34. package/dist/types/src/translations.d.ts.map +1 -1
  35. package/dist/types/src/types.d.ts +14 -2
  36. package/dist/types/src/types.d.ts.map +1 -1
  37. package/dist/types/src/util/overscroll.d.ts +1 -1
  38. package/dist/types/src/util/overscroll.d.ts.map +1 -1
  39. package/package.json +42 -33
  40. package/src/DeckPlugin.tsx +104 -80
  41. package/src/components/DeckLayout/ActiveNode.tsx +4 -1
  42. package/src/components/DeckLayout/ComplementarySidebar.tsx +59 -28
  43. package/src/components/DeckLayout/DeckLayout.tsx +67 -98
  44. package/src/components/DeckLayout/NodePlankHeading.tsx +130 -127
  45. package/src/components/DeckLayout/Plank.tsx +48 -32
  46. package/src/components/DeckLayout/PlankError.tsx +1 -9
  47. package/src/components/DeckLayout/Sidebar.tsx +7 -8
  48. package/src/components/DeckLayout/StatusBar.tsx +12 -3
  49. package/src/components/DeckLayout/Toast.tsx +3 -3
  50. package/src/components/LayoutSettings.tsx +17 -20
  51. package/src/hooks/useNode.ts +5 -1
  52. package/src/layout.ts +1 -0
  53. package/src/meta.ts +3 -1
  54. package/src/translations.ts +1 -3
  55. package/src/types.ts +16 -1
  56. package/src/util/overscroll.ts +5 -5
  57. 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
 
@@ -32,35 +34,43 @@ import { DECK_PLUGIN } from '../../meta';
32
34
  import { useDeckContext } from '../DeckContext';
33
35
  import { useLayout } from '../LayoutContext';
34
36
 
37
+ const UNKNOWN_ID = 'unknown_id';
38
+
35
39
  export type PlankProps = {
36
- entry: LayoutEntry;
40
+ entry?: LayoutEntry;
37
41
  layoutParts: LayoutParts;
38
- // TODO(wittjosiah): Remove.
42
+ // TODO(wittjosiah): Remove. Pass in LayoutCoordinate instead of LayoutEntry.
39
43
  part: LayoutPart;
40
44
  layoutMode: Layout['layoutMode'];
41
45
  flatDeck?: boolean;
42
46
  searchEnabled?: boolean;
43
47
  };
44
48
 
45
- export const Plank = ({ entry, layoutParts, part, flatDeck, searchEnabled, layoutMode }: PlankProps) => {
49
+ export const Plank = memo(({ entry, layoutParts, part, flatDeck, searchEnabled, layoutMode }: PlankProps) => {
46
50
  const { t } = useTranslation(DECK_PLUGIN);
47
51
  const dispatch = useIntentDispatcher();
52
+ const coordinate: LayoutCoordinate = useMemo(() => ({ part, entryId: entry?.id ?? UNKNOWN_ID }), [entry?.id, part]);
48
53
  const { popoverAnchorId, scrollIntoView } = useLayout();
49
54
  const { plankSizing } = useDeckContext();
50
55
  const { graph } = useGraph();
51
- const node = useNode(graph, entry.id);
56
+ const node = useNode(graph, entry?.id);
52
57
  const rootElement = useRef<HTMLDivElement | null>(null);
53
58
  const resizeable = layoutMode === 'deck';
54
59
 
55
- const attendableAttrs = createAttendableAttributes(entry.id);
56
- const coordinate: LayoutCoordinate = { part, entryId: entry.id };
60
+ const attendableAttrs = useAttendableAttributes(coordinate.entryId);
61
+ const index = indexInPart(layoutParts, coordinate);
62
+ const length = partLength(layoutParts, part);
63
+ const canIncrementStart = part === 'main' && index !== undefined && index > 0 && length !== undefined && length > 1;
64
+ const canIncrementEnd = part === 'main' && index !== undefined && index < length - 1 && length !== undefined;
57
65
 
58
- const size = plankSizing?.[entry.id] as number | undefined;
66
+ const size = plankSizing?.[coordinate.entryId] as number | undefined;
59
67
  const setSize = useCallback(
60
- debounce((newSize: number) => {
61
- void dispatch({ action: DeckAction.UPDATE_PLANK_SIZE, data: { id: entry.id, size: newSize } });
62
- }, 200),
63
- [dispatch, entry.id],
68
+ debounce(
69
+ (newSize: number) =>
70
+ dispatch({ action: DeckAction.UPDATE_PLANK_SIZE, data: { id: coordinate.entryId, size: newSize } }),
71
+ 200,
72
+ ),
73
+ [dispatch, coordinate.entryId],
64
74
  );
65
75
 
66
76
  // TODO(thure): Tabster’s focus group should handle moving focus to Main, but something is blocking it.
@@ -71,17 +81,33 @@ export const Plank = ({ entry, layoutParts, part, flatDeck, searchEnabled, layou
71
81
  }, []);
72
82
 
73
83
  useLayoutEffect(() => {
74
- if (scrollIntoView === entry.id) {
84
+ if (scrollIntoView === coordinate.entryId) {
75
85
  rootElement.current?.focus({ preventScroll: true });
76
86
  layoutMode === 'deck' && rootElement.current?.scrollIntoView({ behavior: 'smooth', inline: 'center' });
77
87
  }
78
- }, [scrollIntoView, layoutMode]);
88
+ }, [coordinate.entryId, scrollIntoView, layoutMode]);
79
89
 
80
90
  const isSolo = layoutMode === 'solo' && part === 'solo';
81
- const isSuppressed = layoutMode === 'solo' && part !== 'solo';
91
+ const isSuppressed =
92
+ (layoutMode === 'solo' && part !== 'solo') ||
93
+ (layoutMode === 'deck' && part === 'solo') ||
94
+ coordinate.entryId === UNKNOWN_ID;
82
95
 
83
96
  const sizeAttrs = useMainSize();
84
97
 
98
+ const data = useMemo(
99
+ () =>
100
+ node && {
101
+ ...(entry?.path ? { subject: node.data, path: entry.path } : { object: node.data }),
102
+ coordinate,
103
+ popoverAnchorId,
104
+ },
105
+ [node, node?.data, entry?.path, coordinate, popoverAnchorId],
106
+ );
107
+
108
+ // TODO(wittjosiah): Change prop to accept a component.
109
+ const placeholder = useMemo(() => <PlankLoading />, []);
110
+
85
111
  return (
86
112
  <NaturalPlank.Root
87
113
  size={size}
@@ -100,27 +126,17 @@ export const Plank = ({ entry, layoutParts, part, flatDeck, searchEnabled, layou
100
126
  {node ? (
101
127
  <>
102
128
  <NodePlankHeading
103
- id={entry.id}
129
+ coordinate={coordinate}
104
130
  node={node}
105
- layoutPart={coordinate.part}
106
- layoutParts={layoutParts}
131
+ canIncrementStart={canIncrementStart}
132
+ canIncrementEnd={canIncrementEnd}
107
133
  popoverAnchorId={popoverAnchorId}
108
134
  flatDeck={flatDeck}
109
135
  />
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
- />
136
+ <Surface role='article' data={data} limit={1} fallback={PlankContentError} placeholder={placeholder} />
121
137
  </>
122
138
  ) : (
123
- <PlankError layoutCoordinate={coordinate} id={entry.id} flatDeck={flatDeck} />
139
+ <PlankError layoutCoordinate={coordinate} flatDeck={flatDeck} />
124
140
  )}
125
141
  </NaturalPlank.Content>
126
142
  {searchEnabled && resizeable ? (
@@ -166,4 +182,4 @@ export const Plank = ({ entry, layoutParts, part, flatDeck, searchEnabled, layou
166
182
  ) : null}
167
183
  </NaturalPlank.Root>
168
184
  );
169
- };
185
+ });
@@ -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,36 +4,35 @@
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
9
 
10
10
  import { useLayout } from '../LayoutContext';
11
11
 
12
12
  export type SidebarProps = {
13
- attention: Attention;
14
13
  layoutParts: LayoutParts;
15
14
  };
16
15
 
17
- export const Sidebar = ({ attention, layoutParts }: SidebarProps) => {
16
+ export const Sidebar = ({ layoutParts }: SidebarProps) => {
18
17
  const { layoutMode, popoverAnchorId } = useLayout();
19
18
 
19
+ // TODO(wittjosiah): The activeIds should be path-based to avoid conflicts.
20
20
  const activeIds = useMemo(() => {
21
21
  if (layoutMode === 'solo') {
22
- return new Set<string>(layoutParts?.solo?.map((e) => e.id) ?? []);
22
+ return Array.from(new Set<string>(layoutParts?.solo?.map((e) => e.id) ?? []));
23
23
  } else if (layoutMode === 'deck') {
24
- return new Set<string>(layoutParts?.main?.map((e) => e.id) ?? []);
24
+ return Array.from(new Set<string>(layoutParts?.main?.map((e) => e.id) ?? []));
25
25
  }
26
26
 
27
- return new Set<string>(openIds(layoutParts));
27
+ return Array.from(new Set<string>(openIds(layoutParts)));
28
28
  }, [layoutParts, layoutMode]);
29
29
 
30
30
  const navigationData = useMemo(
31
31
  () => ({
32
32
  popoverAnchorId,
33
33
  activeIds,
34
- attended: attention.attended,
35
34
  }),
36
- [popoverAnchorId, activeIds, attention.attended],
35
+ [popoverAnchorId, activeIds],
37
36
  );
38
37
  return (
39
38
  <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>}
@@ -4,8 +4,8 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { SettingsValue } from '@dxos/plugin-settings';
8
7
  import { Input, Select, useTranslation } from '@dxos/react-ui';
8
+ import { DeprecatedFormInput } from '@dxos/react-ui-data';
9
9
 
10
10
  import { DECK_PLUGIN } from '../meta';
11
11
  import {
@@ -23,7 +23,7 @@ export const LayoutSettings = ({ settings }: { settings: DeckSettingsProps }) =>
23
23
 
24
24
  return (
25
25
  <>
26
- <SettingsValue label={t('select new plank positioning label')}>
26
+ <DeprecatedFormInput label={t('select new plank positioning label')}>
27
27
  <Select.Root
28
28
  value={settings.newPlankPositioning ?? 'start'}
29
29
  onValueChange={(value) => (settings.newPlankPositioning = value as NewPlankPositioning)}
@@ -41,8 +41,8 @@ export const LayoutSettings = ({ settings }: { settings: DeckSettingsProps }) =>
41
41
  </Select.Content>
42
42
  </Select.Portal>
43
43
  </Select.Root>
44
- </SettingsValue>
45
- <SettingsValue label={t('settings overscroll label')}>
44
+ </DeprecatedFormInput>
45
+ <DeprecatedFormInput label={t('settings overscroll label')}>
46
46
  <Select.Root
47
47
  value={settings.overscroll ?? 'none'}
48
48
  onValueChange={(value) => (settings.overscroll = value as Overscroll)}
@@ -60,27 +60,24 @@ export const LayoutSettings = ({ settings }: { settings: DeckSettingsProps }) =>
60
60
  </Select.Content>
61
61
  </Select.Portal>
62
62
  </Select.Root>
63
- </SettingsValue>
64
- <SettingsValue label={t('settings show footer label')}>
65
- <Input.Switch checked={settings.showFooter} onCheckedChange={(checked) => (settings.showFooter = !!checked)} />
66
- </SettingsValue>
63
+ </DeprecatedFormInput>
64
+ <DeprecatedFormInput label={t('settings show hints label')}>
65
+ <Input.Switch checked={settings.showHints} onCheckedChange={(checked) => (settings.showHints = checked)} />
66
+ </DeprecatedFormInput>
67
67
  {!isSocket && (
68
- <SettingsValue label={t('settings native redirect label')}>
68
+ <DeprecatedFormInput 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
- </SettingsValue>
73
+ </DeprecatedFormInput>
74
74
  )}
75
- <SettingsValue label={t('settings custom slots')}>
76
- <Input.Switch
77
- checked={settings.customSlots}
78
- onCheckedChange={(checked) => (settings.customSlots = !!checked)}
79
- />
80
- </SettingsValue>
81
- <SettingsValue label={t('settings flat deck')}>
82
- <Input.Switch checked={settings.flatDeck} onCheckedChange={(checked) => (settings.flatDeck = !!checked)} />
83
- </SettingsValue>
75
+ <DeprecatedFormInput label={t('settings custom slots')}>
76
+ <Input.Switch checked={settings.customSlots} onCheckedChange={(checked) => (settings.customSlots = checked)} />
77
+ </DeprecatedFormInput>
78
+ <DeprecatedFormInput label={t('settings flat deck')}>
79
+ <Input.Switch checked={settings.flatDeck} onCheckedChange={(checked) => (settings.flatDeck = checked)} />
80
+ </DeprecatedFormInput>
84
81
  </>
85
82
  );
86
83
  };
@@ -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',
package/src/types.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  import type {
6
+ Plugin,
6
7
  GraphBuilderProvides,
7
8
  IntentResolverProvides,
8
9
  LayoutProvides,
@@ -11,6 +12,7 @@ import type {
11
12
  SurfaceProvides,
12
13
  TranslationsProvides,
13
14
  } from '@dxos/app-framework';
15
+ import { type Label } from '@dxos/react-ui';
14
16
 
15
17
  // TODO(Zan): In the future we should consider adding new planks adjacent to the attended plank.
16
18
  export const NewPlankPositions = ['start', 'end'] as const;
@@ -19,8 +21,21 @@ export type NewPlankPositioning = (typeof NewPlankPositions)[number];
19
21
  export const OverscrollOptions = ['none', 'centering'] as const;
20
22
  export type Overscroll = (typeof OverscrollOptions)[number];
21
23
 
24
+ // TODO(wittjosiah): Include a predicate for whether the panel is visible for the current subject.
25
+ export type Panel = { id: string; label: Label; icon: string };
26
+
27
+ // TODO(wittjosiah): Is this generic enough to be in the app framework?
28
+ export type PanelProvides = {
29
+ complementary: {
30
+ panels: Panel[];
31
+ };
32
+ };
33
+
34
+ export const parsePanelPlugin = (plugin?: Plugin) =>
35
+ Array.isArray((plugin?.provides as any).complementary?.panels) ? (plugin as Plugin<PanelProvides>) : undefined;
36
+
22
37
  export type DeckSettingsProps = {
23
- showFooter: boolean;
38
+ showHints: boolean;
24
39
  customSlots: boolean;
25
40
  flatDeck: boolean;
26
41
  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
- }