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