@dxos/plugin-deck 0.7.5-main.9d26e3a → 0.7.5-main.e9bb01b

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 (168) hide show
  1. package/dist/lib/browser/app-graph-builder-CI6ZFMNL.mjs +147 -0
  2. package/dist/lib/browser/app-graph-builder-CI6ZFMNL.mjs.map +7 -0
  3. package/dist/lib/browser/check-app-scheme-S3EYUPMF.mjs +33 -0
  4. package/dist/lib/browser/check-app-scheme-S3EYUPMF.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-M2L53AIH.mjs +126 -0
  6. package/dist/lib/browser/chunk-M2L53AIH.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-GVOGPULO.mjs → chunk-N7TEPFVR.mjs} +5 -4
  8. package/dist/lib/browser/chunk-N7TEPFVR.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-NYZJCVAU.mjs +22 -0
  10. package/dist/lib/browser/chunk-NYZJCVAU.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-WXNLVMK2.mjs +1119 -0
  12. package/dist/lib/browser/chunk-WXNLVMK2.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-YQ2GWTDU.mjs +17 -0
  14. package/dist/lib/browser/chunk-YQ2GWTDU.mjs.map +7 -0
  15. package/dist/lib/browser/index.mjs +90 -1775
  16. package/dist/lib/browser/index.mjs.map +4 -4
  17. package/dist/lib/browser/intent-resolver-CSXFDKTC.mjs +494 -0
  18. package/dist/lib/browser/intent-resolver-CSXFDKTC.mjs.map +7 -0
  19. package/dist/lib/browser/meta.json +1 -1
  20. package/dist/lib/browser/react-root-ECDQZYQT.mjs +46 -0
  21. package/dist/lib/browser/react-root-ECDQZYQT.mjs.map +7 -0
  22. package/dist/lib/browser/react-surface-4WIQZW2S.mjs +38 -0
  23. package/dist/lib/browser/react-surface-4WIQZW2S.mjs.map +7 -0
  24. package/dist/lib/browser/settings-WACNLCPB.mjs +28 -0
  25. package/dist/lib/browser/settings-WACNLCPB.mjs.map +7 -0
  26. package/dist/lib/browser/state-VPOYUKK6.mjs +117 -0
  27. package/dist/lib/browser/state-VPOYUKK6.mjs.map +7 -0
  28. package/dist/lib/browser/types.mjs +16 -4
  29. package/dist/lib/browser/url-handler-HLF42IHP.mjs +70 -0
  30. package/dist/lib/browser/url-handler-HLF42IHP.mjs.map +7 -0
  31. package/dist/types/src/DeckPlugin.d.ts +1 -5
  32. package/dist/types/src/DeckPlugin.d.ts.map +1 -1
  33. package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
  34. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  35. package/dist/types/src/capabilities/capabilities.d.ts +142 -0
  36. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
  37. package/dist/types/src/capabilities/check-app-scheme.d.ts +4 -0
  38. package/dist/types/src/capabilities/check-app-scheme.d.ts.map +1 -0
  39. package/dist/types/src/capabilities/index.d.ts +189 -0
  40. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  41. package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
  42. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  43. package/dist/types/src/capabilities/react-root.d.ts +7 -0
  44. package/dist/types/src/capabilities/react-root.d.ts.map +1 -0
  45. package/dist/types/src/capabilities/react-surface.d.ts +4 -0
  46. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  47. package/dist/types/src/capabilities/set-active.d.ts +9 -0
  48. package/dist/types/src/capabilities/set-active.d.ts.map +1 -0
  49. package/dist/types/src/capabilities/settings.d.ts +4 -0
  50. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  51. package/dist/types/src/capabilities/state.d.ts +76 -0
  52. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  53. package/dist/types/src/capabilities/url-handler.d.ts +4 -0
  54. package/dist/types/src/capabilities/url-handler.d.ts.map +1 -0
  55. package/dist/types/src/components/DeckLayout/ActiveNode.d.ts.map +1 -1
  56. package/dist/types/src/components/DeckLayout/Banner.d.ts +6 -0
  57. package/dist/types/src/components/DeckLayout/Banner.d.ts.map +1 -0
  58. package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts.map +1 -1
  59. package/dist/types/src/components/DeckLayout/ContentEmpty.d.ts.map +1 -1
  60. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts +1 -4
  61. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
  62. package/dist/types/src/components/DeckLayout/Fullscreen.d.ts.map +1 -1
  63. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts +3 -3
  64. package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts.map +1 -1
  65. package/dist/types/src/components/DeckLayout/Plank.d.ts +8 -6
  66. package/dist/types/src/components/DeckLayout/Plank.d.ts.map +1 -1
  67. package/dist/types/src/components/DeckLayout/PlankControls.d.ts +2 -2
  68. package/dist/types/src/components/DeckLayout/PlankControls.d.ts.map +1 -1
  69. package/dist/types/src/components/DeckLayout/PlankError.d.ts +4 -3
  70. package/dist/types/src/components/DeckLayout/PlankError.d.ts.map +1 -1
  71. package/dist/types/src/components/DeckLayout/Sidebar.d.ts +1 -5
  72. package/dist/types/src/components/DeckLayout/Sidebar.d.ts.map +1 -1
  73. package/dist/types/src/components/DeckLayout/SidebarButton.d.ts +8 -0
  74. package/dist/types/src/components/DeckLayout/SidebarButton.d.ts.map +1 -0
  75. package/dist/types/src/components/DeckLayout/StatusBar.d.ts.map +1 -1
  76. package/dist/types/src/components/DeckLayout/Toast.d.ts +2 -2
  77. package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
  78. package/dist/types/src/components/DeckLayout/Topbar.d.ts +3 -0
  79. package/dist/types/src/components/DeckLayout/Topbar.d.ts.map +1 -0
  80. package/dist/types/src/components/fragments.d.ts +4 -0
  81. package/dist/types/src/components/fragments.d.ts.map +1 -0
  82. package/dist/types/src/components/index.d.ts +0 -2
  83. package/dist/types/src/components/index.d.ts.map +1 -1
  84. package/dist/types/src/events.d.ts +4 -0
  85. package/dist/types/src/events.d.ts.map +1 -0
  86. package/dist/types/src/hooks/useMainSize.d.ts +2 -2
  87. package/dist/types/src/index.d.ts +3 -2
  88. package/dist/types/src/index.d.ts.map +1 -1
  89. package/dist/types/src/layout.d.ts +5 -19
  90. package/dist/types/src/layout.d.ts.map +1 -1
  91. package/dist/types/src/meta.d.ts +4 -4
  92. package/dist/types/src/meta.d.ts.map +1 -1
  93. package/dist/types/src/translations.d.ts +4 -2
  94. package/dist/types/src/translations.d.ts.map +1 -1
  95. package/dist/types/src/types.d.ts +117 -20
  96. package/dist/types/src/types.d.ts.map +1 -1
  97. package/dist/types/src/util/index.d.ts +3 -2
  98. package/dist/types/src/util/index.d.ts.map +1 -1
  99. package/dist/types/src/util/layoutAppliesTopbar.d.ts +2 -0
  100. package/dist/types/src/util/layoutAppliesTopbar.d.ts.map +1 -0
  101. package/dist/types/src/util/useBreakpoints.d.ts +2 -0
  102. package/dist/types/src/util/useBreakpoints.d.ts.map +1 -0
  103. package/dist/types/src/util/useHoistStatusbar.d.ts +2 -0
  104. package/dist/types/src/util/useHoistStatusbar.d.ts.map +1 -0
  105. package/dist/types/tsconfig.tsbuildinfo +1 -1
  106. package/package.json +30 -36
  107. package/src/DeckPlugin.ts +77 -0
  108. package/src/capabilities/app-graph-builder.ts +109 -0
  109. package/src/capabilities/capabilities.ts +18 -0
  110. package/src/capabilities/check-app-scheme.ts +44 -0
  111. package/src/capabilities/index.ts +16 -0
  112. package/src/capabilities/intent-resolver.ts +350 -0
  113. package/src/capabilities/react-root.tsx +48 -0
  114. package/src/capabilities/react-surface.tsx +31 -0
  115. package/src/capabilities/set-active.ts +43 -0
  116. package/src/capabilities/settings.ts +21 -0
  117. package/src/capabilities/state.ts +102 -0
  118. package/src/capabilities/url-handler.ts +63 -0
  119. package/src/components/DeckLayout/ActiveNode.tsx +2 -3
  120. package/src/components/DeckLayout/Banner.tsx +37 -0
  121. package/src/components/DeckLayout/ComplementarySidebar.tsx +128 -55
  122. package/src/components/DeckLayout/ContentEmpty.tsx +9 -4
  123. package/src/components/DeckLayout/DeckLayout.tsx +113 -76
  124. package/src/components/DeckLayout/Fullscreen.tsx +2 -3
  125. package/src/components/DeckLayout/NodePlankHeading.tsx +64 -77
  126. package/src/components/DeckLayout/Plank.tsx +34 -43
  127. package/src/components/DeckLayout/PlankControls.tsx +11 -10
  128. package/src/components/DeckLayout/PlankError.tsx +6 -5
  129. package/src/components/DeckLayout/Sidebar.tsx +19 -9
  130. package/src/components/DeckLayout/SidebarButton.tsx +68 -0
  131. package/src/components/DeckLayout/StatusBar.tsx +6 -12
  132. package/src/components/DeckLayout/Toast.tsx +2 -2
  133. package/src/components/DeckLayout/Topbar.tsx +11 -0
  134. package/src/components/LayoutSettings.tsx +8 -8
  135. package/src/components/fragments.ts +14 -0
  136. package/src/components/index.ts +0 -2
  137. package/src/events.ts +11 -0
  138. package/src/hooks/useMainSize.ts +3 -3
  139. package/src/index.ts +3 -4
  140. package/src/layout.ts +43 -212
  141. package/src/meta.ts +3 -2
  142. package/src/translations.ts +8 -6
  143. package/src/types.ts +95 -34
  144. package/src/util/index.ts +3 -2
  145. package/src/util/layoutAppliesTopbar.ts +7 -0
  146. package/src/util/useBreakpoints.ts +11 -0
  147. package/src/util/useHoistStatusbar.ts +24 -0
  148. package/dist/lib/browser/chunk-GVOGPULO.mjs.map +0 -7
  149. package/dist/lib/browser/chunk-ZC3K6C2W.mjs +0 -37
  150. package/dist/lib/browser/chunk-ZC3K6C2W.mjs.map +0 -7
  151. package/dist/lib/browser/meta.mjs +0 -9
  152. package/dist/lib/browser/meta.mjs.map +0 -7
  153. package/dist/types/src/components/DeckContext.d.ts +0 -8
  154. package/dist/types/src/components/DeckContext.d.ts.map +0 -1
  155. package/dist/types/src/components/LayoutContext.d.ts +0 -5
  156. package/dist/types/src/components/LayoutContext.d.ts.map +0 -1
  157. package/dist/types/src/layout.test.d.ts +0 -2
  158. package/dist/types/src/layout.test.d.ts.map +0 -1
  159. package/dist/types/src/util/check-app-scheme.d.ts +0 -2
  160. package/dist/types/src/util/check-app-scheme.d.ts.map +0 -1
  161. package/dist/types/src/util/layout-parts.d.ts +0 -7
  162. package/dist/types/src/util/layout-parts.d.ts.map +0 -1
  163. package/src/DeckPlugin.tsx +0 -623
  164. package/src/components/DeckContext.ts +0 -14
  165. package/src/components/LayoutContext.ts +0 -12
  166. package/src/layout.test.ts +0 -380
  167. package/src/util/check-app-scheme.ts +0 -21
  168. package/src/util/layout-parts.ts +0 -12
