@dxos/plugin-deck 0.6.8-main.046e6cf

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 (106) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +15 -0
  3. package/dist/lib/browser/chunk-YVHGFQQR.mjs +12 -0
  4. package/dist/lib/browser/chunk-YVHGFQQR.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +1657 -0
  6. package/dist/lib/browser/index.mjs.map +7 -0
  7. package/dist/lib/browser/meta.json +1 -0
  8. package/dist/lib/browser/meta.mjs +9 -0
  9. package/dist/lib/browser/meta.mjs.map +7 -0
  10. package/dist/types/src/DeckPlugin.d.ts +15 -0
  11. package/dist/types/src/DeckPlugin.d.ts.map +1 -0
  12. package/dist/types/src/components/DeckContext.d.ts +8 -0
  13. package/dist/types/src/components/DeckContext.d.ts.map +1 -0
  14. package/dist/types/src/components/DeckLayout/ActiveNode.d.ts +5 -0
  15. package/dist/types/src/components/DeckLayout/ActiveNode.d.ts.map +1 -0
  16. package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts +9 -0
  17. package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts.map +1 -0
  18. package/dist/types/src/components/DeckLayout/ContentEmpty.d.ts +3 -0
  19. package/dist/types/src/components/DeckLayout/ContentEmpty.d.ts.map +1 -0
  20. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts +25 -0
  21. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -0
  22. package/dist/types/src/components/DeckLayout/Fallback.d.ts +3 -0
  23. package/dist/types/src/components/DeckLayout/Fallback.d.ts.map +1 -0
  24. package/dist/types/src/components/DeckLayout/Fullscreen.d.ts +5 -0
  25. package/dist/types/src/components/DeckLayout/Fullscreen.d.ts.map +1 -0
  26. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts +14 -0
  27. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts.map +1 -0
  28. package/dist/types/src/components/DeckLayout/Plank.d.ts +14 -0
  29. package/dist/types/src/components/DeckLayout/Plank.d.ts.map +1 -0
  30. package/dist/types/src/components/DeckLayout/PlankError.d.ts +14 -0
  31. package/dist/types/src/components/DeckLayout/PlankError.d.ts.map +1 -0
  32. package/dist/types/src/components/DeckLayout/PlankLoading.d.ts +3 -0
  33. package/dist/types/src/components/DeckLayout/PlankLoading.d.ts.map +1 -0
  34. package/dist/types/src/components/DeckLayout/Sidebar.d.ts +8 -0
  35. package/dist/types/src/components/DeckLayout/Sidebar.d.ts.map +1 -0
  36. package/dist/types/src/components/DeckLayout/Toast.d.ts +5 -0
  37. package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -0
  38. package/dist/types/src/components/DeckLayout/constants.d.ts +3 -0
  39. package/dist/types/src/components/DeckLayout/constants.d.ts.map +1 -0
  40. package/dist/types/src/components/DeckLayout/index.d.ts +3 -0
  41. package/dist/types/src/components/DeckLayout/index.d.ts.map +1 -0
  42. package/dist/types/src/components/LayoutContext.d.ts +5 -0
  43. package/dist/types/src/components/LayoutContext.d.ts.map +1 -0
  44. package/dist/types/src/components/LayoutSettings.d.ts +6 -0
  45. package/dist/types/src/components/LayoutSettings.d.ts.map +1 -0
  46. package/dist/types/src/components/index.d.ts +5 -0
  47. package/dist/types/src/components/index.d.ts.map +1 -0
  48. package/dist/types/src/hooks/index.d.ts +3 -0
  49. package/dist/types/src/hooks/index.d.ts.map +1 -0
  50. package/dist/types/src/hooks/useNode.d.ts +11 -0
  51. package/dist/types/src/hooks/useNode.d.ts.map +1 -0
  52. package/dist/types/src/hooks/useNodeActionExpander.d.ts +3 -0
  53. package/dist/types/src/hooks/useNodeActionExpander.d.ts.map +1 -0
  54. package/dist/types/src/index.d.ts +4 -0
  55. package/dist/types/src/index.d.ts.map +1 -0
  56. package/dist/types/src/layout.d.ts +25 -0
  57. package/dist/types/src/layout.d.ts.map +1 -0
  58. package/dist/types/src/layout.test.d.ts +2 -0
  59. package/dist/types/src/layout.test.d.ts.map +1 -0
  60. package/dist/types/src/meta.d.ts +7 -0
  61. package/dist/types/src/meta.d.ts.map +1 -0
  62. package/dist/types/src/translations.d.ts +41 -0
  63. package/dist/types/src/translations.d.ts.map +1 -0
  64. package/dist/types/src/types.d.ts +16 -0
  65. package/dist/types/src/types.d.ts.map +1 -0
  66. package/dist/types/src/util/check-app-scheme.d.ts +2 -0
  67. package/dist/types/src/util/check-app-scheme.d.ts.map +1 -0
  68. package/dist/types/src/util/index.d.ts +4 -0
  69. package/dist/types/src/util/index.d.ts.map +1 -0
  70. package/dist/types/src/util/layout-parts.d.ts +7 -0
  71. package/dist/types/src/util/layout-parts.d.ts.map +1 -0
  72. package/dist/types/src/util/overscroll.d.ts +7 -0
  73. package/dist/types/src/util/overscroll.d.ts.map +1 -0
  74. package/package.json +76 -0
  75. package/src/DeckPlugin.tsx +629 -0
  76. package/src/components/DeckContext.ts +14 -0
  77. package/src/components/DeckLayout/ActiveNode.tsx +24 -0
  78. package/src/components/DeckLayout/ComplementarySidebar.tsx +58 -0
  79. package/src/components/DeckLayout/ContentEmpty.tsx +21 -0
  80. package/src/components/DeckLayout/DeckLayout.tsx +270 -0
  81. package/src/components/DeckLayout/Fallback.tsx +28 -0
  82. package/src/components/DeckLayout/Fullscreen.tsx +32 -0
  83. package/src/components/DeckLayout/NodePlankHeading.tsx +160 -0
  84. package/src/components/DeckLayout/Plank.tsx +142 -0
  85. package/src/components/DeckLayout/PlankError.tsx +64 -0
  86. package/src/components/DeckLayout/PlankLoading.tsx +15 -0
  87. package/src/components/DeckLayout/Sidebar.tsx +43 -0
  88. package/src/components/DeckLayout/Toast.tsx +48 -0
  89. package/src/components/DeckLayout/constants.ts +6 -0
  90. package/src/components/DeckLayout/index.ts +6 -0
  91. package/src/components/LayoutContext.ts +12 -0
  92. package/src/components/LayoutSettings.tsx +86 -0
  93. package/src/components/index.ts +8 -0
  94. package/src/hooks/index.ts +6 -0
  95. package/src/hooks/useNode.ts +40 -0
  96. package/src/hooks/useNodeActionExpander.ts +24 -0
  97. package/src/index.ts +9 -0
  98. package/src/layout.test.ts +380 -0
  99. package/src/layout.ts +245 -0
  100. package/src/meta.ts +10 -0
  101. package/src/translations.ts +47 -0
  102. package/src/types.ts +38 -0
  103. package/src/util/check-app-scheme.ts +21 -0
  104. package/src/util/index.ts +7 -0
  105. package/src/util/layout-parts.ts +12 -0
  106. package/src/util/overscroll.ts +97 -0
