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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +15 -0
  3. package/dist/lib/browser/chunk-U7MTKDFQ.mjs +13 -0
  4. package/dist/lib/browser/chunk-U7MTKDFQ.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +1055 -0
  6. package/dist/lib/browser/index.mjs.map +7 -0
  7. package/dist/lib/browser/meta.json +1 -0
  8. package/dist/lib/browser/meta.mjs +11 -0
  9. package/dist/lib/browser/meta.mjs.map +7 -0
  10. package/dist/types/src/NavTreePlugin.d.ts +4 -0
  11. package/dist/types/src/NavTreePlugin.d.ts.map +1 -0
  12. package/dist/types/src/components/CommandsDialog.d.ts +5 -0
  13. package/dist/types/src/components/CommandsDialog.d.ts.map +1 -0
  14. package/dist/types/src/components/CommandsTrigger.d.ts +3 -0
  15. package/dist/types/src/components/CommandsTrigger.d.ts.map +1 -0
  16. package/dist/types/src/components/HaloButton.d.ts +12 -0
  17. package/dist/types/src/components/HaloButton.d.ts.map +1 -0
  18. package/dist/types/src/components/HaloButton.stories.d.ts +12 -0
  19. package/dist/types/src/components/HaloButton.stories.d.ts.map +1 -0
  20. package/dist/types/src/components/NavBarStart.d.ts +7 -0
  21. package/dist/types/src/components/NavBarStart.d.ts.map +1 -0
  22. package/dist/types/src/components/NavTreeContainer.d.ts +12 -0
  23. package/dist/types/src/components/NavTreeContainer.d.ts.map +1 -0
  24. package/dist/types/src/components/NavTreeDocumentTitle.d.ts +5 -0
  25. package/dist/types/src/components/NavTreeDocumentTitle.d.ts.map +1 -0
  26. package/dist/types/src/components/NavTreeFooter.d.ts +6 -0
  27. package/dist/types/src/components/NavTreeFooter.d.ts.map +1 -0
  28. package/dist/types/src/components/NotchStart.d.ts +3 -0
  29. package/dist/types/src/components/NotchStart.d.ts.map +1 -0
  30. package/dist/types/src/components/index.d.ts +6 -0
  31. package/dist/types/src/components/index.d.ts.map +1 -0
  32. package/dist/types/src/experimental/Tree.d.ts +56 -0
  33. package/dist/types/src/experimental/Tree.d.ts.map +1 -0
  34. package/dist/types/src/experimental/Tree.stories.d.ts +12 -0
  35. package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -0
  36. package/dist/types/src/index.d.ts +5 -0
  37. package/dist/types/src/index.d.ts.map +1 -0
  38. package/dist/types/src/meta.d.ts +7 -0
  39. package/dist/types/src/meta.d.ts.map +1 -0
  40. package/dist/types/src/stories/Graph.stories.d.ts +17 -0
  41. package/dist/types/src/stories/Graph.stories.d.ts.map +1 -0
  42. package/dist/types/src/translations.d.ts +27 -0
  43. package/dist/types/src/translations.d.ts.map +1 -0
  44. package/dist/types/src/util.d.ts +32 -0
  45. package/dist/types/src/util.d.ts.map +1 -0
  46. package/package.json +77 -0
  47. package/src/NavTreePlugin.tsx +262 -0
  48. package/src/components/CommandsDialog.tsx +114 -0
  49. package/src/components/CommandsTrigger.tsx +34 -0
  50. package/src/components/HaloButton.stories.tsx +19 -0
  51. package/src/components/HaloButton.tsx +41 -0
  52. package/src/components/NavBarStart.tsx +48 -0
  53. package/src/components/NavTreeContainer.tsx +375 -0
  54. package/src/components/NavTreeDocumentTitle.tsx +17 -0
  55. package/src/components/NavTreeFooter.tsx +155 -0
  56. package/src/components/NotchStart.tsx +29 -0
  57. package/src/components/index.ts +9 -0
  58. package/src/experimental/Tree.stories.tsx +229 -0
  59. package/src/experimental/Tree.tsx +282 -0
  60. package/src/index.ts +10 -0
  61. package/src/meta.ts +12 -0
  62. package/src/stories/Graph.stories.tsx +162 -0
  63. package/src/translations.ts +28 -0
  64. package/src/util.ts +231 -0
