@dxos/plugin-navtree 0.13.0 → 0.14.0

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.
@@ -22,6 +22,7 @@ import * as Button from "@dxos/react-ui/Button";
22
22
  import * as DragHandle from "@dxos/react-ui/DragHandle";
23
23
  import * as Hooks from "@dxos/react-ui/Hooks";
24
24
  import * as Icon from "@dxos/react-ui/Icon";
25
+ import * as Layout from "@dxos/react-ui/Layout";
25
26
  import * as Main from "@dxos/react-ui/Main";
26
27
  import * as ScrollArea from "@dxos/react-ui/ScrollArea";
27
28
  import * as Theme from "@dxos/react-ui/Theme";
@@ -44,8 +45,9 @@ var useNavTreeContext = () => useContext(NavTreeContext) ?? raise(/* @__PURE__ *
44
45
  var UserAccountAvatar = ({ size, userId, hue, emoji, status, badge }) => {
45
46
  const fallbackValue = userId ? hexToFallback(userId) : void 0;
46
47
  const resolved = fallbackValue !== void 0;
47
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(L0ItemActiveTabIndicator, { classNames: "inset-y-6" }), /* @__PURE__ */ jsx("div", {
48
- className: "grid place-items-center dx-focus-ring-group-indicator rounded-full",
48
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(L0ItemActiveTabIndicator, { classNames: "inset-y-6" }), /* @__PURE__ */ jsx(Layout.Grid, {
49
+ center: true,
50
+ classNames: "dx-focus-ring-group-indicator rounded-full",
49
51
  "data-joyride": "welcome/account",
50
52
  children: /* @__PURE__ */ jsxs("span", {
51
53
  className: "relative inline-grid",
@@ -222,14 +224,15 @@ var L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }) =>
222
224
  path,
223
225
  onMouseEnter: handleMouseEnter,
224
226
  children: [
225
- /* @__PURE__ */ jsx("div", {
227
+ /* @__PURE__ */ jsx(Layout.Flex, {
226
228
  "data-frame": true,
227
229
  ...pending && {
228
230
  "data-pending": true,
229
231
  "aria-busy": true
230
232
  },
231
233
  ...hue && { style: { background: `var(--color-${hue}-surface)` } },
232
- className: mx("flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm", pinned ? "p-2 group-hover/l0item:bg-current-surface" : "w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-current-surface"),
234
+ center: true,
235
+ classNames: ["dx-focus-ring-group-indicator transition-colors rounded-sm", pinned ? "p-2 group-hover/l0item:bg-current-surface" : "w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-current-surface"],
233
236
  children: /* @__PURE__ */ jsx(ItemAvatar, { item })
234
237
  }),
235
238
  /* @__PURE__ */ jsx(L0ItemActiveTabIndicator, {}),
@@ -288,7 +291,7 @@ var L0Menu = ({ menuActions, topLevelItems, pinnedItems, userAccountItem, parent
288
291
  ...landmark,
289
292
  "data-tauri-drag-region": "deep",
290
293
  classNames: [
291
- "group/l0 absolute z-[1] inset-y-0 start-0 rounded-is",
294
+ "group/l0 absolute z-[1] inset-y-0 start-0 rounded-s",
292
295
  "grid grid-cols-[var(--dx-l0-size)] grid-rows-[var(--dx-rail-size)_1fr_min-content_var(--dx-l0-size)] dx-contain-layout",
293
296
  "w-(--dx-l0-size) dx-l0-surface dx-app-drag pb-[env(safe-area-inset-bottom)]",
294
297
  "[body[data-platform=\"macos\"]_&]:pt-[30px]",
@@ -325,8 +328,9 @@ var L0Menu = ({ menuActions, topLevelItems, pinnedItems, userAccountItem, parent
325
328
  }, item.id))
326
329
  })
327
330
  }),
328
- /* @__PURE__ */ jsx("div", {
329
- className: "grid grid-cols-1 auto-rows-(--dx-rail-action) pt-2",
331
+ /* @__PURE__ */ jsx(Layout.Grid, {
332
+ cols: 1,
333
+ classNames: "auto-rows-(--dx-rail-action) pt-2",
330
334
  children: pinnedItems.map((item) => /* @__PURE__ */ jsx(L0Item, {
331
335
  item,
332
336
  parent,
@@ -334,8 +338,8 @@ var L0Menu = ({ menuActions, topLevelItems, pinnedItems, userAccountItem, parent
334
338
  pinned: true
335
339
  }, item.id))
336
340
  }),
337
- /* @__PURE__ */ jsx("div", {
338
- className: "grid dx-app-no-drag",
341
+ /* @__PURE__ */ jsx(Layout.Grid, {
342
+ classNames: "dx-app-no-drag",
339
343
  children: userAccountItem ? /* @__PURE__ */ jsx(L0ItemRoot, {
340
344
  item: userAccountItem,
341
345
  parent,
@@ -348,8 +352,9 @@ var L0Menu = ({ menuActions, topLevelItems, pinnedItems, userAccountItem, parent
348
352
  badge: userAccountItem.properties.badge,
349
353
  size: "lg"
350
354
  })
351
- }, userAccountItem.id) : /* @__PURE__ */ jsx("div", {
352
- className: "flex w-full justify-center items-center",
355
+ }, userAccountItem.id) : /* @__PURE__ */ jsx(Layout.Flex, {
356
+ center: true,
357
+ classNames: "w-full",
353
358
  children: /* @__PURE__ */ jsx(UserAccountAvatar, { size: "lg" })
354
359
  })
355
360
  })
@@ -478,10 +483,11 @@ var L1PanelInner = ({ open, path, id, item, unavailable, isCurrent, onBack }) =>
478
483
  ...!item && { "aria-labelledby": void 0 },
479
484
  ...isCurrent && { "data-testid": pending ? "navtree.workspace.pending" : item ? "navtree.workspace.visible" : "navtree.workspace.unavailable" },
480
485
  ...!open && { inert: true },
481
- children: shouldRenderContent && (pending ? /* @__PURE__ */ jsx("div", {
486
+ children: shouldRenderContent && (pending ? /* @__PURE__ */ jsx(Layout.Flex, {
482
487
  role: "status",
483
488
  "aria-label": t("pending-workspace.label"),
484
- className: "row-start-2 self-start flex justify-center p-4 animate-fade-in",
489
+ justify: "center",
490
+ classNames: "row-start-2 self-start p-4 animate-fade-in",
485
491
  style: {
486
492
  animationDelay: RENDER_DELAY,
487
493
  animationFillMode: "backwards"
@@ -1 +1 @@
1
- {"version":3,"file":"components.mjs","names":[],"sources":["../../src/components/NavTreeContext/NavTreeContext.ts","../../src/components/UserAccountAvatar/UserAccountAvatar.tsx","../../src/components/Sidebar/L0PendingAvatar.tsx","../../src/components/Sidebar/L0Menu.tsx","../../src/components/NavTreeItem/NavTreeItemAction.tsx","../../src/components/NavTreeItem/NavTreeItemColumns.tsx","../../src/components/Sidebar/L1Panel.tsx","../../src/components/Sidebar/L1Tabs.tsx","../../src/components/NavTree/NavTree.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { createContext, useContext } from 'react';\n\nimport { raise } from '@dxos/debug';\n\nimport { type NavTreeContextValue } from '../types.ts';\n\nexport const NavTreeContext = createContext<NavTreeContextValue | null>(null);\n\nexport const useNavTreeContext = () => useContext(NavTreeContext) ?? raise(new Error('Missing NavTreeContext'));\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { type ComponentProps } from 'react';\n\nimport * as Avatar from '@dxos/react-ui/Avatar';\nimport { hexToFallback } from '@dxos/util';\n\nimport { L0ItemActiveTabIndicator } from '../Sidebar/index.ts';\n\nexport type UserAccountAvatarProps = {\n size?: ComponentProps<typeof Avatar.Root>['size'];\n userId?: string;\n hue?: string;\n emoji?: string;\n status?: Avatar.Status;\n /** Shows a dot on the avatar, e.g. while invitations are pending. */\n badge?: boolean;\n};\n\nexport const UserAccountAvatar = ({ size, userId, hue, emoji, status, badge }: UserAccountAvatarProps) => {\n const fallbackValue = userId ? hexToFallback(userId) : undefined;\n const resolved = fallbackValue !== undefined;\n\n return (\n <>\n <L0ItemActiveTabIndicator classNames='inset-y-6' />\n <div\n className='grid place-items-center dx-focus-ring-group-indicator rounded-full'\n data-joyride='welcome/account'\n >\n {/* Sized by the avatar so the badge sits on its corner, not the cell's. */}\n <span className='relative inline-grid'>\n <Avatar.Root\n variant='circle'\n size={size ?? 'xl'}\n {...(resolved && { status: status ?? 'active' })}\n hue={Avatar.toAvatarHue(hue || fallbackValue?.hue)}\n fallback={emoji || fallbackValue?.emoji || ''}\n data-testid={resolved ? 'treeView.userAccount' : 'treeView.userAccount.pending'}\n />\n {badge && (\n <span\n className='absolute top-0 right-0 size-2.5 rounded-full bg-error-text'\n data-testid='treeView.userAccount.badge'\n />\n )}\n </span>\n </div>\n </>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Status from '@dxos/react-ui/Status';\n\nconst PENDING_ANIMATION_DELAY = '2s';\n\nconst PENDING_ANIMATION_DURATION = '4s';\n\nexport const L0PendingAvatar = () => (\n <Status.Skeleton\n classNames='w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) rounded-sm'\n style={{ animationDelay: PENDING_ANIMATION_DELAY, animationDuration: PENDING_ANIMATION_DURATION }}\n />\n);\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport {\n type Edge,\n attachClosestEdge,\n extractClosestEdge,\n} from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';\nimport { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';\nimport { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';\nimport { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';\nimport { scrollJustEnoughIntoView } from '@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view';\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport React, {\n type MouseEvent,\n type PropsWithChildren,\n forwardRef,\n memo,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport type * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\nimport { DxAvatar } from '@dxos/lit-ui/react';\nimport * as GraphHooks from '@dxos/plugin-graph/Hooks';\nimport { ActionMenu, type MenuItem } from '@dxos/react-ui-menu';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as DragHandle from '@dxos/react-ui/DragHandle';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Main from '@dxos/react-ui/Main';\nimport * as ScrollArea from '@dxos/react-ui/ScrollArea';\nimport * as Tabs from '@dxos/react-ui/Tabs';\nimport * as Theme from '@dxos/react-ui/Theme';\nimport * as Tooltip from '@dxos/react-ui/Tooltip';\nimport type * as Util from '@dxos/react-ui/Util';\nimport { mx } from '@dxos/ui-theme';\nimport { arrayMove } from '@dxos/util';\n\nimport { useNavTreeState } from '#hooks';\nimport { meta } from '#meta';\n\nimport { l0ItemType } from '../../util.ts';\nimport { useNavTreeContext } from '../NavTreeContext/index.ts';\nimport { UserAccountAvatar } from '../UserAccountAvatar/index.ts';\nimport { L0PendingAvatar } from './L0PendingAvatar.tsx';\n\n//\n// L0Item\n//\n\ntype L0ItemData = {\n id: L0ItemProps['item']['id'];\n type: 'l0Item';\n};\n\n// Local rearrange-handler callback shape; drag-and-drop is wired directly via pragmatic-dnd in `L0Item`,\n// so only the callback signature is needed here.\ntype StackItemRearrangeHandler<Data extends { id: string } = { id: string }> = (\n source: Data,\n target: Data,\n closestEdge: Edge | null,\n) => void;\n\ntype L0ItemRootProps = {\n item: AppGraphNode.Node;\n parent?: AppGraphNode.Node;\n path: string[];\n onMouseEnter?: () => void;\n};\n\ntype L0ItemProps = L0ItemRootProps & {\n item: AppGraphNode.Node;\n parent?: AppGraphNode.Node;\n path: string[];\n pinned?: boolean;\n onRearrange?: StackItemRearrangeHandler<L0ItemData>;\n onItemHover?: (params: { item: AppGraphNode.Node }) => void;\n};\n\nconst useL0ItemClick = ({ item, parent, path }: L0ItemProps, type: string) => {\n const { onSelect, onTabChange } = useNavTreeContext();\n const { getItem } = useNavTreeState();\n const [isLg] = Hooks.useMediaQuery('lg');\n const runAction = GraphHooks.useActionRunner();\n\n return useCallback(\n (event: MouseEvent) => {\n switch (type) {\n case 'action': {\n const { properties: { caller } = {} } = item;\n return void runAction(item as AppGraphNode.Action, caller ? { parent, path, caller } : { parent, path });\n }\n case 'tab':\n return item.properties.pending === true ? undefined : onTabChange?.(item);\n case 'link':\n return onSelect?.({\n item,\n path,\n current: !getItem(path).current,\n option: event.altKey,\n shift: event.shiftKey,\n meta: event.metaKey || event.ctrlKey,\n });\n }\n },\n [item, parent, type, getItem, onSelect, onTabChange, isLg, runAction],\n );\n};\n\nconst l0Breakpoints: Record<string, string> = {\n lg: 'hidden lg:grid',\n};\n\nconst L0ItemRoot = memo(\n forwardRef<HTMLButtonElement, PropsWithChildren<L0ItemRootProps>>(\n ({ item, parent, path, onMouseEnter, children }, forwardedRef) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const { model } = useNavTreeContext();\n const itemPath = useMemo(() => [...path, item.id], [item.id, path]);\n const { id, testId } = useAtomValue(model.itemProps(itemPath));\n const localizedString = Theme.toLocalizedString(item.properties.label, t);\n\n const type = l0ItemType(item);\n const handleClick = useL0ItemClick({ item, parent, path: itemPath }, type);\n\n return (\n <Tooltip.Trigger asChild side='right' content={localizedString}>\n <Tabs.Trigger asChild value={item.id}>\n <button\n type='button'\n className={mx(\n 'group/l0item flex w-full justify-center items-center relative',\n 'dx-app-no-drag dx-focus-ring-group data[type!=\"collection\"]:cursor-pointer aria-disabled:cursor-default',\n l0Breakpoints[item.properties.l0Breakpoint],\n )}\n tabIndex={type === 'tab' ? 0 : undefined}\n data-type={type}\n data-testid={testId}\n data-object-id={id}\n {...(item.properties.pending === true && { 'aria-disabled': true })}\n onClick={handleClick}\n onMouseEnter={onMouseEnter}\n ref={forwardedRef}\n >\n {children}\n </button>\n </Tabs.Trigger>\n </Tooltip.Trigger>\n );\n },\n ),\n);\n\nexport const L0ItemActiveTabIndicator = ({ classNames }: Util.ThemedClassName<{}>) => (\n <div\n className={mx(\n 'hidden group-aria-selected/l0item:block absolute start-0 h-6 w-1.5 bg-accent-bg rounded-sm',\n classNames,\n )}\n />\n);\n\n// TODO(burdon): Factor out pinned (non-draggable) items.\nconst L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L0ItemProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const itemElement = useRef<HTMLButtonElement | null>(null);\n const [closestEdge, setEdge] = useState<Edge | null>(null);\n const localizedString = Theme.toLocalizedString(item.properties.label, t);\n const hue = item.properties.hue ?? null;\n const pending = item.properties.pending === true;\n\n useLayoutEffect(() => {\n if (!itemElement.current || !onRearrange || pending) {\n return;\n }\n\n return combine(\n draggable({\n element: itemElement.current,\n getInitialData: () => ({ id: item.id, type: 'l0Item' }) satisfies L0ItemData,\n onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {\n document.body.setAttribute('data-drag-preview', 'true');\n const element = source.element.querySelector('[data-frame]') as HTMLElement;\n scrollJustEnoughIntoView({ element });\n const { x, y } = preserveOffsetOnSource({ element, input: location.current.input })({\n container: (element.offsetParent ?? document.body) as HTMLElement,\n });\n nativeSetDragImage?.(element, x, y);\n },\n onDragStart: () => {\n document.body.removeAttribute('data-drag-preview');\n itemElement.current!.closest('[data-drag-autoscroll]')?.setAttribute('data-drag-autoscroll', 'active');\n },\n onDrop: () => {\n itemElement.current!.closest('[data-drag-autoscroll]')?.setAttribute('data-drag-autoscroll', 'idle');\n },\n }),\n dropTargetForElements({\n element: itemElement.current,\n getData: ({ input, element }) => {\n return attachClosestEdge(\n { id: item.id, type: 'l0Item' },\n { input, element, allowedEdges: ['top', 'bottom'] },\n );\n },\n onDragEnter: ({ self, source }) => {\n if (source.data.type === self.data.type) {\n setEdge(extractClosestEdge(self.data));\n }\n },\n onDrag: ({ self, source }) => {\n if (source.data.type === self.data.type) {\n setEdge(extractClosestEdge(self.data));\n }\n },\n onDragLeave: () => setEdge(null),\n onDrop: ({ self, source }) => {\n setEdge(null);\n if (source.data.type === self.data.type) {\n onRearrange(source.data as L0ItemData, self.data as L0ItemData, extractClosestEdge(self.data));\n }\n },\n }),\n );\n }, [item, onRearrange, pending]);\n\n const handleMouseEnter = useCallback(() => onItemHover?.({ item }), [item, onItemHover]);\n\n return (\n <L0ItemRoot ref={itemElement} item={item} parent={parent} path={path} onMouseEnter={handleMouseEnter}>\n <div\n data-frame={true}\n {...(pending && { 'data-pending': true, 'aria-busy': true })}\n {...(hue && { style: { background: `var(--color-${hue}-surface)` } })}\n className={mx(\n 'flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm',\n pinned\n ? 'p-2 group-hover/l0item:bg-current-surface'\n : 'w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-current-surface',\n )}\n >\n <ItemAvatar item={item} />\n </div>\n <L0ItemActiveTabIndicator />\n <span id={`${item.id}__label`} className='sr-only'>\n {localizedString}\n </span>\n {(closestEdge === 'top' || closestEdge === 'bottom') && <DragHandle.DropIndicator edge={closestEdge} />}\n </L0ItemRoot>\n );\n});\n\nconst ItemAvatar = ({ item }: Pick<L0ItemProps, 'item'>) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n\n if (item.properties.pending === true) {\n return <L0PendingAvatar />;\n }\n\n // Actions.\n if (item.properties.icon) {\n const hue = item.properties.hue ?? null;\n const hueFgStyle = hue && { style: { color: `var(--color-${hue}-fg)` } };\n return <Icon.Icon icon={item.properties.icon} size='xl' {...hueFgStyle} />;\n }\n\n const type = l0ItemType(item);\n if (type === 'tab' && item.properties.disposition !== 'pin-end') {\n const hue = item.properties.hue ?? null;\n const localizedString = Theme.toLocalizedString(item.properties.label, t);\n return <DxAvatar hue={hue} hueVariant='surface' variant='square' size={12} fallback={localizedString} />;\n }\n\n return null;\n};\n\n//\n// L0Menu\n//\n\nexport type L0MenuProps = {\n menuActions: MenuItem[];\n topLevelItems: AppGraphNode.Node[];\n pinnedItems: AppGraphNode.Node[];\n userAccountItem?: AppGraphNode.Node;\n parent?: AppGraphNode.Node;\n path: string[];\n onItemHover?: (params: { item: AppGraphNode.Node }) => void;\n};\n\nexport const L0Menu = ({\n menuActions,\n topLevelItems,\n pinnedItems,\n userAccountItem,\n parent,\n path,\n onItemHover,\n}: L0MenuProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const runAction = GraphHooks.useActionRunner();\n const handleAction = useCallback(\n (action: AppGraphNode.Action, params: AppGraphNode.InvokeProps) => {\n void runAction(action, params);\n },\n [runAction],\n );\n\n const handleRearrange = useCallback<StackItemRearrangeHandler<L0ItemData>>(\n (source, target, closestEdge) => {\n const sourceItem = topLevelItems.find((i) => i.id === source.id);\n if (!sourceItem?.properties.onRearrange) {\n return;\n }\n\n const sourceIndex = topLevelItems.findIndex((i) => i.id === source.id);\n const targetIndex = topLevelItems.findIndex((i) => i.id === target.id);\n const insertIndex =\n source.id === target.id\n ? sourceIndex\n : targetIndex +\n (sourceIndex < targetIndex ? (closestEdge === 'top' ? -1 : 0) : closestEdge === 'bottom' ? 1 : 0);\n const nextOrder = arrayMove([...topLevelItems], sourceIndex, insertIndex);\n return sourceItem.properties.onRearrange(nextOrder.map((item) => item.id));\n },\n [topLevelItems],\n );\n\n // Check if any items have onRearrange to enable drag-and-drop.\n const hasRearrangeableItems = topLevelItems.some((item) => item.properties.onRearrange);\n // The rail is a focus area of its own, before the panel beside it.\n const landmark = Main.useMainLandmark(0);\n\n return (\n <Tabs.List\n {...landmark}\n data-tauri-drag-region='deep'\n classNames={[\n 'group/l0 absolute z-[1] inset-y-0 start-0 rounded-is',\n 'grid grid-cols-[var(--dx-l0-size)] grid-rows-[var(--dx-rail-size)_1fr_min-content_var(--dx-l0-size)] dx-contain-layout',\n 'w-(--dx-l0-size) dx-l0-surface dx-app-drag pb-[env(safe-area-inset-bottom)]',\n '[body[data-platform=\"macos\"]_&]:pt-[30px]',\n '[body[data-platform=\"ios\"]_&]:pt-[max(env(safe-area-inset-top),0.25rem)]',\n ]}\n >\n {/* TODO(wittjosiah): Use L0Item trigger. */}\n <ActionMenu onAction={handleAction} group={parent} actions={menuActions}>\n {/* The trigger clones this child, so the testid belongs here rather than on `ActionMenu`. */}\n <div className='grid place-items-center' data-testid='spacePlugin.addSpace'>\n <Button.Root\n size='lg'\n variant='ghost'\n iconSize='lg'\n icon='ph--list--regular'\n iconOnly\n label={t('app-menu.label')}\n />\n </div>\n </ActionMenu>\n\n {/* Space list. */}\n <ScrollArea.Root orientation='vertical'>\n <ScrollArea.Viewport classNames='flex flex-col gap-2 py-1'>\n {topLevelItems.map((item) => (\n <L0Item\n key={item.id}\n item={item}\n parent={parent}\n path={path}\n onItemHover={onItemHover}\n {...(hasRearrangeableItems && { onRearrange: handleRearrange })}\n />\n ))}\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n\n {/* Actions. */}\n <div className='grid grid-cols-1 auto-rows-(--dx-rail-action) pt-2'>\n {pinnedItems.map((item) => (\n <L0Item key={item.id} item={item} parent={parent} path={path} pinned />\n ))}\n </div>\n\n <div className='grid dx-app-no-drag'>\n {userAccountItem ? (\n <L0ItemRoot key={userAccountItem.id} item={userAccountItem} parent={parent} path={path}>\n <UserAccountAvatar\n userId={userAccountItem.properties.userId}\n hue={userAccountItem.properties.hue}\n emoji={userAccountItem.properties.emoji}\n status={userAccountItem.properties.status}\n badge={userAccountItem.properties.badge}\n size='lg'\n />\n </L0ItemRoot>\n ) : (\n <div className='flex w-full justify-center items-center'>\n <UserAccountAvatar size='lg' />\n </div>\n )}\n </div>\n </Tabs.List>\n );\n};\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useCallback } from 'react';\n\nimport type * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\nimport * as GraphHooks from '@dxos/plugin-graph/Hooks';\nimport { ActionMenu, type MenuItem } from '@dxos/react-ui-menu';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Theme from '@dxos/react-ui/Theme';\nimport * as Util from '@dxos/react-ui/Util';\n\nimport { meta } from '#meta';\nimport { NavTreeNode } from '#types';\n\nconst fallbackIcon = 'ph--circle-dashed--regular';\n\nexport type NavTreeItemActionMenuProps = NavTreeNode.ActionProperties & {\n parent: AppGraphNode.Node;\n path?: string[];\n caller?: string;\n monolithic?: boolean;\n menuActions?: AppGraphNode.Action[];\n};\n\nexport const NavTreeItemActionDropdownMenu = Util.composable<HTMLButtonElement, NavTreeItemActionMenuProps>(\n ({ parent, path, label, icon, testId, menuActions, caller, ...props }, forwardedRef) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const runAction = GraphHooks.useActionRunner();\n const handleAction = useCallback(\n (action: AppGraphNode.Action, params: AppGraphNode.InvokeProps = {}) => runAction(action, { ...params, path }),\n [runAction, path],\n );\n\n return (\n <ActionMenu caller={caller} onAction={handleAction} group={parent} actions={menuActions as MenuItem[]}>\n <Button.Root\n {...props}\n classNames='shrink-0 px-2 pointer-fine:px-1'\n variant='ghost'\n icon={icon ?? fallbackIcon}\n iconOnly\n label={Theme.toLocalizedString(label, t)}\n data-testid={testId}\n // The tree selects a row on any click inside it, and selecting navigates away from the\n // menu just opened. The trigger has handled the click by the time this runs.\n onClick={(event) => event.stopPropagation()}\n ref={forwardedRef}\n />\n </ActionMenu>\n );\n },\n);\n\nNavTreeItemActionDropdownMenu.displayName = 'NavTreeItemActionDropdownMenu';\n\nexport const NavTreeItemMonolithicAction = (\n props: AppGraphNode.Action & {\n parent: AppGraphNode.Node;\n path?: string[];\n onAction?: (action: AppGraphNode.Action) => void;\n baseLabel: string;\n },\n) => {\n const {\n parent,\n path,\n properties: { disabled, caller, testId, icon, variant = 'ghost', iconOnly = true } = { label: 'never' },\n baseLabel,\n } = props;\n const runAction = GraphHooks.useActionRunner();\n return (\n <Button.Root\n variant={variant}\n classNames={['shrink-0', iconOnly ? 'px-2 pointer-fine:px-1' : 'p-2 pointer-fine:p-2 me-1']}\n icon={icon ?? fallbackIcon}\n iconOnly={iconOnly}\n label={baseLabel}\n disabled={disabled}\n onClick={(event) => {\n event.stopPropagation();\n if (disabled) {\n return;\n }\n\n void runAction(props, caller ? { parent, caller, path } : { parent, path });\n }}\n data-testid={testId}\n />\n );\n};\n\nexport const NavTreeItemAction = ({\n monolithic,\n menuActions,\n menuType,\n parent,\n path,\n ...props\n}: NavTreeItemActionMenuProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n\n const monolithicAction = menuActions?.length === 1 && menuActions[0];\n const baseLabel = Theme.toLocalizedString(monolithicAction ? monolithicAction.properties!.label : props.label, t);\n return monolithic && menuActions?.length === 1 ? (\n <NavTreeItemMonolithicAction baseLabel={baseLabel} parent={parent} path={path} {...menuActions[0]} />\n ) : (\n <NavTreeItemActionDropdownMenu {...props} label={baseLabel} parent={parent} path={path} menuActions={menuActions} />\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { Fragment, memo, useMemo } from 'react';\n\nimport { Tree } from '@dxos/react-ui-list';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Popover from '@dxos/react-ui/Popover';\nimport * as Theme from '@dxos/react-ui/Theme';\n\nimport { getListActions, useActions } from '#hooks';\nimport { meta } from '#meta';\n\nimport { NAV_TREE_ITEM } from '../NavTree/index.ts';\nimport { useNavTreeContext } from '../NavTreeContext/index.ts';\nimport { type NavTreeItemColumnsProps } from '../types.ts';\nimport { NavTreeItemActionDropdownMenu, NavTreeItemMonolithicAction } from './NavTreeItemAction.tsx';\n\nexport const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumnsProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const { renderItemEnd: ItemEnd, popoverAnchorId } = useNavTreeContext();\n\n const level = path.length - 2;\n const flattenedActions = useActions(item);\n const allActions = useMemo(() => getListActions(flattenedActions), [flattenedActions]);\n\n const anchored = popoverAnchorId === `${NAV_TREE_ITEM}:${item.id}`;\n const ActionRoot = anchored ? Popover.Anchor : Fragment;\n\n return (\n // `data-popover-anchor` lets the enclosing row highlight itself while a popover (e.g. rename) is open on it.\n // The empty div holds the actions track when the item has no actions.\n <div className='contents dx-app-no-drag' {...(anchored && { 'data-popover-anchor': '' })}>\n <Tree.ItemActions>\n <ActionRoot>\n {allActions.length === 1 ? (\n <NavTreeItemMonolithicAction\n baseLabel={Theme.toLocalizedString(allActions[0].properties?.label, t)}\n parent={item}\n path={path}\n {...allActions[0]}\n />\n ) : allActions.length > 1 ? (\n <NavTreeItemActionDropdownMenu\n testId={`navtree.treeItem.actionsLevel${level}`}\n label={t('tree-item-actions.label')}\n icon='ph--dots-three-vertical--regular'\n parent={item}\n path={path}\n menuActions={allActions}\n caller={NAV_TREE_ITEM}\n />\n ) : (\n <div />\n )}\n </ActionRoot>\n </Tree.ItemActions>\n {ItemEnd && <ItemEnd node={item} open={open} />}\n </div>\n );\n});\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport React, { memo, useCallback, useMemo } from 'react';\n\nimport * as AppGraph from '@dxos/app-graph/AppGraph';\nimport * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\nimport * as AppNode from '@dxos/app-toolkit/AppNode';\nimport * as ToolkitHooks from '@dxos/app-toolkit/Hooks';\nimport * as GraphHooks from '@dxos/plugin-graph/Hooks';\nimport { Tree, type TreeNode } from '@dxos/react-ui-list';\nimport { ActionMenu, type MenuItem } from '@dxos/react-ui-menu';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Main from '@dxos/react-ui/Main';\nimport * as Status from '@dxos/react-ui/Status';\nimport * as Tabs from '@dxos/react-ui/Tabs';\nimport * as Theme from '@dxos/react-ui/Theme';\nimport { hoverableControlItem, hoverableOpenControlItem } from '@dxos/ui-theme';\n\nimport { getListActions, useActions, useLoadDescendents } from '#hooks';\nimport { meta } from '#meta';\nimport { type NavTreeNode } from '#types';\n\nimport { NAV_TREE_ITEM } from '../NavTree/index.ts';\nimport { useNavTreeContext } from '../NavTreeContext/index.ts';\nimport { NavTreeItemColumns } from '../NavTreeItem/NavTreeItemColumns.tsx';\n\n/**\n * Width held for the item-end slot, whose surface resolves after the tree has painted: a\n * `min-content` track would start collapsed and re-truncate every label when it lands. Sized to\n * what fills it, an `AttentionGlyph` (`w-3`) inset by `mx-1`.\n */\nconst ITEM_END_SIZE = '1.25rem';\n\n/** Delay before a pending or unavailable workspace renders anything. */\nconst RENDER_DELAY = '1s';\n\nexport type L1PanelProps = {\n open?: boolean;\n path: string[];\n /** The tab's workspace id, which may name a workspace that has no graph node. */\n id: string;\n /** Absent when the workspace is not in the graph; the panel then renders the unavailable message. */\n item?: AppGraphNode.Node;\n /** Whether the workspace this tab names is known to be missing, rather than still on its way. */\n unavailable?: boolean;\n isCurrent: boolean;\n onBack?: () => void;\n};\n\n/**\n * Space or settings panel. Without an `item` — a link to a workspace this identity never had or which no\n * longer exists, or persisted deck state pointing at one after a profile switch — the panel body is the\n * unavailable-workspace message, so the sidebar is never blank.\n */\nconst L1PanelInner = ({ open, path, id, item, unavailable, isCurrent, onBack }: L1PanelProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const pending = item?.properties.pending === true;\n const title = item ? Theme.toLocalizedString(item.properties.label, t) : t('workspace-unavailable.heading');\n const isActivated = useIsActivatedWorkspace(id);\n const shouldRenderContent = isCurrent || isActivated;\n // The panel is a focus area of its own, after the rail.\n const landmark = Main.useMainLandmark(0.5);\n\n return (\n <Tabs.Content\n key={id}\n value={id}\n classNames={[\n 'absolute inset-y-0 end-0',\n 'w-[calc(100%-var(--dx-l0-size))] lg:w-(--dx-l1-size) grid-cols-1 grid-rows-[var(--dx-rail-size)_1fr]',\n 'py-[env(safe-area-inset-top)]',\n isCurrent && 'grid',\n ]}\n tabIndex={-1}\n {...(isCurrent && landmark)}\n aria-label={title}\n // An unavailable workspace has no tab in the rail, so the generated `aria-labelledby` would\n // reference a missing element.\n {...(!item && { 'aria-labelledby': undefined })}\n {...(isCurrent && {\n 'data-testid': pending\n ? 'navtree.workspace.pending'\n : item\n ? 'navtree.workspace.visible'\n : 'navtree.workspace.unavailable',\n })}\n {...(!open && { inert: true })}\n >\n {shouldRenderContent &&\n (pending ? (\n <div\n role='status'\n aria-label={t('pending-workspace.label')}\n className='row-start-2 self-start flex justify-center p-4 animate-fade-in'\n style={{ animationDelay: RENDER_DELAY, animationFillMode: 'backwards' }}\n >\n <Icon.Icon icon='ph--spinner-gap--regular' size='xl' spin />\n </div>\n ) : item ? (\n <L1PanelContent open={open} path={path} item={item} onBack={onBack} />\n ) : (\n unavailable && (\n <Status.Empty\n key={id}\n classNames='row-start-2 self-start animate-fade-in'\n style={{ animationDelay: RENDER_DELAY, animationFillMode: 'backwards' }}\n >\n {t('workspace-unavailable.description')}\n </Status.Empty>\n )\n ))}\n </Tabs.Content>\n );\n};\n\n/** Determines whether a workspace tab has been populated with real child content (i.e. expanded at least once). */\nconst useIsActivatedWorkspace = (id: string): boolean => {\n const { graph } = ToolkitHooks.useAppGraph();\n const edges = GraphHooks.useEdges(graph, id);\n\n return useMemo(() => {\n const childIds = edges[AppGraph.relationKey('child')] ?? [];\n return childIds.some((childId) => {\n const child = AppGraph.getNode(graph, childId);\n if (Option.isNone(child)) {\n return false;\n }\n return child.value.properties.disposition === undefined;\n });\n }, [edges, graph]);\n};\n\n/**\n * Mounted panel content for active or previously-visited tabs.\n */\nconst L1PanelContent = ({\n path,\n item,\n onBack,\n}: Pick<L1PanelProps, 'open' | 'path' | 'onBack'> & { item: AppGraphNode.Node }) => {\n const navTreeContext = useNavTreeContext();\n\n return (\n <>\n <L1PanelHeader path={path} item={item} onBack={onBack} />\n <Tree.Root\n model={navTreeContext.model}\n id={item.id}\n rootId={item.id}\n path={path}\n size='md'\n draggable\n columns={COLUMNS}\n canDrop={navTreeContext.canDrop}\n getDropKind={navTreeContext.getDropKind}\n canSelect={navTreeContext.canSelect}\n onOpenChange={navTreeContext.onOpenChange}\n onSelect={navTreeContext.onSelect}\n onItemHover={navTreeContext.onItemHover}\n >\n <Tree.Content>{renderRow}</Tree.Content>\n </Tree.Root>\n </>\n );\n};\n\n/** Disclosure, icon, label, count, the actions menu, then the late item-end surface. */\nconst COLUMNS = `var(--dx-half-block-size) var(--dx-block-size) minmax(0, 1fr) auto min-content minmax(${ITEM_END_SIZE}, min-content)`;\n\nconst renderRow = (node: TreeNode<NavTreeNode.NavTreeItemGraphNode>) => (\n <Tree.Item node={node}>\n <Tree.ItemIndicator />\n <Tree.ItemIcon />\n <Tree.ItemText data-testid='treeItem.heading' />\n <Tree.ItemCount />\n {node.item && <NavTreeItemColumns path={node.path} item={node.item} open={node.open} />}\n </Tree.Item>\n);\n\n/**\n * Header row.\n */\nconst L1PanelHeader = ({ item, path, onBack }: Pick<L1PanelProps, 'path' | 'onBack'> & { item: AppGraphNode.Node }) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const { renderItemEnd: ItemEnd } = useNavTreeContext();\n const title = Theme.toLocalizedString(item.properties.label, t);\n const backCapableWorkspace = AppNode.isPinnedWorkspace(item);\n\n const { menuActions, onAction } = useL1MenuActions({ item, path });\n useLoadDescendents(item);\n\n return (\n <div\n data-tauri-drag-region='deep'\n className='grid w-full items-center px-2 dx-app-drag dx-density-lg'\n // Same late item-end surface and inline inset as the tree rows below, so its actions and status line up with theirs.\n style={{ gridTemplateColumns: `28px 1fr min-content minmax(${ITEM_END_SIZE}, min-content)` }}\n >\n {backCapableWorkspace ? (\n <Button.Root\n classNames={[hoverableControlItem, hoverableOpenControlItem]}\n variant='ghost'\n icon='ph--caret-left--regular'\n iconOnly\n iconSize='md'\n label={t('button-back.button')}\n data-testid='treeView.primaryTreeButton'\n onClick={() => onBack?.()}\n />\n ) : (\n <div />\n )}\n <h2 className='flex-1 truncate min-w-0'>{title}</h2>\n <div className='contents dx-app-no-drag'>\n <MenuActions item={item} menuActions={menuActions} onAction={onAction} />\n {ItemEnd && <ItemEnd node={item} open />}\n </div>\n </div>\n );\n};\n\ntype L1MenuActions = {\n menuActions: AppGraphNode.Action[];\n onAction: (action: AppGraphNode.Action, params?: AppGraphNode.InvokeProps) => void;\n};\n\n/**\n * Header menu actions for an L1 workspace tab. Renders nothing for an empty\n * `menuActions`, a single inline icon button for one action, and a\n * `…`-menu trigger for multiple.\n */\nconst MenuActions = ({\n item,\n menuActions,\n onAction,\n}: {\n item: AppGraphNode.Node;\n} & Pick<L1MenuActions, 'menuActions' | 'onAction'>) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n\n if (menuActions.length === 0) {\n return null;\n }\n\n if (menuActions.length === 1) {\n return (\n <Button.Root\n classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}\n variant='ghost'\n icon={menuActions[0].properties?.icon ?? 'ph--circle-dashed--regular'}\n iconOnly\n iconSize='md'\n label={Theme.toLocalizedString(menuActions[0].properties?.label, t)}\n data-testid={menuActions[0].properties?.testId}\n onClick={() => onAction(menuActions[0] as AppGraphNode.Action)}\n />\n );\n }\n\n return (\n <ActionMenu caller={NAV_TREE_ITEM} onAction={onAction} group={item} actions={menuActions as MenuItem[]}>\n <Button.Root\n classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}\n variant='ghost'\n icon='ph--dots-three-vertical--regular'\n iconOnly\n iconSize='md'\n label={t('tree-item-actions.label')}\n data-testid='navtree.treeItem.actionsLevel0'\n />\n </ActionMenu>\n );\n};\n\n/**\n * Builds the menu actions for the L1 panel header.\n */\nconst useL1MenuActions = ({ item, path }: Pick<L1PanelProps, 'path'> & { item: AppGraphNode.Node }): L1MenuActions => {\n const runAction = GraphHooks.useActionRunner();\n\n const menuActions = getListActions(useActions(item));\n\n const onAction = useCallback(\n (action: AppGraphNode.Action, params?: AppGraphNode.InvokeProps) => {\n void runAction(action, { ...params, path });\n },\n [runAction, path],\n );\n\n return { menuActions, onAction };\n};\n\nexport const L1Panel = memo(L1PanelInner);\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\n\nimport { l0ItemType } from '../../util.ts';\nimport { L1Panel, type L1PanelProps } from './L1Panel.tsx';\n\nexport type L1TabsProps = Pick<L1PanelProps, 'open' | 'onBack' | 'unavailable'> & {\n currentItemId: string;\n path: string[];\n topLevelItems: AppGraphNode.Node[];\n};\n\n/**\n * Each workspace is an L1 tab.\n */\nexport const L1Tabs = ({ topLevelItems, currentItemId, onBack, open, path, unavailable }: L1TabsProps) => {\n // The current tab can name a workspace that is not in the graph, in which case it gets an item-less\n // panel carrying the unavailable message rather than no panel at all (a blank sidebar).\n const hasCurrentPanel = topLevelItems.some((item) => item.id === currentItemId && l0ItemType(item) === 'tab');\n return (\n <>\n {topLevelItems.map((item) => {\n const type = l0ItemType(item);\n if (type === 'tab') {\n return (\n <L1Panel\n key={item.id}\n id={item.id}\n item={item}\n path={path}\n open={open}\n onBack={onBack}\n isCurrent={item.id === currentItemId}\n />\n );\n }\n return null;\n })}\n {!hasCurrentPanel && (\n <L1Panel key={currentItemId} id={currentItemId} path={path} open={open} unavailable={unavailable} isCurrent />\n )}\n </>\n );\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { forwardRef, useMemo } from 'react';\n\nimport * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\nimport * as Hooks from '@dxos/app-toolkit/Hooks';\nimport * as GraphNode from '@dxos/graph/GraphNode';\nimport * as GraphHooks from '@dxos/plugin-graph/Hooks';\nimport { type MenuItem } from '@dxos/react-ui-menu';\nimport * as Tabs from '@dxos/react-ui/Tabs';\nimport * as Position from '@dxos/util/Position';\n\nimport { useLoadDescendents } from '#hooks';\n\nimport { useNavTreeContext } from '../NavTreeContext/index.ts';\nimport { L0Menu, L1Tabs, type L1TabsProps } from '../Sidebar/index.ts';\n\nexport const NAV_TREE_ITEM = 'NavTreeItem';\n\nexport type NavTreeProps = { id: string; root?: AppGraphNode.Node; tab: string } & Pick<\n L1TabsProps,\n 'open' | 'unavailable'\n>;\n\n// TODO(wittjosiah): Refactor to Radix-style.\nexport const NavTree = forwardRef<HTMLDivElement, NavTreeProps>(({ id, root, tab, ...props }, forwardedRef) => {\n const { onBack, onItemHover } = useNavTreeContext();\n const { topLevelActions, l0Items, pinnedItems, userAccountItem, topLevelItems } = useTopLevelNavItems(root);\n\n useLoadDescendents(root);\n const path = useMemo(() => [id], [id]);\n\n return (\n // TODO(thure): `Tabs.Root` forces all items that should be able to receive focus to use `Tabs.Tab(Primitive)` since\n // it uses RovingFocus and doesn't support moving focus to an item that is not a tab. Assess whether this situation\n // should change including whether it should motivate a change in the design/taxonomy, or if this means this should\n // not use `Tabs` at all.\n <Tabs.Root value={tab} orientation='vertical' classNames='relative' ref={forwardedRef}>\n <L0Menu\n menuActions={topLevelActions as MenuItem[]}\n topLevelItems={l0Items}\n pinnedItems={pinnedItems}\n userAccountItem={userAccountItem}\n path={path}\n parent={root}\n onItemHover={onItemHover}\n />\n <L1Tabs topLevelItems={topLevelItems} path={path} currentItemId={tab} onBack={onBack} {...props} />\n </Tabs.Root>\n );\n});\n\n/**\n * Partitions root children into workspaces, pinned items, user-account, and top-level actions.\n */\nconst useTopLevelNavItems = (root?: AppGraphNode.Node) => {\n const { graph } = Hooks.useAppGraph();\n const rootId = root?.id ?? GraphNode.RootId;\n const rootOutboundItems = GraphHooks.useConnections(graph, rootId, 'child');\n const rootActions = GraphHooks.useActions(graph, rootId);\n\n const { topLevelActions, l0Items, pinnedItems, userAccountItem } = useMemo(() => {\n const topLevelWorkspaces: AppGraphNode.Node[] = [];\n const outboundPinnedItems: AppGraphNode.Node[] = [];\n let userAccountItem: AppGraphNode.Node | undefined;\n for (const node of rootOutboundItems) {\n if (AppGraphNode.hasDisposition(node, 'workspace')) {\n topLevelWorkspaces.push(node);\n } else if (AppGraphNode.hasDisposition(node, 'pin-end')) {\n outboundPinnedItems.push(node);\n } else if (AppGraphNode.hasDisposition(node, 'user-account')) {\n userAccountItem ??= node;\n }\n }\n\n const topLevelActions = rootActions\n .filter((action) => AppGraphNode.hasDisposition(action, 'menu'))\n .toSorted((a, b) => Position.compare(a.properties, b.properties));\n const pinnedItems = [\n ...outboundPinnedItems,\n ...rootActions.filter((action) => AppGraphNode.hasDisposition(action, 'pin-end')),\n ].toSorted((a, b) => Position.compare(a.properties, b.properties));\n\n return {\n pinnedItems,\n topLevelActions,\n userAccountItem,\n l0Items: topLevelWorkspaces,\n };\n }, [rootActions, rootOutboundItems]);\n\n const topLevelItems = useMemo(\n () => [...l0Items, ...pinnedItems, ...(userAccountItem ? [userAccountItem] : [])],\n [l0Items, pinnedItems, userAccountItem],\n );\n\n return { topLevelActions, l0Items, pinnedItems, userAccountItem, topLevelItems };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,IAAa,iBAAiB,cAA0C,IAAI;AAE5E,IAAa,0BAA0B,WAAW,cAAc,KAAK,sBAAM,IAAI,MAAM,wBAAwB,CAAC;;;ACS9G,IAAa,qBAAqB,EAAE,MAAM,QAAQ,KAAK,OAAO,QAAQ,YAAoC;CACxG,MAAM,gBAAgB,SAAS,cAAc,MAAM,IAAI,KAAA;CACvD,MAAM,WAAW,kBAAkB,KAAA;CAEnC,OACE,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,0BAAD,EAA0B,YAAW,YAAa,CAAA,GAClD,oBAAC,OAAD;EACE,WAAU;EACV,gBAAa;EAGb,UAAA,qBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CACE,oBAAC,OAAO,MAAR;IACE,SAAQ;IACR,MAAM,QAAQ;IACd,GAAK,YAAY,EAAE,QAAQ,UAAU,SAAS;IAC9C,KAAK,OAAO,YAAY,OAAO,eAAe,GAAG;IACjD,UAAU,SAAS,eAAe,SAAS;IAC3C,eAAa,WAAW,yBAAyB;GAClD,CAAA,GACA,SACC,oBAAC,QAAD;IACE,WAAU;IACV,eAAY;GACb,CAAA,CAEC;;CACH,CAAA,CACL,EAAA,CAAA;AAEN;;;AC5CA,IAAM,0BAA0B;AAEhC,IAAM,6BAA6B;AAEnC,IAAa,wBACX,oBAAC,OAAO,UAAR;CACE,YAAW;CACX,OAAO;EAAE,gBAAgB;EAAyB,mBAAmB;CAA2B;AACjG,CAAA;;;ACoEH,IAAM,kBAAkB,EAAE,MAAM,QAAQ,QAAqB,SAAiB;CAC5E,MAAM,EAAE,UAAU,gBAAgB,kBAAkB;CACpD,MAAM,EAAE,YAAY,gBAAgB;CACpC,MAAM,CAAC,QAAQ,MAAM,cAAc,IAAI;CACvC,MAAM,YAAY,WAAW,gBAAgB;CAE7C,OAAO,aACJ,UAAsB;EACrB,QAAQ,MAAR;GACE,KAAK,UAAU;IACb,MAAM,EAAE,YAAY,EAAE,WAAW,CAAC,MAAM;IACjC,UAAe,MAA6B,SAAS;KAAE;KAAQ;KAAM;IAAO,IAAI;KAAE;KAAQ;IAAK,CAAC;IAAvG;GACF;GACA,KAAK,OACH,OAAO,KAAK,WAAW,YAAY,OAAO,KAAA,IAAY,cAAc,IAAI;GAC1E,KAAK,QACH,OAAO,WAAW;IAChB;IACA;IACA,SAAS,CAAC,QAAQ,IAAI,CAAC,CAAC;IACxB,QAAQ,MAAM;IACd,OAAO,MAAM;IACb,MAAM,MAAM,WAAW,MAAM;GAC/B,CAAC;EACL;CACF,GACA;EAAC;EAAM;EAAQ;EAAM;EAAS;EAAU;EAAa;EAAM;CAAS,CACtE;AACF;AAEA,IAAM,gBAAwC,EAC5C,IAAI,iBACN;AAEA,IAAM,aAAa,KACjB,YACG,EAAE,MAAM,QAAQ,MAAM,cAAc,YAAY,iBAAiB;CAChE,MAAM,EAAE,MAAM,MAAM,eAAe,KAAK,QAAQ,GAAG;CACnD,MAAM,EAAE,UAAU,kBAAkB;CACpC,MAAM,WAAW,cAAc,CAAC,GAAG,MAAM,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC;CAClE,MAAM,EAAE,IAAI,WAAW,aAAa,MAAM,UAAU,QAAQ,CAAC;CAC7D,MAAM,kBAAkB,MAAM,kBAAkB,KAAK,WAAW,OAAO,CAAC;CAExE,MAAM,OAAO,WAAW,IAAI;CAC5B,MAAM,cAAc,eAAe;EAAE;EAAM;EAAQ,MAAM;CAAS,GAAG,IAAI;CAEzE,OACE,oBAAC,QAAQ,SAAT;EAAiB,SAAA;EAAQ,MAAK;EAAQ,SAAS;EAC7C,UAAA,oBAAC,KAAK,SAAN;GAAc,SAAA;GAAQ,OAAO,KAAK;GAChC,UAAA,oBAAC,UAAD;IACE,MAAK;IACL,WAAW,GACT,iEACA,6GACA,cAAc,KAAK,WAAW,aAChC;IACA,UAAU,SAAS,QAAQ,IAAI,KAAA;IAC/B,aAAW;IACX,eAAa;IACb,kBAAgB;IAChB,GAAK,KAAK,WAAW,YAAY,QAAQ,EAAE,iBAAiB,KAAK;IACjE,SAAS;IACK;IACd,KAAK;IAEJ;GACK,CAAA;EACI,CAAA;CACC,CAAA;AAErB,CACF,CACF;AAEA,IAAa,4BAA4B,EAAE,iBACzC,oBAAC,OAAD,EACE,WAAW,GACT,8FACA,UACF,EACD,CAAA;AAIH,IAAM,SAAS,MAAM,EAAE,MAAM,QAAQ,MAAM,QAAQ,aAAa,kBAA+B;CAC7F,MAAM,EAAE,MAAM,MAAM,eAAe,KAAK,QAAQ,GAAG;CACnD,MAAM,cAAc,OAAiC,IAAI;CACzD,MAAM,CAAC,aAAa,WAAW,SAAsB,IAAI;CACzD,MAAM,kBAAkB,MAAM,kBAAkB,KAAK,WAAW,OAAO,CAAC;CACxE,MAAM,MAAM,KAAK,WAAW,OAAO;CACnC,MAAM,UAAU,KAAK,WAAW,YAAY;CAE5C,sBAAsB;EACpB,IAAI,CAAC,YAAY,WAAW,CAAC,eAAe,SAC1C;EAGF,OAAO,QACL,UAAU;GACR,SAAS,YAAY;GACrB,uBAAuB;IAAE,IAAI,KAAK;IAAI,MAAM;GAAS;GACrD,wBAAwB,EAAE,oBAAoB,QAAQ,eAAe;IACnE,SAAS,KAAK,aAAa,qBAAqB,MAAM;IACtD,MAAM,UAAU,OAAO,QAAQ,cAAc,cAAc;IAC3D,yBAAyB,EAAE,QAAQ,CAAC;IACpC,MAAM,EAAE,GAAG,MAAM,uBAAuB;KAAE;KAAS,OAAO,SAAS,QAAQ;IAAM,CAAC,CAAC,CAAC,EAClF,WAAY,QAAQ,gBAAgB,SAAS,KAC/C,CAAC;IACD,qBAAqB,SAAS,GAAG,CAAC;GACpC;GACA,mBAAmB;IACjB,SAAS,KAAK,gBAAgB,mBAAmB;IACjD,YAAY,QAAS,QAAQ,wBAAwB,CAAC,EAAE,aAAa,wBAAwB,QAAQ;GACvG;GACA,cAAc;IACZ,YAAY,QAAS,QAAQ,wBAAwB,CAAC,EAAE,aAAa,wBAAwB,MAAM;GACrG;EACF,CAAC,GACD,sBAAsB;GACpB,SAAS,YAAY;GACrB,UAAU,EAAE,OAAO,cAAc;IAC/B,OAAO,kBACL;KAAE,IAAI,KAAK;KAAI,MAAM;IAAS,GAC9B;KAAE;KAAO;KAAS,cAAc,CAAC,OAAO,QAAQ;IAAE,CACpD;GACF;GACA,cAAc,EAAE,MAAM,aAAa;IACjC,IAAI,OAAO,KAAK,SAAS,KAAK,KAAK,MACjC,QAAQ,mBAAmB,KAAK,IAAI,CAAC;GAEzC;GACA,SAAS,EAAE,MAAM,aAAa;IAC5B,IAAI,OAAO,KAAK,SAAS,KAAK,KAAK,MACjC,QAAQ,mBAAmB,KAAK,IAAI,CAAC;GAEzC;GACA,mBAAmB,QAAQ,IAAI;GAC/B,SAAS,EAAE,MAAM,aAAa;IAC5B,QAAQ,IAAI;IACZ,IAAI,OAAO,KAAK,SAAS,KAAK,KAAK,MACjC,YAAY,OAAO,MAAoB,KAAK,MAAoB,mBAAmB,KAAK,IAAI,CAAC;GAEjG;EACF,CAAC,CACH;CACF,GAAG;EAAC;EAAM;EAAa;CAAO,CAAC;CAE/B,MAAM,mBAAmB,kBAAkB,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,WAAW,CAAC;CAEvF,OACE,qBAAC,YAAD;EAAY,KAAK;EAAmB;EAAc;EAAc;EAAM,cAAc;EAApF,UAAA;GACE,oBAAC,OAAD;IACE,cAAY;IACZ,GAAK,WAAW;KAAE,gBAAgB;KAAM,aAAa;IAAK;IAC1D,GAAK,OAAO,EAAE,OAAO,EAAE,YAAY,eAAe,IAAI,WAAW,EAAE;IACnE,WAAW,GACT,+FACA,SACI,8CACA,oEACN;IAEA,UAAA,oBAAC,YAAD,EAAkB,KAAO,CAAA;GACtB,CAAA;GACL,oBAAC,0BAAD,CAA2B,CAAA;GAC3B,oBAAC,QAAD;IAAM,IAAI,GAAG,KAAK,GAAG;IAAU,WAAU;IACtC,UAAA;GACG,CAAA;IACJ,gBAAgB,SAAS,gBAAgB,aAAa,oBAAC,WAAW,eAAZ,EAA0B,MAAM,YAAc,CAAA;EAC5F;;AAEhB,CAAC;AAED,IAAM,cAAc,EAAE,WAAsC;CAC1D,MAAM,EAAE,MAAM,MAAM,eAAe,KAAK,QAAQ,GAAG;CAEnD,IAAI,KAAK,WAAW,YAAY,MAC9B,OAAO,oBAAC,iBAAD,CAAkB,CAAA;CAI3B,IAAI,KAAK,WAAW,MAAM;EACxB,MAAM,MAAM,KAAK,WAAW,OAAO;EACnC,MAAM,aAAa,OAAO,EAAE,OAAO,EAAE,OAAO,eAAe,IAAI,MAAM,EAAE;EACvE,OAAO,oBAAC,KAAK,MAAN;GAAW,MAAM,KAAK,WAAW;GAAM,MAAK;GAAK,GAAI;EAAa,CAAA;CAC3E;CAGA,IADa,WAAW,IACpB,MAAS,SAAS,KAAK,WAAW,gBAAgB,WAAW;EAC/D,MAAM,MAAM,KAAK,WAAW,OAAO;EACnC,MAAM,kBAAkB,MAAM,kBAAkB,KAAK,WAAW,OAAO,CAAC;EACxE,OAAO,oBAAC,UAAD;GAAe;GAAK,YAAW;GAAU,SAAQ;GAAS,MAAM;GAAI,UAAU;EAAkB,CAAA;CACzG;CAEA,OAAO;AACT;AAgBA,IAAa,UAAU,EACrB,aACA,eACA,aACA,iBACA,QACA,MACA,kBACiB;CACjB,MAAM,EAAE,MAAM,MAAM,eAAe,KAAK,QAAQ,GAAG;CACnD,MAAM,YAAY,WAAW,gBAAgB;CAC7C,MAAM,eAAe,aAClB,QAA6B,WAAqC;EACjE,UAAe,QAAQ,MAAM;CAC/B,GACA,CAAC,SAAS,CACZ;CAEA,MAAM,kBAAkB,aACrB,QAAQ,QAAQ,gBAAgB;EAC/B,MAAM,aAAa,cAAc,MAAM,MAAM,EAAE,OAAO,OAAO,EAAE;EAC/D,IAAI,CAAC,YAAY,WAAW,aAC1B;EAGF,MAAM,cAAc,cAAc,WAAW,MAAM,EAAE,OAAO,OAAO,EAAE;EACrE,MAAM,cAAc,cAAc,WAAW,MAAM,EAAE,OAAO,OAAO,EAAE;EACrE,MAAM,cACJ,OAAO,OAAO,OAAO,KACjB,cACA,eACC,cAAc,cAAe,gBAAgB,QAAQ,KAAK,IAAK,gBAAgB,WAAW,IAAI;EACrG,MAAM,YAAY,UAAU,CAAC,GAAG,aAAa,GAAG,aAAa,WAAW;EACxE,OAAO,WAAW,WAAW,YAAY,UAAU,KAAK,SAAS,KAAK,EAAE,CAAC;CAC3E,GACA,CAAC,aAAa,CAChB;CAGA,MAAM,wBAAwB,cAAc,MAAM,SAAS,KAAK,WAAW,WAAW;CAEtF,MAAM,WAAW,KAAK,gBAAgB,CAAC;CAEvC,OACE,qBAAC,KAAK,MAAN;EACE,GAAI;EACJ,0BAAuB;EACvB,YAAY;GACV;GACA;GACA;GACA;GACA;EACF;EATF,UAAA;GAYE,oBAAC,YAAD;IAAY,UAAU;IAAc,OAAO;IAAQ,SAAS;IAE1D,UAAA,oBAAC,OAAD;KAAK,WAAU;KAA0B,eAAY;KACnD,UAAA,oBAAC,OAAO,MAAR;MACE,MAAK;MACL,SAAQ;MACR,UAAS;MACT,MAAK;MACL,UAAA;MACA,OAAO,EAAE,gBAAgB;KAC1B,CAAA;IACE,CAAA;GACK,CAAA;GAGZ,oBAAC,WAAW,MAAZ;IAAiB,aAAY;IAC3B,UAAA,oBAAC,WAAW,UAAZ;KAAqB,YAAW;KAC7B,UAAA,cAAc,KAAK,SAClB,oBAAC,QAAD;MAEQ;MACE;MACF;MACO;MACb,GAAK,yBAAyB,EAAE,aAAa,gBAAgB;KAC9D,GANM,KAAK,EAMX,CACF;IACkB,CAAA;GACN,CAAA;GAGjB,oBAAC,OAAD;IAAK,WAAU;IACZ,UAAA,YAAY,KAAK,SAChB,oBAAC,QAAD;KAA4B;KAAc;KAAc;KAAM,QAAA;IAAQ,GAAzD,KAAK,EAAoD,CACvE;GACE,CAAA;GAEL,oBAAC,OAAD;IAAK,WAAU;IACZ,UAAA,kBACC,oBAAC,YAAD;KAAqC,MAAM;KAAyB;KAAc;KAChF,UAAA,oBAAC,mBAAD;MACE,QAAQ,gBAAgB,WAAW;MACnC,KAAK,gBAAgB,WAAW;MAChC,OAAO,gBAAgB,WAAW;MAClC,QAAQ,gBAAgB,WAAW;MACnC,OAAO,gBAAgB,WAAW;MAClC,MAAK;KACN,CAAA;IACS,GATK,gBAAgB,EASrB,IAEZ,oBAAC,OAAD;KAAK,WAAU;KACb,UAAA,oBAAC,mBAAD,EAAmB,MAAK,KAAM,CAAA;IAC3B,CAAA;GAEJ,CAAA;EACI;;AAEf;;;ACvYA,IAAM,eAAe;AAUrB,IAAa,gCAAgC,KAAK,YAC/C,EAAE,QAAQ,MAAM,OAAO,MAAM,QAAQ,aAAa,QAAQ,GAAG,SAAS,iBAAiB;CACtF,MAAM,EAAE,MAAM,MAAM,eAAe,KAAK,QAAQ,GAAG;CACnD,MAAM,YAAY,WAAW,gBAAgB;CAC7C,MAAM,eAAe,aAClB,QAA6B,SAAmC,CAAC,MAAM,UAAU,QAAQ;EAAE,GAAG;EAAQ;CAAK,CAAC,GAC7G,CAAC,WAAW,IAAI,CAClB;CAEA,OACE,oBAAC,YAAD;EAAoB;EAAQ,UAAU;EAAc,OAAO;EAAQ,SAAS;EAC1E,UAAA,oBAAC,OAAO,MAAR;GACE,GAAI;GACJ,YAAW;GACX,SAAQ;GACR,MAAM,QAAQ;GACd,UAAA;GACA,OAAO,MAAM,kBAAkB,OAAO,CAAC;GACvC,eAAa;GAGb,UAAU,UAAU,MAAM,gBAAgB;GAC1C,KAAK;EACN,CAAA;CACS,CAAA;AAEhB,CACF;AAEA,8BAA8B,cAAc;AAE5C,IAAa,+BACX,UAMG;CACH,MAAM,EACJ,QACA,MACA,YAAY,EAAE,UAAU,QAAQ,QAAQ,MAAM,UAAU,SAAS,WAAW,SAAS,EAAE,OAAO,QAAQ,GACtG,cACE;CACJ,MAAM,YAAY,WAAW,gBAAgB;CAC7C,OACE,oBAAC,OAAO,MAAR;EACW;EACT,YAAY,CAAC,YAAY,WAAW,2BAA2B,2BAA2B;EAC1F,MAAM,QAAQ;EACJ;EACV,OAAO;EACG;EACV,UAAU,UAAU;GAClB,MAAM,gBAAgB;GACtB,IAAI,UACF;GAGF,UAAe,OAAO,SAAS;IAAE;IAAQ;IAAQ;GAAK,IAAI;IAAE;IAAQ;GAAK,CAAC;EAC5E;EACA,eAAa;CACd,CAAA;AAEL;;;ACzEA,IAAa,qBAAqB,MAAM,EAAE,MAAM,MAAM,WAAoC;CACxF,MAAM,EAAE,MAAM,MAAM,eAAe,KAAK,QAAQ,GAAG;CACnD,MAAM,EAAE,eAAe,SAAS,oBAAoB,kBAAkB;CAEtE,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,mBAAmB,WAAW,IAAI;CACxC,MAAM,aAAa,cAAc,eAAe,gBAAgB,GAAG,CAAC,gBAAgB,CAAC;CAErF,MAAM,WAAW,oBAAoB,GAAG,cAAc,GAAG,KAAK;CAC9D,MAAM,aAAa,WAAW,QAAQ,SAAS;CAE/C,OAGE,qBAAC,OAAD;EAAK,WAAU;EAA0B,GAAK,YAAY,EAAE,uBAAuB,GAAG;EAAtF,UAAA,CACE,oBAAC,KAAK,aAAN,EAAA,UACE,oBAAC,YAAD,EAAA,UACG,WAAW,WAAW,IACrB,oBAAC,6BAAD;GACE,WAAW,MAAM,kBAAkB,WAAW,EAAE,CAAC,YAAY,OAAO,CAAC;GACrE,QAAQ;GACF;GACN,GAAI,WAAW;EAChB,CAAA,IACC,WAAW,SAAS,IACtB,oBAAC,+BAAD;GACE,QAAQ,gCAAgC;GACxC,OAAO,EAAE,yBAAyB;GAClC,MAAK;GACL,QAAQ;GACF;GACN,aAAa;GACb,QAAQ;EACT,CAAA,IAED,oBAAC,OAAD,CAAM,CAAA,EAEE,CAAA,EACI,CAAA,GACjB,WAAW,oBAAC,SAAD;GAAS,MAAM;GAAY;EAAO,CAAA,CAC3C;;AAET,CAAC;;;;;;;;ACzBD,IAAM,gBAAgB;;AAGtB,IAAM,eAAe;;;;;;AAoBrB,IAAM,gBAAgB,EAAE,MAAM,MAAM,IAAI,MAAM,aAAa,WAAW,aAA2B;CAC/F,MAAM,EAAE,MAAM,MAAM,eAAe,KAAK,QAAQ,GAAG;CACnD,MAAM,UAAU,MAAM,WAAW,YAAY;CAC7C,MAAM,QAAQ,OAAO,MAAM,kBAAkB,KAAK,WAAW,OAAO,CAAC,IAAI,EAAE,+BAA+B;CAC1G,MAAM,cAAc,wBAAwB,EAAE;CAC9C,MAAM,sBAAsB,aAAa;CAEzC,MAAM,WAAW,KAAK,gBAAgB,EAAG;CAEzC,OACE,oBAAC,KAAK,SAAN;EAEE,OAAO;EACP,YAAY;GACV;GACA;GACA;GACA,aAAa;EACf;EACA,UAAU;EACV,GAAK,aAAa;EAClB,cAAY;EAGZ,GAAK,CAAC,QAAQ,EAAE,mBAAmB,KAAA,EAAU;EAC7C,GAAK,aAAa,EAChB,eAAe,UACX,8BACA,OACE,8BACA,gCACR;EACA,GAAK,CAAC,QAAQ,EAAE,OAAO,KAAK;EAE3B,UAAA,wBACE,UACC,oBAAC,OAAD;GACE,MAAK;GACL,cAAY,EAAE,yBAAyB;GACvC,WAAU;GACV,OAAO;IAAE,gBAAgB;IAAc,mBAAmB;GAAY;GAEtE,UAAA,oBAAC,KAAK,MAAN;IAAW,MAAK;IAA2B,MAAK;IAAK,MAAA;GAAM,CAAA;EACxD,CAAA,IACH,OACF,oBAAC,gBAAD;GAAsB;GAAY;GAAY;GAAc;EAAS,CAAA,IAErE,eACE,oBAAC,OAAO,OAAR;GAEE,YAAW;GACX,OAAO;IAAE,gBAAgB;IAAc,mBAAmB;GAAY;GAErE,UAAA,EAAE,mCAAmC;EAC1B,GALP,EAKO;CAGR,GA9CP,EA8CO;AAElB;;AAGA,IAAM,2BAA2B,OAAwB;CACvD,MAAM,EAAE,UAAU,aAAa,YAAY;CAC3C,MAAM,QAAQ,WAAW,SAAS,OAAO,EAAE;CAE3C,OAAO,cAAc;EAEnB,QADiB,MAAM,SAAS,YAAY,OAAO,MAAM,CAAC,EAAA,CAC1C,MAAM,YAAY;GAChC,MAAM,QAAQ,SAAS,QAAQ,OAAO,OAAO;GAC7C,IAAI,OAAO,OAAO,KAAK,GACrB,OAAO;GAET,OAAO,MAAM,MAAM,WAAW,gBAAgB,KAAA;EAChD,CAAC;CACH,GAAG,CAAC,OAAO,KAAK,CAAC;AACnB;;;;AAKA,IAAM,kBAAkB,EACtB,MACA,MACA,aACkF;CAClF,MAAM,iBAAiB,kBAAkB;CAEzC,OACE,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,eAAD;EAAqB;EAAY;EAAc;CAAS,CAAA,GACxD,oBAAC,KAAK,MAAN;EACE,OAAO,eAAe;EACtB,IAAI,KAAK;EACT,QAAQ,KAAK;EACP;EACN,MAAK;EACL,WAAA;EACA,SAAS;EACT,SAAS,eAAe;EACxB,aAAa,eAAe;EAC5B,WAAW,eAAe;EAC1B,cAAc,eAAe;EAC7B,UAAU,eAAe;EACzB,aAAa,eAAe;EAE5B,UAAA,oBAAC,KAAK,SAAN,EAAA,UAAe,UAAwB,CAAA;CAC9B,CAAA,CACX,EAAA,CAAA;AAEN;;AAGA,IAAM,UAAU,yFAAyF,cAAc;AAEvH,IAAM,aAAa,SACjB,qBAAC,KAAK,MAAN;CAAiB;CAAjB,UAAA;EACE,oBAAC,KAAK,eAAN,CAAqB,CAAA;EACrB,oBAAC,KAAK,UAAN,CAAgB,CAAA;EAChB,oBAAC,KAAK,UAAN,EAAe,eAAY,mBAAoB,CAAA;EAC/C,oBAAC,KAAK,WAAN,CAAiB,CAAA;EAChB,KAAK,QAAQ,oBAAC,oBAAD;GAAoB,MAAM,KAAK;GAAM,MAAM,KAAK;GAAM,MAAM,KAAK;EAAO,CAAA;CAC7E;;;;;AAMb,IAAM,iBAAiB,EAAE,MAAM,MAAM,aAAkF;CACrH,MAAM,EAAE,MAAM,MAAM,eAAe,KAAK,QAAQ,GAAG;CACnD,MAAM,EAAE,eAAe,YAAY,kBAAkB;CACrD,MAAM,QAAQ,MAAM,kBAAkB,KAAK,WAAW,OAAO,CAAC;CAC9D,MAAM,uBAAuB,QAAQ,kBAAkB,IAAI;CAE3D,MAAM,EAAE,aAAa,aAAa,iBAAiB;EAAE;EAAM;CAAK,CAAC;CACjE,mBAAmB,IAAI;CAEvB,OACE,qBAAC,OAAD;EACE,0BAAuB;EACvB,WAAU;EAEV,OAAO,EAAE,qBAAqB,+BAA+B,cAAc,gBAAgB;EAJ7F,UAAA;GAMG,uBACC,oBAAC,OAAO,MAAR;IACE,YAAY,CAAC,sBAAsB,wBAAwB;IAC3D,SAAQ;IACR,MAAK;IACL,UAAA;IACA,UAAS;IACT,OAAO,EAAE,oBAAoB;IAC7B,eAAY;IACZ,eAAe,SAAS;GACzB,CAAA,IAED,oBAAC,OAAD,CAAM,CAAA;GAER,oBAAC,MAAD;IAAI,WAAU;IAA2B,UAAA;GAAU,CAAA;GACnD,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,aAAD;KAAmB;KAAmB;KAAuB;IAAW,CAAA,GACvE,WAAW,oBAAC,SAAD;KAAS,MAAM;KAAM,MAAA;IAAM,CAAA,CACpC;;EACF;;AAET;;;;;;AAYA,IAAM,eAAe,EACnB,MACA,aACA,eAGsD;CACtD,MAAM,EAAE,MAAM,MAAM,eAAe,KAAK,QAAQ,GAAG;CAEnD,IAAI,YAAY,WAAW,GACzB,OAAO;CAGT,IAAI,YAAY,WAAW,GACzB,OACE,oBAAC,OAAO,MAAR;EACE,YAAY;GAAC;GAAmC;GAAsB;EAAwB;EAC9F,SAAQ;EACR,MAAM,YAAY,EAAE,CAAC,YAAY,QAAQ;EACzC,UAAA;EACA,UAAS;EACT,OAAO,MAAM,kBAAkB,YAAY,EAAE,CAAC,YAAY,OAAO,CAAC;EAClE,eAAa,YAAY,EAAE,CAAC,YAAY;EACxC,eAAe,SAAS,YAAY,EAAyB;CAC9D,CAAA;CAIL,OACE,oBAAC,YAAD;EAAY,QAAQ;EAAyB;EAAU,OAAO;EAAM,SAAS;EAC3E,UAAA,oBAAC,OAAO,MAAR;GACE,YAAY;IAAC;IAAmC;IAAsB;GAAwB;GAC9F,SAAQ;GACR,MAAK;GACL,UAAA;GACA,UAAS;GACT,OAAO,EAAE,yBAAyB;GAClC,eAAY;EACb,CAAA;CACS,CAAA;AAEhB;;;;AAKA,IAAM,oBAAoB,EAAE,MAAM,WAAoF;CACpH,MAAM,YAAY,WAAW,gBAAgB;CAW7C,OAAO;EAAE,aATW,eAAe,WAAW,IAAI,CASzC;EAAa,UAPL,aACd,QAA6B,WAAsC;GAClE,UAAe,QAAQ;IAAE,GAAG;IAAQ;GAAK,CAAC;EAC5C,GACA,CAAC,WAAW,IAAI,CAGI;CAAS;AACjC;AAEA,IAAa,UAAU,KAAK,YAAY;;;;;;ACrRxC,IAAa,UAAU,EAAE,eAAe,eAAe,QAAQ,MAAM,MAAM,kBAA+B;CAGxG,MAAM,kBAAkB,cAAc,MAAM,SAAS,KAAK,OAAO,iBAAiB,WAAW,IAAI,MAAM,KAAK;CAC5G,OACE,qBAAA,YAAA,EAAA,UAAA,CACG,cAAc,KAAK,SAAS;EAE3B,IADa,WAAW,IACpB,MAAS,OACX,OACE,oBAAC,SAAD;GAEE,IAAI,KAAK;GACH;GACA;GACA;GACE;GACR,WAAW,KAAK,OAAO;EACxB,GAPM,KAAK,EAOX;EAGL,OAAO;CACT,CAAC,GACA,CAAC,mBACA,oBAAC,SAAD;EAA6B,IAAI;EAAqB;EAAY;EAAmB;EAAa,WAAA;CAAW,GAA/F,aAA+F,CAE/G,EAAA,CAAA;AAEN;;;AC7BA,IAAa,gBAAgB;AAQ7B,IAAa,UAAU,YAA0C,EAAE,IAAI,MAAM,KAAK,GAAG,SAAS,iBAAiB;CAC7G,MAAM,EAAE,QAAQ,gBAAgB,kBAAkB;CAClD,MAAM,EAAE,iBAAiB,SAAS,aAAa,iBAAiB,kBAAkB,oBAAoB,IAAI;CAE1G,mBAAmB,IAAI;CACvB,MAAM,OAAO,cAAc,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;CAErC,OAKE,qBAAC,KAAK,MAAN;EAAW,OAAO;EAAK,aAAY;EAAW,YAAW;EAAW,KAAK;EAAzE,UAAA,CACE,oBAAC,QAAD;GACE,aAAa;GACb,eAAe;GACF;GACI;GACX;GACN,QAAQ;GACK;EACd,CAAA,GACD,oBAAC,QAAD;GAAuB;GAAqB;GAAM,eAAe;GAAa;GAAQ,GAAI;EAAQ,CAAA,CACzF;;AAEf,CAAC;;;;AAKD,IAAM,uBAAuB,SAA6B;CACxD,MAAM,EAAE,UAAU,aAAM,YAAY;CACpC,MAAM,SAAS,MAAM,MAAM,UAAU;CACrC,MAAM,oBAAoB,WAAW,eAAe,OAAO,QAAQ,OAAO;CAC1E,MAAM,cAAc,WAAW,WAAW,OAAO,MAAM;CAEvD,MAAM,EAAE,iBAAiB,SAAS,aAAa,oBAAoB,cAAc;EAC/E,MAAM,qBAA0C,CAAC;EACjD,MAAM,sBAA2C,CAAC;EAClD,IAAI;EACJ,KAAK,MAAM,QAAQ,mBACjB,IAAI,aAAa,eAAe,MAAM,WAAW,GAC/C,mBAAmB,KAAK,IAAI;OACvB,IAAI,aAAa,eAAe,MAAM,SAAS,GACpD,oBAAoB,KAAK,IAAI;OACxB,IAAI,aAAa,eAAe,MAAM,cAAc,GACzD,oBAAoB;EAIxB,MAAM,kBAAkB,YACrB,QAAQ,WAAW,aAAa,eAAe,QAAQ,MAAM,CAAC,CAAA,CAC9D,UAAU,GAAG,MAAM,SAAS,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC;EAMlE,OAAO;GACL,aANkB,CAClB,GAAG,qBACH,GAAG,YAAY,QAAQ,WAAW,aAAa,eAAe,QAAQ,SAAS,CAAC,CAClF,CAAC,CAAC,UAAU,GAAG,MAAM,SAAS,QAAQ,EAAE,YAAY,EAAE,UAAU,CAG9D;GACA;GACA;GACA,SAAS;EACX;CACF,GAAG,CAAC,aAAa,iBAAiB,CAAC;CAOnC,OAAO;EAAE;EAAiB;EAAS;EAAa;EAAiB,eAL3C,cACd;GAAC,GAAG;GAAS,GAAG;GAAa,GAAI,kBAAkB,CAAC,eAAe,IAAI,CAAC;EAAE,GAChF;GAAC;GAAS;GAAa;EAAe,CAGyB;CAAc;AACjF"}
1
+ {"version":3,"file":"components.mjs","names":[],"sources":["../../src/components/NavTreeContext/NavTreeContext.ts","../../src/components/UserAccountAvatar/UserAccountAvatar.tsx","../../src/components/Sidebar/L0PendingAvatar.tsx","../../src/components/Sidebar/L0Menu.tsx","../../src/components/NavTreeItem/NavTreeItemAction.tsx","../../src/components/NavTreeItem/NavTreeItemColumns.tsx","../../src/components/Sidebar/L1Panel.tsx","../../src/components/Sidebar/L1Tabs.tsx","../../src/components/NavTree/NavTree.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { createContext, useContext } from 'react';\n\nimport { raise } from '@dxos/debug';\n\nimport { type NavTreeContextValue } from '../types.ts';\n\nexport const NavTreeContext = createContext<NavTreeContextValue | null>(null);\n\nexport const useNavTreeContext = () => useContext(NavTreeContext) ?? raise(new Error('Missing NavTreeContext'));\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { type ComponentProps } from 'react';\n\nimport * as Avatar from '@dxos/react-ui/Avatar';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport { hexToFallback } from '@dxos/util';\n\nimport { L0ItemActiveTabIndicator } from '../Sidebar/index.ts';\n\nexport type UserAccountAvatarProps = {\n size?: ComponentProps<typeof Avatar.Root>['size'];\n userId?: string;\n hue?: string;\n emoji?: string;\n status?: Avatar.Status;\n /** Shows a dot on the avatar, e.g. while invitations are pending. */\n badge?: boolean;\n};\n\nexport const UserAccountAvatar = ({ size, userId, hue, emoji, status, badge }: UserAccountAvatarProps) => {\n const fallbackValue = userId ? hexToFallback(userId) : undefined;\n const resolved = fallbackValue !== undefined;\n\n return (\n <>\n <L0ItemActiveTabIndicator classNames='inset-y-6' />\n <Layout.Grid center classNames='dx-focus-ring-group-indicator rounded-full' data-joyride='welcome/account'>\n {/* Sized by the avatar so the badge sits on its corner, not the cell's. */}\n <span className='relative inline-grid'>\n <Avatar.Root\n variant='circle'\n size={size ?? 'xl'}\n {...(resolved && { status: status ?? 'active' })}\n hue={Avatar.toAvatarHue(hue || fallbackValue?.hue)}\n fallback={emoji || fallbackValue?.emoji || ''}\n data-testid={resolved ? 'treeView.userAccount' : 'treeView.userAccount.pending'}\n />\n {badge && (\n <span\n className='absolute top-0 right-0 size-2.5 rounded-full bg-error-text'\n data-testid='treeView.userAccount.badge'\n />\n )}\n </span>\n </Layout.Grid>\n </>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Status from '@dxos/react-ui/Status';\n\nconst PENDING_ANIMATION_DELAY = '2s';\n\nconst PENDING_ANIMATION_DURATION = '4s';\n\nexport const L0PendingAvatar = () => (\n <Status.Skeleton\n classNames='w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) rounded-sm'\n style={{ animationDelay: PENDING_ANIMATION_DELAY, animationDuration: PENDING_ANIMATION_DURATION }}\n />\n);\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport {\n type Edge,\n attachClosestEdge,\n extractClosestEdge,\n} from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';\nimport { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';\nimport { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';\nimport { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';\nimport { scrollJustEnoughIntoView } from '@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view';\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport React, {\n type MouseEvent,\n type PropsWithChildren,\n forwardRef,\n memo,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport type * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\nimport { DxAvatar } from '@dxos/lit-ui/react';\nimport * as GraphHooks from '@dxos/plugin-graph/Hooks';\nimport { ActionMenu, type MenuItem } from '@dxos/react-ui-menu';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as DragHandle from '@dxos/react-ui/DragHandle';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Main from '@dxos/react-ui/Main';\nimport * as ScrollArea from '@dxos/react-ui/ScrollArea';\nimport * as Tabs from '@dxos/react-ui/Tabs';\nimport * as Theme from '@dxos/react-ui/Theme';\nimport * as Tooltip from '@dxos/react-ui/Tooltip';\nimport type * as Util from '@dxos/react-ui/Util';\nimport { mx } from '@dxos/ui-theme';\nimport { arrayMove } from '@dxos/util';\n\nimport { useNavTreeState } from '#hooks';\nimport { meta } from '#meta';\n\nimport { l0ItemType } from '../../util.ts';\nimport { useNavTreeContext } from '../NavTreeContext/index.ts';\nimport { UserAccountAvatar } from '../UserAccountAvatar/index.ts';\nimport { L0PendingAvatar } from './L0PendingAvatar.tsx';\n\n//\n// L0Item\n//\n\ntype L0ItemData = {\n id: L0ItemProps['item']['id'];\n type: 'l0Item';\n};\n\n// Local rearrange-handler callback shape; drag-and-drop is wired directly via pragmatic-dnd in `L0Item`,\n// so only the callback signature is needed here.\ntype StackItemRearrangeHandler<Data extends { id: string } = { id: string }> = (\n source: Data,\n target: Data,\n closestEdge: Edge | null,\n) => void;\n\ntype L0ItemRootProps = {\n item: AppGraphNode.Node;\n parent?: AppGraphNode.Node;\n path: string[];\n onMouseEnter?: () => void;\n};\n\ntype L0ItemProps = L0ItemRootProps & {\n item: AppGraphNode.Node;\n parent?: AppGraphNode.Node;\n path: string[];\n pinned?: boolean;\n onRearrange?: StackItemRearrangeHandler<L0ItemData>;\n onItemHover?: (params: { item: AppGraphNode.Node }) => void;\n};\n\nconst useL0ItemClick = ({ item, parent, path }: L0ItemProps, type: string) => {\n const { onSelect, onTabChange } = useNavTreeContext();\n const { getItem } = useNavTreeState();\n const [isLg] = Hooks.useMediaQuery('lg');\n const runAction = GraphHooks.useActionRunner();\n\n return useCallback(\n (event: MouseEvent) => {\n switch (type) {\n case 'action': {\n const { properties: { caller } = {} } = item;\n return void runAction(item as AppGraphNode.Action, caller ? { parent, path, caller } : { parent, path });\n }\n case 'tab':\n return item.properties.pending === true ? undefined : onTabChange?.(item);\n case 'link':\n return onSelect?.({\n item,\n path,\n current: !getItem(path).current,\n option: event.altKey,\n shift: event.shiftKey,\n meta: event.metaKey || event.ctrlKey,\n });\n }\n },\n [item, parent, type, getItem, onSelect, onTabChange, isLg, runAction],\n );\n};\n\nconst l0Breakpoints: Record<string, string> = {\n lg: 'hidden lg:grid',\n};\n\nconst L0ItemRoot = memo(\n forwardRef<HTMLButtonElement, PropsWithChildren<L0ItemRootProps>>(\n ({ item, parent, path, onMouseEnter, children }, forwardedRef) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const { model } = useNavTreeContext();\n const itemPath = useMemo(() => [...path, item.id], [item.id, path]);\n const { id, testId } = useAtomValue(model.itemProps(itemPath));\n const localizedString = Theme.toLocalizedString(item.properties.label, t);\n\n const type = l0ItemType(item);\n const handleClick = useL0ItemClick({ item, parent, path: itemPath }, type);\n\n return (\n <Tooltip.Trigger asChild side='right' content={localizedString}>\n <Tabs.Trigger asChild value={item.id}>\n <button\n type='button'\n className={mx(\n 'group/l0item flex w-full justify-center items-center relative',\n 'dx-app-no-drag dx-focus-ring-group data[type!=\"collection\"]:cursor-pointer aria-disabled:cursor-default',\n l0Breakpoints[item.properties.l0Breakpoint],\n )}\n tabIndex={type === 'tab' ? 0 : undefined}\n data-type={type}\n data-testid={testId}\n data-object-id={id}\n {...(item.properties.pending === true && { 'aria-disabled': true })}\n onClick={handleClick}\n onMouseEnter={onMouseEnter}\n ref={forwardedRef}\n >\n {children}\n </button>\n </Tabs.Trigger>\n </Tooltip.Trigger>\n );\n },\n ),\n);\n\nexport const L0ItemActiveTabIndicator = ({ classNames }: Util.ThemedClassName<{}>) => (\n <div\n className={mx(\n 'hidden group-aria-selected/l0item:block absolute start-0 h-6 w-1.5 bg-accent-bg rounded-sm',\n classNames,\n )}\n />\n);\n\n// TODO(burdon): Factor out pinned (non-draggable) items.\nconst L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L0ItemProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const itemElement = useRef<HTMLButtonElement | null>(null);\n const [closestEdge, setEdge] = useState<Edge | null>(null);\n const localizedString = Theme.toLocalizedString(item.properties.label, t);\n const hue = item.properties.hue ?? null;\n const pending = item.properties.pending === true;\n\n useLayoutEffect(() => {\n if (!itemElement.current || !onRearrange || pending) {\n return;\n }\n\n return combine(\n draggable({\n element: itemElement.current,\n getInitialData: () => ({ id: item.id, type: 'l0Item' }) satisfies L0ItemData,\n onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {\n document.body.setAttribute('data-drag-preview', 'true');\n const element = source.element.querySelector('[data-frame]') as HTMLElement;\n scrollJustEnoughIntoView({ element });\n const { x, y } = preserveOffsetOnSource({ element, input: location.current.input })({\n container: (element.offsetParent ?? document.body) as HTMLElement,\n });\n nativeSetDragImage?.(element, x, y);\n },\n onDragStart: () => {\n document.body.removeAttribute('data-drag-preview');\n itemElement.current!.closest('[data-drag-autoscroll]')?.setAttribute('data-drag-autoscroll', 'active');\n },\n onDrop: () => {\n itemElement.current!.closest('[data-drag-autoscroll]')?.setAttribute('data-drag-autoscroll', 'idle');\n },\n }),\n dropTargetForElements({\n element: itemElement.current,\n getData: ({ input, element }) => {\n return attachClosestEdge(\n { id: item.id, type: 'l0Item' },\n { input, element, allowedEdges: ['top', 'bottom'] },\n );\n },\n onDragEnter: ({ self, source }) => {\n if (source.data.type === self.data.type) {\n setEdge(extractClosestEdge(self.data));\n }\n },\n onDrag: ({ self, source }) => {\n if (source.data.type === self.data.type) {\n setEdge(extractClosestEdge(self.data));\n }\n },\n onDragLeave: () => setEdge(null),\n onDrop: ({ self, source }) => {\n setEdge(null);\n if (source.data.type === self.data.type) {\n onRearrange(source.data as L0ItemData, self.data as L0ItemData, extractClosestEdge(self.data));\n }\n },\n }),\n );\n }, [item, onRearrange, pending]);\n\n const handleMouseEnter = useCallback(() => onItemHover?.({ item }), [item, onItemHover]);\n\n return (\n <L0ItemRoot ref={itemElement} item={item} parent={parent} path={path} onMouseEnter={handleMouseEnter}>\n <Layout.Flex\n data-frame={true}\n {...(pending && { 'data-pending': true, 'aria-busy': true })}\n {...(hue && { style: { background: `var(--color-${hue}-surface)` } })}\n center\n classNames={[\n 'dx-focus-ring-group-indicator transition-colors rounded-sm',\n pinned\n ? 'p-2 group-hover/l0item:bg-current-surface'\n : 'w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-current-surface',\n ]}\n >\n <ItemAvatar item={item} />\n </Layout.Flex>\n <L0ItemActiveTabIndicator />\n <span id={`${item.id}__label`} className='sr-only'>\n {localizedString}\n </span>\n {(closestEdge === 'top' || closestEdge === 'bottom') && <DragHandle.DropIndicator edge={closestEdge} />}\n </L0ItemRoot>\n );\n});\n\nconst ItemAvatar = ({ item }: Pick<L0ItemProps, 'item'>) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n\n if (item.properties.pending === true) {\n return <L0PendingAvatar />;\n }\n\n // Actions.\n if (item.properties.icon) {\n const hue = item.properties.hue ?? null;\n const hueFgStyle = hue && { style: { color: `var(--color-${hue}-fg)` } };\n return <Icon.Icon icon={item.properties.icon} size='xl' {...hueFgStyle} />;\n }\n\n const type = l0ItemType(item);\n if (type === 'tab' && item.properties.disposition !== 'pin-end') {\n const hue = item.properties.hue ?? null;\n const localizedString = Theme.toLocalizedString(item.properties.label, t);\n return <DxAvatar hue={hue} hueVariant='surface' variant='square' size={12} fallback={localizedString} />;\n }\n\n return null;\n};\n\n//\n// L0Menu\n//\n\nexport type L0MenuProps = {\n menuActions: MenuItem[];\n topLevelItems: AppGraphNode.Node[];\n pinnedItems: AppGraphNode.Node[];\n userAccountItem?: AppGraphNode.Node;\n parent?: AppGraphNode.Node;\n path: string[];\n onItemHover?: (params: { item: AppGraphNode.Node }) => void;\n};\n\nexport const L0Menu = ({\n menuActions,\n topLevelItems,\n pinnedItems,\n userAccountItem,\n parent,\n path,\n onItemHover,\n}: L0MenuProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const runAction = GraphHooks.useActionRunner();\n const handleAction = useCallback(\n (action: AppGraphNode.Action, params: AppGraphNode.InvokeProps) => {\n void runAction(action, params);\n },\n [runAction],\n );\n\n const handleRearrange = useCallback<StackItemRearrangeHandler<L0ItemData>>(\n (source, target, closestEdge) => {\n const sourceItem = topLevelItems.find((i) => i.id === source.id);\n if (!sourceItem?.properties.onRearrange) {\n return;\n }\n\n const sourceIndex = topLevelItems.findIndex((i) => i.id === source.id);\n const targetIndex = topLevelItems.findIndex((i) => i.id === target.id);\n const insertIndex =\n source.id === target.id\n ? sourceIndex\n : targetIndex +\n (sourceIndex < targetIndex ? (closestEdge === 'top' ? -1 : 0) : closestEdge === 'bottom' ? 1 : 0);\n const nextOrder = arrayMove([...topLevelItems], sourceIndex, insertIndex);\n return sourceItem.properties.onRearrange(nextOrder.map((item) => item.id));\n },\n [topLevelItems],\n );\n\n // Check if any items have onRearrange to enable drag-and-drop.\n const hasRearrangeableItems = topLevelItems.some((item) => item.properties.onRearrange);\n // The rail is a focus area of its own, before the panel beside it.\n const landmark = Main.useMainLandmark(0);\n\n return (\n <Tabs.List\n {...landmark}\n data-tauri-drag-region='deep'\n classNames={[\n 'group/l0 absolute z-[1] inset-y-0 start-0 rounded-s',\n 'grid grid-cols-[var(--dx-l0-size)] grid-rows-[var(--dx-rail-size)_1fr_min-content_var(--dx-l0-size)] dx-contain-layout',\n 'w-(--dx-l0-size) dx-l0-surface dx-app-drag pb-[env(safe-area-inset-bottom)]',\n '[body[data-platform=\"macos\"]_&]:pt-[30px]',\n '[body[data-platform=\"ios\"]_&]:pt-[max(env(safe-area-inset-top),0.25rem)]',\n ]}\n >\n {/* TODO(wittjosiah): Use L0Item trigger. */}\n <ActionMenu onAction={handleAction} group={parent} actions={menuActions}>\n {/* The trigger clones this child, so the testid belongs here rather than on `ActionMenu`. */}\n <div className='grid place-items-center' data-testid='spacePlugin.addSpace'>\n <Button.Root\n size='lg'\n variant='ghost'\n iconSize='lg'\n icon='ph--list--regular'\n iconOnly\n label={t('app-menu.label')}\n />\n </div>\n </ActionMenu>\n\n {/* Space list. */}\n <ScrollArea.Root orientation='vertical'>\n <ScrollArea.Viewport classNames='flex flex-col gap-2 py-1'>\n {topLevelItems.map((item) => (\n <L0Item\n key={item.id}\n item={item}\n parent={parent}\n path={path}\n onItemHover={onItemHover}\n {...(hasRearrangeableItems && { onRearrange: handleRearrange })}\n />\n ))}\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n\n {/* Actions. */}\n <Layout.Grid cols={1} classNames='auto-rows-(--dx-rail-action) pt-2'>\n {pinnedItems.map((item) => (\n <L0Item key={item.id} item={item} parent={parent} path={path} pinned />\n ))}\n </Layout.Grid>\n\n <Layout.Grid classNames='dx-app-no-drag'>\n {userAccountItem ? (\n <L0ItemRoot key={userAccountItem.id} item={userAccountItem} parent={parent} path={path}>\n <UserAccountAvatar\n userId={userAccountItem.properties.userId}\n hue={userAccountItem.properties.hue}\n emoji={userAccountItem.properties.emoji}\n status={userAccountItem.properties.status}\n badge={userAccountItem.properties.badge}\n size='lg'\n />\n </L0ItemRoot>\n ) : (\n <Layout.Flex center classNames='w-full'>\n <UserAccountAvatar size='lg' />\n </Layout.Flex>\n )}\n </Layout.Grid>\n </Tabs.List>\n );\n};\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useCallback } from 'react';\n\nimport type * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\nimport * as GraphHooks from '@dxos/plugin-graph/Hooks';\nimport { ActionMenu, type MenuItem } from '@dxos/react-ui-menu';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Theme from '@dxos/react-ui/Theme';\nimport * as Util from '@dxos/react-ui/Util';\n\nimport { meta } from '#meta';\nimport { NavTreeNode } from '#types';\n\nconst fallbackIcon = 'ph--circle-dashed--regular';\n\nexport type NavTreeItemActionMenuProps = NavTreeNode.ActionProperties & {\n parent: AppGraphNode.Node;\n path?: string[];\n caller?: string;\n monolithic?: boolean;\n menuActions?: AppGraphNode.Action[];\n};\n\nexport const NavTreeItemActionDropdownMenu = Util.composable<HTMLButtonElement, NavTreeItemActionMenuProps>(\n ({ parent, path, label, icon, testId, menuActions, caller, ...props }, forwardedRef) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const runAction = GraphHooks.useActionRunner();\n const handleAction = useCallback(\n (action: AppGraphNode.Action, params: AppGraphNode.InvokeProps = {}) => runAction(action, { ...params, path }),\n [runAction, path],\n );\n\n return (\n <ActionMenu caller={caller} onAction={handleAction} group={parent} actions={menuActions as MenuItem[]}>\n <Button.Root\n {...props}\n classNames='shrink-0 px-2 pointer-fine:px-1'\n variant='ghost'\n icon={icon ?? fallbackIcon}\n iconOnly\n label={Theme.toLocalizedString(label, t)}\n data-testid={testId}\n // The tree selects a row on any click inside it, and selecting navigates away from the\n // menu just opened. The trigger has handled the click by the time this runs.\n onClick={(event) => event.stopPropagation()}\n ref={forwardedRef}\n />\n </ActionMenu>\n );\n },\n);\n\nNavTreeItemActionDropdownMenu.displayName = 'NavTreeItemActionDropdownMenu';\n\nexport const NavTreeItemMonolithicAction = (\n props: AppGraphNode.Action & {\n parent: AppGraphNode.Node;\n path?: string[];\n onAction?: (action: AppGraphNode.Action) => void;\n baseLabel: string;\n },\n) => {\n const {\n parent,\n path,\n properties: { disabled, caller, testId, icon, variant = 'ghost', iconOnly = true } = { label: 'never' },\n baseLabel,\n } = props;\n const runAction = GraphHooks.useActionRunner();\n return (\n <Button.Root\n variant={variant}\n classNames={['shrink-0', iconOnly ? 'px-2 pointer-fine:px-1' : 'p-2 pointer-fine:p-2 me-1']}\n icon={icon ?? fallbackIcon}\n iconOnly={iconOnly}\n label={baseLabel}\n disabled={disabled}\n onClick={(event) => {\n event.stopPropagation();\n if (disabled) {\n return;\n }\n\n void runAction(props, caller ? { parent, caller, path } : { parent, path });\n }}\n data-testid={testId}\n />\n );\n};\n\nexport const NavTreeItemAction = ({\n monolithic,\n menuActions,\n menuType,\n parent,\n path,\n ...props\n}: NavTreeItemActionMenuProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n\n const monolithicAction = menuActions?.length === 1 && menuActions[0];\n const baseLabel = Theme.toLocalizedString(monolithicAction ? monolithicAction.properties!.label : props.label, t);\n return monolithic && menuActions?.length === 1 ? (\n <NavTreeItemMonolithicAction baseLabel={baseLabel} parent={parent} path={path} {...menuActions[0]} />\n ) : (\n <NavTreeItemActionDropdownMenu {...props} label={baseLabel} parent={parent} path={path} menuActions={menuActions} />\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { Fragment, memo, useMemo } from 'react';\n\nimport { Tree } from '@dxos/react-ui-list';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Popover from '@dxos/react-ui/Popover';\nimport * as Theme from '@dxos/react-ui/Theme';\n\nimport { getListActions, useActions } from '#hooks';\nimport { meta } from '#meta';\n\nimport { NAV_TREE_ITEM } from '../NavTree/index.ts';\nimport { useNavTreeContext } from '../NavTreeContext/index.ts';\nimport { type NavTreeItemColumnsProps } from '../types.ts';\nimport { NavTreeItemActionDropdownMenu, NavTreeItemMonolithicAction } from './NavTreeItemAction.tsx';\n\nexport const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumnsProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const { renderItemEnd: ItemEnd, popoverAnchorId } = useNavTreeContext();\n\n const level = path.length - 2;\n const flattenedActions = useActions(item);\n const allActions = useMemo(() => getListActions(flattenedActions), [flattenedActions]);\n\n const anchored = popoverAnchorId === `${NAV_TREE_ITEM}:${item.id}`;\n const ActionRoot = anchored ? Popover.Anchor : Fragment;\n\n return (\n // `data-popover-anchor` lets the enclosing row highlight itself while a popover (e.g. rename) is open on it.\n // The empty div holds the actions track when the item has no actions.\n <div className='contents dx-app-no-drag' {...(anchored && { 'data-popover-anchor': '' })}>\n <Tree.ItemActions>\n <ActionRoot>\n {allActions.length === 1 ? (\n <NavTreeItemMonolithicAction\n baseLabel={Theme.toLocalizedString(allActions[0].properties?.label, t)}\n parent={item}\n path={path}\n {...allActions[0]}\n />\n ) : allActions.length > 1 ? (\n <NavTreeItemActionDropdownMenu\n testId={`navtree.treeItem.actionsLevel${level}`}\n label={t('tree-item-actions.label')}\n icon='ph--dots-three-vertical--regular'\n parent={item}\n path={path}\n menuActions={allActions}\n caller={NAV_TREE_ITEM}\n />\n ) : (\n <div />\n )}\n </ActionRoot>\n </Tree.ItemActions>\n {ItemEnd && <ItemEnd node={item} open={open} />}\n </div>\n );\n});\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport React, { memo, useCallback, useMemo } from 'react';\n\nimport * as AppGraph from '@dxos/app-graph/AppGraph';\nimport * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\nimport * as AppNode from '@dxos/app-toolkit/AppNode';\nimport * as ToolkitHooks from '@dxos/app-toolkit/Hooks';\nimport * as GraphHooks from '@dxos/plugin-graph/Hooks';\nimport { Tree, type TreeNode } from '@dxos/react-ui-list';\nimport { ActionMenu, type MenuItem } from '@dxos/react-ui-menu';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Main from '@dxos/react-ui/Main';\nimport * as Status from '@dxos/react-ui/Status';\nimport * as Tabs from '@dxos/react-ui/Tabs';\nimport * as Theme from '@dxos/react-ui/Theme';\nimport { hoverableControlItem, hoverableOpenControlItem } from '@dxos/ui-theme';\n\nimport { getListActions, useActions, useLoadDescendents } from '#hooks';\nimport { meta } from '#meta';\nimport { type NavTreeNode } from '#types';\n\nimport { NAV_TREE_ITEM } from '../NavTree/index.ts';\nimport { useNavTreeContext } from '../NavTreeContext/index.ts';\nimport { NavTreeItemColumns } from '../NavTreeItem/NavTreeItemColumns.tsx';\n\n/**\n * Width held for the item-end slot, whose surface resolves after the tree has painted: a\n * `min-content` track would start collapsed and re-truncate every label when it lands. Sized to\n * what fills it, an `AttentionGlyph` (`w-3`) inset by `mx-1`.\n */\nconst ITEM_END_SIZE = '1.25rem';\n\n/** Delay before a pending or unavailable workspace renders anything. */\nconst RENDER_DELAY = '1s';\n\nexport type L1PanelProps = {\n open?: boolean;\n path: string[];\n /** The tab's workspace id, which may name a workspace that has no graph node. */\n id: string;\n /** Absent when the workspace is not in the graph; the panel then renders the unavailable message. */\n item?: AppGraphNode.Node;\n /** Whether the workspace this tab names is known to be missing, rather than still on its way. */\n unavailable?: boolean;\n isCurrent: boolean;\n onBack?: () => void;\n};\n\n/**\n * Space or settings panel. Without an `item` — a link to a workspace this identity never had or which no\n * longer exists, or persisted deck state pointing at one after a profile switch — the panel body is the\n * unavailable-workspace message, so the sidebar is never blank.\n */\nconst L1PanelInner = ({ open, path, id, item, unavailable, isCurrent, onBack }: L1PanelProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const pending = item?.properties.pending === true;\n const title = item ? Theme.toLocalizedString(item.properties.label, t) : t('workspace-unavailable.heading');\n const isActivated = useIsActivatedWorkspace(id);\n const shouldRenderContent = isCurrent || isActivated;\n // The panel is a focus area of its own, after the rail.\n const landmark = Main.useMainLandmark(0.5);\n\n return (\n <Tabs.Content\n key={id}\n value={id}\n classNames={[\n 'absolute inset-y-0 end-0',\n 'w-[calc(100%-var(--dx-l0-size))] lg:w-(--dx-l1-size) grid-cols-1 grid-rows-[var(--dx-rail-size)_1fr]',\n 'py-[env(safe-area-inset-top)]',\n isCurrent && 'grid',\n ]}\n tabIndex={-1}\n {...(isCurrent && landmark)}\n aria-label={title}\n // An unavailable workspace has no tab in the rail, so the generated `aria-labelledby` would\n // reference a missing element.\n {...(!item && { 'aria-labelledby': undefined })}\n {...(isCurrent && {\n 'data-testid': pending\n ? 'navtree.workspace.pending'\n : item\n ? 'navtree.workspace.visible'\n : 'navtree.workspace.unavailable',\n })}\n {...(!open && { inert: true })}\n >\n {shouldRenderContent &&\n (pending ? (\n <Layout.Flex\n role='status'\n aria-label={t('pending-workspace.label')}\n justify='center'\n classNames='row-start-2 self-start p-4 animate-fade-in'\n style={{ animationDelay: RENDER_DELAY, animationFillMode: 'backwards' }}\n >\n <Icon.Icon icon='ph--spinner-gap--regular' size='xl' spin />\n </Layout.Flex>\n ) : item ? (\n <L1PanelContent open={open} path={path} item={item} onBack={onBack} />\n ) : (\n unavailable && (\n <Status.Empty\n key={id}\n classNames='row-start-2 self-start animate-fade-in'\n style={{ animationDelay: RENDER_DELAY, animationFillMode: 'backwards' }}\n >\n {t('workspace-unavailable.description')}\n </Status.Empty>\n )\n ))}\n </Tabs.Content>\n );\n};\n\n/** Determines whether a workspace tab has been populated with real child content (i.e. expanded at least once). */\nconst useIsActivatedWorkspace = (id: string): boolean => {\n const { graph } = ToolkitHooks.useAppGraph();\n const edges = GraphHooks.useEdges(graph, id);\n\n return useMemo(() => {\n const childIds = edges[AppGraph.relationKey('child')] ?? [];\n return childIds.some((childId) => {\n const child = AppGraph.getNode(graph, childId);\n if (Option.isNone(child)) {\n return false;\n }\n return child.value.properties.disposition === undefined;\n });\n }, [edges, graph]);\n};\n\n/**\n * Mounted panel content for active or previously-visited tabs.\n */\nconst L1PanelContent = ({\n path,\n item,\n onBack,\n}: Pick<L1PanelProps, 'open' | 'path' | 'onBack'> & { item: AppGraphNode.Node }) => {\n const navTreeContext = useNavTreeContext();\n\n return (\n <>\n <L1PanelHeader path={path} item={item} onBack={onBack} />\n <Tree.Root\n model={navTreeContext.model}\n id={item.id}\n rootId={item.id}\n path={path}\n size='md'\n draggable\n columns={COLUMNS}\n canDrop={navTreeContext.canDrop}\n getDropKind={navTreeContext.getDropKind}\n canSelect={navTreeContext.canSelect}\n onOpenChange={navTreeContext.onOpenChange}\n onSelect={navTreeContext.onSelect}\n onItemHover={navTreeContext.onItemHover}\n >\n <Tree.Content>{renderRow}</Tree.Content>\n </Tree.Root>\n </>\n );\n};\n\n/** Disclosure, icon, label, count, the actions menu, then the late item-end surface. */\nconst COLUMNS = `var(--dx-half-block-size) var(--dx-block-size) minmax(0, 1fr) auto min-content minmax(${ITEM_END_SIZE}, min-content)`;\n\nconst renderRow = (node: TreeNode<NavTreeNode.NavTreeItemGraphNode>) => (\n <Tree.Item node={node}>\n <Tree.ItemIndicator />\n <Tree.ItemIcon />\n <Tree.ItemText data-testid='treeItem.heading' />\n <Tree.ItemCount />\n {node.item && <NavTreeItemColumns path={node.path} item={node.item} open={node.open} />}\n </Tree.Item>\n);\n\n/**\n * Header row.\n */\nconst L1PanelHeader = ({ item, path, onBack }: Pick<L1PanelProps, 'path' | 'onBack'> & { item: AppGraphNode.Node }) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const { renderItemEnd: ItemEnd } = useNavTreeContext();\n const title = Theme.toLocalizedString(item.properties.label, t);\n const backCapableWorkspace = AppNode.isPinnedWorkspace(item);\n\n const { menuActions, onAction } = useL1MenuActions({ item, path });\n useLoadDescendents(item);\n\n return (\n <div\n data-tauri-drag-region='deep'\n className='grid w-full items-center px-2 dx-app-drag dx-density-lg'\n // Same late item-end surface and inline inset as the tree rows below, so its actions and status line up with theirs.\n style={{ gridTemplateColumns: `28px 1fr min-content minmax(${ITEM_END_SIZE}, min-content)` }}\n >\n {backCapableWorkspace ? (\n <Button.Root\n classNames={[hoverableControlItem, hoverableOpenControlItem]}\n variant='ghost'\n icon='ph--caret-left--regular'\n iconOnly\n iconSize='md'\n label={t('button-back.button')}\n data-testid='treeView.primaryTreeButton'\n onClick={() => onBack?.()}\n />\n ) : (\n <div />\n )}\n <h2 className='flex-1 truncate min-w-0'>{title}</h2>\n <div className='contents dx-app-no-drag'>\n <MenuActions item={item} menuActions={menuActions} onAction={onAction} />\n {ItemEnd && <ItemEnd node={item} open />}\n </div>\n </div>\n );\n};\n\ntype L1MenuActions = {\n menuActions: AppGraphNode.Action[];\n onAction: (action: AppGraphNode.Action, params?: AppGraphNode.InvokeProps) => void;\n};\n\n/**\n * Header menu actions for an L1 workspace tab. Renders nothing for an empty\n * `menuActions`, a single inline icon button for one action, and a\n * `…`-menu trigger for multiple.\n */\nconst MenuActions = ({\n item,\n menuActions,\n onAction,\n}: {\n item: AppGraphNode.Node;\n} & Pick<L1MenuActions, 'menuActions' | 'onAction'>) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n\n if (menuActions.length === 0) {\n return null;\n }\n\n if (menuActions.length === 1) {\n return (\n <Button.Root\n classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}\n variant='ghost'\n icon={menuActions[0].properties?.icon ?? 'ph--circle-dashed--regular'}\n iconOnly\n iconSize='md'\n label={Theme.toLocalizedString(menuActions[0].properties?.label, t)}\n data-testid={menuActions[0].properties?.testId}\n onClick={() => onAction(menuActions[0] as AppGraphNode.Action)}\n />\n );\n }\n\n return (\n <ActionMenu caller={NAV_TREE_ITEM} onAction={onAction} group={item} actions={menuActions as MenuItem[]}>\n <Button.Root\n classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}\n variant='ghost'\n icon='ph--dots-three-vertical--regular'\n iconOnly\n iconSize='md'\n label={t('tree-item-actions.label')}\n data-testid='navtree.treeItem.actionsLevel0'\n />\n </ActionMenu>\n );\n};\n\n/**\n * Builds the menu actions for the L1 panel header.\n */\nconst useL1MenuActions = ({ item, path }: Pick<L1PanelProps, 'path'> & { item: AppGraphNode.Node }): L1MenuActions => {\n const runAction = GraphHooks.useActionRunner();\n\n const menuActions = getListActions(useActions(item));\n\n const onAction = useCallback(\n (action: AppGraphNode.Action, params?: AppGraphNode.InvokeProps) => {\n void runAction(action, { ...params, path });\n },\n [runAction, path],\n );\n\n return { menuActions, onAction };\n};\n\nexport const L1Panel = memo(L1PanelInner);\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\n\nimport { l0ItemType } from '../../util.ts';\nimport { L1Panel, type L1PanelProps } from './L1Panel.tsx';\n\nexport type L1TabsProps = Pick<L1PanelProps, 'open' | 'onBack' | 'unavailable'> & {\n currentItemId: string;\n path: string[];\n topLevelItems: AppGraphNode.Node[];\n};\n\n/**\n * Each workspace is an L1 tab.\n */\nexport const L1Tabs = ({ topLevelItems, currentItemId, onBack, open, path, unavailable }: L1TabsProps) => {\n // The current tab can name a workspace that is not in the graph, in which case it gets an item-less\n // panel carrying the unavailable message rather than no panel at all (a blank sidebar).\n const hasCurrentPanel = topLevelItems.some((item) => item.id === currentItemId && l0ItemType(item) === 'tab');\n return (\n <>\n {topLevelItems.map((item) => {\n const type = l0ItemType(item);\n if (type === 'tab') {\n return (\n <L1Panel\n key={item.id}\n id={item.id}\n item={item}\n path={path}\n open={open}\n onBack={onBack}\n isCurrent={item.id === currentItemId}\n />\n );\n }\n return null;\n })}\n {!hasCurrentPanel && (\n <L1Panel key={currentItemId} id={currentItemId} path={path} open={open} unavailable={unavailable} isCurrent />\n )}\n </>\n );\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { forwardRef, useMemo } from 'react';\n\nimport * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\nimport * as Hooks from '@dxos/app-toolkit/Hooks';\nimport * as GraphNode from '@dxos/graph/GraphNode';\nimport * as GraphHooks from '@dxos/plugin-graph/Hooks';\nimport { type MenuItem } from '@dxos/react-ui-menu';\nimport * as Tabs from '@dxos/react-ui/Tabs';\nimport * as Position from '@dxos/util/Position';\n\nimport { useLoadDescendents } from '#hooks';\n\nimport { useNavTreeContext } from '../NavTreeContext/index.ts';\nimport { L0Menu, L1Tabs, type L1TabsProps } from '../Sidebar/index.ts';\n\nexport const NAV_TREE_ITEM = 'NavTreeItem';\n\nexport type NavTreeProps = { id: string; root?: AppGraphNode.Node; tab: string } & Pick<\n L1TabsProps,\n 'open' | 'unavailable'\n>;\n\n// TODO(wittjosiah): Refactor to Radix-style.\nexport const NavTree = forwardRef<HTMLDivElement, NavTreeProps>(({ id, root, tab, ...props }, forwardedRef) => {\n const { onBack, onItemHover } = useNavTreeContext();\n const { topLevelActions, l0Items, pinnedItems, userAccountItem, topLevelItems } = useTopLevelNavItems(root);\n\n useLoadDescendents(root);\n const path = useMemo(() => [id], [id]);\n\n return (\n // TODO(thure): `Tabs.Root` forces all items that should be able to receive focus to use `Tabs.Tab(Primitive)` since\n // it uses RovingFocus and doesn't support moving focus to an item that is not a tab. Assess whether this situation\n // should change including whether it should motivate a change in the design/taxonomy, or if this means this should\n // not use `Tabs` at all.\n <Tabs.Root value={tab} orientation='vertical' classNames='relative' ref={forwardedRef}>\n <L0Menu\n menuActions={topLevelActions as MenuItem[]}\n topLevelItems={l0Items}\n pinnedItems={pinnedItems}\n userAccountItem={userAccountItem}\n path={path}\n parent={root}\n onItemHover={onItemHover}\n />\n <L1Tabs topLevelItems={topLevelItems} path={path} currentItemId={tab} onBack={onBack} {...props} />\n </Tabs.Root>\n );\n});\n\n/**\n * Partitions root children into workspaces, pinned items, user-account, and top-level actions.\n */\nconst useTopLevelNavItems = (root?: AppGraphNode.Node) => {\n const { graph } = Hooks.useAppGraph();\n const rootId = root?.id ?? GraphNode.RootId;\n const rootOutboundItems = GraphHooks.useConnections(graph, rootId, 'child');\n const rootActions = GraphHooks.useActions(graph, rootId);\n\n const { topLevelActions, l0Items, pinnedItems, userAccountItem } = useMemo(() => {\n const topLevelWorkspaces: AppGraphNode.Node[] = [];\n const outboundPinnedItems: AppGraphNode.Node[] = [];\n let userAccountItem: AppGraphNode.Node | undefined;\n for (const node of rootOutboundItems) {\n if (AppGraphNode.hasDisposition(node, 'workspace')) {\n topLevelWorkspaces.push(node);\n } else if (AppGraphNode.hasDisposition(node, 'pin-end')) {\n outboundPinnedItems.push(node);\n } else if (AppGraphNode.hasDisposition(node, 'user-account')) {\n userAccountItem ??= node;\n }\n }\n\n const topLevelActions = rootActions\n .filter((action) => AppGraphNode.hasDisposition(action, 'menu'))\n .toSorted((a, b) => Position.compare(a.properties, b.properties));\n const pinnedItems = [\n ...outboundPinnedItems,\n ...rootActions.filter((action) => AppGraphNode.hasDisposition(action, 'pin-end')),\n ].toSorted((a, b) => Position.compare(a.properties, b.properties));\n\n return {\n pinnedItems,\n topLevelActions,\n userAccountItem,\n l0Items: topLevelWorkspaces,\n };\n }, [rootActions, rootOutboundItems]);\n\n const topLevelItems = useMemo(\n () => [...l0Items, ...pinnedItems, ...(userAccountItem ? [userAccountItem] : [])],\n [l0Items, pinnedItems, userAccountItem],\n );\n\n return { topLevelActions, l0Items, pinnedItems, userAccountItem, topLevelItems };\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"L0Menu.d.ts","sourceRoot":"","sources":["../../../../../src/components/Sidebar/L0Menu.tsx"],"names":[],"mappings":"AAcA,OAAO,KAUN,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,KAAK,YAAY,MAAM,8BAA8B,CAAC;AAGlE,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAUhE,OAAO,KAAK,KAAK,IAAI,MAAM,qBAAqB,CAAC;AAuHjD,eAAO,MAAM,wBAAwB,mBAAoB,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,sBAOhF,CAAC;AAwHF,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,QAAQ,EAAE,CAAC;IACxB,aAAa,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC;IACnC,WAAW,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC;IACjC,eAAe,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;CAC7D,CAAC;AAEF,eAAO,MAAM,MAAM,6FAQhB,WAAW,sBAyGb,CAAC"}
1
+ {"version":3,"file":"L0Menu.d.ts","sourceRoot":"","sources":["../../../../../src/components/Sidebar/L0Menu.tsx"],"names":[],"mappings":"AAcA,OAAO,KAUN,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,KAAK,YAAY,MAAM,8BAA8B,CAAC;AAGlE,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAWhE,OAAO,KAAK,KAAK,IAAI,MAAM,qBAAqB,CAAC;AAuHjD,eAAO,MAAM,wBAAwB,mBAAoB,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,sBAOhF,CAAC;AAyHF,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,QAAQ,EAAE,CAAC;IACxB,aAAa,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC;IACnC,WAAW,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC;IACjC,eAAe,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;CAC7D,CAAC;AAEF,eAAO,MAAM,MAAM,6FAQhB,WAAW,sBAyGb,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"L1Panel.d.ts","sourceRoot":"","sources":["../../../../../src/components/Sidebar/L1Panel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAG1D,OAAO,KAAK,YAAY,MAAM,8BAA8B,CAAC;AAiC7D,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,qGAAqG;IACrG,IAAI,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC;IACzB,iGAAiG;IACjG,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,YAAY,6DAA8D,YAAY,sBA2D3F,CAAC;AAmLF,eAAO,MAAM,OAAO,gDAAqB,CAAC"}
1
+ {"version":3,"file":"L1Panel.d.ts","sourceRoot":"","sources":["../../../../../src/components/Sidebar/L1Panel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAG1D,OAAO,KAAK,YAAY,MAAM,8BAA8B,CAAC;AAkC7D,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,qGAAqG;IACrG,IAAI,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC;IACzB,iGAAiG;IACjG,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,YAAY,6DAA8D,YAAY,sBA4D3F,CAAC;AAmLF,eAAO,MAAM,OAAO,gDAAqB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"UserAccountAvatar.d.ts","sourceRoot":"","sources":["../../../../../src/components/UserAccountAvatar/UserAccountAvatar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAKhD,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,CAAC,EAAE,cAAc,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;IACvB,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,iBAAiB,gDAAiD,sBAAsB,sBA+BpG,CAAC"}
1
+ {"version":3,"file":"UserAccountAvatar.d.ts","sourceRoot":"","sources":["../../../../../src/components/UserAccountAvatar/UserAccountAvatar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAMhD,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,CAAC,EAAE,cAAc,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;IACvB,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,iBAAiB,gDAAiD,sBAAsB,sBA4BpG,CAAC"}