@dxos/plugin-deck 0.8.1-staging.391c573 → 0.8.1-staging.5be625a

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 (75) hide show
  1. package/dist/lib/browser/{app-graph-builder-IYHAGFA3.mjs → app-graph-builder-K4KVSHNT.mjs} +3 -3
  2. package/dist/lib/browser/{check-app-scheme-S3EYUPMF.mjs → check-app-scheme-6SS6I3RN.mjs} +2 -2
  3. package/dist/lib/browser/{chunk-N7TEPFVR.mjs → chunk-2WTHB3TG.mjs} +1 -1
  4. package/dist/lib/browser/{chunk-N7TEPFVR.mjs.map → chunk-2WTHB3TG.mjs.map} +2 -2
  5. package/dist/lib/browser/{chunk-FYKBOM3C.mjs → chunk-7X43JKZG.mjs} +33 -3
  6. package/dist/lib/browser/chunk-7X43JKZG.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-Z23S33X6.mjs → chunk-MWUT66KV.mjs} +164 -63
  8. package/dist/lib/browser/chunk-MWUT66KV.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-NSNAYFAX.mjs +24 -0
  10. package/dist/lib/browser/{chunk-YCKJNTKG.mjs → chunk-RZLH5F56.mjs} +2 -2
  11. package/dist/lib/browser/{chunk-22AQ5IVX.mjs → chunk-WCNPMAR4.mjs} +2 -2
  12. package/dist/lib/browser/index.mjs +5 -4
  13. package/dist/lib/browser/index.mjs.map +2 -2
  14. package/dist/lib/browser/{intent-resolver-P5BVUQKU.mjs → intent-resolver-MEBOMCYI.mjs} +46 -17
  15. package/dist/lib/browser/intent-resolver-MEBOMCYI.mjs.map +7 -0
  16. package/dist/lib/browser/meta.json +1 -1
  17. package/dist/lib/browser/{react-root-EP4UF3KA.mjs → react-root-USUAHDML.mjs} +7 -7
  18. package/dist/lib/browser/{react-surface-5B3RLJCD.mjs → react-surface-TQG4YYES.mjs} +7 -7
  19. package/dist/lib/browser/{settings-X3P2HKQJ.mjs → settings-DYS3FFMN.mjs} +3 -3
  20. package/dist/lib/browser/{state-2MOTLKVR.mjs → state-DRRCGMU2.mjs} +7 -11
  21. package/dist/lib/browser/state-DRRCGMU2.mjs.map +7 -0
  22. package/dist/lib/browser/tools-NDEUSO4R.mjs +78 -0
  23. package/dist/lib/browser/tools-NDEUSO4R.mjs.map +7 -0
  24. package/dist/lib/browser/types.mjs +10 -4
  25. package/dist/lib/browser/{url-handler-MVHTKUYA.mjs → url-handler-4BCN7AYC.mjs} +7 -9
  26. package/dist/lib/browser/url-handler-4BCN7AYC.mjs.map +7 -0
  27. package/dist/types/src/capabilities/capabilities.d.ts +26 -2
  28. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  29. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  30. package/dist/types/src/capabilities/state.d.ts +13 -1
  31. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  32. package/dist/types/src/capabilities/tools.d.ts +1 -0
  33. package/dist/types/src/capabilities/tools.d.ts.map +1 -1
  34. package/dist/types/src/capabilities/url-handler.d.ts.map +1 -1
  35. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
  36. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts +6 -2
  37. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts.map +1 -1
  38. package/dist/types/src/components/DeckLayout/Plank.d.ts +4 -4
  39. package/dist/types/src/components/DeckLayout/Plank.d.ts.map +1 -1
  40. package/dist/types/src/components/DeckLayout/PlankControls.d.ts +6 -1
  41. package/dist/types/src/components/DeckLayout/PlankControls.d.ts.map +1 -1
  42. package/dist/types/src/meta.d.ts +2 -5
  43. package/dist/types/src/meta.d.ts.map +1 -1
  44. package/dist/types/src/translations.d.ts +1 -0
  45. package/dist/types/src/translations.d.ts.map +1 -1
  46. package/dist/types/src/types.d.ts +31 -0
  47. package/dist/types/src/types.d.ts.map +1 -1
  48. package/package.json +29 -29
  49. package/src/capabilities/intent-resolver.ts +29 -3
  50. package/src/capabilities/state.ts +2 -9
  51. package/src/capabilities/tools.ts +34 -22
  52. package/src/capabilities/url-handler.ts +2 -8
  53. package/src/components/DeckLayout/DeckLayout.tsx +31 -8
  54. package/src/components/DeckLayout/NodePlankHeading.tsx +49 -29
  55. package/src/components/DeckLayout/Plank.tsx +183 -111
  56. package/src/components/DeckLayout/PlankControls.tsx +34 -3
  57. package/src/meta.ts +2 -2
  58. package/src/translations.ts +1 -0
  59. package/src/types.ts +29 -0
  60. package/dist/lib/browser/chunk-FYKBOM3C.mjs.map +0 -7
  61. package/dist/lib/browser/chunk-IZ5RPJ6T.mjs +0 -24
  62. package/dist/lib/browser/chunk-Z23S33X6.mjs.map +0 -7
  63. package/dist/lib/browser/intent-resolver-P5BVUQKU.mjs.map +0 -7
  64. package/dist/lib/browser/state-2MOTLKVR.mjs.map +0 -7
  65. package/dist/lib/browser/tools-64LXGLYR.mjs +0 -59
  66. package/dist/lib/browser/tools-64LXGLYR.mjs.map +0 -7
  67. package/dist/lib/browser/url-handler-MVHTKUYA.mjs.map +0 -7
  68. /package/dist/lib/browser/{app-graph-builder-IYHAGFA3.mjs.map → app-graph-builder-K4KVSHNT.mjs.map} +0 -0
  69. /package/dist/lib/browser/{check-app-scheme-S3EYUPMF.mjs.map → check-app-scheme-6SS6I3RN.mjs.map} +0 -0
  70. /package/dist/lib/browser/{chunk-IZ5RPJ6T.mjs.map → chunk-NSNAYFAX.mjs.map} +0 -0
  71. /package/dist/lib/browser/{chunk-YCKJNTKG.mjs.map → chunk-RZLH5F56.mjs.map} +0 -0
  72. /package/dist/lib/browser/{chunk-22AQ5IVX.mjs.map → chunk-WCNPMAR4.mjs.map} +0 -0
  73. /package/dist/lib/browser/{react-root-EP4UF3KA.mjs.map → react-root-USUAHDML.mjs.map} +0 -0
  74. /package/dist/lib/browser/{react-surface-5B3RLJCD.mjs.map → react-surface-TQG4YYES.mjs.map} +0 -0
  75. /package/dist/lib/browser/{settings-X3P2HKQJ.mjs.map → settings-DYS3FFMN.mjs.map} +0 -0
