@dxos/plugin-navtree 0.8.4-main.3f58842 → 0.8.4-main.52d7546f51

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 (184) hide show
  1. package/dist/lib/browser/app-graph-builder-XGA4GPGL.mjs +44 -0
  2. package/dist/lib/browser/app-graph-builder-XGA4GPGL.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-63YLDLLE.mjs +1373 -0
  4. package/dist/lib/browser/chunk-63YLDLLE.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-X2HDG62A.mjs +23 -0
  6. package/dist/lib/browser/chunk-X2HDG62A.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-YKTYPINZ.mjs +19 -0
  8. package/dist/lib/browser/chunk-YKTYPINZ.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +85 -96
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/{keyboard-QRS6WOQH.mjs → keyboard-46XQHY2O.mjs} +21 -19
  12. package/dist/lib/browser/keyboard-46XQHY2O.mjs.map +7 -0
  13. package/dist/lib/browser/meta.json +1 -1
  14. package/dist/lib/browser/operation-resolver-NNNDII45.mjs +53 -0
  15. package/dist/lib/browser/operation-resolver-NNNDII45.mjs.map +7 -0
  16. package/dist/lib/browser/react-surface-APSEG23H.mjs +59 -0
  17. package/dist/lib/browser/react-surface-APSEG23H.mjs.map +7 -0
  18. package/dist/lib/browser/state-M5YUCIQU.mjs +121 -0
  19. package/dist/lib/browser/state-M5YUCIQU.mjs.map +7 -0
  20. package/dist/types/src/NavTreePlugin.d.ts +2 -1
  21. package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
  22. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
  23. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
  24. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
  25. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
  26. package/dist/types/src/capabilities/index.d.ts +5 -105
  27. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  28. package/dist/types/src/capabilities/keyboard/index.d.ts +3 -0
  29. package/dist/types/src/capabilities/keyboard/index.d.ts.map +1 -0
  30. package/dist/types/src/capabilities/keyboard/keyboard.d.ts +5 -0
  31. package/dist/types/src/capabilities/keyboard/keyboard.d.ts.map +1 -0
  32. package/dist/types/src/capabilities/operation-resolver/index.d.ts +3 -0
  33. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
  34. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +5 -0
  35. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
  36. package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
  37. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  38. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
  39. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  40. package/dist/types/src/capabilities/state/index.d.ts +3 -0
  41. package/dist/types/src/capabilities/state/index.d.ts.map +1 -0
  42. package/dist/types/src/capabilities/state/state.d.ts +6 -0
  43. package/dist/types/src/capabilities/state/state.d.ts.map +1 -0
  44. package/dist/types/src/components/CommandsDialog/CommandsDialog.d.ts +3 -2
  45. package/dist/types/src/components/CommandsDialog/CommandsDialog.d.ts.map +1 -1
  46. package/dist/types/src/components/CommandsDialog/CommandsTrigger.d.ts.map +1 -1
  47. package/dist/types/src/components/NavTree/NavTree.d.ts +32 -3
  48. package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
  49. package/dist/types/src/components/NavTree/NavTree.stories.d.ts +29 -4
  50. package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
  51. package/dist/types/src/components/NavTreeContainer.d.ts +8 -1
  52. package/dist/types/src/components/NavTreeContainer.d.ts.map +1 -1
  53. package/dist/types/src/components/NavTreeDocumentTitle.d.ts +1 -1
  54. package/dist/types/src/components/NavTreeDocumentTitle.d.ts.map +1 -1
  55. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +6 -6
  56. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
  57. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +33 -4
  58. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts.map +1 -1
  59. package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts +2 -2
  60. package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
  61. package/dist/types/src/components/Sidebar/L0Menu.d.ts +6 -4
  62. package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
  63. package/dist/types/src/components/Sidebar/L1Panel.d.ts +6 -7
  64. package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
  65. package/dist/types/src/components/Sidebar/L1Tabs.d.ts +12 -0
  66. package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -0
  67. package/dist/types/src/components/Sidebar/index.d.ts +1 -0
  68. package/dist/types/src/components/Sidebar/index.d.ts.map +1 -1
  69. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.d.ts.map +1 -1
  70. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts +8 -5
  71. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
  72. package/dist/types/src/components/index.d.ts.map +1 -1
  73. package/dist/types/src/components/types.d.ts +8 -8
  74. package/dist/types/src/components/types.d.ts.map +1 -1
  75. package/dist/types/src/experimental/Tree.d.ts +1 -2
  76. package/dist/types/src/experimental/Tree.d.ts.map +1 -1
  77. package/dist/types/src/experimental/Tree.stories.d.ts +23 -6
  78. package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
  79. package/dist/types/src/hooks.d.ts +32 -1
  80. package/dist/types/src/hooks.d.ts.map +1 -1
  81. package/dist/types/src/index.d.ts +1 -2
  82. package/dist/types/src/index.d.ts.map +1 -1
  83. package/dist/types/src/meta.d.ts +3 -4
  84. package/dist/types/src/meta.d.ts.map +1 -1
  85. package/dist/types/src/testing/app-graph-builder.d.ts +2 -3
  86. package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
  87. package/dist/types/src/testing/generator.d.ts +5 -6
  88. package/dist/types/src/testing/generator.d.ts.map +1 -1
  89. package/dist/types/src/testing/update-state.d.ts +2 -2
  90. package/dist/types/src/testing/update-state.d.ts.map +1 -1
  91. package/dist/types/src/translations.d.ts +1 -0
  92. package/dist/types/src/translations.d.ts.map +1 -1
  93. package/dist/types/src/types/capabilities.d.ts +16 -0
  94. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  95. package/dist/types/src/types/events.d.ts +5 -0
  96. package/dist/types/src/types/events.d.ts.map +1 -0
  97. package/dist/types/src/types/index.d.ts +4 -0
  98. package/dist/types/src/types/index.d.ts.map +1 -0
  99. package/dist/types/src/{types.d.ts → types/schema.d.ts} +10 -9
  100. package/dist/types/src/types/schema.d.ts.map +1 -0
  101. package/dist/types/src/util.d.ts +8 -9
  102. package/dist/types/src/util.d.ts.map +1 -1
  103. package/dist/types/tsconfig.tsbuildinfo +1 -1
  104. package/package.json +56 -53
  105. package/src/NavTreePlugin.tsx +63 -83
  106. package/src/capabilities/app-graph-builder/app-graph-builder.ts +42 -0
  107. package/src/capabilities/app-graph-builder/index.ts +7 -0
  108. package/src/capabilities/index.ts +5 -9
  109. package/src/capabilities/keyboard/index.ts +7 -0
  110. package/src/capabilities/keyboard/keyboard.ts +66 -0
  111. package/src/capabilities/operation-resolver/index.ts +7 -0
  112. package/src/capabilities/operation-resolver/operation-resolver.ts +42 -0
  113. package/src/capabilities/react-surface/index.ts +7 -0
  114. package/src/capabilities/react-surface/react-surface.tsx +55 -0
  115. package/src/capabilities/state/index.ts +7 -0
  116. package/src/capabilities/state/state.ts +122 -0
  117. package/src/components/CommandsDialog/CommandsDialog.tsx +108 -98
  118. package/src/components/CommandsDialog/CommandsTrigger.tsx +6 -15
  119. package/src/components/NavTree/NavTree.stories.tsx +99 -93
  120. package/src/components/NavTree/NavTree.tsx +12 -18
  121. package/src/components/NavTreeContainer.tsx +282 -257
  122. package/src/components/NavTreeDocumentTitle.tsx +5 -4
  123. package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +20 -12
  124. package/src/components/NavTreeItem/NavTreeItemAction.tsx +25 -18
  125. package/src/components/NavTreeItem/NavTreeItemColumns.tsx +38 -32
  126. package/src/components/Sidebar/L0Menu.tsx +115 -143
  127. package/src/components/Sidebar/L1Panel.tsx +177 -121
  128. package/src/components/Sidebar/L1Tabs.tsx +33 -0
  129. package/src/components/Sidebar/index.ts +1 -0
  130. package/src/components/UserAccountAvatar/UserAccountAvatar.stories.tsx +9 -8
  131. package/src/components/UserAccountAvatar/UserAccountAvatar.tsx +20 -12
  132. package/src/components/index.ts +1 -0
  133. package/src/components/types.ts +9 -8
  134. package/src/experimental/Tree.stories.tsx +69 -77
  135. package/src/experimental/Tree.tsx +7 -24
  136. package/src/hooks.ts +54 -2
  137. package/src/index.ts +1 -2
  138. package/src/meta.ts +11 -8
  139. package/src/testing/app-graph-builder.ts +159 -234
  140. package/src/testing/generator.ts +20 -18
  141. package/src/testing/update-state.ts +6 -6
  142. package/src/translations.ts +1 -0
  143. package/src/types/capabilities.ts +21 -0
  144. package/src/types/events.ts +12 -0
  145. package/src/types/index.ts +7 -0
  146. package/src/{types.ts → types/schema.ts} +9 -8
  147. package/src/util.ts +14 -35
  148. package/dist/lib/browser/app-graph-builder-5J4LRWDX.mjs +0 -45
  149. package/dist/lib/browser/app-graph-builder-5J4LRWDX.mjs.map +0 -7
  150. package/dist/lib/browser/chunk-ERDGQTH5.mjs +0 -16
  151. package/dist/lib/browser/chunk-ERDGQTH5.mjs.map +0 -7
  152. package/dist/lib/browser/chunk-SICQTLXC.mjs +0 -1442
  153. package/dist/lib/browser/chunk-SICQTLXC.mjs.map +0 -7
  154. package/dist/lib/browser/chunk-WCARAZ7J.mjs +0 -15
  155. package/dist/lib/browser/chunk-WCARAZ7J.mjs.map +0 -7
  156. package/dist/lib/browser/intent-resolver-3XYN2CBU.mjs +0 -47
  157. package/dist/lib/browser/intent-resolver-3XYN2CBU.mjs.map +0 -7
  158. package/dist/lib/browser/keyboard-QRS6WOQH.mjs.map +0 -7
  159. package/dist/lib/browser/react-surface-WURHCBQQ.mjs +0 -51
  160. package/dist/lib/browser/react-surface-WURHCBQQ.mjs.map +0 -7
  161. package/dist/lib/browser/state-54DY3DOY.mjs +0 -117
  162. package/dist/lib/browser/state-54DY3DOY.mjs.map +0 -7
  163. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
  164. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  165. package/dist/types/src/capabilities/capabilities.d.ts +0 -21
  166. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  167. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  168. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  169. package/dist/types/src/capabilities/keyboard.d.ts +0 -4
  170. package/dist/types/src/capabilities/keyboard.d.ts.map +0 -1
  171. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  172. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  173. package/dist/types/src/capabilities/state.d.ts +0 -20
  174. package/dist/types/src/capabilities/state.d.ts.map +0 -1
  175. package/dist/types/src/events.d.ts +0 -4
  176. package/dist/types/src/events.d.ts.map +0 -1
  177. package/dist/types/src/types.d.ts.map +0 -1
  178. package/src/capabilities/app-graph-builder.ts +0 -52
  179. package/src/capabilities/capabilities.ts +0 -20
  180. package/src/capabilities/intent-resolver.ts +0 -37
  181. package/src/capabilities/keyboard.ts +0 -59
  182. package/src/capabilities/react-surface.tsx +0 -45
  183. package/src/capabilities/state.ts +0 -104
  184. package/src/events.ts +0 -11
