@dxos/react-ui-menu 0.10.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/index.mjs +747 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/translations.mjs +7 -0
- package/dist/lib/translations.mjs.map +1 -0
- package/dist/types/src/builder.d.ts +1 -1
- package/dist/types/src/builder.d.ts.map +1 -1
- package/dist/types/src/components/ActionLabel.d.ts +0 -2
- package/dist/types/src/components/ActionLabel.d.ts.map +1 -1
- package/dist/types/src/components/DropdownMenu.d.ts +2 -4
- package/dist/types/src/components/DropdownMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menu.d.ts +5 -15
- package/dist/types/src/components/Menu.d.ts.map +1 -1
- package/dist/types/src/components/MenuContext.d.ts +28 -0
- package/dist/types/src/components/MenuContext.d.ts.map +1 -0
- package/dist/types/src/components/ToolbarMenu.d.ts +2 -2
- package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
- package/dist/types/src/components/ToolbarMenu.stories.d.ts +2 -2
- package/dist/types/src/components/action-label.d.ts +7 -0
- package/dist/types/src/components/action-label.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +2 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useGraphMenuActions.d.ts +13 -1
- package/dist/types/src/hooks/useGraphMenuActions.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/presentation.d.ts +8 -0
- package/dist/types/src/presentation.d.ts.map +1 -0
- package/dist/types/src/toolbar.d.ts +6 -0
- package/dist/types/src/toolbar.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +1 -1
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +5 -3
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -20
- package/src/builder.ts +3 -3
- package/src/components/ActionLabel.tsx +1 -6
- package/src/components/DropdownMenu.tsx +30 -8
- package/src/components/Menu.stories.tsx +1 -1
- package/src/components/Menu.test.tsx +3 -2
- package/src/components/Menu.tsx +32 -122
- package/src/components/MenuContext.ts +129 -0
- package/src/components/ToolbarMenu.tsx +27 -13
- package/src/components/action-label.ts +20 -0
- package/src/components/index.ts +3 -0
- package/src/hooks/useGraphMenuActions.ts +16 -3
- package/src/index.ts +2 -0
- package/src/presentation.ts +19 -0
- package/src/toolbar.ts +11 -0
- package/src/types.ts +1 -1
- package/src/util.ts +2 -2
- package/dist/lib/browser/index.mjs +0 -797
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/translations.mjs +0 -16
- package/dist/lib/browser/translations.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -799
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/translations.mjs +0 -18
- package/dist/lib/node-esm/translations.mjs.map +0 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/components/MenuContext.ts","../../src/util.ts","../../src/components/action-label.ts","../../src/types.ts","../../src/components/ActionLabel.tsx","../../src/components/DropdownMenu.tsx","../../src/components/ToolbarMenu.tsx","../../src/components/Menu.tsx","../../src/presentation.ts","../../src/hooks/useMenuActions.ts","../../src/hooks/useGraphMenuActions.ts","../../src/builder.ts","../../src/toolbar.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Atom, useAtomValue } from '@effect-atom/atom-react';\nimport { type Scope, createContextScope } from '@radix-ui/react-context';\nimport { createContext, useMemo } from 'react';\n\nimport { log } from '@dxos/log';\n\nimport {\n type MenuContextValue,\n type MenuGroupContext,\n type MenuItem,\n type MenuItems,\n type MenuItemsAccessor,\n type MenuItemsMap,\n} from '../types';\n\n// Kept out of `Menu.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so contexts and hooks exported beside them force a full page reload on every edit.\n\n//\n// Scoped context.\n//\n\nexport type MenuScopedProps<P> = P & { __menuScope?: Scope };\n\nexport const MENU_NAME = 'Menu';\n\nexport const [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, []);\n\nconst nullItemsAtom = Atom.make<MenuItem[] | null>(null);\nconst defaultItemsAccessor: MenuItemsAccessor = () => nullItemsAtom;\n\nexport const menuContextDefaults: MenuContextValue = {\n iconSize: 5,\n items: defaultItemsAccessor,\n onAction: undefined,\n menuItemsAtom: Atom.make<MenuItemsMap>(new Map()),\n addMenuItems: () => {},\n removeMenuItems: () => {},\n};\n\nexport const [MenuContextProvider, useMenuScoped] = createMenuContext<MenuContextValue>(MENU_NAME, menuContextDefaults);\n\nexport const useMenuScope = createMenuScope();\n\n//\n// Dropdown context (internal) — allows Menu.Content to close the parent dropdown.\n//\n\nexport type MenuDropdownContextValue = {\n closeMenu: () => void;\n caller?: string;\n};\n\nexport const MenuDropdownContext = createContext<MenuDropdownContextValue>({\n closeMenu: () => {},\n});\n\n//\n// Item resolution.\n//\n\nconst sortMenuItems = (items: MenuItems[]) =>\n [...items].sort((a, b) => (a.priority !== b.priority ? a.priority - b.priority : a.id.localeCompare(b.id)));\n\nexport const resolveItems = (\n baseItems: MenuItem[] | null,\n group: MenuGroupContext | undefined,\n entries: ReadonlyMap<string, MenuItems>,\n): MenuItem[] | null => {\n const applicable = [...entries.values()].filter((entry) => !entry.groupFilter || entry.groupFilter(group));\n if (applicable.length === 0) {\n return baseItems;\n }\n\n const sorted = sortMenuItems(applicable);\n\n const replacements = sorted.filter((entry) => entry.mode === 'replacement');\n if (replacements.length > 0) {\n if (replacements.length > 1) {\n log.warn('multiple replacement entries found', {\n ids: replacements.map((r) => r.id).join(', '),\n using: replacements[0].id,\n });\n }\n return replacements[0].items;\n }\n\n const additive = sorted.filter((entry) => entry.mode === 'additive');\n const additiveItems = additive.flatMap((entry) => entry.items);\n\n if (!baseItems || baseItems.length === 0) {\n return additiveItems.length > 0 ? additiveItems : null;\n }\n\n return [...baseItems, ...additiveItems];\n};\n\n//\n// Public hooks.\n//\n\nexport const useMenuItems = (\n group?: MenuGroupContext,\n propsItems?: MenuItem[],\n consumerName: string = 'useMenuItemConsumer',\n __menuScope?: Scope,\n) => {\n const { items, menuItemsAtom } = useMenuScoped(consumerName, __menuScope);\n const groupItems = useAtomValue(items(group));\n const entries = useAtomValue(menuItemsAtom) ?? new Map();\n\n const baseItems = useMemo(() => propsItems ?? groupItems ?? null, [propsItems, groupItems]);\n\n const resolved = useMemo(\n () => resolveItems(baseItems, group, entries as ReadonlyMap<string, MenuItems>),\n [baseItems, group, entries],\n );\n\n return resolved ?? undefined;\n};\n\n/** Returns the menu context without Radix scope. */\nexport const useMenu = (consumerName: string): MenuContextValue => {\n return useMenuScoped(consumerName, undefined);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Node } from '@dxos/app-graph';\nimport { EffectEx } from '@dxos/effect';\nimport { type MenuActionProperties, type MenuItemGroupProperties } from '@dxos/ui-types';\nimport { getHostPlatform } from '@dxos/util';\n\nimport { type MenuAction, type MenuItemGroup, type MenuSeparator } from './types';\n\n/**\n * Execute a menu action's Effect with its captured context.\n * This provides the `_actionContext` layer if available.\n */\nexport const executeMenuAction = async (action: MenuAction, params: Node.InvokeProps = {}): Promise<void> => {\n let effect = action.data(params);\n\n // Provide captured action context if available.\n if (action._actionContext) {\n effect = effect.pipe(Effect.provide(action._actionContext));\n }\n\n await EffectEx.runAndForwardErrors(effect);\n};\n\nexport const getShortcut = (action: Node.ActionLike) => {\n return typeof action.properties?.keyBinding === 'string'\n ? action.properties.keyBinding\n : action.properties?.keyBinding?.[getHostPlatform()];\n};\n\nexport const fallbackIcon = 'ph--circle-dashed--regular';\n\nexport const createMenuAction = <P extends {} = {}>(\n id: string,\n invoke: (params?: Node.InvokeProps) => void,\n properties: P & MenuActionProperties,\n) =>\n ({\n id,\n type: Node.ActionType,\n properties,\n data: (params?: Node.InvokeProps) => Effect.sync(() => invoke(params)),\n }) satisfies MenuAction;\n\nexport const createMenuItemGroup = <P extends MenuItemGroupProperties>(id: string, properties: P) =>\n ({\n id,\n type: Node.ActionGroupType,\n properties,\n data: Node.actionGroupSymbol,\n }) satisfies MenuItemGroup;\n\nexport const createGapSeparator = (id: string = 'gap', source: string = 'root') => ({\n nodes: [\n {\n id,\n type: '@dxos/react-ui-toolbar/separator',\n properties: { variant: 'gap' },\n data: undefined as never,\n } satisfies MenuSeparator,\n ],\n edges: [\n {\n source,\n target: id,\n relation: 'child' as const,\n },\n ],\n});\n\nexport const createLineSeparator = (id: string = 'line', source: string = 'root') => ({\n nodes: [\n {\n id,\n type: '@dxos/react-ui-toolbar/separator',\n properties: { variant: 'line' },\n data: undefined as never,\n } satisfies MenuSeparator,\n ],\n edges: [{ source, target: id, relation: 'child' as const }],\n});\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Node } from '@dxos/app-graph';\nimport { keySymbols } from '@dxos/keyboard';\nimport { type TFunction, toLocalizedString } from '@dxos/react-ui';\nimport { type MenuActionProperties, type MenuItemChrome } from '@dxos/ui-types';\n\nimport { getShortcut } from '../util';\n\ntype Action = Node.Action<MenuActionProperties> | Node.ActionGroup<MenuItemChrome>;\n\n// Kept out of `ActionLabel.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so a value exported beside them forces a full page reload on every edit.\n\nexport const actionLabel = (action: Action, t: TFunction) => {\n const shortcut = getShortcut(action);\n return `${toLocalizedString(action.properties!.label, t)}${shortcut ? ` (${keySymbols(shortcut).join('')})` : ''}`;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Atom } from '@effect-atom/atom';\n\nimport { Node } from '@dxos/app-graph';\nimport { type IconButtonProps, type ToolbarSeparatorProps } from '@dxos/react-ui';\nimport { type MenuActionProperties } from '@dxos/ui-types';\n\nexport type MenuAction<P extends {} = {}> = Node.Action<P & MenuActionProperties>;\n\nexport const MenuSeparatorType = '@dxos/react-ui-toolbar/separator' as const;\n\nexport type MenuSeparator = Node.Node<never, Pick<ToolbarSeparatorProps, 'variant'>> & {\n type: typeof MenuSeparatorType;\n};\n\nexport const isSeparator = (node: Node.Node): node is MenuSeparator => node.type === MenuSeparatorType;\n\nexport type MenuItemGroup<P extends Record<string, any> = Record<string, any>> = Node.ActionGroup<P>;\n\nexport const isMenuGroup = (node: Node.Node): node is MenuItemGroup => node.type === Node.ActionGroupType;\n\n/** Graph-sourced menu nodes carry plugin-specific properties validated at runtime. */\nexport type GraphMenuItem = Node.Action | Node.ActionGroup;\n\nexport type MenuItem = MenuSeparator | MenuAction | MenuItemGroup | GraphMenuItem;\n\n/** Group context for graph-backed dropdown menus (any graph node, not only action groups). */\nexport type MenuGroupContext = MenuItemGroup | Node.Node;\n\n/** Atom-family-style accessor: returns an atom of items for a given group (or root when undefined). */\nexport type MenuItemsAccessor = (group?: MenuGroupContext) => Atom.Atom<MenuItem[] | null>;\n\nexport type ActionExecutor = (action: MenuAction, params: Node.InvokeProps) => void;\n\nexport type MenuItemsMode = 'additive' | 'replacement';\n\nexport type AddMenuItemsProps = {\n id: string;\n mode: MenuItemsMode;\n priority?: number;\n items: MenuItem[];\n groupFilter?: (group?: MenuGroupContext) => boolean;\n};\n\nexport type MenuItems = Omit<AddMenuItemsProps, 'priority'> & { priority: number };\nexport type MenuItemsMap = Map<string, MenuItems>;\n\nexport type MenuContextValue = {\n /** Atom-family accessor for base menu items, keyed by group (similar to Tree model). */\n items: MenuItemsAccessor;\n iconSize: IconButtonProps['size'];\n attendableId?: string;\n /** TODO(burdon): Remove and assume always active if attendableId is undefined. */\n /** If true, the menu is always active regardless of attention state. */\n alwaysActive?: boolean;\n /** Atom holding the current set of imperatively added menu items. */\n menuItemsAtom: Atom.Atom<MenuItemsMap>;\n /** Imperatively add menu items to the nearest MenuProvider. */\n addMenuItems: (props: AddMenuItemsProps) => void;\n /** Remove previously added menu items by id. */\n removeMenuItems: (id: string) => void;\n /** Optional action executor. If provided, will be used instead of default execution. */\n onAction?: ActionExecutor;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { type Node } from '@dxos/app-graph';\nimport { keySymbols } from '@dxos/keyboard';\nimport { toLocalizedString, useTranslation } from '@dxos/react-ui';\nimport { mx } from '@dxos/ui-theme';\nimport { type MenuActionProperties, type MenuItemChrome } from '@dxos/ui-types';\n\nimport { translationKey } from '#translations';\n\nimport { getShortcut } from '../util';\n\ntype Action = Node.Action<MenuActionProperties> | Node.ActionGroup<MenuItemChrome>;\n\nexport const ActionLabel = ({ action }: { action: Action }) => {\n const { t } = useTranslation(translationKey);\n const shortcut = getShortcut(action);\n return (\n <>\n <span className='grow truncate'>{toLocalizedString(action.properties!.label, t)}</span>\n {shortcut && <span className={mx('shrink-0', 'text-description')}>{keySymbols(shortcut).join('')}</span>}\n </>\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport React, { type MouseEvent, useCallback } from 'react';\n\nimport { type DropdownMenuRootProps, Icon, DropdownMenu as NaturalDropdownMenu } from '@dxos/react-ui';\nimport { mx } from '@dxos/ui-theme';\n\nimport { type MenuAction, type MenuItem, type MenuItemGroup, isSeparator } from '../types';\nimport { executeMenuAction } from '../util';\nimport { ActionLabel } from './ActionLabel';\nimport { type MenuScopedProps, useMenuItems, useMenuScoped } from './MenuContext';\n\nexport type DropdownMenuProps = DropdownMenuRootProps & {\n group?: MenuItemGroup;\n items?: MenuItem[];\n caller?: string;\n};\n\nconst DropdownMenuItem = ({\n item,\n group,\n onClick,\n __menuScope,\n}: MenuScopedProps<{\n item: MenuItem;\n group?: MenuItemGroup;\n onClick: (action: MenuAction, event: MouseEvent) => void;\n}>) => {\n // TODO(thure): handle other items.\n const action = item as MenuAction;\n const handleClick = useCallback((event: MouseEvent) => onClick(action, event), [action, onClick]);\n const { iconSize } = useMenuScoped('DropdownMenuItem', __menuScope);\n // An item that declares `checked` is a select-group member: expose the checked role + state to AT so\n // the current value is announced, not conveyed by the trailing check icon alone. Mutually-exclusive\n // (single-select) groups use radio semantics; multi-select groups use checkbox.\n const checkable = typeof action.properties?.checked === 'boolean';\n const role = group?.properties?.selectCardinality === 'multiple' ? 'menuitemcheckbox' : 'menuitemradio';\n return (\n <NaturalDropdownMenu.Item\n onClick={handleClick}\n classNames='gap-2'\n disabled={action.properties?.disabled}\n {...(checkable && { role, 'aria-checked': !!action.properties?.checked })}\n {...(action.properties?.testId && { 'data-testid': action.properties.testId })}\n >\n {action.properties?.icon && (\n <Icon\n icon={action.properties.icon}\n size={iconSize}\n classNames={mx(action.properties.spin && 'animate-spin', action.properties.iconClassNames)}\n />\n )}\n <ActionLabel action={action} />\n {/* Trailing check marks the current value of a single-select group (`checked`). */}\n {action.properties?.checked && <Icon icon='ph--check--regular' size={iconSize} classNames='mis-auto' />}\n </NaturalDropdownMenu.Item>\n );\n};\n\nconst DropdownMenuRoot = ({\n items: propsItems,\n group,\n open,\n defaultOpen,\n onOpenChange,\n caller,\n children,\n __menuScope,\n ...naturalProps\n}: MenuScopedProps<DropdownMenuProps>) => {\n const [optionsMenuOpen, setOptionsMenuOpen] = useControllableState({\n prop: open,\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n });\n\n const { onAction } = useMenuScoped('DropdownMenuRoot', __menuScope);\n\n const handleActionClick = useCallback(\n (action: MenuAction, event: MouseEvent) => {\n if (action.properties?.disabled) {\n return;\n }\n event.stopPropagation();\n // TODO(thure): Why does Dialog's modal-ness cause issues if we don't explicitly close the menu here?\n setOptionsMenuOpen(false);\n const params = { parent: group, caller, modifiers: { shift: event.shiftKey } };\n if (onAction) {\n onAction(action, params);\n } else {\n void executeMenuAction(action, params);\n }\n },\n [group, caller, onAction],\n );\n\n const items = useMenuItems(group, propsItems);\n\n return (\n <NaturalDropdownMenu.Root open={optionsMenuOpen} onOpenChange={setOptionsMenuOpen} {...naturalProps}>\n {children}\n <NaturalDropdownMenu.Portal>\n <NaturalDropdownMenu.Content>\n <NaturalDropdownMenu.Viewport>\n {items?.map((item) =>\n isSeparator(item) ? (\n <NaturalDropdownMenu.Separator key={item.id} />\n ) : (\n <DropdownMenuItem key={item.id} item={item} group={group} onClick={handleActionClick} />\n ),\n )}\n </NaturalDropdownMenu.Viewport>\n <NaturalDropdownMenu.Arrow />\n </NaturalDropdownMenu.Content>\n </NaturalDropdownMenu.Portal>\n </NaturalDropdownMenu.Root>\n );\n};\n\nexport const DropdownMenu = {\n Root: DropdownMenuRoot,\n Trigger: NaturalDropdownMenu.Trigger,\n VirtualTrigger: NaturalDropdownMenu.VirtualTrigger,\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useRef, useState } from 'react';\n\nimport {\n Input,\n Toolbar as NaturalToolbar,\n type ToolbarRootProps,\n Tooltip,\n toLocalizedString,\n useTranslation,\n} from '@dxos/react-ui';\nimport { composable, composableProps } from '@dxos/react-ui';\nimport { useAttention } from '@dxos/react-ui-attention';\nimport { mx } from '@dxos/ui-theme';\nimport { type DropdownMenuItemGroupProperties, type ToggleGroupMenuItemGroupProperties } from '@dxos/ui-types';\n\nimport { translationKey } from '#translations';\n\nimport { type MenuAction, type MenuItem, type MenuItemGroup, isMenuGroup, isSeparator } from '../types';\nimport { executeMenuAction } from '../util';\nimport { actionLabel } from './action-label';\nimport { ActionLabel } from './ActionLabel';\nimport { DropdownMenu } from './DropdownMenu';\nimport { type MenuScopedProps, useMenuItems, useMenuScoped } from './MenuContext';\n\nexport type ToolbarMenuDropdownMenuActionGroup = DropdownMenuItemGroupProperties;\n\nexport type ToolbarMenuToggleGroupActionGroup = ToggleGroupMenuItemGroupProperties;\n\nexport type ToolbarMenuActionGroupProperties = DropdownMenuItemGroupProperties | ToggleGroupMenuItemGroupProperties;\n\nexport type ToolbarMenuProps = ToolbarRootProps;\n\nexport type ToolbarMenuActionGroupProps = {\n group: MenuItemGroup<ToolbarMenuActionGroupProperties>;\n items?: MenuItem[];\n};\n\nexport type ToolbarMenuDropdownGroupProps = {\n group: MenuItemGroup<DropdownMenuItemGroupProperties>;\n items?: MenuItem[];\n};\n\nexport type ToolbarMenuToggleGroupProps = {\n group: MenuItemGroup<ToggleGroupMenuItemGroupProperties>;\n items?: MenuItem[];\n};\n\nexport type ToolbarMenuActionProps = {\n group: MenuItemGroup<ToggleGroupMenuItemGroupProperties>;\n action: MenuAction;\n};\n\nconst ActionToolbarItem = ({ __menuScope, action }: MenuScopedProps<{ action: MenuAction }>) => {\n const { iconSize, onAction } = useMenuScoped('ActionToolbarItem', __menuScope);\n const { t } = useTranslation(translationKey);\n const [pending, setPending] = useState(false);\n const pendingRef = useRef(false);\n\n const { icon, iconOnly = true, disabled, testId, hidden, classNames, iconClassNames, spin } = action.properties;\n const buttonVariant = action.properties.variant === 'primary' ? ('primary' as const) : ('ghost' as const);\n\n const handleClick = useCallback(() => {\n if (pendingRef.current) {\n return;\n }\n pendingRef.current = true;\n setPending(true);\n const done = () => {\n pendingRef.current = false;\n setPending(false);\n };\n if (onAction) {\n Promise.resolve(onAction(action, {})).then(done, done);\n } else {\n executeMenuAction(action).then(done, done);\n }\n }, [action, onAction]);\n\n const commonProps = {\n variant: buttonVariant,\n disabled: disabled || pending,\n classNames,\n onClick: handleClick,\n ...(testId && { 'data-testid': testId }),\n };\n\n if (hidden) {\n return null;\n }\n\n return icon ? (\n <NaturalToolbar.IconButton\n key={action.id}\n {...commonProps}\n icon={icon}\n size={iconSize}\n iconOnly={iconOnly}\n iconClassNames={mx(spin && 'animate-spin', iconClassNames)}\n label={actionLabel(action, t)}\n />\n ) : (\n <NaturalToolbar.Button key={action.id} {...commonProps}>\n <ActionLabel action={action} />\n </NaturalToolbar.Button>\n );\n};\n\nconst SwitchToolbarItem = ({ __menuScope, action }: MenuScopedProps<{ action: MenuAction }>) => {\n const { onAction } = useMenuScoped('SwitchToolbarItem', __menuScope);\n const { t } = useTranslation(translationKey);\n const { label, iconOnly, disabled, testId, hidden, checked } = action.properties;\n const labelStr = toLocalizedString(label, t);\n\n const handleCheckedChange = useCallback(() => {\n if (onAction) {\n onAction(action, {});\n } else {\n void executeMenuAction(action);\n }\n }, [action, onAction]);\n\n if (hidden) {\n return null;\n }\n\n const switchInput = (\n <Input.Switch\n checked={checked}\n disabled={disabled}\n aria-label={iconOnly ? labelStr : undefined}\n onCheckedChange={handleCheckedChange}\n {...(testId && { 'data-testid': testId })}\n />\n );\n\n return (\n <Input.Root>\n {iconOnly ? (\n <Tooltip.Trigger asChild content={labelStr}>\n <Input.Block>{switchInput}</Input.Block>\n </Tooltip.Trigger>\n ) : (\n <Input.Block>{switchInput}</Input.Block>\n )}\n {!iconOnly && <Input.Label>{labelStr}</Input.Label>}\n </Input.Root>\n );\n};\n\nconst DropdownMenuToolbarItem = ({\n __menuScope,\n group,\n items: propsItems,\n}: MenuScopedProps<ToolbarMenuDropdownGroupProps>) => {\n const { t } = useTranslation(translationKey);\n const { iconSize } = useMenuScoped('DropdownMenuToolbarItem', __menuScope);\n const items = useMenuItems(group, propsItems, 'DropdownMenuToolbarItem', __menuScope);\n const {\n iconOnly,\n disabled,\n testId,\n applyActive,\n caretDown = true,\n icon: groupIcon,\n iconClassNames: groupIconClassNames,\n spin: groupSpin,\n } = group.properties;\n const activeItem = items?.find((item) => !!(item as MenuAction).properties.checked) as MenuAction | undefined;\n const icon =\n (applyActive &&\n // TODO(thure): Handle other menu item types.\n activeItem?.properties.icon) ||\n groupIcon;\n // Follow the same `applyActive` rule for `iconClassNames` so a per-item accent (e.g. tag colour) tracks the displayed icon.\n const iconClassNames = (applyActive && activeItem?.properties.iconClassNames) || groupIconClassNames;\n const spin = (applyActive && activeItem?.properties.spin) || groupSpin;\n const labelAction = applyActive && activeItem ? activeItem : group;\n\n return (\n <DropdownMenu.Root group={group} items={items}>\n <DropdownMenu.Trigger asChild>\n {icon ? (\n <NaturalToolbar.IconButton\n variant='ghost'\n disabled={disabled}\n icon={icon}\n size={iconSize}\n iconOnly={iconOnly}\n iconClassNames={mx(spin && 'animate-spin', iconClassNames)}\n label={actionLabel(labelAction, t)}\n caretDown={caretDown}\n {...(testId && { 'data-testid': testId })}\n />\n ) : (\n <NaturalToolbar.Button\n variant='ghost'\n disabled={disabled}\n caretDown={caretDown}\n {...(testId && { 'data-testid': testId })}\n >\n <ActionLabel action={labelAction} />\n </NaturalToolbar.Button>\n )}\n </DropdownMenu.Trigger>\n </DropdownMenu.Root>\n );\n};\n\nconst ToggleGroupItem = ({ __menuScope, group, action }: MenuScopedProps<ToolbarMenuActionProps>) => {\n const { iconSize, onAction } = useMenuScoped('ToggleGroupItem', __menuScope);\n const { t } = useTranslation(translationKey);\n const { icon, iconOnly = true, disabled, testId, hidden, classNames, iconClassNames, spin } = action.properties;\n\n const handleClick = useCallback(() => {\n if (onAction) {\n onAction(action, { parent: group });\n } else {\n void executeMenuAction(action, { parent: group });\n }\n }, [action, group, onAction]);\n\n const commonProps = {\n value: action.id,\n disabled,\n variant: 'ghost' as const,\n classNames,\n onClick: handleClick,\n ...(testId && { 'data-testid': testId }),\n };\n\n return hidden ? null : icon ? (\n <NaturalToolbar.ToggleGroupIconItem\n {...commonProps}\n icon={icon}\n size={iconSize}\n iconOnly={iconOnly}\n iconClassNames={mx(spin && 'animate-spin', iconClassNames)}\n label={actionLabel(action, t)}\n />\n ) : (\n <NaturalToolbar.ToggleGroupItem {...commonProps}>\n <ActionLabel action={action} />\n </NaturalToolbar.ToggleGroupItem>\n );\n};\n\nconst ToggleGroupToolbarItem = ({\n __menuScope,\n group,\n items: itemsProp,\n}: MenuScopedProps<ToolbarMenuToggleGroupProps>) => {\n const items = useMenuItems(group, itemsProp, 'ToggleGroupToolbarItem', __menuScope);\n const { selectCardinality } = group.properties;\n\n // TODO(thure): Handle other menu item types.\n const children = (items as MenuAction[]).map((action) => (\n <ToggleGroupItem key={action.id} group={group} action={action} />\n ));\n\n if (selectCardinality === 'multiple') {\n return (\n <NaturalToolbar.ToggleGroup type='multiple' value={group.properties.value}>\n {children}\n </NaturalToolbar.ToggleGroup>\n );\n } else {\n return (\n <NaturalToolbar.ToggleGroup type='single' value={group.properties.value}>\n {children}\n </NaturalToolbar.ToggleGroup>\n );\n }\n};\n\nexport const ToolbarMenu = composable<HTMLDivElement, MenuScopedProps<ToolbarMenuProps>>(\n ({ __menuScope, children, ...props }, forwardedRef) => {\n const items = useMenuItems(undefined, undefined, 'ToolbarMenu', __menuScope);\n const { attendableId, alwaysActive } = useMenuScoped('ToolbarMenu', __menuScope);\n const { hasAttention } = useAttention(attendableId);\n\n return (\n <NaturalToolbar.Root\n {...composableProps(props, { classNames: attendableId })}\n disabled={!alwaysActive && !hasAttention}\n ref={forwardedRef}\n >\n {items?.map((item: MenuItem) => (\n <ToolbarMenuItem key={item.id} __menuScope={__menuScope} item={item} />\n ))}\n {children}\n </NaturalToolbar.Root>\n );\n },\n);\n\nconst ToolbarMenuItem = ({ __menuScope, item }: MenuScopedProps<{ item: MenuItem }>) => {\n if (isSeparator(item)) {\n return <NaturalToolbar.Separator variant={item.properties.variant} />;\n }\n\n if (isMenuGroup(item)) {\n if (item.properties.variant === 'dropdownMenu') {\n return (\n <DropdownMenuToolbarItem\n __menuScope={__menuScope}\n group={item as MenuItemGroup<DropdownMenuItemGroupProperties>}\n />\n );\n }\n\n return (\n <ToggleGroupToolbarItem\n __menuScope={__menuScope}\n group={item as MenuItemGroup<ToggleGroupMenuItemGroupProperties>}\n />\n );\n }\n\n const action = item as MenuAction;\n if (action.properties?.variant === 'switch') {\n return <SwitchToolbarItem __menuScope={__menuScope} action={action} />;\n }\n\n // The contributor owns the rendered element (interactions the action model cannot express).\n if (action.properties?.variant === 'custom' && action.properties.render) {\n return <>{action.properties.render()}</>;\n }\n\n return <ActionToolbarItem __menuScope={__menuScope} action={action} />;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { Atom, RegistryContext } from '@effect-atom/atom-react';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport React, { type MouseEvent, type PropsWithChildren, useCallback, useContext, useMemo } from 'react';\n\nimport { type DropdownMenuRootProps, Icon, DropdownMenu as NaturalDropdownMenu } from '@dxos/react-ui';\nimport { mx } from '@dxos/ui-theme';\n\nimport {\n type AddMenuItemsProps,\n type MenuAction,\n type MenuContextValue,\n type MenuGroupContext,\n type MenuItem,\n type MenuItemsMap,\n isSeparator,\n} from '../types';\nimport { executeMenuAction } from '../util';\nimport { ActionLabel } from './ActionLabel';\nimport {\n MenuContextProvider,\n MenuDropdownContext,\n type MenuScopedProps,\n menuContextDefaults,\n useMenuItems,\n useMenuScope,\n useMenuScoped,\n} from './MenuContext';\nimport { ToolbarMenu } from './ToolbarMenu';\n\n//\n// MenuProvider (internal) — the context provider used by Menu.Root.\n//\n\nconst DEFAULT_PRIORITY = 100;\n\ntype MenuProviderProps = PropsWithChildren<Partial<MenuContextValue>>;\n\nconst MenuProvider = ({\n children,\n items = menuContextDefaults.items,\n iconSize = menuContextDefaults.iconSize,\n attendableId,\n alwaysActive,\n onAction,\n}: MenuProviderProps) => {\n const { scope } = useMenuScope(undefined);\n const registry = useContext(RegistryContext);\n const menuItemsAtom = useMemo(() => Atom.make<MenuItemsMap>(new Map()).pipe(Atom.keepAlive), []);\n\n const addMenuItems = useCallback(\n (props: AddMenuItemsProps) => {\n const priority = props.priority ?? DEFAULT_PRIORITY;\n const prev = registry.get(menuItemsAtom);\n const next = new Map(prev);\n next.set(props.id, { ...props, priority });\n registry.set(menuItemsAtom, next);\n },\n [registry, menuItemsAtom],\n );\n\n const removeMenuItems = useCallback(\n (id: string) => {\n const prev = registry.get(menuItemsAtom);\n const next = new Map(prev);\n next.delete(id);\n registry.set(menuItemsAtom, next);\n },\n [registry, menuItemsAtom],\n );\n\n return (\n <MenuContextProvider\n items={items}\n iconSize={iconSize}\n attendableId={attendableId}\n alwaysActive={alwaysActive}\n menuItemsAtom={menuItemsAtom}\n addMenuItems={addMenuItems}\n removeMenuItems={removeMenuItems}\n onAction={onAction}\n scope={scope}\n >\n {children}\n </MenuContextProvider>\n );\n};\n\n//\n// Menu.Root\n//\n\ntype MenuRootProps = MenuProviderProps &\n Pick<DropdownMenuRootProps, 'children' | 'open' | 'defaultOpen' | 'onOpenChange'> & {\n /** Identifies the component that owns this menu (passed to action handlers). */\n caller?: string;\n };\n\n/**\n * Menu context boundary.\n *\n * NOTE: This component is headless since it's root div has `contents`.\n *\n * Provides the menu context (action dispatch, contribution registry, icon size, etc.)\n * and an optional dropdown root for use with `Menu.Trigger` + `Menu.Content`.\n */\nconst MenuRoot = ({ children, open, defaultOpen, onOpenChange, caller, ...props }: MenuRootProps) => {\n const [menuOpen, setMenuOpen] = useControllableState({\n prop: open,\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n });\n\n const closeMenu = useCallback(() => setMenuOpen(false), [setMenuOpen]);\n\n return (\n <MenuProvider {...props}>\n <MenuDropdownContext.Provider value={{ closeMenu, caller }}>\n <NaturalDropdownMenu.Root open={menuOpen} onOpenChange={setMenuOpen}>\n {children}\n </NaturalDropdownMenu.Root>\n </MenuDropdownContext.Provider>\n </MenuProvider>\n );\n};\n\n//\n// Menu.Content\n//\n\ntype MenuContentProps = {\n group?: MenuGroupContext;\n items?: MenuItem[];\n caller?: string;\n};\n\nconst MenuContentItem = ({\n item,\n onClick,\n __menuScope,\n}: MenuScopedProps<{\n item: MenuItem;\n onClick: (action: MenuAction, event: MouseEvent) => void;\n}>) => {\n const action = item as MenuAction;\n const handleClick = useCallback((event: MouseEvent) => onClick(action, event), [action, onClick]);\n const { iconSize } = useMenuScoped('MenuContentItem', __menuScope);\n return (\n <NaturalDropdownMenu.Item\n onClick={handleClick}\n classNames='gap-2'\n disabled={action.properties?.disabled}\n {...(action.properties?.testId && { 'data-testid': action.properties.testId })}\n >\n {action.properties?.icon && (\n <Icon\n icon={action.properties.icon}\n size={iconSize}\n classNames={mx(action.properties.spin && 'animate-spin', action.properties.iconClassNames)}\n />\n )}\n <ActionLabel action={action} />\n </NaturalDropdownMenu.Item>\n );\n};\n\n/**\n * Renders the dropdown menu portal, content, and graph-backed items.\n *\n * Must be a descendant of `Menu.Root`. Reads items via `useMenuItems` from the\n * nearest menu context, with optional `group`/`items` prop overrides.\n */\nconst MenuContent = ({\n group,\n items: propsItems,\n caller: callerOverride,\n __menuScope,\n}: MenuScopedProps<MenuContentProps>) => {\n const { closeMenu, caller: contextCaller } = useContext(MenuDropdownContext);\n const caller = callerOverride ?? contextCaller;\n const { onAction } = useMenuScoped('MenuContent', __menuScope);\n const resolvedItems = useMenuItems(group, propsItems, 'MenuContent', __menuScope);\n\n const handleActionClick = useCallback(\n (action: MenuAction, event: MouseEvent) => {\n if (action.properties?.disabled) {\n return;\n }\n event.stopPropagation();\n closeMenu();\n const params = { parent: group, caller, modifiers: { shift: event.shiftKey } };\n if (onAction) {\n onAction(action, params);\n } else {\n void executeMenuAction(action, params);\n }\n },\n [group, caller, onAction, closeMenu],\n );\n\n return (\n <NaturalDropdownMenu.Portal>\n <NaturalDropdownMenu.Content>\n <NaturalDropdownMenu.Viewport>\n {resolvedItems?.map((item) =>\n isSeparator(item) ? (\n <NaturalDropdownMenu.Separator key={item.id} />\n ) : (\n <MenuContentItem key={item.id} item={item} onClick={handleActionClick} />\n ),\n )}\n </NaturalDropdownMenu.Viewport>\n <NaturalDropdownMenu.Arrow />\n </NaturalDropdownMenu.Content>\n </NaturalDropdownMenu.Portal>\n );\n};\n\n//\n// Namespace.\n//\n\n/**\n * Primary namespace export for the menu system.\n *\n * - `Menu.Root` — context boundary (replaces `MenuProvider`); also provides a dropdown root.\n * - `Menu.Trigger` / `Menu.VirtualTrigger` — dropdown trigger (use with `Menu.Content`).\n * - `Menu.Content` — renders graph-backed dropdown items inside a portal.\n * - `Menu.Toolbar` — flat toolbar component with graph-backed item rendering.\n */\nconst Menu = {\n Root: MenuRoot,\n Trigger: NaturalDropdownMenu.Trigger,\n Content: MenuContent,\n VirtualTrigger: NaturalDropdownMenu.VirtualTrigger,\n Toolbar: ToolbarMenu,\n};\n\nexport { Menu };\n\nexport type { MenuContentProps, MenuRootProps };\n\nexport type {\n ToolbarMenuActionGroupProperties,\n ToolbarMenuActionGroupProps,\n ToolbarMenuActionProps,\n ToolbarMenuDropdownMenuActionGroup,\n ToolbarMenuProps,\n ToolbarMenuToggleGroupActionGroup,\n} from './ToolbarMenu';\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type Node } from '@dxos/app-graph';\nimport { type MenuActionProperties } from '@dxos/ui-types';\n\n/**\n * Merges an action's `presentation[surface]` chrome override (if any) into its properties, letting a\n * single action declare multiple dispositions yet render appropriately in each surface — e.g. a\n * primary toolbar button and a plain nav-tree row from the same definition.\n */\nexport const applyPresentation = <A extends Node.ActionLike>(action: A, surface: string): A => {\n const presentation = (action.properties as MenuActionProperties).presentation?.[surface];\n if (!presentation) {\n return action;\n }\n return { ...action, properties: { ...action.properties, ...presentation } };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { Atom, RegistryContext, useAtomValue } from '@effect-atom/atom-react';\nimport { type DependencyList, useCallback, useContext, useMemo } from 'react';\n\nimport { Graph, Node } from '@dxos/app-graph';\n\nimport { type MenuItem, type MenuItemGroup, type MenuItemsAccessor } from '../types';\n\nexport type ActionGraphNodes = Node.NodeArg<any>[];\nexport type ActionGraphEdges = Graph.Edge[];\nexport type ActionGraphProps = {\n nodes: ActionGraphNodes;\n edges: ActionGraphEdges;\n};\n\nexport type MenuActions = {\n items: MenuItemsAccessor;\n};\n\nexport const useMenuActions = (props: Atom.Atom<ActionGraphProps>): MenuActions => {\n const registry = useContext(RegistryContext);\n const menuGraphProps = useAtomValue(props);\n\n // Create a new graph whenever props change to preserve correct order.\n // (Graph.addEdges appends rather than replaces, which breaks ordering on updates.)\n // NOTE: Using useMemo rather than a ref-mutation pattern to avoid calling registry.set during render,\n // which would trigger atom state updates in other components (setState-in-render React warning).\n const graph = useMemo(() => {\n const newGraph = Graph.make({ registry });\n newGraph.pipe(Graph.addNodes(menuGraphProps.nodes as Node.NodeArg<any>[]), Graph.addEdges(menuGraphProps.edges));\n return newGraph;\n }, [registry, menuGraphProps]);\n\n const items: MenuItemsAccessor = useCallback(\n (group?: MenuItemGroup) => {\n // TODO(wittjosiah): Migrate to using action relation instead of child.\n return graph.connections(group?.id || Node.RootId, 'child') as Atom.Atom<MenuItem[] | null>;\n },\n [graph],\n );\n\n return { items };\n};\n\n/**\n * Convenience wrapper around `useMenuActions` that creates the backing atom inline.\n * Pass a builder thunk and a dependency list — the hook memoizes `Atom.make(build)` and threads\n * it through `useMenuActions`. Saves the `useMemo(() => Atom.make(...), deps)` boilerplate when\n * the action graph is composed from local state (e.g. a toolbar driven by component state).\n *\n * Read reactive state via `get` inside the builder; `deps` should hold only stable references.\n */\nexport const useMenuBuilder = (build: (get: Atom.Context) => ActionGraphProps, deps: DependencyList): MenuActions => {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const atom = useMemo(() => Atom.make(build), deps);\n return useMenuActions(atom);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { Atom } from '@effect-atom/atom';\nimport { useMemo } from 'react';\n\nimport { type Graph, Node } from '@dxos/app-graph';\n\nimport { applyPresentation } from '../presentation';\nimport {\n type ActionGraphEdges,\n type ActionGraphNodes,\n type ActionGraphProps,\n type MenuActions,\n useMenuActions,\n} from './useMenuActions';\n\nexport type GraphMenuOptions = {\n /** Group the actions descend from. Defaults to the menu root (top-level toolbar items). */\n rootId?: string;\n /** Keep only the actions the predicate accepts (e.g. by `disposition`). */\n filter?: (action: Node.ActionLike) => boolean;\n /**\n * Disposition key this surface renders — when set, each action's `presentation[surface]` chrome\n * override (if any) is merged into its properties, letting one action multi-target dispositions\n * (e.g. `['toolbar', 'list-item']`) with per-surface chrome.\n */\n surface?: string;\n};\n\n/**\n * Flatten a node's contributed actions (and nested {@link Node.ActionGroup}s) into the\n * `{ nodes, edges }` an {@link useMenuActions} / `Menu` consumes. The action nodes are spliced\n * verbatim, so their Effect `data` (and captured `_actionContext`) execute via `executeMenuAction`\n * without any `onAction` wiring.\n *\n * Pure over a `resolve` function so it is testable without a live graph; `resolve(id)` returns the\n * direct actions for `id` (a node id at the top level, a group id when expanding a group).\n */\nexport const buildGraphMenu = (\n resolve: (id: string) => Node.ActionLike[],\n nodeId: string,\n options: GraphMenuOptions = {},\n): ActionGraphProps => {\n const { rootId = Node.RootId, filter, surface } = options;\n const nodes: ActionGraphNodes = [];\n const edges: ActionGraphEdges = [];\n const seen = new Set<string>();\n\n const visit = (parentId: string, sourceId: string) => {\n for (const action of resolve(sourceId)) {\n if (filter && !filter(action)) {\n continue;\n }\n // Always record the parent→child edge (a shared action may sit under multiple groups).\n edges.push({ source: parentId, target: action.id, relation: 'child' });\n if (seen.has(action.id)) {\n continue;\n }\n seen.add(action.id);\n nodes.push((surface ? applyPresentation(action, surface) : action) as ActionGraphNodes[number]);\n // A group's children are the actions contributed for the group's own id.\n if (Node.isActionGroup(action)) {\n visit(action.id, action.id);\n }\n }\n };\n\n visit(rootId, nodeId);\n return { nodes, edges };\n};\n\n/**\n * Read a node's contributed actions from the app-graph as menu `ActionGraphProps`, for splicing into a\n * hand-built toolbar via `MenuBuilder.subgraph(graphActions(graph, get, nodeId))`. Reactive: reads the\n * graph's action atoms through `get`, so contributed actions appear/disappear as extensions update.\n *\n * @idiom org.dxos.react-ui-menu.graphActionsToolbar\n * applies: Splicing a node's app-graph-contributed toolbar actions into a hand-built object toolbar\n * instead-of: Reading `graph.actions(nodeId)` and filtering/wiring `nodes`/`edges` by hand in every toolbar\n * uses: {@link graphActions}, {@link MenuBuilder}, {@link useMenuBuilder}\n * related: org.dxos.react-ui-menu.toolbarMenu\n */\nexport const graphActions = (\n graph: Graph.ReadableGraph | undefined,\n get: Atom.Context,\n nodeId: string | undefined,\n options?: GraphMenuOptions,\n): ActionGraphProps =>\n graph && nodeId ? buildGraphMenu((id) => get(graph.actions(id)), nodeId, options) : { nodes: [], edges: [] };\n\n/**\n * Menu actions sourced entirely from a node's app-graph contributions — the common \"show every action\n * the graph offers for this object\" toolbar/menu. Compose with hand-built items via {@link graphActions}.\n */\nexport const useGraphMenuActions = (\n graph: Graph.ReadableGraph | undefined,\n nodeId: string | undefined,\n options?: GraphMenuOptions,\n): MenuActions => {\n const atom = useMemo(\n () => Atom.make((get) => graphActions(graph, get, nodeId, options)),\n // `options` is expected to be stable; `rootId` participates since it reshapes the graph.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [graph, nodeId, options?.rootId],\n );\n return useMenuActions(atom);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport type { DropdownMenuItemGroupProperties, MenuActionProperties, MenuItemGroupProperties } from '@dxos/ui-types';\n\nimport { translationKey } from '#translations';\n\nimport type { ActionGraphProps } from './hooks';\nimport { MenuSeparatorType } from './types';\nimport { createMenuAction, createMenuItemGroup } from './util';\n\n/** Default trigger for toolbar overflow (⋮) dropdown menus. */\nconst overflowMenuProperties = {\n label: ['toolbar-overflow.menu', { ns: translationKey }],\n icon: 'ph--dots-three-vertical--regular',\n iconOnly: true,\n caretDown: false,\n variant: 'dropdownMenu',\n} as const satisfies DropdownMenuItemGroupProperties;\n\n/** Callback that populates an action group builder. */\nexport type ActionGroupBuilderFn = (builder: ActionGroupBuilder) => void;\n\n/**\n * Fluent builder for composing menu action graphs.\n * Subgraph functions return a callback that receives the builder, enabling composition via partial application:\n * ```ts\n * const addHeadings = (state): ActionGroupBuilderFn => (builder) => {\n * builder.group('headings', { ... }, (group) => { ... });\n * };\n *\n * MenuBuilder.make()\n * .subgraph(showHeadings && addHeadings(state))\n * .subgraph(showFormatting && addFormatting(state))\n * .build();\n * ```\n */\nexport interface ActionGroupBuilder {\n /** Add an action node as a child of the current group. */\n action<P extends {} = {}>(id: string, props: P & MenuActionProperties, invoke: () => void): this;\n\n /** Add a switch action rendered as a labeled Input.Switch. */\n switch(id: string, props: Omit<MenuActionProperties, 'variant'> & { checked: boolean }, invoke: () => void): this;\n\n /** Add a nested action group. */\n group(id: string, props: MenuItemGroupProperties, cb: ActionGroupBuilderFn): this;\n\n /** Merge pre-built nodes and edges, or build a subgraph via callback scoped to the current group. Falsy values are ignored. */\n subgraph(subgraphOrCb: ActionGraphProps | ActionGroupBuilderFn | false | null | undefined): this;\n\n /** Add a separator. */\n separator(variant?: 'gap' | 'line'): this;\n}\n\n/** Top-level builder that creates the root group and produces the final action graph. */\nexport interface MenuBuilder extends ActionGroupBuilder {\n /**\n * Set properties on the root menu group. May only be called once.\n */\n root(props: MenuItemGroupProperties): this;\n\n /**\n * Add a root-level toolbar overflow dropdown (⋮) with built-in trigger styling.\n */\n menu(id: string, cb: ActionGroupBuilderFn, testId?: string): this;\n\n /**\n * Return the assembled action graph.\n */\n build(): ActionGraphProps;\n}\n\nclass MenuBuilderImpl implements MenuBuilder {\n private _separatorCount = 0;\n\n constructor(\n private readonly _data: ActionGraphProps,\n private readonly _rootId: string,\n ) {}\n\n root(props: MenuItemGroupProperties): this {\n invariant(this._rootId === 'root', 'Root group can only be at the top level');\n invariant(this._data.nodes.find((node) => node.id === 'root') === undefined, 'Root group can only be created once');\n this._data.nodes.push(createMenuItemGroup('root', props));\n return this;\n }\n\n build(): ActionGraphProps {\n return this._data;\n }\n\n action<P extends {} = {}>(id: string, props: P & MenuActionProperties, invoke: () => void): this {\n this._data.nodes.push(createMenuAction(id, invoke, props));\n this._data.edges.push({ source: this._rootId, target: id, relation: 'child' });\n return this;\n }\n\n switch(id: string, props: Omit<MenuActionProperties, 'variant'> & { checked: boolean }, invoke: () => void): this {\n return this.action(id, { ...props, variant: 'switch' }, invoke);\n }\n\n group(id: string, props: MenuItemGroupProperties, cb: ActionGroupBuilderFn): this {\n this._data.nodes.push(createMenuItemGroup(id, props));\n this._data.edges.push({ source: this._rootId, target: id, relation: 'child' });\n cb(new MenuBuilderImpl(this._data, id));\n return this;\n }\n\n menu(id: string, cb: ActionGroupBuilderFn, testId?: string): this {\n return this.group(id, testId === undefined ? overflowMenuProperties : { ...overflowMenuProperties, testId }, cb);\n }\n\n subgraph(subgraphOrCb: ActionGraphProps | ActionGroupBuilderFn | false | null | undefined): this {\n if (!subgraphOrCb) {\n return this;\n }\n if (typeof subgraphOrCb === 'function') {\n subgraphOrCb(new MenuBuilderImpl(this._data, this._rootId));\n } else {\n this._data.nodes.push(...subgraphOrCb.nodes);\n this._data.edges.push(...subgraphOrCb.edges);\n }\n return this;\n }\n\n separator(variant: 'gap' | 'line' = 'gap'): this {\n const id = `separator-${++this._separatorCount}`;\n this._data.nodes.push({\n id,\n type: MenuSeparatorType,\n properties: { variant },\n data: undefined as never,\n });\n this._data.edges.push({ source: this._rootId, target: id, relation: 'child' });\n return this;\n }\n}\n\nexport const MenuBuilder = Object.freeze({\n make: (): MenuBuilder => new MenuBuilderImpl({ nodes: [], edges: [] }, 'root'),\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { Node } from '@dxos/app-graph';\n\n/** `disposition` value an action opts into to appear in an object toolbar (vs context-menu-only). */\nexport const TOOLBAR_DISPOSITION = 'toolbar';\n\n/** Filter for {@link graphActions}: keeps only actions a producer opted into the toolbar. */\nexport const isToolbarAction = (action: Node.ActionLike): boolean => Node.hasDisposition(action, TOOLBAR_DISPOSITION);\n"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/translations.ts
|
|
2
|
+
var translationKey = "@dxos/react-ui-menu";
|
|
3
|
+
var translations = [{ "en-US": { [translationKey]: { "toolbar-overflow.menu": "More" } } }];
|
|
4
|
+
//#endregion
|
|
5
|
+
export { translationKey, translations };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=translations.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translations.mjs","names":[],"sources":["../../src/translations.ts"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Resource } from '@dxos/react-ui';\n\nexport const translationKey = '@dxos/react-ui-menu';\n\nexport const translations = [\n {\n 'en-US': {\n [translationKey]: {\n 'toolbar-overflow.menu': 'More',\n },\n },\n },\n] as const satisfies Resource[];\n"],"mappings":";AAMA,IAAa,iBAAiB;AAE9B,IAAa,eAAe,CAC1B,EACE,SAAS,GACN,iBAAiB,EAChB,yBAAyB,OAC3B,EACF,EACF,CACF"}
|
|
@@ -39,7 +39,7 @@ export interface MenuBuilder extends ActionGroupBuilder {
|
|
|
39
39
|
/**
|
|
40
40
|
* Add a root-level toolbar overflow dropdown (⋮) with built-in trigger styling.
|
|
41
41
|
*/
|
|
42
|
-
menu(id: string, cb: ActionGroupBuilderFn): this;
|
|
42
|
+
menu(id: string, cb: ActionGroupBuilderFn, testId?: string): this;
|
|
43
43
|
/**
|
|
44
44
|
* Return the assembled action graph.
|
|
45
45
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/builder.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAmC,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAIrH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAahD,uDAAuD;AACvD,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAEzE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,MAAM,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,oBAAoB,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAEjG,8DAA8D;IAC9D,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,GAAG;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAElH,iCAAiC;IACjC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAElF,+HAA+H;IAC/H,QAAQ,CAAC,YAAY,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAAC;IAEjG,uBAAuB;IACvB,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,yFAAyF;AACzF,MAAM,WAAW,WAAY,SAAQ,kBAAkB;IACrD;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAE3C;;OAEG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,oBAAoB,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/builder.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAmC,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAIrH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAahD,uDAAuD;AACvD,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAEzE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,MAAM,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,oBAAoB,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAEjG,8DAA8D;IAC9D,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,GAAG;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAElH,iCAAiC;IACjC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAElF,+HAA+H;IAC/H,QAAQ,CAAC,YAAY,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAAC;IAEjG,uBAAuB;IACvB,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,yFAAyF;AACzF,MAAM,WAAW,WAAY,SAAQ,kBAAkB;IACrD;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAE3C;;OAEG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAElE;;OAEG;IACH,KAAK,IAAI,gBAAgB,CAAC;CAC3B;AAoED,eAAO,MAAM,WAAW;gBACZ,WAAW;EACrB,CAAC"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type Node } from '@dxos/app-graph';
|
|
3
|
-
import { type TFunction } from '@dxos/react-ui';
|
|
4
3
|
import { type MenuActionProperties, type MenuItemChrome } from '@dxos/ui-types';
|
|
5
4
|
type Action = Node.Action<MenuActionProperties> | Node.ActionGroup<MenuItemChrome>;
|
|
6
5
|
export declare const ActionLabel: ({ action }: {
|
|
7
6
|
action: Action;
|
|
8
7
|
}) => React.JSX.Element;
|
|
9
|
-
export declare const actionLabel: (action: Action, t: TFunction) => string;
|
|
10
8
|
export {};
|
|
11
9
|
//# sourceMappingURL=ActionLabel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionLabel.d.ts","sourceRoot":"","sources":["../../../../src/components/ActionLabel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ActionLabel.d.ts","sourceRoot":"","sources":["../../../../src/components/ActionLabel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAI5C,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMhF,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;AAEnF,eAAO,MAAM,WAAW,eAAgB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,sBASzD,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type DropdownMenuRootProps } from '@dxos/react-ui';
|
|
3
3
|
import { type MenuItem, type MenuItemGroup } from '../types';
|
|
4
|
-
import { type MenuScopedProps } from './
|
|
4
|
+
import { type MenuScopedProps } from './MenuContext';
|
|
5
5
|
export type DropdownMenuProps = DropdownMenuRootProps & {
|
|
6
6
|
group?: MenuItemGroup;
|
|
7
7
|
items?: MenuItem[];
|
|
@@ -13,9 +13,7 @@ export declare const DropdownMenu: {
|
|
|
13
13
|
asChild?: boolean;
|
|
14
14
|
}, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
15
15
|
VirtualTrigger: {
|
|
16
|
-
(props: import("@dxos/react-ui").DropdownMenuVirtualTriggerProps
|
|
17
|
-
__scopeDropdownMenu?: import("@radix-ui/react-context").Scope;
|
|
18
|
-
}): React.JSX.Element;
|
|
16
|
+
(props: import("@dxos/react-ui").DropdownMenuScopedProps<import("@dxos/react-ui").DropdownMenuVirtualTriggerProps>): React.JSX.Element;
|
|
19
17
|
displayName: string;
|
|
20
18
|
};
|
|
21
19
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../../../src/components/DropdownMenu.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D,OAAO,EAAE,KAAK,qBAAqB,EAA6C,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../../../src/components/DropdownMenu.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D,OAAO,EAAE,KAAK,qBAAqB,EAA6C,MAAM,gBAAgB,CAAC;AAGvG,OAAO,EAAmB,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAe,MAAM,UAAU,CAAC;AAG3F,OAAO,EAAE,KAAK,eAAe,EAA+B,MAAM,eAAe,CAAC;AAElF,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG;IACtD,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAuGF,eAAO,MAAM,YAAY;IACvB,IAAI,kHAnDH,eAAe,CAAC,iBAAiB,CAAC;IAoDnC,OAAO;;;IACP,cAAc;;;;CACf,CAAC"}
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import { type Scope } from '@radix-ui/react-context';
|
|
2
1
|
import React, { type PropsWithChildren } from 'react';
|
|
3
2
|
import { type DropdownMenuRootProps } from '@dxos/react-ui';
|
|
4
3
|
import { type MenuContextValue, type MenuGroupContext, type MenuItem } from '../types';
|
|
5
|
-
type MenuScopedProps
|
|
6
|
-
__menuScope?: Scope;
|
|
7
|
-
};
|
|
8
|
-
declare const menuContextDefaults: MenuContextValue;
|
|
9
|
-
declare const useMenuScoped: (consumerName: string, scope: Scope<MenuContextValue | undefined>) => MenuContextValue;
|
|
4
|
+
import { type MenuScopedProps } from './MenuContext';
|
|
10
5
|
type MenuProviderProps = PropsWithChildren<Partial<MenuContextValue>>;
|
|
11
|
-
declare const useMenuItems: (group?: MenuGroupContext, propsItems?: MenuItem[], consumerName?: string, __menuScope?: Scope) => MenuItem[] | undefined;
|
|
12
|
-
/** Returns the menu context without Radix scope. */
|
|
13
|
-
declare const useMenu: (consumerName: string) => MenuContextValue;
|
|
14
6
|
type MenuRootProps = MenuProviderProps & Pick<DropdownMenuRootProps, 'children' | 'open' | 'defaultOpen' | 'onOpenChange'> & {
|
|
15
7
|
/** Identifies the component that owns this menu (passed to action handlers). */
|
|
16
8
|
caller?: string;
|
|
@@ -35,16 +27,14 @@ declare const Menu: {
|
|
|
35
27
|
}, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
36
28
|
Content: ({ group, items: propsItems, caller: callerOverride, __menuScope, }: MenuScopedProps<MenuContentProps>) => React.JSX.Element;
|
|
37
29
|
VirtualTrigger: {
|
|
38
|
-
(props: import("@dxos/react-ui").DropdownMenuVirtualTriggerProps
|
|
39
|
-
__scopeDropdownMenu?: Scope;
|
|
40
|
-
}): React.JSX.Element;
|
|
30
|
+
(props: import("@dxos/react-ui").DropdownMenuScopedProps<import("@dxos/react-ui").DropdownMenuVirtualTriggerProps>): React.JSX.Element;
|
|
41
31
|
displayName: string;
|
|
42
32
|
};
|
|
43
33
|
Toolbar: React.ForwardRefExoticComponent<Omit<MenuScopedProps<import("@dxos/react-ui").ToolbarRootProps>, "className"> & {
|
|
44
34
|
classNames?: import("@dxos/ui-types").ClassNameValue;
|
|
45
|
-
} & Pick<React.HTMLAttributes<Element>, "children" | "
|
|
35
|
+
} & Pick<React.HTMLAttributes<Element>, "children" | "role" | "style"> & React.RefAttributes<HTMLDivElement>>;
|
|
46
36
|
};
|
|
47
|
-
export { Menu
|
|
48
|
-
export type { MenuContentProps, MenuRootProps
|
|
37
|
+
export { Menu };
|
|
38
|
+
export type { MenuContentProps, MenuRootProps };
|
|
49
39
|
export type { ToolbarMenuActionGroupProperties, ToolbarMenuActionGroupProps, ToolbarMenuActionProps, ToolbarMenuDropdownMenuActionGroup, ToolbarMenuProps, ToolbarMenuToggleGroupActionGroup, } from './ToolbarMenu';
|
|
50
40
|
//# sourceMappingURL=Menu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../../src/components/Menu.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../../src/components/Menu.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,EAAmB,KAAK,iBAAiB,EAAoC,MAAM,OAAO,CAAC;AAEzG,OAAO,EAAE,KAAK,qBAAqB,EAA6C,MAAM,gBAAgB,CAAC;AAGvG,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EAGd,MAAM,UAAU,CAAC;AAGlB,OAAO,EAGL,KAAK,eAAe,EAKrB,MAAM,eAAe,CAAC;AASvB,KAAK,iBAAiB,GAAG,iBAAiB,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAwDtE,KAAK,aAAa,GAAG,iBAAiB,GACpC,IAAI,CAAC,qBAAqB,EAAE,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,cAAc,CAAC,GAAG;IAClF,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAkCJ,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAwFF;;;;;;;GAOG;AACH,QAAA,MAAM,IAAI;IACR,IAAI,oEA7H6E,aAAa;IA8H9F,OAAO;;;IACP,OAAO,uEAxDN,eAAe,CAAC,gBAAgB,CAAC;IAyDlC,cAAc;;;;IACd,OAAO;;;CACR,CAAC;AAEF,OAAO,EAAE,IAAI,EAAE,CAAC;AAEhB,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,CAAC;AAEhD,YAAY,EACV,gCAAgC,EAChC,2BAA2B,EAC3B,sBAAsB,EACtB,kCAAkC,EAClC,gBAAgB,EAChB,iCAAiC,GAClC,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Scope } from '@radix-ui/react-context';
|
|
2
|
+
import { type MenuContextValue, type MenuGroupContext, type MenuItem, type MenuItems } from '../types';
|
|
3
|
+
export type MenuScopedProps<P> = P & {
|
|
4
|
+
__menuScope?: Scope;
|
|
5
|
+
};
|
|
6
|
+
export declare const MENU_NAME = "Menu";
|
|
7
|
+
export declare const createMenuContext: <ContextValueType extends object | null>(rootComponentName: string, defaultContext?: ContextValueType | undefined) => readonly [React.FC<ContextValueType & {
|
|
8
|
+
scope: Scope<ContextValueType>;
|
|
9
|
+
children: import("react").ReactNode;
|
|
10
|
+
}>, (consumerName: string, scope: Scope<ContextValueType | undefined>) => ContextValueType], createMenuScope: import("@radix-ui/react-context").CreateScope;
|
|
11
|
+
export declare const menuContextDefaults: MenuContextValue;
|
|
12
|
+
export declare const MenuContextProvider: import("react").FC<MenuContextValue & {
|
|
13
|
+
scope: Scope<MenuContextValue>;
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
}>, useMenuScoped: (consumerName: string, scope: Scope<MenuContextValue | undefined>) => MenuContextValue;
|
|
16
|
+
export declare const useMenuScope: (scope: Scope) => {
|
|
17
|
+
[__scopeProp: string]: Scope<any>;
|
|
18
|
+
};
|
|
19
|
+
export type MenuDropdownContextValue = {
|
|
20
|
+
closeMenu: () => void;
|
|
21
|
+
caller?: string;
|
|
22
|
+
};
|
|
23
|
+
export declare const MenuDropdownContext: import("react").Context<MenuDropdownContextValue>;
|
|
24
|
+
export declare const resolveItems: (baseItems: MenuItem[] | null, group: MenuGroupContext | undefined, entries: ReadonlyMap<string, MenuItems>) => MenuItem[] | null;
|
|
25
|
+
export declare const useMenuItems: (group?: MenuGroupContext, propsItems?: MenuItem[], consumerName?: string, __menuScope?: Scope) => MenuItem[] | undefined;
|
|
26
|
+
/** Returns the menu context without Radix scope. */
|
|
27
|
+
export declare const useMenu: (consumerName: string) => MenuContextValue;
|
|
28
|
+
//# sourceMappingURL=MenuContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MenuContext.d.ts","sourceRoot":"","sources":["../../../../src/components/MenuContext.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,KAAK,EAAsB,MAAM,yBAAyB,CAAC;AAKzE,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,SAAS,EAGf,MAAM,UAAU,CAAC;AASlB,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE7D,eAAO,MAAM,SAAS,SAAS,CAAC;AAEhC,eAAO,MAAO,iBAAiB;;;6FAAE,eAAe,+CAAqC,CAAC;AAKtF,eAAO,MAAM,mBAAmB,EAAE,gBAOjC,CAAC;AAEF,eAAO,MAAO,mBAAmB;;;IAAE,aAAa,wFAAuE,CAAC;AAExH,eAAO,MAAM,YAAY;;CAAoB,CAAC;AAM9C,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,mBAAmB,mDAE9B,CAAC;AASH,eAAO,MAAM,YAAY,cACZ,QAAQ,EAAE,GAAG,IAAI,SACrB,gBAAgB,GAAG,SAAS,WAC1B,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,KACtC,QAAQ,EAAE,GAAG,IA2Bf,CAAC;AAMF,eAAO,MAAM,YAAY,WACf,gBAAgB,eACX,QAAQ,EAAE,iBACT,MAAM,gBACN,KAAK,2BAcpB,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,OAAO,iBAAkB,MAAM,KAAG,gBAE9C,CAAC"}
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { type ToolbarRootProps } from '@dxos/react-ui';
|
|
3
3
|
import { type DropdownMenuItemGroupProperties, type ToggleGroupMenuItemGroupProperties } from '@dxos/ui-types';
|
|
4
4
|
import { type MenuAction, type MenuItem, type MenuItemGroup } from '../types';
|
|
5
|
-
import { type MenuScopedProps } from './
|
|
5
|
+
import { type MenuScopedProps } from './MenuContext';
|
|
6
6
|
export type ToolbarMenuDropdownMenuActionGroup = DropdownMenuItemGroupProperties;
|
|
7
7
|
export type ToolbarMenuToggleGroupActionGroup = ToggleGroupMenuItemGroupProperties;
|
|
8
8
|
export type ToolbarMenuActionGroupProperties = DropdownMenuItemGroupProperties | ToggleGroupMenuItemGroupProperties;
|
|
@@ -25,5 +25,5 @@ export type ToolbarMenuActionProps = {
|
|
|
25
25
|
};
|
|
26
26
|
export declare const ToolbarMenu: React.ForwardRefExoticComponent<Omit<MenuScopedProps<ToolbarRootProps>, "className"> & {
|
|
27
27
|
classNames?: import("@dxos/ui-types").ClassNameValue;
|
|
28
|
-
} & Pick<React.HTMLAttributes<Element>, "children" | "
|
|
28
|
+
} & Pick<React.HTMLAttributes<Element>, "children" | "role" | "style"> & React.RefAttributes<HTMLDivElement>>;
|
|
29
29
|
//# sourceMappingURL=ToolbarMenu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolbarMenu.d.ts","sourceRoot":"","sources":["../../../../src/components/ToolbarMenu.tsx"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"ToolbarMenu.d.ts","sourceRoot":"","sources":["../../../../src/components/ToolbarMenu.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAE7D,OAAO,EAGL,KAAK,gBAAgB,EAItB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAAE,KAAK,+BAA+B,EAAE,KAAK,kCAAkC,EAAE,MAAM,gBAAgB,CAAC;AAI/G,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAA4B,MAAM,UAAU,CAAC;AAKxG,OAAO,EAAE,KAAK,eAAe,EAA+B,MAAM,eAAe,CAAC;AAElF,MAAM,MAAM,kCAAkC,GAAG,+BAA+B,CAAC;AAEjF,MAAM,MAAM,iCAAiC,GAAG,kCAAkC,CAAC;AAEnF,MAAM,MAAM,gCAAgC,GAAG,+BAA+B,GAAG,kCAAkC,CAAC;AAEpH,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEhD,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,EAAE,aAAa,CAAC,gCAAgC,CAAC,CAAC;IACvD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,KAAK,EAAE,aAAa,CAAC,+BAA+B,CAAC,CAAC;IACtD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,EAAE,aAAa,CAAC,kCAAkC,CAAC,CAAC;IACzD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,aAAa,CAAC,kCAAkC,CAAC,CAAC;IACzD,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAgOF,eAAO,MAAM,WAAW;;6GAmBvB,CAAC"}
|
|
@@ -2,9 +2,9 @@ import { type StoryObj } from '@storybook/react-vite';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
declare const meta: {
|
|
4
4
|
title: string;
|
|
5
|
-
component: React.ForwardRefExoticComponent<Omit<import("./
|
|
5
|
+
component: React.ForwardRefExoticComponent<Omit<import("./MenuContext").MenuScopedProps<import("@dxos/react-ui").ToolbarRootProps>, "className"> & {
|
|
6
6
|
classNames?: import("@dxos/ui-types").ClassNameValue;
|
|
7
|
-
} & Pick<React.HTMLAttributes<Element>, "children" | "
|
|
7
|
+
} & Pick<React.HTMLAttributes<Element>, "children" | "role" | "style"> & React.RefAttributes<HTMLDivElement>>;
|
|
8
8
|
decorators: import("@storybook/react").Decorator[];
|
|
9
9
|
parameters: {
|
|
10
10
|
translations: [{
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Node } from '@dxos/app-graph';
|
|
2
|
+
import { type TFunction } from '@dxos/react-ui';
|
|
3
|
+
import { type MenuActionProperties, type MenuItemChrome } from '@dxos/ui-types';
|
|
4
|
+
type Action = Node.Action<MenuActionProperties> | Node.ActionGroup<MenuItemChrome>;
|
|
5
|
+
export declare const actionLabel: (action: Action, t: TFunction) => string;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=action-label.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-label.d.ts","sourceRoot":"","sources":["../../../../src/components/action-label.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIhF,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;AAKnF,eAAO,MAAM,WAAW,WAAY,MAAM,KAAK,SAAS,WAGvD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/index.ts"],"names":[],"mappings":"AAIA,cAAc,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,eAAe,EAAE,mBAAmB,EAAE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEhH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,cAAc,QAAQ,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Atom } from '@effect-atom/atom
|
|
1
|
+
import { Atom } from '@effect-atom/atom';
|
|
2
2
|
import { type Graph, Node } from '@dxos/app-graph';
|
|
3
3
|
import { type ActionGraphProps, type MenuActions } from './useMenuActions';
|
|
4
4
|
export type GraphMenuOptions = {
|
|
@@ -6,6 +6,12 @@ export type GraphMenuOptions = {
|
|
|
6
6
|
rootId?: string;
|
|
7
7
|
/** Keep only the actions the predicate accepts (e.g. by `disposition`). */
|
|
8
8
|
filter?: (action: Node.ActionLike) => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Disposition key this surface renders — when set, each action's `presentation[surface]` chrome
|
|
11
|
+
* override (if any) is merged into its properties, letting one action multi-target dispositions
|
|
12
|
+
* (e.g. `['toolbar', 'list-item']`) with per-surface chrome.
|
|
13
|
+
*/
|
|
14
|
+
surface?: string;
|
|
9
15
|
};
|
|
10
16
|
/**
|
|
11
17
|
* Flatten a node's contributed actions (and nested {@link Node.ActionGroup}s) into the
|
|
@@ -21,6 +27,12 @@ export declare const buildGraphMenu: (resolve: (id: string) => Node.ActionLike[]
|
|
|
21
27
|
* Read a node's contributed actions from the app-graph as menu `ActionGraphProps`, for splicing into a
|
|
22
28
|
* hand-built toolbar via `MenuBuilder.subgraph(graphActions(graph, get, nodeId))`. Reactive: reads the
|
|
23
29
|
* graph's action atoms through `get`, so contributed actions appear/disappear as extensions update.
|
|
30
|
+
*
|
|
31
|
+
* @idiom org.dxos.react-ui-menu.graphActionsToolbar
|
|
32
|
+
* applies: Splicing a node's app-graph-contributed toolbar actions into a hand-built object toolbar
|
|
33
|
+
* instead-of: Reading `graph.actions(nodeId)` and filtering/wiring `nodes`/`edges` by hand in every toolbar
|
|
34
|
+
* uses: {@link graphActions}, {@link MenuBuilder}, {@link useMenuBuilder}
|
|
35
|
+
* related: org.dxos.react-ui-menu.toolbarMenu
|
|
24
36
|
*/
|
|
25
37
|
export declare const graphActions: (graph: Graph.ReadableGraph | undefined, get: Atom.Context, nodeId: string | undefined, options?: GraphMenuOptions) => ActionGraphProps;
|
|
26
38
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGraphMenuActions.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useGraphMenuActions.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"useGraphMenuActions.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useGraphMenuActions.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGzC,OAAO,EAAE,KAAK,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAEjB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,MAAM,gBAAgB,GAAG;IAC7B,2FAA2F;IAC3F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,KAAK,OAAO,CAAC;IAC9C;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,YAChB,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,UAAU,EAAE,UAClC,MAAM,YACL,gBAAgB,KACxB,gBA2BF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,UAChB,KAAK,CAAC,aAAa,GAAG,SAAS,OACjC,IAAI,CAAC,OAAO,UACT,MAAM,GAAG,SAAS,YAChB,gBAAgB,KACzB,gBAC2G,CAAC;AAE/G;;;GAGG;AACH,eAAO,MAAM,mBAAmB,UACvB,KAAK,CAAC,aAAa,GAAG,SAAS,UAC9B,MAAM,GAAG,SAAS,YAChB,gBAAgB,KACzB,WAQF,CAAC"}
|
|
@@ -3,4 +3,6 @@ export * from './hooks';
|
|
|
3
3
|
export * from './types';
|
|
4
4
|
export { createGapSeparator, createLineSeparator, createMenuAction, createMenuItemGroup } from './util';
|
|
5
5
|
export { type ActionGroupBuilder, type ActionGroupBuilderFn, MenuBuilder } from './builder';
|
|
6
|
+
export { TOOLBAR_DISPOSITION, isToolbarAction } from './toolbar';
|
|
7
|
+
export { applyPresentation } from './presentation';
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AACxG,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AACxG,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC5F,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Node } from '@dxos/app-graph';
|
|
2
|
+
/**
|
|
3
|
+
* Merges an action's `presentation[surface]` chrome override (if any) into its properties, letting a
|
|
4
|
+
* single action declare multiple dispositions yet render appropriately in each surface — e.g. a
|
|
5
|
+
* primary toolbar button and a plain nav-tree row from the same definition.
|
|
6
|
+
*/
|
|
7
|
+
export declare const applyPresentation: <A extends Node.ActionLike>(action: A, surface: string) => A;
|
|
8
|
+
//# sourceMappingURL=presentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation.d.ts","sourceRoot":"","sources":["../../../src/presentation.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAG5C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,IAAI,CAAC,UAAU,UAAU,CAAC,WAAW,MAAM,KAAG,CAMzF,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Node } from '@dxos/app-graph';
|
|
2
|
+
/** `disposition` value an action opts into to appear in an object toolbar (vs context-menu-only). */
|
|
3
|
+
export declare const TOOLBAR_DISPOSITION = "toolbar";
|
|
4
|
+
/** Filter for {@link graphActions}: keeps only actions a producer opted into the toolbar. */
|
|
5
|
+
export declare const isToolbarAction: (action: Node.ActionLike) => boolean;
|
|
6
|
+
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/toolbar.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,qGAAqG;AACrG,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C,6FAA6F;AAC7F,eAAO,MAAM,eAAe,WAAY,IAAI,CAAC,UAAU,KAAG,OAA2D,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Atom } from '@effect-atom/atom
|
|
1
|
+
import { type Atom } from '@effect-atom/atom';
|
|
2
2
|
import { Node } from '@dxos/app-graph';
|
|
3
3
|
import { type IconButtonProps, type ToolbarSeparatorProps } from '@dxos/react-ui';
|
|
4
4
|
import { type MenuActionProperties } from '@dxos/ui-types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types/src/util.d.ts
CHANGED
|
@@ -9,16 +9,18 @@ import { type MenuAction } from './types';
|
|
|
9
9
|
export declare const executeMenuAction: (action: MenuAction, params?: Node.InvokeProps) => Promise<void>;
|
|
10
10
|
export declare const getShortcut: (action: Node.ActionLike) => any;
|
|
11
11
|
export declare const fallbackIcon = "ph--circle-dashed--regular";
|
|
12
|
-
export declare const createMenuAction: <P extends {} = {}>(id: string, invoke: () => void, properties: P & MenuActionProperties) => {
|
|
12
|
+
export declare const createMenuAction: <P extends {} = {}>(id: string, invoke: (params?: Node.InvokeProps) => void, properties: P & MenuActionProperties) => {
|
|
13
13
|
id: string;
|
|
14
14
|
type: string;
|
|
15
15
|
properties: P & import("@dxos/ui-types").MenuItemChrome & {
|
|
16
|
-
variant?: 'action' | 'toggle' | 'switch' | 'custom';
|
|
16
|
+
variant?: 'action' | 'primary' | 'toggle' | 'switch' | 'custom';
|
|
17
17
|
value?: string;
|
|
18
18
|
checked?: boolean;
|
|
19
19
|
render?: () => import("react").ReactNode;
|
|
20
|
+
} & {
|
|
21
|
+
presentation?: Partial<Record<string, Partial<import("@dxos/ui-types").MenuActionChrome>>>;
|
|
20
22
|
};
|
|
21
|
-
data: () => Effect.Effect<void, never, never>;
|
|
23
|
+
data: (params?: Node.InvokeProps) => Effect.Effect<void, never, never>;
|
|
22
24
|
};
|
|
23
25
|
export declare const createMenuItemGroup: <P extends MenuItemGroupProperties>(id: string, properties: P) => {
|
|
24
26
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/util.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzF,OAAO,EAAE,KAAK,UAAU,EAA0C,MAAM,SAAS,CAAC;AAElF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WAAkB,UAAU,WAAU,IAAI,CAAC,WAAW,KAAQ,OAAO,CAAC,IAAI,CASvG,CAAC;AAEF,eAAO,MAAM,WAAW,WAAY,IAAI,CAAC,UAAU,QAIlD,CAAC;AAEF,eAAO,MAAM,YAAY,+BAA+B,CAAC;AAEzD,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,EAAE,WACvC,MAAM,UACF,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/util.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzF,OAAO,EAAE,KAAK,UAAU,EAA0C,MAAM,SAAS,CAAC;AAElF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WAAkB,UAAU,WAAU,IAAI,CAAC,WAAW,KAAQ,OAAO,CAAC,IAAI,CASvG,CAAC;AAEF,eAAO,MAAM,WAAW,WAAY,IAAI,CAAC,UAAU,QAIlD,CAAC;AAEF,eAAO,MAAM,YAAY,+BAA+B,CAAC;AAEzD,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,EAAE,WACvC,MAAM,UACF,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,WAAW,KAAK,IAAI,cAC/B,CAAC,GAAG,oBAAoB;;;;;;;;;;;oBAMlB,IAAI,CAAC,WAAW;CACX,CAAC;AAE1B,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,uBAAuB,MAAM,MAAM,cAAc,CAAC;;;;;CAMpE,CAAC;AAE7B,eAAO,MAAM,kBAAkB,QAAQ,MAAM,WAAkB,MAAM;;;;;;;cAM5C,KAAK;;;;;kBAOd,OAAO;;CAGrB,CAAC;AAEH,eAAO,MAAM,mBAAmB,QAAQ,MAAM,WAAmB,MAAM;;;;;;;cAM9C,KAAK;;;;;kBAGY,OAAO;;CAC/C,CAAC"}
|