@@ -2,7 +2,16 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { type KeyboardEvent, memo, useCallback, useLayoutEffect, useMemo, useRef } from 'react';
5
+ import React, {
6
+ Fragment,
7
+ type KeyboardEvent,
8
+ memo,
9
+ type PropsWithChildren,
10
+ useCallback,
11
+ useLayoutEffect,
12
+ useMemo,
13
+ useRef,
14
+ } from 'react';
6
15
 
7
16
  import {
8
17
  createIntent,
@@ -17,133 +26,196 @@ import { useAttendableAttributes } from '@dxos/react-ui-attention';
17
26
  import { StackItem, railGridHorizontal } from '@dxos/react-ui-stack';
18
27
  import { mainIntrinsicSize, mx } from '@dxos/react-ui-theme';
19
28
 
20
- import { NodePlankHeading, type NodePlankHeadingProps } from './NodePlankHeading';
29
+ import { NodePlankHeading } from './NodePlankHeading';
21
30
  import { PlankContentError, PlankError } from './PlankError';
22
31
  import { PlankLoading } from './PlankLoading';
23
32
  import { DeckCapabilities } from '../../capabilities';
24
33
  import { useNode, useMainSize } from '../../hooks';
25
- import { DeckAction, type LayoutMode } from '../../types';
34
+ import { DeckAction, type LayoutMode, type Part, type ResolvedPart, surfaceVariantSeparator } from '../../types';
26
35
 
27
36
  const UNKNOWN_ID = 'unknown_id';
28
37
 
29
38
  export type PlankProps = {
30
39
  id?: string;
31
- part: NodePlankHeadingProps['part'];
40
+ companionId?: string;
41
+ part: Part;
32
42
  path?: string[];
33
43
  order?: number;
34
44
  active?: string[];
35
45
  layoutMode: LayoutMode;
36
46
  };
37
47
 
38
- export const Plank = memo(({ id = UNKNOWN_ID, part, path, order, active, layoutMode }: PlankProps) => {
39
- const { dispatchPromise: dispatch } = useIntentDispatcher();
40
- const { deck, popoverAnchorId, scrollIntoView } = useCapability(DeckCapabilities.DeckState);
41
- const { graph } = useAppGraph();
42
- const node = useNode(graph, id);
43
- const rootElement = useRef<HTMLDivElement | null>(null);
44
- const canResize = layoutMode === 'deck';
45
- const Root = part === 'solo' ? 'article' : StackItem.Root;
46
-
47
- const attendableAttrs = useAttendableAttributes(id);
48
- const index = active ? active.findIndex((entryId) => entryId === id) : 0;
49
- const length = active?.length ?? 1;
50
- const canIncrementStart = active && index !== undefined && index > 0 && length !== undefined && length > 1;
51
- const canIncrementEnd = active && index !== undefined && index < length - 1 && length !== undefined;
52
-
53
- const key = id.split('+')[0];
54
- const size = deck.plankSizing[key] as number | undefined;
55
- const setSize = useCallback(
56
- debounce((nextSize: number) => {
57
- return dispatch(createIntent(DeckAction.UpdatePlankSize, { id: key, size: nextSize }));
58
- }, 200),
59
- [dispatch, key],
60
- );
61
-
62
- // TODO(thure): Tabster’s focus group should handle moving focus to Main, but something is blocking it.
63
- const handleKeyDown = useCallback((event: KeyboardEvent) => {
64
- if (event.target === event.currentTarget && event.key === 'Escape') {
65
- rootElement.current?.closest('main')?.focus();
66
- }
67
- }, []);
68
-
69
- useLayoutEffect(() => {
70
- if (scrollIntoView === id) {
71
- // TODO(wittjosiah): When focused on page load, the focus is always visible.
72
- // Forcing focus to something smaller than the plank prevents large focus ring in the interim.
73
- const focusable = rootElement.current?.querySelector('button') || rootElement.current;
74
- focusable?.focus({ preventScroll: true });
75
- layoutMode === 'deck' && focusable?.scrollIntoView({ behavior: 'smooth', inline: 'center' });
76
- // Clear the scroll into view state once it has been actioned.
77
- void dispatch(createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: undefined }));
78
- }
79
- }, [id, scrollIntoView, layoutMode]);
80
-
81
- const isSolo = layoutMode === 'solo' && part === 'solo';
82
- const isAttendable = isSolo || (layoutMode === 'deck' && part === 'deck');
48
+ type PlankImplProps = Omit<PlankProps, 'companionId' | 'part'> & {
49
+ part: ResolvedPart;
50
+ surfaceVariant?: string;
51
+ companioned?: 'primary' | 'companion';
52
+ primaryId?: string;
53
+ };
83
54
 
55
+ const PlankImpl = memo(
56
+ ({
57
+ id = UNKNOWN_ID,
58
+ part,
59
+ path,
60
+ order,
61
+ active,
62
+ layoutMode,
63
+ surfaceVariant,
64
+ companioned,
65
+ primaryId,
66
+ }: PlankImplProps) => {
67
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
68
+ const { deck, popoverAnchorId, scrollIntoView } = useCapability(DeckCapabilities.DeckState);
69
+ const { graph } = useAppGraph();
70
+ const node = useNode(graph, id);
71
+ const rootElement = useRef<HTMLDivElement | null>(null);
72
+ const canResize = layoutMode === 'deck';
73
+ const Root = part.startsWith('solo') ? 'article' : StackItem.Root;
74
+
75
+ const attendableAttrs = useAttendableAttributes(id);
76
+ const index = active ? active.findIndex((entryId) => entryId === id) : 0;
77
+ const length = active?.length ?? 1;
78
+ const canIncrementStart = active && index !== undefined && index > 0 && length !== undefined && length > 1;
79
+ const canIncrementEnd = active && index !== undefined && index < length - 1 && length !== undefined;
80
+
81
+ const sizeKey = `${id.split('+')[0]}${surfaceVariant ? `${surfaceVariantSeparator}${surfaceVariant}` : ''}`;
82
+ const size = deck.plankSizing[sizeKey] as number | undefined;
83
+ const setSize = useCallback(
84
+ debounce((nextSize: number) => {
85
+ return dispatch(createIntent(DeckAction.UpdatePlankSize, { id: sizeKey, size: nextSize }));
86
+ }, 200),
87
+ [dispatch, sizeKey],
88
+ );
89
+
90
+ // TODO(thure): Tabster’s focus group should handle moving focus to Main, but something is blocking it.
91
+ const handleKeyDown = useCallback((event: KeyboardEvent) => {
92
+ if (event.target === event.currentTarget && event.key === 'Escape') {
93
+ rootElement.current?.closest('main')?.focus();
94
+ }
95
+ }, []);
96
+
97
+ useLayoutEffect(() => {
98
+ if (scrollIntoView === id) {
99
+ // TODO(wittjosiah): When focused on page load, the focus is always visible.
100
+ // Forcing focus to something smaller than the plank prevents large focus ring in the interim.
101
+ const focusable = rootElement.current?.querySelector('button') || rootElement.current;
102
+ focusable?.focus({ preventScroll: true });
103
+ layoutMode === 'deck' && focusable?.scrollIntoView({ behavior: 'smooth', inline: 'center' });
104
+ // Clear the scroll into view state once it has been actioned.
105
+ void dispatch(createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: undefined }));
106
+ }
107
+ }, [id, scrollIntoView, layoutMode]);
108
+
109
+ const isSolo = layoutMode === 'solo' && part === 'solo';
110
+ const isAttendable =
111
+ (layoutMode === 'solo' && part.startsWith('solo')) || (layoutMode === 'deck' && part === 'deck');
112
+
113
+ const sizeAttrs = useMainSize();
114
+
115
+ const data = useMemo(
116
+ () =>
117
+ node && {
118
+ subject: node.data,
119
+ variant: surfaceVariant,
120
+ path,
121
+ popoverAnchorId,
122
+ },
123
+ [node, node?.data, path, popoverAnchorId, surfaceVariant],
124
+ );
125
+
126
+ // TODO(wittjosiah): Change prop to accept a component.
127
+ const placeholder = useMemo(() => <PlankLoading />, []);
128
+
129
+ const className = mx(
130
+ 'attention-surface relative',
131
+ isSolo && mainIntrinsicSize,
132
+ isSolo && railGridHorizontal,
133
+ isSolo && 'absolute inset-0',
134
+ part.startsWith('solo') && 'grid',
135
+ part === 'deck' && (companioned === 'companion' ? '!border-separator border-ie' : '!border-separator border-li'),
136
+ part.startsWith('solo-') && 'row-span-2 min-is-0',
137
+ part === 'solo-companion' && '!border-separator border-is',
138
+ );
139
+
140
+ return (
141
+ <Root
142
+ ref={rootElement}
143
+ data-testid='deck.plank'
144
+ tabIndex={0}
145
+ {...(part.startsWith('solo')
146
+ ? ({ ...sizeAttrs, className } as any)
147
+ : {
148
+ item: { id },
149
+ size,
150
+ onSizeChange: setSize,
151
+ classNames: className,
152
+ order,
153
+ role: 'article',
154
+ })}
155
+ {...(isAttendable ? attendableAttrs : {})}
156
+ onKeyDown={handleKeyDown}
157
+ >
158
+ {node ? (
159
+ <>
160
+ <NodePlankHeading
161
+ id={id}
162
+ part={part.startsWith('solo-') ? 'solo' : part}
163
+ node={node}
164
+ canIncrementStart={canIncrementStart}
165
+ canIncrementEnd={canIncrementEnd}
166
+ popoverAnchorId={popoverAnchorId}
167
+ companioned={companioned}
168
+ primaryId={primaryId}
169
+ surfaceVariant={surfaceVariant}
170
+ />
171
+ <Surface
172
+ key={node.id}
173
+ role='article'
174
+ data={data}
175
+ limit={1}
176
+ fallback={PlankContentError}
177
+ placeholder={placeholder}
178
+ />
179
+ </>
180
+ ) : (
181
+ <PlankError id={id} part={part} />
182
+ )}
183
+ {canResize && <StackItem.ResizeHandle />}
184
+ </Root>
185
+ );
186
+ },
187
+ );
188
+
189
+ const SplitFrame = ({ children }: PropsWithChildren<{}>) => {
84
190
  const sizeAttrs = useMainSize();
85
-
86
- const data = useMemo(
87
- () =>
88
- node && {
89
- subject: node.data,
90
- path,
91
- popoverAnchorId,
92
- },
93
- [node, node?.data, path, popoverAnchorId],
94
- );
95
-
96
- // TODO(wittjosiah): Change prop to accept a component.
97
- const placeholder = useMemo(() => <PlankLoading />, []);
98
-
99
- const className = mx(
100
- 'attention-surface relative',
101
- isSolo && mainIntrinsicSize,
102
- isSolo && railGridHorizontal,
103
- isSolo ? 'grid absolute inset-0' : '!border-separator border-li',
104
- );
105
-
106
191
  return (
107
- <Root
108
- ref={rootElement}
109
- data-testid='deck.plank'
110
- tabIndex={0}
111
- {...(part === 'solo'
112
- ? ({ ...sizeAttrs, className } as any)
113
- : {
114
- item: { id },
115
- size,
116
- onSizeChange: setSize,
117
- classNames: className,
118
- order,
119
- role: 'article',
120
- })}
121
- {...(isAttendable ? attendableAttrs : {})}
122
- onKeyDown={handleKeyDown}
192
+ <div
193
+ role='none'
194
+ className={mx('grid grid-cols-[1fr_1fr] absolute inset-0', railGridHorizontal, mainIntrinsicSize)}
195
+ {...sizeAttrs}
123
196
  >
124
- {node ? (
125
- <>
126
- <NodePlankHeading
127
- id={id}
128
- part={part}
129
- node={node}
130
- canIncrementStart={canIncrementStart}
131
- canIncrementEnd={canIncrementEnd}
132
- popoverAnchorId={popoverAnchorId}
133
- />
134
- <Surface
135
- key={node.id}
136
- role='article'
137
- data={data}
138
- limit={1}
139
- fallback={PlankContentError}
140
- placeholder={placeholder}
141
- />
142
- </>
143
- ) : (
144
- <PlankError id={id} part={part} />
145
- )}
146
- {canResize && <StackItem.ResizeHandle />}
147
- </Root>
197
+ {children}
198
+ </div>
148
199
  );
149
- });
200
+ };
201
+
202
+ export const Plank = (props: PlankProps) => {
203
+ if (props.companionId) {
204
+ const Root = props.part === 'solo' ? SplitFrame : Fragment;
205
+ return (
206
+ <Root>
207
+ <PlankImpl {...props} {...(props.part === 'solo' ? { part: 'solo-primary' } : {})} companioned='primary' />
208
+ <PlankImpl
209
+ {...props}
210
+ {...(props.companionId.startsWith(surfaceVariantSeparator)
211
+ ? { surfaceVariant: props.companionId.substring(2) }
212
+ : { id: props.companionId, primaryId: props.id })}
213
+ {...(props.part === 'solo' ? { part: 'solo-companion' } : { order: props.order! + 1 })}
214
+ companioned='companion'
215
+ />
216
+ </Root>
217
+ );
218
+ } else {
219
+ return <PlankImpl {...props} />;
220
+ }
221
+ };
@@ -2,8 +2,10 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { forwardRef } from 'react';
5
+ import React, { forwardRef, useCallback } from 'react';
6
6
 
