@xsolla/xui-context-menu 0.173.1 → 0.174.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.
@@ -125,6 +125,8 @@ interface ContextMenuContextValue {
125
125
  cellsVersion: number;
126
126
  query: string;
127
127
  setQuery: (query: string) => void;
128
+ activeSubmenuId: string | null;
129
+ setActiveSubmenuId: (id: string | null) => void;
128
130
  }
129
131
  interface ContextMenuSizing {
130
132
  paddingVertical: number;
package/native/index.d.ts CHANGED
@@ -125,6 +125,8 @@ interface ContextMenuContextValue {
125
125
  cellsVersion: number;
126
126
  query: string;
127
127
  setQuery: (query: string) => void;
128
+ activeSubmenuId: string | null;
129
+ setActiveSubmenuId: (id: string | null) => void;
128
130
  }
129
131
  interface ContextMenuSizing {
130
132
  paddingVertical: number;
package/native/index.js CHANGED
@@ -909,6 +909,7 @@ var import_jsx_runtime3 = require("react/jsx-runtime");
909
909
  var SUBMENU_GAP2 = 4;
910
910
  var OPEN_DELAY_MS = 200;
911
911
  var CLOSE_GRACE_MS = 100;
912
+ var _submenuIdCounter = 0;
912
913
  var ContextMenuSubmenu = ({
913
914
  label,
914
915
  icon,
@@ -923,6 +924,11 @@ var ContextMenuSubmenu = ({
923
924
  const size = propSize || context?.size || "md";
924
925
  const sizeStyles = xuiTheme.sizing.contextMenu(size);
925
926
  const borderRadius = xuiTheme.shape?.contextMenu?.[size]?.borderRadius ?? xuiTheme.radius?.button ?? 8;
927
+ const submenuIdRef = (0, import_react3.useRef)(null);
928
+ if (submenuIdRef.current === null) {
929
+ submenuIdRef.current = `xui-cm-submenu-${_submenuIdCounter += 1}`;
930
+ }
931
+ const submenuId = submenuIdRef.current;
926
932
  const [isOpen, setIsOpen] = (0, import_react3.useState)(false);
927
933
  const [visible, setVisible] = (0, import_react3.useState)(false);
928
934
  const [openLeft, setOpenLeft] = (0, import_react3.useState)(false);
@@ -935,12 +941,19 @@ var ContextMenuSubmenu = ({
935
941
  if (openTimerRef.current) clearTimeout(openTimerRef.current);
936
942
  if (closeTimerRef.current) clearTimeout(closeTimerRef.current);
937
943
  }, []);
944
+ (0, import_react3.useEffect)(() => {
945
+ if (!context?.activeSubmenuId) return;
946
+ if (context.activeSubmenuId !== submenuId) {
947
+ setIsOpen(false);
948
+ }
949
+ }, [context?.activeSubmenuId, submenuId]);
938
950
  const calculatePlacement = (0, import_react3.useCallback)(() => {
939
951
  if (!triggerRef.current) return;
940
952
  const triggerRect = triggerRef.current.getBoundingClientRect();
941
953
  const estimatedWidth = sizeStyles.minWidth + 32;
942
954
  const wouldOverflowRight = triggerRect.right + estimatedWidth + SUBMENU_GAP2 > window.innerWidth - 8;
943
- setOpenLeft(wouldOverflowRight);
955
+ const hasSpaceOnLeft = triggerRect.left - SUBMENU_GAP2 - estimatedWidth >= 8;
956
+ setOpenLeft(wouldOverflowRight && hasSpaceOnLeft);
944
957
  setTopOffset(0);
945
958
  }, [sizeStyles.minWidth]);
946
959
  (0, import_react3.useLayoutEffect)(() => {
@@ -948,7 +961,8 @@ var ContextMenuSubmenu = ({
948
961
  const submenuRect = submenuRef.current.getBoundingClientRect();
949
962
  const triggerRect = triggerRef.current.getBoundingClientRect();
950
963
  const wouldOverflowRight = triggerRect.right + submenuRect.width + SUBMENU_GAP2 > window.innerWidth - 8;
951
- setOpenLeft(wouldOverflowRight);
964
+ const hasSpaceOnLeft = triggerRect.left - SUBMENU_GAP2 - submenuRect.width >= 8;
965
+ setOpenLeft(wouldOverflowRight && hasSpaceOnLeft);
952
966
  const overflowBottom = triggerRect.top + submenuRect.height - (window.innerHeight - 8);
953
967
  if (overflowBottom > 0) {
954
968
  setTopOffset(-Math.min(overflowBottom, triggerRect.top - 8));
@@ -971,16 +985,27 @@ var ContextMenuSubmenu = ({
971
985
  openTimerRef.current = setTimeout(() => {
972
986
  calculatePlacement();
973
987
  setIsOpen(true);
988
+ context?.setActiveSubmenuId(submenuId);
974
989
  }, OPEN_DELAY_MS);
975
990
  };
976
991
  const handleTriggerLeave = () => {
977
992
  clearTimers();
978
- closeTimerRef.current = setTimeout(() => setIsOpen(false), CLOSE_GRACE_MS);
993
+ closeTimerRef.current = setTimeout(() => {
994
+ setIsOpen(false);
995
+ if (context?.activeSubmenuId === submenuId) {
996
+ context.setActiveSubmenuId(null);
997
+ }
998
+ }, CLOSE_GRACE_MS);
979
999
  };
980
1000
  const handleSubmenuEnter = () => clearTimers();
981
1001
  const handleSubmenuLeave = () => {
982
1002
  clearTimers();
983
- closeTimerRef.current = setTimeout(() => setIsOpen(false), CLOSE_GRACE_MS);
1003
+ closeTimerRef.current = setTimeout(() => {
1004
+ setIsOpen(false);
1005
+ if (context?.activeSubmenuId === submenuId) {
1006
+ context.setActiveSubmenuId(null);
1007
+ }
1008
+ }, CLOSE_GRACE_MS);
984
1009
  };
985
1010
  const submenuPositionStyle = openLeft ? { right: `calc(100% + ${SUBMENU_GAP2}px)` } : { left: `calc(100% + ${SUBMENU_GAP2}px)` };
986
1011
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
@@ -1311,6 +1336,7 @@ var ContextMenuRoot = (0, import_react6.forwardRef)(
1311
1336
  const [cellsVersion, setCellsVersion] = (0, import_react6.useState)(0);
1312
1337
  const [query, setQuery] = (0, import_react6.useState)("");
1313
1338
  const [debouncedQuery, setDebouncedQuery] = (0, import_react6.useState)("");
1339
+ const [activeSubmenuId, setActiveSubmenuId] = (0, import_react6.useState)(null);
1314
1340
  const containerRef = (0, import_react6.useRef)(null);
1315
1341
  const triggerRef = (0, import_react6.useRef)(null);
1316
1342
  const panelRef = (0, import_react6.useRef)(null);
@@ -1377,6 +1403,7 @@ var ContextMenuRoot = (0, import_react6.forwardRef)(
1377
1403
  setCellsVersion((version) => version + 1);
1378
1404
  setQuery("");
1379
1405
  setDebouncedQuery("");
1406
+ setActiveSubmenuId(null);
1380
1407
  }
1381
1408
  }, [isOpen]);
1382
1409
  (0, import_react6.useEffect)(() => {
@@ -1431,7 +1458,9 @@ var ContextMenuRoot = (0, import_react6.forwardRef)(
1431
1458
  getCellIndex,
1432
1459
  cellsVersion,
1433
1460
  query,
1434
- setQuery
1461
+ setQuery,
1462
+ activeSubmenuId,
1463
+ setActiveSubmenuId
1435
1464
  }),
1436
1465
  [
1437
1466
  size,
@@ -1442,7 +1471,8 @@ var ContextMenuRoot = (0, import_react6.forwardRef)(
1442
1471
  unregisterCell,
1443
1472
  getCellIndex,
1444
1473
  cellsVersion,
1445
- query
1474
+ query,
1475
+ activeSubmenuId
1446
1476
  ]
1447
1477
  );
1448
1478
  const renderPresetItem = (item, index) => {
@@ -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 { useDesignSystem, 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 ContextMenuProps,\n} from \"./types\";\n\ntype CellEntry = { id: string; meta: CellMeta };\n\nconst DEFAULT_EMPTY_MESSAGE = \"No results\";\nconst SEARCH_DEBOUNCE_MS = 200;\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 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 } = useDesignSystem();\n const xuiTheme = theme as any;\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 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 =\n xuiTheme.shape?.contextMenu?.[size]?.borderRadius ??\n xuiTheme.radius?.button ??\n 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 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 }\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 }),\n [\n size,\n menuId,\n closeMenu,\n activeIndex,\n registerCell,\n unregisterCell,\n getCellIndex,\n cellsVersion,\n query,\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 triggerNode =\n trigger && isValidElement(trigger) ? (\n cloneElement(trigger as React.ReactElement<any>, {\n ref: assignTriggerRef,\n \"aria-haspopup\": \"menu\",\n \"aria-expanded\": isOpen ? \"true\" : \"false\",\n onClick: (event: React.MouseEvent) => {\n trigger.props.onClick?.(event);\n if (!event.defaultPrevented) toggleMenu();\n },\n })\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={positioned?.placement ?? placement}\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: \"0 4px 12px rgba(0,0,0,0.15)\",\n maxHeight,\n overflowY: \"auto\",\n outline: \"none\",\n }}\n >\n {renderContent()}\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\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 [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 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 setOpenLeft(wouldOverflowRight);\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 setOpenLeft(wouldOverflowRight);\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 }, OPEN_DELAY_MS);\n };\n\n const handleTriggerLeave = () => {\n clearTimers();\n closeTimerRef.current = setTimeout(() => setIsOpen(false), CLOSE_GRACE_MS);\n };\n\n const handleSubmenuEnter = () => clearTimers();\n\n const handleSubmenuLeave = () => {\n clearTimers();\n closeTimerRef.current = setTimeout(() => setIsOpen(false), 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\" } => {\n const [vertical, horizontal] = placement.split(\"-\") as [\n \"top\" | \"bottom\",\n \"start\" | \"end\",\n ];\n return { vertical, horizontal };\n};\n\nconst joinPlacement = (\n vertical: \"top\" | \"bottom\",\n horizontal: \"start\" | \"end\"\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\") =>\n h === \"start\" ? triggerRect.left : triggerRect.right - panelRect.width;\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 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 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 { useDesignSystem, 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 ContextMenuProps,\n} from \"./types\";\n\ntype CellEntry = { id: string; meta: CellMeta };\n\nconst DEFAULT_EMPTY_MESSAGE = \"No results\";\nconst SEARCH_DEBOUNCE_MS = 200;\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 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 } = useDesignSystem();\n const xuiTheme = theme as any;\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 =\n xuiTheme.shape?.contextMenu?.[size]?.borderRadius ??\n xuiTheme.radius?.button ??\n 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 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 triggerNode =\n trigger && isValidElement(trigger) ? (\n cloneElement(trigger as React.ReactElement<any>, {\n ref: assignTriggerRef,\n \"aria-haspopup\": \"menu\",\n \"aria-expanded\": isOpen ? \"true\" : \"false\",\n onClick: (event: React.MouseEvent) => {\n trigger.props.onClick?.(event);\n if (!event.defaultPrevented) toggleMenu();\n },\n })\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={positioned?.placement ?? placement}\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: \"0 4px 12px rgba(0,0,0,0.15)\",\n maxHeight,\n overflowY: \"auto\",\n outline: \"none\",\n }}\n >\n {renderContent()}\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\" } => {\n const [vertical, horizontal] = placement.split(\"-\") as [\n \"top\" | \"bottom\",\n \"start\" | \"end\",\n ];\n return { vertical, horizontal };\n};\n\nconst joinPlacement = (\n vertical: \"top\" | \"bottom\",\n horizontal: \"start\" | \"end\"\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\") =>\n h === \"start\" ? triggerRect.left : triggerRect.right - panelRect.width;\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 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 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"]}