@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,21 +3,14 @@
3
3
  //
4
4
 
5
5
  import { Sidebar as MenuIcon } from '@phosphor-icons/react';
6
- import React, { useCallback, useEffect, useMemo, useRef, useState, useLayoutEffect, type UIEvent } from 'react';
6
+ import { untracked } from '@preact/signals-core';
7
+ import React, { useCallback, useEffect, useMemo, useRef, type UIEvent } from 'react';
7
8
 
8
- import {
9
- SLUG_PATH_SEPARATOR,
10
- type Attention,
11
- type LayoutEntry,
12
- type LayoutParts,
13
- Surface,
14
- type Toast as ToastSchema,
15
- firstIdInPart,
16
- usePlugin,
17
- } from '@dxos/app-framework';
18
- import { Button, Dialog, Main, Popover, useTranslation } from '@dxos/react-ui';
9
+ import { type LayoutParts, Surface, type Toast as ToastSchema, firstIdInPart, usePlugin } from '@dxos/app-framework';
10
+ import { type AttentionPluginProvides } from '@dxos/plugin-attention';
11
+ import { Button, Dialog, Main, Popover, useOnTransition, useTranslation } from '@dxos/react-ui';
19
12
  import { Deck } from '@dxos/react-ui-deck';
20
- import { getSize } from '@dxos/react-ui-theme';
13
+ import { getSize, mainPaddingTransitions } from '@dxos/react-ui-theme';
21
14
 
22
15
  import { ActiveNode } from './ActiveNode';
23
16
  import { ComplementarySidebar } from './ComplementarySidebar';
@@ -35,11 +28,10 @@ import { useLayout } from '../LayoutContext';
35
28
 