7
+ import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
8
+ import { invariant } from '@dxos/invariant';
7
9
  import {
8
10
  Button,
9
11
  ButtonGroup,
@@ -15,7 +17,7 @@ import {
15
17
  } from '@dxos/react-ui';
16
18
 
17
19
  import { DECK_PLUGIN } from '../../meta';
18
- import { type DeckAction } from '../../types';
20
+ import { DeckAction } from '../../types';
19
21
 
20
22
  export type PlankControlHandler = (event: DeckAction.PartAdjustment) => void;
21
23
 
@@ -50,6 +52,34 @@ const PlankControl = ({ icon, label, ...props }: Omit<ButtonProps, 'children'> &
50
52
  );
51
53
  };
52
54
 
55
+ const plankControlSpacing = 'pli-2 plb-3';
56
+
57
+ type PlankComplimentControlsProps = {
58
+ primary?: string;
59
+ };
60
+
61
+ export const PlankCompanionControls = forwardRef<HTMLDivElement, PlankComplimentControlsProps>(
62
+ ({ primary }, forwardedRef) => {
63
+ const { t } = useTranslation(DECK_PLUGIN);
64
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
65
+ const handleCloseCompanion = useCallback(() => {
66
+ invariant(primary);
67
+ return dispatch(createIntent(DeckAction.ChangeCompanion, { primary, companion: null }));
68
+ }, []);
69
+ return (
70
+ <div ref={forwardedRef} className='contents app-no-drag'>
71
+ <PlankControl
72
+ label={t('close companion label')}
73
+ variant='ghost'
74
+ icon='ph--minus--regular'
75
+ onClick={handleCloseCompanion}
76
+ classNames={plankControlSpacing}
77
+ />
78
+ </div>
79
+ );
80
+ },
81
+ );
82
+
53
83
  // TODO(wittjosiah): Duplicate of stack LayoutControls?