@@ -0,0 +1,1657 @@
1
+ import {
2
+ DECK_PLUGIN,
3
+ meta_default
4
+ } from "./chunk-YVHGFQQR.mjs";
5
+
6
+ // packages/plugins/plugin-deck/src/DeckPlugin.tsx
7
+ import { ArrowsOut } from "@phosphor-icons/react";
8
+ import { batch, effect } from "@preact/signals-core";
9
+ import { setAutoFreeze } from "immer";
10
+ import React14 from "react";
11
+ import { IntentAction, LayoutAction as LayoutAction3, NavigationAction as NavigationAction3, parseGraphPlugin, parseIntentPlugin, resolvePlugin, Toast as ToastSchema, SLUG_PATH_SEPARATOR as SLUG_PATH_SEPARATOR5, isLayoutParts, isLayoutAdjustment, isLayoutMode, openIds as openIds2 } from "@dxos/app-framework";
12
+ import { create, getTypename, isReactiveObject } from "@dxos/echo-schema";
13
+ import { LocalStorageStore } from "@dxos/local-storage";
14
+ import { log } from "@dxos/log";
15
+ import { parseAttentionPlugin } from "@dxos/plugin-attention";
16
+ import { parseClientPlugin } from "@dxos/plugin-client";
17
+ import { createExtension } from "@dxos/plugin-graph";
18
+ import { ObservabilityAction } from "@dxos/plugin-observability/meta";
19
+ import { fullyQualifiedId } from "@dxos/react-client/echo";
20
+ import { translations as deckTranslations } from "@dxos/react-ui-deck";
21
+ import { Mosaic } from "@dxos/react-ui-mosaic";
22
+
23
+ // packages/plugins/plugin-deck/src/components/DeckLayout/constants.ts
24
+ var NAV_ID = "NavTree";
25
+ var SURFACE_PREFIX = "surface:";
26
+
27
+ // packages/plugins/plugin-deck/src/components/DeckLayout/DeckLayout.tsx
28
+ import { Sidebar as MenuIcon } from "@phosphor-icons/react";
29
+ import React12, { useMemo as useMemo2 } from "react";
30
+ import { SLUG_PATH_SEPARATOR as SLUG_PATH_SEPARATOR3, Surface as Surface8, firstIdInPart, usePlugin } from "@dxos/app-framework";
31
+ import { Button as Button3, Dialog, Main as Main3, Popover as Popover2, useTranslation as useTranslation5 } from "@dxos/react-ui";
32
+ import { Deck } from "@dxos/react-ui-deck";
33
+ import { getSize, mx as mx4 } from "@dxos/react-ui-theme";
34
+
35
+ // packages/plugins/plugin-deck/src/components/DeckLayout/ActiveNode.tsx
36
+ import React from "react";
37
+ import { Surface } from "@dxos/app-framework";
38
+ import { useGraph } from "@dxos/plugin-graph";
39
+
40
+ // packages/plugins/plugin-deck/src/hooks/useNode.ts
41
+ import { useEffect, useState } from "react";
42
+ var useNode = (graph, id, timeout) => {
43
+ const [nodeState, setNodeState] = useState(id ? graph.findNode(id) : void 0);
44
+ useEffect(() => {
45
+ if (nodeState?.id === id || !id) {
46
+ return;
47
+ }
48
+ const frame = requestAnimationFrame(async () => {
49
+ try {
50
+ const node = await graph.waitForNode(id, timeout);
51
+ if (node) {
52
+ setNodeState(node);
53
+ }
54
+ } catch {
55
+ }
56
+ });
57
+ return () => cancelAnimationFrame(frame);
58
+ }, [
59
+ graph,
60
+ id,
61
+ timeout,
62
+ nodeState?.id
63
+ ]);
64
+ return nodeState;
65
+ };
66
+
67
+ // packages/plugins/plugin-deck/src/hooks/useNodeActionExpander.ts
68
+ import { useEffect as useEffect2 } from "react";
69
+ import { ACTION_GROUP_TYPE, ACTION_TYPE, getGraph } from "@dxos/plugin-graph";
70
+ var expandNodeActions = async (node) => {
71
+ const graph = getGraph(node);
72
+ await graph.expand(node, "outbound", ACTION_GROUP_TYPE);
73
+ await graph.expand(node, "outbound", ACTION_TYPE);
74
+ };
75
+ var useNodeActionExpander = (node) => {
76
+ useEffect2(() => {
77
+ if (node) {
78
+ const frame = requestAnimationFrame(() => {
79
+ void expandNodeActions(node);
80
+ });
81
+ return () => cancelAnimationFrame(frame);
82
+ }
83
+ }, [
84
+ node
85
+ ]);
86
+ };
87
+
88
+ // packages/plugins/plugin-deck/src/components/DeckLayout/ActiveNode.tsx
89
+ var ActiveNode = ({ id }) => {
90
+ const { graph } = useGraph();
91
+ const activeNode = useNode(graph, id);
92
+ useNodeActionExpander(activeNode);
93
+ return /* @__PURE__ */ React.createElement("div", {
94
+ role: "none",
95
+ className: "sr-only"
96
+ }, /* @__PURE__ */ React.createElement(Surface, {
97
+ role: "document-title",
98
+ data: {
99
+ activeNode
100
+ },
101
+ limit: 1
102
+ }));
103
+ };
104
+
105
+ // packages/plugins/plugin-deck/src/components/DeckLayout/ComplementarySidebar.tsx
106
+ import React5 from "react";
107
+ import { SLUG_PATH_SEPARATOR as SLUG_PATH_SEPARATOR2, Surface as Surface3 } from "@dxos/app-framework";
108
+ import { useGraph as useGraph3 } from "@dxos/plugin-graph";
109
+ import { Main } from "@dxos/react-ui";
110
+ import { createAttendableAttributes } from "@dxos/react-ui-attention";
111
+ import { deckGrid } from "@dxos/react-ui-deck";
112
+ import { mx as mx2 } from "@dxos/react-ui-theme";
113
+
114
+ // packages/plugins/plugin-deck/src/components/DeckLayout/NodePlankHeading.tsx
115
+ import { Placeholder } from "@phosphor-icons/react";
116
+ import React2, { Fragment, useEffect as useEffect3 } from "react";
117
+ import { LayoutAction, NavigationAction, SLUG_COLLECTION_INDICATOR, SLUG_PATH_SEPARATOR, Surface as Surface2, useIntentDispatcher, indexInPart, partLength } from "@dxos/app-framework";
118
+ import { useGraph as useGraph2 } from "@dxos/plugin-graph";
119
+ import { Popover, toLocalizedString, useMediaQuery, useTranslation } from "@dxos/react-ui";
120
+ import { PlankHeading, plankHeadingIconProps } from "@dxos/react-ui-deck";
121
+ import { TextTooltip } from "@dxos/react-ui-text-tooltip";
122
+ var NodePlankHeading = ({
123
+ node,
124
+ id,
125
+ layoutParts,
126
+ layoutPart,
127
+ // TODO(wittjosiah): Unused?
128
+ layoutEntry,
129
+ popoverAnchorId,
130
+ pending,
131
+ flatDeck
132
+ }) => {
133
+ const { t } = useTranslation(DECK_PLUGIN);
134
+ const { graph } = useGraph2();
135
+ const Icon = node?.properties?.icon ?? Placeholder;
136
+ const label = pending ? t("pending heading") : toLocalizedString(node?.properties?.label ?? [
137
+ "plank heading fallback label",
138
+ {
139
+ ns: DECK_PLUGIN
140
+ }
141
+ ], t);
142
+ const dispatch = useIntentDispatcher();
143
+ const ActionRoot = node && popoverAnchorId === `dxos.org/ui/${DECK_PLUGIN}/${node.id}` ? Popover.Anchor : Fragment;
144
+ const [isNotMobile] = useMediaQuery("md");
145
+ useEffect3(() => {
146
+ const frame = requestAnimationFrame(() => {
147
+ node && graph.actions(node);
148
+ });
149
+ return () => cancelAnimationFrame(frame);
150
+ }, [
151
+ node
152
+ ]);
153
+ const attendableId = id?.split(SLUG_PATH_SEPARATOR).at(0);
154
+ const layoutCoordinate = layoutPart !== void 0 && id !== void 0 ? {
155
+ part: layoutPart,
156
+ entryId: id
157
+ } : void 0;
158
+ const index = indexInPart(layoutParts, layoutCoordinate);
159
+ const length = partLength(layoutParts, layoutPart);
160
+ const canIncrementStart = layoutPart === "main" && index !== void 0 && index > 0 && length !== void 0 && length > 1;
161
+ const canIncrementEnd = layoutPart === "main" && index !== void 0 && index < length - 1 && length !== void 0;
162
+ return /* @__PURE__ */ React2.createElement(PlankHeading.Root, (layoutPart !== "main" || !flatDeck) && {
163
+ classNames: "pie-1 border-b separator-separator"
164
+ }, /* @__PURE__ */ React2.createElement(ActionRoot, null, node ? /* @__PURE__ */ React2.createElement(PlankHeading.ActionsMenu, {
165
+ Icon,
166
+ attendableId,
167
+ triggerLabel: t("actions menu label"),
168
+ actions: graph.actions(node),
169
+ onAction: (action) => typeof action.data === "function" && action.data?.({
170
+ node: action,
171
+ caller: DECK_PLUGIN
172
+ })
173
+ }, /* @__PURE__ */ React2.createElement(Surface2, {
174
+ role: "menu-footer",
175
+ data: {
176
+ object: node.data
177
+ }
178
+ })) : /* @__PURE__ */ React2.createElement(PlankHeading.Button, null, /* @__PURE__ */ React2.createElement("span", {
179
+ className: "sr-only"
180
+ }, label), /* @__PURE__ */ React2.createElement(Icon, plankHeadingIconProps))), /* @__PURE__ */ React2.createElement(TextTooltip, {
181
+ text: label,
182
+ onlyWhenTruncating: true
183
+ }, /* @__PURE__ */ React2.createElement(PlankHeading.Label, {
184
+ attendableId: node?.id,
185
+ ...pending && {
186
+ classNames: "fg-description"
187
+ }
188
+ }, label)), node && layoutPart !== "complementary" && // TODO(Zan): What are we doing with layout coordinate here?
189
+ /* @__PURE__ */ React2.createElement(Surface2, {
190
+ role: "navbar-end",
191
+ direction: "inline-reverse",
192
+ data: {
193
+ object: node.data
194
+ }
195
+ }), /* @__PURE__ */ React2.createElement(PlankHeading.Controls, {
196
+ capabilities: {
197
+ solo: (layoutPart === "solo" || layoutPart === "main") && isNotMobile,
198
+ incrementStart: canIncrementStart,
199
+ incrementEnd: canIncrementEnd
200
+ },
201
+ isSolo: layoutPart === "solo",
202
+ onClick: (eventType) => {
203
+ if (!layoutPart) {
204
+ return;
205
+ }
206
+ if (eventType === "solo") {
207
+ return dispatch([
208
+ {
209
+ action: NavigationAction.ADJUST,
210
+ data: {
211
+ type: eventType,
212
+ layoutCoordinate: {
213
+ part: "main",
214
+ entryId: id
215
+ }
216
+ }
217
+ }
218
+ ]);
219
+ }
220
+ return dispatch(eventType === "close" ? layoutPart === "complementary" ? {
221
+ action: LayoutAction.SET_LAYOUT,
222
+ data: {
223
+ element: "complementary",
224
+ state: false
225
+ }
226
+ } : {
227
+ action: NavigationAction.CLOSE,
228
+ data: {
229
+ activeParts: {
230
+ complementary: [
231
+ `${id}${SLUG_PATH_SEPARATOR}comments${SLUG_COLLECTION_INDICATOR}`
232
+ ],
233
+ [layoutPart]: [
234
+ id
235
+ ]
236
+ }
237
+ }
238
+ } : {
239
+ action: NavigationAction.ADJUST,
240
+ data: {
241
+ type: eventType,
242
+ layoutCoordinate
243
+ }
244
+ });
245
+ },
246
+ close: layoutCoordinate?.part === "complementary" ? "minify-end" : true
247
+ }));
248
+ };
249
+
250
+ // packages/plugins/plugin-deck/src/components/DeckLayout/PlankError.tsx
251
+ import React4, { useEffect as useEffect4, useState as useState2 } from "react";
252
+ import { useTranslation as useTranslation2 } from "@dxos/react-ui";
253
+ import { descriptionText, mx } from "@dxos/react-ui-theme";
254
+
255
+ // packages/plugins/plugin-deck/src/components/DeckLayout/PlankLoading.tsx
256
+ import React3 from "react";
257
+ import { Status } from "@dxos/react-ui";
258
+ var PlankLoading = () => {
259
+ return /* @__PURE__ */ React3.createElement("div", {
260
+ role: "none",
261
+ className: "grid bs-[100dvh] place-items-center row-span-2"
262
+ }, /* @__PURE__ */ React3.createElement(Status, {
263
+ indeterminate: true,
264
+ "aria-label": "Initializing"
265
+ }));
266
+ };
267
+
268
+ // packages/plugins/plugin-deck/src/components/DeckLayout/PlankError.tsx
269
+ var PlankContentError = ({ error }) => {
270
+ const { t } = useTranslation2(DECK_PLUGIN);
271
+ return /* @__PURE__ */ React4.createElement("div", {
272
+ role: "none",
273
+ className: "grid place-items-center row-span-2"
274
+ }, /* @__PURE__ */ React4.createElement("p", {
275
+ role: "alert",
276
+ className: mx(
277
+ descriptionText,
278
+ // TODO(burdon): Factor out common styles for all dialogs.
279
+ "overflow-hidden break-words",
280
+ "place-self-center border border-dashed border-neutral-400/50 rounded-lg text-center p-8 font-normal text-lg"
281
+ )
282
+ }, error ? error.toString() : t("error fallback message")));
283
+ };
284
+ var PlankError = ({ layoutCoordinate, id, node, error, flatDeck }) => {
285
+ const [timedOut, setTimedOut] = useState2(false);
286
+ useEffect4(() => {
287
+ setTimeout(() => setTimedOut(true), 5e3);
288
+ }, []);
289
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(NodePlankHeading, {
290
+ node,
291
+ id,
292
+ layoutPart: layoutCoordinate.part,
293
+ pending: !timedOut,
294
+ flatDeck
295
+ }), timedOut ? /* @__PURE__ */ React4.createElement(PlankContentError, {
296
+ error
297
+ }) : /* @__PURE__ */ React4.createElement(PlankLoading, null));
298
+ };
299
+
300
+ // packages/plugins/plugin-deck/src/components/LayoutContext.ts
301
+ import { createContext, useContext } from "react";
302
+ import { raise } from "@dxos/debug";
303
+ var LayoutContext = createContext(null);
304
+ var useLayout = () => useContext(LayoutContext) ?? raise(new Error("Missing LayoutContext"));
305
+
306
+ // packages/plugins/plugin-deck/src/components/DeckLayout/ComplementarySidebar.tsx
307
+ var ComplementarySidebar = ({ id, layoutParts, flatDeck }) => {
308
+ const { popoverAnchorId } = useLayout();
309
+ const { graph } = useGraph3();
310
+ const node = useNode(graph, id);
311
+ const complementaryAttrs = createAttendableAttributes(id?.split(SLUG_PATH_SEPARATOR2)[0] ?? "never");
312
+ useNodeActionExpander(node);
313
+ return /* @__PURE__ */ React5.createElement(Main.ComplementarySidebar, complementaryAttrs, node ? /* @__PURE__ */ React5.createElement("div", {
314
+ role: "none",
315
+ className: mx2(deckGrid, "grid-cols-1 bs-full")
316
+ }, /* @__PURE__ */ React5.createElement(NodePlankHeading, {
317
+ node,
318
+ id,
319
+ layoutParts,
320
+ layoutPart: "complementary",
321
+ popoverAnchorId,
322
+ flatDeck
323
+ }), /* @__PURE__ */ React5.createElement(Surface3, {
324
+ role: "article",
325
+ data: {
326
+ subject: node.data,
327
+ part: "complementary",
328
+ popoverAnchorId
329
+ },
330
+ limit: 1,
331
+ fallback: PlankContentError,
332
+ placeholder: /* @__PURE__ */ React5.createElement(PlankLoading, null)
333
+ })) : null);
334
+ };
335
+
336
+ // packages/plugins/plugin-deck/src/components/DeckLayout/ContentEmpty.tsx
337
+ import React6 from "react";
338
+ import { Surface as Surface4 } from "@dxos/app-framework";
339
+ var ContentEmpty = () => {
340
+ return /* @__PURE__ */ React6.createElement("div", {
341
+ role: "none",
342
+ className: "min-bs-screen is-dvw sm:is-full flex items-center justify-center p-8",
343
+ "data-testid": "layoutPlugin.firstRunMessage"
344
+ }, /* @__PURE__ */ React6.createElement("div", {
345
+ role: "none",
346
+ className: "grid place-items-center grid-rows-[min-content_min-content]"
347
+ }, /* @__PURE__ */ React6.createElement(Surface4, {
348
+ role: "keyshortcuts"
349
+ })));
350
+ };
351
+
352
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Fullscreen.tsx
353
+ import React8 from "react";
354
+ import { Surface as Surface5 } from "@dxos/app-framework";
355
+ import { useGraph as useGraph4 } from "@dxos/plugin-graph";
356
+ import { fixedInsetFlexLayout } from "@dxos/react-ui-theme";
357
+
358
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Fallback.tsx
359
+ import React7 from "react";
360
+ import { useTranslation as useTranslation3 } from "@dxos/react-ui";
361
+ import { errorText, mx as mx3 } from "@dxos/react-ui-theme";
362
+ var Fallback = () => {
363
+ const { t } = useTranslation3(DECK_PLUGIN);
364
+ return /* @__PURE__ */ React7.createElement("div", {
365
+ role: "none",
366
+ className: "min-bs-screen is-full flex items-center justify-center p-8"
367
+ }, /* @__PURE__ */ React7.createElement("p", {
368
+ role: "alert",
369
+ className: mx3(errorText, "border border-error-400/50 rounded-lg flex items-center justify-center p-8 font-normal text-lg")
370
+ }, t("plugin error message")));
371
+ };
372
+
373
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Fullscreen.tsx
374
+ var Fullscreen = ({ id }) => {
375
+ const { graph } = useGraph4();
376
+ const fullScreenNode = useNode(graph, id);
377
+ return /* @__PURE__ */ React8.createElement("div", {
378
+ role: "none",
379
+ className: fixedInsetFlexLayout
380
+ }, /* @__PURE__ */ React8.createElement(Surface5, {
381
+ role: "main",
382
+ limit: 1,
383
+ fallback: Fallback,
384
+ data: {
385
+ active: fullScreenNode?.data,
386
+ component: id?.startsWith(SURFACE_PREFIX) ? id.slice(SURFACE_PREFIX.length) : void 0
387
+ }
388
+ }));
389
+ };
390
+
391
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Plank.tsx
392
+ import { Plus } from "@phosphor-icons/react";
393
+ import React9, { useCallback } from "react";
394
+ import { LayoutAction as LayoutAction2, NavigationAction as NavigationAction2, Surface as Surface6, useIntentDispatcher as useIntentDispatcher2 } from "@dxos/app-framework";
395
+ import { debounce } from "@dxos/async";
396
+ import { useGraph as useGraph5 } from "@dxos/plugin-graph";
397
+ import { Button, Tooltip, useTranslation as useTranslation4 } from "@dxos/react-ui";
398
+ import { createAttendableAttributes as createAttendableAttributes2 } from "@dxos/react-ui-attention";
399
+ import { Plank as NaturalPlank } from "@dxos/react-ui-deck";
400
+
401
+ // packages/plugins/plugin-deck/src/components/DeckContext.ts
402
+ import { createContext as createContext2, useContext as useContext2 } from "react";
403
+ import { raise as raise2 } from "@dxos/debug";
404
+ var DeckContext = createContext2(null);
405
+ var useDeckContext = () => useContext2(DeckContext) ?? raise2(new Error("Missing DeckContext"));
406
+
407
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Plank.tsx
408
+ var Plank = ({ entry, layoutParts, part, resizeable, flatDeck, searchEnabled, classNames }) => {
409
+ const { t } = useTranslation4(DECK_PLUGIN);
410
+ const dispatch = useIntentDispatcher2();
411
+ const { popoverAnchorId, scrollIntoView } = useLayout();
412
+ const { plankSizing } = useDeckContext();
413
+ const { graph } = useGraph5();
414
+ const node = useNode(graph, entry.id);
415
+ const attendableAttrs = createAttendableAttributes2(entry.id);
416
+ const size = plankSizing?.[entry.id];
417
+ const setSize = useCallback(debounce((newSize) => {
418
+ void dispatch({
419
+ action: DeckAction.UPDATE_PLANK_SIZE,
420
+ data: {
421
+ id: entry.id,
422
+ size: newSize
423
+ }
424
+ });
425
+ }, 200), [
426
+ dispatch,
427
+ entry.id
428
+ ]);
429
+ const coordinate = {
430
+ part,
431
+ entryId: entry.id
432
+ };
433
+ return /* @__PURE__ */ React9.createElement(NaturalPlank.Root, {
434
+ size,
435
+ setSize
436
+ }, /* @__PURE__ */ React9.createElement(NaturalPlank.Content, {
437
+ ...attendableAttrs,
438
+ classNames: [
439
+ !flatDeck && "surface-base",
440
+ classNames
441
+ ],
442
+ scrollIntoViewOnMount: entry.id === scrollIntoView,
443
+ suppressAutofocus: entry.id === NAV_ID || !!node?.properties?.managesAutofocus
444
+ }, node ? /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(NodePlankHeading, {
445
+ layoutPart: coordinate.part,
446
+ layoutParts,
447
+ node,
448
+ id: entry.id,
449
+ popoverAnchorId,
450
+ flatDeck
451
+ }), /* @__PURE__ */ React9.createElement(Surface6, {
452
+ role: "article",
453
+ data: {
454
+ ...entry.path ? {
455
+ subject: node.data,
456
+ path: entry.path
457
+ } : {
458
+ object: node.data
459
+ },
460
+ coordinate,
461
+ popoverAnchorId
462
+ },
463
+ limit: 1,
464
+ fallback: PlankContentError,
465
+ placeholder: /* @__PURE__ */ React9.createElement(PlankLoading, null)
466
+ })) : /* @__PURE__ */ React9.createElement(PlankError, {
467
+ layoutCoordinate: coordinate,
468
+ id: entry.id,
469
+ flatDeck
470
+ })), searchEnabled && resizeable ? /* @__PURE__ */ React9.createElement("div", {
471
+ role: "none",
472
+ className: "grid grid-rows-subgrid row-span-3"
473
+ }, /* @__PURE__ */ React9.createElement(Tooltip.Root, null, /* @__PURE__ */ React9.createElement(Tooltip.Trigger, {
474
+ asChild: true
475
+ }, /* @__PURE__ */ React9.createElement(Button, {
476
+ "data-testid": "plankHeading.open",
477
+ variant: "ghost",
478
+ classNames: "p-1 w-fit",
479
+ onClick: () => dispatch([
480
+ {
481
+ action: LayoutAction2.SET_LAYOUT,
482
+ data: {
483
+ element: "dialog",
484
+ component: "dxos.org/plugin/search/Dialog",
485
+ dialogBlockAlign: "start",
486
+ subject: {
487
+ action: NavigationAction2.SET,
488
+ position: "add-after",
489
+ coordinate
490
+ }
491
+ }
492
+ }
493
+ ])
494
+ }, /* @__PURE__ */ React9.createElement("span", {
495
+ className: "sr-only"
496
+ }, t("insert plank label")), /* @__PURE__ */ React9.createElement(Plus, null))), /* @__PURE__ */ React9.createElement(Tooltip.Portal, null, /* @__PURE__ */ React9.createElement(Tooltip.Content, {
497
+ side: "bottom",
498
+ classNames: "z-[70]"
499
+ }, t("insert plank label")))), /* @__PURE__ */ React9.createElement(NaturalPlank.ResizeHandle, {
500
+ classNames: "row-start-[toolbar-start] row-end-[content-end]"
501
+ })) : resizeable ? /* @__PURE__ */ React9.createElement(NaturalPlank.ResizeHandle, {
502
+ classNames: "row-span-3"
503
+ }) : null);
504
+ };
505
+
506
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Sidebar.tsx
507
+ import React10, { useMemo } from "react";
508
+ import { openIds, Surface as Surface7 } from "@dxos/app-framework";
509
+ import { Main as Main2 } from "@dxos/react-ui";
510
+ var Sidebar = ({ attention, layoutParts }) => {
511
+ const { layoutMode, popoverAnchorId } = useLayout();
512
+ const activeIds = useMemo(() => {
513
+ if (layoutMode === "solo") {
514
+ return new Set(layoutParts?.solo?.map((e) => e.id) ?? []);
515
+ } else if (layoutMode === "deck") {
516
+ return new Set(layoutParts?.main?.map((e) => e.id) ?? []);
517
+ }
518
+ return new Set(openIds(layoutParts));
519
+ }, [
520
+ layoutParts,
521
+ layoutMode
522
+ ]);
523
+ const navigationData = useMemo(() => ({
524
+ popoverAnchorId,
525
+ activeIds,
526
+ attended: attention.attended
527
+ }), [
528
+ popoverAnchorId,
529
+ activeIds,
530
+ attention.attended
531
+ ]);
532
+ return /* @__PURE__ */ React10.createElement(Main2.NavigationSidebar, null, /* @__PURE__ */ React10.createElement(Surface7, {
533
+ role: "navigation",
534
+ data: {
535
+ ...navigationData
536
+ },
537
+ limit: 1
538
+ }));
539
+ };
540
+
541
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Toast.tsx
542
+ import React11 from "react";
543
+ import { Button as Button2, Toast as NaturalToast } from "@dxos/react-ui";
544
+ var Toast = ({ id, title, description, icon, duration, actionLabel, actionAlt, closeLabel, onAction, onOpenChange }) => {
545
+ return /* @__PURE__ */ React11.createElement(NaturalToast.Root, {
546
+ "data-testid": id,
547
+ defaultOpen: true,
548
+ duration,
549
+ onOpenChange
550
+ }, /* @__PURE__ */ React11.createElement(NaturalToast.Body, null, /* @__PURE__ */ React11.createElement(NaturalToast.Title, null, icon?.({
551
+ className: "inline mr-1"
552
+ }), /* @__PURE__ */ React11.createElement("span", null, title)), description && /* @__PURE__ */ React11.createElement(NaturalToast.Description, null, description)), /* @__PURE__ */ React11.createElement(NaturalToast.Actions, null, onAction && actionAlt && actionLabel && /* @__PURE__ */ React11.createElement(NaturalToast.Action, {
553
+ altText: actionAlt,
554
+ asChild: true
555
+ }, /* @__PURE__ */ React11.createElement(Button2, {
556
+ "data-testid": "toast.action",
557
+ variant: "primary",
558
+ onClick: () => onAction?.()
559
+ }, actionLabel)), closeLabel && /* @__PURE__ */ React11.createElement(NaturalToast.Close, {
560
+ asChild: true
561
+ }, /* @__PURE__ */ React11.createElement(Button2, {
562
+ "data-testid": "toast.close"
563
+ }, closeLabel))));
564
+ };
565
+
566
+ // packages/plugins/plugin-deck/src/util/check-app-scheme.ts
567
+ var checkAppScheme = (url) => {
568
+ const iframe = document.createElement("iframe");
569
+ iframe.style.display = "none";
570
+ document.body.appendChild(iframe);
571
+ iframe.src = url + window.location.pathname.replace(/^\/+/, "") + window.location.search;
572
+ const timer = setTimeout(() => {
573
+ document.body.removeChild(iframe);
574
+ }, 3e3);
575
+ window.addEventListener("pagehide", (event) => {
576
+ clearTimeout(timer);
577
+ document.body.removeChild(iframe);
578
+ });
579
+ };
580
+
581
+ // packages/plugins/plugin-deck/src/util/layout-parts.ts
582
+ var getEffectivePart = (partName, layoutMode) => layoutMode === "solo" && partName === "main" ? "solo" : partName;
583
+
584
+ // packages/plugins/plugin-deck/src/util/overscroll.ts
585
+ import { PLANK_DEFAULTS } from "@dxos/react-ui-deck";
586
+ var calculateOverscroll = (layoutMode, sidebarOpen, complementarySidebarOpen, layoutParts, plankSizing, overscroll) => {
587
+ if (!(layoutMode === "deck" && overscroll === "centering")) {
588
+ return;
589
+ }
590
+ if (!layoutParts.main || layoutParts.main.length === 0) {
591
+ return;
592
+ }
593
+ const sidebarWidth = sidebarOpen ? "270px" : "0px";
594
+ const complementarySidebarWidth = complementarySidebarOpen ? "360px" : "0px";
595
+ const getPlankSize = (id) => (plankSizing[id] ?? PLANK_DEFAULTS.size).toFixed(2) + "rem";
596
+ if (layoutParts.main.length === 1) {
597
+ const plank = layoutParts.main[0];
598
+ const plankSize = getPlankSize(plank.id);
599
+ const overscrollPadding = `max(0px, calc(((100dvw - ${sidebarWidth} - ${complementarySidebarWidth} - (${plankSize} + 20px)) / 2)))`;
600
+ return {
601
+ paddingLeft: overscrollPadding,
602
+ paddingRight: overscrollPadding
603
+ };
604
+ } else {
605
+ const firstPlank = layoutParts.main[0];
606
+ const firstPlankInlineSize = getPlankSize(firstPlank.id);
607
+ const paddingLeft = `max(0px, calc(((100dvw - (${firstPlankInlineSize} + 20px)) / 2) - ${sidebarWidth}))`;
608
+ const lastPlank = layoutParts.main[layoutParts.main.length - 1];
609
+ const lastPlankInlineSize = getPlankSize(lastPlank.id);
610
+ const paddingRight = `max(0px, calc(((100dvw - (${lastPlankInlineSize} + 20px)) / 2) - ${complementarySidebarWidth}))`;
611
+ return {
612
+ paddingLeft,
613
+ paddingRight
614
+ };
615
+ }
616
+ };
617
+
618
+ // packages/plugins/plugin-deck/src/components/DeckLayout/DeckLayout.tsx
619
+ var DeckLayout = ({ showHintsFooter, toasts, onDismissToast, flatDeck, attention, layoutParts, slots, overscroll }) => {
620
+ const context = useLayout();
621
+ const { layoutMode, sidebarOpen, complementarySidebarOpen, dialogOpen, dialogContent, dialogBlockAlign, popoverOpen, popoverContent, popoverAnchorId } = context;
622
+ const { t } = useTranslation5(DECK_PLUGIN);
623
+ const { plankSizing } = useDeckContext();
624
+ const fullScreenSlug = useMemo2(() => firstIdInPart(layoutParts, "fullScreen"), [
625
+ layoutParts
626
+ ]);
627
+ const complementarySlug = useMemo2(() => {
628
+ const entry = layoutParts.complementary?.at(0);
629
+ if (entry) {
630
+ return entry.path ? `${entry.id}${SLUG_PATH_SEPARATOR3}${entry.path}` : entry.id;
631
+ }
632
+ }, [
633
+ layoutParts
634
+ ]);
635
+ const searchEnabled = !!usePlugin("dxos.org/plugin/search");
636
+ const activeId = useMemo2(() => Array.from(attention.attended ?? [])[0], [
637
+ attention.attended
638
+ ]);
639
+ const overscrollAmount = calculateOverscroll(layoutMode, sidebarOpen, complementarySidebarOpen, layoutParts, plankSizing, overscroll);
640
+ if (layoutMode === "fullscreen") {
641
+ return /* @__PURE__ */ React12.createElement(Fullscreen, {
642
+ id: fullScreenSlug
643
+ });
644
+ }
645
+ return /* @__PURE__ */ React12.createElement(Popover2.Root, {
646
+ modal: true,
647
+ open: !!(popoverAnchorId && popoverOpen),
648
+ onOpenChange: (nextOpen) => {
649
+ if (nextOpen && popoverAnchorId) {
650
+ context.popoverOpen = true;
651
+ } else {
652
+ context.popoverOpen = false;
653
+ context.popoverAnchorId = void 0;
654
+ }
655
+ }
656
+ }, /* @__PURE__ */ React12.createElement(ActiveNode, {
657
+ id: activeId
658
+ }), /* @__PURE__ */ React12.createElement(Main3.Root, {
659
+ navigationSidebarOpen: context.sidebarOpen,
660
+ onNavigationSidebarOpenChange: (next) => context.sidebarOpen = next,
661
+ ...complementarySidebarOpen !== null && {
662
+ complementarySidebarOpen: (
663
+ /* complementaryAvailable && */
664
+ context.complementarySidebarOpen
665
+ ),
666
+ onComplementarySidebarOpenChange: (next) => context.complementarySidebarOpen = next
667
+ }
668
+ }, /* @__PURE__ */ React12.createElement(Main3.Notch, {
669
+ classNames: "z-[21]"
670
+ }, /* @__PURE__ */ React12.createElement(Surface8, {
671
+ role: "notch-start"
672
+ }), /* @__PURE__ */ React12.createElement(Button3, {
673
+ // disabled={!sidebarAvailable}
674
+ onClick: () => context.sidebarOpen = !context.sidebarOpen,
675
+ variant: "ghost",
676
+ classNames: "p-1"
677
+ }, /* @__PURE__ */ React12.createElement("span", {
678
+ className: "sr-only"
679
+ }, t("open navigation sidebar label")), /* @__PURE__ */ React12.createElement(MenuIcon, {
680
+ weight: "light",
681
+ className: getSize(5)
682
+ })), /* @__PURE__ */ React12.createElement(Button3, {
683
+ // disabled={!complementaryAvailable}
684
+ onClick: () => context.complementarySidebarOpen = !context.complementarySidebarOpen,
685
+ variant: "ghost",
686
+ classNames: "p-1"
687
+ }, /* @__PURE__ */ React12.createElement("span", {
688
+ className: "sr-only"
689
+ }, t("open complementary sidebar label")), /* @__PURE__ */ React12.createElement(MenuIcon, {
690
+ mirrored: true,
691
+ weight: "light",
692
+ className: getSize(5)
693
+ })), /* @__PURE__ */ React12.createElement(Surface8, {
694
+ role: "notch-end"
695
+ })), /* @__PURE__ */ React12.createElement(Sidebar, {
696
+ attention,
697
+ layoutParts
698
+ }), /* @__PURE__ */ React12.createElement(ComplementarySidebar, {
699
+ id: complementarySlug,
700
+ layoutParts,
701
+ flatDeck
702
+ }), /* @__PURE__ */ React12.createElement(Main3.Overlay, null), layoutMode === "deck" && layoutParts.main && layoutParts.main.length > 0 && /* @__PURE__ */ React12.createElement(Main3.Content, {
703
+ bounce: true,
704
+ classNames: [
705
+ "grid",
706
+ "block-end-[--statusbar-size]"
707
+ ]
708
+ }, /* @__PURE__ */ React12.createElement("div", {
709
+ role: "none",
710
+ className: "relative"
711
+ }, /* @__PURE__ */ React12.createElement(Deck.Root, {
712
+ classNames: mx4("absolute inset-0", !flatDeck && "surface-deck", slots?.wallpaper?.classNames, slots?.deck?.classNames, "transition-[padding] duration-200 ease-in-out"),
713
+ style: {
714
+ ...overscrollAmount
715
+ }
716
+ }, layoutParts.main.map((layoutEntry) => {
717
+ return /* @__PURE__ */ React12.createElement(Plank, {
718
+ key: layoutEntry.id,
719
+ entry: layoutEntry,
720
+ layoutParts,
721
+ part: "main",
722
+ resizeable: true,
723
+ flatDeck,
724
+ searchEnabled
725
+ });
726
+ })))), layoutMode === "solo" && layoutParts.solo && layoutParts.solo.length > 0 && /* @__PURE__ */ React12.createElement(Main3.Content, {
727
+ bounce: true,
728
+ classNames: [
729
+ "grid",
730
+ "block-end-[--statusbar-size]"
731
+ ]
732
+ }, /* @__PURE__ */ React12.createElement(Deck.Root, {
733
+ classNames: [
734
+ !flatDeck && "surface-deck",
735
+ slots?.wallpaper?.classNames,
736
+ slots?.deck?.classNames
737
+ ],
738
+ solo: true
739
+ }, layoutParts.solo.map((layoutEntry) => {
740
+ return /* @__PURE__ */ React12.createElement(Plank, {
741
+ key: layoutEntry.id,
742
+ entry: layoutEntry,
743
+ layoutParts,
744
+ part: "solo",
745
+ flatDeck,
746
+ classNames: slots?.plank?.classNames
747
+ });
748
+ }))), (layoutMode === "solo" && (!layoutParts.solo || layoutParts.solo.length === 0) || layoutMode === "deck" && (!layoutParts.main || layoutParts.main.length === 0)) && /* @__PURE__ */ React12.createElement(Main3.Content, null, /* @__PURE__ */ React12.createElement(ContentEmpty, null)), /* @__PURE__ */ React12.createElement(Main3.Content, {
749
+ role: "none",
750
+ classNames: [
751
+ "fixed inset-inline-0 block-end-0 z-[2]"
752
+ ]
753
+ }, /* @__PURE__ */ React12.createElement(Surface8, {
754
+ role: "status-bar",
755
+ limit: 1
756
+ })), showHintsFooter && /* @__PURE__ */ React12.createElement("div", {
757
+ className: "fixed bottom-0 left-0 right-0 h-[32px] z-[1] flex justify-center"
758
+ }, /* @__PURE__ */ React12.createElement(Surface8, {
759
+ role: "hints",
760
+ limit: 1
761
+ })), /* @__PURE__ */ React12.createElement(Popover2.Portal, null, /* @__PURE__ */ React12.createElement(Popover2.Content, {
762
+ classNames: "z-[60]",
763
+ onEscapeKeyDown: () => {
764
+ context.popoverOpen = false;
765
+ context.popoverAnchorId = void 0;
766
+ }
767
+ }, /* @__PURE__ */ React12.createElement(Popover2.Viewport, null, /* @__PURE__ */ React12.createElement(Surface8, {
768
+ role: "popover",
769
+ data: popoverContent
770
+ })), /* @__PURE__ */ React12.createElement(Popover2.Arrow, null))), /* @__PURE__ */ React12.createElement(Dialog.Root, {
771
+ open: dialogOpen,
772
+ onOpenChange: (nextOpen) => context.dialogOpen = nextOpen
773
+ }, /* @__PURE__ */ React12.createElement(Dialog.Overlay, {
774
+ blockAlign: dialogBlockAlign
775
+ }, /* @__PURE__ */ React12.createElement(Surface8, {
776
+ role: "dialog",
777
+ data: dialogContent
778
+ }))), toasts?.map((toast) => /* @__PURE__ */ React12.createElement(Toast, {
779
+ ...toast,
780
+ key: toast.id,
781
+ onOpenChange: (open) => {
782
+ if (!open) {
783
+ onDismissToast(toast.id);
784
+ }
785
+ return open;
786
+ }
787
+ }))));
788
+ };
789
+
790
+ // packages/plugins/plugin-deck/src/components/LayoutSettings.tsx
791
+ import React13 from "react";
792
+ import { SettingsValue } from "@dxos/plugin-settings";
793
+ import { Input, Select, useTranslation as useTranslation6 } from "@dxos/react-ui";
794
+
795
+ // packages/plugins/plugin-deck/src/types.ts
796
+ var NewPlankPositions = [
797
+ "start",
798
+ "end"
799
+ ];
800
+ var OverscrollOptions = [
801
+ "none",
802
+ "centering"
803
+ ];
804
+
805
+ // packages/plugins/plugin-deck/src/components/LayoutSettings.tsx
806
+ var isSocket = !!globalThis.__args;
807
+ var LayoutSettings = ({ settings }) => {
808
+ const { t } = useTranslation6(DECK_PLUGIN);
809
+ return /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(SettingsValue, {
810
+ label: t("select new plank positioning label")
811
+ }, /* @__PURE__ */ React13.createElement(Select.Root, {
812
+ value: settings.newPlankPositioning ?? "start",
813
+ onValueChange: (value) => settings.newPlankPositioning = value
814
+ }, /* @__PURE__ */ React13.createElement(Select.TriggerButton, {
815
+ placeholder: t("select new plank positioning placeholder")
816
+ }), /* @__PURE__ */ React13.createElement(Select.Portal, null, /* @__PURE__ */ React13.createElement(Select.Content, null, /* @__PURE__ */ React13.createElement(Select.Viewport, null, NewPlankPositions.map((position) => /* @__PURE__ */ React13.createElement(Select.Option, {
817
+ key: position,
818
+ value: position
819
+ }, t(`settings new plank position ${position} label`)))))))), /* @__PURE__ */ React13.createElement(SettingsValue, {
820
+ label: t("settings overscroll label")
821
+ }, /* @__PURE__ */ React13.createElement(Select.Root, {
822
+ value: settings.overscroll ?? "none",
823
+ onValueChange: (value) => settings.overscroll = value
824
+ }, /* @__PURE__ */ React13.createElement(Select.TriggerButton, {
825
+ placeholder: t("select overscroll placeholder")
826
+ }), /* @__PURE__ */ React13.createElement(Select.Portal, null, /* @__PURE__ */ React13.createElement(Select.Content, null, /* @__PURE__ */ React13.createElement(Select.Viewport, null, OverscrollOptions.map((option) => /* @__PURE__ */ React13.createElement(Select.Option, {
827
+ key: option,
828
+ value: option
829
+ }, t(`settings overscroll ${option} label`)))))))), /* @__PURE__ */ React13.createElement(SettingsValue, {
830
+ label: t("settings show footer label")
831
+ }, /* @__PURE__ */ React13.createElement(Input.Switch, {
832
+ checked: settings.showFooter,
833
+ onCheckedChange: (checked) => settings.showFooter = !!checked
834
+ })), !isSocket && /* @__PURE__ */ React13.createElement(SettingsValue, {
835
+ label: t("settings native redirect label")
836
+ }, /* @__PURE__ */ React13.createElement(Input.Switch, {
837
+ checked: settings.enableNativeRedirect,
838
+ onCheckedChange: (checked) => settings.enableNativeRedirect = !!checked
839
+ })), /* @__PURE__ */ React13.createElement(SettingsValue, {
840
+ label: t("settings custom slots")
841
+ }, /* @__PURE__ */ React13.createElement(Input.Switch, {
842
+ checked: settings.customSlots,
843
+ onCheckedChange: (checked) => settings.customSlots = !!checked
844
+ })), /* @__PURE__ */ React13.createElement(SettingsValue, {
845
+ label: t("settings flat deck")
846
+ }, /* @__PURE__ */ React13.createElement(Input.Switch, {
847
+ checked: settings.flatDeck,
848
+ onCheckedChange: (checked) => settings.flatDeck = !!checked
849
+ })));
850
+ };
851
+
852
+ // packages/plugins/plugin-deck/src/layout.ts
853
+ import { produce } from "immer";
854
+ import { SLUG_ENTRY_SEPARATOR, SLUG_KEY_VALUE_SEPARATOR, SLUG_LIST_SEPARATOR, SLUG_PATH_SEPARATOR as SLUG_PATH_SEPARATOR4 } from "@dxos/app-framework";
855
+ var partsThatSupportIncrement = [
856
+ "main"
857
+ ];
858
+ var openEntry = (layout, part, entry, options) => {
859
+ return produce(layout, (draft) => {
860
+ const layoutPart = draft[part];
861
+ if (!layoutPart) {
862
+ draft[part] = [
863
+ entry
864
+ ];
865
+ return;
866
+ }
867
+ if (part === "main") {
868
+ if (layoutPart.find((e) => e.id === entry.id)) {
869
+ return;
870
+ }
871
+ const plankPositioning = options?.positioning ?? "start";
872
+ const pivotId = options?.pivotId;
873
+ if (pivotId) {
874
+ const pivotIndex = layoutPart.findIndex((e) => e.id === pivotId);
875
+ if (pivotIndex !== -1) {
876
+ if (plankPositioning === "start") {
877
+ layoutPart.splice(pivotIndex, 0, entry);
878
+ } else {
879
+ layoutPart.splice(pivotIndex + 1, 0, entry);
880
+ }
881
+ return;
882
+ }
883
+ }
884
+ if (plankPositioning === "start") {
885
+ layoutPart.unshift(entry);
886
+ } else {
887
+ layoutPart.push(entry);
888
+ }
889
+ } else {
890
+ draft[part] = [
891
+ entry
892
+ ];
893
+ }
894
+ });
895
+ };
896
+ var closeEntry = (layout, layoutCoordinate) => {
897
+ return produce(layout, (draft) => {
898
+ const { part, entryId: slugId } = layoutCoordinate;
899
+ const layoutPart = draft[part];
900
+ if (!layoutPart) {
901
+ return;
902
+ }
903
+ const index = layoutPart.findIndex((entry) => entry.id === slugId);
904
+ if (index === -1) {
905
+ return;
906
+ }
907
+ if (layoutPart.length === 1) {
908
+ delete draft[part];
909
+ } else {
910
+ layoutPart.splice(index, 1);
911
+ }
912
+ });
913
+ };
914
+ var incrementPlank = (layout, adjustment) => {
915
+ return produce(layout, (draft) => {
916
+ const { layoutCoordinate, type } = adjustment;
917
+ const { part, entryId } = layoutCoordinate;
918
+ if (partsThatSupportIncrement.includes(part) === false) {
919
+ return;
920
+ }
921
+ const layoutPart = draft[part];
922
+ if (!layoutPart) {
923
+ return;
924
+ }
925
+ const index = layoutPart.findIndex((entry) => entry.id === entryId);
926
+ if (index === -1 || type === "increment-start" && index === 0 || type === "increment-end" && index === layoutPart.length - 1) {
927
+ return;
928
+ }
929
+ if (type === "increment-start") {
930
+ [layoutPart[index - 1], layoutPart[index]] = [
931
+ layoutPart[index],
932
+ layoutPart[index - 1]
933
+ ];
934
+ } else if (type === "increment-end") {
935
+ [layoutPart[index], layoutPart[index + 1]] = [
936
+ layoutPart[index + 1],
937
+ layoutPart[index]
938
+ ];
939
+ }
940
+ });
941
+ };
942
+ var removePart = (layout, part) => {
943
+ return produce(layout, (draft) => {
944
+ delete draft[part];
945
+ });
946
+ };
947
+ var mergeLayoutParts = (...layoutParts) => {
948
+ return layoutParts.reduce((merged, current) => produce(merged, (draft) => {
949
+ Object.entries(current).forEach(([part, entries]) => {
950
+ const typedPart = part;
951
+ if (!draft[typedPart]) {
952
+ draft[typedPart] = [];
953
+ }
954
+ const partEntries = draft[typedPart];
955
+ entries.forEach((entry) => {
956
+ const existingIndex = partEntries.findIndex((e) => e.id === entry.id);
957
+ if (existingIndex !== -1) {
958
+ partEntries[existingIndex] = entry;
959
+ } else {
960
+ partEntries.push(entry);
961
+ }
962
+ });
963
+ });
964
+ }), {});
965
+ };
966
+ var parseLayoutEntry = (itemString) => {
967
+ const [id, path] = itemString.split(SLUG_PATH_SEPARATOR4);
968
+ const entry = {
969
+ id
970
+ };
971
+ if (path) {
972
+ entry.path = path;
973
+ }
974
+ return entry;
975
+ };
976
+ var uriToSoloPart = (uri) => {
977
+ const parts = uri.split("/");
978
+ const slug = parts[parts.length - 1];
979
+ if (slug.length > 0) {
980
+ return {
981
+ solo: [
982
+ parseLayoutEntry(slug)
983
+ ]
984
+ };
985
+ }
986
+ return void 0;
987
+ };
988
+ var soloPartToUri = (layout) => {
989
+ const soloPart = layout?.solo;
990
+ if (!soloPart || soloPart.length === 0) {
991
+ return "";
992
+ }
993
+ const entry = soloPart[0];
994
+ return `${entry.id}${entry.path ? SLUG_PATH_SEPARATOR4 + entry.path : ""}`;
995
+ };
996
+
997
+ // packages/plugins/plugin-deck/src/translations.ts
998
+ var translations_default = [
999
+ {
1000
+ "en-US": {
1001
+ [DECK_PLUGIN]: {
1002
+ "main header label": "Main header",
1003
+ "open navigation sidebar label": "Open navigation sidebar.",
1004
+ "open complementary sidebar label": "Open complementary sidebar.",
1005
+ "open settings label": "Show settings",
1006
+ "plugin error message": "Content failed to render.",
1007
+ "content fallback message": "Unsupported",
1008
+ "content fallback description": "No plugin had a response for the address you navigated\xA0to. Double-check the URL, and ensure you\u2019ve enabled a plugin that supports the\xA0object.",
1009
+ "toggle fullscreen label": "Toggle fullscreen",
1010
+ "settings show footer label": "Show footer (experimental)",
1011
+ "settings native redirect label": "Enable native url redirect (experimental)",
1012
+ "settings custom slots": "Theme option (experimental)",
1013
+ "settings new plank position start label": "Start",
1014
+ "settings new plank position end label": "End",
1015
+ "select new plank positioning placeholder": "Select new plank positioning",
1016
+ "select new plank positioning label": "New plank positioning",
1017
+ "undo available label": "Click to undo previous action.",
1018
+ "undo action label": "Undo",
1019
+ "undo action alt": "Undo previous action",
1020
+ "undo close label": "Dismiss",
1021
+ "open comments label": "Open comments",
1022
+ "error fallback message": "Unable to open this item",
1023
+ "plank heading fallback label": "Untitled",
1024
+ "actions menu label": "Options",
1025
+ "settings deck label": "Disable Deck",
1026
+ "reload required message": "Reload required.",
1027
+ "pending heading": "Loading\u2026",
1028
+ "insert plank label": "Open",
1029
+ "solo plank label": "Solo",
1030
+ "settings overscroll label": "Plank Overscrolling",
1031
+ "select overscroll placeholder": "Select plank overscrolling behavior",
1032
+ "settings overscroll centering label": "Centering",
1033
+ "settings overscroll none label": "None",
1034
+ "settings flat deck": "Flatten deck appearance"
1035
+ }
1036
+ }
1037
+ }
1038
+ ];
1039
+
1040
+ // packages/plugins/plugin-deck/src/DeckPlugin.tsx
1041
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-deck/src/DeckPlugin.tsx";
1042
+ var isSocket2 = !!globalThis.__args;
1043
+ var appScheme = "composer://";
1044
+ var customSlots = {
1045
+ wallpaper: {
1046
+ classNames: "bg-cover bg-no-repeat dark:bg-[url(https://cdn.midjourney.com/3865ba61-f98a-4d94-b91a-1763ead01f4f/0_0.jpeg)]"
1047
+ },
1048
+ deck: {
1049
+ classNames: "px-96 bg-neutral-50 __dark:bg-neutral-950 dark:bg-transparent dark:opacity-95"
1050
+ },
1051
+ plank: {
1052
+ classNames: "mx-1 bg-neutral-25 dark:bg-neutral-900"
1053
+ }
1054
+ };
1055
+ setAutoFreeze(false);
1056
+ var DECK_ACTION = "dxos.org/plugin/deck";
1057
+ var DeckAction;
1058
+ (function(DeckAction2) {
1059
+ DeckAction2[DeckAction2["UPDATE_PLANK_SIZE"] = `${DECK_ACTION}/update-plank-size`] = "UPDATE_PLANK_SIZE";
1060
+ })(DeckAction || (DeckAction = {}));
1061
+ var DeckPlugin = ({ observability } = {}) => {
1062
+ let graphPlugin;
1063
+ let intentPlugin;
1064
+ let attentionPlugin;
1065
+ let clientPlugin;
1066
+ const unsubscriptionCallbacks = [];
1067
+ let currentUndoId;
1068
+ let handleNavigation;
1069
+ const settings = new LocalStorageStore("dxos.org/settings/layout", {
1070
+ showFooter: false,
1071
+ customSlots: false,
1072
+ flatDeck: false,
1073
+ enableNativeRedirect: false,
1074
+ disableDeck: false,
1075
+ newPlankPositioning: "start",
1076
+ overscroll: "centering"
1077
+ });
1078
+ const layout = new LocalStorageStore("dxos.org/settings/layout", {
1079
+ layoutMode: "solo",
1080
+ sidebarOpen: true,
1081
+ complementarySidebarOpen: false,
1082
+ dialogContent: null,
1083
+ dialogOpen: false,
1084
+ dialogBlockAlign: void 0,
1085
+ popoverContent: null,
1086
+ popoverAnchorId: void 0,
1087
+ popoverOpen: false,
1088
+ toasts: []
1089
+ });
1090
+ const deck = new LocalStorageStore("dxos.org/settings/deck", {
1091
+ plankSizing: {}
1092
+ });
1093
+ const location = new LocalStorageStore("dxos.org/state/layout", {
1094
+ active: {
1095
+ sidebar: [
1096
+ {
1097
+ id: NAV_ID
1098
+ }
1099
+ ]
1100
+ },
1101
+ closed: []
1102
+ });
1103
+ const layoutModeHistory = create({
1104
+ values: []
1105
+ });
1106
+ const handleSetLayout = ({ element, state, component, subject, anchorId, dialogBlockAlign }) => {
1107
+ switch (element) {
1108
+ case "sidebar": {
1109
+ layout.values.sidebarOpen = state ?? !layout.values.sidebarOpen;
1110
+ return {
1111
+ data: true
1112
+ };
1113
+ }
1114
+ case "complementary": {
1115
+ layout.values.complementarySidebarOpen = !!state;
1116
+ return {
1117
+ data: true
1118
+ };
1119
+ }
1120
+ case "dialog": {
1121
+ layout.values.dialogOpen = state ?? Boolean(component);
1122
+ layout.values.dialogContent = component ? {
1123
+ component,
1124
+ subject
1125
+ } : null;
1126
+ layout.values.dialogBlockAlign = dialogBlockAlign ?? "center";
1127
+ return {
1128
+ data: true
1129
+ };
1130
+ }
1131
+ case "popover": {
1132
+ layout.values.popoverOpen = state ?? Boolean(component);
1133
+ layout.values.popoverContent = component ? {
1134
+ component,
1135
+ subject
1136
+ } : null;
1137
+ layout.values.popoverAnchorId = anchorId;
1138
+ return {
1139
+ data: true
1140
+ };
1141
+ }
1142
+ case "toast": {
1143
+ if (ToastSchema.safeParse(subject).success) {
1144
+ layout.values.toasts = [
1145
+ ...layout.values.toasts,
1146
+ subject
1147
+ ];
1148
+ return {
1149
+ data: true
1150
+ };
1151
+ }
1152
+ }
1153
+ }
1154
+ };
1155
+ return {
1156
+ meta: meta_default,
1157
+ ready: async (plugins) => {
1158
+ intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
1159
+ graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
1160
+ attentionPlugin = resolvePlugin(plugins, parseAttentionPlugin);
1161
+ clientPlugin = resolvePlugin(plugins, parseClientPlugin);
1162
+ layout.prop({
1163
+ key: "layoutMode",
1164
+ storageKey: "layout-mode",
1165
+ type: LocalStorageStore.enum()
1166
+ }).prop({
1167
+ key: "sidebarOpen",
1168
+ storageKey: "sidebar-open",
1169
+ type: LocalStorageStore.bool()
1170
+ }).prop({
1171
+ key: "complementarySidebarOpen",
1172
+ storageKey: "complementary-sidebar-open",
1173
+ type: LocalStorageStore.bool()
1174
+ });
1175
+ deck.prop({
1176
+ key: "plankSizing",
1177
+ storageKey: "plank-sizing",
1178
+ type: LocalStorageStore.json()
1179
+ });
1180
+ location.prop({
1181
+ key: "active",
1182
+ storageKey: "active",
1183
+ type: LocalStorageStore.json()
1184
+ }).prop({
1185
+ key: "closed",
1186
+ storageKey: "closed",
1187
+ type: LocalStorageStore.json()
1188
+ });
1189
+ unsubscriptionCallbacks.push(clientPlugin?.provides.client.shell.onReset(() => {
1190
+ layout.expunge();
1191
+ location.expunge();
1192
+ deck.expunge();
1193
+ }));
1194
+ settings.prop({
1195
+ key: "showFooter",
1196
+ storageKey: "show-footer",
1197
+ type: LocalStorageStore.bool()
1198
+ }).prop({
1199
+ key: "customSlots",
1200
+ storageKey: "customSlots",
1201
+ type: LocalStorageStore.bool()
1202
+ }).prop({
1203
+ key: "flatDeck",
1204
+ storageKey: "flatDeck",
1205
+ type: LocalStorageStore.bool()
1206
+ }).prop({
1207
+ key: "enableNativeRedirect",
1208
+ storageKey: "enable-native-redirect",
1209
+ type: LocalStorageStore.bool()
1210
+ }).prop({
1211
+ key: "disableDeck",
1212
+ storageKey: "disable-deck",
1213
+ type: LocalStorageStore.bool()
1214
+ }).prop({
1215
+ key: "newPlankPositioning",
1216
+ storageKey: "newPlankPositioning",
1217
+ type: LocalStorageStore.enum()
1218
+ }).prop({
1219
+ key: "overscroll",
1220
+ storageKey: "overscroll",
1221
+ type: LocalStorageStore.enum()
1222
+ });
1223
+ if (!isSocket2 && settings.values.enableNativeRedirect) {
1224
+ checkAppScheme(appScheme);
1225
+ }
1226
+ handleNavigation = async () => {
1227
+ const layoutFromUri = uriToSoloPart(window.location.pathname);
1228
+ if (!layoutFromUri) {
1229
+ return;
1230
+ }
1231
+ const startingLayout = removePart(location.values.active, "solo");
1232
+ location.values.active = mergeLayoutParts(layoutFromUri, startingLayout);
1233
+ layout.values.layoutMode = "solo";
1234
+ };
1235
+ await handleNavigation();
1236
+ window.addEventListener("popstate", handleNavigation);
1237
+ unsubscriptionCallbacks.push(effect(() => {
1238
+ const selectedPath = soloPartToUri(location.values.active);
1239
+ history.pushState(null, "", `/${selectedPath}${window.location.search}`);
1240
+ }));
1241
+ unsubscriptionCallbacks.push(effect(() => {
1242
+ const soloId = location.values.active.solo?.[0].id;
1243
+ if (layout.values.layoutMode === "solo" && soloId && layout.values.scrollIntoView !== soloId) {
1244
+ void intentPlugin?.provides.intent.dispatch({
1245
+ action: LayoutAction3.SCROLL_INTO_VIEW,
1246
+ data: {
1247
+ id: soloId
1248
+ }
1249
+ });
1250
+ }
1251
+ }));
1252
+ layoutModeHistory.values.push(`${layout.values.layoutMode}`);
1253
+ },
1254
+ unload: async () => {
1255
+ layout.close();
1256
+ location.close();
1257
+ unsubscriptionCallbacks.forEach((unsubscribe) => unsubscribe?.());
1258
+ window.removeEventListener("popstate", handleNavigation);
1259
+ },
1260
+ provides: {
1261
+ settings: settings.values,
1262
+ layout: layout.values,
1263
+ location: location.values,
1264
+ translations: [
1265
+ ...translations_default,
1266
+ ...deckTranslations
1267
+ ],
1268
+ graph: {
1269
+ builder: () => {
1270
+ return createExtension({
1271
+ id: DECK_PLUGIN,
1272
+ filter: (node) => node.id === "root",
1273
+ actions: () => [
1274
+ {
1275
+ id: `${LayoutAction3.SET_LAYOUT_MODE}/fullscreen`,
1276
+ data: async () => {
1277
+ await intentPlugin?.provides.intent.dispatch({
1278
+ plugin: DECK_PLUGIN,
1279
+ action: LayoutAction3.SET_LAYOUT_MODE,
1280
+ data: {
1281
+ layoutMode: "fullscreen"
1282
+ }
1283
+ });
1284
+ },
1285
+ properties: {
1286
+ label: [
1287
+ "toggle fullscreen label",
1288
+ {
1289
+ ns: DECK_PLUGIN
1290
+ }
1291
+ ],
1292
+ icon: (props) => /* @__PURE__ */ React14.createElement(ArrowsOut, props),
1293
+ iconSymbol: "ph--arrows-out--regular",
1294
+ keyBinding: {
1295
+ macos: "ctrl+meta+f",
1296
+ windows: "shift+ctrl+f"
1297
+ }
1298
+ }
1299
+ }
1300
+ ]
1301
+ });
1302
+ }
1303
+ },
1304
+ context: (props) => /* @__PURE__ */ React14.createElement(LayoutContext.Provider, {
1305
+ value: layout.values
1306
+ }, /* @__PURE__ */ React14.createElement(DeckContext.Provider, {
1307
+ value: deck.values
1308
+ }, props.children)),
1309
+ root: () => {
1310
+ return /* @__PURE__ */ React14.createElement(Mosaic.Root, null, /* @__PURE__ */ React14.createElement(DeckLayout, {
1311
+ attention: attentionPlugin?.provides.attention ?? {
1312
+ attended: /* @__PURE__ */ new Set()
1313
+ },
1314
+ layoutParts: location.values.active,
1315
+ overscroll: settings.values.overscroll,
1316
+ flatDeck: settings.values.flatDeck,
1317
+ showHintsFooter: settings.values.showFooter,
1318
+ slots: settings.values.customSlots ? customSlots : void 0,
1319
+ toasts: layout.values.toasts,
1320
+ onDismissToast: (id) => {
1321
+ const index = layout.values.toasts.findIndex((toast) => toast.id === id);
1322
+ if (index !== -1) {
1323
+ setTimeout(() => {
1324
+ if (layout.values.toasts[index].id === currentUndoId) {
1325
+ currentUndoId = void 0;
1326
+ }
1327
+ layout.values.toasts.splice(index, 1);
1328
+ }, 1e3);
1329
+ }
1330
+ }
1331
+ }), /* @__PURE__ */ React14.createElement(Mosaic.DragOverlay, null));
1332
+ },
1333
+ surface: {
1334
+ component: ({ data, role }) => {
1335
+ switch (role) {
1336
+ case "settings":
1337
+ return data.plugin === meta_default.id ? /* @__PURE__ */ React14.createElement(LayoutSettings, {
1338
+ settings: settings.values
1339
+ }) : null;
1340
+ }
1341
+ return null;
1342
+ }
1343
+ },
1344
+ intent: {
1345
+ resolver: (intent) => {
1346
+ switch (intent.action) {
1347
+ case LayoutAction3.SET_LAYOUT: {
1348
+ return intent.data && handleSetLayout(intent.data);
1349
+ }
1350
+ case LayoutAction3.SET_LAYOUT_MODE: {
1351
+ return batch(() => {
1352
+ if (!intent.data) {
1353
+ return;
1354
+ }
1355
+ if (intent.data?.revert) {
1356
+ layout.values.layoutMode = layoutModeHistory.values.pop() ?? "solo";
1357
+ return {
1358
+ data: true
1359
+ };
1360
+ }
1361
+ if (isLayoutMode(intent?.data?.layoutMode)) {
1362
+ layoutModeHistory.values.push(layout.values.layoutMode);
1363
+ layout.values.layoutMode = intent.data.layoutMode;
1364
+ } else {
1365
+ log.warn("Invalid layout mode", intent?.data?.layoutMode, {
1366
+ F: __dxlog_file,
1367
+ L: 384,
1368
+ S: void 0,
1369
+ C: (f, a) => f(...a)
1370
+ });
1371
+ }
1372
+ return {
1373
+ data: true
1374
+ };
1375
+ });
1376
+ }
1377
+ case LayoutAction3.SCROLL_INTO_VIEW: {
1378
+ layout.values.scrollIntoView = intent.data?.id ?? void 0;
1379
+ return void 0;
1380
+ }
1381
+ case DeckAction.UPDATE_PLANK_SIZE: {
1382
+ const { id, size } = intent.data;
1383
+ deck.values.plankSizing[id] = size;
1384
+ return {
1385
+ data: true
1386
+ };
1387
+ }
1388
+ case IntentAction.SHOW_UNDO: {
1389
+ if (currentUndoId) {
1390
+ layout.values.toasts = layout.values.toasts.filter((toast) => toast.id !== currentUndoId);
1391
+ }
1392
+ currentUndoId = `${IntentAction.SHOW_UNDO}-${Date.now()}`;
1393
+ const title = (
1394
+ // TODO(wittjosiah): How to handle chains better?
1395
+ intent.data?.results?.[0]?.result?.undoable?.message ?? translations_default[0]["en-US"]["dxos.org/plugin/deck"]["undo available label"]
1396
+ );
1397
+ layout.values.toasts = [
1398
+ ...layout.values.toasts,
1399
+ {
1400
+ id: currentUndoId,
1401
+ title,
1402
+ duration: 1e4,
1403
+ actionLabel: translations_default[0]["en-US"]["dxos.org/plugin/deck"]["undo action label"],
1404
+ actionAlt: translations_default[0]["en-US"]["dxos.org/plugin/deck"]["undo action alt"],
1405
+ closeLabel: translations_default[0]["en-US"]["dxos.org/plugin/deck"]["undo close label"],
1406
+ onAction: () => intentPlugin?.provides.intent.undo?.()
1407
+ }
1408
+ ];
1409
+ return {
1410
+ data: true
1411
+ };
1412
+ }
1413
+ case NavigationAction3.OPEN: {
1414
+ const previouslyOpenIds = new Set(openIds2(location.values.active));
1415
+ const layoutMode = layout.values.layoutMode;
1416
+ batch(() => {
1417
+ if (!intent.data || !intent.data?.activeParts) {
1418
+ return;
1419
+ }
1420
+ const newPlankPositioning = settings.values.newPlankPositioning;
1421
+ const processLayoutEntry = (partName, entryString, currentLayout) => {
1422
+ const [id, path] = entryString.split(SLUG_PATH_SEPARATOR5);
1423
+ const layoutEntry = {
1424
+ id,
1425
+ ...path ? {
1426
+ path
1427
+ } : {}
1428
+ };
1429
+ const effectivePart = getEffectivePart(partName, layoutMode);
1430
+ if (layoutMode === "deck" && effectivePart === "main" && currentLayout[effectivePart]?.some((entry) => entry.id === id) && !intent.data?.noToggle) {
1431
+ return closeEntry(currentLayout, {
1432
+ part: effectivePart,
1433
+ entryId: id
1434
+ });
1435
+ } else {
1436
+ return openEntry(currentLayout, effectivePart, layoutEntry, {
1437
+ positioning: newPlankPositioning
1438
+ });
1439
+ }
1440
+ };
1441
+ let newLayout = location.values.active;
1442
+ Object.entries(intent.data.activeParts).forEach(([partName, layoutEntries]) => {
1443
+ if (Array.isArray(layoutEntries)) {
1444
+ layoutEntries.forEach((activePartEntry) => {
1445
+ newLayout = processLayoutEntry(partName, activePartEntry, newLayout);
1446
+ });
1447
+ } else if (typeof layoutEntries === "string") {
1448
+ newLayout = processLayoutEntry(partName, layoutEntries, newLayout);
1449
+ }
1450
+ });
1451
+ location.values.active = newLayout;
1452
+ });
1453
+ const ids = openIds2(location.values.active);
1454
+ const newlyOpen = ids.filter((i) => !previouslyOpenIds.has(i));
1455
+ return {
1456
+ data: {
1457
+ ids
1458
+ },
1459
+ intents: [
1460
+ newlyOpen.length > 0 ? [
1461
+ {
1462
+ action: LayoutAction3.SCROLL_INTO_VIEW,
1463
+ data: {
1464
+ id: newlyOpen[0]
1465
+ }
1466
+ }
1467
+ ] : [],
1468
+ intent.data?.object ? [
1469
+ {
1470
+ action: NavigationAction3.EXPOSE,
1471
+ data: {
1472
+ id: fullyQualifiedId(intent.data.object)
1473
+ }
1474
+ }
1475
+ ] : [],
1476
+ observability ? newlyOpen.map((id) => {
1477
+ const active = graphPlugin?.provides.graph.findNode(id)?.data;
1478
+ const typename = isReactiveObject(active) ? getTypename(active) : void 0;
1479
+ return {
1480
+ action: ObservabilityAction.SEND_EVENT,
1481
+ data: {
1482
+ name: "navigation.activate",
1483
+ properties: {
1484
+ id,
1485
+ typename
1486
+ }
1487
+ }
1488
+ };
1489
+ }) : []
1490
+ ]
1491
+ };
1492
+ }
1493
+ case NavigationAction3.ADD_TO_ACTIVE: {
1494
+ const data = intent.data;
1495
+ const layoutEntry = {
1496
+ id: data.id
1497
+ };
1498
+ const effectivePart = getEffectivePart(data.part, layout.values.layoutMode);
1499
+ location.values.active = openEntry(location.values.active, effectivePart, layoutEntry, {
1500
+ positioning: data.positioning ?? settings.values.newPlankPositioning,
1501
+ pivotId: data.pivotId
1502
+ });
1503
+ const intents = [];
1504
+ if (data.scrollIntoView && layout.values.layoutMode === "deck") {
1505
+ intents.push([
1506
+ {
1507
+ action: LayoutAction3.SCROLL_INTO_VIEW,
1508
+ data: {
1509
+ id: data.id
1510
+ }
1511
+ }
1512
+ ]);
1513
+ }
1514
+ return {
1515
+ data: true,
1516
+ intents
1517
+ };
1518
+ }
1519
+ case NavigationAction3.CLOSE: {
1520
+ return batch(() => {
1521
+ if (!intent.data) {
1522
+ return;
1523
+ }
1524
+ let newLayout = location.values.active;
1525
+ const layoutMode = layout.values.layoutMode;
1526
+ const intentParts = intent.data.activeParts;
1527
+ Object.keys(intentParts).forEach((partName) => {
1528
+ const effectivePart = getEffectivePart(partName, layoutMode);
1529
+ const ids = intentParts[partName];
1530
+ if (Array.isArray(ids)) {
1531
+ ids.forEach((id) => {
1532
+ newLayout = closeEntry(newLayout, {
1533
+ part: effectivePart,
1534
+ entryId: id
1535
+ });
1536
+ });
1537
+ } else {
1538
+ newLayout = closeEntry(newLayout, {
1539
+ part: effectivePart,
1540
+ entryId: ids
1541
+ });
1542
+ }
1543
+ });
1544
+ location.values.active = newLayout;
1545
+ return {
1546
+ data: true
1547
+ };
1548
+ });
1549
+ }
1550
+ case NavigationAction3.SET: {
1551
+ return batch(() => {
1552
+ if (isLayoutParts(intent.data?.activeParts)) {
1553
+ location.values.active = intent.data.activeParts;
1554
+ }
1555
+ return {
1556
+ data: true
1557
+ };
1558
+ });
1559
+ }
1560
+ case NavigationAction3.ADJUST: {
1561
+ return batch(() => {
1562
+ if (isLayoutAdjustment(intent.data)) {
1563
+ const adjustment = intent.data;
1564
+ if (adjustment.type === "increment-end" || adjustment.type === "increment-start") {
1565
+ const nextActive = incrementPlank(location.values.active, {
1566
+ type: adjustment.type,
1567
+ layoutCoordinate: adjustment.layoutCoordinate
1568
+ });
1569
+ location.values.active = nextActive;
1570
+ }
1571
+ if (adjustment.type === "solo") {
1572
+ const entryId = adjustment.layoutCoordinate.entryId;
1573
+ if (layout.values.layoutMode !== "solo") {
1574
+ return {
1575
+ data: true,
1576
+ intents: [
1577
+ [
1578
+ {
1579
+ action: LayoutAction3.SET_LAYOUT_MODE,
1580
+ data: {
1581
+ layoutMode: "solo"
1582
+ }
1583
+ },
1584
+ {
1585
+ action: NavigationAction3.OPEN,
1586
+ data: {
1587
+ activeParts: {
1588
+ solo: [
1589
+ entryId
1590
+ ]
1591
+ }
1592
+ }
1593
+ }
1594
+ ]
1595
+ ]
1596
+ };
1597
+ } else {
1598
+ return {
1599
+ data: true,
1600
+ intents: [
1601
+ [
1602
+ {
1603
+ action: LayoutAction3.SET_LAYOUT_MODE,
1604
+ data: {
1605
+ layoutMode: "deck"
1606
+ }
1607
+ },
1608
+ {
1609
+ action: NavigationAction3.CLOSE,
1610
+ data: {
1611
+ activeParts: {
1612
+ solo: [
1613
+ entryId
1614
+ ]
1615
+ }
1616
+ }
1617
+ },
1618
+ {
1619
+ action: NavigationAction3.OPEN,
1620
+ data: {
1621
+ noToggle: true,
1622
+ activeParts: {
1623
+ main: [
1624
+ entryId
1625
+ ]
1626
+ }
1627
+ }
1628
+ },
1629
+ {
1630
+ action: LayoutAction3.SCROLL_INTO_VIEW,
1631
+ data: {
1632
+ id: entryId
1633
+ }
1634
+ }
1635
+ ]
1636
+ ]
1637
+ };
1638
+ }
1639
+ }
1640
+ }
1641
+ });
1642
+ }
1643
+ }
1644
+ }
1645
+ }
1646
+ }
1647
+ };
1648
+ };
1649
+
1650
+ // packages/plugins/plugin-deck/src/index.ts
1651
+ var src_default = DeckPlugin;
1652
+ export {
1653
+ DeckAction,
1654
+ DeckPlugin,
1655
+ src_default as default
1656
+ };
1657
+ //# sourceMappingURL=index.mjs.map