@@ -0,0 +1,1055 @@
1
+ import {
2
+ KEY_BINDING,
3
+ NAVTREE_PLUGIN,
4
+ meta_default
5
+ } from "./chunk-U7MTKDFQ.mjs";
6
+
7
+ // packages/plugins/plugin-navtree/src/NavTreePlugin.tsx
8
+ import { MagnifyingGlass as MagnifyingGlass2 } from "@phosphor-icons/react";
9
+ import React8 from "react";
10
+ import { resolvePlugin, parseIntentPlugin, LayoutAction as LayoutAction4, parseGraphPlugin, NavigationAction as NavigationAction2 } from "@dxos/app-framework";
11
+ import { createExtension, isAction as isAction4, isGraphNode } from "@dxos/app-graph";
12
+ import { Keyboard as Keyboard2 } from "@dxos/keyboard";
13
+ import { LocalStorageStore } from "@dxos/local-storage";
14
+ import { Path as Path3 } from "@dxos/react-ui-mosaic";
15
+ import { getHostPlatform as getHostPlatform2 } from "@dxos/util";
16
+
17
+ // packages/plugins/plugin-navtree/src/components/CommandsDialog.tsx
18
+ import { DotOutline } from "@phosphor-icons/react";
19
+ import React, { useMemo, useState } from "react";
20
+ import { useIntentDispatcher, LayoutAction } from "@dxos/app-framework";
21
+ import { isActionGroup, isAction } from "@dxos/app-graph";
22
+ import { Keyboard, keySymbols } from "@dxos/keyboard";
23
+ import { useGraph } from "@dxos/plugin-graph";
24
+ import { Button, Dialog, useTranslation, toLocalizedString } from "@dxos/react-ui";
25
+ import { SearchList } from "@dxos/react-ui-searchlist";
26
+ import { descriptionText, getSize, mx } from "@dxos/react-ui-theme";
27
+ import { getHostPlatform } from "@dxos/util";
28
+ var CommandsDialogContent = ({ selected: initial }) => {
29
+ const { t } = useTranslation(NAVTREE_PLUGIN);
30
+ const [selected, setSelected] = useState(initial);
31
+ const dispatch = useIntentDispatcher();
32
+ const { graph } = useGraph();
33
+ const allActions = useMemo(() => {
34
+ const current = Keyboard.singleton.getCurrentContext();
35
+ const actionMap = /* @__PURE__ */ new Set();
36
+ const actions2 = [];
37
+ graph?.traverse({
38
+ visitor: (node, path) => {
39
+ if ((isAction(node) || isActionGroup(node)) && !actionMap.has(node.id) && current.startsWith(path.slice(0, -1).join("/"))) {
40
+ actionMap.add(node.id);
41
+ actions2.push(node);
42
+ }
43
+ }
44
+ });
45
+ actions2.sort((a, b) => {
46
+ return toLocalizedString(a.properties.label, t)?.toLowerCase().localeCompare(toLocalizedString(b.properties.label, t)?.toLowerCase());
47
+ });
48
+ return actions2;
49
+ }, [
50
+ graph
51
+ ]);
52
+ const group = allActions.find(({ id }) => id === selected);
53
+ const actions = isActionGroup(group) ? graph.actions(group) : allActions;
54
+ return /* @__PURE__ */ React.createElement(Dialog.Content, {
55
+ classNames: [
56
+ "md:max-is-[30rem] overflow-hidden mbs-12"
57
+ ]
58
+ }, /* @__PURE__ */ React.createElement(Dialog.Title, null, t("commands dialog title", {
59
+ ns: NAVTREE_PLUGIN
60
+ })), /* @__PURE__ */ React.createElement(SearchList.Root, {
61
+ label: t("command list input placeholder"),
62
+ classNames: "flex flex-col grow overflow-hidden my-2"
63
+ }, /* @__PURE__ */ React.createElement(SearchList.Input, {
64
+ placeholder: t("command list input placeholder"),
65
+ classNames: "px-1 my-2"
66
+ }), /* @__PURE__ */ React.createElement(SearchList.Content, {
67
+ classNames: "max-bs-[24rem] overflow-auto"
68
+ }, actions?.map((action) => {
69
+ const label = toLocalizedString(action.properties.label, t);
70
+ const shortcut = typeof action.properties.keyBinding === "string" ? action.properties.keyBinding : action.properties.keyBinding?.[getHostPlatform()];
71
+ const Icon = action.properties.icon ?? DotOutline;
72
+ return /* @__PURE__ */ React.createElement(SearchList.Item, {
73
+ value: label,
74
+ key: action.id,
75
+ onSelect: () => {
76
+ if (action.properties.disabled) {
77
+ return;
78
+ }
79
+ if (isActionGroup(action)) {
80
+ setSelected(action.id);
81
+ return;
82
+ }
83
+ void dispatch({
84
+ action: LayoutAction.SET_LAYOUT,
85
+ data: {
86
+ element: "dialog",
87
+ state: false
88
+ }
89
+ });
90
+ setTimeout(() => {
91
+ const node = graph.nodes(group ?? action, {
92
+ relation: "inbound"
93
+ })[0];
94
+ void (node && isAction(action) && action.data({
95
+ node,
96
+ caller: KEY_BINDING
97
+ }));
98
+ });
99
+ },
100
+ classNames: "flex items-center gap-2",
101
+ disabled: action.properties.disabled,
102
+ ...action.properties?.testId && {
103
+ "data-testid": action.properties.testId
104
+ }
105
+ }, /* @__PURE__ */ React.createElement(Icon, {
106
+ className: mx(getSize(4), "shrink-0", !action.properties.icon && "invisible")
107
+ }), /* @__PURE__ */ React.createElement("span", {
108
+ className: "grow truncate"
109
+ }, label), shortcut && /* @__PURE__ */ React.createElement("span", {
110
+ className: mx("shrink-0", descriptionText)
111
+ }, keySymbols(shortcut).join("")));
112
+ }))), /* @__PURE__ */ React.createElement(Dialog.Close, {
113
+ asChild: true
114
+ }, /* @__PURE__ */ React.createElement(Button, {
115
+ variant: "primary",
116
+ classNames: "mbs-2"
117
+ }, t("close label", {
118
+ ns: "os"
119
+ }))));
120
+ };
121
+
122
+ // packages/plugins/plugin-navtree/src/components/NavBarStart.tsx
123
+ import { DotsThreeVertical } from "@phosphor-icons/react";
124
+ import React2, { Fragment } from "react";
125
+ import { getGraph } from "@dxos/app-graph";
126
+ import { Popover, toLocalizedString as toLocalizedString2, useTranslation as useTranslation2 } from "@dxos/react-ui";
127
+ import { PlankHeading } from "@dxos/react-ui-deck";
128
+ var TREE_ITEM_MAIN_HEADING = "TreeItemMainHeading";
129
+ var NavBarStart = ({ activeNode, popoverAnchorId }) => {
130
+ const { t } = useTranslation2(NAVTREE_PLUGIN);
131
+ const ActionRoot = popoverAnchorId === `dxos.org/ui/${TREE_ITEM_MAIN_HEADING}/${activeNode.id}` || popoverAnchorId === `dxos.org/ui/${KEY_BINDING}/${activeNode.id}` ? Popover.Anchor : Fragment;
132
+ const Icon = activeNode.properties?.icon ?? DotsThreeVertical;
133
+ const graph = getGraph(activeNode);
134
+ const actions = graph.actions(activeNode);
135
+ const label = toLocalizedString2(activeNode.properties?.label, t);
136
+ const menuTriggerLabel = t("node actions menu invoker label");
137
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ActionRoot, null, /* @__PURE__ */ React2.createElement(PlankHeading.ActionsMenu, {
138
+ Icon,
139
+ attendableId: activeNode.id,
140
+ triggerLabel: menuTriggerLabel,
141
+ actions,
142
+ onAction: (action) => typeof action.data === "function" && action.data({
143
+ node: action,
144
+ caller: TREE_ITEM_MAIN_HEADING
145
+ })
146
+ })), /* @__PURE__ */ React2.createElement(PlankHeading.Label, {
147
+ attendableId: activeNode.id
148
+ }, label));
149
+ };
150
+
151
+ // packages/plugins/plugin-navtree/src/components/NavTreeContainer.tsx
152
+ import React4, { useCallback, useMemo as useMemo2 } from "react";
153
+ import { NavigationAction, LayoutAction as LayoutAction2, Surface, SLUG_PATH_SEPARATOR, SLUG_COLLECTION_INDICATOR, useIntentDispatcher as useIntentDispatcher3 } from "@dxos/app-framework";
154
+ import { getGraph as getGraph2, isAction as isAction3, isActionLike } from "@dxos/app-graph";
155
+ import { ElevationProvider, useMediaQuery, useSidebars as useSidebars2 } from "@dxos/react-ui";
156
+ import { Path as Path2 } from "@dxos/react-ui-mosaic";
157
+ import { NavTree, getLevel } from "@dxos/react-ui-navtree";
158
+ import { arrayMove } from "@dxos/util";
159
+
160
+ // packages/plugins/plugin-navtree/src/components/NavTreeFooter.tsx
161
+ import { ArrowSquareOut, GearSix, Warning } from "@phosphor-icons/react";
162
+ import { formatDistance } from "date-fns/formatDistance";
163
+ import React3 from "react";
164
+ import { SettingsAction, useResolvePlugin, parseNavigationPlugin, useIntentDispatcher as useIntentDispatcher2 } from "@dxos/app-framework";
165
+ import { useConfig } from "@dxos/react-client";
166
+ import { Button as Button2, Tooltip, Popover as Popover2, useSidebars, useTranslation as useTranslation3, Link, Message, Trans, useDefaultValue } from "@dxos/react-ui";
167
+ import { PlankHeading as PlankHeading2 } from "@dxos/react-ui-deck";
168
+ import { getSize as getSize2, mx as mx2 } from "@dxos/react-ui-theme";
169
+ var buttonStyles = "pli-1.5 text-xs font-normal";
170
+ var repo = "https://github.com/dxos/dxos";
171
+ var NavTreeFooter = (props) => {
172
+ const layoutPart = useDefaultValue(props.layoutPart, "sidebar");
173
+ const config = useConfig();
174
+ const { t } = useTranslation3(NAVTREE_PLUGIN);
175
+ const { navigationSidebarOpen } = useSidebars(NAVTREE_PLUGIN);
176
+ const dispatch = useIntentDispatcher2();
177
+ const { version, timestamp, commitHash } = config.values.runtime?.app?.build ?? {};
178
+ const navigationPlugin = useResolvePlugin(parseNavigationPlugin);
179
+ const releaseUrl = config.values.runtime?.app?.env?.DX_ENVIRONMENT === "production" ? `${repo}/releases/tag/v${version}` : `${repo}/commit/${commitHash}`;
180
+ const previewUrl = "https://docs.dxos.org/composer#technology-preview";
181
+ return /* @__PURE__ */ React3.createElement("div", {
182
+ role: "none",
183
+ className: mx2("bs-[--rail-size] pbe-[env(safe-area-inset-bottom)] box-content separator-separator border-bs pli-1 flex justify-end", layoutPart === "complementary" && "md:justify-end flex-row-reverse")
184
+ }, /* @__PURE__ */ React3.createElement(Popover2.Root, null, /* @__PURE__ */ React3.createElement(Popover2.Trigger, {
185
+ asChild: true
186
+ }, /* @__PURE__ */ React3.createElement(Button2, {
187
+ variant: "ghost",
188
+ classNames: buttonStyles,
189
+ ...!navigationSidebarOpen && {
190
+ tabIndex: -1
191
+ }
192
+ }, "v", version)), /* @__PURE__ */ React3.createElement(Popover2.Portal, null, /* @__PURE__ */ React3.createElement(Popover2.Content, {
193
+ side: "top",
194
+ role: "message",
195
+ classNames: "z-[12] bg-warning-500 max-is-[min(calc(100vw-16px),40ch)]"
196
+ }, /* @__PURE__ */ React3.createElement(Message.Root, {
197
+ valence: "warning",
198
+ className: "rounded-be-none p-5"
199
+ }, /* @__PURE__ */ React3.createElement(Message.Title, null, /* @__PURE__ */ React3.createElement(Warning, {
200
+ weight: "duotone",
201
+ className: "inline mie-2 is-6 bs-6"
202
+ }), /* @__PURE__ */ React3.createElement("span", null, t("warning title"))), /* @__PURE__ */ React3.createElement(Message.Body, null, t("technology preview message"), /* @__PURE__ */ React3.createElement("br", null), /* @__PURE__ */ React3.createElement(Link, {
203
+ href: previewUrl,
204
+ target: "_blank",
205
+ rel: "noreferrer",
206
+ variant: "neutral"
207
+ }, t("learn more label"), /* @__PURE__ */ React3.createElement(ArrowSquareOut, {
208
+ className: "inline mis-1",
209
+ weight: "bold"
210
+ })))), /* @__PURE__ */ React3.createElement("div", {
211
+ role: "none",
212
+ className: "plb-4 pli-5 space-b-2 text-base"
213
+ }, timestamp && /* @__PURE__ */ React3.createElement("p", null, t("released message", {
214
+ released: formatDistance(new Date(timestamp), /* @__PURE__ */ new Date(), {
215
+ addSuffix: true
216
+ })
217
+ }), /* @__PURE__ */ React3.createElement("br", null), /* @__PURE__ */ React3.createElement(Link, {
218
+ href: releaseUrl,
219
+ target: "_blank",
220
+ rel: "noreferrer",
221
+ variant: "neutral"
222
+ }, t("see release label"), /* @__PURE__ */ React3.createElement(ArrowSquareOut, {
223
+ className: "inline mis-1",
224
+ weight: "bold"
225
+ }))), /* @__PURE__ */ React3.createElement("p", null, /* @__PURE__ */ React3.createElement(Trans, {
226
+ t,
227
+ i18nKey: "powered by dxos message",
228
+ components: {
229
+ dxos: /* @__PURE__ */ React3.createElement(Link, {
230
+ href: "https://dxos.org",
231
+ target: "_blank",
232
+ rel: "noreferrer",
233
+ variant: "neutral"
234
+ })
235
+ }
236
+ }))), /* @__PURE__ */ React3.createElement(Popover2.Arrow, null)))), /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
237
+ asChild: true
238
+ }, /* @__PURE__ */ React3.createElement(Button2, {
239
+ variant: "ghost",
240
+ classNames: buttonStyles,
241
+ "data-testid": "treeView.openSettings",
242
+ "data-joyride": "welcome/settings",
243
+ ...!navigationSidebarOpen && {
244
+ tabIndex: -1
245
+ },
246
+ onClick: () => dispatch({
247
+ action: SettingsAction.OPEN
248
+ })
249
+ }, /* @__PURE__ */ React3.createElement("span", {
250
+ className: "sr-only"
251
+ }, t("open settings label")), /* @__PURE__ */ React3.createElement(GearSix, {
252
+ className: mx2(getSize2(4), "rotate-90")
253
+ }))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, {
254
+ classNames: "z-[12]"
255
+ }, t("open settings label"), /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null)))), navigationPlugin?.meta.id === "dxos.org/plugin/deck" && /* @__PURE__ */ React3.createElement(PlankHeading2.Controls, {
256
+ variant: "hide-disabled",
257
+ capabilities: {
258
+ incrementStart: false,
259
+ incrementEnd: false
260
+ },
261
+ onClick: (_type) => {
262
+ }
263
+ }));
264
+ };
265
+
266
+ // packages/plugins/plugin-navtree/src/util.ts
267
+ import { ACTION_TYPE, ACTION_GROUP_TYPE, isAction as isAction2 } from "@dxos/app-graph";
268
+ import { Path } from "@dxos/react-ui-mosaic";
269
+ import { nonNullable } from "@dxos/util";
270
+ var getParent = (graph, node, path) => {
271
+ const parentId = path[path.length - 2];
272
+ return graph.nodes(node, {
273
+ relation: "inbound"
274
+ }).find((n) => n.id === parentId);
275
+ };
276
+ var getPersistenceParent = (graph, node, path, persistenceClass) => {
277
+ if (node.properties.acceptPersistenceClass?.has(persistenceClass)) {
278
+ return node;
279
+ } else {
280
+ const parent = getParent(graph, node, path);
281
+ return parent ? getPersistenceParent(graph, parent, path.slice(0, path.length - 1), persistenceClass) : null;
282
+ }
283
+ };
284
+ var resolveMigrationOperation = (graph, activeNode, destinationPath, destinationRelatedNode) => {
285
+ const activeClass = activeNode.properties.persistenceClass;
286
+ if (destinationRelatedNode && activeClass) {
287
+ const persistenceParent = getPersistenceParent(graph, destinationRelatedNode, destinationPath, activeClass);
288
+ if (persistenceParent) {
289
+ const activeKey = activeNode.properties.persistenceKey;
290
+ if (activeKey && persistenceParent?.properties.acceptPersistenceKey) {
291
+ return persistenceParent.properties.acceptPersistenceKey.has(activeKey) && destinationRelatedNode.properties.onTransferStart ? "transfer" : destinationRelatedNode.properties.onCopy ? "copy" : "reject";
292
+ } else {
293
+ return "reject";
294
+ }
295
+ } else {
296
+ return "reject";
297
+ }
298
+ } else {
299
+ return "reject";
300
+ }
301
+ };
302
+ var sortActions = (actions) => actions.sort((a, b) => {
303
+ if (a.properties.disposition === b.properties.disposition) {
304
+ return 0;
305
+ }
306
+ if (a.properties.disposition === "toolbar") {
307
+ return -1;
308
+ }
309
+ return 1;
310
+ });
311
+ var getTreeItemNode = (treeItems, path) => {
312
+ if (!path) {
313
+ return void 0;
314
+ }
315
+ return treeItems.find((treeItem) => {
316
+ return treeItem.path && !treeItem.path.find((id, index) => path[index] !== id);
317
+ });
318
+ };
319
+ var getChildren = (graph, node, filter, path = []) => {
320
+ return graph.nodes(node, {
321
+ relation: "outbound",
322
+ filter
323
+ }).map((n) => {
324
+ const nextPath = [
325
+ ...path,
326
+ node.id
327
+ ];
328
+ return nextPath.includes(n.id) ? void 0 : n;
329
+ }).filter(nonNullable);
330
+ };
331
+ var getActions = (graph, node) => {
332
+ return graph.actions(node).reduce((acc, arg) => {
333
+ acc.actions.push(arg);
334
+ if (!isAction2(arg)) {
335
+ const actionGroup = graph.actions(arg);
336
+ acc.groupedActions[arg.id] = actionGroup;
337
+ }
338
+ return acc;
339
+ }, {
340
+ actions: [],
341
+ groupedActions: {}
342
+ });
343
+ };
344
+ var expandChildrenAndActions = (graph, node) => {
345
+ return Promise.all([
346
+ expandChildren(graph, node),
347
+ expandActions(graph, node)
348
+ ]);
349
+ };
350
+ var expandChildren = (graph, node) => {
351
+ return graph.expand(node, "outbound");
352
+ };
353
+ var expandActions = (graph, node) => {
354
+ return Promise.all([
355
+ graph.expand(node, "outbound", ACTION_TYPE),
356
+ graph.expand(node, "outbound", ACTION_GROUP_TYPE)
357
+ ]);
358
+ };
359
+ function* navTreeItemVisitor(graph, node, openItemIds, path = [], filter) {
360
+ const l0Children = getChildren(graph, node, filter, path);
361
+ const { actions: l0Actions, groupedActions: l0GroupedActions } = getActions(graph, node);
362
+ const stack = [
363
+ {
364
+ id: node.id,
365
+ node,
366
+ path: [],
367
+ parentOf: (l0Children ?? []).map(({ id }) => id),
368
+ actions: l0Actions,
369
+ groupedActions: l0GroupedActions
370
+ }
371
+ ];
372
+ while (stack.length > 0) {
373
+ const nextItem = stack.pop();
374
+ if ((nextItem.path?.length ?? 0) > 0) {
375
+ yield nextItem;
376
+ }
377
+ const { id, node: node2, path: path2 } = nextItem;
378
+ const children = getChildren(graph, node2, filter, path2);
379
+ if (path2?.length === 0 || (id ?? "never") in openItemIds) {
380
+ for (let i = children.length - 1; i >= 0; i--) {
381
+ const child = children[i];
382
+ const childPath = path2 ? [
383
+ ...path2,
384
+ child.id
385
+ ] : [
386
+ child.id
387
+ ];
388
+ const childChildren = getChildren(graph, child, filter, childPath);
389
+ const { actions: childActions, groupedActions: childGroupedActions } = getActions(graph, child);
390
+ stack.push({
391
+ id: Path.create(...childPath),
392
+ node: child,
393
+ path: childPath,
394
+ ...(childChildren?.length ?? 0) > 0 && {
395
+ parentOf: childChildren.map(({ id: id2 }) => Path.create(...childPath, id2))
396
+ },
397
+ actions: childActions,
398
+ groupedActions: childGroupedActions
399
+ });
400
+ }
401
+ }
402
+ }
403
+ }
404
+ var treeItemsFromRootNode = (graph, rootNode, openItemIds, path = [], filter) => {
405
+ return Array.from(navTreeItemVisitor(graph, rootNode, openItemIds, path, filter));
406
+ };
407
+ var expandOpenGraphNodes = (graph, openItemIds) => {
408
+ return Promise.all(Object.keys(openItemIds).map((openItemId) => {
409
+ const node = graph.findNode(Path.last(openItemId));
410
+ return node && expandChildrenAndActions(graph, node);
411
+ }).filter(nonNullable));
412
+ };
413
+
414
+ // packages/plugins/plugin-navtree/src/components/NavTreeContainer.tsx
415
+ var NODE_TYPE = "dxos/app-graph/node";
416
+ var renderPresence = (node) => /* @__PURE__ */ React4.createElement(Surface, {
417
+ role: "presence--glyph",
418
+ data: {
419
+ object: node.data
420
+ }
421
+ });
422
+ var NavTreeContainer = ({ root, activeIds, openItemIds, onOpenItemIdsChange, attended, popoverAnchorId }) => {
423
+ const { closeNavigationSidebar } = useSidebars2(NAVTREE_PLUGIN);
424
+ const [isLg] = useMediaQuery("lg", {
425
+ ssr: false
426
+ });
427
+ const dispatch = useIntentDispatcher3();
428
+ const graph = useMemo2(() => getGraph2(root), [
429
+ root
430
+ ]);
431
+ const items = treeItemsFromRootNode(graph, root, openItemIds);
432
+ const loadDescendents = useCallback((node) => {
433
+ void expandActions(graph, node);
434
+ if (!isActionLike(node)) {
435
+ void expandChildren(graph, node).then(() => (
436
+ // Load one level deeper, which resolves some juddering observed on open/close.
437
+ Promise.all(getChildren(graph, node).flatMap((child) => [
438
+ expandActions(graph, child),
439
+ expandChildren(graph, child)
440
+ ]))
441
+ ));
442
+ }
443
+ }, [
444
+ graph
445
+ ]);
446
+ const handleNavigate = async ({ node, actions }) => {
447
+ if (!node.data) {
448
+ return;
449
+ }
450
+ await dispatch({
451
+ action: NavigationAction.OPEN,
452
+ data: {
453
+ activeParts: node.data?.comments ? {
454
+ main: [
455
+ node.id
456
+ ],
457
+ complementary: [
458
+ `${node.id}${SLUG_PATH_SEPARATOR}comments${SLUG_COLLECTION_INDICATOR}`
459
+ ]
460
+ } : {
461
+ main: [
462
+ node.id
463
+ ]
464
+ }
465
+ }
466
+ });
467
+ await dispatch({
468
+ action: LayoutAction2.SCROLL_INTO_VIEW,
469
+ data: {
470
+ id: node.id
471
+ }
472
+ });
473
+ const defaultAction = actions?.find((action) => action.properties?.disposition === "default");
474
+ if (isAction3(defaultAction)) {
475
+ void defaultAction.data();
476
+ }
477
+ !isLg && closeNavigationSidebar();
478
+ };
479
+ const handleItemOpenChange = ({ id, actions, path }, nextOpen) => {
480
+ if (path) {
481
+ if (nextOpen) {
482
+ onOpenItemIdsChange({
483
+ ...openItemIds,
484
+ [id]: true
485
+ });
486
+ } else {
487
+ const { [id]: _, ...nextOpenItemIds } = openItemIds;
488
+ onOpenItemIdsChange(nextOpenItemIds);
489
+ }
490
+ }
491
+ const defaultAction = actions?.find((action) => action.properties?.disposition === "default");
492
+ if (isAction3(defaultAction)) {
493
+ void defaultAction.data();
494
+ }
495
+ };
496
+ const resolveItemLevel = useCallback((overPosition, activeId, levelOffset) => {
497
+ if (!(typeof overPosition === "number" && activeId)) {
498
+ return 1;
499
+ } else {
500
+ const nextItems = arrayMove(items, items.findIndex(({ id }) => id === activeId), overPosition);
501
+ const previousItem = nextItems[overPosition - 1];
502
+ const nextItem = nextItems[overPosition + 1];
503
+ return Math.min(previousItem ? getLevel(previousItem?.path) + 1 : 1, Math.max(nextItem ? getLevel(nextItem?.path) : 1, getLevel(nextItems[overPosition].path) + levelOffset));
504
+ }
505
+ }, [
506
+ items
507
+ ]);
508
+ const handleMove = useCallback(({ active, over, details }) => {
509
+ const levelOffset = Math.floor((details?.delta?.x ?? 0) / 16);
510
+ const overPosition = over.position ?? 0;
511
+ const nextItems = arrayMove(items, items.findIndex(({ id }) => id === active.item.id), overPosition);
512
+ const previousItem = nextItems[overPosition - 1];
513
+ const nextItem = nextItems[overPosition + 1];
514
+ const activeNode = "node" in active.item ? active.item.node : void 0;
515
+ if (!activeNode || !previousItem || !previousItem.path) {
516
+ return {
517
+ operation: "reject",
518
+ details: {
519
+ levelOffset
520
+ }
521
+ };
522
+ }
523
+ const overLevel = resolveItemLevel(overPosition, active.item.id, levelOffset);
524
+ const previousLevel = getLevel(previousItem.path);
525
+ if (previousLevel === overLevel - 1) {
526
+ if (Path2.hasChild(previousItem.id, active.item.id)) {
527
+ const operation = previousItem.node.properties.onRearrangeChildren ? "rearrange" : "reject";
528
+ return {
529
+ operation,
530
+ details: {
531
+ levelOffset
532
+ }
533
+ };
534
+ } else {
535
+ const operation = resolveMigrationOperation(graph, activeNode, previousItem.path, previousItem.node);
536
+ return {
537
+ operation,
538
+ details: {
539
+ levelOffset
540
+ }
541
+ };
542
+ }
543
+ } else if (previousLevel === overLevel) {
544
+ const parent = getParent(graph, previousItem.node, previousItem.path);
545
+ const parentPath = previousItem.path.slice(0, previousItem.path.length - 1);
546
+ if (Path2.siblings(previousItem.id, active.item.id)) {
547
+ const operation = parent?.properties.onRearrangeChildren ? "rearrange" : "reject";
548
+ return {
549
+ operation,
550
+ details: {
551
+ levelOffset
552
+ }
553
+ };
554
+ } else {
555
+ const operation = resolveMigrationOperation(graph, activeNode, parentPath, parent);
556
+ return {
557
+ operation,
558
+ details: {
559
+ levelOffset
560
+ }
561
+ };
562
+ }
563
+ } else if (nextItem && nextItem.path) {
564
+ const nextLevel = getLevel(nextItem.path);
565
+ if (nextLevel === overLevel) {
566
+ const parent = getParent(graph, nextItem.node, nextItem.path);
567
+ const parentPath = nextItem.path.slice(0, nextItem.path.length - 1);
568
+ if (Path2.siblings(nextItem.id, active.item.id)) {
569
+ const operation = parent?.properties.onRearrangeChildren ? "rearrange" : "reject";
570
+ return {
571
+ operation,
572
+ details: {
573
+ levelOffset
574
+ }
575
+ };
576
+ } else {
577
+ const operation = resolveMigrationOperation(graph, activeNode, parentPath, parent);
578
+ return {
579
+ operation,
580
+ details: {
581
+ levelOffset
582
+ }
583
+ };
584
+ }
585
+ } else {
586
+ return {
587
+ operation: "reject",
588
+ details: {
589
+ levelOffset
590
+ }
591
+ };
592
+ }
593
+ } else {
594
+ return {
595
+ operation: "reject",
596
+ details: {
597
+ levelOffset
598
+ }
599
+ };
600
+ }
601
+ }, [
602
+ root,
603
+ items
604
+ ]);
605
+ const handleDrop = useCallback(({ operation, active, over, details = {} }) => {
606
+ if (Path2.first(over.path) !== root.id) {
607
+ return void 0;
608
+ }
609
+ const { levelOffset = 0 } = details;
610
+ const overPosition = over.position ?? 0;
611
+ const nextItems = arrayMove(items, items.findIndex(({ id }) => id === active.item.id), overPosition);
612
+ const activeNode = "node" in active.item ? active.item.node : void 0;
613
+ const activeParentId = Path2.parent(active.item.id);
614
+ if (!activeNode) {
615
+ return void 0;
616
+ }
617
+ const activeParent = getParent(graph, activeNode, active.item.path ?? []);
618
+ if (operation === "rearrange") {
619
+ void activeParent?.properties.onRearrangeChildren?.(nextItems.filter(({ id }) => Path2.hasChild(activeParentId, id)).map(({ node }) => node.data));
620
+ return null;
621
+ } else {
622
+ const previousItem = nextItems[overPosition - 1];
623
+ const nextItem = nextItems[overPosition + 1];
624
+ const overLevel = resolveItemLevel(overPosition, active.item.id, levelOffset);
625
+ const previousLevel = getLevel(previousItem.path);
626
+ if (operation === "copy") {
627
+ if (previousLevel === overLevel - 1) {
628
+ void previousItem.node.properties.onCopy?.(activeNode, 0);
629
+ return null;
630
+ } else if (previousLevel === overLevel) {
631
+ const parent = getParent(graph, previousItem.node, previousItem.path ?? []);
632
+ void parent?.properties.onCopy?.(activeNode, getChildren(graph, parent).findIndex(({ id }) => id === previousItem.node.id) + 1);
633
+ return null;
634
+ } else if (nextItem && nextItem.path) {
635
+ const parent = getParent(graph, nextItem.node, nextItem.path ?? []);
636
+ void parent?.properties.onCopy?.(activeNode, getChildren(graph, parent).findIndex(({ id }) => id === nextItem.node.id));
637
+ return null;
638
+ }
639
+ } else if (operation === "transfer") {
640
+ const onTransferEnd = activeParent?.properties.onTransferEnd;
641
+ if (!onTransferEnd) {
642
+ return void 0;
643
+ } else if (previousLevel === overLevel - 1) {
644
+ const onTransferStart = previousItem.node.properties.onTransferStart;
645
+ if (onTransferStart) {
646
+ void onTransferEnd(activeNode, previousItem.node);
647
+ void onTransferStart(activeNode, 0);
648
+ return null;
649
+ }
650
+ } else if (previousLevel === overLevel && previousItem.path) {
651
+ const parent = getParent(graph, previousItem.node, previousItem.path);
652
+ if (parent?.properties.onTransferStart) {
653
+ void onTransferEnd(activeNode, previousItem.node);
654
+ void parent.properties.onTransferStart(activeNode, getChildren(graph, parent).findIndex(({ id }) => id === previousItem.node.id) + 1);
655
+ return null;
656
+ }
657
+ } else if (nextItem && nextItem.path) {
658
+ const parent = getParent(graph, nextItem.node, nextItem.path);
659
+ if (parent?.properties.onTransferStart) {
660
+ void onTransferEnd(activeNode, previousItem.node);
661
+ void parent.properties.onTransferStart(activeNode, getChildren(graph, parent).findIndex(({ id }) => id === nextItem.node.id));
662
+ return null;
663
+ }
664
+ }
665
+ }
666
+ }
667
+ return void 0;
668
+ }, [
669
+ root,
670
+ items
671
+ ]);
672
+ const handleDragEnd = useCallback(() => {
673
+ onOpenItemIdsChange({
674
+ ...openItemIds
675
+ });
676
+ }, [
677
+ onOpenItemIdsChange,
678
+ openItemIds
679
+ ]);
680
+ return /* @__PURE__ */ React4.createElement(ElevationProvider, {
681
+ elevation: "chrome"
682
+ }, /* @__PURE__ */ React4.createElement("div", {
683
+ role: "none",
684
+ className: "bs-full overflow-hidden row-span-3 grid grid-cols-1 grid-rows-[min-content_1fr_min-content]"
685
+ }, /* @__PURE__ */ React4.createElement(Surface, {
686
+ role: "search-input",
687
+ limit: 1
688
+ }), /* @__PURE__ */ React4.createElement("div", {
689
+ role: "none",
690
+ className: "!overflow-y-auto"
691
+ }, /* @__PURE__ */ React4.createElement(NavTree, {
692
+ id: root.id,
693
+ items,
694
+ current: activeIds,
695
+ attended,
696
+ type: NODE_TYPE,
697
+ onNavigate: handleNavigate,
698
+ onItemOpenChange: handleItemOpenChange,
699
+ open: openItemIds,
700
+ onMove: handleMove,
701
+ onDrop: handleDrop,
702
+ onDragEnd: handleDragEnd,
703
+ popoverAnchorId,
704
+ renderPresence,
705
+ resolveItemLevel,
706
+ loadDescendents
707
+ })), /* @__PURE__ */ React4.createElement(NavTreeFooter, null)));
708
+ };
709
+
710
+ // packages/plugins/plugin-navtree/src/components/NavTreeDocumentTitle.tsx
711
+ import { useEffect } from "react";
712
+ import { toLocalizedString as toLocalizedString3, useTranslation as useTranslation4 } from "@dxos/react-ui";
713
+ var NavTreeDocumentTitle = ({ node }) => {
714
+ const { t } = useTranslation4(NAVTREE_PLUGIN);
715
+ useEffect(() => {
716
+ document.title = node ? toLocalizedString3(node.properties.label, t) : t("current app name", {
717
+ ns: "appkit"
718
+ });
719
+ }, [
720
+ node?.properties?.label
721
+ ]);
722
+ return null;
723
+ };
724
+
725
+ // packages/plugins/plugin-navtree/src/components/NotchStart.tsx
726
+ import React6 from "react";
727
+ import { useIntentDispatcher as useIntentDispatcher4, useResolvePlugin as useResolvePlugin2 } from "@dxos/app-framework";
728
+ import { ClientAction } from "@dxos/plugin-client/meta";
729
+ import { parseObservabilityPlugin } from "@dxos/plugin-observability";
730
+ import { useIdentity } from "@dxos/react-client/halo";
731
+
732
+ // packages/plugins/plugin-navtree/src/components/HaloButton.tsx
733
+ import React5 from "react";
734
+ import { ConnectionState, useNetworkStatus } from "@dxos/react-client/mesh";
735
+ import { Avatar } from "@dxos/react-ui";
736
+ import { focusRing, mx as mx3 } from "@dxos/react-ui-theme";
737
+ import { hexToFallback } from "@dxos/util";
738
+ var INTERNAL = "https://avatars.githubusercontent.com/u/57182821";
739
+ var HaloButton = (props) => {
740
+ const { onClick, identityKey, internal, size = 8 } = props;
741
+ const fallbackValue = hexToFallback(identityKey ?? "0");
742
+ const { swarm: connectionState } = useNetworkStatus();
743
+ return /* @__PURE__ */ React5.createElement("button", {
744
+ className: mx3(focusRing, "rounded grid place-items-center"),
745
+ onClick
746
+ }, /* @__PURE__ */ React5.createElement(Avatar.Root, {
747
+ size,
748
+ variant: "circle",
749
+ status: connectionState === ConnectionState.OFFLINE ? "error" : internal ? "internal" : "active",
750
+ hue: props.hue || fallbackValue.hue
751
+ }, /* @__PURE__ */ React5.createElement(Avatar.Frame, {
752
+ "data-testid": "treeView.haloButton",
753
+ "data-joyride": "welcome/halo"
754
+ }, internal ? /* @__PURE__ */ React5.createElement(Avatar.Image, {
755
+ href: INTERNAL
756
+ }) : /* @__PURE__ */ React5.createElement(Avatar.Fallback, {
757
+ text: props.emoji || fallbackValue.emoji
758
+ }))));
759
+ };
760
+
761
+ // packages/plugins/plugin-navtree/src/components/NotchStart.tsx
762
+ var NotchStart = () => {
763
+ const identity = useIdentity();
764
+ const observabilityPlugin = useResolvePlugin2(parseObservabilityPlugin);
765
+ const dispatch = useIntentDispatcher4();
766
+ return /* @__PURE__ */ React6.createElement(HaloButton, {
767
+ size: 8,
768
+ identityKey: identity?.identityKey.toHex(),
769
+ hue: identity?.profile?.data?.hue,
770
+ emoji: identity?.profile?.data?.emoji,
771
+ internal: observabilityPlugin?.provides?.observability?.group === "dxos",
772
+ onClick: () => dispatch({
773
+ action: ClientAction.SHARE_IDENTITY
774
+ })
775
+ });
776
+ };
777
+
778
+ // packages/plugins/plugin-navtree/src/components/CommandsTrigger.tsx
779
+ import { MagnifyingGlass } from "@phosphor-icons/react";
780
+ import React7 from "react";
781
+ import { LayoutAction as LayoutAction3, useIntent } from "@dxos/app-framework";
782
+ import { Button as Button3, useTranslation as useTranslation5 } from "@dxos/react-ui";
783
+ import { getSize as getSize3 } from "@dxos/react-ui-theme";
784
+ var CommandsTrigger = () => {
785
+ const { dispatch } = useIntent();
786
+ const { t } = useTranslation5(NAVTREE_PLUGIN);
787
+ return /* @__PURE__ */ React7.createElement(Button3, {
788
+ classNames: "pis-3 pie-2 gap-2 mli-1 mbs-1 min-bs-0 bs-[--rail-action] justify-start",
789
+ onClick: () => dispatch({
790
+ action: LayoutAction3.SET_LAYOUT,
791
+ data: {
792
+ element: "dialog",
793
+ component: `${NAVTREE_PLUGIN}/Commands`,
794
+ dialogBlockAlign: "start"
795
+ }
796
+ })
797
+ }, /* @__PURE__ */ React7.createElement("span", {
798
+ className: "fg-description text-base font-normal grow text-start"
799
+ }, t("command list input placeholder")), /* @__PURE__ */ React7.createElement(MagnifyingGlass, {
800
+ className: getSize3(5)
801
+ }));
802
+ };
803
+
804
+ // packages/plugins/plugin-navtree/src/translations.ts
805
+ import { translations as navtreeTranslations } from "@dxos/react-ui-navtree";
806
+ var translations_default = [
807
+ {
808
+ "en-US": {
809
+ [NAVTREE_PLUGIN]: {
810
+ "open settings label": "Settings",
811
+ "open commands label": "Search commands",
812
+ "commands dialog title": "Commands",
813
+ "command list input placeholder": "Search for commands\u2026",
814
+ "node actions menu invoker label": "More options",
815
+ "warning title": "WARNING",
816
+ "technology preview message": "Composer is still in technology preview.",
817
+ "learn more label": "Learn more",
818
+ "released message": "This version released {{released}}.",
819
+ "see release label": "See release on GitHub",
820
+ "powered by dxos message": "Powered by <dxos>DXOS</dxos>"
821
+ }
822
+ }
823
+ },
824
+ ...navtreeTranslations
825
+ ];
826
+
827
+ // packages/plugins/plugin-navtree/src/NavTreePlugin.tsx
828
+ var NavTreePlugin = () => {
829
+ const state = new LocalStorageStore("dxos.org/settings/navtree", {
830
+ // TODO(thure): Do this dynamically.
831
+ openItemIds: {
832
+ root: true,
833
+ "dxos.org/plugin/space-spaces": true,
834
+ "dxos.org/plugin/files": true
835
+ }
836
+ });
837
+ let graphPlugin;
838
+ let graph;
839
+ const handleOpenItemIdsChange = (nextOpenItemIds) => {
840
+ state.values.openItemIds = nextOpenItemIds;
841
+ if (graph) {
842
+ void expandOpenGraphNodes(graph, nextOpenItemIds);
843
+ }
844
+ };
845
+ return {
846
+ meta: meta_default,
847
+ ready: async (plugins) => {
848
+ graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
849
+ graph = graphPlugin?.provides.graph;
850
+ if (!graph) {
851
+ return;
852
+ }
853
+ state.values.root = graph.root;
854
+ getChildren(graph, state.values.root);
855
+ getActions(graph, state.values.root);
856
+ state.prop({
857
+ key: "openItemIds",
858
+ storageKey: "openItemIds",
859
+ type: LocalStorageStore.json()
860
+ });
861
+ void expandOpenGraphNodes(graph, state.values.openItemIds);
862
+ graph.subscribeTraverse({
863
+ visitor: (node, path) => {
864
+ let shortcut;
865
+ if (typeof node.properties.keyBinding === "object") {
866
+ const availablePlatforms = Object.keys(node.properties.keyBinding);
867
+ const platform = getHostPlatform2();
868
+ shortcut = availablePlatforms.includes(platform) ? node.properties.keyBinding[platform] : platform === "ios" ? node.properties.keyBinding.macos : platform === "linux" || platform === "unknown" ? node.properties.keyBinding.windows : void 0;
869
+ } else {
870
+ shortcut = node.properties.keyBinding;
871
+ }
872
+ if (shortcut && isAction4(node)) {
873
+ Keyboard2.singleton.getContext(path.slice(0, -1).join("/")).bind({
874
+ shortcut,
875
+ handler: () => {
876
+ void node.data({
877
+ node,
878
+ caller: KEY_BINDING
879
+ });
880
+ },
881
+ data: node.properties.label
882
+ });
883
+ }
884
+ }
885
+ });
886
+ Keyboard2.singleton.initialize();
887
+ Keyboard2.singleton.setCurrentContext(graphPlugin?.provides.graph.root.id);
888
+ },
889
+ unload: async () => {
890
+ Keyboard2.singleton.destroy();
891
+ },
892
+ provides: {
893
+ metadata: {
894
+ records: {
895
+ [NODE_TYPE]: {
896
+ parse: (item, type) => {
897
+ switch (type) {
898
+ case "node":
899
+ return item.node;
900
+ case "object":
901
+ return item.node.data;
902
+ case "view-object":
903
+ return {
904
+ id: `${item.id}-view`,
905
+ object: item.node.data
906
+ };
907
+ }
908
+ }
909
+ }
910
+ }
911
+ },
912
+ surface: {
913
+ component: ({ data, role }) => {
914
+ switch (data.component) {
915
+ case `${NAVTREE_PLUGIN}/Commands`: {
916
+ const selected = typeof data.subject === "string" ? data.subject : void 0;
917
+ return /* @__PURE__ */ React8.createElement(CommandsDialogContent, {
918
+ selected
919
+ });
920
+ }
921
+ }
922
+ switch (role) {
923
+ case "navigation":
924
+ if (state.values.root && state.values.openItemIds) {
925
+ return /* @__PURE__ */ React8.createElement(NavTreeContainer, {
926
+ root: state.values.root,
927
+ activeIds: data.activeIds,
928
+ openItemIds: state.values.openItemIds,
929
+ onOpenItemIdsChange: handleOpenItemIdsChange,
930
+ attended: data.attended,
931
+ popoverAnchorId: data.popoverAnchorId
932
+ });
933
+ }
934
+ break;
935
+ case "document-title": {
936
+ return /* @__PURE__ */ React8.createElement(NavTreeDocumentTitle, {
937
+ node: isGraphNode(data.activeNode) ? data.activeNode : void 0
938
+ });
939
+ }
940
+ case "navbar-start": {
941
+ if (state.values.root && data.activeNode) {
942
+ return {
943
+ node: /* @__PURE__ */ React8.createElement(NavBarStart, {
944
+ activeNode: data.activeNode,
945
+ popoverAnchorId: data.popoverAnchorId
946
+ }),
947
+ disposition: "hoist"
948
+ };
949
+ }
950
+ break;
951
+ }
952
+ case "notch-start":
953
+ return /* @__PURE__ */ React8.createElement(NotchStart, null);
954
+ case "search-input":
955
+ return {
956
+ node: /* @__PURE__ */ React8.createElement(CommandsTrigger, null),
957
+ disposition: "fallback"
958
+ };
959
+ }
960
+ return null;
961
+ }
962
+ },
963
+ intent: {
964
+ resolver: (intent) => {
965
+ switch (intent.action) {
966
+ case NavigationAction2.EXPOSE: {
967
+ if (graph && intent.data?.id) {
968
+ const path = graph.getPath({
969
+ target: intent.data.id
970
+ });
971
+ if (Array.isArray(path)) {
972
+ const additionalOpenItems = [
973
+ ...Array(path.length - 1)
974
+ ].reduce((acc, _, index) => {
975
+ const itemId = Path3.create(...path.slice(1, index + 1));
976
+ if (itemId.length > 0) {
977
+ acc[itemId] = true;
978
+ }
979
+ return acc;
980
+ }, {});
981
+ state.values.openItemIds = {
982
+ ...additionalOpenItems,
983
+ ...state.values.openItemIds
984
+ };
985
+ }
986
+ }
987
+ break;
988
+ }
989
+ }
990
+ }
991
+ },
992
+ graph: {
993
+ builder: (plugins) => {
994
+ const intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
995
+ return [
996
+ createExtension({
997
+ id: NAVTREE_PLUGIN,
998
+ filter: (node) => node.id === "root",
999
+ actions: () => [
1000
+ {
1001
+ id: "dxos.org/plugin/navtree/open-commands",
1002
+ data: async () => {
1003
+ await intentPlugin?.provides.intent.dispatch({
1004
+ action: LayoutAction4.SET_LAYOUT,
1005
+ data: {
1006
+ element: "dialog",
1007
+ component: `${NAVTREE_PLUGIN}/Commands`,
1008
+ dialogBlockAlign: "start"
1009
+ }
1010
+ });
1011
+ },
1012
+ properties: {
1013
+ label: [
1014
+ "open commands label",
1015
+ {
1016
+ ns: NAVTREE_PLUGIN
1017
+ }
1018
+ ],
1019
+ icon: (props) => /* @__PURE__ */ React8.createElement(MagnifyingGlass2, props),
1020
+ iconSymbol: "ph--magnifying-glass--regular",
1021
+ keyBinding: {
1022
+ macos: "meta+k",
1023
+ windows: "ctrl+k"
1024
+ }
1025
+ }
1026
+ }
1027
+ ]
1028
+ })
1029
+ ];
1030
+ }
1031
+ },
1032
+ translations: translations_default
1033
+ }
1034
+ };
1035
+ };
1036
+
1037
+ // packages/plugins/plugin-navtree/src/index.ts
1038
+ var src_default = NavTreePlugin;
1039
+ export {
1040
+ NavTreePlugin,
1041
+ src_default as default,
1042
+ expandActions,
1043
+ expandChildren,
1044
+ expandChildrenAndActions,
1045
+ expandOpenGraphNodes,
1046
+ getActions,
1047
+ getChildren,
1048
+ getParent,
1049
+ getPersistenceParent,
1050
+ getTreeItemNode,
1051
+ resolveMigrationOperation,
1052
+ sortActions,
1053
+ treeItemsFromRootNode
1054
+ };
1055
+ //# sourceMappingURL=index.mjs.map