54
84
  // Translations were to be duplicated between packages.
55
85
  // NOTE(thure): Pinning & unpinning are disabled indefinitely.
@@ -59,7 +89,8 @@ export const PlankControls = forwardRef<HTMLDivElement, PlankControlsProps>(
59
89
  forwardedRef,
60
90
  ) => {
61
91
  const { t } = useTranslation(DECK_PLUGIN);
62
- const buttonClassNames = variant === 'hide-disabled' ? 'disabled:hidden pli-2 plb-3' : 'pli-2 plb-3';
92
+ const buttonClassNames =
93
+ variant === 'hide-disabled' ? `disabled:hidden ${plankControlSpacing}` : plankControlSpacing;
63
94
 
64
95
  return (
65
96
  <ButtonGroup {...props} classNames={['app-no-drag', classNames]} ref={forwardedRef}>
package/src/meta.ts CHANGED
@@ -6,8 +6,8 @@ import { type PluginMeta } from '@dxos/app-framework';
6
6
 
7
7
  export const DECK_PLUGIN = 'dxos.org/plugin/deck' as const;
8
8
 
9
- export const meta = {
9
+ export const meta: PluginMeta = {
10
10
  id: DECK_PLUGIN,
11
11
  name: 'Deck',
12
12
  icon: 'ph--columns--regular',
13
- } satisfies PluginMeta;
13
+ };
@@ -55,6 +55,7 @@ export default [
55
55
  'close current label': 'Close current plank',
56
56
  'close others label': 'Close other planks',
57
57
  'close all label': 'Close all planks',
58
+ 'companion plank heading fallback label': 'Related',
58
59
  },
59
60
  },
60
61
  },