@@ -0,0 +1,1373 @@
1
+ import {
2
+ NavTreeCapabilities
3
+ } from "./chunk-X2HDG62A.mjs";
4
+ import {
5
+ COMMANDS_DIALOG,
6
+ KEY_BINDING,
7
+ meta
8
+ } from "./chunk-YKTYPINZ.mjs";
9
+
10
+ // src/components/CommandsDialog/CommandsDialog.tsx
11
+ import React, { forwardRef, useMemo, useState } from "react";
12
+ import { useOperationInvoker } from "@dxos/app-framework/ui";
13
+ import { LayoutOperation } from "@dxos/app-toolkit";
14
+ import { useAppGraph } from "@dxos/app-toolkit/ui";
15
+ import { Keyboard, keySymbols } from "@dxos/keyboard";
16
+ import { Graph, Node, useActionRunner } from "@dxos/plugin-graph";
17
+ import { useActions } from "@dxos/plugin-graph";
18
+ import { Button, Dialog, toLocalizedString, useTranslation } from "@dxos/react-ui";
19
+ import { SearchList, useSearchListResults } from "@dxos/react-ui-searchlist";
20
+ import { osTranslations } from "@dxos/ui-theme";
21
+ import { getHostPlatform } from "@dxos/util";
22
+ var CommandsDialogContent = /* @__PURE__ */ forwardRef(({ selected: initial }, forwardedRef) => {
23
+ const { t } = useTranslation(meta.id);
24
+ const { invokeSync } = useOperationInvoker();
25
+ const runAction = useActionRunner();
26
+ const { graph } = useAppGraph();
27
+ const [selected, setSelected] = useState(initial);
28
+ const allActions = useMemo(() => {
29
+ const current = Keyboard.singleton.getCurrentContext();
30
+ const actionMap = /* @__PURE__ */ new Set();
31
+ const actions2 = [];
32
+ Graph.traverse(graph, {
33
+ visitor: (node, path) => {
34
+ if ((Node.isAction(node) || Node.isActionGroup(node)) && !actionMap.has(node.id) && current.startsWith(path.slice(0, -1).join("/"))) {
35
+ actionMap.add(node.id);
36
+ actions2.push(node);
37
+ }
38
+ }
39
+ });
40
+ actions2.sort((a, b) => {
41
+ return toLocalizedString(a.properties.label, t)?.toLowerCase().localeCompare(toLocalizedString(b.properties.label, t)?.toLowerCase());
42
+ });
43
+ return actions2;
44
+ }, [
45
+ graph
46
+ ]);
47
+ const group = allActions.find(({ id }) => id === selected);
48
+ const groupActions = useActions(graph, group?.id);
49
+ const actions = Node.isActionGroup(group) ? groupActions : allActions;
50
+ const { results, handleSearch } = useSearchListResults({
51
+ items: actions,
52
+ extract: (action) => toLocalizedString(action.properties.label, t)
53
+ });
54
+ return /* @__PURE__ */ React.createElement(Dialog.Content, {
55
+ ref: forwardedRef
56
+ }, /* @__PURE__ */ React.createElement(Dialog.Title, null, t("commands dialog title", {
57
+ ns: meta.id
58
+ })), /* @__PURE__ */ React.createElement(SearchList.Root, {
59
+ onSearch: handleSearch
60
+ }, /* @__PURE__ */ React.createElement(SearchList.Content, null, /* @__PURE__ */ React.createElement(SearchList.Input, {
61
+ placeholder: t("command list input placeholder")
62
+ }), /* @__PURE__ */ React.createElement(SearchList.Viewport, null, results.map((action) => {
63
+ const shortcut = typeof action.properties.keyBinding === "string" ? action.properties.keyBinding : action.properties.keyBinding?.[getHostPlatform()];
64
+ return /* @__PURE__ */ React.createElement(SearchList.Item, {
65
+ value: action.id,
66
+ key: action.id,
67
+ label: toLocalizedString(action.properties.label, t),
68
+ icon: action.properties.icon,
69
+ suffix: shortcut ? keySymbols(shortcut).join("") : void 0,
70
+ onSelect: () => {
71
+ if (action.properties.disabled) {
72
+ return;
73
+ }
74
+ if (Node.isActionGroup(action)) {
75
+ setSelected(action.id);
76
+ return;
77
+ }
78
+ invokeSync(LayoutOperation.UpdateDialog, {
79
+ state: false
80
+ });
81
+ setTimeout(() => {
82
+ const node = Graph.getConnections(graph, group?.id ?? action.id, "inbound")[0];
83
+ if (node && Node.isAction(action)) {
84
+ void runAction(action, {
85
+ parent: node,
86
+ caller: KEY_BINDING
87
+ });
88
+ }
89
+ });
90
+ },
91
+ classNames: "flex items-center gap-2",
92
+ disabled: action.properties.disabled,
93
+ ...action.properties?.testId && {
94
+ "data-testid": action.properties.testId
95
+ }
96
+ });
97
+ })))), /* @__PURE__ */ React.createElement("div", {
98
+ role: "none",
99
+ className: "pli-cardSpacingInline pbe-cardSpacingBlock"
100
+ }, /* @__PURE__ */ React.createElement(Dialog.Close, {
101
+ asChild: true
102
+ }, /* @__PURE__ */ React.createElement(Button, {
103
+ classNames: "is-full"
104
+ }, t("close label", {
105
+ ns: osTranslations
106
+ })))));
107
+ });
108
+
109
+ // src/components/CommandsDialog/CommandsTrigger.tsx
110
+ import React2 from "react";
111
+ import { useOperationInvoker as useOperationInvoker2 } from "@dxos/app-framework/ui";
112
+ import { LayoutOperation as LayoutOperation2 } from "@dxos/app-toolkit";
113
+ import { Button as Button2, Icon, useTranslation as useTranslation2 } from "@dxos/react-ui";
114
+ var CommandsTrigger = () => {
115
+ const { invokeSync } = useOperationInvoker2();
116
+ const { t } = useTranslation2(meta.id);
117
+ return /* @__PURE__ */ React2.createElement(Button2, {
118
+ classNames: "m-1 pli-1 lg:pli-2",
119
+ onClick: () => invokeSync(LayoutOperation2.UpdateDialog, {
120
+ subject: COMMANDS_DIALOG,
121
+ blockAlign: "start"
122
+ })
123
+ }, /* @__PURE__ */ React2.createElement("span", {
124
+ className: "text-description font-normal grow text-start"
125
+ }, t("command list input placeholder")), /* @__PURE__ */ React2.createElement(Icon, {
126
+ icon: "ph--magnifying-glass--regular",
127
+ size: 5
128
+ }));
129
+ };
130
+
131
+ // src/util.ts
132
+ import { Graph as Graph2, Node as Node2 } from "@dxos/plugin-graph";
133
+ import { isNonNullable } from "@dxos/util";
134
+ var getParent = (graph, node, path) => {
135
+ const parentId = path[path.length - 2];
136
+ return Graph2.getConnections(graph, node.id, "inbound").find((n) => n.id === parentId);
137
+ };
138
+ var getPersistenceParent = (graph, node, path, persistenceClass) => {
139
+ if (node.properties.acceptPersistenceClass?.has(persistenceClass)) {
140
+ return node;
141
+ } else {
142
+ const parent = getParent(graph, node, path);
143
+ return parent ? getPersistenceParent(graph, parent, path.slice(0, path.length - 1), persistenceClass) : null;
144
+ }
145
+ };
146
+ var resolveMigrationOperation = (graph, activeNode, destinationPath, destinationRelatedNode) => {
147
+ const activeClass = activeNode.properties.persistenceClass;
148
+ if (destinationRelatedNode && activeClass) {
149
+ const persistenceParent = getPersistenceParent(graph, destinationRelatedNode, destinationPath, activeClass);
150
+ if (persistenceParent) {
151
+ const activeKey = activeNode.properties.persistenceKey;
152
+ if (activeKey && persistenceParent?.properties.acceptPersistenceKey) {
153
+ return persistenceParent.properties.acceptPersistenceKey.has(activeKey) && persistenceParent.properties.onTransferStart ? "transfer" : persistenceParent.properties.onCopy ? "copy" : "reject";
154
+ } else {
155
+ return "reject";
156
+ }
157
+ } else {
158
+ return "reject";
159
+ }
160
+ } else {
161
+ return "reject";
162
+ }
163
+ };
164
+ var sortActions = (actions) => actions.sort((a, b) => {
165
+ if (a.properties.disposition === b.properties.disposition) {
166
+ return 0;
167
+ }
168
+ if (a.properties.disposition === "list-item-primary") {
169
+ return -1;
170
+ }
171
+ return 1;
172
+ });
173
+ var getChildren = (graph, node, path = []) => {
174
+ return Graph2.getConnections(graph, node.id, "outbound").map((n) => {
175
+ const nextPath = [
176
+ ...path,
177
+ node.id
178
+ ];
179
+ return nextPath.includes(n.id) ? void 0 : n;
180
+ }).filter(isNonNullable);
181
+ };
182
+ var l0ItemType = (item) => {
183
+ if (Node2.isActionLike(item)) {
184
+ return "action";
185
+ } else {
186
+ return "tab";
187
+ }
188
+ };
189
+
190
+ // src/components/NavTreeContainer.tsx
191
+ import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
192
+ import { extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
193
+ import React10, { forwardRef as forwardRef4, memo as memo2, useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo6 } from "react";
194
+ import { Surface, useOperationInvoker as useOperationInvoker3 } from "@dxos/app-framework/ui";
195
+ import { LayoutOperation as LayoutOperation3 } from "@dxos/app-toolkit";
196
+ import { useAppGraph as useAppGraph2, useLayout } from "@dxos/app-toolkit/ui";
197
+ import { PLANK_COMPANION_TYPE } from "@dxos/plugin-deck/types";
198
+ import { Graph as Graph3, Node as Node5, useActionRunner as useActionRunner5 } from "@dxos/plugin-graph";
199
+ import { useConnections, useActions as useGraphActions } from "@dxos/plugin-graph";
200
+ import { useMediaQuery as useMediaQuery2, useSidebars } from "@dxos/react-ui";
201
+ import { isTreeData } from "@dxos/react-ui-list";
202
+ import { mx as mx2 } from "@dxos/ui-theme";
203
+ import { arrayMove as arrayMove2, byPosition } from "@dxos/util";
204
+
205
+ // src/hooks.ts
206
+ import { useAtomValue } from "@effect-atom/atom-react";
207
+ import { useEffect as useEffect2, useMemo as useMemo5 } from "react";
208
+ import { useCapability } from "@dxos/app-framework/ui";
209
+
210
+ // src/components/NavTree/NavTree.tsx
211
+ import React9, { forwardRef as forwardRef3, useMemo as useMemo4 } from "react";
212
+ import { Tabs as Tabs3 } from "@dxos/react-ui-tabs";
213
+
214
+ // src/components/NavTreeContext.tsx
215
+ import { createContext, useContext } from "react";
216
+ import { raise } from "@dxos/debug";
217
+ var NavTreeContext = /* @__PURE__ */ createContext(null);
218
+ var useNavTreeContext = () => useContext(NavTreeContext) ?? raise(new Error("Missing NavTreeContext"));
219
+
220
+ // src/components/Sidebar/L0Menu.tsx
221
+ import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
222
+ import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
223
+ import { preserveOffsetOnSource } from "@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source";
224
+ import { scrollJustEnoughIntoView } from "@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view";
225
+ import { attachClosestEdge, extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
226
+ import React4, { forwardRef as forwardRef2, useCallback, useLayoutEffect, useMemo as useMemo2, useRef, useState as useState2 } from "react";
227
+ import { DxAvatar } from "@dxos/lit-ui/react";
228
+ import { useActionRunner as useActionRunner2 } from "@dxos/plugin-graph";
229
+ import { Icon as Icon2, ListItem, ScrollArea, Tooltip, toLocalizedString as toLocalizedString2, useMediaQuery, useTranslation as useTranslation3 } from "@dxos/react-ui";
230
+ import { DropdownMenu, MenuProvider } from "@dxos/react-ui-menu";
231
+ import { Tabs } from "@dxos/react-ui-tabs";
232
+ import { mx } from "@dxos/ui-theme";
233
+ import { arrayMove } from "@dxos/util";
234
+
235
+ // src/components/UserAccountAvatar/UserAccountAvatar.tsx
236
+ import React3 from "react";
237
+ import { Avatar } from "@dxos/react-ui";
238
+ import { hexToFallback } from "@dxos/util";
239
+ var UserAccountAvatar = ({ size, userId, hue, emoji, status }) => {
240
+ const fallbackValue = hexToFallback(userId ?? "0");
241
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(L0ItemActiveTabIndicator, {
242
+ classNames: "inset-block-6"
243
+ }), /* @__PURE__ */ React3.createElement("div", {
244
+ className: "grid place-items-center dx-focus-ring-group-indicator rounded-full",
245
+ "data-joyride": "welcome/account"
246
+ }, /* @__PURE__ */ React3.createElement(Avatar.Root, null, /* @__PURE__ */ React3.createElement(Avatar.Content, {
247
+ variant: "circle",
248
+ size: size ?? 12,
249
+ status: status ?? "active",
250
+ hue: hue || fallbackValue.hue,
251
+ fallback: emoji || fallbackValue.emoji,
252
+ "data-testid": "treeView.userAccount"
253
+ }))));
254
+ };
255
+
256
+ // src/components/Sidebar/L0Menu.tsx
257
+ var useL0ItemClick = ({ item, parent, path }, type) => {
258
+ const { tab, onSelect, onTabChange } = useNavTreeContext();
259
+ const { getItem } = useNavTreeState();
260
+ const [isLg] = useMediaQuery("lg");
261
+ const runAction = useActionRunner2();
262
+ return useCallback((event) => {
263
+ switch (type) {
264
+ case "action": {
265
+ const { properties: { caller } = {} } = item;
266
+ return void runAction(item, caller ? {
267
+ parent,
268
+ caller
269
+ } : {
270
+ parent
271
+ });
272
+ }
273
+ case "tab":
274
+ return onTabChange?.(item);
275
+ case "link":
276
+ return onSelect?.({
277
+ item,
278
+ path,
279
+ current: !getItem(path).current,
280
+ option: event.altKey
281
+ });
282
+ }
283
+ }, [
284
+ item,
285
+ parent,
286
+ type,
287
+ tab,
288
+ getItem,
289
+ onSelect,
290
+ onTabChange,
291
+ isLg,
292
+ runAction
293
+ ]);
294
+ };
295
+ var l0Breakpoints = {
296
+ lg: "hidden lg:grid"
297
+ };
298
+ var l0ItemRoot = 'group/l0item flex is-full justify-center items-center relative data[type!="collection"]:cursor-pointer app-no-drag dx-focus-ring-group';
299
+ var l0ItemContent = "flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm";
300
+ var L0ItemRoot = /* @__PURE__ */ forwardRef2(({ item, parent, path, children }, forwardedRef) => {
301
+ const { getProps } = useNavTreeContext();
302
+ const { id, testId } = getProps?.(item, path) ?? {};
303
+ const type = l0ItemType(item);
304
+ const itemPath = useMemo2(() => [
305
+ ...path,
306
+ item.id
307
+ ], [
308
+ item.id,
309
+ path
310
+ ]);
311
+ const { t } = useTranslation3(meta.id);
312
+ const localizedString = toLocalizedString2(item.properties.label, t);
313
+ const handleClick = useL0ItemClick({
314
+ item,
315
+ parent,
316
+ path: itemPath
317
+ }, type);
318
+ const rootProps = type === "tab" ? {
319
+ value: item.id,
320
+ tabIndex: 0,
321
+ onClick: handleClick,
322
+ "data-testid": testId,
323
+ "data-object-id": id
324
+ } : {
325
+ onClick: handleClick,
326
+ "data-testid": testId,
327
+ "data-object-id": id
328
+ };
329
+ return /* @__PURE__ */ React4.createElement(Tooltip.Trigger, {
330
+ asChild: true,
331
+ delayDuration: 0,
332
+ side: "right",
333
+ content: localizedString
334
+ }, /* @__PURE__ */ React4.createElement(Tabs.TabPrimitive, {
335
+ ...rootProps,
336
+ "data-type": type,
337
+ className: mx(l0ItemRoot, l0Breakpoints[item.properties.l0Breakpoint]),
338
+ ref: forwardedRef
339
+ }, children));
340
+ });
341
+ var L0ItemActiveTabIndicator = ({ classNames }) => /* @__PURE__ */ React4.createElement("div", {
342
+ role: "none",
343
+ className: mx("hidden group-aria-selected/l0item:block absolute inline-start-0 inset-block-2 is-1 bg-accentSurface rounded-ie", classNames)
344
+ });
345
+ var L0Item = ({ item, parent, path, pinned, onRearrange }) => {
346
+ const { t } = useTranslation3(meta.id);
347
+ const itemElement = useRef(null);
348
+ const [closestEdge, setEdge] = useState2(null);
349
+ const localizedString = toLocalizedString2(item.properties.label, t);
350
+ const hue = item.properties.hue ?? null;
351
+ useLayoutEffect(() => {
352
+ if (!itemElement.current || !onRearrange) {
353
+ return;
354
+ }
355
+ return combine(draggable({
356
+ element: itemElement.current,
357
+ getInitialData: () => ({
358
+ id: item.id,
359
+ type: "l0Item"
360
+ }),
361
+ onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
362
+ document.body.setAttribute("data-drag-preview", "true");
363
+ const element = source.element.querySelector("[data-frame]");
364
+ scrollJustEnoughIntoView({
365
+ element
366
+ });
367
+ const { x, y } = preserveOffsetOnSource({
368
+ element,
369
+ input: location.current.input
370
+ })({
371
+ container: element.offsetParent ?? document.body
372
+ });
373
+ nativeSetDragImage?.(element, x, y);
374
+ },
375
+ onDragStart: () => {
376
+ document.body.removeAttribute("data-drag-preview");
377
+ itemElement.current.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "active");
378
+ },
379
+ onDrop: () => {
380
+ itemElement.current.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "idle");
381
+ }
382
+ }), dropTargetForElements({
383
+ element: itemElement.current,
384
+ getData: ({ input, element }) => {
385
+ return attachClosestEdge({
386
+ id: item.id,
387
+ type: "l0Item"
388
+ }, {
389
+ input,
390
+ element,
391
+ allowedEdges: [
392
+ "top",
393
+ "bottom"
394
+ ]
395
+ });
396
+ },
397
+ onDragEnter: ({ self, source }) => {
398
+ if (source.data.type === self.data.type) {
399
+ setEdge(extractClosestEdge(self.data));
400
+ }
401
+ },
402
+ onDrag: ({ self, source }) => {
403
+ if (source.data.type === self.data.type) {
404
+ setEdge(extractClosestEdge(self.data));
405
+ }
406
+ },
407
+ onDragLeave: () => setEdge(null),
408
+ onDrop: ({ self, source }) => {
409
+ setEdge(null);
410
+ if (source.data.type === self.data.type) {
411
+ onRearrange(source.data, self.data, extractClosestEdge(self.data));
412
+ }
413
+ }
414
+ }));
415
+ }, [
416
+ item,
417
+ onRearrange
418
+ ]);
419
+ return /* @__PURE__ */ React4.createElement(L0ItemRoot, {
420
+ ref: itemElement,
421
+ item,
422
+ parent,
423
+ path
424
+ }, /* @__PURE__ */ React4.createElement("div", {
425
+ role: "none",
426
+ "data-frame": true,
427
+ ...hue && {
428
+ style: {
429
+ background: `var(--dx-${hue}Surface)`
430
+ }
431
+ },
432
+ className: mx(l0ItemContent, pinned ? "p-2 group-hover/l0item:bg-activeSurface" : "is-[--l0-avatar-size] bs-[--l0-avatar-size] bg-activeSurface")
433
+ }, /* @__PURE__ */ React4.createElement(ItemAvatar, {
434
+ item
435
+ })), /* @__PURE__ */ React4.createElement(L0ItemActiveTabIndicator, null), /* @__PURE__ */ React4.createElement("span", {
436
+ id: `${item.id}__label`,
437
+ className: "sr-only"
438
+ }, localizedString), closestEdge && /* @__PURE__ */ React4.createElement(ListItem.DropIndicator, {
439
+ edge: closestEdge
440
+ }));
441
+ };
442
+ var ItemAvatar = ({ item }) => {
443
+ const { t } = useTranslation3(meta.id);
444
+ const type = l0ItemType(item);
445
+ if (item.properties.icon) {
446
+ const hue = item.properties.hue ?? null;
447
+ const hueFgStyle = hue && {
448
+ style: {
449
+ color: `var(--dx-${hue}SurfaceText)`
450
+ }
451
+ };
452
+ return /* @__PURE__ */ React4.createElement(Icon2, {
453
+ icon: item.properties.icon,
454
+ size: 6,
455
+ ...hueFgStyle
456
+ });
457
+ }
458
+ if (type === "tab" && item.properties.disposition !== "pin-end") {
459
+ const hue = item.properties.hue ?? null;
460
+ const localizedString = toLocalizedString2(item.properties.label, t);
461
+ return /* @__PURE__ */ React4.createElement(DxAvatar, {
462
+ hue,
463
+ hueVariant: "surface",
464
+ variant: "square",
465
+ size: 12,
466
+ fallback: localizedString
467
+ });
468
+ }
469
+ return null;
470
+ };
471
+ var L0Menu = ({ menuActions, topLevelItems, pinnedItems, userAccountItem, parent, path }) => {
472
+ const { t } = useTranslation3(meta.id);
473
+ const runAction = useActionRunner2();
474
+ const handleAction = useCallback((action, params) => {
475
+ void runAction(action, params);
476
+ }, [
477
+ runAction
478
+ ]);
479
+ const handleRearrange = useCallback((source, target, closestEdge) => {
480
+ const sourceItem = topLevelItems.find((i) => i.id === source.id);
481
+ if (!sourceItem?.properties.onRearrange) {
482
+ return;
483
+ }
484
+ const sourceIndex = topLevelItems.findIndex((i) => i.id === source.id);
485
+ const targetIndex = topLevelItems.findIndex((i) => i.id === target.id);
486
+ const insertIndex = source.id === target.id ? sourceIndex : targetIndex + (sourceIndex < targetIndex ? closestEdge === "top" ? -1 : 0 : closestEdge === "bottom" ? 1 : 0);
487
+ const nextOrder = arrayMove([
488
+ ...topLevelItems
489
+ ], sourceIndex, insertIndex);
490
+ return sourceItem.properties.onRearrange(nextOrder.map((item) => item.data));
491
+ }, [
492
+ topLevelItems
493
+ ]);
494
+ const hasRearrangeableItems = topLevelItems.some((item) => item.properties.onRearrange);
495
+ return /* @__PURE__ */ React4.createElement(Tabs.Tablist, {
496
+ classNames: [
497
+ "group/l0 absolute z-[1] inset-block-0 inline-start-0 rounded-is",
498
+ "grid grid-cols-[var(--l0-size)] grid-rows-[var(--rail-size)_1fr_min-content_var(--l0-size)] contain-layout",
499
+ "!is-[--l0-size] bg-baseSurface border-ie border-subduedSeparator app-drag pbe-[env(safe-area-inset-bottom)]"
500
+ ]
501
+ }, /* @__PURE__ */ React4.createElement(MenuProvider, {
502
+ onAction: handleAction
503
+ }, /* @__PURE__ */ React4.createElement(DropdownMenu.Root, {
504
+ group: parent,
505
+ items: menuActions
506
+ }, /* @__PURE__ */ React4.createElement(Tooltip.Trigger, {
507
+ content: t("app menu label"),
508
+ side: "right",
509
+ asChild: true
510
+ }, /* @__PURE__ */ React4.createElement(Tabs.TabPrimitive, {
511
+ value: "options",
512
+ asChild: true,
513
+ role: "button"
514
+ }, /* @__PURE__ */ React4.createElement(DropdownMenu.Trigger, {
515
+ "data-testid": "spacePlugin.addSpace",
516
+ className: mx(l0ItemRoot, "grid place-items-center dx-focus-ring-group", '[body[data-platform="macos"]_&]:mt-[30px]')
517
+ }, /* @__PURE__ */ React4.createElement("div", {
518
+ role: "none",
519
+ className: mx(l0ItemContent, "bs-[--rail-action] is-[--rail-action] group-hover/l0item:bg-hoverSurface")
520
+ }, /* @__PURE__ */ React4.createElement(Icon2, {
521
+ icon: "ph--list--regular",
522
+ size: 5
523
+ }))))))), /* @__PURE__ */ React4.createElement(ScrollArea.Root, {
524
+ thin: true,
525
+ orientation: "vertical"
526
+ }, /* @__PURE__ */ React4.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React4.createElement("div", {
527
+ role: "none",
528
+ className: mx([
529
+ "flex flex-col gap-1 pbs-1",
530
+ '[body[data-platform="macos"]_&]:pbs-[30px]',
531
+ '[body[data-platform="ios"]_&]:pbs-[max(env(safe-area-inset-top),0.25rem)]'
532
+ ])
533
+ }, topLevelItems.map((item) => /* @__PURE__ */ React4.createElement(L0Item, {
534
+ key: item.id,
535
+ item,
536
+ parent,
537
+ path,
538
+ ...hasRearrangeableItems && {
539
+ onRearrange: handleRearrange
540
+ }
541
+ }))))), /* @__PURE__ */ React4.createElement("div", {
542
+ role: "none",
543
+ className: "grid grid-cols-1 auto-rows-[--rail-action] pbs-2"
544
+ }, pinnedItems.map((item) => /* @__PURE__ */ React4.createElement(L0Item, {
545
+ key: item.id,
546
+ item,
547
+ parent,
548
+ path,
549
+ pinned: true
550
+ }))), userAccountItem && /* @__PURE__ */ React4.createElement("div", {
551
+ role: "none",
552
+ className: "grid app-no-drag"
553
+ }, /* @__PURE__ */ React4.createElement(L0ItemRoot, {
554
+ key: userAccountItem.id,
555
+ item: userAccountItem,
556
+ parent,
557
+ path
558
+ }, /* @__PURE__ */ React4.createElement(UserAccountAvatar, {
559
+ userId: userAccountItem.properties.userId,
560
+ hue: userAccountItem.properties.hue,
561
+ emoji: userAccountItem.properties.emoji,
562
+ status: userAccountItem.properties.status,
563
+ size: 10
564
+ }))));
565
+ };
566
+
567
+ // src/components/Sidebar/L1Panel.tsx
568
+ import * as Effect from "effect/Effect";
569
+ import React7, { useCallback as useCallback2, useMemo as useMemo3 } from "react";
570
+ import { Node as Node4 } from "@dxos/app-graph";
571
+ import { useActionRunner as useActionRunner4 } from "@dxos/plugin-graph";
572
+ import { DensityProvider, IconButton as IconButton2, ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString5, useTranslation as useTranslation6 } from "@dxos/react-ui";
573
+ import { Tree } from "@dxos/react-ui-list";
574
+ import { DropdownMenu as DropdownMenu3, MenuProvider as MenuProvider3 } from "@dxos/react-ui-menu";
575
+ import { Tabs as Tabs2 } from "@dxos/react-ui-tabs";
576
+ import { hoverableControlItem as hoverableControlItem2, hoverableOpenControlItem as hoverableOpenControlItem2 } from "@dxos/ui-theme";
577
+
578
+ // src/components/NavTreeItem/NavTreeItemAction.tsx
579
+ import React5 from "react";
580
+ import { useActionRunner as useActionRunner3 } from "@dxos/plugin-graph";
581
+ import { IconButton, toLocalizedString as toLocalizedString3, useDensityContext, useTranslation as useTranslation4 } from "@dxos/react-ui";
582
+ import { DropdownMenu as DropdownMenu2, MenuProvider as MenuProvider2 } from "@dxos/react-ui-menu";
583
+ import { hoverableControlItem, hoverableOpenControlItem } from "@dxos/ui-theme";
584
+ var fallbackIcon = "ph--placeholder--regular";
585
+ var fineActionButtonProps = {
586
+ size: 4,
587
+ density: "fine"
588
+ };
589
+ var coarseActionButtonProps = {
590
+ size: 5,
591
+ density: "coarse"
592
+ };
593
+ var NavTreeItemActionDropdownMenu = ({ parent, label, icon, testId, menuActions, caller }) => {
594
+ const { t } = useTranslation4(meta.id);
595
+ const density = useDensityContext();
596
+ const runAction = useActionRunner3();
597
+ return /* @__PURE__ */ React5.createElement(MenuProvider2, {
598
+ onAction: runAction
599
+ }, /* @__PURE__ */ React5.createElement(DropdownMenu2.Root, {
600
+ group: parent,
601
+ items: menuActions,
602
+ caller
603
+ }, /* @__PURE__ */ React5.createElement(DropdownMenu2.Trigger, {
604
+ asChild: true
605
+ }, /* @__PURE__ */ React5.createElement(IconButton, {
606
+ ...density === "coarse" ? coarseActionButtonProps : fineActionButtonProps,
607
+ classNames: [
608
+ "shrink-0 pli-2 pointer-fine:pli-1",
609
+ hoverableControlItem,
610
+ hoverableOpenControlItem
611
+ ],
612
+ variant: "ghost",
613
+ icon: icon ?? fallbackIcon,
614
+ iconOnly: true,
615
+ label: toLocalizedString3(label, t),
616
+ "data-testid": testId
617
+ }))));
618
+ };
619
+ var NavTreeItemMonolithicAction = (props) => {
620
+ const { parent, properties: { disabled, caller, testId, icon, variant = "ghost", iconOnly = true } = {
621
+ label: "never"
622
+ }, baseLabel } = props;
623
+ const density = useDensityContext();
624
+ const runAction = useActionRunner3();
625
+ return /* @__PURE__ */ React5.createElement(IconButton, {
626
+ ...density === "coarse" ? coarseActionButtonProps : fineActionButtonProps,
627
+ variant,
628
+ classNames: [
629
+ "shrink-0",
630
+ hoverableControlItem,
631
+ hoverableOpenControlItem,
632
+ iconOnly ? "pli-2 pointer-fine:pli-1" : "p-2 pointer-fine:p-2 mie-1"
633
+ ],
634
+ icon: icon ?? fallbackIcon,
635
+ iconOnly,
636
+ label: baseLabel,
637
+ disabled,
638
+ onClick: (event) => {
639
+ event.stopPropagation();
640
+ if (disabled) {
641
+ return;
642
+ }
643
+ void runAction(props, caller ? {
644
+ parent,
645
+ caller
646
+ } : {
647
+ parent
648
+ });
649
+ },
650
+ "data-testid": testId
651
+ });
652
+ };
653
+ var NavTreeItemAction = ({ monolithic, menuActions, parent: node, ...props }) => {
654
+ const { t } = useTranslation4(meta.id);
655
+ const monolithicAction = menuActions?.length === 1 && menuActions[0];
656
+ const baseLabel = toLocalizedString3(monolithicAction ? monolithicAction.properties.label : props.label, t);
657
+ return monolithic && menuActions?.length === 1 ? /* @__PURE__ */ React5.createElement(NavTreeItemMonolithicAction, {
658
+ baseLabel,
659
+ parent: node,
660
+ ...menuActions[0]
661
+ }) : /* @__PURE__ */ React5.createElement(NavTreeItemActionDropdownMenu, {
662
+ ...props,
663
+ label: baseLabel,
664
+ parent: node,
665
+ menuActions
666
+ });
667
+ };
668
+
669
+ // src/components/NavTreeItem/NavTreeItemColumns.tsx
670
+ import React6, { Fragment, memo } from "react";
671
+ import { Node as Node3 } from "@dxos/app-graph";
672
+ import { Popover, Treegrid, toLocalizedString as toLocalizedString4, useTranslation as useTranslation5 } from "@dxos/react-ui";
673
+ var NavTreeItemColumns = /* @__PURE__ */ memo(({ path, item, open }) => {
674
+ const { t } = useTranslation5(meta.id);
675
+ const { useActions: useActions3, renderItemEnd: ItemEnd, popoverAnchorId } = useNavTreeContext();
676
+ const level = path.length - 2;
677
+ const { actions: _actions, groupedActions } = useActions3(item);
678
+ const [primaryAction, ...secondaryActions] = _actions.toSorted((a, _b) => a.properties?.disposition === "list-item-primary" ? -1 : 1);
679
+ const actions = (primaryAction?.properties?.disposition === "list-item-primary" ? secondaryActions : _actions).flatMap((action) => Node3.isAction(action) ? [
680
+ action
681
+ ] : []).filter((a) => [
682
+ "list-item",
683
+ "list-item-primary"
684
+ ].includes(a.properties?.disposition));
685
+ useLoadDescendents(item);
686
+ useLoadDescendents(primaryAction && !Node3.isAction(primaryAction) ? primaryAction : void 0);
687
+ const ActionRoot = popoverAnchorId === `dxos.org/ui/${NAV_TREE_ITEM}/${item.id}` ? Popover.Anchor : Fragment;
688
+ return /* @__PURE__ */ React6.createElement("div", {
689
+ role: "none",
690
+ className: "contents app-no-drag"
691
+ }, primaryAction?.properties?.disposition === "list-item-primary" && !primaryAction?.properties?.disabled ? /* @__PURE__ */ React6.createElement(Treegrid.Cell, {
692
+ classNames: "contents"
693
+ }, /* @__PURE__ */ React6.createElement(NavTreeItemAction, {
694
+ testId: primaryAction.properties?.testId,
695
+ label: toLocalizedString4(primaryAction.properties?.label, t),
696
+ icon: primaryAction.properties?.icon ?? "ph--placeholder--regular",
697
+ parent: item,
698
+ monolithic: Node3.isAction(primaryAction),
699
+ menuActions: Node3.isAction(primaryAction) ? [
700
+ primaryAction
701
+ ] : groupedActions[primaryAction?.id ?? ""],
702
+ menuType: primaryAction.properties?.menuType,
703
+ caller: NAV_TREE_ITEM
704
+ })) : /* @__PURE__ */ React6.createElement(Treegrid.Cell, {
705
+ role: "none"
706
+ }), /* @__PURE__ */ React6.createElement(ActionRoot, null, actions.length > 0 ? /* @__PURE__ */ React6.createElement(Treegrid.Cell, {
707
+ classNames: "contents"
708
+ }, /* @__PURE__ */ React6.createElement(NavTreeItemAction, {
709
+ testId: `navtree.treeItem.actionsLevel${level}`,
710
+ label: t("tree item actions label"),
711
+ icon: "ph--dots-three-vertical--regular",
712
+ parent: item,
713
+ menuActions: actions,
714
+ menuType: "dropdown",
715
+ caller: NAV_TREE_ITEM
716
+ })) : /* @__PURE__ */ React6.createElement(Treegrid.Cell, {
717
+ role: "none"
718
+ })), ItemEnd && /* @__PURE__ */ React6.createElement(Treegrid.Cell, {
719
+ classNames: "contents"
720
+ }, /* @__PURE__ */ React6.createElement(ItemEnd, {
721
+ node: item,
722
+ open
723
+ })));
724
+ });
725
+
726
+ // src/components/Sidebar/L1Panel.tsx
727
+ var L1Panel = ({ open, path, item, currentItemId, onBack }) => {
728
+ const { t } = useTranslation6(meta.id);
729
+ const navTreeContext = useNavTreeContext();
730
+ const title = toLocalizedString5(item.properties.label, t);
731
+ const { useItems: useItems2 } = navTreeContext;
732
+ const alternateTree = useItems2(item, {
733
+ disposition: "alternate-tree"
734
+ })[0];
735
+ const alternatePath = useMemo3(() => [
736
+ ...path,
737
+ item.id
738
+ ], [
739
+ item.id,
740
+ path
741
+ ]);
742
+ const isAlternate = useIsAlternateTree(alternatePath, item);
743
+ const useAlternateItems = useCallback2((node, { disposition } = {}) => {
744
+ return useItems2(node, {
745
+ disposition,
746
+ sort: node?.id === alternateTree.id
747
+ });
748
+ }, [
749
+ alternateTree,
750
+ useItems2
751
+ ]);
752
+ return /* @__PURE__ */ React7.createElement(Tabs2.Tabpanel, {
753
+ key: item.id,
754
+ value: item.id,
755
+ classNames: [
756
+ "absolute inset-block-0 inline-end-0",
757
+ "is-[calc(100%-var(--l0-size))] lg:is-[--l1-size] grid-cols-1 grid-rows-[var(--rail-size)_1fr]",
758
+ "pbs-[env(safe-area-inset-top)]",
759
+ item.id === currentItemId && "grid"
760
+ ],
761
+ tabIndex: -1,
762
+ "aria-label": title,
763
+ ...!open && {
764
+ inert: true
765
+ }
766
+ }, item.id === currentItemId && /* @__PURE__ */ React7.createElement(DensityProvider, {
767
+ density: "fine"
768
+ }, /* @__PURE__ */ React7.createElement(L1PanelHeader, {
769
+ path,
770
+ item,
771
+ currentItemId,
772
+ onBack
773
+ }), /* @__PURE__ */ React7.createElement(ScrollArea2.Root, {
774
+ thin: true,
775
+ orientation: "vertical"
776
+ }, /* @__PURE__ */ React7.createElement(ScrollArea2.Viewport, null, isAlternate ? /* @__PURE__ */ React7.createElement(Tree, {
777
+ ...navTreeContext,
778
+ id: alternateTree.id,
779
+ root: alternateTree,
780
+ path: alternatePath,
781
+ levelOffset: 5,
782
+ gridTemplateColumns: "[tree-row-start] 1fr min-content min-content min-content [tree-row-end]",
783
+ renderColumns: NavTreeItemColumns,
784
+ useItems: useAlternateItems
785
+ }) : /* @__PURE__ */ React7.createElement(Tree, {
786
+ ...navTreeContext,
787
+ id: item.id,
788
+ root: item,
789
+ path,
790
+ levelOffset: 5,
791
+ gridTemplateColumns: "[tree-row-start] 1fr min-content min-content min-content [tree-row-end]",
792
+ renderColumns: NavTreeItemColumns,
793
+ draggable: true
794
+ })))));
795
+ };
796
+ var L1PanelHeader = ({ item, path, onBack }) => {
797
+ const { t } = useTranslation6(meta.id);
798
+ const { renderItemEnd: ItemEnd } = useNavTreeContext();
799
+ const title = toLocalizedString5(item.properties.label, t);
800
+ const { primaryAction, groupedActions, menuActions, onAction } = useL1MenuActions({
801
+ item,
802
+ path
803
+ });
804
+ useLoadDescendents(item);
805
+ return /* @__PURE__ */ React7.createElement("div", {
806
+ className: "flex is-full items-center border-be border-subduedSeparator app-drag density-coarse"
807
+ }, /* @__PURE__ */ React7.createElement("div", {
808
+ className: "is-6"
809
+ }), /* @__PURE__ */ React7.createElement("h2", {
810
+ className: "flex-1 truncate min-is-0"
811
+ }, title), /* @__PURE__ */ React7.createElement("div", {
812
+ role: "none",
813
+ className: "contents app-no-drag"
814
+ }, primaryAction?.properties?.disposition === "list-item-primary" && !primaryAction?.properties?.disabled && /* @__PURE__ */ React7.createElement(NavTreeItemAction, {
815
+ testId: primaryAction.properties?.testId,
816
+ label: toLocalizedString5(primaryAction.properties?.label, t),
817
+ icon: primaryAction.properties?.icon ?? "ph--placeholder--regular",
818
+ parent: item,
819
+ monolithic: Node4.isAction(primaryAction),
820
+ menuActions: Node4.isAction(primaryAction) ? [
821
+ primaryAction
822
+ ] : groupedActions[primaryAction?.id ?? ""],
823
+ menuType: primaryAction.properties?.menuType,
824
+ caller: NAV_TREE_ITEM
825
+ }), menuActions.length === 1 && /* @__PURE__ */ React7.createElement(IconButton2, {
826
+ size: 5,
827
+ density: "coarse",
828
+ classNames: [
829
+ "shrink-0 pli-2 pointer-fine:pli-1",
830
+ hoverableControlItem2,
831
+ hoverableOpenControlItem2
832
+ ],
833
+ variant: "ghost",
834
+ icon: menuActions[0].properties?.icon ?? "ph--placeholder--regular",
835
+ iconOnly: true,
836
+ label: toLocalizedString5(menuActions[0].properties?.label, t),
837
+ "data-testid": menuActions[0].properties?.testId,
838
+ onClick: () => onAction(menuActions[0])
839
+ }), menuActions.length > 1 && /* @__PURE__ */ React7.createElement(MenuProvider3, {
840
+ onAction
841
+ }, /* @__PURE__ */ React7.createElement(DropdownMenu3.Root, {
842
+ group: item,
843
+ items: menuActions,
844
+ caller: NAV_TREE_ITEM
845
+ }, /* @__PURE__ */ React7.createElement(DropdownMenu3.Trigger, {
846
+ asChild: true
847
+ }, /* @__PURE__ */ React7.createElement(IconButton2, {
848
+ size: 5,
849
+ density: "coarse",
850
+ classNames: [
851
+ "shrink-0 pli-2 pointer-fine:pli-1",
852
+ hoverableControlItem2,
853
+ hoverableOpenControlItem2
854
+ ],
855
+ variant: "ghost",
856
+ icon: "ph--dots-three-vertical--regular",
857
+ iconOnly: true,
858
+ label: t("tree item actions label"),
859
+ "data-testid": "navtree.treeItem.actionsLevel0"
860
+ })))), ItemEnd && /* @__PURE__ */ React7.createElement(ItemEnd, {
861
+ node: item,
862
+ open: true
863
+ })));
864
+ };
865
+ var useL1MenuActions = ({ item, path }) => {
866
+ const { t } = useTranslation6(meta.id);
867
+ const { setAlternateTree, useActions: useActions3, ...navTreeContext } = useNavTreeContext();
868
+ const runAction = useActionRunner4();
869
+ const alternateTree = navTreeContext.useItems(item, {
870
+ disposition: "alternate-tree"
871
+ })[0];
872
+ const alternatePath = useMemo3(() => [
873
+ ...path,
874
+ item.id
875
+ ], [
876
+ item.id,
877
+ path
878
+ ]);
879
+ const isAlternate = useIsAlternateTree(alternatePath, item);
880
+ const { actions: _actions, groupedActions } = useActions3(item);
881
+ const [primaryAction, ...secondaryActions] = _actions.toSorted((a, _b) => a.properties?.disposition === "list-item-primary" ? -1 : 1);
882
+ const graphMenuActions = (primaryAction?.properties?.disposition === "list-item-primary" ? secondaryActions : _actions).flatMap((action) => Node4.isAction(action) ? [
883
+ action
884
+ ] : []).filter((a) => [
885
+ "list-item",
886
+ "list-item-primary"
887
+ ].includes(a.properties?.disposition));
888
+ const settingsActionId = `${item.id}~settings`;
889
+ const settingsAction = useMemo3(() => {
890
+ if (!alternateTree) {
891
+ return void 0;
892
+ }
893
+ return {
894
+ id: settingsActionId,
895
+ type: Node4.ActionType,
896
+ data: () => Effect.void,
897
+ properties: {
898
+ label: isAlternate ? [
899
+ "button back",
900
+ {
901
+ ns: meta.id
902
+ }
903
+ ] : alternateTree.properties.label ?? alternateTree.id,
904
+ icon: isAlternate ? "ph--arrow-u-down-left--regular" : alternateTree.properties.icon ?? "ph--placeholder--regular",
905
+ disposition: "list-item",
906
+ testId: isAlternate ? "navtree.backToSpace" : "navtree.spaceSettings"
907
+ }
908
+ };
909
+ }, [
910
+ alternateTree,
911
+ isAlternate,
912
+ settingsActionId,
913
+ t
914
+ ]);
915
+ const menuActions = useMemo3(() => [
916
+ ...graphMenuActions,
917
+ ...settingsAction ? [
918
+ settingsAction
919
+ ] : []
920
+ ], [
921
+ graphMenuActions,
922
+ settingsAction
923
+ ]);
924
+ const onAction = useCallback2((action, params) => {
925
+ if (action.id === settingsActionId) {
926
+ setAlternateTree?.(alternatePath, !isAlternate);
927
+ } else {
928
+ void runAction(action, params);
929
+ }
930
+ }, [
931
+ settingsActionId,
932
+ setAlternateTree,
933
+ alternatePath,
934
+ isAlternate,
935
+ runAction
936
+ ]);
937
+ return {
938
+ primaryAction,
939
+ groupedActions,
940
+ menuActions,
941
+ onAction
942
+ };
943
+ };
944
+
945
+ // src/components/Sidebar/L1Tabs.tsx
946
+ import React8 from "react";
947
+ var L1Tabs = ({ topLevelItems, onBack, ...props }) => {
948
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, topLevelItems.map((item) => {
949
+ const type = l0ItemType(item);
950
+ if (type === "tab") {
951
+ return /* @__PURE__ */ React8.createElement(L1Panel, {
952
+ key: item.id,
953
+ item,
954
+ ...props,
955
+ onBack
956
+ });
957
+ }
958
+ return null;
959
+ }));
960
+ };
961
+
962
+ // src/components/NavTree/NavTree.tsx
963
+ var NAV_TREE_ITEM = "NavTreeItem";
964
+ var NavTree = /* @__PURE__ */ forwardRef3(({ id, root, ...props }, forwardedRef) => {
965
+ const { tab, useItems: useItems2, onBack } = useNavTreeContext();
966
+ const topLevelActions = useItems2(root, {
967
+ disposition: "menu",
968
+ sort: true
969
+ });
970
+ const topLevelWorkspaces = useItems2(root, {
971
+ disposition: "workspace"
972
+ });
973
+ const l0Items = topLevelWorkspaces;
974
+ const pinnedItems = useItems2(root, {
975
+ disposition: "pin-end",
976
+ sort: true
977
+ });
978
+ const userAccountItem = useItems2(root, {
979
+ disposition: "user-account"
980
+ })[0];
981
+ const topLevelItems = useMemo4(() => [
982
+ // prettier-ignore
983
+ ...l0Items,
984
+ ...pinnedItems,
985
+ ...userAccountItem ? [
986
+ userAccountItem
987
+ ] : []
988
+ ], [
989
+ l0Items,
990
+ pinnedItems,
991
+ userAccountItem
992
+ ]);
993
+ useLoadDescendents(root);
994
+ const path = useMemo4(() => [
995
+ id
996
+ ], [
997
+ id
998
+ ]);
999
+ return (
1000
+ // TODO(thure): `Tabs.Root` forces all items that should be able to receive focus to use `Tabs.Tab(Primitive)` since
1001
+ // it uses RovingFocus and doesn’t support moving focus to an item that is not a tab. Assess whether this situation
1002
+ // should change including whether it should motivate a change in the design/taxonomy, or if this means this should
1003
+ // not use `react-ui-tabs` at all.
1004
+ /* @__PURE__ */ React9.createElement(Tabs3.Root, {
1005
+ value: tab,
1006
+ orientation: "vertical",
1007
+ verticalVariant: "stateless",
1008
+ classNames: "relative",
1009
+ ref: forwardedRef
1010
+ }, /* @__PURE__ */ React9.createElement(L0Menu, {
1011
+ menuActions: topLevelActions,
1012
+ topLevelItems: l0Items,
1013
+ pinnedItems,
1014
+ userAccountItem,
1015
+ path,
1016
+ parent: root
1017
+ }), /* @__PURE__ */ React9.createElement(L1Tabs, {
1018
+ topLevelItems,
1019
+ path,
1020
+ currentItemId: tab,
1021
+ onBack,
1022
+ ...props
1023
+ }))
1024
+ );
1025
+ });
1026
+
1027
+ // src/components/NavTreeDocumentTitle.tsx
1028
+ import { useEffect } from "react";
1029
+ import { toLocalizedString as toLocalizedString6, useTranslation as useTranslation7 } from "@dxos/react-ui";
1030
+ import { osTranslations as osTranslations2 } from "@dxos/ui-theme";
1031
+ var NavTreeDocumentTitle = ({ node }) => {
1032
+ const { t } = useTranslation7(meta.id);
1033
+ useEffect(() => {
1034
+ document.title = node ? toLocalizedString6(node.properties.label, t) : t("current app name", {
1035
+ ns: osTranslations2
1036
+ });
1037
+ }, [
1038
+ node?.properties?.label
1039
+ ]);
1040
+ return null;
1041
+ };
1042
+
1043
+ // src/hooks.ts
1044
+ var useLoadDescendents = (root) => {
1045
+ const { loadDescendents } = useNavTreeContext();
1046
+ useEffect2(() => {
1047
+ const frame = requestAnimationFrame(() => {
1048
+ if (root) {
1049
+ void loadDescendents?.(root);
1050
+ }
1051
+ });
1052
+ return () => cancelAnimationFrame(frame);
1053
+ }, [
1054
+ root
1055
+ ]);
1056
+ };
1057
+ var useNavTreeState = () => {
1058
+ return useCapability(NavTreeCapabilities.State);
1059
+ };
1060
+ var useNavTreeItemState = (path) => {
1061
+ const { getItemAtom } = useCapability(NavTreeCapabilities.State);
1062
+ const pathKey = useMemo5(() => path.join("~"), [
1063
+ path
1064
+ ]);
1065
+ const atom = useMemo5(() => getItemAtom(path), [
1066
+ getItemAtom,
1067
+ pathKey
1068
+ ]);
1069
+ return useAtomValue(atom);
1070
+ };
1071
+ var useIsOpen = (path, _item) => {
1072
+ return useNavTreeItemState(path).open;
1073
+ };
1074
+ var useIsCurrent = (path, _item) => {
1075
+ return useNavTreeItemState(path).current;
1076
+ };
1077
+ var useIsAlternateTree = (path, _item) => {
1078
+ return useNavTreeItemState(path).alternateTree ?? false;
1079
+ };
1080
+
1081
+ // src/components/NavTreeContainer.tsx
1082
+ var NODE_TYPE = "dxos/app-graph/node";
1083
+ var renderItemEnd = ({ node, open }) => /* @__PURE__ */ React10.createElement(Surface.Surface, {
1084
+ role: "navtree-item-end",
1085
+ data: {
1086
+ id: node.id,
1087
+ subject: node.data,
1088
+ open
1089
+ },
1090
+ limit: 1
1091
+ });
1092
+ var getChildrenFilter = (node) => !Node5.isActionLike(node) && node.type !== PLANK_COMPANION_TYPE && node.properties.disposition !== "hidden";
1093
+ var filterItems = (node, disposition) => {
1094
+ if (!disposition && (node.properties.disposition === "hidden" || node.properties.disposition === "alternate-tree")) {
1095
+ return false;
1096
+ } else if (!disposition) {
1097
+ const action = Node5.isAction(node);
1098
+ return !action || node.properties.disposition === "item";
1099
+ } else {
1100
+ return node.properties.disposition === disposition;
1101
+ }
1102
+ };
1103
+ var getItems = (graph, node, disposition) => {
1104
+ return Graph3.getConnections(graph, node?.id ?? Node5.RootId, "outbound").filter((node2) => filterItems(node2, disposition));
1105
+ };
1106
+ var useItems = (node, options) => {
1107
+ const { graph } = useAppGraph2();
1108
+ const connections = useConnections(graph, node?.id ?? Node5.RootId);
1109
+ const filtered = connections.filter((node2) => filterItems(node2, options?.disposition));
1110
+ return options?.sort ? filtered.toSorted((a, b) => byPosition(a.properties, b.properties)) : filtered;
1111
+ };
1112
+ var useActions2 = (node) => {
1113
+ const { graph } = useAppGraph2();
1114
+ const actions = useGraphActions(graph, node.id);
1115
+ return useMemo6(() => actions.reduce((acc, arg) => {
1116
+ if (arg.properties.disposition === "item") {
1117
+ return acc;
1118
+ }
1119
+ acc.actions.push(arg);
1120
+ if (!Node5.isAction(arg)) {
1121
+ const actionGroup = Graph3.getActions(graph, arg.id);
1122
+ acc.groupedActions[arg.id] = actionGroup;
1123
+ }
1124
+ return acc;
1125
+ }, {
1126
+ actions: [],
1127
+ groupedActions: {}
1128
+ }), [
1129
+ actions
1130
+ ]);
1131
+ };
1132
+ var NavTreeContainer$ = /* @__PURE__ */ forwardRef4(({ tab, popoverAnchorId, topbar }, forwardedRef) => {
1133
+ const [isLg] = useMediaQuery2("lg");
1134
+ const { invokeSync, invokePromise } = useOperationInvoker3();
1135
+ const runAction = useActionRunner5();
1136
+ const { graph } = useAppGraph2();
1137
+ const { getItem, setItem } = useNavTreeState();
1138
+ const layout = useLayout();
1139
+ const { navigationSidebarState } = useSidebars(meta.id);
1140
+ const getProps = useCallback3((node, path) => {
1141
+ const children = getChildren(graph, node, path).filter(getChildrenFilter);
1142
+ const parentOf = children.length > 0 ? children.map(({ id }) => id) : node.properties.role === "branch" ? [] : void 0;
1143
+ return {
1144
+ id: node.id,
1145
+ parentOf,
1146
+ disabled: node.properties.disabled,
1147
+ label: node.properties.label ?? node.id,
1148
+ className: mx2(node.properties.className, node.properties.modified && "italic"),
1149
+ headingClassName: node.properties.headingClassName,
1150
+ icon: node.properties.icon,
1151
+ iconHue: node.properties.iconHue,
1152
+ testId: node.properties.testId
1153
+ };
1154
+ }, [
1155
+ graph
1156
+ ]);
1157
+ const loadDescendents = useCallback3((node) => {
1158
+ Graph3.expand(graph, node.id, "outbound");
1159
+ Graph3.getConnections(graph, node.id, "outbound").forEach((child) => {
1160
+ Graph3.expand(graph, child.id, "outbound");
1161
+ });
1162
+ }, [
1163
+ graph
1164
+ ]);
1165
+ const handleOpenChange = useCallback3(({ item: { id }, path, open }) => {
1166
+ setItem(path, "open", open);
1167
+ Graph3.expand(graph, id, "outbound");
1168
+ }, [
1169
+ graph
1170
+ ]);
1171
+ const handleTabChange = useCallback3((node) => {
1172
+ invokeSync(LayoutOperation3.UpdateSidebar, {
1173
+ state: node.id === tab ? navigationSidebarState === "expanded" ? isLg ? "collapsed" : "closed" : "expanded" : "expanded"
1174
+ });
1175
+ invokeSync(LayoutOperation3.SwitchWorkspace, {
1176
+ subject: node.id
1177
+ });
1178
+ if (layout.active.length === 0) {
1179
+ const [item] = getItems(graph, node).filter((node2) => !Node5.isActionLike(node2));
1180
+ if (item && item.data) {
1181
+ invokeSync(LayoutOperation3.Open, {
1182
+ subject: [
1183
+ item.id
1184
+ ]
1185
+ });
1186
+ }
1187
+ }
1188
+ }, [
1189
+ invokeSync,
1190
+ layout.active,
1191
+ tab,
1192
+ navigationSidebarState,
1193
+ isLg
1194
+ ]);
1195
+ const blockInstruction = useCallback3(({ instruction, source, target }) => {
1196
+ return target.item.properties.blockInstruction?.(source, instruction) ?? false;
1197
+ }, []);
1198
+ const canDrop = useCallback3(({ source, target }) => {
1199
+ return target.item.properties.canDrop?.(source) ?? false;
1200
+ }, []);
1201
+ const canSelect = useCallback3(({ item }) => {
1202
+ return item.properties.selectable ?? true;
1203
+ }, []);
1204
+ const handleSelect = useCallback3(({ item: node, path, option }) => {
1205
+ if (!node.data) {
1206
+ return;
1207
+ }
1208
+ if (Node5.isAction(node)) {
1209
+ const [parent] = Graph3.getConnections(graph, node.id, "inbound");
1210
+ if (parent) {
1211
+ void runAction(node, {
1212
+ parent,
1213
+ caller: NAV_TREE_ITEM
1214
+ });
1215
+ }
1216
+ return;
1217
+ }
1218
+ const current = getItem(path).current;
1219
+ if (!current) {
1220
+ invokeSync(LayoutOperation3.Open, {
1221
+ subject: [
1222
+ node.id
1223
+ ],
1224
+ key: node.properties.key
1225
+ });
1226
+ } else if (option) {
1227
+ invokeSync(LayoutOperation3.Close, {
1228
+ subject: [
1229
+ node.id
1230
+ ]
1231
+ });
1232
+ } else {
1233
+ void invokePromise(LayoutOperation3.ScrollIntoView, {
1234
+ subject: node.id
1235
+ });
1236
+ }
1237
+ const defaultAction = Graph3.getActions(graph, node.id).find((action) => action.properties?.disposition === "default");
1238
+ if (Node5.isAction(defaultAction)) {
1239
+ void runAction(defaultAction);
1240
+ }
1241
+ if (!isLg) {
1242
+ invokeSync(LayoutOperation3.UpdateSidebar, {
1243
+ state: "closed"
1244
+ });
1245
+ }
1246
+ }, [
1247
+ graph,
1248
+ invokeSync,
1249
+ invokePromise,
1250
+ getItem,
1251
+ isLg,
1252
+ runAction
1253
+ ]);
1254
+ const handleBack = useCallback3(() => invokeSync(LayoutOperation3.RevertWorkspace), [
1255
+ invokeSync
1256
+ ]);
1257
+ useEffect3(() => {
1258
+ return monitorForElements({
1259
+ canMonitor: ({ source }) => isTreeData(source.data),
1260
+ onDrop: ({ location, source }) => {
1261
+ if (!location.current.dropTargets.length) {
1262
+ return;
1263
+ }
1264
+ const target = location.current.dropTargets[0];
1265
+ const instruction = extractInstruction(target.data);
1266
+ if (instruction !== null && instruction.type !== "instruction-blocked") {
1267
+ const sourceNode = source.data.item;
1268
+ const targetNode = target.data.item;
1269
+ const sourcePath = source.data.path;
1270
+ const targetPath = target.data.path;
1271
+ const operation = sourcePath.slice(0, -1).join() === targetPath.slice(0, -1).join() && instruction.type !== "make-child" ? "rearrange" : resolveMigrationOperation(graph, sourceNode, targetPath, targetNode);
1272
+ const sourceParent = getParent(graph, sourceNode, sourcePath);
1273
+ const targetParent = getParent(graph, targetNode, targetPath);
1274
+ const sourceItems = getItems(graph, sourceParent);
1275
+ const targetItems = getItems(graph, targetParent);
1276
+ const sourceIndex = sourceItems.findIndex(({ id }) => id === sourceNode.id);
1277
+ const targetIndex = targetItems.findIndex(({ id }) => id === targetNode.id);
1278
+ const migrationIndex = instruction.type === "make-child" ? void 0 : instruction.type === "reorder-below" ? targetIndex + 1 : targetIndex;
1279
+ switch (operation) {
1280
+ case "rearrange": {
1281
+ const nextItems = sourceItems.map(({ data }) => data);
1282
+ arrayMove2(nextItems, sourceIndex, targetIndex);
1283
+ void sourceNode.properties.onRearrange?.(nextItems);
1284
+ break;
1285
+ }
1286
+ case "copy": {
1287
+ const target2 = instruction.type === "make-child" ? targetNode : targetParent;
1288
+ void target2?.properties.onCopy?.(sourceNode, migrationIndex);
1289
+ break;
1290
+ }
1291
+ case "transfer": {
1292
+ const target2 = instruction.type === "make-child" ? targetNode : targetParent;
1293
+ if (!target2?.properties.onTransferStart || !sourceParent?.properties.onTransferEnd) {
1294
+ break;
1295
+ }
1296
+ void target2?.properties.onTransferStart(sourceNode, migrationIndex);
1297
+ void sourceParent?.properties.onTransferEnd?.(sourceNode, target2);
1298
+ break;
1299
+ }
1300
+ }
1301
+ }
1302
+ }
1303
+ });
1304
+ }, [
1305
+ graph
1306
+ ]);
1307
+ const setAlternateTree = useCallback3((path, open) => {
1308
+ setItem(path, "alternateTree", open);
1309
+ }, [
1310
+ setItem
1311
+ ]);
1312
+ const navTreeContextValue = useMemo6(() => ({
1313
+ blockInstruction,
1314
+ canDrop,
1315
+ canSelect,
1316
+ getProps,
1317
+ useIsAlternateTree,
1318
+ useIsCurrent,
1319
+ useIsOpen,
1320
+ loadDescendents,
1321
+ onBack: handleBack,
1322
+ onOpenChange: handleOpenChange,
1323
+ onSelect: handleSelect,
1324
+ onTabChange: handleTabChange,
1325
+ popoverAnchorId,
1326
+ renderItemEnd,
1327
+ setAlternateTree,
1328
+ tab,
1329
+ topbar,
1330
+ useActions: useActions2,
1331
+ useItems
1332
+ }), [
1333
+ blockInstruction,
1334
+ canDrop,
1335
+ canSelect,
1336
+ getProps,
1337
+ handleBack,
1338
+ handleOpenChange,
1339
+ handleSelect,
1340
+ handleTabChange,
1341
+ loadDescendents,
1342
+ popoverAnchorId,
1343
+ renderItemEnd,
1344
+ setAlternateTree,
1345
+ tab,
1346
+ topbar,
1347
+ useActions2
1348
+ ]);
1349
+ return /* @__PURE__ */ React10.createElement(NavTreeContext.Provider, {
1350
+ value: navTreeContextValue
1351
+ }, /* @__PURE__ */ React10.createElement(NavTree, {
1352
+ id: Node5.RootId,
1353
+ root: Graph3.getRoot(graph),
1354
+ open: layout.sidebarOpen,
1355
+ ref: forwardedRef
1356
+ }));
1357
+ });
1358
+ var NavTreeContainer = /* @__PURE__ */ memo2(NavTreeContainer$);
1359
+
1360
+ export {
1361
+ CommandsDialogContent,
1362
+ CommandsTrigger,
1363
+ getParent,
1364
+ getPersistenceParent,
1365
+ resolveMigrationOperation,
1366
+ sortActions,
1367
+ getChildren,
1368
+ l0ItemType,
1369
+ NODE_TYPE,
1370
+ NavTreeContainer,
1371
+ NavTreeDocumentTitle
1372
+ };
1373
+ //# sourceMappingURL=chunk-63YLDLLE.mjs.map