{"version":3,"file":"menu-content.cjs","sources":["../../../components/menu/menu-content.tsx"],"sourcesContent":["'use client';\n\nimport {\n  Autocomplete as AutocompletePrimitive,\n  Menu as MenuPrimitive\n} from '@base-ui/react';\nimport { cx } from 'class-variance-authority';\nimport { KeyboardEvent, useCallback, useRef } from 'react';\nimport styles from './menu.module.css';\nimport { useMenuContext } from './menu-root';\nimport {\n  dispatchKeyboardEvent,\n  isElementSubMenuOpen,\n  isElementSubMenuTrigger,\n  KEYCODES\n} from './utils';\n\nexport interface MenuContentProps\n  extends Omit<\n      MenuPrimitive.Positioner.Props,\n      'render' | 'className' | 'style'\n    >,\n    MenuPrimitive.Popup.Props {\n  searchPlaceholder?: string;\n}\n\nexport function MenuContent({\n  ref,\n  className,\n  children,\n  searchPlaceholder = 'Search...',\n  render,\n  finalFocus,\n  style,\n  sideOffset = 4,\n  align = 'start',\n  onFocus,\n  ...positionerProps\n}: MenuContentProps) {\n  const {\n    autocomplete,\n    inputValue,\n    onInputValueChange,\n    inputRef,\n    isInitialRender,\n    parent\n  } = useMenuContext();\n\n  const focusInput = useCallback(() => {\n    if (document?.activeElement !== inputRef?.current)\n      inputRef?.current?.focus();\n  }, [inputRef]);\n  const highlightedItem = useRef<\n    [index: number, reason: 'keyboard' | 'pointer' | 'none']\n  >([-1, 'none']);\n  const containerRef = useRef<HTMLDivElement>(null);\n\n  const highlightFirstItem = useCallback(() => {\n    if (!isInitialRender?.current) return;\n    isInitialRender.current = false;\n    const item = containerRef.current?.querySelector('[role=\"option\"]');\n    if (!item) return;\n    item.dispatchEvent(new PointerEvent('mousemove', { bubbles: true }));\n  }, [isInitialRender]);\n\n  const checkAndOpenSubMenu = useCallback(() => {\n    if (highlightedItem.current[0] === -1) return;\n    const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n    const item = items?.[highlightedItem.current[0]];\n    if (!item || !isElementSubMenuTrigger(item)) return;\n    dispatchKeyboardEvent(item, KEYCODES.ARROW_RIGHT);\n  }, []);\n\n  const checkAndCloseSubMenu = useCallback(\n    (e: KeyboardEvent<HTMLInputElement>) => {\n      if (highlightedItem.current[0] === -1) return;\n      const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n      const item = items?.[highlightedItem.current[0]];\n      if (\n        !item ||\n        !isElementSubMenuTrigger(item) ||\n        !isElementSubMenuOpen(item)\n      )\n        return;\n      dispatchKeyboardEvent(item, KEYCODES.ESCAPE);\n      e.stopPropagation();\n    },\n    []\n  );\n\n  const blurStaleMenuItem = useCallback((index: number) => {\n    const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n    const item = items?.[index];\n    if (!item || !isElementSubMenuTrigger(item) || !isElementSubMenuOpen(item))\n      return;\n    dispatchKeyboardEvent(item, KEYCODES.ESCAPE);\n    item.dispatchEvent(new PointerEvent('pointerout', { bubbles: true }));\n  }, []);\n\n  return (\n    <MenuPrimitive.Portal>\n      <MenuPrimitive.Positioner\n        data-slot='menu-positioner'\n        className={styles.positioner}\n        sideOffset={sideOffset}\n        align={align}\n        {...positionerProps}\n      >\n        <MenuPrimitive.Popup\n          ref={ref}\n          data-slot='menu-content'\n          className={cx(\n            styles.content,\n            autocomplete && styles.comboboxContainer,\n            className\n          )}\n          style={style}\n          render={render}\n          finalFocus={finalFocus}\n          role={autocomplete ? 'dialog' : 'menu'}\n          onFocus={\n            autocomplete || parent?.autocomplete\n              ? e => {\n                  focusInput();\n                  e.stopPropagation();\n                  highlightFirstItem();\n                  onFocus?.(e);\n                }\n              : undefined\n          }\n        >\n          {autocomplete ? (\n            <AutocompletePrimitive.Root\n              inline\n              open\n              value={inputValue}\n              onValueChange={(value: string) => onInputValueChange?.(value)}\n              autoHighlight={!!inputValue?.length}\n              mode='none'\n              loopFocus={false}\n              onItemHighlighted={(value, eventDetails) => {\n                if (\n                  highlightedItem.current[1] === 'pointer' &&\n                  eventDetails.reason === 'keyboard'\n                ) {\n                  // focus moved using keyboard after using pointer\n                  blurStaleMenuItem(highlightedItem.current[0]);\n                }\n                highlightedItem.current = [\n                  eventDetails.index,\n                  eventDetails.reason\n                ];\n              }}\n            >\n              <AutocompletePrimitive.Input\n                data-slot='menu-search-input'\n                placeholder={searchPlaceholder}\n                className={styles.comboboxInput}\n                ref={inputRef}\n                onPointerEnter={e => {\n                  focusInput();\n                }}\n                onKeyDown={e => {\n                  if (e.key === 'ArrowLeft') return;\n                  if (e.key === 'Escape') return checkAndCloseSubMenu(e);\n                  if (e.key === 'ArrowRight' || e.key === 'Enter')\n                    checkAndOpenSubMenu();\n                  e.stopPropagation();\n                }}\n                tabIndex={-1}\n              />\n              <AutocompletePrimitive.List\n                data-slot='menu-search-list'\n                className={styles.comboboxContent}\n                ref={containerRef}\n              >\n                {children}\n              </AutocompletePrimitive.List>\n            </AutocompletePrimitive.Root>\n          ) : (\n            children\n          )}\n        </MenuPrimitive.Popup>\n      </MenuPrimitive.Positioner>\n    </MenuPrimitive.Portal>\n  );\n}\nMenuContent.displayName = 'Menu.Content';\n\nexport function MenuSubContent(props: MenuContentProps) {\n  return <MenuContent sideOffset={2} {...props} />;\n}\nMenuSubContent.displayName = 'Menu.SubmenuContent';\n"],"names":[],"mappings":";;;;;;;;;;;AA0BgB;AAad;AASA;AACE;AACE;AACJ;;AAIA;AAEA;;;AAEE;;AAEA;;AACA;AACF;AAEA;;;;AAGE;AACA;;AACA;;AAGF;;;;AAII;AACA;;;;AAMA;;;AAMJ;;AAEE;AACA;;AAEA;AACA;;AAGF;;AAwBgB;;AAEA;AACA;;;AAeF;AAEE;;;;;AAMA;AACA;;;AAUA;AACF;AAEE;;AACA;AAAwB;;AAEtB;;AAEJ;AAkBhB;AACA;AAEM;;AAEN;AACA;;;"}