package/src/types.ts CHANGED
@@ -17,6 +17,9 @@ export type NewPlankPositioning = (typeof NewPlankPositions)[number];
17
17
  export const OverscrollOptions = ['none', 'centering'] as const;
18
18
  export type Overscroll = (typeof OverscrollOptions)[number];
19
19
 
20
+ export type Part = 'solo' | 'deck' | 'complementary';
21
+ export type ResolvedPart = Part | 'solo-primary' | 'solo-companion';
22
+
20
23
  export type Panel = {
21
24
  id: string;
22
25
  label: Label;
@@ -53,13 +56,31 @@ export const Deck = S.Struct({
53
56
  description: "If false, the deck has not yet left solo mode and new planks should be solo'd.",
54
57
  }),
55
58
  active: S.mutable(S.Array(S.String)),
59
+ // TODO(wittjosiah): Piping into both mutable and optional caused invalid typescript output.
60
+ activeCompanions: S.optional(S.mutable(S.Record({ key: S.String, value: S.String }))),
56
61
  inactive: S.mutable(S.Array(S.String)),
57
62
  solo: S.optional(S.String),
58
63
  fullscreen: S.Boolean,
59
64
  plankSizing: S.mutable(PlankSizing),
65
+ companionFrameSizing: S.mutable(PlankSizing),
60
66
  });
