@xsolla/xui-context-menu 0.183.0 → 0.185.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.
- package/native/index.d.mts +14 -1
- package/native/index.d.ts +14 -1
- package/native/index.js +32 -10
- package/native/index.js.map +1 -1
- package/native/index.mjs +41 -19
- package/native/index.mjs.map +1 -1
- package/package.json +10 -10
- package/web/index.d.mts +14 -1
- package/web/index.d.ts +14 -1
- package/web/index.js +32 -10
- package/web/index.js.map +1 -1
- package/web/index.mjs +41 -19
- package/web/index.mjs.map +1 -1
package/native/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.tsx","../../src/ContextMenu.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../src/ContextMenuContext.tsx","../../src/ContextMenuItem.tsx","../../src/ContextMenuSubmenu.tsx","../../src/hooks/useContextMenuPosition.ts","../../src/hooks/useKeyboardNavigation.ts"],"sourcesContent":["// Components\nexport { ContextMenu } from \"./ContextMenu\";\nexport { ContextMenuItem } from \"./ContextMenuItem\";\nexport { ContextMenuSubmenu } from \"./ContextMenuSubmenu\";\n\n// Context\nexport {\n ContextMenuContext,\n useContextMenu,\n useContextMenuRequired,\n} from \"./ContextMenuContext\";\n\n// Hooks\nexport { useContextMenuPosition } from \"./hooks/useContextMenuPosition\";\nexport { useKeyboardNavigation } from \"./hooks/useKeyboardNavigation\";\n\n// Types\nexport type {\n ContextMenuSize,\n ContextMenuPlacement,\n ContextMenuPresetType,\n ContextMenuPosition,\n ContextMenuProps,\n ContextMenuItemProps,\n ContextMenuOptionItemProps,\n ContextMenuSearchItemProps,\n ContextMenuHeadingItemProps,\n ContextMenuDividerItemProps,\n ContextMenuSubmenuProps,\n ContextMenuContextValue,\n ContextMenuSizing,\n} from \"./types\";\n","import React, {\n cloneElement,\n forwardRef,\n isValidElement,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, useId } from \"@xsolla/xui-core\";\nimport { Spinner } from \"@xsolla/xui-spinner\";\nimport { ContextMenuContext } from \"./ContextMenuContext\";\nimport { ContextMenuItem } from \"./ContextMenuItem\";\nimport { ContextMenuSubmenu } from \"./ContextMenuSubmenu\";\nimport { useContextMenuPosition } from \"./hooks/useContextMenuPosition\";\nimport {\n useKeyboardNavigation,\n type CellMeta,\n} from \"./hooks/useKeyboardNavigation\";\nimport type {\n ContextMenuContextValue,\n ContextMenuItemProps,\n ContextMenuOptionItemProps,\n ContextMenuPlacement,\n ContextMenuProps,\n ContextMenuSizing,\n} from \"./types\";\n\ntype CellEntry = { id: string; meta: CellMeta };\n\ntype ContextMenuTheme = {\n sizing: {\n contextMenu: (\n size: NonNullable<ContextMenuProps[\"size\"]>\n ) => ContextMenuSizing;\n };\n shape?: {\n contextMenu?: Partial<\n Record<\n NonNullable<ContextMenuProps[\"size\"]>,\n {\n borderRadius?: number | string;\n }\n >\n >;\n };\n colors: {\n background: {\n secondary: string;\n };\n border: {\n secondary: string;\n };\n control: {\n brand: {\n primary: {\n bg: string;\n };\n };\n };\n };\n};\n\nconst DEFAULT_EMPTY_MESSAGE = \"No results\";\nconst SEARCH_DEBOUNCE_MS = 200;\nconst ARROW_SIZE = 10;\nconst ARROW_HALF = ARROW_SIZE / 2;\nconst ARROW_EDGE_OFFSET = 12;\nconst PANEL_SHADOW = \"0 4px 12px rgba(0,0,0,0.15)\";\n\nconst textFromNode = (node: React.ReactNode): string => {\n if (node === null || node === undefined || typeof node === \"boolean\")\n return \"\";\n if (typeof node === \"string\" || typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(textFromNode).join(\" \");\n if (isValidElement(node)) return textFromNode(node.props.children);\n return \"\";\n};\n\nconst filterItems = (\n items: ReadonlyArray<ContextMenuItemProps>,\n query: string\n): ContextMenuItemProps[] => {\n const normalized = query.trim().toLowerCase();\n if (!normalized) return [...items];\n\n const result: ContextMenuItemProps[] = [];\n let pendingStructural: ContextMenuItemProps[] = [];\n\n for (const item of items) {\n if (item.type === \"option\") {\n const label = textFromNode(item.label).toLowerCase();\n if (label.includes(normalized)) {\n result.push(...pendingStructural, item);\n pendingStructural = [];\n }\n continue;\n }\n\n if (item.type === \"heading\") {\n pendingStructural = [item];\n continue;\n }\n\n if (item.type === \"divider\") {\n if (result.length > 0) pendingStructural.push(item);\n continue;\n }\n }\n\n return result;\n};\n\nconst isOption = (\n item: ContextMenuItemProps\n): item is ContextMenuOptionItemProps => item.type === \"option\";\n\nconst ContextMenuRoot = forwardRef<HTMLElement, ContextMenuProps>(\n (\n {\n children,\n type = \"list\",\n items = [],\n size = \"md\",\n searchable,\n loading,\n isLoading,\n emptyMessage = DEFAULT_EMPTY_MESSAGE,\n empty,\n isOpen: propIsOpen,\n onOpenChange,\n trigger,\n placement = \"bottom-start\",\n position,\n width,\n maxHeight = 300,\n withArrow = false,\n onSelect,\n closeOnSelect,\n \"aria-label\": ariaLabel,\n testID,\n \"data-testid\": dataTestId,\n themeMode,\n themeProductContext,\n style,\n },\n ref\n ) => {\n const { theme: rawTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const xuiTheme = rawTheme as ContextMenuTheme;\n const menuId = useId();\n const [internalIsOpen, setInternalIsOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [cellsVersion, setCellsVersion] = useState(0);\n const [query, setQuery] = useState(\"\");\n const [debouncedQuery, setDebouncedQuery] = useState(\"\");\n const [activeSubmenuId, setActiveSubmenuId] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const triggerRef = useRef<HTMLElement | null>(null);\n const panelRef = useRef<HTMLElement | null>(null);\n const cellsRef = useRef<CellEntry[]>([]);\n\n const isOpen = propIsOpen !== undefined ? propIsOpen : internalIsOpen;\n const sizeStyles = xuiTheme.sizing.contextMenu(size);\n const borderRadius = xuiTheme.shape?.contextMenu?.[size]?.borderRadius ?? 8;\n const shouldCloseOnSelect =\n closeOnSelect ?? (type === \"checkbox\" ? false : true);\n\n const positioned = useContextMenuPosition({\n triggerRef,\n panelRef,\n isOpen: isOpen && !!trigger && !position,\n placement,\n });\n\n const resolvedPlacement: ContextMenuPlacement =\n positioned?.placement ?? placement;\n\n const getArrowStyle = (\n arrowPlacement: ContextMenuPlacement\n ): React.CSSProperties => {\n const isTop = arrowPlacement.startsWith(\"top\");\n const arrowStyle: React.CSSProperties = {\n position: \"absolute\",\n width: ARROW_SIZE,\n height: ARROW_SIZE,\n backgroundColor: xuiTheme.colors.background.secondary,\n borderStyle: \"solid\",\n borderColor: xuiTheme.colors.border.secondary,\n // 1px outline only on the two outward-facing edges of the rotated square\n borderWidth: isTop ? \"0 1px 1px 0\" : \"1px 0 0 1px\",\n transform: \"rotate(45deg)\",\n pointerEvents: \"none\",\n };\n // Cross axis: sit half outside the panel edge nearest the trigger.\n if (isTop) arrowStyle.bottom = -ARROW_HALF;\n else arrowStyle.top = -ARROW_HALF;\n // Main axis: align toward the trigger side.\n if (arrowPlacement.endsWith(\"center\")) {\n arrowStyle.left = \"50%\";\n arrowStyle.marginLeft = -ARROW_HALF;\n } else if (arrowPlacement.endsWith(\"end\")) {\n arrowStyle.right = ARROW_EDGE_OFFSET;\n } else {\n arrowStyle.left = ARROW_EDGE_OFFSET;\n }\n return arrowStyle;\n };\n\n const setOpen = useCallback(\n (nextOpen: boolean) => {\n if (propIsOpen === undefined) setInternalIsOpen(nextOpen);\n onOpenChange?.(nextOpen);\n if (!nextOpen) setActiveIndex(-1);\n },\n [propIsOpen, onOpenChange]\n );\n\n const closeMenu = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n const toggleMenu = useCallback(() => {\n setOpen(!isOpen);\n }, [isOpen, setOpen]);\n\n const registerCell = useCallback((id: string, meta: CellMeta) => {\n const existingIndex = cellsRef.current.findIndex(\n (cell) => cell.id === id\n );\n if (existingIndex >= 0) {\n cellsRef.current[existingIndex] = { id, meta };\n setCellsVersion((version) => version + 1);\n return existingIndex;\n }\n cellsRef.current.push({ id, meta });\n setCellsVersion((version) => version + 1);\n return cellsRef.current.length - 1;\n }, []);\n\n const unregisterCell = useCallback((id: string) => {\n const index = cellsRef.current.findIndex((cell) => cell.id === id);\n if (index >= 0) {\n cellsRef.current.splice(index, 1);\n setCellsVersion((version) => version + 1);\n }\n }, []);\n\n const getCellIndex = useCallback((id: string) => {\n return cellsRef.current.findIndex((cell) => cell.id === id);\n }, []);\n\n const cells = useMemo(() => [...cellsRef.current], [cellsVersion]);\n const keyboard = useKeyboardNavigation({\n isOpen,\n cells,\n activeIndex,\n setActiveIndex,\n onClose: closeMenu,\n triggerRef,\n });\n\n useEffect(() => {\n if (!isOpen) {\n cellsRef.current = [];\n setCellsVersion((version) => version + 1);\n setQuery(\"\");\n setDebouncedQuery(\"\");\n setActiveSubmenuId(null);\n }\n }, [isOpen]);\n\n useEffect(() => {\n const timer = setTimeout(\n () => setDebouncedQuery(query),\n SEARCH_DEBOUNCE_MS\n );\n return () => clearTimeout(timer);\n }, [query]);\n\n useEffect(() => {\n if (!isOpen || !trigger) return;\n\n const onMouseDown = (event: MouseEvent) => {\n const target = event.target as Node | null;\n if (!target || containerRef.current?.contains(target)) return;\n closeMenu();\n };\n\n const onScroll = () => closeMenu();\n\n document.addEventListener(\"mousedown\", onMouseDown);\n window.addEventListener(\"scroll\", onScroll);\n return () => {\n document.removeEventListener(\"mousedown\", onMouseDown);\n window.removeEventListener(\"scroll\", onScroll);\n };\n }, [isOpen, trigger, closeMenu]);\n\n useLayoutEffect(() => {\n if (!isOpen || !panelRef.current) return;\n const searchbox =\n panelRef.current.querySelector<HTMLElement>('[role=\"searchbox\"]');\n const firstOption = panelRef.current.querySelector<HTMLElement>(\n '[role=\"menuitem\"],[role=\"menuitemcheckbox\"],[role=\"menuitemradio\"]'\n );\n (searchbox ?? firstOption)?.focus();\n }, [isOpen]);\n\n useLayoutEffect(() => {\n if (!isOpen || !panelRef.current) return;\n const activeElement = document.activeElement;\n if (activeElement && panelRef.current.contains(activeElement)) return;\n panelRef.current.focus();\n }, [isOpen, cellsVersion]);\n\n useEffect(() => {\n if (isOpen) return;\n triggerRef.current?.focus();\n }, [isOpen]);\n\n const contextValue: ContextMenuContextValue = useMemo(\n () => ({\n size,\n menuId,\n closeMenu,\n activeIndex,\n setActiveIndex,\n registerCell,\n unregisterCell,\n getCellIndex,\n cellsVersion,\n query,\n setQuery,\n activeSubmenuId,\n setActiveSubmenuId,\n }),\n [\n size,\n menuId,\n closeMenu,\n activeIndex,\n registerCell,\n unregisterCell,\n getCellIndex,\n cellsVersion,\n query,\n activeSubmenuId,\n ]\n );\n\n const renderPresetItem = (item: ContextMenuItemProps, index: number) => {\n if (!isOption(item)) {\n return (\n <ContextMenuItem\n key={`context-menu-item-${index}`}\n {...item}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n );\n }\n\n const leadingControl =\n item.leadingControl ??\n (type === \"checkbox\"\n ? \"checkbox\"\n : type === \"radio\"\n ? \"radio\"\n : undefined);\n\n return (\n <ContextMenuItem\n key={`context-menu-item-${index}`}\n {...item}\n leadingControl={leadingControl}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n onSelect={() => {\n item.onSelect?.();\n onSelect?.(item);\n if (shouldCloseOnSelect) closeMenu();\n }}\n />\n );\n };\n\n const renderedItems = searchable\n ? filterItems(items, debouncedQuery)\n : [...items];\n\n const renderContent = () => {\n if (loading || isLoading || type === \"loading\") {\n const brandColor = xuiTheme.colors.control.brand.primary.bg;\n return (\n <Box\n padding={16}\n alignItems=\"center\"\n justifyContent=\"center\"\n minHeight={60}\n >\n <Spinner size=\"md\" color={brandColor} />\n </Box>\n );\n }\n\n if (children) return children;\n\n const content = renderedItems.map(renderPresetItem);\n if (searchable) {\n content.unshift(\n <div\n key=\"context-menu-search\"\n data-sticky=\"top\"\n style={{\n position: \"sticky\",\n top: 0,\n zIndex: 1,\n backgroundColor: xuiTheme.colors.background.secondary,\n }}\n >\n <ContextMenuItem\n type=\"search\"\n value={query}\n onValueChange={setQuery}\n placeholder=\"Search\"\n autoFocus\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </div>\n );\n }\n\n if (content.length > (searchable ? 1 : 0)) return content;\n return empty ?? <div style={{ padding: 16 }}>{emptyMessage}</div>;\n };\n\n const assignPanelRef = (node: HTMLElement | null) => {\n panelRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n };\n\n const assignTriggerRef = (node: HTMLElement | null) => {\n triggerRef.current = node;\n };\n\n const assignTriggerWrapperRef = (node: HTMLSpanElement | null) => {\n if (!node) {\n assignTriggerRef(null);\n return;\n }\n const firstChild = node.firstElementChild;\n assignTriggerRef(\n firstChild instanceof HTMLElement ? firstChild : (node as HTMLElement)\n );\n };\n\n const triggerNode =\n trigger && isValidElement(trigger) ? (\n <span\n ref={assignTriggerWrapperRef}\n onClick={(event) => {\n if (!event.defaultPrevented) toggleMenu();\n }}\n style={{ display: \"inline-flex\" }}\n >\n {cloneElement(trigger as React.ReactElement<any>, {\n \"aria-haspopup\": \"menu\",\n \"aria-expanded\": isOpen ? \"true\" : \"false\",\n })}\n </span>\n ) : trigger ? (\n <span\n ref={assignTriggerRef}\n role=\"button\"\n tabIndex={0}\n aria-haspopup=\"menu\"\n aria-expanded={isOpen ? \"true\" : \"false\"}\n onClick={toggleMenu}\n >\n {trigger}\n </span>\n ) : null;\n\n const positionStyle = position\n ? {\n position: \"fixed\" as const,\n left: position.x,\n top: position.y,\n }\n : trigger\n ? {\n position: \"fixed\" as const,\n left: positioned?.left ?? 0,\n top: positioned?.top ?? 0,\n }\n : undefined;\n\n return (\n <ContextMenuContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n style={{\n position: trigger || position ? \"relative\" : undefined,\n display: trigger ? \"inline-block\" : undefined,\n }}\n >\n {triggerNode}\n {isOpen && (\n <Box\n ref={assignPanelRef}\n role=\"menu\"\n aria-label={ariaLabel}\n data-testid={dataTestId ?? testID ?? \"context-menu\"}\n data-placement={resolvedPlacement}\n backgroundColor={xuiTheme.colors.background.secondary}\n borderColor={xuiTheme.colors.border.secondary}\n borderWidth={1}\n borderRadius={borderRadius}\n paddingVertical={sizeStyles.paddingVertical}\n width={width}\n minWidth={sizeStyles.minWidth}\n tabIndex={-1}\n onKeyDown={keyboard.handleKeyDown}\n onMouseLeave={() => setActiveIndex(-1)}\n style={{\n ...positionStyle,\n ...style,\n zIndex: 1000,\n boxShadow: PANEL_SHADOW,\n ...(withArrow\n ? {\n overflow: \"visible\",\n }\n : {\n maxHeight,\n overflowY: \"auto\",\n }),\n outline: \"none\",\n }}\n >\n {withArrow ? (\n <>\n <span\n aria-hidden=\"true\"\n data-testid=\"context-menu-arrow\"\n style={getArrowStyle(resolvedPlacement)}\n />\n <div style={{ maxHeight, overflowY: \"auto\", borderRadius }}>\n {renderContent()}\n </div>\n </>\n ) : (\n renderContent()\n )}\n </Box>\n )}\n </div>\n </ContextMenuContext.Provider>\n );\n }\n);\n\nContextMenuRoot.displayName = \"ContextMenu\";\n\nexport const ContextMenu = Object.assign(ContextMenuRoot, {\n Item: ContextMenuItem,\n Submenu: ContextMenuSubmenu,\n});\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import { createContext, useContext } from \"react\";\nimport type { ContextMenuContextValue } from \"./types\";\n\nexport const ContextMenuContext = createContext<\n ContextMenuContextValue | undefined\n>(undefined);\n\nexport const useContextMenu = () => {\n const context = useContext(ContextMenuContext);\n return context;\n};\n\nexport const useContextMenuRequired = () => {\n const context = useContext(ContextMenuContext);\n if (!context) {\n throw new Error(\n \"useContextMenuRequired must be used within a ContextMenu component\"\n );\n }\n return context;\n};\n","import React, { useEffect, useLayoutEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n useResolvedTheme,\n useId,\n type ThemeOverrideProps,\n} from \"@xsolla/xui-core\";\nimport { Typography } from \"@xsolla/xui-typography\";\nimport { Checkbox } from \"@xsolla/xui-checkbox\";\nimport { Radio } from \"@xsolla/xui-radio\";\nimport { Search } from \"@xsolla/xui-icons-base\";\nimport { useContextMenu } from \"./ContextMenuContext\";\nimport type {\n ContextMenuDividerItemProps,\n ContextMenuHeadingItemProps,\n ContextMenuItemProps,\n ContextMenuOptionItemProps,\n ContextMenuSearchItemProps,\n ContextMenuSize,\n} from \"./types\";\n\ntype BodyVariant = \"bodyLg\" | \"bodyMd\" | \"bodySm\" | \"bodyXs\";\ntype AccentVariant =\n | \"bodyLgAccent\"\n | \"bodyMdAccent\"\n | \"bodySmAccent\"\n | \"bodyXsAccent\";\n\nconst sizeToVariants: Record<\n ContextMenuSize,\n { label: BodyVariant; description: BodyVariant; headingAccent: AccentVariant }\n> = {\n xl: { label: \"bodyLg\", description: \"bodyLg\", headingAccent: \"bodyLgAccent\" },\n lg: { label: \"bodyLg\", description: \"bodyMd\", headingAccent: \"bodyMdAccent\" },\n md: { label: \"bodyMd\", description: \"bodySm\", headingAccent: \"bodySmAccent\" },\n sm: { label: \"bodySm\", description: \"bodyXs\", headingAccent: \"bodyXsAccent\" },\n};\n\nconst sizeLabelOverride: Partial<\n Record<ContextMenuSize, { fontSize: number; lineHeight: string }>\n> = {\n xl: { fontSize: 20, lineHeight: \"26px\" },\n};\n\nconst SUBMENU_GAP = 8;\nconst SUBMENU_VIEWPORT_PADDING = 8;\n\nconst clipsOverflow = (style: CSSStyleDeclaration) => {\n return /(auto|scroll|hidden|clip)/.test(\n `${style.overflow}${style.overflowX}${style.overflowY}`\n );\n};\n\nconst getSubmenuBoundary = (node: HTMLElement) => {\n const viewport = {\n top: SUBMENU_VIEWPORT_PADDING,\n right: window.innerWidth - SUBMENU_VIEWPORT_PADDING,\n bottom: window.innerHeight - SUBMENU_VIEWPORT_PADDING,\n left: SUBMENU_VIEWPORT_PADDING,\n };\n\n let current = node.parentElement;\n while (current && current !== document.body) {\n const style = window.getComputedStyle(current);\n if (clipsOverflow(style) && current.getAttribute(\"role\") !== \"menu\") {\n const rect = current.getBoundingClientRect();\n return {\n top: Math.max(viewport.top, rect.top + SUBMENU_VIEWPORT_PADDING),\n right: Math.min(viewport.right, rect.right - SUBMENU_VIEWPORT_PADDING),\n bottom: Math.min(\n viewport.bottom,\n rect.bottom - SUBMENU_VIEWPORT_PADDING\n ),\n left: Math.max(viewport.left, rect.left + SUBMENU_VIEWPORT_PADDING),\n };\n }\n current = current.parentElement;\n }\n\n return viewport;\n};\n\ntype Props = ContextMenuItemProps & ThemeOverrideProps;\n\nexport const ContextMenuItem: React.FC<Props> = (props) => {\n if (props.type === \"option\") return <OptionCell {...props} />;\n if (props.type === \"heading\") return <HeadingCell {...props} />;\n if (props.type === \"divider\") return <DividerCell {...props} />;\n if (props.type === \"search\") return <SearchCell {...props} />;\n return null;\n};\n\nContextMenuItem.displayName = \"ContextMenuItem\";\n\nconst SubmenuChevron: React.FC<{ color: string; size: number }> = ({\n color,\n size,\n}) => (\n <span\n data-testid=\"ctxmenu-submenu-chevron\"\n aria-hidden=\"true\"\n style={{\n color,\n display: \"inline-flex\",\n alignItems: \"center\",\n width: size,\n height: size,\n }}\n >\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M17.0605 11.6464C17.2558 11.8417 17.2558 12.1583 17.0605 12.3536L9.70703 19.707L8.29297 18.293L14.5859 12L8.29297 5.70703L9.70703 4.29297L17.0605 11.6464Z\"\n fill=\"currentColor\"\n />\n </svg>\n </span>\n);\n\nconst OptionCell: React.FC<ContextMenuOptionItemProps & ThemeOverrideProps> = ({\n size: propSize,\n label,\n description,\n disabled,\n destructive,\n checked,\n leadingControl,\n leadingIcon,\n status,\n iconWrapper,\n slot,\n slotContent,\n value,\n hint,\n trailingIcon,\n keyboardShortcut,\n hasSubmenu,\n submenu,\n onSelect,\n onCheckedChange,\n testID,\n themeMode,\n themeProductContext,\n \"data-testid\": testId,\n}) => {\n const { theme: rawTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = rawTheme as any;\n const ctx = useContextMenu();\n const size: ContextMenuSize = propSize ?? ctx?.size ?? \"md\";\n const sizing = theme.sizing.contextMenu(size);\n const variants = sizeToVariants[size];\n\n const id = useId();\n const registerCell = ctx?.registerCell;\n const unregisterCell = ctx?.unregisterCell;\n const getCellIndex = ctx?.getCellIndex;\n const [isHovered, setIsHovered] = useState(false);\n const [submenuOpen, setSubmenuOpen] = useState(false);\n const [submenuPos, setSubmenuPos] = useState<{\n top: number;\n left: number;\n } | null>(null);\n const optionRef = React.useRef<HTMLDivElement | null>(null);\n const submenuWrapperRef = React.useRef<HTMLDivElement | null>(null);\n const closeTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(\n null\n );\n\n const cancelClose = () => {\n if (closeTimerRef.current) {\n clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n }\n };\n\n const scheduleClose = () => {\n cancelClose();\n closeTimerRef.current = setTimeout(() => setSubmenuOpen(false), 120);\n };\n\n useEffect(() => () => cancelClose(), []);\n\n useEffect(() => {\n if (!hasSubmenu || !submenuOpen) return;\n const onMouseDown = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n const inOption = optionRef.current?.contains(target);\n const inSubmenu = submenuWrapperRef.current?.contains(target);\n if (!inOption && !inSubmenu) {\n setSubmenuOpen(false);\n return;\n }\n if (\n inSubmenu &&\n target.closest(\n '[role=\"menuitem\"],[role=\"menuitemcheckbox\"],[role=\"menuitemradio\"]'\n )\n ) {\n setSubmenuOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", onMouseDown);\n return () => document.removeEventListener(\"mousedown\", onMouseDown);\n }, [hasSubmenu, submenuOpen]);\n\n useLayoutEffect(() => {\n if (!hasSubmenu || !submenuOpen) {\n setSubmenuPos(null);\n return;\n }\n\n const update = () => {\n const node = optionRef.current;\n if (!node) return;\n const rect = node.getBoundingClientRect();\n const submenuRect = submenuWrapperRef.current?.getBoundingClientRect();\n const submenuWidth = submenuRect?.width ?? 0;\n const submenuHeight = submenuRect?.height ?? 0;\n const boundary = getSubmenuBoundary(node);\n\n const rightSideLeft = rect.right + SUBMENU_GAP;\n const leftSideLeft = rect.left - SUBMENU_GAP - submenuWidth;\n const opensLeft =\n submenuWidth > 0 && rightSideLeft + submenuWidth > boundary.right;\n\n let left = opensLeft ? leftSideLeft : rightSideLeft;\n\n if (submenuWidth > 0) {\n if (opensLeft) {\n left = Math.max(SUBMENU_VIEWPORT_PADDING, left);\n } else {\n left = Math.min(\n Math.max(boundary.left, left),\n Math.max(boundary.left, boundary.right - submenuWidth)\n );\n }\n }\n\n let top = rect.top;\n if (submenuHeight > 0 && top + submenuHeight > boundary.bottom) {\n top = boundary.bottom - submenuHeight;\n }\n top = Math.max(boundary.top, top);\n\n setSubmenuPos((prev) =>\n prev?.top === top && prev.left === left ? prev : { top, left }\n );\n };\n\n update();\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n });\n const onSelectRef = React.useRef(onSelect);\n onSelectRef.current = onSelect;\n // Register on mount / unregister on unmount. Deps are the stable registry\n // callbacks + id only — NOT `ctx`, whose identity changes on every hover\n // (activeIndex). Depending on `ctx` here churned register/unregister and, on\n // React <18 (interleaved passive-effect flush), collapsed every row to the\n // same index so one hover highlighted all rows (FEP-764).\n useEffect(() => {\n if (!registerCell || !unregisterCell) return;\n registerCell(id, {\n type: \"option\",\n onSelect: () => onSelectRef.current?.(),\n });\n return () => unregisterCell(id);\n }, [registerCell, unregisterCell, id]);\n\n // Keep registry metadata (disabled) in sync without reordering the cell.\n useEffect(() => {\n if (!registerCell) return;\n registerCell(id, {\n type: \"option\",\n disabled,\n onSelect: () => onSelectRef.current?.(),\n });\n }, [registerCell, id, disabled]);\n\n // Derive index live from the registry instead of caching it in state, so it\n // is always correct after dynamic add/remove without per-item re-registration.\n const index = getCellIndex ? getCellIndex(id) : -1;\n const isActive = ctx ? index >= 0 && ctx.activeIndex === index : false;\n const inHoverState =\n isActive || (!ctx && isHovered) || (hasSubmenu && submenuOpen);\n\n const handleEnter = () => {\n if (disabled) return;\n if (ctx && index >= 0) ctx.setActiveIndex(index);\n if (!ctx) setIsHovered(true);\n if (hasSubmenu) setSubmenuOpen(true);\n };\n\n const handleLeave = () => {\n if (!ctx) setIsHovered(false);\n if (hasSubmenu) scheduleClose();\n };\n\n const labelColor = disabled\n ? theme.colors.control.input.textDisable\n : destructive\n ? theme.colors.content.alert.primary\n : theme.colors.content.primary;\n\n const bg = inHoverState ? theme.colors.control.input.bgHover : \"transparent\";\n\n const role =\n !hasSubmenu && checked !== undefined\n ? leadingControl === \"radio\"\n ? \"menuitemradio\"\n : \"menuitemcheckbox\"\n : \"menuitem\";\n const ariaChecked =\n !hasSubmenu && checked !== undefined\n ? checked\n ? \"true\"\n : \"false\"\n : undefined;\n\n const handleClick = () => {\n if (disabled) return;\n if (hasSubmenu) {\n setSubmenuOpen(true);\n return;\n }\n if (checked !== undefined) {\n onCheckedChange?.(!checked);\n }\n onSelect?.();\n };\n\n const closeSubmenuAndFocus = () => {\n setSubmenuOpen(false);\n optionRef.current?.focus();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (disabled) {\n if (e.key === \"Enter\" || e.key === \" \") e.preventDefault();\n return;\n }\n if (hasSubmenu) {\n if (e.key === \"ArrowRight\" || e.key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n setSubmenuOpen(true);\n return;\n }\n if (e.key === \"ArrowLeft\" || e.key === \"Escape\") {\n if (submenuOpen) {\n e.preventDefault();\n e.stopPropagation();\n closeSubmenuAndFocus();\n return;\n }\n }\n }\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (checked !== undefined) {\n onCheckedChange?.(!checked);\n }\n onSelect?.();\n }\n };\n\n return (\n <div\n ref={optionRef}\n role={role}\n aria-checked={ariaChecked}\n aria-disabled={disabled ? \"true\" : undefined}\n aria-haspopup={hasSubmenu ? \"menu\" : undefined}\n aria-expanded={hasSubmenu ? (submenuOpen ? \"true\" : \"false\") : undefined}\n tabIndex={0}\n data-testid={testId || testID}\n data-state={inHoverState ? \"hover\" : undefined}\n data-destructive={destructive ? \"true\" : undefined}\n aria-keyshortcuts={keyboardShortcut}\n onMouseEnter={() => {\n cancelClose();\n handleEnter();\n }}\n onMouseLeave={handleLeave}\n onFocus={handleEnter}\n onBlur={() => {\n if (!ctx) setIsHovered(false);\n }}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n style={{\n position: \"relative\",\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: sizing.gap,\n paddingLeft: sizing.itemPaddingHorizontal,\n paddingRight: sizing.itemPaddingHorizontal,\n paddingTop: sizing.itemPaddingVertical,\n paddingBottom: sizing.itemPaddingVertical,\n backgroundColor: bg,\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n outline: \"none\",\n }}\n >\n {leadingControl === \"checkbox\" && (\n <span\n data-testid=\"ctxmenu-leading-checkbox\"\n aria-hidden=\"true\"\n style={{ pointerEvents: \"none\", display: \"inline-flex\" }}\n >\n <Checkbox\n size={size}\n checked={!!checked}\n disabled={!!disabled}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </span>\n )}\n {leadingControl === \"radio\" && (\n <span\n data-testid=\"ctxmenu-leading-radio\"\n aria-hidden=\"true\"\n style={{ pointerEvents: \"none\", display: \"inline-flex\" }}\n >\n <Radio\n size={size}\n checked={!!checked}\n disabled={!!disabled}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </span>\n )}\n {leadingIcon}\n {status}\n {iconWrapper}\n {slot}\n {slotContent}\n <span\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n minWidth: 0,\n }}\n >\n <Typography\n variant={variants.label}\n color={labelColor}\n noWrap={description === undefined}\n style={{\n ...(description === undefined\n ? { display: \"block\", minWidth: 0 }\n : {}),\n ...(sizeLabelOverride[size] ?? {}),\n }}\n >\n {label}\n </Typography>\n {description !== undefined && (\n <Typography\n variant={variants.description}\n color={theme.colors.content.tertiary}\n >\n {description}\n </Typography>\n )}\n </span>\n {(value !== undefined || hint !== undefined) && (\n <span\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-end\",\n }}\n >\n {value !== undefined && (\n <Typography\n variant={variants.label}\n color={theme.colors.content.secondary}\n style={sizeLabelOverride[size]}\n >\n {value}\n </Typography>\n )}\n {hint !== undefined && (\n <Typography\n variant={variants.description}\n color={theme.colors.content.tertiary}\n >\n {hint}\n </Typography>\n )}\n </span>\n )}\n {keyboardShortcut && (\n <Typography\n as=\"kbd\"\n variant={variants.description}\n color={theme.colors.content.tertiary}\n >\n {keyboardShortcut}\n </Typography>\n )}\n {hasSubmenu && (\n <SubmenuChevron\n color={theme.colors.content.tertiary}\n size={sizing.iconSize}\n />\n )}\n {trailingIcon}\n {hasSubmenu &&\n submenuOpen &&\n submenu &&\n submenuPos &&\n typeof document !== \"undefined\" &&\n createPortal(\n <div\n ref={submenuWrapperRef}\n data-xui-context-menu-portal={ctx?.menuId}\n onMouseEnter={cancelClose}\n onMouseLeave={scheduleClose}\n style={{\n position: \"fixed\",\n top: submenuPos.top,\n left: submenuPos.left,\n zIndex: 2000,\n }}\n >\n {submenu}\n </div>,\n document.body\n )}\n </div>\n );\n};\n\nconst HeadingCell: React.FC<\n ContextMenuHeadingItemProps & ThemeOverrideProps\n> = ({\n size: propSize,\n label,\n description,\n testID,\n themeMode,\n themeProductContext,\n \"data-testid\": testId,\n}) => {\n const { theme: rawTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = rawTheme as any;\n const ctx = useContextMenu();\n const size: ContextMenuSize = propSize ?? ctx?.size ?? \"md\";\n const sizing = theme.sizing.contextMenu(size);\n const variants = sizeToVariants[size];\n\n const id = useId();\n const registerCell = ctx?.registerCell;\n const unregisterCell = ctx?.unregisterCell;\n useEffect(() => {\n if (!registerCell || !unregisterCell) return;\n registerCell(id, { type: \"heading\" });\n return () => unregisterCell(id);\n }, [registerCell, unregisterCell, id]);\n\n return (\n <div\n role=\"presentation\"\n data-testid={testId || testID}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n paddingLeft: sizing.itemPaddingHorizontal,\n paddingRight: sizing.itemPaddingHorizontal,\n paddingTop: sizing.itemPaddingVertical,\n paddingBottom: sizing.itemPaddingVertical,\n }}\n >\n <Typography\n variant={variants.headingAccent}\n color={theme.colors.content.secondary}\n style={{ textTransform: \"uppercase\", letterSpacing: 0.5 }}\n >\n {label}\n </Typography>\n {description !== undefined && (\n <Typography\n variant={variants.description}\n color={theme.colors.content.tertiary}\n >\n {description}\n </Typography>\n )}\n </div>\n );\n};\n\nconst SearchCell: React.FC<ContextMenuSearchItemProps & ThemeOverrideProps> = ({\n size: propSize,\n value,\n onChange,\n onValueChange,\n placeholder = \"Search\",\n autoFocus,\n \"aria-label\": ariaLabel = \"Search options\",\n \"data-testid\": testId,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme: rawTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = rawTheme as any;\n const ctx = useContextMenu();\n const size: ContextMenuSize = propSize ?? ctx?.size ?? \"md\";\n const sizing = theme.sizing.contextMenu(size);\n\n const id = useId();\n const registerCell = ctx?.registerCell;\n const unregisterCell = ctx?.unregisterCell;\n useEffect(() => {\n if (!registerCell || !unregisterCell) return;\n registerCell(id, { type: \"search\" });\n return () => unregisterCell(id);\n }, [registerCell, unregisterCell, id]);\n\n return (\n <div\n style={{\n boxSizing: \"border-box\",\n paddingLeft: sizing.searchPaddingHorizontal,\n paddingRight: sizing.searchPaddingHorizontal,\n paddingTop: sizing.searchPaddingVertical,\n paddingBottom: sizing.searchPaddingVertical,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n paddingBottom: 6,\n borderBottom: `1px solid ${theme.colors.border.secondary}`,\n }}\n >\n <Search\n variant=\"line\"\n size={sizing.searchIconSize}\n color={theme.colors.control.input.placeholder}\n aria-hidden\n />\n <input\n type=\"search\"\n role=\"searchbox\"\n aria-label={ariaLabel}\n placeholder={placeholder}\n value={value ?? \"\"}\n autoFocus={autoFocus}\n onChange={(e) => {\n onChange?.(e);\n onValueChange?.(e.target.value);\n }}\n data-testid={testId || testID}\n style={{\n flex: 1,\n minWidth: 0,\n boxSizing: \"border-box\",\n border: \"none\",\n outline: \"none\",\n background: \"transparent\",\n padding: 0,\n color: theme.colors.content.primary,\n fontSize: sizing.searchFontSize,\n lineHeight: `${sizing.searchLineHeight}px`,\n }}\n />\n </div>\n </div>\n );\n};\n\nconst DividerCell: React.FC<\n ContextMenuDividerItemProps & ThemeOverrideProps\n> = ({ themeMode, themeProductContext, \"data-testid\": testId }) => {\n const { theme: rawTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = rawTheme as any;\n const ctx = useContextMenu();\n const id = useId();\n const registerCell = ctx?.registerCell;\n const unregisterCell = ctx?.unregisterCell;\n useEffect(() => {\n if (!registerCell || !unregisterCell) return;\n registerCell(id, { type: \"divider\" });\n return () => unregisterCell(id);\n }, [registerCell, unregisterCell, id]);\n return (\n <div\n role=\"separator\"\n data-testid={testId}\n style={{\n height: 1,\n backgroundColor: theme.colors.border.secondary,\n margin: \"4px 0\",\n }}\n />\n );\n};\n","import React, {\n useState,\n useRef,\n useEffect,\n useLayoutEffect,\n useCallback,\n} from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\nimport { ContextMenuItem } from \"./ContextMenuItem\";\nimport { useContextMenu } from \"./ContextMenuContext\";\nimport type { ContextMenuSubmenuProps } from \"./types\";\n\n/** Gap (px) between the parent menu panel and the submenu panel */\nconst SUBMENU_GAP = 4;\n/** Delay (ms) before the submenu opens on hover */\nconst OPEN_DELAY_MS = 200;\n/** Grace period (ms) before the submenu closes after the pointer leaves */\nconst CLOSE_GRACE_MS = 100;\n\n/** Module-level counter for stable, unique submenu IDs (React 16 compatible) */\nlet _submenuIdCounter = 0;\n\nexport const ContextMenuSubmenu: React.FC<ContextMenuSubmenuProps> = ({\n label,\n icon,\n disabled,\n children,\n size: propSize,\n \"data-testid\": testId = \"context-menu-submenu\",\n}) => {\n const { theme } = useDesignSystem();\n const xuiTheme = theme as any;\n const context = useContextMenu();\n const size = propSize || context?.size || \"md\";\n const sizeStyles = xuiTheme.sizing.contextMenu(size);\n const borderRadius =\n xuiTheme.shape?.contextMenu?.[size]?.borderRadius ??\n xuiTheme.radius?.button ??\n 8;\n\n const submenuIdRef = useRef<string | null>(null);\n if (submenuIdRef.current === null) {\n submenuIdRef.current = `xui-cm-submenu-${(_submenuIdCounter += 1)}`;\n }\n const submenuId = submenuIdRef.current;\n\n const [isOpen, setIsOpen] = useState(false);\n const [visible, setVisible] = useState(false);\n const [openLeft, setOpenLeft] = useState(false);\n const [topOffset, setTopOffset] = useState(0);\n\n const triggerRef = useRef<HTMLDivElement>(null);\n const submenuRef = useRef<HTMLDivElement>(null);\n const openTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const clearTimers = useCallback(() => {\n if (openTimerRef.current) clearTimeout(openTimerRef.current);\n if (closeTimerRef.current) clearTimeout(closeTimerRef.current);\n }, []);\n\n // Close this submenu when a sibling submenu becomes active (Bug #3 fix)\n useEffect(() => {\n if (!context?.activeSubmenuId) return;\n if (context.activeSubmenuId !== submenuId) {\n setIsOpen(false);\n }\n }, [context?.activeSubmenuId, submenuId]);\n\n const calculatePlacement = useCallback(() => {\n if (!triggerRef.current) return;\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const estimatedWidth = sizeStyles.minWidth + 32;\n const wouldOverflowRight =\n triggerRect.right + estimatedWidth + SUBMENU_GAP > window.innerWidth - 8;\n // Bug #1/#2 fix: only flip left when there is actually space on the left\n const hasSpaceOnLeft =\n triggerRect.left - SUBMENU_GAP - estimatedWidth >= 8;\n setOpenLeft(wouldOverflowRight && hasSpaceOnLeft);\n setTopOffset(0);\n }, [sizeStyles.minWidth]);\n\n useLayoutEffect(() => {\n if (!isOpen || !submenuRef.current || !triggerRef.current) return;\n\n const submenuRect = submenuRef.current.getBoundingClientRect();\n const triggerRect = triggerRef.current.getBoundingClientRect();\n\n const wouldOverflowRight =\n triggerRect.right + submenuRect.width + SUBMENU_GAP >\n window.innerWidth - 8;\n const hasSpaceOnLeft =\n triggerRect.left - SUBMENU_GAP - submenuRect.width >= 8;\n setOpenLeft(wouldOverflowRight && hasSpaceOnLeft);\n\n const overflowBottom =\n triggerRect.top + submenuRect.height - (window.innerHeight - 8);\n if (overflowBottom > 0) {\n setTopOffset(-Math.min(overflowBottom, triggerRect.top - 8));\n } else {\n setTopOffset(0);\n }\n }, [isOpen]);\n\n useEffect(() => {\n if (!isOpen) {\n setVisible(false);\n return;\n }\n const raf = requestAnimationFrame(() => setVisible(true));\n return () => cancelAnimationFrame(raf);\n }, [isOpen]);\n\n useEffect(() => () => clearTimers(), [clearTimers]);\n\n const handleTriggerEnter = () => {\n if (disabled) return;\n clearTimers();\n openTimerRef.current = setTimeout(() => {\n calculatePlacement();\n setIsOpen(true);\n context?.setActiveSubmenuId(submenuId);\n }, OPEN_DELAY_MS);\n };\n\n const handleTriggerLeave = () => {\n clearTimers();\n closeTimerRef.current = setTimeout(() => {\n setIsOpen(false);\n if (context?.activeSubmenuId === submenuId) {\n context.setActiveSubmenuId(null);\n }\n }, CLOSE_GRACE_MS);\n };\n\n const handleSubmenuEnter = () => clearTimers();\n\n const handleSubmenuLeave = () => {\n clearTimers();\n closeTimerRef.current = setTimeout(() => {\n setIsOpen(false);\n if (context?.activeSubmenuId === submenuId) {\n context.setActiveSubmenuId(null);\n }\n }, CLOSE_GRACE_MS);\n };\n\n const submenuPositionStyle = openLeft\n ? { right: `calc(100% + ${SUBMENU_GAP}px)` }\n : { left: `calc(100% + ${SUBMENU_GAP}px)` };\n\n return (\n <div\n ref={triggerRef}\n style={{ position: \"relative\" }}\n onMouseEnter={handleTriggerEnter}\n onMouseLeave={handleTriggerLeave}\n data-testid={testId}\n >\n <ContextMenuItem\n type=\"option\"\n label={label}\n leadingIcon={icon}\n disabled={disabled}\n hasSubmenu\n size={size}\n data-testid={`${testId}-trigger`}\n />\n\n {isOpen && (\n <div\n ref={submenuRef}\n onMouseEnter={handleSubmenuEnter}\n onMouseLeave={handleSubmenuLeave}\n style={{\n position: \"absolute\",\n top: topOffset,\n ...submenuPositionStyle,\n zIndex: 1001,\n opacity: visible ? 1 : 0,\n transform: visible\n ? \"translateX(0)\"\n : openLeft\n ? \"translateX(4px)\"\n : \"translateX(-4px)\",\n transition: \"opacity 100ms ease, transform 100ms ease\",\n }}\n data-testid={`${testId}-content`}\n >\n <Box\n role=\"menu\"\n backgroundColor={xuiTheme.colors.background.secondary}\n borderColor={xuiTheme.colors.border.secondary}\n borderWidth={1}\n borderRadius={borderRadius}\n paddingVertical={sizeStyles.paddingVertical}\n style={{\n boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\",\n minWidth: sizeStyles.minWidth,\n }}\n >\n {children}\n </Box>\n </div>\n )}\n </div>\n );\n};\n\nContextMenuSubmenu.displayName = \"ContextMenuSubmenu\";\n","import { useEffect, useState, type RefObject } from \"react\";\nimport type { ContextMenuPlacement } from \"../types\";\n\ninterface UseContextMenuPositionOptions {\n triggerRef: RefObject<HTMLElement | null>;\n panelRef: RefObject<HTMLElement | null>;\n isOpen: boolean;\n placement?: ContextMenuPlacement;\n offset?: number;\n}\n\ninterface ResolvedPosition {\n top: number;\n left: number;\n placement: ContextMenuPlacement;\n}\n\nconst splitPlacement = (\n placement: ContextMenuPlacement\n): { vertical: \"top\" | \"bottom\"; horizontal: \"start\" | \"end\" | \"center\" } => {\n const [vertical, horizontal] = placement.split(\"-\") as [\n \"top\" | \"bottom\",\n \"start\" | \"end\" | \"center\",\n ];\n return { vertical, horizontal };\n};\n\nconst joinPlacement = (\n vertical: \"top\" | \"bottom\",\n horizontal: \"start\" | \"end\" | \"center\"\n): ContextMenuPlacement => `${vertical}-${horizontal}` as ContextMenuPlacement;\n\nexport const useContextMenuPosition = ({\n triggerRef,\n panelRef,\n isOpen,\n placement = \"bottom-start\",\n offset = 4,\n}: UseContextMenuPositionOptions): ResolvedPosition | undefined => {\n const [resolved, setResolved] = useState<ResolvedPosition | undefined>();\n\n useEffect(() => {\n if (!isOpen) {\n setResolved(undefined);\n return;\n }\n\n const compute = () => {\n const trigger = triggerRef.current;\n const panel = panelRef.current;\n if (!trigger || !panel) return;\n\n const triggerRect = trigger.getBoundingClientRect();\n const panelRect = panel.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n let { vertical, horizontal } = splitPlacement(placement);\n\n const computeTop = (v: \"top\" | \"bottom\") =>\n v === \"bottom\"\n ? triggerRect.bottom + offset\n : triggerRect.top - panelRect.height - offset;\n\n const computeLeft = (h: \"start\" | \"end\" | \"center\") => {\n if (h === \"center\")\n return triggerRect.left + triggerRect.width / 2 - panelRect.width / 2;\n return h === \"start\"\n ? triggerRect.left\n : triggerRect.right - panelRect.width;\n };\n\n let top = computeTop(vertical);\n const wantedBottom = top + panelRect.height;\n if (top < 0 || wantedBottom > viewportHeight) {\n const flipped = vertical === \"bottom\" ? \"top\" : \"bottom\";\n const flippedTop = computeTop(flipped);\n const flippedBottom = flippedTop + panelRect.height;\n if (flippedTop >= 0 && flippedBottom <= viewportHeight) {\n vertical = flipped;\n top = flippedTop;\n }\n }\n\n let left = computeLeft(horizontal);\n if (horizontal === \"center\") {\n // Center can't flip; clamp into the viewport instead.\n const maxLeft = viewportWidth - panelRect.width;\n left = maxLeft >= 0 ? Math.min(Math.max(left, 0), maxLeft) : 0;\n } else {\n const wantedRight = left + panelRect.width;\n if (left < 0 || wantedRight > viewportWidth) {\n const flipped = horizontal === \"start\" ? \"end\" : \"start\";\n const flippedLeft = computeLeft(flipped);\n const flippedRight = flippedLeft + panelRect.width;\n if (flippedLeft >= 0 && flippedRight <= viewportWidth) {\n horizontal = flipped;\n left = flippedLeft;\n }\n }\n }\n\n const next = {\n top,\n left,\n placement: joinPlacement(vertical, horizontal),\n };\n setResolved((prev) =>\n prev &&\n prev.top === next.top &&\n prev.left === next.left &&\n prev.placement === next.placement\n ? prev\n : next\n );\n };\n\n const rafId = window.requestAnimationFrame(compute);\n // No scroll listener: the menu dismisses on scroll (see ContextMenu), so\n // following the trigger would be dead work. Resize still repositions an\n // open menu.\n const onResize = () => compute();\n window.addEventListener(\"resize\", onResize);\n\n return () => {\n window.cancelAnimationFrame(rafId);\n window.removeEventListener(\"resize\", onResize);\n };\n }, [isOpen, placement, offset, triggerRef, panelRef]);\n\n return resolved;\n};\n","import { useCallback, type RefObject } from \"react\";\n\nexport type CellType = \"option\" | \"search\" | \"heading\" | \"divider\";\n\nexport interface CellMeta {\n type: CellType;\n onSelect?: () => void;\n disabled?: boolean;\n}\n\ninterface UseKeyboardNavigationOptions {\n isOpen: boolean;\n cells: Array<{ id: string; meta: CellMeta }>;\n activeIndex: number;\n setActiveIndex: (index: number) => void;\n onClose: () => void;\n triggerRef?: RefObject<HTMLElement | null>;\n}\n\nconst isNavigableOption = (meta: CellMeta) =>\n meta.type === \"option\" && !meta.disabled;\n\nconst isTextInputTarget = (target: EventTarget | null): boolean => {\n if (!(target instanceof HTMLElement)) return false;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") return true;\n return target.getAttribute(\"role\") === \"searchbox\";\n};\n\nexport const useKeyboardNavigation = ({\n isOpen,\n cells,\n activeIndex,\n setActiveIndex,\n onClose,\n triggerRef,\n}: UseKeyboardNavigationOptions) => {\n const findFirstOption = useCallback(() => {\n for (let i = 0; i < cells.length; i += 1) {\n if (isNavigableOption(cells[i].meta)) return i;\n }\n return -1;\n }, [cells]);\n\n const findLastOption = useCallback(() => {\n for (let i = cells.length - 1; i >= 0; i -= 1) {\n if (isNavigableOption(cells[i].meta)) return i;\n }\n return -1;\n }, [cells]);\n\n const findNextOption = useCallback(\n (from: number) => {\n const len = cells.length;\n if (len === 0) return -1;\n for (let step = 1; step <= len; step += 1) {\n const idx = (from + step + len) % len;\n if (isNavigableOption(cells[idx].meta)) return idx;\n }\n return -1;\n },\n [cells]\n );\n\n const findPrevOption = useCallback(\n (from: number) => {\n const len = cells.length;\n if (len === 0) return -1;\n for (let step = 1; step <= len; step += 1) {\n const idx = (from - step + len * 2) % len;\n if (isNavigableOption(cells[idx].meta)) return idx;\n }\n return -1;\n },\n [cells]\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (!isOpen) return;\n\n switch (event.key) {\n case \"ArrowDown\": {\n event.preventDefault();\n const next =\n activeIndex < 0 ? findFirstOption() : findNextOption(activeIndex);\n if (next >= 0) setActiveIndex(next);\n break;\n }\n case \"ArrowUp\": {\n event.preventDefault();\n const prev =\n activeIndex < 0 ? findLastOption() : findPrevOption(activeIndex);\n if (prev >= 0) setActiveIndex(prev);\n break;\n }\n case \"Home\": {\n event.preventDefault();\n const first = findFirstOption();\n if (first >= 0) setActiveIndex(first);\n break;\n }\n case \"End\": {\n event.preventDefault();\n const last = findLastOption();\n if (last >= 0) setActiveIndex(last);\n break;\n }\n case \"Enter\":\n case \" \": {\n if (event.defaultPrevented) break;\n if (event.key === \" \" && isTextInputTarget(event.target)) break;\n if (event.key === \" \") event.preventDefault();\n if (activeIndex >= 0 && activeIndex < cells.length) {\n const meta = cells[activeIndex].meta;\n if (isNavigableOption(meta)) meta.onSelect?.();\n }\n break;\n }\n case \"Escape\": {\n event.preventDefault();\n onClose();\n triggerRef?.current?.focus();\n break;\n }\n case \"Tab\": {\n onClose();\n break;\n }\n default:\n break;\n }\n },\n [\n isOpen,\n cells,\n activeIndex,\n setActiveIndex,\n onClose,\n triggerRef,\n findFirstOption,\n findLastOption,\n findNextOption,\n findPrevOption,\n ]\n );\n\n return { handleKeyDown };\n};\n"],"mappings":"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","names":["import_react","import_xui_core","import_react","import_jsx_runtime","React","import_react","import_xui_core","import_jsx_runtime","SUBMENU_GAP","import_react","import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.tsx","../../src/ContextMenu.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../src/ContextMenuContext.tsx","../../src/ContextMenuItem.tsx","../../src/ContextMenuSubmenu.tsx","../../src/hooks/useContextMenuPosition.ts","../../src/hooks/useKeyboardNavigation.ts"],"sourcesContent":["// Components\nexport { ContextMenu } from \"./ContextMenu\";\nexport { ContextMenuItem } from \"./ContextMenuItem\";\nexport { ContextMenuSubmenu } from \"./ContextMenuSubmenu\";\n\n// Context\nexport {\n ContextMenuContext,\n useContextMenu,\n useContextMenuRequired,\n} from \"./ContextMenuContext\";\n\n// Hooks\nexport { useContextMenuPosition } from \"./hooks/useContextMenuPosition\";\nexport { useKeyboardNavigation } from \"./hooks/useKeyboardNavigation\";\n\n// Types\nexport type {\n ContextMenuSize,\n ContextMenuPlacement,\n ContextMenuPresetType,\n ContextMenuPosition,\n ContextMenuProps,\n ContextMenuItemProps,\n ContextMenuOptionItemProps,\n ContextMenuSearchItemProps,\n ContextMenuHeadingItemProps,\n ContextMenuDividerItemProps,\n ContextMenuSubmenuProps,\n ContextMenuContextValue,\n ContextMenuSizing,\n} from \"./types\";\n","import React, {\n cloneElement,\n forwardRef,\n isValidElement,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, useId } from \"@xsolla/xui-core\";\nimport { Spinner } from \"@xsolla/xui-spinner\";\nimport { ContextMenuContext } from \"./ContextMenuContext\";\nimport { ContextMenuItem } from \"./ContextMenuItem\";\nimport { ContextMenuSubmenu } from \"./ContextMenuSubmenu\";\nimport { useContextMenuPosition } from \"./hooks/useContextMenuPosition\";\nimport {\n useKeyboardNavigation,\n type CellMeta,\n} from \"./hooks/useKeyboardNavigation\";\nimport type {\n ContextMenuContextValue,\n ContextMenuItemProps,\n ContextMenuOptionItemProps,\n ContextMenuPlacement,\n ContextMenuProps,\n ContextMenuSizing,\n} from \"./types\";\n\ntype CellEntry = { id: string; meta: CellMeta };\n\ntype ContextMenuTheme = {\n sizing: {\n contextMenu: (\n size: NonNullable<ContextMenuProps[\"size\"]>\n ) => ContextMenuSizing;\n };\n shape?: {\n contextMenu?: Partial<\n Record<\n NonNullable<ContextMenuProps[\"size\"]>,\n {\n borderRadius?: number | string;\n }\n >\n >;\n };\n colors: {\n background: {\n secondary: string;\n };\n border: {\n secondary: string;\n };\n control: {\n brand: {\n primary: {\n bg: string;\n };\n };\n };\n };\n};\n\nconst DEFAULT_EMPTY_MESSAGE = \"No results\";\nconst SEARCH_DEBOUNCE_MS = 200;\nconst ARROW_SIZE = 10;\nconst ARROW_HALF = ARROW_SIZE / 2;\nconst ARROW_EDGE_OFFSET = 12;\n// Distance the rotated arrow's tip protrudes past the panel edge toward the\n// trigger. The square is rotated 45deg about its center (pinned to the edge),\n// so its corner sits ARROW_HALF * √2 beyond it. Folded into the position\n// offset when `withArrow` is set so `offset` measures to the arrow tip.\nconst ARROW_TIP_PROTRUSION = ARROW_HALF * Math.SQRT2;\nconst PANEL_SHADOW = \"0 4px 12px rgba(0,0,0,0.15)\";\n\nconst textFromNode = (node: React.ReactNode): string => {\n if (node === null || node === undefined || typeof node === \"boolean\")\n return \"\";\n if (typeof node === \"string\" || typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(textFromNode).join(\" \");\n if (isValidElement(node)) return textFromNode(node.props.children);\n return \"\";\n};\n\nconst filterItems = (\n items: ReadonlyArray<ContextMenuItemProps>,\n query: string\n): ContextMenuItemProps[] => {\n const normalized = query.trim().toLowerCase();\n if (!normalized) return [...items];\n\n const result: ContextMenuItemProps[] = [];\n let pendingStructural: ContextMenuItemProps[] = [];\n\n for (const item of items) {\n if (item.type === \"option\") {\n const label = textFromNode(item.label).toLowerCase();\n if (label.includes(normalized)) {\n result.push(...pendingStructural, item);\n pendingStructural = [];\n }\n continue;\n }\n\n if (item.type === \"heading\") {\n pendingStructural = [item];\n continue;\n }\n\n if (item.type === \"divider\") {\n if (result.length > 0) pendingStructural.push(item);\n continue;\n }\n }\n\n return result;\n};\n\nconst isOption = (\n item: ContextMenuItemProps\n): item is ContextMenuOptionItemProps => item.type === \"option\";\n\nconst ContextMenuRoot = forwardRef<HTMLElement, ContextMenuProps>(\n (\n {\n children,\n type = \"list\",\n items = [],\n size = \"md\",\n searchable,\n loading,\n isLoading,\n emptyMessage = DEFAULT_EMPTY_MESSAGE,\n empty,\n isOpen: propIsOpen,\n onOpenChange,\n trigger,\n triggerFullWidth = false,\n placement = \"bottom-start\",\n offset = 4,\n position,\n width,\n maxHeight = 300,\n withArrow = false,\n onSelect,\n closeOnSelect,\n \"aria-label\": ariaLabel,\n testID,\n \"data-testid\": dataTestId,\n themeMode,\n themeProductContext,\n style,\n },\n ref\n ) => {\n const { theme: rawTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const xuiTheme = rawTheme as ContextMenuTheme;\n const menuId = useId();\n const [internalIsOpen, setInternalIsOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [cellsVersion, setCellsVersion] = useState(0);\n const [query, setQuery] = useState(\"\");\n const [debouncedQuery, setDebouncedQuery] = useState(\"\");\n const [activeSubmenuId, setActiveSubmenuId] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const triggerRef = useRef<HTMLElement | null>(null);\n const panelRef = useRef<HTMLElement | null>(null);\n const cellsRef = useRef<CellEntry[]>([]);\n\n const isOpen = propIsOpen !== undefined ? propIsOpen : internalIsOpen;\n const sizeStyles = xuiTheme.sizing.contextMenu(size);\n const borderRadius = xuiTheme.shape?.contextMenu?.[size]?.borderRadius ?? 8;\n const shouldCloseOnSelect =\n closeOnSelect ?? (type === \"checkbox\" ? false : true);\n\n // With an arrow, the tip protrudes past the panel edge, so push the panel\n // out by that amount to keep `offset` measured to the visible arrow tip.\n const positionOffset = withArrow ? offset + ARROW_TIP_PROTRUSION : offset;\n\n const positioned = useContextMenuPosition({\n triggerRef,\n panelRef,\n containerRef,\n isOpen: isOpen && !!trigger && !position,\n placement,\n offset: positionOffset,\n });\n\n const resolvedPlacement: ContextMenuPlacement =\n positioned?.placement ?? placement;\n\n const getArrowStyle = (\n arrowPlacement: ContextMenuPlacement\n ): React.CSSProperties => {\n const isTop = arrowPlacement.startsWith(\"top\");\n const arrowStyle: React.CSSProperties = {\n position: \"absolute\",\n width: ARROW_SIZE,\n height: ARROW_SIZE,\n backgroundColor: xuiTheme.colors.background.secondary,\n borderStyle: \"solid\",\n borderColor: xuiTheme.colors.border.secondary,\n // 1px outline only on the two outward-facing edges of the rotated square\n borderWidth: isTop ? \"0 1px 1px 0\" : \"1px 0 0 1px\",\n transform: \"rotate(45deg)\",\n pointerEvents: \"none\",\n };\n // Cross axis: sit half outside the panel edge nearest the trigger.\n if (isTop) arrowStyle.bottom = -ARROW_HALF;\n else arrowStyle.top = -ARROW_HALF;\n // Main axis: align toward the trigger side.\n if (arrowPlacement.endsWith(\"center\")) {\n arrowStyle.left = \"50%\";\n arrowStyle.marginLeft = -ARROW_HALF;\n } else if (arrowPlacement.endsWith(\"end\")) {\n arrowStyle.right = ARROW_EDGE_OFFSET;\n } else {\n arrowStyle.left = ARROW_EDGE_OFFSET;\n }\n return arrowStyle;\n };\n\n const setOpen = useCallback(\n (nextOpen: boolean) => {\n if (propIsOpen === undefined) setInternalIsOpen(nextOpen);\n onOpenChange?.(nextOpen);\n if (!nextOpen) setActiveIndex(-1);\n },\n [propIsOpen, onOpenChange]\n );\n\n const closeMenu = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n const toggleMenu = useCallback(() => {\n setOpen(!isOpen);\n }, [isOpen, setOpen]);\n\n const registerCell = useCallback((id: string, meta: CellMeta) => {\n const existingIndex = cellsRef.current.findIndex(\n (cell) => cell.id === id\n );\n if (existingIndex >= 0) {\n cellsRef.current[existingIndex] = { id, meta };\n setCellsVersion((version) => version + 1);\n return existingIndex;\n }\n cellsRef.current.push({ id, meta });\n setCellsVersion((version) => version + 1);\n return cellsRef.current.length - 1;\n }, []);\n\n const unregisterCell = useCallback((id: string) => {\n const index = cellsRef.current.findIndex((cell) => cell.id === id);\n if (index >= 0) {\n cellsRef.current.splice(index, 1);\n setCellsVersion((version) => version + 1);\n }\n }, []);\n\n const getCellIndex = useCallback((id: string) => {\n return cellsRef.current.findIndex((cell) => cell.id === id);\n }, []);\n\n const cells = useMemo(() => [...cellsRef.current], [cellsVersion]);\n const keyboard = useKeyboardNavigation({\n isOpen,\n cells,\n activeIndex,\n setActiveIndex,\n onClose: closeMenu,\n triggerRef,\n });\n\n useEffect(() => {\n if (!isOpen) {\n cellsRef.current = [];\n setCellsVersion((version) => version + 1);\n setQuery(\"\");\n setDebouncedQuery(\"\");\n setActiveSubmenuId(null);\n }\n }, [isOpen]);\n\n useEffect(() => {\n const timer = setTimeout(\n () => setDebouncedQuery(query),\n SEARCH_DEBOUNCE_MS\n );\n return () => clearTimeout(timer);\n }, [query]);\n\n useEffect(() => {\n if (!isOpen || !trigger) return;\n\n const onMouseDown = (event: MouseEvent) => {\n const target = event.target as Node | null;\n if (!target || containerRef.current?.contains(target)) return;\n closeMenu();\n };\n\n const onScroll = () => closeMenu();\n\n document.addEventListener(\"mousedown\", onMouseDown);\n window.addEventListener(\"scroll\", onScroll);\n return () => {\n document.removeEventListener(\"mousedown\", onMouseDown);\n window.removeEventListener(\"scroll\", onScroll);\n };\n }, [isOpen, trigger, closeMenu]);\n\n useLayoutEffect(() => {\n if (!isOpen || !panelRef.current) return;\n const searchbox =\n panelRef.current.querySelector<HTMLElement>('[role=\"searchbox\"]');\n const firstOption = panelRef.current.querySelector<HTMLElement>(\n '[role=\"menuitem\"],[role=\"menuitemcheckbox\"],[role=\"menuitemradio\"]'\n );\n (searchbox ?? firstOption)?.focus();\n }, [isOpen]);\n\n useLayoutEffect(() => {\n if (!isOpen || !panelRef.current) return;\n const activeElement = document.activeElement;\n if (activeElement && panelRef.current.contains(activeElement)) return;\n panelRef.current.focus();\n }, [isOpen, cellsVersion]);\n\n useEffect(() => {\n if (isOpen) return;\n triggerRef.current?.focus();\n }, [isOpen]);\n\n const contextValue: ContextMenuContextValue = useMemo(\n () => ({\n size,\n menuId,\n closeMenu,\n activeIndex,\n setActiveIndex,\n registerCell,\n unregisterCell,\n getCellIndex,\n cellsVersion,\n query,\n setQuery,\n activeSubmenuId,\n setActiveSubmenuId,\n }),\n [\n size,\n menuId,\n closeMenu,\n activeIndex,\n registerCell,\n unregisterCell,\n getCellIndex,\n cellsVersion,\n query,\n activeSubmenuId,\n ]\n );\n\n const renderPresetItem = (item: ContextMenuItemProps, index: number) => {\n if (!isOption(item)) {\n return (\n <ContextMenuItem\n key={`context-menu-item-${index}`}\n {...item}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n );\n }\n\n const leadingControl =\n item.leadingControl ??\n (type === \"checkbox\"\n ? \"checkbox\"\n : type === \"radio\"\n ? \"radio\"\n : undefined);\n\n return (\n <ContextMenuItem\n key={`context-menu-item-${index}`}\n {...item}\n leadingControl={leadingControl}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n onSelect={() => {\n item.onSelect?.();\n onSelect?.(item);\n if (shouldCloseOnSelect) closeMenu();\n }}\n />\n );\n };\n\n const renderedItems = searchable\n ? filterItems(items, debouncedQuery)\n : [...items];\n\n const renderContent = () => {\n if (loading || isLoading || type === \"loading\") {\n const brandColor = xuiTheme.colors.control.brand.primary.bg;\n return (\n <Box\n padding={16}\n alignItems=\"center\"\n justifyContent=\"center\"\n minHeight={60}\n >\n <Spinner size=\"md\" color={brandColor} />\n </Box>\n );\n }\n\n if (children) return children;\n\n const content = renderedItems.map(renderPresetItem);\n if (searchable) {\n content.unshift(\n <div\n key=\"context-menu-search\"\n data-sticky=\"top\"\n style={{\n position: \"sticky\",\n top: 0,\n zIndex: 1,\n backgroundColor: xuiTheme.colors.background.secondary,\n }}\n >\n <ContextMenuItem\n type=\"search\"\n value={query}\n onValueChange={setQuery}\n placeholder=\"Search\"\n autoFocus\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </div>\n );\n }\n\n if (content.length > (searchable ? 1 : 0)) return content;\n return empty ?? <div style={{ padding: 16 }}>{emptyMessage}</div>;\n };\n\n const assignPanelRef = (node: HTMLElement | null) => {\n panelRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n };\n\n const assignTriggerRef = (node: HTMLElement | null) => {\n triggerRef.current = node;\n };\n\n const assignTriggerWrapperRef = (node: HTMLSpanElement | null) => {\n if (!node) {\n assignTriggerRef(null);\n return;\n }\n const firstChild = node.firstElementChild;\n assignTriggerRef(\n firstChild instanceof HTMLElement ? firstChild : (node as HTMLElement)\n );\n };\n\n const triggerNode =\n trigger && isValidElement(trigger) ? (\n <span\n ref={assignTriggerWrapperRef}\n onClick={(event) => {\n if (!event.defaultPrevented) toggleMenu();\n }}\n style={{\n display: \"inline-flex\",\n width: triggerFullWidth ? \"100%\" : \"auto\",\n }}\n >\n {cloneElement(trigger as React.ReactElement<any>, {\n \"aria-haspopup\": \"menu\",\n \"aria-expanded\": isOpen ? \"true\" : \"false\",\n })}\n </span>\n ) : trigger ? (\n <span\n ref={assignTriggerRef}\n role=\"button\"\n tabIndex={0}\n aria-haspopup=\"menu\"\n aria-expanded={isOpen ? \"true\" : \"false\"}\n onClick={toggleMenu}\n >\n {trigger}\n </span>\n ) : null;\n\n const positionStyle: React.CSSProperties | undefined = position\n ? {\n position: \"fixed\" as const,\n left: position.x,\n top: position.y,\n }\n : trigger\n ? positioned\n ? {\n position: \"absolute\" as const,\n left: positioned.left,\n top: positioned.top,\n }\n : {\n position: \"absolute\" as const,\n visibility: \"hidden\" as const,\n }\n : undefined;\n\n return (\n <ContextMenuContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n style={{\n position: trigger || position ? \"relative\" : undefined,\n display: trigger ? \"inline-block\" : undefined,\n }}\n >\n {triggerNode}\n {isOpen && (\n <Box\n ref={assignPanelRef}\n role=\"menu\"\n aria-label={ariaLabel}\n data-testid={dataTestId ?? testID ?? \"context-menu\"}\n data-placement={resolvedPlacement}\n backgroundColor={xuiTheme.colors.background.secondary}\n borderColor={xuiTheme.colors.border.secondary}\n borderWidth={1}\n borderRadius={borderRadius}\n paddingVertical={sizeStyles.paddingVertical}\n width={width}\n minWidth={sizeStyles.minWidth}\n tabIndex={-1}\n onKeyDown={keyboard.handleKeyDown}\n onMouseLeave={() => setActiveIndex(-1)}\n style={{\n ...positionStyle,\n ...style,\n zIndex: 1000,\n boxShadow: PANEL_SHADOW,\n ...(withArrow\n ? {\n overflow: \"visible\",\n }\n : {\n maxHeight,\n overflowY: \"auto\",\n }),\n outline: \"none\",\n }}\n >\n {withArrow ? (\n <>\n <span\n aria-hidden=\"true\"\n data-testid=\"context-menu-arrow\"\n style={getArrowStyle(resolvedPlacement)}\n />\n <div style={{ maxHeight, overflowY: \"auto\", borderRadius }}>\n {renderContent()}\n </div>\n </>\n ) : (\n renderContent()\n )}\n </Box>\n )}\n </div>\n </ContextMenuContext.Provider>\n );\n }\n);\n\nContextMenuRoot.displayName = \"ContextMenu\";\n\nexport const ContextMenu = Object.assign(ContextMenuRoot, {\n Item: ContextMenuItem,\n Submenu: ContextMenuSubmenu,\n});\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import { createContext, useContext } from \"react\";\nimport type { ContextMenuContextValue } from \"./types\";\n\nexport const ContextMenuContext = createContext<\n ContextMenuContextValue | undefined\n>(undefined);\n\nexport const useContextMenu = () => {\n const context = useContext(ContextMenuContext);\n return context;\n};\n\nexport const useContextMenuRequired = () => {\n const context = useContext(ContextMenuContext);\n if (!context) {\n throw new Error(\n \"useContextMenuRequired must be used within a ContextMenu component\"\n );\n }\n return context;\n};\n","import React, { useEffect, useLayoutEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n useResolvedTheme,\n useId,\n type ThemeOverrideProps,\n} from \"@xsolla/xui-core\";\nimport { Typography } from \"@xsolla/xui-typography\";\nimport { Checkbox } from \"@xsolla/xui-checkbox\";\nimport { Radio } from \"@xsolla/xui-radio\";\nimport { Search } from \"@xsolla/xui-icons-base\";\nimport { useContextMenu } from \"./ContextMenuContext\";\nimport type {\n ContextMenuDividerItemProps,\n ContextMenuHeadingItemProps,\n ContextMenuItemProps,\n ContextMenuOptionItemProps,\n ContextMenuSearchItemProps,\n ContextMenuSize,\n} from \"./types\";\n\ntype BodyVariant = \"bodyLg\" | \"bodyMd\" | \"bodySm\" | \"bodyXs\";\ntype AccentVariant =\n | \"bodyLgAccent\"\n | \"bodyMdAccent\"\n | \"bodySmAccent\"\n | \"bodyXsAccent\";\n\nconst sizeToVariants: Record<\n ContextMenuSize,\n { label: BodyVariant; description: BodyVariant; headingAccent: AccentVariant }\n> = {\n xl: { label: \"bodyLg\", description: \"bodyLg\", headingAccent: \"bodyLgAccent\" },\n lg: { label: \"bodyLg\", description: \"bodyMd\", headingAccent: \"bodyMdAccent\" },\n md: { label: \"bodyMd\", description: \"bodySm\", headingAccent: \"bodySmAccent\" },\n sm: { label: \"bodySm\", description: \"bodyXs\", headingAccent: \"bodyXsAccent\" },\n};\n\nconst sizeLabelOverride: Partial<\n Record<ContextMenuSize, { fontSize: number; lineHeight: string }>\n> = {\n xl: { fontSize: 20, lineHeight: \"26px\" },\n};\n\nconst SUBMENU_GAP = 8;\nconst SUBMENU_VIEWPORT_PADDING = 8;\n\nconst clipsOverflow = (style: CSSStyleDeclaration) => {\n return /(auto|scroll|hidden|clip)/.test(\n `${style.overflow}${style.overflowX}${style.overflowY}`\n );\n};\n\nconst getSubmenuBoundary = (node: HTMLElement) => {\n const viewport = {\n top: SUBMENU_VIEWPORT_PADDING,\n right: window.innerWidth - SUBMENU_VIEWPORT_PADDING,\n bottom: window.innerHeight - SUBMENU_VIEWPORT_PADDING,\n left: SUBMENU_VIEWPORT_PADDING,\n };\n\n let current = node.parentElement;\n while (current && current !== document.body) {\n const style = window.getComputedStyle(current);\n if (clipsOverflow(style) && current.getAttribute(\"role\") !== \"menu\") {\n const rect = current.getBoundingClientRect();\n return {\n top: Math.max(viewport.top, rect.top + SUBMENU_VIEWPORT_PADDING),\n right: Math.min(viewport.right, rect.right - SUBMENU_VIEWPORT_PADDING),\n bottom: Math.min(\n viewport.bottom,\n rect.bottom - SUBMENU_VIEWPORT_PADDING\n ),\n left: Math.max(viewport.left, rect.left + SUBMENU_VIEWPORT_PADDING),\n };\n }\n current = current.parentElement;\n }\n\n return viewport;\n};\n\ntype Props = ContextMenuItemProps & ThemeOverrideProps;\n\nexport const ContextMenuItem: React.FC<Props> = (props) => {\n if (props.type === \"option\") return <OptionCell {...props} />;\n if (props.type === \"heading\") return <HeadingCell {...props} />;\n if (props.type === \"divider\") return <DividerCell {...props} />;\n if (props.type === \"search\") return <SearchCell {...props} />;\n return null;\n};\n\nContextMenuItem.displayName = \"ContextMenuItem\";\n\nconst SubmenuChevron: React.FC<{ color: string; size: number }> = ({\n color,\n size,\n}) => (\n <span\n data-testid=\"ctxmenu-submenu-chevron\"\n aria-hidden=\"true\"\n style={{\n color,\n display: \"inline-flex\",\n alignItems: \"center\",\n width: size,\n height: size,\n }}\n >\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M17.0605 11.6464C17.2558 11.8417 17.2558 12.1583 17.0605 12.3536L9.70703 19.707L8.29297 18.293L14.5859 12L8.29297 5.70703L9.70703 4.29297L17.0605 11.6464Z\"\n fill=\"currentColor\"\n />\n </svg>\n </span>\n);\n\nconst OptionCell: React.FC<ContextMenuOptionItemProps & ThemeOverrideProps> = ({\n size: propSize,\n label,\n description,\n disabled,\n destructive,\n checked,\n leadingControl,\n leadingIcon,\n status,\n iconWrapper,\n slot,\n slotContent,\n value,\n hint,\n trailingIcon,\n keyboardShortcut,\n hasSubmenu,\n submenu,\n onSelect,\n onCheckedChange,\n testID,\n themeMode,\n themeProductContext,\n \"data-testid\": testId,\n}) => {\n const { theme: rawTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = rawTheme as any;\n const ctx = useContextMenu();\n const size: ContextMenuSize = propSize ?? ctx?.size ?? \"md\";\n const sizing = theme.sizing.contextMenu(size);\n const variants = sizeToVariants[size];\n\n const id = useId();\n const registerCell = ctx?.registerCell;\n const unregisterCell = ctx?.unregisterCell;\n const getCellIndex = ctx?.getCellIndex;\n const [isHovered, setIsHovered] = useState(false);\n const [submenuOpen, setSubmenuOpen] = useState(false);\n const [submenuPos, setSubmenuPos] = useState<{\n top: number;\n left: number;\n } | null>(null);\n const optionRef = React.useRef<HTMLDivElement | null>(null);\n const submenuWrapperRef = React.useRef<HTMLDivElement | null>(null);\n const closeTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(\n null\n );\n\n const cancelClose = () => {\n if (closeTimerRef.current) {\n clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n }\n };\n\n const scheduleClose = () => {\n cancelClose();\n closeTimerRef.current = setTimeout(() => setSubmenuOpen(false), 120);\n };\n\n useEffect(() => () => cancelClose(), []);\n\n useEffect(() => {\n if (!hasSubmenu || !submenuOpen) return;\n const onMouseDown = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n const inOption = optionRef.current?.contains(target);\n const inSubmenu = submenuWrapperRef.current?.contains(target);\n if (!inOption && !inSubmenu) {\n setSubmenuOpen(false);\n return;\n }\n if (\n inSubmenu &&\n target.closest(\n '[role=\"menuitem\"],[role=\"menuitemcheckbox\"],[role=\"menuitemradio\"]'\n )\n ) {\n setSubmenuOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", onMouseDown);\n return () => document.removeEventListener(\"mousedown\", onMouseDown);\n }, [hasSubmenu, submenuOpen]);\n\n useLayoutEffect(() => {\n if (!hasSubmenu || !submenuOpen) {\n setSubmenuPos(null);\n return;\n }\n\n const update = () => {\n const node = optionRef.current;\n if (!node) return;\n const rect = node.getBoundingClientRect();\n const submenuRect = submenuWrapperRef.current?.getBoundingClientRect();\n const submenuWidth = submenuRect?.width ?? 0;\n const submenuHeight = submenuRect?.height ?? 0;\n const boundary = getSubmenuBoundary(node);\n\n const rightSideLeft = rect.right + SUBMENU_GAP;\n const leftSideLeft = rect.left - SUBMENU_GAP - submenuWidth;\n const opensLeft =\n submenuWidth > 0 && rightSideLeft + submenuWidth > boundary.right;\n\n let left = opensLeft ? leftSideLeft : rightSideLeft;\n\n if (submenuWidth > 0) {\n if (opensLeft) {\n left = Math.max(SUBMENU_VIEWPORT_PADDING, left);\n } else {\n left = Math.min(\n Math.max(boundary.left, left),\n Math.max(boundary.left, boundary.right - submenuWidth)\n );\n }\n }\n\n let top = rect.top;\n if (submenuHeight > 0 && top + submenuHeight > boundary.bottom) {\n top = boundary.bottom - submenuHeight;\n }\n top = Math.max(boundary.top, top);\n\n setSubmenuPos((prev) =>\n prev?.top === top && prev.left === left ? prev : { top, left }\n );\n };\n\n update();\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n });\n const onSelectRef = React.useRef(onSelect);\n onSelectRef.current = onSelect;\n // Register on mount / unregister on unmount. Deps are the stable registry\n // callbacks + id only — NOT `ctx`, whose identity changes on every hover\n // (activeIndex). Depending on `ctx` here churned register/unregister and, on\n // React <18 (interleaved passive-effect flush), collapsed every row to the\n // same index so one hover highlighted all rows (FEP-764).\n useEffect(() => {\n if (!registerCell || !unregisterCell) return;\n registerCell(id, {\n type: \"option\",\n onSelect: () => onSelectRef.current?.(),\n });\n return () => unregisterCell(id);\n }, [registerCell, unregisterCell, id]);\n\n // Keep registry metadata (disabled) in sync without reordering the cell.\n useEffect(() => {\n if (!registerCell) return;\n registerCell(id, {\n type: \"option\",\n disabled,\n onSelect: () => onSelectRef.current?.(),\n });\n }, [registerCell, id, disabled]);\n\n // Derive index live from the registry instead of caching it in state, so it\n // is always correct after dynamic add/remove without per-item re-registration.\n const index = getCellIndex ? getCellIndex(id) : -1;\n const isActive = ctx ? index >= 0 && ctx.activeIndex === index : false;\n const inHoverState =\n isActive || (!ctx && isHovered) || (hasSubmenu && submenuOpen);\n\n const handleEnter = () => {\n if (disabled) return;\n if (ctx && index >= 0) ctx.setActiveIndex(index);\n if (!ctx) setIsHovered(true);\n if (hasSubmenu) setSubmenuOpen(true);\n };\n\n const handleLeave = () => {\n if (!ctx) setIsHovered(false);\n if (hasSubmenu) scheduleClose();\n };\n\n const labelColor = disabled\n ? theme.colors.control.input.textDisable\n : destructive\n ? theme.colors.content.alert.primary\n : theme.colors.content.primary;\n\n const bg = inHoverState ? theme.colors.control.input.bgHover : \"transparent\";\n\n const role =\n !hasSubmenu && checked !== undefined\n ? leadingControl === \"radio\"\n ? \"menuitemradio\"\n : \"menuitemcheckbox\"\n : \"menuitem\";\n const ariaChecked =\n !hasSubmenu && checked !== undefined\n ? checked\n ? \"true\"\n : \"false\"\n : undefined;\n\n const handleClick = () => {\n if (disabled) return;\n if (hasSubmenu) {\n setSubmenuOpen(true);\n return;\n }\n if (checked !== undefined) {\n onCheckedChange?.(!checked);\n }\n onSelect?.();\n };\n\n const closeSubmenuAndFocus = () => {\n setSubmenuOpen(false);\n optionRef.current?.focus();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (disabled) {\n if (e.key === \"Enter\" || e.key === \" \") e.preventDefault();\n return;\n }\n if (hasSubmenu) {\n if (e.key === \"ArrowRight\" || e.key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n setSubmenuOpen(true);\n return;\n }\n if (e.key === \"ArrowLeft\" || e.key === \"Escape\") {\n if (submenuOpen) {\n e.preventDefault();\n e.stopPropagation();\n closeSubmenuAndFocus();\n return;\n }\n }\n }\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (checked !== undefined) {\n onCheckedChange?.(!checked);\n }\n onSelect?.();\n }\n };\n\n return (\n <div\n ref={optionRef}\n role={role}\n aria-checked={ariaChecked}\n aria-disabled={disabled ? \"true\" : undefined}\n aria-haspopup={hasSubmenu ? \"menu\" : undefined}\n aria-expanded={hasSubmenu ? (submenuOpen ? \"true\" : \"false\") : undefined}\n tabIndex={0}\n data-testid={testId || testID}\n data-state={inHoverState ? \"hover\" : undefined}\n data-destructive={destructive ? \"true\" : undefined}\n aria-keyshortcuts={keyboardShortcut}\n onMouseEnter={() => {\n cancelClose();\n handleEnter();\n }}\n onMouseLeave={handleLeave}\n onFocus={handleEnter}\n onBlur={() => {\n if (!ctx) setIsHovered(false);\n }}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n style={{\n position: \"relative\",\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: sizing.gap,\n paddingLeft: sizing.itemPaddingHorizontal,\n paddingRight: sizing.itemPaddingHorizontal,\n paddingTop: sizing.itemPaddingVertical,\n paddingBottom: sizing.itemPaddingVertical,\n backgroundColor: bg,\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n outline: \"none\",\n }}\n >\n {leadingControl === \"checkbox\" && (\n <span\n data-testid=\"ctxmenu-leading-checkbox\"\n aria-hidden=\"true\"\n style={{ pointerEvents: \"none\", display: \"inline-flex\" }}\n >\n <Checkbox\n size={size}\n checked={!!checked}\n disabled={!!disabled}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </span>\n )}\n {leadingControl === \"radio\" && (\n <span\n data-testid=\"ctxmenu-leading-radio\"\n aria-hidden=\"true\"\n style={{ pointerEvents: \"none\", display: \"inline-flex\" }}\n >\n <Radio\n size={size}\n checked={!!checked}\n disabled={!!disabled}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </span>\n )}\n {leadingIcon}\n {status}\n {iconWrapper}\n {slot}\n {slotContent}\n <span\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n minWidth: 0,\n }}\n >\n <Typography\n variant={variants.label}\n color={labelColor}\n noWrap={description === undefined}\n style={{\n ...(description === undefined\n ? { display: \"block\", minWidth: 0 }\n : {}),\n ...(sizeLabelOverride[size] ?? {}),\n }}\n >\n {label}\n </Typography>\n {description !== undefined && (\n <Typography\n variant={variants.description}\n color={theme.colors.content.tertiary}\n >\n {description}\n </Typography>\n )}\n </span>\n {(value !== undefined || hint !== undefined) && (\n <span\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-end\",\n }}\n >\n {value !== undefined && (\n <Typography\n variant={variants.label}\n color={theme.colors.content.secondary}\n style={sizeLabelOverride[size]}\n >\n {value}\n </Typography>\n )}\n {hint !== undefined && (\n <Typography\n variant={variants.description}\n color={theme.colors.content.tertiary}\n >\n {hint}\n </Typography>\n )}\n </span>\n )}\n {keyboardShortcut && (\n <Typography\n as=\"kbd\"\n variant={variants.description}\n color={theme.colors.content.tertiary}\n >\n {keyboardShortcut}\n </Typography>\n )}\n {hasSubmenu && (\n <SubmenuChevron\n color={theme.colors.content.tertiary}\n size={sizing.iconSize}\n />\n )}\n {trailingIcon}\n {hasSubmenu &&\n submenuOpen &&\n submenu &&\n submenuPos &&\n typeof document !== \"undefined\" &&\n createPortal(\n <div\n ref={submenuWrapperRef}\n data-xui-context-menu-portal={ctx?.menuId}\n onMouseEnter={cancelClose}\n onMouseLeave={scheduleClose}\n style={{\n position: \"fixed\",\n top: submenuPos.top,\n left: submenuPos.left,\n zIndex: 2000,\n }}\n >\n {submenu}\n </div>,\n document.body\n )}\n </div>\n );\n};\n\nconst HeadingCell: React.FC<\n ContextMenuHeadingItemProps & ThemeOverrideProps\n> = ({\n size: propSize,\n label,\n description,\n testID,\n themeMode,\n themeProductContext,\n \"data-testid\": testId,\n}) => {\n const { theme: rawTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = rawTheme as any;\n const ctx = useContextMenu();\n const size: ContextMenuSize = propSize ?? ctx?.size ?? \"md\";\n const sizing = theme.sizing.contextMenu(size);\n const variants = sizeToVariants[size];\n\n const id = useId();\n const registerCell = ctx?.registerCell;\n const unregisterCell = ctx?.unregisterCell;\n useEffect(() => {\n if (!registerCell || !unregisterCell) return;\n registerCell(id, { type: \"heading\" });\n return () => unregisterCell(id);\n }, [registerCell, unregisterCell, id]);\n\n return (\n <div\n role=\"presentation\"\n data-testid={testId || testID}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n paddingLeft: sizing.itemPaddingHorizontal,\n paddingRight: sizing.itemPaddingHorizontal,\n paddingTop: sizing.itemPaddingVertical,\n paddingBottom: sizing.itemPaddingVertical,\n }}\n >\n <Typography\n variant={variants.headingAccent}\n color={theme.colors.content.secondary}\n style={{ textTransform: \"uppercase\", letterSpacing: 0.5 }}\n >\n {label}\n </Typography>\n {description !== undefined && (\n <Typography\n variant={variants.description}\n color={theme.colors.content.tertiary}\n >\n {description}\n </Typography>\n )}\n </div>\n );\n};\n\nconst SearchCell: React.FC<ContextMenuSearchItemProps & ThemeOverrideProps> = ({\n size: propSize,\n value,\n onChange,\n onValueChange,\n placeholder = \"Search\",\n autoFocus,\n \"aria-label\": ariaLabel = \"Search options\",\n \"data-testid\": testId,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme: rawTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = rawTheme as any;\n const ctx = useContextMenu();\n const size: ContextMenuSize = propSize ?? ctx?.size ?? \"md\";\n const sizing = theme.sizing.contextMenu(size);\n\n const id = useId();\n const registerCell = ctx?.registerCell;\n const unregisterCell = ctx?.unregisterCell;\n useEffect(() => {\n if (!registerCell || !unregisterCell) return;\n registerCell(id, { type: \"search\" });\n return () => unregisterCell(id);\n }, [registerCell, unregisterCell, id]);\n\n return (\n <div\n style={{\n boxSizing: \"border-box\",\n paddingLeft: sizing.searchPaddingHorizontal,\n paddingRight: sizing.searchPaddingHorizontal,\n paddingTop: sizing.searchPaddingVertical,\n paddingBottom: sizing.searchPaddingVertical,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n paddingBottom: 6,\n borderBottom: `1px solid ${theme.colors.border.secondary}`,\n }}\n >\n <Search\n variant=\"line\"\n size={sizing.searchIconSize}\n color={theme.colors.control.input.placeholder}\n aria-hidden\n />\n <input\n type=\"search\"\n role=\"searchbox\"\n aria-label={ariaLabel}\n placeholder={placeholder}\n value={value ?? \"\"}\n autoFocus={autoFocus}\n onChange={(e) => {\n onChange?.(e);\n onValueChange?.(e.target.value);\n }}\n data-testid={testId || testID}\n style={{\n flex: 1,\n minWidth: 0,\n boxSizing: \"border-box\",\n border: \"none\",\n outline: \"none\",\n background: \"transparent\",\n padding: 0,\n color: theme.colors.content.primary,\n fontSize: sizing.searchFontSize,\n lineHeight: `${sizing.searchLineHeight}px`,\n }}\n />\n </div>\n </div>\n );\n};\n\nconst DividerCell: React.FC<\n ContextMenuDividerItemProps & ThemeOverrideProps\n> = ({ themeMode, themeProductContext, \"data-testid\": testId }) => {\n const { theme: rawTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = rawTheme as any;\n const ctx = useContextMenu();\n const id = useId();\n const registerCell = ctx?.registerCell;\n const unregisterCell = ctx?.unregisterCell;\n useEffect(() => {\n if (!registerCell || !unregisterCell) return;\n registerCell(id, { type: \"divider\" });\n return () => unregisterCell(id);\n }, [registerCell, unregisterCell, id]);\n return (\n <div\n role=\"separator\"\n data-testid={testId}\n style={{\n height: 1,\n backgroundColor: theme.colors.border.secondary,\n margin: \"4px 0\",\n }}\n />\n );\n};\n","import React, {\n useState,\n useRef,\n useEffect,\n useLayoutEffect,\n useCallback,\n} from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\nimport { ContextMenuItem } from \"./ContextMenuItem\";\nimport { useContextMenu } from \"./ContextMenuContext\";\nimport type { ContextMenuSubmenuProps } from \"./types\";\n\n/** Gap (px) between the parent menu panel and the submenu panel */\nconst SUBMENU_GAP = 4;\n/** Delay (ms) before the submenu opens on hover */\nconst OPEN_DELAY_MS = 200;\n/** Grace period (ms) before the submenu closes after the pointer leaves */\nconst CLOSE_GRACE_MS = 100;\n\n/** Module-level counter for stable, unique submenu IDs (React 16 compatible) */\nlet _submenuIdCounter = 0;\n\nexport const ContextMenuSubmenu: React.FC<ContextMenuSubmenuProps> = ({\n label,\n icon,\n disabled,\n children,\n size: propSize,\n \"data-testid\": testId = \"context-menu-submenu\",\n}) => {\n const { theme } = useDesignSystem();\n const xuiTheme = theme as any;\n const context = useContextMenu();\n const size = propSize || context?.size || \"md\";\n const sizeStyles = xuiTheme.sizing.contextMenu(size);\n const borderRadius =\n xuiTheme.shape?.contextMenu?.[size]?.borderRadius ??\n xuiTheme.radius?.button ??\n 8;\n\n const submenuIdRef = useRef<string | null>(null);\n if (submenuIdRef.current === null) {\n submenuIdRef.current = `xui-cm-submenu-${(_submenuIdCounter += 1)}`;\n }\n const submenuId = submenuIdRef.current;\n\n const [isOpen, setIsOpen] = useState(false);\n const [visible, setVisible] = useState(false);\n const [openLeft, setOpenLeft] = useState(false);\n const [topOffset, setTopOffset] = useState(0);\n\n const triggerRef = useRef<HTMLDivElement>(null);\n const submenuRef = useRef<HTMLDivElement>(null);\n const openTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const clearTimers = useCallback(() => {\n if (openTimerRef.current) clearTimeout(openTimerRef.current);\n if (closeTimerRef.current) clearTimeout(closeTimerRef.current);\n }, []);\n\n // Close this submenu when a sibling submenu becomes active (Bug #3 fix)\n useEffect(() => {\n if (!context?.activeSubmenuId) return;\n if (context.activeSubmenuId !== submenuId) {\n setIsOpen(false);\n }\n }, [context?.activeSubmenuId, submenuId]);\n\n const calculatePlacement = useCallback(() => {\n if (!triggerRef.current) return;\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const estimatedWidth = sizeStyles.minWidth + 32;\n const wouldOverflowRight =\n triggerRect.right + estimatedWidth + SUBMENU_GAP > window.innerWidth - 8;\n // Bug #1/#2 fix: only flip left when there is actually space on the left\n const hasSpaceOnLeft =\n triggerRect.left - SUBMENU_GAP - estimatedWidth >= 8;\n setOpenLeft(wouldOverflowRight && hasSpaceOnLeft);\n setTopOffset(0);\n }, [sizeStyles.minWidth]);\n\n useLayoutEffect(() => {\n if (!isOpen || !submenuRef.current || !triggerRef.current) return;\n\n const submenuRect = submenuRef.current.getBoundingClientRect();\n const triggerRect = triggerRef.current.getBoundingClientRect();\n\n const wouldOverflowRight =\n triggerRect.right + submenuRect.width + SUBMENU_GAP >\n window.innerWidth - 8;\n const hasSpaceOnLeft =\n triggerRect.left - SUBMENU_GAP - submenuRect.width >= 8;\n setOpenLeft(wouldOverflowRight && hasSpaceOnLeft);\n\n const overflowBottom =\n triggerRect.top + submenuRect.height - (window.innerHeight - 8);\n if (overflowBottom > 0) {\n setTopOffset(-Math.min(overflowBottom, triggerRect.top - 8));\n } else {\n setTopOffset(0);\n }\n }, [isOpen]);\n\n useEffect(() => {\n if (!isOpen) {\n setVisible(false);\n return;\n }\n const raf = requestAnimationFrame(() => setVisible(true));\n return () => cancelAnimationFrame(raf);\n }, [isOpen]);\n\n useEffect(() => () => clearTimers(), [clearTimers]);\n\n const handleTriggerEnter = () => {\n if (disabled) return;\n clearTimers();\n openTimerRef.current = setTimeout(() => {\n calculatePlacement();\n setIsOpen(true);\n context?.setActiveSubmenuId(submenuId);\n }, OPEN_DELAY_MS);\n };\n\n const handleTriggerLeave = () => {\n clearTimers();\n closeTimerRef.current = setTimeout(() => {\n setIsOpen(false);\n if (context?.activeSubmenuId === submenuId) {\n context.setActiveSubmenuId(null);\n }\n }, CLOSE_GRACE_MS);\n };\n\n const handleSubmenuEnter = () => clearTimers();\n\n const handleSubmenuLeave = () => {\n clearTimers();\n closeTimerRef.current = setTimeout(() => {\n setIsOpen(false);\n if (context?.activeSubmenuId === submenuId) {\n context.setActiveSubmenuId(null);\n }\n }, CLOSE_GRACE_MS);\n };\n\n const submenuPositionStyle = openLeft\n ? { right: `calc(100% + ${SUBMENU_GAP}px)` }\n : { left: `calc(100% + ${SUBMENU_GAP}px)` };\n\n return (\n <div\n ref={triggerRef}\n style={{ position: \"relative\" }}\n onMouseEnter={handleTriggerEnter}\n onMouseLeave={handleTriggerLeave}\n data-testid={testId}\n >\n <ContextMenuItem\n type=\"option\"\n label={label}\n leadingIcon={icon}\n disabled={disabled}\n hasSubmenu\n size={size}\n data-testid={`${testId}-trigger`}\n />\n\n {isOpen && (\n <div\n ref={submenuRef}\n onMouseEnter={handleSubmenuEnter}\n onMouseLeave={handleSubmenuLeave}\n style={{\n position: \"absolute\",\n top: topOffset,\n ...submenuPositionStyle,\n zIndex: 1001,\n opacity: visible ? 1 : 0,\n transform: visible\n ? \"translateX(0)\"\n : openLeft\n ? \"translateX(4px)\"\n : \"translateX(-4px)\",\n transition: \"opacity 100ms ease, transform 100ms ease\",\n }}\n data-testid={`${testId}-content`}\n >\n <Box\n role=\"menu\"\n backgroundColor={xuiTheme.colors.background.secondary}\n borderColor={xuiTheme.colors.border.secondary}\n borderWidth={1}\n borderRadius={borderRadius}\n paddingVertical={sizeStyles.paddingVertical}\n style={{\n boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\",\n minWidth: sizeStyles.minWidth,\n }}\n >\n {children}\n </Box>\n </div>\n )}\n </div>\n );\n};\n\nContextMenuSubmenu.displayName = \"ContextMenuSubmenu\";\n","import { useLayoutEffect, useState, type RefObject } from \"react\";\nimport type { ContextMenuPlacement } from \"../types\";\n\ninterface UseContextMenuPositionOptions {\n triggerRef: RefObject<HTMLElement | null>;\n panelRef: RefObject<HTMLElement | null>;\n containerRef: RefObject<HTMLElement | null>;\n isOpen: boolean;\n placement?: ContextMenuPlacement;\n offset?: number;\n}\n\ninterface ResolvedPosition {\n top: number;\n left: number;\n placement: ContextMenuPlacement;\n}\n\nconst splitPlacement = (\n placement: ContextMenuPlacement\n): { vertical: \"top\" | \"bottom\"; horizontal: \"start\" | \"end\" | \"center\" } => {\n const [vertical, horizontal] = placement.split(\"-\") as [\n \"top\" | \"bottom\",\n \"start\" | \"end\" | \"center\",\n ];\n return { vertical, horizontal };\n};\n\nconst joinPlacement = (\n vertical: \"top\" | \"bottom\",\n horizontal: \"start\" | \"end\" | \"center\"\n): ContextMenuPlacement => `${vertical}-${horizontal}` as ContextMenuPlacement;\n\nexport const useContextMenuPosition = ({\n triggerRef,\n panelRef,\n containerRef,\n isOpen,\n placement = \"bottom-start\",\n offset = 4,\n}: UseContextMenuPositionOptions): ResolvedPosition | undefined => {\n const [resolved, setResolved] = useState<ResolvedPosition | undefined>();\n\n useLayoutEffect(() => {\n if (!isOpen) {\n setResolved(undefined);\n return;\n }\n\n const compute = () => {\n const trigger = triggerRef.current;\n const panel = panelRef.current;\n const container = containerRef.current;\n if (!trigger || !panel) return;\n\n const triggerRect = trigger.getBoundingClientRect();\n const panelRect = panel.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n let { vertical, horizontal } = splitPlacement(placement);\n\n const computeTop = (v: \"top\" | \"bottom\") =>\n v === \"bottom\"\n ? triggerRect.bottom + offset\n : triggerRect.top - panelRect.height - offset;\n\n const computeLeft = (h: \"start\" | \"end\" | \"center\") => {\n if (h === \"center\")\n return triggerRect.left + triggerRect.width / 2 - panelRect.width / 2;\n return h === \"start\"\n ? triggerRect.left\n : triggerRect.right - panelRect.width;\n };\n\n let top = computeTop(vertical);\n const wantedBottom = top + panelRect.height;\n if (top < 0 || wantedBottom > viewportHeight) {\n const flipped = vertical === \"bottom\" ? \"top\" : \"bottom\";\n const flippedTop = computeTop(flipped);\n const flippedBottom = flippedTop + panelRect.height;\n if (flippedTop >= 0 && flippedBottom <= viewportHeight) {\n vertical = flipped;\n top = flippedTop;\n }\n }\n\n let left = computeLeft(horizontal);\n if (horizontal === \"center\") {\n const maxLeft = viewportWidth - panelRect.width;\n left = maxLeft >= 0 ? Math.min(Math.max(left, 0), maxLeft) : 0;\n } else {\n const wantedRight = left + panelRect.width;\n if (left < 0 || wantedRight > viewportWidth) {\n const flipped = horizontal === \"start\" ? \"end\" : \"start\";\n const flippedLeft = computeLeft(flipped);\n const flippedRight = flippedLeft + panelRect.width;\n if (flippedLeft >= 0 && flippedRight <= viewportWidth) {\n horizontal = flipped;\n left = flippedLeft;\n }\n }\n }\n\n // Convert viewport coordinates to local (absolute-positioning) coords\n // relative to the container. Reading containerRect here (inside the\n // layout effect) guarantees we measure at the same time as the trigger\n // and panel, avoiding stale-rect issues from intermediate renders.\n if (container) {\n const containerRect = container.getBoundingClientRect();\n const cOffsetW = container.offsetWidth;\n const cOffsetH = container.offsetHeight;\n const scaleX = cOffsetW > 0 ? containerRect.width / cOffsetW : 1;\n const scaleY = cOffsetH > 0 ? containerRect.height / cOffsetH : 1;\n left = (left - containerRect.left) / (scaleX || 1);\n top = (top - containerRect.top) / (scaleY || 1);\n }\n\n const next = {\n top,\n left,\n placement: joinPlacement(vertical, horizontal),\n };\n setResolved((prev) =>\n prev &&\n prev.top === next.top &&\n prev.left === next.left &&\n prev.placement === next.placement\n ? prev\n : next\n );\n };\n\n compute();\n // No scroll listener: the menu dismisses on scroll (see ContextMenu), so\n // following the trigger would be dead work. Resize still repositions an\n // open menu.\n const onResize = () => compute();\n window.addEventListener(\"resize\", onResize);\n\n return () => {\n window.removeEventListener(\"resize\", onResize);\n };\n }, [isOpen, placement, offset, triggerRef, panelRef, containerRef]);\n\n return resolved;\n};\n","import { useCallback, type RefObject } from \"react\";\n\nexport type CellType = \"option\" | \"search\" | \"heading\" | \"divider\";\n\nexport interface CellMeta {\n type: CellType;\n onSelect?: () => void;\n disabled?: boolean;\n}\n\ninterface UseKeyboardNavigationOptions {\n isOpen: boolean;\n cells: Array<{ id: string; meta: CellMeta }>;\n activeIndex: number;\n setActiveIndex: (index: number) => void;\n onClose: () => void;\n triggerRef?: RefObject<HTMLElement | null>;\n}\n\nconst isNavigableOption = (meta: CellMeta) =>\n meta.type === \"option\" && !meta.disabled;\n\nconst isTextInputTarget = (target: EventTarget | null): boolean => {\n if (!(target instanceof HTMLElement)) return false;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") return true;\n return target.getAttribute(\"role\") === \"searchbox\";\n};\n\nexport const useKeyboardNavigation = ({\n isOpen,\n cells,\n activeIndex,\n setActiveIndex,\n onClose,\n triggerRef,\n}: UseKeyboardNavigationOptions) => {\n const findFirstOption = useCallback(() => {\n for (let i = 0; i < cells.length; i += 1) {\n if (isNavigableOption(cells[i].meta)) return i;\n }\n return -1;\n }, [cells]);\n\n const findLastOption = useCallback(() => {\n for (let i = cells.length - 1; i >= 0; i -= 1) {\n if (isNavigableOption(cells[i].meta)) return i;\n }\n return -1;\n }, [cells]);\n\n const findNextOption = useCallback(\n (from: number) => {\n const len = cells.length;\n if (len === 0) return -1;\n for (let step = 1; step <= len; step += 1) {\n const idx = (from + step + len) % len;\n if (isNavigableOption(cells[idx].meta)) return idx;\n }\n return -1;\n },\n [cells]\n );\n\n const findPrevOption = useCallback(\n (from: number) => {\n const len = cells.length;\n if (len === 0) return -1;\n for (let step = 1; step <= len; step += 1) {\n const idx = (from - step + len * 2) % len;\n if (isNavigableOption(cells[idx].meta)) return idx;\n }\n return -1;\n },\n [cells]\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (!isOpen) return;\n\n switch (event.key) {\n case \"ArrowDown\": {\n event.preventDefault();\n const next =\n activeIndex < 0 ? findFirstOption() : findNextOption(activeIndex);\n if (next >= 0) setActiveIndex(next);\n break;\n }\n case \"ArrowUp\": {\n event.preventDefault();\n const prev =\n activeIndex < 0 ? findLastOption() : findPrevOption(activeIndex);\n if (prev >= 0) setActiveIndex(prev);\n break;\n }\n case \"Home\": {\n event.preventDefault();\n const first = findFirstOption();\n if (first >= 0) setActiveIndex(first);\n break;\n }\n case \"End\": {\n event.preventDefault();\n const last = findLastOption();\n if (last >= 0) setActiveIndex(last);\n break;\n }\n case \"Enter\":\n case \" \": {\n if (event.defaultPrevented) break;\n if (event.key === \" \" && isTextInputTarget(event.target)) break;\n if (event.key === \" \") event.preventDefault();\n if (activeIndex >= 0 && activeIndex < cells.length) {\n const meta = cells[activeIndex].meta;\n if (isNavigableOption(meta)) meta.onSelect?.();\n }\n break;\n }\n case \"Escape\": {\n event.preventDefault();\n onClose();\n triggerRef?.current?.focus();\n break;\n }\n case \"Tab\": {\n onClose();\n break;\n }\n default:\n break;\n }\n },\n [\n isOpen,\n cells,\n activeIndex,\n setActiveIndex,\n onClose,\n triggerRef,\n findFirstOption,\n findLastOption,\n findNextOption,\n findPrevOption,\n ]\n );\n\n return { handleKeyDown };\n};\n"],"mappings":"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","names":["import_react","import_xui_core","import_react","import_jsx_runtime","React","import_react","import_xui_core","import_jsx_runtime","SUBMENU_GAP","import_react","import_react","import_jsx_runtime"]}
|