{"version":3,"file":"MenubarTarget.mjs","names":[],"sources":["../../../../src/components/Menubar/MenubarTarget/MenubarTarget.tsx"],"sourcesContent":["import {\n  createEventHandler,\n  ElementProps,\n  MantineStyleProp,\n  useDirection,\n  useProps,\n} from '../../../core';\nimport { Popover } from '../../Popover';\nimport { UnstyledButton } from '../../UnstyledButton';\nimport { useMenubarContext, useMenubarMenuContext } from '../Menubar.context';\n\nexport interface MenubarTargetProps extends ElementProps<'button'> {\n  'data-disabled'?: boolean;\n\n  /** Target label */\n  children: React.ReactNode;\n\n  /** Inline styles applied to the target button */\n  style?: MantineStyleProp;\n\n  /** Key of the prop used to get element ref, useful for forwarding refs to custom components @default 'ref' */\n  refProp?: string;\n}\n\nconst defaultProps = {\n  refProp: 'ref',\n} satisfies Partial<MenubarTargetProps>;\n\nfunction isPrintableKey(event: React.KeyboardEvent) {\n  return (\n    event.key.length === 1 && event.key !== ' ' && !event.ctrlKey && !event.metaKey && !event.altKey\n  );\n}\n\nfunction getTargetLabel(node: HTMLElement) {\n  return (node.textContent ?? '').trim().toLowerCase();\n}\n\nexport function MenubarTarget(props: MenubarTargetProps) {\n  const {\n    children,\n    refProp,\n    className,\n    style,\n    disabled,\n    'data-disabled': dataDisabled,\n    onClick,\n    onMouseEnter,\n    onMouseLeave,\n    onFocus,\n    onKeyDown,\n    ...others\n  } = useProps('MenubarTarget', defaultProps, props);\n\n  const ctx = useMenubarContext();\n  const menuCtx = useMenubarMenuContext();\n  const { dir } = useDirection();\n\n  const isDisabled = disabled || dataDisabled;\n  const isActive = ctx.activeIndex === menuCtx.index;\n\n  // Before the menu indexes resolve from the DOM (first render / SSR HTML), every target\n  // would otherwise compute `tabIndex={-1}`, leaving the menubar with no tab stop until\n  // effects run. Keep unresolved targets focusable so keyboard users can enter the menubar.\n  const isUnresolvedTabStop = menuCtx.index === -1 && !isDisabled;\n\n  const moveToAdjacent = (direction: 1 | -1) => {\n    const nextIndex = ctx.getAdjacentIndex(menuCtx.index, direction);\n    ctx.setActiveIndex(nextIndex);\n    ctx.focusTarget(nextIndex);\n    if (ctx.openIndex !== null) {\n      ctx.openMenu(nextIndex, 'click');\n    }\n  };\n\n  const openAndFocusItem = (itemPosition: 'first' | 'last') => {\n    ctx.openMenu(menuCtx.index, 'click');\n    ctx.setActiveIndex(menuCtx.index);\n    ctx.focusMenuItem(menuCtx.index, itemPosition);\n  };\n\n  const typeAhead = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n    const targets = ctx.getTargets();\n    if (targets.length === 0) {\n      return;\n    }\n\n    const char = event.key.toLowerCase();\n    for (let offset = 1; offset <= targets.length; offset += 1) {\n      const index = (menuCtx.index + offset) % targets.length;\n      const node = targets[index];\n      if (\n        node &&\n        !node.disabled &&\n        !node.hasAttribute('data-disabled') &&\n        getTargetLabel(node).startsWith(char)\n      ) {\n        event.preventDefault();\n        ctx.setActiveIndex(index);\n        node.focus();\n        if (ctx.openIndex !== null) {\n          ctx.openMenu(index, 'click');\n        }\n        break;\n      }\n    }\n  };\n\n  const handleClick = createEventHandler<any>(onClick, () => {\n    if (isDisabled) {\n      return;\n    }\n    if (ctx.openIndex === menuCtx.index && ctx.getOpenSource() !== 'hover') {\n      ctx.closeMenu();\n    } else {\n      ctx.openMenu(menuCtx.index, 'click');\n      ctx.setActiveIndex(menuCtx.index);\n    }\n  });\n\n  const handleMouseEnter = createEventHandler<any>(onMouseEnter, () => {\n    if (isDisabled) {\n      return;\n    }\n    ctx.cancelClose();\n    if (ctx.trigger === 'hover') {\n      ctx.openMenu(menuCtx.index, 'hover');\n      ctx.setActiveIndex(menuCtx.index);\n    } else if (ctx.openIndex !== null && ctx.openIndex !== menuCtx.index) {\n      ctx.openMenu(menuCtx.index, 'hover');\n      ctx.setActiveIndex(menuCtx.index);\n    }\n  });\n\n  const handleMouseLeave = createEventHandler<any>(onMouseLeave, () => {\n    if (ctx.trigger === 'hover') {\n      ctx.scheduleClose();\n    }\n  });\n\n  const handleFocus = createEventHandler<any>(onFocus, () => ctx.setActiveIndex(menuCtx.index));\n\n  const handleKeyDown = createEventHandler<any>(onKeyDown, (event) => {\n    if (isDisabled) {\n      return;\n    }\n    const forwardKey = dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight';\n    const backKey = dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft';\n\n    if (event.key === forwardKey) {\n      event.preventDefault();\n      moveToAdjacent(1);\n    } else if (event.key === backKey) {\n      event.preventDefault();\n      moveToAdjacent(-1);\n    } else if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n      event.preventDefault();\n      openAndFocusItem('first');\n    } else if (event.key === 'ArrowUp') {\n      event.preventDefault();\n      openAndFocusItem('last');\n    } else if (event.key === 'Home') {\n      event.preventDefault();\n      const enabled = ctx.getEnabledIndexes();\n      if (enabled.length > 0) {\n        ctx.setActiveIndex(enabled[0]);\n        ctx.focusTarget(enabled[0]);\n      }\n    } else if (event.key === 'End') {\n      event.preventDefault();\n      const enabled = ctx.getEnabledIndexes();\n      if (enabled.length > 0) {\n        const last = enabled[enabled.length - 1];\n        ctx.setActiveIndex(last);\n        ctx.focusTarget(last);\n      }\n    } else if (event.key === 'Escape') {\n      if (menuCtx.opened) {\n        ctx.closeMenu();\n      }\n    } else if (event.key === 'Tab') {\n      if (menuCtx.opened) {\n        ctx.closeMenu();\n      }\n    } else if (isPrintableKey(event)) {\n      typeAhead(event);\n    }\n  });\n\n  return (\n    <Popover.Target refProp={refProp} popupType=\"menu\">\n      <UnstyledButton\n        {...others}\n        unstyled={ctx.unstyled}\n        role=\"menuitem\"\n        tabIndex={isActive || isUnresolvedTabStop ? 0 : -1}\n        disabled={disabled}\n        data-menubar-target\n        data-menubar-id={menuCtx.id}\n        data-disabled={dataDisabled || undefined}\n        data-expanded={menuCtx.opened || undefined}\n        data-mantine-stop-propagation={menuCtx.opened || undefined}\n        {...ctx.getStyles('target', { className, style })}\n        onClick={handleClick}\n        onMouseEnter={handleMouseEnter}\n        onMouseLeave={handleMouseLeave}\n        onFocus={handleFocus}\n        onKeyDown={handleKeyDown}\n      >\n        {children}\n      </UnstyledButton>\n    </Popover.Target>\n  );\n}\n\nMenubarTarget.displayName = '@mantine/core/MenubarTarget';\n"],"mappings":"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"}