61
67
  export type Deck = S.Schema.Type<typeof Deck>;
62
68
 
69
+ export const defaultDeck = {
70
+ initialized: false,
71
+ active: [],
72
+ activeCompanions: {},
73
+ inactive: [],
74
+ fullscreen: false,
75
+ solo: undefined,
76
+ plankSizing: {},
77
+ companionFrameSizing: {},
78
+ } satisfies Deck;
79
+
80
+ export const surfaceVariantSeparator = '--';
81
+
82
+ export const surfaceVariant = (id: string) => `${surfaceVariantSeparator}${id}`;
83
+
63
84
  export const DeckState = S.mutable(
64
85
  S.Struct({
65
86
  sidebarState: S.Literal('closed', 'collapsed', 'expanded'),
@@ -139,4 +160,12 @@ export namespace DeckAction {
139
160
  }),
140
161
  output: S.Void,
141
162
  }) {}
163
+
164
+ export class ChangeCompanion extends S.TaggedClass<ChangeCompanion>()(`${DECK_ACTION}/change-companion`, {
165
+ input: S.Struct({
166
+ primary: S.String,
167
+ companion: S.Union(S.String, S.Null),
168
+ }),
169
+ output: S.Void,
170
+ }) {}
142
171
  }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/types.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { LayoutAction } from '@dxos/app-framework';\nimport { S } from '@dxos/echo-schema';\nimport { type Node } from '@dxos/plugin-graph';\nimport { type Label } from '@dxos/react-ui';\nimport { type Position } from '@dxos/util';\n\nimport { DECK_PLUGIN } from './meta';\n\n// TODO(Zan): In the future we should consider adding new planks adjacent to the attended plank.\nexport const NewPlankPositions = ['start', 'end'] as const;\nexport type NewPlankPositioning = (typeof NewPlankPositions)[number];\n\nexport const OverscrollOptions = ['none', 'centering'] as const;\nexport type Overscroll = (typeof OverscrollOptions)[number];\n\nexport type Panel = {\n id: string;\n label: Label;\n icon: string;\n position?: Position;\n /**\n * If true, the panel will now be wrapped in a scroll area.\n */\n fixed?: boolean;\n filter?: (node: Node) => boolean;\n};\n\nexport const DeckSettingsSchema = S.mutable(\n S.Struct({\n showHints: S.Boolean,\n enableNativeRedirect: S.Boolean,\n enableStatusbar: S.Boolean,\n newPlankPositioning: S.Literal(...NewPlankPositions),\n overscroll: S.Literal(...OverscrollOptions),\n }),\n);\n\nexport type DeckSettingsProps = S.Schema.Type<typeof DeckSettingsSchema>;\n\nconst LayoutMode = S.Union(S.Literal('deck'), S.Literal('solo'), S.Literal('fullscreen'));\nexport const isLayoutMode = (value: any): value is LayoutMode => S.is(LayoutMode)(value);\nexport type LayoutMode = S.Schema.Type<typeof LayoutMode>;\n\nexport const PlankSizing = S.Record({ key: S.String, value: S.Number });\nexport type PlankSizing = S.Schema.Type<typeof PlankSizing>;\n\nexport const Deck = S.Struct({\n initialized: S.Boolean.annotations({\n description: \"If false, the deck has not yet left solo mode and new planks should be solo'd.\",\n }),\n active: S.mutable(S.Array(S.String)),\n inactive: S.mutable(S.Array(S.String)),\n solo: S.optional(S.String),\n fullscreen: S.Boolean,\n plankSizing: S.mutable(PlankSizing),\n});\nexport type Deck = S.Schema.Type<typeof Deck>;\n\nexport const DeckState = S.mutable(\n S.Struct({\n sidebarState: S.Literal('closed', 'collapsed', 'expanded'),\n complementarySidebarState: S.Literal('closed', 'collapsed', 'expanded'),\n complementarySidebarPanel: S.optional(S.String),\n\n dialogOpen: S.Boolean,\n /**\n * Data to be passed to the dialog Surface.\n */\n dialogContent: S.optional(S.Any),\n dialogBlockAlign: S.optional(S.Literal('start', 'center', 'end')),\n dialogType: S.optional(S.Literal('default', 'alert')),\n\n popoverOpen: S.Boolean,\n popoverSide: S.optional(S.Literal('top', 'right', 'bottom', 'left')),\n /**\n * Data to be passed to the popover Surface.\n */\n popoverContent: S.optional(S.Any),\n popoverAnchorId: S.optional(S.String),\n\n toasts: S.mutable(S.Array(LayoutAction.Toast)),\n currentUndoId: S.optional(S.String),\n\n activeDeck: S.String,\n previousDeck: S.String,\n decks: S.mutable(S.Record({ key: S.String, value: S.mutable(Deck) })),\n previousMode: S.mutable(S.Record({ key: S.String, value: LayoutMode })),\n deck: S.mutable(Deck),\n\n /**\n * The identifier of a component to scroll into view when it is mounted.\n */\n scrollIntoView: S.optional(S.String),\n }),\n);\n\nexport type DeckState = S.Schema.Type<typeof DeckState>;\n\nexport const getMode = (deck: Deck): LayoutMode => {\n if (deck.solo) {\n return deck.fullscreen ? 'fullscreen' : 'solo';\n }\n\n return 'deck';\n};\n\n// NOTE: Chosen from RFC 1738’s `safe` characters: http://www.faqs.org/rfcs/rfc1738.html\nexport const SLUG_PATH_SEPARATOR = '~';\n\nexport const DECK_ACTION = `${DECK_PLUGIN}/action`;\n\nexport namespace DeckAction {\n const PartAdjustmentSchema = S.Union(\n S.Literal('close').annotations({ description: 'Close the plank.' }),\n S.Literal('solo').annotations({ description: 'Solo the plank.' }),\n S.Literal('increment-start').annotations({ description: 'Move the plank towards the start of the deck.' }),\n S.Literal('increment-end').annotations({ description: 'Move the plank towards the end of the deck.' }),\n );\n export type PartAdjustment = S.Schema.Type<typeof PartAdjustmentSchema>;\n export const Adjustment = S.mutable(S.Struct({ id: S.String, type: PartAdjustmentSchema }));\n export type Adjustment = S.Schema.Type<typeof Adjustment>;\n\n /**\n * An atomic transaction to apply to the deck, describing which element to move to which location.\n */\n export class Adjust extends S.TaggedClass<Adjust>()(`${DECK_ACTION}/adjust`, {\n input: Adjustment,\n output: S.Void,\n }) {}\n\n export class UpdatePlankSize extends S.TaggedClass<UpdatePlankSize>()(`${DECK_ACTION}/update-plank-size`, {\n input: S.Struct({\n id: S.String,\n size: S.Number,\n }),\n output: S.Void,\n }) {}\n}\n"],