36
29
  export type DeckLayoutProps = {
37
30
  layoutParts: LayoutParts;
38
- attention: Attention;
39
31
  toasts: ToastSchema[];
40
32
  flatDeck?: boolean;
41
33
  overscroll: Overscroll;
42
- showHintsFooter: boolean;
34
+ showHints: boolean;
43
35
  slots?: {
44
36
  wallpaper?: { classNames?: string };
45
37
  };
@@ -48,11 +40,10 @@ export type DeckLayoutProps = {
48
40
 
49
41
  export const DeckLayout = ({
50
42
  layoutParts,
51
- attention,
52
43
  toasts,
53
44
  flatDeck,
54
45
  overscroll,
55
- showHintsFooter,
46
+ showHints,
56
47
  slots,
57
48
  onDismissToast,
58
49
  }: DeckLayoutProps) => {
@@ -70,36 +61,44 @@ export const DeckLayout = ({
70
61
  } = context;
71
62
  const { t } = useTranslation(DECK_PLUGIN);
72
63
  const { plankSizing } = useDeckContext();
64
+ // NOTE: Not `useAttended` so that the layout component is not re-rendered when the attended list changes.
65
+ const attentionPlugin = usePlugin<AttentionPluginProvides>('dxos.org/plugin/attention');
73
66
  const searchPlugin = usePlugin('dxos.org/plugin/search');
74
67
  const fullScreenSlug = useMemo(() => firstIdInPart(layoutParts, 'fullScreen'), [layoutParts]);
75
68
 
76
- const [scrollLeft, setScrollLeft] = useState<number | null>(null);
77
- const deckRef = useRef<HTMLDivElement | null>(null);
78
- const restoreScrollRef = useRef<boolean>(false);
69
+ const scrollLeftRef = useRef<number | null>();
70
+ const deckRef = useRef<HTMLDivElement>(null);
71
+
72
+ // Ensure the first plank is attended when the deck is first rendered.
73
+ useEffect(() => {
74
+ const attended = untracked(() => attentionPlugin?.provides.attention.attended ?? []);
75
+ const firstId = layoutMode === 'solo' ? firstIdInPart(layoutParts, 'solo') : firstIdInPart(layoutParts, 'main');
76
+ if (attended.length === 0 && firstId) {
77
+ // TODO(wittjosiah): Focusing the type button is a workaround.
78
+ // If the plank is directly focused on first load the focus ring appears.
79
+ document.querySelector<HTMLElement>(`article[data-attendable-id="${firstId}"] button`)?.focus();
80
+ }
81
+ }, []);
79
82
 
80
83
  /**
81
84
  * Clear scroll restoration state if the window is resized
82
85
  */
83
86
  const handleResize = useCallback(() => {
84
- setScrollLeft(null);
87
+ scrollLeftRef.current = null;
85
88
  }, []);
89
+
86
90
  useEffect(() => {
87
91
  window.addEventListener('resize', handleResize);
88
92
  return () => window.removeEventListener('resize', handleResize);
89
93
  }, [handleResize]);
90
94
 
91
- /**
92
- * Restore scroll when returning to deck mode
93
- */
94
- useLayoutEffect(() => {
95
- if (layoutMode !== 'deck') {
96
- restoreScrollRef.current = true;
97
- } else if (restoreScrollRef.current && deckRef.current && scrollLeft) {
98
- // console.log('[restoring scrollLeft]', scrollLeft);
99
- deckRef.current.scrollLeft = scrollLeft;
100
- restoreScrollRef.current = false;
95
+ const restoreScroll = useCallback(() => {
96
+ if (deckRef.current && scrollLeftRef.current != null) {
97
+ deckRef.current.scrollLeft = scrollLeftRef.current;
101
98
  }
102
- }, [layoutMode, deckRef.current, scrollLeft]);
99
+ }, []);
100
+
101
+ useOnTransition(layoutMode, (mode) => mode !== 'deck', 'deck', restoreScroll);
103
102
 
104
103
  /**
105
104
  * Save scroll position as the user scrolls
@@ -107,48 +106,20 @@ export const DeckLayout = ({
107
106
  const handleScroll = useCallback(
108
107
  (event: UIEvent) => {
109
108
  if (layoutMode === 'deck' && event.currentTarget === event.target) {
110
- // console.log('[save scroll left]', (event.target as HTMLDivElement).scrollLeft);
111
- setScrollLeft((event.target as HTMLDivElement).scrollLeft);
109
+ scrollLeftRef.current = (event.target as HTMLDivElement).scrollLeft;
112
110
  }
113
111
  },
114
112
  [layoutMode],
115
113
  );
116
114
 
117
- const complementarySlug = useMemo(() => {
118
- const entry = layoutParts.complementary?.at(0);
119
- if (entry) {
120
- return entry.path ? `${entry.id}${SLUG_PATH_SEPARATOR}${entry.path}` : entry.id;
121
- }
122
- }, [layoutParts]);
123
-
124
- const firstAttendedId = useMemo(() => Array.from(attention.attended ?? [])[0], [attention.attended]);
115
+ const isEmpty = layoutParts.main?.length === 0 && layoutParts.solo?.length === 0;
125
116
 
126
- useEffect(() => {
127
- // TODO(burdon): Can we prevent the need to re-scroll since the planks are preserved?
128
- // E.g., hide the deck and just move the solo article?
129
- if (layoutMode === 'deck' && firstAttendedId) {
130
- // setTimeout(() => {
131
- // const el = deckRef.current?.querySelector(`article[data-attendable-id="${firstAttendedId}"]`);
132
- // el?.scrollIntoView({ behavior: 'smooth', inline: 'center' });
133
- // }, 0);
134
- }
135
- }, [layoutMode, firstAttendedId]);
136
-
137
- // TODO(burdon): Needs cleaning up.
138
- const parts: LayoutEntry[] = useMemo(() => {
139
- const parts = [...(layoutParts.main ?? [])];
140
- for (const part of layoutParts.solo ?? []) {
141
- if (!parts.find((entry) => entry.id === part.id)) {
142
- parts.push(part);
143
- }
117
+ const padding = useMemo(() => {
118
+ if (layoutMode === 'deck' && overscroll === 'centering') {
119
+ return calculateOverscroll(layoutParts.main, plankSizing, sidebarOpen, complementarySidebarOpen);
144
120
  }
145
- return parts;
146
- }, [layoutParts.main, layoutParts.solo]);
147
-
148
- const padding =
149
- layoutMode === 'deck' && overscroll === 'centering'
150
- ? calculateOverscroll(layoutParts.main, plankSizing, sidebarOpen, complementarySidebarOpen)
151
- : {};
121
+ return {};
122
+ }, [layoutMode, overscroll, layoutParts.main, plankSizing, sidebarOpen, complementarySidebarOpen]);
152
123
 
153
124
  if (layoutMode === 'fullscreen') {
154
125
  return <Fullscreen id={fullScreenSlug} />;
@@ -167,31 +138,22 @@ export const DeckLayout = ({
167
138
  }
168
139
  }}
169
140
  >
170
- {/* TODO(burdon): Factor out hook to set document title. */}
171
- <ActiveNode id={firstAttendedId} />
141
+ <ActiveNode />
172
142
 
173
143
  <Main.Root
174
144
  navigationSidebarOpen={context.sidebarOpen}
175
145
  onNavigationSidebarOpenChange={(next) => (context.sidebarOpen = next)}
176
- {...(complementarySidebarOpen !== null && {
177
- complementarySidebarOpen: /* complementaryAvailable && */ context.complementarySidebarOpen as boolean,
178
- onComplementarySidebarOpenChange: (next) => (context.complementarySidebarOpen = next),
179
- })}
146
+ complementarySidebarOpen={context.complementarySidebarOpen}
147
+ onComplementarySidebarOpenChange={(next) => (context.complementarySidebarOpen = next)}
180
148
  >
181
149
  {/* Notch */}
182
150
  <Main.Notch classNames='z-[21]'>
183
151
  <Surface role='notch-start' />
184
- <Button
185
- // disabled={!sidebarAvailable}
186
- onClick={() => (context.sidebarOpen = !context.sidebarOpen)}
187
- variant='ghost'
188
- classNames='p-1'
189
- >
152
+ <Button onClick={() => (context.sidebarOpen = !context.sidebarOpen)} variant='ghost' classNames='p-1'>
190
153
  <span className='sr-only'>{t('open navigation sidebar label')}</span>
191
154
  <MenuIcon weight='light' className={getSize(5)} />
192
155
  </Button>
193
156
  <Button
194
- // disabled={!complementaryAvailable}
195
157
  onClick={() => (context.complementarySidebarOpen = !context.complementarySidebarOpen)}
196
158
  variant='ghost'
197
159
  classNames='p-1'
@@ -203,38 +165,51 @@ export const DeckLayout = ({
203
165
  </Main.Notch>
204
166
 
205
167
  {/* Left sidebar. */}
206
- <Sidebar attention={attention} layoutParts={layoutParts} />
168
+ <Sidebar layoutParts={layoutParts} />
207
169
 
208
170
  {/* Right sidebar. */}
209
- <ComplementarySidebar id={complementarySlug} layoutParts={layoutParts} flatDeck={flatDeck} />
171
+ <ComplementarySidebar panel={layoutParts.complementary?.[0].id} flatDeck={flatDeck} />
210
172
 
211
173
  {/* Dialog overlay to dismiss dialogs. */}
212
174
  <Main.Overlay />
213
175
 
214
176
  {/* No content. */}
215
- {parts.length === 0 && (
177
+ {isEmpty && (
216
178
  <Main.Content handlesFocus>
217
179
  <ContentEmpty />
218
180
  </Main.Content>
219
181
  )}
220
182
 
221
183
  {/* Solo/deck mode. */}
222
- {parts.length !== 0 && (
184
+ {!isEmpty && (
223
185
  <Main.Content bounce classNames='grid block-end-[--statusbar-size]' handlesFocus>
224
186
  <div role='none' className='relative'>
225
187
  <Deck.Root
226
188
  style={padding}
227
- classNames={[!flatDeck && 'bg-deck', 'absolute inset-0', slots?.wallpaper?.classNames]}
189
+ classNames={[
190
+ !flatDeck && 'bg-deck',
191
+ mainPaddingTransitions,
192
+ 'absolute inset-0',
193
+ slots?.wallpaper?.classNames,
194
+ ]}
228
195
  solo={layoutMode === 'solo'}
229
196
  onScroll={handleScroll}
230
197
  ref={deckRef}
231
198
  >
232
- {parts.map((layoutEntry) => (
199
+ <Plank
200
+ entry={layoutParts.solo?.[0] ?? { id: 'unknown-solo' }}
201
+ layoutParts={layoutParts}
202
+ part='solo'
203
+ layoutMode={layoutMode}
204
+ flatDeck={flatDeck}
205
+ searchEnabled={!!searchPlugin}
206
+ />
207
+ {layoutParts.main?.map((layoutEntry) => (
233
208
  <Plank
234
209
  key={layoutEntry.id}
235
210
  entry={layoutEntry}
236
211
  layoutParts={layoutParts}
237
- part={layoutMode === 'solo' && layoutEntry.id === layoutParts.solo?.[0]?.id ? 'solo' : 'main'}
212
+ part='main'
238
213
  layoutMode={layoutMode}
239
214
  flatDeck={flatDeck}
240
215
  searchEnabled={!!searchPlugin}
@@ -245,15 +220,8 @@ export const DeckLayout = ({
245
220
  </Main.Content>
246
221
  )}
247
222
 
248
- <StatusBar />
249
-
250
- {/* Help hints. */}
251
- {/* TODO(burdon): Need to make room for this in status bar. */}
252
- {showHintsFooter && (
253
- <div className='fixed bottom-0 left-0 right-0 h-[32px] z-[1] flex justify-center'>
254
- <Surface role='hints' limit={1} />
255
- </div>
256
- )}
223
+ {/* Footer status. */}
224
+ <StatusBar showHints={showHints} />
257
225
 
258
226
  {/* Global popovers. */}
259
227
  <Popover.Portal>
@@ -2,157 +2,160 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Placeholder } from '@phosphor-icons/react';
6
- import React, { Fragment, useEffect } from 'react';
5
+ import React, { Fragment, memo, useEffect, useMemo } from 'react';
7
6
 
8
7
  import {
9
8
  LayoutAction,
10
9
  NavigationAction,
11
- SLUG_COLLECTION_INDICATOR,
12
10
  SLUG_PATH_SEPARATOR,
13
11
  Surface,
14
12
  useIntentDispatcher,
15
- indexInPart,
16
- partLength,
17
- type LayoutParts,
18
- type LayoutPart,
19
- type LayoutEntry,
13
+ type LayoutCoordinate,
20
14
  } from '@dxos/app-framework';
21
15
  import { type Node, useGraph } from '@dxos/plugin-graph';
22
- import { Popover, toLocalizedString, useMediaQuery, useTranslation } from '@dxos/react-ui';
23
- import { PlankHeading, plankHeadingIconProps } from '@dxos/react-ui-deck';
16
+ import { Icon, Popover, toLocalizedString, useMediaQuery, useTranslation } from '@dxos/react-ui';
17
+ import { PlankHeading, type PlankHeadingAction } from '@dxos/react-ui-deck';
24
18
  import { TextTooltip } from '@dxos/react-ui-text-tooltip';
25
19
 
26
20
  import { DECK_PLUGIN } from '../../meta';
27
21
 
28
- export const NodePlankHeading = ({
29
- node,
30
- id,
31
- layoutParts,
32
- layoutPart,
33
- // TODO(wittjosiah): Unused?
34
- layoutEntry,
35
- popoverAnchorId,
36
- pending,
37
- flatDeck,
38
- }: {
22
+ export type NodePlankHeadingProps = {
23
+ coordinate: LayoutCoordinate;
39
24
  node?: Node;
40
- id?: string;
41
- layoutParts?: LayoutParts;
42
- layoutPart?: LayoutPart;
43
- layoutEntry?: LayoutEntry;
25
+ canIncrementStart?: boolean;
26
+ canIncrementEnd?: boolean;
44
27
  popoverAnchorId?: string;
45
28
  pending?: boolean;
46
29
  flatDeck?: boolean;
47
- }) => {
48
- const { t } = useTranslation(DECK_PLUGIN);
49
- const { graph } = useGraph();
50
- const Icon = node?.properties?.icon ?? Placeholder;
51
- const label = pending
52
- ? t('pending heading')
53
- : toLocalizedString(node?.properties?.label ?? ['plank heading fallback label', { ns: DECK_PLUGIN }], t);
54
- const dispatch = useIntentDispatcher();
55
- const ActionRoot = node && popoverAnchorId === `dxos.org/ui/${DECK_PLUGIN}/${node.id}` ? Popover.Anchor : Fragment;
56
- const [isNotMobile] = useMediaQuery('md');
57
-
58
- useEffect(() => {
59
- const frame = requestAnimationFrame(() => {
60
- // Load actions for the node.
61
- node && graph.actions(node);
62
- });
30
+ actions?: PlankHeadingAction[];
31
+ };
63
32
 
64
- return () => cancelAnimationFrame(frame);
65
- }, [node]);
33
+ export const NodePlankHeading = memo(
34
+ ({
35
+ coordinate,
36
+ node,
37
+ canIncrementStart,
38
+ canIncrementEnd,
39
+ popoverAnchorId,
40
+ pending,
41
+ flatDeck,
42
+ actions = [],
43
+ }: NodePlankHeadingProps) => {
44
+ const { t } = useTranslation(DECK_PLUGIN);
45
+ const { graph } = useGraph();
46
+ const icon = node?.properties?.icon ?? 'ph--placeholder--regular';
47
+ const label = pending
48
+ ? t('pending heading')
49
+ : toLocalizedString(node?.properties?.label ?? ['plank heading fallback label', { ns: DECK_PLUGIN }], t);
50
+ const dispatch = useIntentDispatcher();
51
+ const ActionRoot = node && popoverAnchorId === `dxos.org/ui/${DECK_PLUGIN}/${node.id}` ? Popover.Anchor : Fragment;
52
+ const [isNotMobile] = useMediaQuery('md');
66
53
 
67
- // NOTE(Zan): Node ids may now contain a path like `${space}:${id}~comments`
68
- const attendableId = id?.split(SLUG_PATH_SEPARATOR).at(0);
54
+ useEffect(() => {
55
+ const frame = requestAnimationFrame(() => {
56
+ // Load actions for the node.
57
+ node && graph.actions(node);
58
+ });
69
59
 
70
- const layoutCoordinate = layoutPart !== undefined && id !== undefined ? { part: layoutPart, entryId: id } : undefined;
71
- const index = indexInPart(layoutParts, layoutCoordinate);
72
- const length = partLength(layoutParts, layoutPart);
60
+ return () => cancelAnimationFrame(frame);
61
+ }, [node]);
73
62
 
74
- const canIncrementStart =
75
- layoutPart === 'main' && index !== undefined && index > 0 && length !== undefined && length > 1;
76
- const canIncrementEnd = layoutPart === 'main' && index !== undefined && index < length - 1 && length !== undefined;
63
+ const layoutPart = coordinate.part;
64
+ // NOTE(Zan): Node ids may now contain a path like `${space}:${id}~comments`
65
+ const attendableId = coordinate.entryId.split(SLUG_PATH_SEPARATOR).at(0);
66
+ const capabilities = useMemo(
67
+ () => ({
68
+ solo: (layoutPart === 'solo' || layoutPart === 'main') && isNotMobile,
69
+ incrementStart: canIncrementStart,
70
+ incrementEnd: canIncrementEnd,
71
+ }),
72
+ [isNotMobile, layoutPart, canIncrementStart, canIncrementEnd],
73
+ );
77
74
 
78
- return (
79
- <PlankHeading.Root {...((layoutPart !== 'main' || !flatDeck) && { classNames: 'pie-1 border-b border-separator' })}>
80
- <ActionRoot>
81
- {node ? (
82
- <PlankHeading.ActionsMenu
83
- Icon={Icon}
75
+ return (
76
+ <PlankHeading.Root
77
+ {...((layoutPart !== 'main' || !flatDeck) && { classNames: 'pie-1 border-b border-separator' })}
78
+ >
79
+ <ActionRoot>
80
+ {node ? (
81
+ <PlankHeading.ActionsMenu
82
+ icon={icon}
83
+ related={layoutPart === 'complementary'}
84
+ attendableId={attendableId}
85
+ triggerLabel={t('actions menu label')}
86
+ actions={[actions, graph.actions(node)].filter((a) => a.length > 0)}
87
+ onAction={(action) =>
88
+ typeof action.data === 'function' && action.data?.({ node: action as Node, caller: DECK_PLUGIN })
89
+ }
90
+ >
91
+ <Surface role='menu-footer' data={{ object: node.data }} />
92
+ </PlankHeading.ActionsMenu>
93
+ ) : (
94
+ <PlankHeading.Button>
95
+ <span className='sr-only'>{label}</span>
96
+ <Icon icon={icon} size={5} />
97
+ </PlankHeading.Button>
98
+ )}
99
+ </ActionRoot>
100
+ <TextTooltip text={label} onlyWhenTruncating>
101
+ <PlankHeading.Label
84
102
  attendableId={attendableId}
85
- triggerLabel={t('actions menu label')}
86
- actions={graph.actions(node)}
87
- onAction={(action) =>
88
- typeof action.data === 'function' && action.data?.({ node: action as Node, caller: DECK_PLUGIN })
89
- }
103
+ related={layoutPart === 'complementary'}
104
+ {...(pending && { classNames: 'text-description' })}
90
105
  >
91
- <Surface role='menu-footer' data={{ object: node.data }} />
92
- </PlankHeading.ActionsMenu>
93
- ) : (
94
- <PlankHeading.Button>
95
- <span className='sr-only'>{label}</span>
96
- <Icon {...plankHeadingIconProps} />
97
- </PlankHeading.Button>
106
+ {label}
107
+ </PlankHeading.Label>
108
+ </TextTooltip>
109
+ {node && layoutPart !== 'complementary' && (
110
+ // TODO(Zan): What are we doing with layout coordinate here?
111
+ <Surface role='navbar-end' direction='inline-reverse' data={{ object: node.data }} />
98
112
  )}
99
- </ActionRoot>
100
- <TextTooltip text={label} onlyWhenTruncating>
101
- <PlankHeading.Label attendableId={node?.id} {...(pending && { classNames: 'text-description' })}>
102
- {label}
103
- </PlankHeading.Label>
104
- </TextTooltip>
105
- {node && layoutPart !== 'complementary' && (
106
- // TODO(Zan): What are we doing with layout coordinate here?
107
- <Surface role='navbar-end' direction='inline-reverse' data={{ object: node.data }} />
108
- )}
109
- {/* NOTE(thure): Pinning & unpinning are temporarily disabled */}
110
- <PlankHeading.Controls
111
- capabilities={{
112
- solo: (layoutPart === 'solo' || layoutPart === 'main') && isNotMobile,
113
- incrementStart: canIncrementStart,
114
- incrementEnd: canIncrementEnd,
115
- }}
116
- isSolo={layoutPart === 'solo'}
117
- onClick={(eventType) => {
118
- if (!layoutPart) {
119
- return;
120
- }
121
-
122
- if (eventType === 'solo') {
123
- return dispatch([
124
- {
125
- action: NavigationAction.ADJUST,
126
- data: { type: eventType, layoutCoordinate: { part: 'main', entryId: id } },
127
- },
128
- ]);
129
- }
113
+ {/* NOTE(thure): Pinning & unpinning are temporarily disabled */}
114
+ <PlankHeading.Controls
115
+ capabilities={capabilities}
116
+ isSolo={layoutPart === 'solo'}
117
+ onClick={(eventType) => {
118
+ if (!layoutPart) {
119
+ return;
120
+ }
130
121
 
131
- // TODO(Zan): Update this to use the new layout actions.
132
- return dispatch(
133
- eventType === 'close'
134
- ? layoutPart === 'complementary'
135
- ? {
136
- action: LayoutAction.SET_LAYOUT,
137
- data: {
138
- element: 'complementary',
139
- state: false,
140
- },
141
- }
142
- : {
143
- action: NavigationAction.CLOSE,
144
- data: {
145
- activeParts: {
146
- complementary: [`${id}${SLUG_PATH_SEPARATOR}comments${SLUG_COLLECTION_INDICATOR}`],
147
- [layoutPart]: [id],
148
- },
122
+ // TODO(Zan): Update this to use the new layout actions.
123
+ if (eventType === 'solo') {
124
+ return dispatch([
125
+ {
126
+ action: NavigationAction.ADJUST,
127
+ data: { type: eventType, layoutCoordinate: { part: 'main', entryId: coordinate.entryId } },
128
+ },
129
+ ]);
130
+ } else if (eventType === 'close') {
131
+ if (layoutPart === 'complementary') {
132
+ return dispatch({
133
+ action: LayoutAction.SET_LAYOUT,
134
+ data: {
135
+ element: 'complementary',
136
+ state: false,
137
+ },
138
+ });
139
+ } else {
140
+ return dispatch({
141
+ action: NavigationAction.CLOSE,
142
+ data: {
143
+ activeParts: {
144
+ [layoutPart]: [coordinate.entryId],
149
145
  },
150
- }
151
- : { action: NavigationAction.ADJUST, data: { type: eventType, layoutCoordinate } },
152
- );
153
- }}
154
- close={layoutCoordinate?.part === 'complementary' ? 'minify-end' : true}
155
- />
156
- </PlankHeading.Root>
157
- );
158
- };
146
+ },
147
+ });
148
+ }
149
+ } else {
150
+ return dispatch({
151
+ action: NavigationAction.ADJUST,
152
+ data: { type: eventType, layoutCoordinate: coordinate },
153
+ });
154
+ }
155
+ }}
156
+ close={layoutPart === 'complementary' ? 'minify-end' : true}
157
+ />
158
+ </PlankHeading.Root>
159
+ );
160
+ },
161
+ );