@@ -0,0 +1,1119 @@
1
+ import {
2
+ DeckCapabilities
3
+ } from "./chunk-YQ2GWTDU.mjs";
4
+ import {
5
+ DeckAction,
6
+ NewPlankPositions,
7
+ OverscrollOptions,
8
+ SLUG_PATH_SEPARATOR,
9
+ getMode
10
+ } from "./chunk-M2L53AIH.mjs";
11
+ import {
12
+ DECK_PLUGIN
13
+ } from "./chunk-N7TEPFVR.mjs";
14
+
15
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Banner.tsx
16
+ import React2 from "react";
17
+ import { Surface } from "@dxos/app-framework";
18
+ import { mx } from "@dxos/react-ui-theme";
19
+
20
+ // packages/plugins/plugin-deck/src/components/DeckLayout/SidebarButton.tsx
21
+ import React from "react";
22
+ import { useCapability } from "@dxos/app-framework";
23
+ import { IconButton, useTranslation } from "@dxos/react-ui";
24
+ var ToggleSidebarButton = ({ classNames, variant = "ghost" }) => {
25
+ const layoutContext = useCapability(DeckCapabilities.MutableDeckState);
26
+ const { t } = useTranslation(DECK_PLUGIN);
27
+ return /* @__PURE__ */ React.createElement(IconButton, {
28
+ variant,
29
+ iconOnly: true,
30
+ icon: "ph--sidebar--regular",
31
+ size: 4,
32
+ label: t("open navigation sidebar label"),
33
+ onClick: () => layoutContext.sidebarState = layoutContext.sidebarState === "expanded" ? "collapsed" : "expanded",
34
+ classNames
35
+ });
36
+ };
37
+ var CloseSidebarButton = () => {
38
+ const layoutContext = useCapability(DeckCapabilities.MutableDeckState);
39
+ const { t } = useTranslation(DECK_PLUGIN);
40
+ return /* @__PURE__ */ React.createElement(IconButton, {
41
+ variant: "ghost",
42
+ iconOnly: true,
43
+ icon: "ph--caret-line-left--regular",
44
+ size: 4,
45
+ label: t("close navigation sidebar label"),
46
+ onClick: () => layoutContext.sidebarState = "collapsed",
47
+ classNames: "rounded-none pli-1 dx-focus-ring-inset pie-[max(.5rem,env(safe-area-inset-left))]"
48
+ });
49
+ };
50
+ var ToggleComplementarySidebarButton = ({ inR0, classNames }) => {
51
+ const layoutContext = useCapability(DeckCapabilities.MutableDeckState);
52
+ const { t } = useTranslation(DECK_PLUGIN);
53
+ return /* @__PURE__ */ React.createElement(IconButton, {
54
+ iconOnly: true,
55
+ onClick: () => layoutContext.complementarySidebarState = layoutContext.complementarySidebarState === "expanded" ? "collapsed" : "expanded",
56
+ variant: "ghost",
57
+ label: t("open complementary sidebar label"),
58
+ classNames: [
59
+ "[&>svg]:-scale-x-100",
60
+ classNames
61
+ ],
62
+ icon: "ph--sidebar-simple--regular",
63
+ size: inR0 ? 5 : 4,
64
+ tooltipSide: inR0 ? "left" : void 0
65
+ });
66
+ };
67
+
68
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Banner.tsx
69
+ var Banner = ({ variant, classNames }) => {
70
+ return /* @__PURE__ */ React2.createElement("header", {
71
+ className: mx("flex items-stretch relative plb-1 pis-1 pie-2", variant === "topbar" && "fixed inset-inline-0 block-start-[env(safe-area-inset-top)] bs-[--rail-size] border-be border-separator", classNames)
72
+ }, variant === "sidebar" ? /* @__PURE__ */ React2.createElement(CloseSidebarButton, null) : /* @__PURE__ */ React2.createElement(ToggleSidebarButton, null), /* @__PURE__ */ React2.createElement("span", {
73
+ className: "self-center grow mis-1"
74
+ }, "Composer"), variant === "topbar" && /* @__PURE__ */ React2.createElement("div", {
75
+ role: "none",
76
+ className: "absolute inset-0 pointer-events-none"
77
+ }, /* @__PURE__ */ React2.createElement("div", {
78
+ role: "none",
79
+ className: "grid bs-full pointer-fine:p-1 max-is-md mli-auto pointer-events-auto"
80
+ }, /* @__PURE__ */ React2.createElement(Surface, {
81
+ role: "search-input",
82
+ limit: 1
83
+ }))), /* @__PURE__ */ React2.createElement("span", {
84
+ role: "none",
85
+ className: "grow"
86
+ }), /* @__PURE__ */ React2.createElement(Surface, {
87
+ role: "header-end",
88
+ limit: 1
89
+ }), /* @__PURE__ */ React2.createElement(Surface, {
90
+ role: "notch-start",
91
+ limit: 1
92
+ }));
93
+ };
94
+
95
+ // packages/plugins/plugin-deck/src/components/DeckLayout/DeckLayout.tsx
96
+ import { untracked } from "@preact/signals-core";
97
+ import React17, { useCallback as useCallback4, useEffect as useEffect6, useMemo as useMemo6, useRef as useRef2, Fragment as Fragment2 } from "react";
98
+ import { LayoutAction as LayoutAction4, createIntent as createIntent4, Surface as Surface10, useCapability as useCapability6, useIntentDispatcher as useIntentDispatcher4, usePluginManager } from "@dxos/app-framework";
99
+ import { AttentionCapabilities } from "@dxos/plugin-attention";
100
+ import { AlertDialog, Dialog as NaturalDialog, Main as Main3, Popover as Popover2, useOnTransition, useMediaQuery as useMediaQuery2 } from "@dxos/react-ui";
101
+ import { Stack, StackContext, DEFAULT_HORIZONTAL_SIZE } from "@dxos/react-ui-stack";
102
+ import { mainPaddingTransitions } from "@dxos/react-ui-theme";
103
+
104
+ // packages/plugins/plugin-deck/src/components/DeckLayout/ActiveNode.tsx
105
+ import React3 from "react";
106
+ import { Surface as Surface2, useAppGraph } from "@dxos/app-framework";
107
+ import { useAttended } from "@dxos/react-ui-attention";
108
+
109
+ // packages/plugins/plugin-deck/src/hooks/useNode.ts
110
+ import { useEffect, useState } from "react";
111
+ var useNode = (graph, id, timeout) => {
112
+ const [nodeState, setNodeState] = useState(id ? graph.findNode(id, false) : void 0);
113
+ useEffect(() => {
114
+ if (!id && nodeState) {
115
+ setNodeState(void 0);
116
+ }
117
+ if (nodeState?.id === id || !id) {
118
+ return;
119
+ }
120
+ const frame = requestAnimationFrame(async () => {
121
+ try {
122
+ const node = await graph.waitForNode(id, timeout);
123
+ if (node) {
124
+ setNodeState(node);
125
+ }
126
+ } catch {
127
+ }
128
+ });
129
+ return () => cancelAnimationFrame(frame);
130
+ }, [
131
+ graph,
132
+ id,
133
+ timeout,
134
+ nodeState?.id
135
+ ]);
136
+ return nodeState;
137
+ };
138
+
139
+ // packages/plugins/plugin-deck/src/hooks/useNodeActionExpander.ts
140
+ import { useEffect as useEffect2 } from "react";
141
+ import { ACTION_GROUP_TYPE, ACTION_TYPE, getGraph } from "@dxos/plugin-graph";
142
+ var expandNodeActions = async (node) => {
143
+ const graph = getGraph(node);
144
+ await graph.expand(node, "outbound", ACTION_GROUP_TYPE);
145
+ await graph.expand(node, "outbound", ACTION_TYPE);
146
+ };
147
+ var useNodeActionExpander = (node) => {
148
+ useEffect2(() => {
149
+ if (node) {
150
+ const frame = requestAnimationFrame(() => {
151
+ void expandNodeActions(node);
152
+ });
153
+ return () => cancelAnimationFrame(frame);
154
+ }
155
+ }, [
156
+ node
157
+ ]);
158
+ };
159
+
160
+ // packages/plugins/plugin-deck/src/hooks/useMainSize.ts
161
+ import { useMainContext } from "@dxos/react-ui";
162
+ var useMainSize = () => {
163
+ const { navigationSidebarState, complementarySidebarState } = useMainContext("DeckPluginPlank");
164
+ return {
165
+ "data-sidebar-inline-start-state": navigationSidebarState,
166
+ "data-sidebar-inline-end-state": complementarySidebarState
167
+ };
168
+ };
169
+
170
+ // packages/plugins/plugin-deck/src/components/DeckLayout/ActiveNode.tsx
171
+ var ActiveNode = () => {
172
+ const [id] = useAttended();
173
+ const { graph } = useAppGraph();
174
+ const activeNode = useNode(graph, id);
175
+ useNodeActionExpander(activeNode);
176
+ return /* @__PURE__ */ React3.createElement("div", {
177
+ role: "none",
178
+ className: "sr-only"
179
+ }, /* @__PURE__ */ React3.createElement(Surface2, {
180
+ role: "document-title",
181
+ data: {
182
+ subject: activeNode
183
+ },
184
+ limit: 1
185
+ }));
186
+ };
187
+
188
+ // packages/plugins/plugin-deck/src/components/DeckLayout/ComplementarySidebar.tsx
189
+ import React8, { useCallback as useCallback2, useEffect as useEffect5, useMemo as useMemo3, useState as useState3 } from "react";
190
+ import { createIntent as createIntent2, LayoutAction as LayoutAction2, Surface as Surface4, useAppGraph as useAppGraph3, useCapability as useCapability3, useIntentDispatcher as useIntentDispatcher2 } from "@dxos/app-framework";
191
+ import { Main, useTranslation as useTranslation5, toLocalizedString as toLocalizedString2, IconButton as IconButton2, ScrollArea } from "@dxos/react-ui";
192
+ import { useAttended as useAttended2 } from "@dxos/react-ui-attention";
193
+ import { Tabs } from "@dxos/react-ui-tabs";
194
+
195
+ // packages/plugins/plugin-deck/src/components/DeckLayout/PlankError.tsx
196
+ import React7, { useEffect as useEffect4, useState as useState2 } from "react";
197
+ import { useTranslation as useTranslation4 } from "@dxos/react-ui";
198
+ import { descriptionText, mx as mx3 } from "@dxos/react-ui-theme";
199
+
200
+ // packages/plugins/plugin-deck/src/components/DeckLayout/NodePlankHeading.tsx
201
+ import React5, { Fragment, memo, useCallback, useEffect as useEffect3, useMemo as useMemo2 } from "react";
202
+ import { createIntent, LayoutAction, Surface as Surface3, useAppGraph as useAppGraph2, useIntentDispatcher } from "@dxos/app-framework";
203
+ import { Icon as Icon2, Popover, toLocalizedString, useTranslation as useTranslation3 } from "@dxos/react-ui";
204
+ import { StackItem } from "@dxos/react-ui-stack";
205
+ import { TextTooltip } from "@dxos/react-ui-text-tooltip";
206
+
207
+ // packages/plugins/plugin-deck/src/components/DeckLayout/PlankControls.tsx
208
+ import React4, { forwardRef } from "react";
209
+ import { Button, ButtonGroup, Icon, Tooltip, useTranslation as useTranslation2 } from "@dxos/react-ui";
210
+ var PlankControl = ({ icon, label, ...props }) => {
211
+ return /* @__PURE__ */ React4.createElement(Tooltip.Root, null, /* @__PURE__ */ React4.createElement(Tooltip.Trigger, {
212
+ asChild: true
213
+ }, /* @__PURE__ */ React4.createElement(Button, {
214
+ variant: "ghost",
215
+ ...props
216
+ }, /* @__PURE__ */ React4.createElement("span", {
217
+ className: "sr-only"
218
+ }, label), /* @__PURE__ */ React4.createElement(Icon, {
219
+ icon,
220
+ size: 4
221
+ }))), /* @__PURE__ */ React4.createElement(Tooltip.Portal, null, /* @__PURE__ */ React4.createElement(Tooltip.Content, {
222
+ side: "bottom"
223
+ }, label)));
224
+ };
225
+ var PlankControls = /* @__PURE__ */ forwardRef(({ onClick, variant = "default", capabilities: can, isSolo, pin, close = false, children, classNames, ...props }, forwardedRef) => {
226
+ const { t } = useTranslation2(DECK_PLUGIN);
227
+ const buttonClassNames = variant === "hide-disabled" ? "disabled:hidden pli-2 plb-3" : "pli-2 plb-3";
228
+ return /* @__PURE__ */ React4.createElement(ButtonGroup, {
229
+ ...props,
230
+ classNames: [
231
+ "app-no-drag",
232
+ classNames
233
+ ],
234
+ ref: forwardedRef
235
+ }, can.solo && /* @__PURE__ */ React4.createElement(PlankControl, {
236
+ label: isSolo ? t("show deck plank label") : t("show solo plank label"),
237
+ classNames: buttonClassNames,
238
+ onClick: () => onClick?.("solo"),
239
+ icon: isSolo ? "ph--corners-in--regular" : "ph--corners-out--regular"
240
+ }), !isSolo && can.solo && /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(PlankControl, {
241
+ label: t("increment start label"),
242
+ disabled: !can.incrementStart,
243
+ classNames: buttonClassNames,
244
+ onClick: () => onClick?.("increment-start"),
245
+ icon: "ph--caret-left--regular"
246
+ }), /* @__PURE__ */ React4.createElement(PlankControl, {
247
+ label: t("increment end label"),
248
+ disabled: !can.incrementEnd,
249
+ classNames: buttonClassNames,
250
+ onClick: () => onClick?.("increment-end"),
251
+ icon: "ph--caret-right--regular"
252
+ })), close && !isSolo && /* @__PURE__ */ React4.createElement(PlankControl, {
253
+ label: t(`${typeof close === "string" ? "minify" : "close"} label`),
254
+ classNames: buttonClassNames,
255
+ onClick: () => onClick?.("close"),
256
+ "data-testid": "plankHeading.close",
257
+ icon: close === "minify-start" ? "ph--caret-line-left--regular" : close === "minify-end" ? "ph--caret-line-right--regular" : "ph--x--regular"
258
+ }), children);
259
+ });
260
+
261
+ // packages/plugins/plugin-deck/src/util/overscroll.ts
262
+ var calculateOverscroll = (planksCount) => {
263
+ if (!planksCount) {
264
+ return {
265
+ paddingInlineStart: 0,
266
+ paddingInlineEnd: 0
267
+ };
268
+ }
269
+ if (planksCount === 1) {
270
+ const overscrollPadding = "max(0px, calc(((100dvw - var(--dx-main-sidebarWidth) - var(--dx-main-complementaryWidth) - (var(--dx-main-contentFirstWidth) + 1px)) / 2)))";
271
+ return {
272
+ paddingInlineStart: overscrollPadding,
273
+ paddingInlineEnd: overscrollPadding
274
+ };
275
+ } else {
276
+ return {
277
+ paddingInlineStart: "max(0px, calc(((100dvw - (var(--dx-main-contentFirstWidth) + 1px)) / 2) - var(--dx-main-sidebarWidth)))",
278
+ paddingInlineEnd: "max(0px, calc(((100dvw - (var(--dx-main-contentLastWidth) + 1px)) / 2) - var(--dx-main-complementaryWidth)))"
279
+ };
280
+ }
281
+ };
282
+
283
+ // packages/plugins/plugin-deck/src/util/useBreakpoints.ts
284
+ import { useMediaQuery } from "@dxos/react-ui";
285
+ var useBreakpoints = () => {
286
+ const [isNotMobile] = useMediaQuery("md");
287
+ const [isDesktop] = useMediaQuery("lg");
288
+ return isDesktop ? "desktop" : isNotMobile ? "tablet" : "mobile";
289
+ };
290
+
291
+ // packages/plugins/plugin-deck/src/util/layoutAppliesTopbar.ts
292
+ var layoutAppliesTopbar = (breakpoint) => {
293
+ return document.body.getAttribute("data-platform") === "win" && breakpoint === "desktop";
294
+ };
295
+
296
+ // packages/plugins/plugin-deck/src/util/useHoistStatusbar.ts
297
+ import { useMemo } from "react";
298
+ import { Capabilities, useCapability as useCapability2 } from "@dxos/app-framework";
299
+ var useHoistStatusbar = (breakpoint) => {
300
+ const enableIdeStyleStatusbar = useCapability2(Capabilities.SettingsStore).getStore(DECK_PLUGIN).value.enableIdeStyleStatusbar;
301
+ return useMemo(() => {
302
+ return breakpoint === "desktop" && enableIdeStyleStatusbar && // NOTE(thure): this last predicate depends on a head script that measures `env(safe-area-bottom)` on resize;
303
+ // see that of composer-app for an example.
304
+ document.body.getAttribute("data-safe-area-bottom") === "0";
305
+ }, [
306
+ enableIdeStyleStatusbar,
307
+ breakpoint
308
+ ]);
309
+ };
310
+
311
+ // packages/plugins/plugin-deck/src/components/fragments.ts
312
+ import { mx as mx2 } from "@dxos/react-ui-theme";
313
+ var soloInlinePadding = "pis-[calc(env(safe-area-inset-left)+.25rem)] pie-[calc(env(safe-area-inset-left)+.25rem)]";
314
+ var sidebarToggleStyles = "bs-[--rail-item] is-[--rail-item] absolute block-end-2 z-[1] !bg-deck lg:hidden";
315
+ var fixedSidebarToggleStyles = mx2(sidebarToggleStyles, "inline-start-2");
316
+ var fixedComplementarySidebarToggleStyles = mx2(sidebarToggleStyles, "inline-end-2");
317
+
318
+ // packages/plugins/plugin-deck/src/components/DeckLayout/NodePlankHeading.tsx
319
+ var NodePlankHeading = /* @__PURE__ */ memo(({ id, part, node, canIncrementStart, canIncrementEnd, popoverAnchorId, pending, actions = [] }) => {
320
+ const { t } = useTranslation3(DECK_PLUGIN);
321
+ const { graph } = useAppGraph2();
322
+ const breakpoint = useBreakpoints();
323
+ const icon = node?.properties?.icon ?? "ph--placeholder--regular";
324
+ const label = pending ? t("pending heading") : toLocalizedString(node?.properties?.label ?? [
325
+ "plank heading fallback label",
326
+ {
327
+ ns: DECK_PLUGIN
328
+ }
329
+ ], t);
330
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
331
+ const ActionRoot = node && popoverAnchorId === `dxos.org/ui/${DECK_PLUGIN}/${node.id}` ? Popover.Anchor : Fragment;
332
+ useEffect3(() => {
333
+ const frame = requestAnimationFrame(() => {
334
+ node && graph.actions(node);
335
+ });
336
+ return () => cancelAnimationFrame(frame);
337
+ }, [
338
+ node
339
+ ]);
340
+ const attendableId = id.split(SLUG_PATH_SEPARATOR).at(0);
341
+ const capabilities = useMemo2(() => ({
342
+ solo: breakpoint !== "mobile" && (part === "solo" || part === "deck"),
343
+ incrementStart: canIncrementStart,
344
+ incrementEnd: canIncrementEnd
345
+ }), [
346
+ breakpoint,
347
+ part,
348
+ canIncrementStart,
349
+ canIncrementEnd
350
+ ]);
351
+ const sigilActions = useMemo2(() => node && [
352
+ actions,
353
+ graph.actions(node)
354
+ ].filter((a) => a.length > 0), [
355
+ actions,
356
+ node,
357
+ graph
358
+ ]);
359
+ const handleAction = useCallback((action) => {
360
+ typeof action.data === "function" && action.data?.({
361
+ node: action,
362
+ caller: DECK_PLUGIN
363
+ });
364
+ }, []);
365
+ const handlePlankAction = useCallback((eventType) => {
366
+ if (eventType === "solo") {
367
+ return dispatch(createIntent(DeckAction.Adjust, {
368
+ type: eventType,
369
+ id
370
+ }));
371
+ } else if (eventType === "close") {
372
+ if (part === "complementary") {
373
+ return dispatch(createIntent(LayoutAction.UpdateComplementary, {
374
+ part: "complementary",
375
+ options: {
376
+ state: "collapsed"
377
+ }
378
+ }));
379
+ } else {
380
+ return dispatch(createIntent(LayoutAction.Close, {
381
+ part: "main",
382
+ subject: [
383
+ id
384
+ ],
385
+ options: {
386
+ state: false
387
+ }
388
+ }));
389
+ }
390
+ } else {
391
+ return dispatch(createIntent(DeckAction.Adjust, {
392
+ type: eventType,
393
+ id
394
+ }));
395
+ }
396
+ }, [
397
+ dispatch,
398
+ id,
399
+ part
400
+ ]);
401
+ return /* @__PURE__ */ React5.createElement(StackItem.Heading, {
402
+ classNames: [
403
+ "plb-1 border-be border-separator items-stretch gap-1 sticky inline-start-12 app-drag",
404
+ part === "solo" ? soloInlinePadding : "pli-1"
405
+ ]
406
+ }, /* @__PURE__ */ React5.createElement(ActionRoot, null, node && sigilActions ? /* @__PURE__ */ React5.createElement(StackItem.Sigil, {
407
+ icon,
408
+ related: part === "complementary",
409
+ attendableId,
410
+ triggerLabel: t("actions menu label"),
411
+ actions: sigilActions,
412
+ onAction: handleAction
413
+ }, /* @__PURE__ */ React5.createElement(Surface3, {
414
+ role: "menu-footer",
415
+ data: {
416
+ subject: node.data
417
+ }
418
+ })) : /* @__PURE__ */ React5.createElement(StackItem.SigilButton, null, /* @__PURE__ */ React5.createElement("span", {
419
+ className: "sr-only"
420
+ }, label), /* @__PURE__ */ React5.createElement(Icon2, {
421
+ icon,
422
+ size: 5
423
+ }))), /* @__PURE__ */ React5.createElement(TextTooltip, {
424
+ text: label,
425
+ onlyWhenTruncating: true
426
+ }, /* @__PURE__ */ React5.createElement(StackItem.HeadingLabel, {
427
+ attendableId,
428
+ related: part === "complementary",
429
+ ...pending && {
430
+ classNames: "text-description"
431
+ }
432
+ }, label)), node && part !== "complementary" && /* @__PURE__ */ React5.createElement(Surface3, {
433
+ role: "navbar-end",
434
+ data: {
435
+ subject: node.data
436
+ }
437
+ }), /* @__PURE__ */ React5.createElement(PlankControls, {
438
+ capabilities,
439
+ isSolo: part === "solo",
440
+ onClick: handlePlankAction,
441
+ close: part === "complementary" ? "minify-end" : true
442
+ }));
443
+ });
444
+
445
+ // packages/plugins/plugin-deck/src/components/DeckLayout/PlankLoading.tsx
446
+ import React6 from "react";
447
+ var PlankLoading = () => {
448
+ return /* @__PURE__ */ React6.createElement("div", {
449
+ role: "none",
450
+ className: "grid place-items-center attention-surface"
451
+ });
452
+ };
453
+
454
+ // packages/plugins/plugin-deck/src/components/DeckLayout/PlankError.tsx
455
+ var PlankContentError = ({ error }) => {
456
+ const { t } = useTranslation4(DECK_PLUGIN);
457
+ const errorString = error?.toString() ?? "";
458
+ return /* @__PURE__ */ React7.createElement("div", {
459
+ role: "none",
460
+ className: "overflow-auto p-8 attention-surface grid place-items-center"
461
+ }, /* @__PURE__ */ React7.createElement("p", {
462
+ role: "alert",
463
+ className: mx3(descriptionText, "break-words border border-dashed border-separator rounded-lg p-8", errorString.length < 256 && "text-lg")
464
+ }, error ? errorString : t("error fallback message")));
465
+ };
466
+ var PlankError = ({ id, part, node, error }) => {
467
+ const [timedOut, setTimedOut] = useState2(false);
468
+ useEffect4(() => {
469
+ setTimeout(() => setTimedOut(true), 5e3);
470
+ }, []);
471
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(NodePlankHeading, {
472
+ id,
473
+ part,
474
+ node,
475
+ pending: !timedOut
476
+ }), timedOut ? /* @__PURE__ */ React7.createElement(PlankContentError, {
477
+ error
478
+ }) : /* @__PURE__ */ React7.createElement(PlankLoading, null));
479
+ };
480
+
481
+ // packages/plugins/plugin-deck/src/components/DeckLayout/ComplementarySidebar.tsx
482
+ var ComplementarySidebar = ({ panels, current }) => {
483
+ const layout = useCapability3(DeckCapabilities.MutableDeckState);
484
+ const attended = useAttended2();
485
+ const panelIds = useMemo3(() => panels.map((p) => p.id), [
486
+ panels
487
+ ]);
488
+ const activePanelId = panelIds.find((p) => p === current) ?? panels[0].id;
489
+ const activeEntryId = attended[0] ? `${attended[0]}${SLUG_PATH_SEPARATOR}${activePanelId}` : void 0;
490
+ const { graph } = useAppGraph3();
491
+ const node = useNode(graph, activeEntryId);
492
+ const { t } = useTranslation5(DECK_PLUGIN);
493
+ const { dispatchPromise: dispatch } = useIntentDispatcher2();
494
+ useNodeActionExpander(node);
495
+ const breakpoint = useBreakpoints();
496
+ const topbar = layoutAppliesTopbar(breakpoint);
497
+ const hoistStatusbar = useHoistStatusbar(breakpoint);
498
+ const [internalValue, setInternalValue] = useState3(activePanelId);
499
+ useEffect5(() => {
500
+ setInternalValue(activePanelId);
501
+ }, [
502
+ activePanelId
503
+ ]);
504
+ const handleTabClick = useCallback2((event) => {
505
+ const nextValue = event.currentTarget.getAttribute("data-value");
506
+ if (nextValue === activePanelId) {
507
+ layout.complementarySidebarState = layout.complementarySidebarState === "expanded" ? "collapsed" : "expanded";
508
+ } else {
509
+ setInternalValue(nextValue);
510
+ layout.complementarySidebarState = "expanded";
511
+ void dispatch(createIntent2(LayoutAction2.UpdateComplementary, {
512
+ part: "complementary",
513
+ subject: nextValue
514
+ }));
515
+ }
516
+ }, [
517
+ layout,
518
+ activePanelId,
519
+ dispatch
520
+ ]);
521
+ return /* @__PURE__ */ React8.createElement(Main.ComplementarySidebar, {
522
+ classNames: [
523
+ topbar && "block-start-[calc(env(safe-area-inset-top)+var(--rail-size))]",
524
+ hoistStatusbar && "block-end-[--statusbar-size]"
525
+ ]
526
+ }, /* @__PURE__ */ React8.createElement(Tabs.Root, {
527
+ orientation: "vertical",
528
+ verticalVariant: "stateless",
529
+ value: internalValue,
530
+ attendableId: attended[0],
531
+ classNames: "contents"
532
+ }, /* @__PURE__ */ React8.createElement("div", {
533
+ role: "none",
534
+ className: "absolute z-[1] inset-block-0 inline-end-0 !is-[--r0-size] border-is border-separator grid grid-cols-1 grid-rows-[1fr_min-content] bg-baseSurface contain-layout app-drag"
535
+ }, /* @__PURE__ */ React8.createElement(Tabs.Tablist, {
536
+ classNames: "grid grid-cols-1 auto-rows-[--rail-action] p-1 gap-1 !overflow-y-auto"
537
+ }, panels.map((panel) => /* @__PURE__ */ React8.createElement(Tabs.Tab, {
538
+ key: panel.id,
539
+ value: panel.id,
540
+ asChild: true
541
+ }, /* @__PURE__ */ React8.createElement(IconButton2, {
542
+ label: toLocalizedString2(panel.label, t),
543
+ icon: panel.icon,
544
+ size: 5,
545
+ iconOnly: true,
546
+ tooltipSide: "left",
547
+ "data-value": panel.id,
548
+ variant: activePanelId === panel.id ? layout.complementarySidebarState === "expanded" ? "primary" : "default" : "ghost",
549
+ onClick: handleTabClick
550
+ })))), !hoistStatusbar && /* @__PURE__ */ React8.createElement("div", {
551
+ role: "none",
552
+ className: "grid grid-cols-1 auto-rows-[--rail-item] p-1 overflow-y-auto"
553
+ }, /* @__PURE__ */ React8.createElement(Surface4, {
554
+ role: "status-bar--r0-footer",
555
+ limit: 1
556
+ })), /* @__PURE__ */ React8.createElement("div", {
557
+ role: "none",
558
+ className: "hidden lg:grid grid-cols-1 auto-rows-[--rail-action] p-1"
559
+ }, /* @__PURE__ */ React8.createElement(ToggleComplementarySidebarButton, null))), panels.map((panel) => /* @__PURE__ */ React8.createElement(Tabs.Tabpanel, {
560
+ key: panel.id,
561
+ value: panel.id,
562
+ classNames: 'absolute data-[state="inactive"]:-z-[1] inset-block-0 inline-start-0 is-[calc(100%-var(--r0-size))] lg:is-[--r1-size] grid grid-cols-1 grid-rows-[var(--rail-size)_1fr_min-content]',
563
+ ...layout.complementarySidebarState !== "expanded" && {
564
+ inert: "true"
565
+ }
566
+ }, panel.id === activePanelId && node && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement("h2", {
567
+ className: "flex items-center pli-2 border-separator border-be"
568
+ }, toLocalizedString2(panel.label, t)), /* @__PURE__ */ React8.createElement(ScrollArea.Root, null, /* @__PURE__ */ React8.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React8.createElement(Surface4, {
569
+ key: activeEntryId,
570
+ role: `complementary--${activePanelId}`,
571
+ data: {
572
+ id: activeEntryId,
573
+ subject: node.properties.object ?? node.properties.space,
574
+ popoverAnchorId: layout.popoverAnchorId
575
+ },
576
+ fallback: PlankContentError,
577
+ placeholder: /* @__PURE__ */ React8.createElement(PlankLoading, null)
578
+ })), /* @__PURE__ */ React8.createElement(ScrollArea.Scrollbar, {
579
+ orientation: "vertical"
580
+ }, /* @__PURE__ */ React8.createElement(ScrollArea.Thumb, null))), !hoistStatusbar && /* @__PURE__ */ React8.createElement("div", {
581
+ role: "contentinfo",
582
+ className: "flex flex-wrap justify-center items-center border-bs border-separator plb-1"
583
+ }, /* @__PURE__ */ React8.createElement(Surface4, {
584
+ role: "status-bar--r1-footer",
585
+ limit: 1
586
+ })))))));
587
+ };
588
+
589
+ // packages/plugins/plugin-deck/src/components/DeckLayout/ContentEmpty.tsx
590
+ import React9 from "react";
591
+ import { Surface as Surface5 } from "@dxos/app-framework";
592
+ var ContentEmpty = () => {
593
+ const breakpoint = useBreakpoints();
594
+ const topbar = layoutAppliesTopbar(breakpoint);
595
+ return /* @__PURE__ */ React9.createElement("div", {
596
+ role: "none",
597
+ className: "grid place-items-center p-8 relative bg-deck",
598
+ "data-testid": "layoutPlugin.firstRunMessage"
599
+ }, /* @__PURE__ */ React9.createElement(Surface5, {
600
+ role: "keyshortcuts"
601
+ }), !topbar && /* @__PURE__ */ React9.createElement(ToggleSidebarButton, {
602
+ variant: "default",
603
+ classNames: fixedSidebarToggleStyles
604
+ }));
605
+ };
606
+
607
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Fullscreen.tsx
608
+ import React11 from "react";
609
+ import { Surface as Surface6, useAppGraph as useAppGraph4 } from "@dxos/app-framework";
610
+ import { fixedInsetFlexLayout } from "@dxos/react-ui-theme";
611
+
612
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Fallback.tsx
613
+ import React10 from "react";
614
+ import { useTranslation as useTranslation6 } from "@dxos/react-ui";
615
+ import { errorText, mx as mx4 } from "@dxos/react-ui-theme";
616
+ var Fallback = () => {
617
+ const { t } = useTranslation6(DECK_PLUGIN);
618
+ return /* @__PURE__ */ React10.createElement("div", {
619
+ role: "none",
620
+ className: "min-bs-screen is-full flex items-center justify-center p-8"
621
+ }, /* @__PURE__ */ React10.createElement("p", {
622
+ role: "alert",
623
+ className: mx4(errorText, "border border-error-400/50 rounded-lg flex items-center justify-center p-8 font-normal text-lg")
624
+ }, t("plugin error message")));
625
+ };
626
+
627
+ // packages/plugins/plugin-deck/src/components/DeckLayout/constants.ts
628
+ var SURFACE_PREFIX = "surface:";
629
+
630
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Fullscreen.tsx
631
+ var Fullscreen = ({ id }) => {
632
+ const { graph } = useAppGraph4();
633
+ const fullScreenNode = useNode(graph, id);
634
+ return /* @__PURE__ */ React11.createElement("div", {
635
+ role: "none",
636
+ className: fixedInsetFlexLayout
637
+ }, /* @__PURE__ */ React11.createElement(Surface6, {
638
+ role: "main",
639
+ limit: 1,
640
+ fallback: Fallback,
641
+ data: {
642
+ subject: fullScreenNode?.data,
643
+ component: id?.startsWith(SURFACE_PREFIX) ? id.slice(SURFACE_PREFIX.length) : void 0
644
+ }
645
+ }));
646
+ };
647
+
648
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Plank.tsx
649
+ import React12, { memo as memo2, useCallback as useCallback3, useLayoutEffect, useMemo as useMemo4, useRef } from "react";
650
+ import { createIntent as createIntent3, LayoutAction as LayoutAction3, Surface as Surface7, useCapability as useCapability4, useAppGraph as useAppGraph5, useIntentDispatcher as useIntentDispatcher3 } from "@dxos/app-framework";
651
+ import { debounce } from "@dxos/async";
652
+ import { useAttendableAttributes } from "@dxos/react-ui-attention";
653
+ import { StackItem as StackItem2, railGridHorizontal } from "@dxos/react-ui-stack";
654
+ import { mainIntrinsicSize, mx as mx5 } from "@dxos/react-ui-theme";
655
+ var UNKNOWN_ID = "unknown_id";
656
+ var Plank = /* @__PURE__ */ memo2(({ id = UNKNOWN_ID, part, path, order, active, layoutMode }) => {
657
+ const { dispatchPromise: dispatch } = useIntentDispatcher3();
658
+ const { deck, popoverAnchorId, scrollIntoView } = useCapability4(DeckCapabilities.DeckState);
659
+ const { graph } = useAppGraph5();
660
+ const node = useNode(graph, id);
661
+ const rootElement = useRef(null);
662
+ const canResize = layoutMode === "deck";
663
+ const Root = part === "solo" ? "article" : StackItem2.Root;
664
+ const attendableAttrs = useAttendableAttributes(id);
665
+ const index = active ? active.findIndex((entryId) => entryId === id) : 0;
666
+ const length = active?.length ?? 1;
667
+ const canIncrementStart = active && index !== void 0 && index > 0 && length !== void 0 && length > 1;
668
+ const canIncrementEnd = active && index !== void 0 && index < length - 1 && length !== void 0;
669
+ const size = deck.plankSizing[id];
670
+ const setSize = useCallback3(debounce((nextSize) => {
671
+ return dispatch(createIntent3(DeckAction.UpdatePlankSize, {
672
+ id,
673
+ size: nextSize
674
+ }));
675
+ }, 200), [
676
+ dispatch,
677
+ id
678
+ ]);
679
+ const handleKeyDown = useCallback3((event) => {
680
+ if (event.target === event.currentTarget && event.key === "Escape") {
681
+ rootElement.current?.closest("main")?.focus();
682
+ }
683
+ }, []);
684
+ useLayoutEffect(() => {
685
+ if (scrollIntoView === id) {
686
+ const focusable = rootElement.current?.querySelector("button") || rootElement.current;
687
+ focusable?.focus({
688
+ preventScroll: true
689
+ });
690
+ layoutMode === "deck" && focusable?.scrollIntoView({
691
+ behavior: "smooth",
692
+ inline: "center"
693
+ });
694
+ void dispatch(createIntent3(LayoutAction3.ScrollIntoView, {
695
+ part: "current",
696
+ subject: void 0
697
+ }));
698
+ }
699
+ }, [
700
+ id,
701
+ scrollIntoView,
702
+ layoutMode
703
+ ]);
704
+ const isSolo = layoutMode === "solo" && part === "solo";
705
+ const isAttendable = isSolo || layoutMode === "deck" && part === "deck";
706
+ const sizeAttrs = useMainSize();
707
+ const data = useMemo4(() => node && {
708
+ subject: node.data,
709
+ path,
710
+ popoverAnchorId
711
+ }, [
712
+ node,
713
+ node?.data,
714
+ path,
715
+ popoverAnchorId
716
+ ]);
717
+ const placeholder = useMemo4(() => /* @__PURE__ */ React12.createElement(PlankLoading, null), []);
718
+ const className = mx5("attention-surface relative", isSolo && mainIntrinsicSize, isSolo && railGridHorizontal, isSolo ? "grid absolute inset-0" : "!border-separator border-li");
719
+ return /* @__PURE__ */ React12.createElement(Root, {
720
+ ref: rootElement,
721
+ "data-testid": "deck.plank",
722
+ tabIndex: 0,
723
+ ...part === "solo" ? {
724
+ ...sizeAttrs,
725
+ className
726
+ } : {
727
+ item: {
728
+ id
729
+ },
730
+ size,
731
+ onSizeChange: setSize,
732
+ classNames: className,
733
+ order,
734
+ role: "article"
735
+ },
736
+ ...isAttendable ? attendableAttrs : {},
737
+ onKeyDown: handleKeyDown
738
+ }, node ? /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(NodePlankHeading, {
739
+ id,
740
+ part,
741
+ node,
742
+ canIncrementStart,
743
+ canIncrementEnd,
744
+ popoverAnchorId
745
+ }), /* @__PURE__ */ React12.createElement(Surface7, {
746
+ key: node.id,
747
+ role: "article",
748
+ data,
749
+ limit: 1,
750
+ fallback: PlankContentError,
751
+ placeholder
752
+ })) : /* @__PURE__ */ React12.createElement(PlankError, {
753
+ id,
754
+ part
755
+ }), canResize && /* @__PURE__ */ React12.createElement(StackItem2.ResizeHandle, null));
756
+ });
757
+
758
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Sidebar.tsx
759
+ import React13, { useMemo as useMemo5 } from "react";
760
+ import { Surface as Surface8, useCapability as useCapability5 } from "@dxos/app-framework";
761
+ import { Main as Main2 } from "@dxos/react-ui";
762
+ var Sidebar = () => {
763
+ const { popoverAnchorId, activeDeck: current } = useCapability5(DeckCapabilities.DeckState);
764
+ const breakpoint = useBreakpoints();
765
+ const topbar = layoutAppliesTopbar(breakpoint);
766
+ const hoistStatusbar = useHoistStatusbar(breakpoint);
767
+ const navigationData = useMemo5(() => ({
768
+ popoverAnchorId,
769
+ topbar,
770
+ hoistStatusbar,
771
+ current
772
+ }), [
773
+ popoverAnchorId,
774
+ topbar,
775
+ hoistStatusbar,
776
+ current
777
+ ]);
778
+ return /* @__PURE__ */ React13.createElement(Main2.NavigationSidebar, {
779
+ classNames: [
780
+ "grid",
781
+ topbar && "block-start-[calc(env(safe-area-inset-top)+var(--rail-size))]",
782
+ hoistStatusbar && "block-end-[--statusbar-size]"
783
+ ]
784
+ }, /* @__PURE__ */ React13.createElement(Surface8, {
785
+ role: "navigation",
786
+ data: navigationData,
787
+ limit: 1
788
+ }));
789
+ };
790
+
791
+ // packages/plugins/plugin-deck/src/components/DeckLayout/StatusBar.tsx
792
+ import React14 from "react";
793
+ import { Surface as Surface9 } from "@dxos/app-framework";
794
+ import { useLandmarkMover } from "@dxos/react-ui";
795
+ var StatusBar = ({ showHints }) => {
796
+ const mover = useLandmarkMover(void 0, "3");
797
+ return /* @__PURE__ */ React14.createElement("div", {
798
+ role: "contentinfo",
799
+ className: "fixed block-end-0 inset-inline-0 bs-[--statusbar-size] border-bs border-separator z-[2] flex text-description",
800
+ ...mover
801
+ }, showHints && /* @__PURE__ */ React14.createElement(Surface9, {
802
+ role: "hints",
803
+ limit: 1
804
+ }), /* @__PURE__ */ React14.createElement(Surface9, {
805
+ role: "status-bar",
806
+ limit: 1
807
+ }));
808
+ };
809
+
810
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Toast.tsx
811
+ import React15 from "react";
812
+ import { Button as Button2, Icon as Icon3, Toast as NaturalToast, toLocalizedString as toLocalizedString3, useTranslation as useTranslation7 } from "@dxos/react-ui";
813
+ var Toast = ({ id, title, description, icon, duration, actionLabel, actionAlt, closeLabel, onAction, onOpenChange }) => {
814
+ const { t } = useTranslation7(DECK_PLUGIN);
815
+ return /* @__PURE__ */ React15.createElement(NaturalToast.Root, {
816
+ "data-testid": id,
817
+ defaultOpen: true,
818
+ duration,
819
+ onOpenChange
820
+ }, /* @__PURE__ */ React15.createElement(NaturalToast.Body, null, /* @__PURE__ */ React15.createElement(NaturalToast.Title, {
821
+ classNames: "items-center"
822
+ }, icon && /* @__PURE__ */ React15.createElement(Icon3, {
823
+ icon,
824
+ size: 5,
825
+ classNames: "inline mr-1"
826
+ }), title && /* @__PURE__ */ React15.createElement("span", null, toLocalizedString3(title, t))), description && /* @__PURE__ */ React15.createElement(NaturalToast.Description, null, description && toLocalizedString3(description, t))), /* @__PURE__ */ React15.createElement(NaturalToast.Actions, null, onAction && actionAlt && actionLabel && /* @__PURE__ */ React15.createElement(NaturalToast.Action, {
827
+ altText: toLocalizedString3(actionAlt, t),
828
+ asChild: true
829
+ }, /* @__PURE__ */ React15.createElement(Button2, {
830
+ "data-testid": "toast.action",
831
+ variant: "primary",
832
+ onClick: () => onAction?.()
833
+ }, toLocalizedString3(actionLabel, t))), closeLabel && /* @__PURE__ */ React15.createElement(NaturalToast.Close, {
834
+ asChild: true
835
+ }, /* @__PURE__ */ React15.createElement(Button2, {
836
+ "data-testid": "toast.close"
837
+ }, toLocalizedString3(closeLabel, t)))));
838
+ };
839
+
840
+ // packages/plugins/plugin-deck/src/components/DeckLayout/Topbar.tsx
841
+ import React16 from "react";
842
+ var Topbar = () => {
843
+ return /* @__PURE__ */ React16.createElement(Banner, {
844
+ variant: "topbar"
845
+ });
846
+ };
847
+
848
+ // packages/plugins/plugin-deck/src/components/DeckLayout/DeckLayout.tsx
849
+ var PlankSeparator = ({ index }) => index > 0 ? /* @__PURE__ */ React17.createElement("span", {
850
+ role: "separator",
851
+ className: "row-span-2 bg-deck is-4",
852
+ style: {
853
+ gridColumn: index * 2
854
+ }
855
+ }) : null;
856
+ var DeckLayout = ({ overscroll, showHints, panels, onDismissToast }) => {
857
+ const { dispatchPromise: dispatch } = useIntentDispatcher4();
858
+ const context = useCapability6(DeckCapabilities.MutableDeckState);
859
+ const { sidebarState, complementarySidebarState, complementarySidebarPanel, dialogOpen, dialogContent, dialogBlockAlign, dialogType, popoverOpen, popoverContent, popoverAnchorId, deck, toasts } = context;
860
+ const { active, fullscreen, solo, plankSizing } = deck;
861
+ const breakpoint = useBreakpoints();
862
+ const topbar = layoutAppliesTopbar(breakpoint);
863
+ const hoistStatusbar = useHoistStatusbar(breakpoint);
864
+ const pluginManager = usePluginManager();
865
+ const scrollLeftRef = useRef2();
866
+ const deckRef = useRef2(null);
867
+ useEffect6(() => {
868
+ const attended = untracked(() => {
869
+ const attention = pluginManager.context.requestCapability(AttentionCapabilities.Attention);
870
+ return attention.current;
871
+ });
872
+ const firstId = solo ?? active[0];
873
+ if (attended.length === 0 && firstId) {
874
+ document.querySelector(`article[data-attendable-id="${firstId}"] button`)?.focus();
875
+ }
876
+ }, []);
877
+ const [isNotMobile] = useMediaQuery2("md", {
878
+ ssr: false
879
+ });
880
+ const shouldRevert = useRef2(false);
881
+ useEffect6(() => {
882
+ if (!isNotMobile && getMode(deck) === "deck") {
883
+ const attended = untracked(() => {
884
+ const attention = pluginManager.context.requestCapability(AttentionCapabilities.Attention);
885
+ return attention.current;
886
+ });
887
+ shouldRevert.current = true;
888
+ void dispatch(createIntent4(LayoutAction4.SetLayoutMode, {
889
+ part: "mode",
890
+ subject: attended[0],
891
+ options: {
892
+ mode: "solo"
893
+ }
894
+ }));
895
+ } else if (isNotMobile && getMode(deck) === "solo" && shouldRevert.current) {
896
+ void dispatch(createIntent4(LayoutAction4.SetLayoutMode, {
897
+ part: "mode",
898
+ options: {
899
+ revert: true
900
+ }
901
+ }));
902
+ }
903
+ }, [
904
+ isNotMobile,
905
+ deck,
906
+ dispatch
907
+ ]);
908
+ const handleResize = useCallback4(() => {
909
+ scrollLeftRef.current = null;
910
+ }, []);
911
+ useEffect6(() => {
912
+ window.addEventListener("resize", handleResize);
913
+ return () => window.removeEventListener("resize", handleResize);
914
+ }, [
915
+ handleResize
916
+ ]);
917
+ const restoreScroll = useCallback4(() => {
918
+ if (deckRef.current && scrollLeftRef.current != null) {
919
+ deckRef.current.scrollLeft = scrollLeftRef.current;
920
+ }
921
+ }, []);
922
+ const layoutMode = getMode(deck);
923
+ useOnTransition(layoutMode, (mode) => mode !== "deck", "deck", restoreScroll);
924
+ const handleScroll = useCallback4((event) => {
925
+ if (!solo && event.currentTarget === event.target) {
926
+ scrollLeftRef.current = event.target.scrollLeft;
927
+ }
928
+ }, [
929
+ solo
930
+ ]);
931
+ const isEmpty = !solo && active.length === 0;
932
+ const padding = useMemo6(() => {
933
+ if (!solo && overscroll === "centering") {
934
+ return calculateOverscroll(active.length);
935
+ }
936
+ return {};
937
+ }, [
938
+ solo,
939
+ overscroll,
940
+ deck
941
+ ]);
942
+ const mainPosition = useMemo6(() => [
943
+ "grid !block-start-[env(safe-area-inset-top)]",
944
+ topbar && "!block-start-[calc(env(safe-area-inset-top)+var(--rail-size))]",
945
+ hoistStatusbar && "lg:block-end-[--statusbar-size]"
946
+ ], [
947
+ topbar,
948
+ hoistStatusbar
949
+ ]);
950
+ const Dialog = dialogType === "alert" ? AlertDialog : NaturalDialog;
951
+ return /* @__PURE__ */ React17.createElement(Popover2.Root, {
952
+ modal: true,
953
+ open: !!(popoverAnchorId && popoverOpen),
954
+ onOpenChange: (nextOpen) => {
955
+ if (nextOpen && popoverAnchorId) {
956
+ context.popoverOpen = true;
957
+ } else {
958
+ context.popoverOpen = false;
959
+ context.popoverAnchorId = void 0;
960
+ }
961
+ }
962
+ }, /* @__PURE__ */ React17.createElement(ActiveNode, null), fullscreen && /* @__PURE__ */ React17.createElement(Fullscreen, {
963
+ id: solo
964
+ }), !fullscreen && /* @__PURE__ */ React17.createElement(Main3.Root, {
965
+ navigationSidebarState: context.sidebarState,
966
+ onNavigationSidebarStateChange: (next) => context.sidebarState = next,
967
+ complementarySidebarState: context.complementarySidebarState,
968
+ onComplementarySidebarStateChange: (next) => context.complementarySidebarState = next
969
+ }, /* @__PURE__ */ React17.createElement(Sidebar, null), /* @__PURE__ */ React17.createElement(ComplementarySidebar, {
970
+ panels,
971
+ current: complementarySidebarPanel
972
+ }), /* @__PURE__ */ React17.createElement(Main3.Overlay, null), isEmpty && /* @__PURE__ */ React17.createElement(Main3.Content, {
973
+ bounce: true,
974
+ handlesFocus: true,
975
+ classNames: mainPosition
976
+ }, /* @__PURE__ */ React17.createElement(ContentEmpty, null)), !isEmpty && /* @__PURE__ */ React17.createElement(Main3.Content, {
977
+ bounce: true,
978
+ classNames: mainPosition,
979
+ handlesFocus: true,
980
+ style: {
981
+ "--dx-main-sidebarWidth": sidebarState === "expanded" ? "var(--nav-sidebar-size)" : sidebarState === "collapsed" ? "var(--l0-size)" : "0",
982
+ "--dx-main-complementaryWidth": complementarySidebarState === "expanded" ? "var(--complementary-sidebar-size)" : complementarySidebarState === "collapsed" ? "var(--rail-size)" : "0",
983
+ "--dx-main-contentFirstWidth": `${plankSizing[active[0] ?? "never"] ?? DEFAULT_HORIZONTAL_SIZE}rem`,
984
+ "--dx-main-contentLastWidth": `${plankSizing[active[(active.length ?? 1) - 1] ?? "never"] ?? DEFAULT_HORIZONTAL_SIZE}rem`
985
+ }
986
+ }, /* @__PURE__ */ React17.createElement("div", {
987
+ role: "none",
988
+ className: !solo ? "relative bg-deck overflow-hidden" : "sr-only",
989
+ ...solo && {
990
+ inert: ""
991
+ }
992
+ }, !topbar && /* @__PURE__ */ React17.createElement(ToggleSidebarButton, {
993
+ classNames: fixedSidebarToggleStyles
994
+ }), !topbar && /* @__PURE__ */ React17.createElement(ToggleComplementarySidebarButton, {
995
+ classNames: fixedComplementarySidebarToggleStyles
996
+ }), /* @__PURE__ */ React17.createElement(Stack, {
997
+ orientation: "horizontal",
998
+ size: "contain",
999
+ classNames: [
1000
+ "absolute inset-block-0 -inset-inline-px",
1001
+ mainPaddingTransitions
1002
+ ],
1003
+ onScroll: handleScroll,
1004
+ itemsCount: 2 * (active.length ?? 0) - 1,
1005
+ style: padding,
1006
+ ref: deckRef
1007
+ }, active.map((entryId, index) => /* @__PURE__ */ React17.createElement(Fragment2, {
1008
+ key: entryId
1009
+ }, /* @__PURE__ */ React17.createElement(PlankSeparator, {
1010
+ index
1011
+ }), /* @__PURE__ */ React17.createElement(Plank, {
1012
+ id: entryId,
1013
+ part: "deck",
1014
+ order: index * 2 + 1,
1015
+ active,
1016
+ layoutMode
1017
+ }))))), /* @__PURE__ */ React17.createElement("div", {
1018
+ role: "none",
1019
+ className: solo ? "relative bg-deck overflow-hidden" : "sr-only",
1020
+ ...!solo && {
1021
+ inert: ""
1022
+ }
1023
+ }, !topbar && /* @__PURE__ */ React17.createElement(ToggleSidebarButton, {
1024
+ classNames: fixedSidebarToggleStyles
1025
+ }), !topbar && /* @__PURE__ */ React17.createElement(ToggleComplementarySidebarButton, {
1026
+ classNames: fixedComplementarySidebarToggleStyles
1027
+ }), /* @__PURE__ */ React17.createElement(StackContext.Provider, {
1028
+ value: {
1029
+ size: "contain",
1030
+ orientation: "horizontal",
1031
+ rail: true
1032
+ }
1033
+ }, /* @__PURE__ */ React17.createElement(Plank, {
1034
+ id: solo,
1035
+ part: "solo",
1036
+ layoutMode
1037
+ })))), topbar && /* @__PURE__ */ React17.createElement(Topbar, null), hoistStatusbar && /* @__PURE__ */ React17.createElement(StatusBar, {
1038
+ showHints
1039
+ })), /* @__PURE__ */ React17.createElement(Popover2.Portal, null, /* @__PURE__ */ React17.createElement(Popover2.Content, {
1040
+ onEscapeKeyDown: () => {
1041
+ context.popoverOpen = false;
1042
+ context.popoverAnchorId = void 0;
1043
+ }
1044
+ }, /* @__PURE__ */ React17.createElement(Popover2.Viewport, null, /* @__PURE__ */ React17.createElement(Surface10, {
1045
+ role: "popover",
1046
+ data: popoverContent,
1047
+ limit: 1
1048
+ })), /* @__PURE__ */ React17.createElement(Popover2.Arrow, null))), /* @__PURE__ */ React17.createElement(Dialog.Root, {
1049
+ open: dialogOpen,
1050
+ onOpenChange: (nextOpen) => context.dialogOpen = nextOpen
1051
+ }, /* @__PURE__ */ React17.createElement(Dialog.Overlay, {
1052
+ blockAlign: dialogBlockAlign
1053
+ }, /* @__PURE__ */ React17.createElement(Surface10, {
1054
+ role: "dialog",
1055
+ data: dialogContent,
1056
+ limit: 1
1057
+ }))), toasts?.map((toast) => /* @__PURE__ */ React17.createElement(Toast, {
1058
+ ...toast,
1059
+ key: toast.id,
1060
+ onOpenChange: (open) => {
1061
+ if (!open) {
1062
+ onDismissToast(toast.id);
1063
+ }
1064
+ return open;
1065
+ }
1066
+ })));
1067
+ };
1068
+
1069
+ // packages/plugins/plugin-deck/src/components/LayoutSettings.tsx
1070
+ import React18 from "react";
1071
+ import { Input, Select, useTranslation as useTranslation8 } from "@dxos/react-ui";
1072
+ import { DeprecatedFormContainer, DeprecatedFormInput } from "@dxos/react-ui-form";
1073
+ var isSocket = !!globalThis.__args;
1074
+ var LayoutSettings = ({ settings }) => {
1075
+ const { t } = useTranslation8(DECK_PLUGIN);
1076
+ return /* @__PURE__ */ React18.createElement(DeprecatedFormContainer, null, /* @__PURE__ */ React18.createElement(DeprecatedFormInput, {
1077
+ label: t("select new plank positioning label")
1078
+ }, /* @__PURE__ */ React18.createElement(Select.Root, {
1079
+ value: settings.newPlankPositioning ?? "start",
1080
+ onValueChange: (value) => settings.newPlankPositioning = value
1081
+ }, /* @__PURE__ */ React18.createElement(Select.TriggerButton, {
1082
+ placeholder: t("select new plank positioning placeholder")
1083
+ }), /* @__PURE__ */ React18.createElement(Select.Portal, null, /* @__PURE__ */ React18.createElement(Select.Content, null, /* @__PURE__ */ React18.createElement(Select.Viewport, null, NewPlankPositions.map((position) => /* @__PURE__ */ React18.createElement(Select.Option, {
1084
+ key: position,
1085
+ value: position
1086
+ }, t(`settings new plank position ${position} label`)))))))), /* @__PURE__ */ React18.createElement(DeprecatedFormInput, {
1087
+ label: t("settings overscroll label")
1088
+ }, /* @__PURE__ */ React18.createElement(Select.Root, {
1089
+ value: settings.overscroll ?? "none",
1090
+ onValueChange: (value) => settings.overscroll = value
1091
+ }, /* @__PURE__ */ React18.createElement(Select.TriggerButton, {
1092
+ placeholder: t("select overscroll placeholder")
1093
+ }), /* @__PURE__ */ React18.createElement(Select.Portal, null, /* @__PURE__ */ React18.createElement(Select.Content, null, /* @__PURE__ */ React18.createElement(Select.Viewport, null, OverscrollOptions.map((option) => /* @__PURE__ */ React18.createElement(Select.Option, {
1094
+ key: option,
1095
+ value: option
1096
+ }, t(`settings overscroll ${option} label`)))))))), /* @__PURE__ */ React18.createElement(DeprecatedFormInput, {
1097
+ label: t("settings show hints label")
1098
+ }, /* @__PURE__ */ React18.createElement(Input.Switch, {
1099
+ checked: settings.showHints,
1100
+ onCheckedChange: (checked) => settings.showHints = checked
1101
+ })), !isSocket && /* @__PURE__ */ React18.createElement(DeprecatedFormInput, {
1102
+ label: t("settings native redirect label")
1103
+ }, /* @__PURE__ */ React18.createElement(Input.Switch, {
1104
+ checked: settings.enableNativeRedirect,
1105
+ onCheckedChange: (checked) => settings.enableNativeRedirect = checked
1106
+ })), /* @__PURE__ */ React18.createElement(DeprecatedFormInput, {
1107
+ label: t("settings enable ide-style statusbar label")
1108
+ }, /* @__PURE__ */ React18.createElement(Input.Switch, {
1109
+ checked: settings.enableIdeStyleStatusbar,
1110
+ onCheckedChange: (checked) => settings.enableIdeStyleStatusbar = checked
1111
+ })));
1112
+ };
1113
+
1114
+ export {
1115
+ Banner,
1116
+ DeckLayout,
1117
+ LayoutSettings
1118
+ };
1119
+ //# sourceMappingURL=chunk-WXNLVMK2.mjs.map