5
- "mappings": "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",
6
- "names": ["LayoutAction", "S", "NewPlankPositions", "OverscrollOptions", "DeckSettingsSchema", "S", "mutable", "Struct", "showHints", "Boolean", "enableNativeRedirect", "enableStatusbar", "newPlankPositioning", "Literal", "overscroll", "LayoutMode", "Union", "isLayoutMode", "value", "is", "PlankSizing", "Record", "key", "String", "Number", "Deck", "initialized", "annotations", "description", "active", "Array", "inactive", "solo", "optional", "fullscreen", "plankSizing", "DeckState", "sidebarState", "complementarySidebarState", "complementarySidebarPanel", "dialogOpen", "dialogContent", "Any", "dialogBlockAlign", "dialogType", "popoverOpen", "popoverSide", "popoverContent", "popoverAnchorId", "toasts", "LayoutAction", "Toast", "currentUndoId", "activeDeck", "previousDeck", "decks", "previousMode", "deck", "scrollIntoView", "getMode", "SLUG_PATH_SEPARATOR", "DECK_ACTION", "DECK_PLUGIN", "DeckAction", "PartAdjustmentSchema", "Adjustment", "id", "type", "Adjust", "TaggedClass", "input", "output", "Void", "UpdatePlankSize", "size"]
7
- }
@@ -1,24 +0,0 @@
1
- // packages/plugins/plugin-deck/src/capabilities/index.ts
2
- import { lazy } from "@dxos/app-framework";
3
- var AppGraphBuilder = lazy(() => import("./app-graph-builder-IYHAGFA3.mjs"));
4
- var CheckAppScheme = lazy(() => import("./check-app-scheme-S3EYUPMF.mjs"));
5
- var LayoutIntentResolver = lazy(() => import("./intent-resolver-P5BVUQKU.mjs"));
6
- var ReactRoot = lazy(() => import("./react-root-EP4UF3KA.mjs"));
7
- var ReactSurface = lazy(() => import("./react-surface-5B3RLJCD.mjs"));
8
- var DeckSettings = lazy(() => import("./settings-X3P2HKQJ.mjs"));
9
- var DeckState = lazy(() => import("./state-2MOTLKVR.mjs"));
10
- var Tools = lazy(() => import("./tools-64LXGLYR.mjs"));
11
- var UrlHandler = lazy(() => import("./url-handler-MVHTKUYA.mjs"));
12
-
13
- export {
14
- AppGraphBuilder,
15
- CheckAppScheme,
16
- LayoutIntentResolver,
17
- ReactRoot,
18
- ReactSurface,
19
- DeckSettings,
20
- DeckState,
21
- Tools,
22
- UrlHandler
23
- };
24
- //# sourceMappingURL=chunk-IZ5RPJ6T.mjs.map