@dxos/plugin-navtree 0.8.4-main.bc674ce → 0.8.4-main.c351d160a8

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