@plexui/ui 0.20.7 → 0.20.9

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.
Files changed (42) hide show
  1. package/dist/es/components/DateRangePicker/Calendar.js +18 -19
  2. package/dist/es/components/DateRangePicker/Calendar.js.map +1 -1
  3. package/dist/es/components/DateRangePicker/DateRangePicker.js +3 -1
  4. package/dist/es/components/DateRangePicker/DateRangePicker.js.map +1 -1
  5. package/dist/es/components/DateRangePicker/context.js.map +1 -1
  6. package/dist/es/components/DateRangePicker/index.js.map +1 -1
  7. package/dist/es/components/DateRangePicker/types.js.map +1 -1
  8. package/dist/es/components/Dialog/Dialog.js +8 -2
  9. package/dist/es/components/Dialog/Dialog.js.map +1 -1
  10. package/dist/es/components/Field/Field.js +6 -3
  11. package/dist/es/components/Field/Field.js.map +1 -1
  12. package/dist/es/components/InputGroup/InputGroup.js +1 -1
  13. package/dist/es/components/InputGroup/InputGroup.js.map +1 -1
  14. package/dist/es/components/Menu/Menu.js +8 -3
  15. package/dist/es/components/Menu/Menu.js.map +1 -1
  16. package/dist/es/components/Popover/Popover.js +16 -8
  17. package/dist/es/components/Popover/Popover.js.map +1 -1
  18. package/dist/es/components/Select/Select.js +18 -10
  19. package/dist/es/components/Select/Select.js.map +1 -1
  20. package/dist/es/components/SelectControl/SelectControl.js +6 -5
  21. package/dist/es/components/SelectControl/SelectControl.js.map +1 -1
  22. package/dist/es/components/Transition/TransitionGroup.js +7 -6
  23. package/dist/es/components/Transition/TransitionGroup.js.map +1 -1
  24. package/dist/es/components/Transition/shared.js +30 -0
  25. package/dist/es/components/Transition/shared.js.map +1 -1
  26. package/dist/es/lib/dateUtils.js +5 -0
  27. package/dist/es/lib/dateUtils.js.map +1 -1
  28. package/dist/es/lib/helpers.js +30 -0
  29. package/dist/es/lib/helpers.js.map +1 -1
  30. package/dist/types/components/DateRangePicker/DateRangePicker.d.ts +6 -1
  31. package/dist/types/components/DateRangePicker/context.d.ts +2 -1
  32. package/dist/types/components/DateRangePicker/index.d.ts +1 -1
  33. package/dist/types/components/DateRangePicker/types.d.ts +2 -0
  34. package/dist/types/components/Field/Field.d.ts +4 -2
  35. package/dist/types/components/Popover/Popover.d.ts +2 -0
  36. package/dist/types/components/Select/Select.d.ts +5 -0
  37. package/dist/types/components/SelectControl/SelectControl.d.ts +7 -1
  38. package/dist/types/components/Transition/TransitionGroup.d.ts +5 -0
  39. package/dist/types/components/Transition/shared.d.ts +23 -0
  40. package/dist/types/lib/dateUtils.d.ts +5 -0
  41. package/dist/types/lib/helpers.d.ts +14 -1
  42. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"InputGroup.js","sourceRoot":"","sources":["../../../../src/components/InputGroup/InputGroup.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport {\n createContext,\n useContext,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type Ref,\n type TextareaHTMLAttributes,\n} from \"react\"\nimport { type ControlSize, type Variants } from \"../../types\"\nimport { Button, type ButtonProps } from \"../Button\"\nimport s from \"@plexui/styles/components/InputGroup/InputGroup.module.css\"\n\ntype InputGroupContextValue = {\n size: ControlSize\n pill: boolean\n disabled: boolean\n invalid: boolean\n}\n\nconst InputGroupContext = createContext<InputGroupContextValue | null>(null)\n\nconst CONTROL_SELECTOR = \"[data-slot='input-group-control']\"\n\n/** Button size for each group size: the closest Button that fits inside the control */\nconst BUTTON_SIZE: Record<ControlSize, ControlSize> = {\n \"3xs\": \"3xs\",\n \"2xs\": \"3xs\",\n \"xs\": \"3xs\",\n \"sm\": \"3xs\",\n \"md\": \"2xs\",\n \"lg\": \"sm\",\n \"xl\": \"md\",\n \"2xl\": \"lg\",\n \"3xl\": \"xl\",\n}\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport type InputGroupProps = HTMLAttributes<HTMLDivElement> & {\n /**\n * Visual style of the group\n * @default outline\n */\n variant?: Variants<\"outline\" | \"soft\">\n /**\n * Controls the size of the group, on the same scale as Input\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n *\n * @default md\n */\n size?: ControlSize\n /**\n * Fully rounded group, with pill buttons inside\n * @default false\n */\n pill?: boolean\n /**\n * Disables the control and the buttons inside the group\n * @default false\n */\n disabled?: boolean\n /**\n * Mark the group as invalid\n * @default false\n */\n invalid?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\nconst InputGroupRoot = ({\n variant = \"outline\",\n size = \"md\",\n pill = false,\n disabled = false,\n invalid = false,\n className,\n onMouseDown,\n ref,\n ...restProps\n}: InputGroupProps) => {\n // Clicks on the frame, icons and text focus the control, as in Input\n const handleMouseDown = (evt: React.MouseEvent<HTMLDivElement>) => {\n onMouseDown?.(evt)\n const control = evt.currentTarget.querySelector<HTMLElement>(CONTROL_SELECTOR)\n const { target } = evt\n if (evt.defaultPrevented || !control || !(target instanceof Element) || control.contains(target)) {\n return\n }\n // Buttons, links, menus and other controls in the addons take their own clicks\n if (target.closest(\"button, a, input, textarea, select, [role='button'], [role='menuitem']\")) {\n return\n }\n evt.preventDefault()\n control.focus()\n }\n\n return (\n <InputGroupContext.Provider value={{ size, pill, disabled, invalid }}>\n <div\n ref={ref}\n role=\"group\"\n data-slot=\"input-group\"\n data-variant={variant}\n data-size={size}\n data-pill={pill ? \"\" : undefined}\n data-disabled={disabled ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n className={clsx(s.InputGroup, className)}\n onMouseDown={handleMouseDown}\n {...restProps}\n />\n </InputGroupContext.Provider>\n )\n}\n\n/* ------------------------------------------------------------------ */\n/* Input / Textarea: the native control, framed by the group */\n/* ------------------------------------------------------------------ */\n\nexport type InputGroupInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, \"size\"> & {\n ref?: Ref<HTMLInputElement>\n}\n\nconst InputGroupInput = ({ type = \"text\", disabled, className, ref, ...restProps }: InputGroupInputProps) => {\n const group = useContext(InputGroupContext)\n return (\n <input\n ref={ref}\n type={type}\n data-slot=\"input-group-control\"\n className={clsx(s.Control, className)}\n disabled={disabled ?? group?.disabled}\n // Expose the group's invalid state to assistive tech; an explicit aria-invalid wins\n aria-invalid={restProps[\"aria-invalid\"] ?? (group?.invalid || undefined)}\n {...restProps}\n />\n )\n}\n\nexport type InputGroupTextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & {\n ref?: Ref<HTMLTextAreaElement>\n}\n\nconst InputGroupTextarea = ({ rows = 3, disabled, className, ref, ...restProps }: InputGroupTextareaProps) => {\n const group = useContext(InputGroupContext)\n return (\n <textarea\n ref={ref}\n rows={rows}\n data-slot=\"input-group-control\"\n className={clsx(s.Control, className)}\n disabled={disabled ?? group?.disabled}\n aria-invalid={restProps[\"aria-invalid\"] ?? (group?.invalid || undefined)}\n {...restProps}\n />\n )\n}\n\n/* ------------------------------------------------------------------ */\n/* Addon: icons, text and buttons beside, above or below the control */\n/* ------------------------------------------------------------------ */\n\nexport type InputGroupAddonAlign = \"inline-start\" | \"inline-end\" | \"block-start\" | \"block-end\"\n\nexport type InputGroupAddonProps = HTMLAttributes<HTMLDivElement> & {\n /**\n * Where the addon sits: before or after the control on its line, or as a\n * row above or below it. Inline addons suit `InputGroup.Input`, block\n * addons suit `InputGroup.Textarea` and labels.\n * @default \"inline-start\"\n */\n align?: InputGroupAddonAlign\n ref?: Ref<HTMLDivElement>\n}\n\nconst InputGroupAddon = ({ align = \"inline-start\", className, ref, ...restProps }: InputGroupAddonProps) => (\n <div\n ref={ref}\n data-slot=\"input-group-addon\"\n data-align={align}\n className={clsx(s.Addon, className)}\n {...restProps}\n />\n)\n\n/* ------------------------------------------------------------------ */\n/* Button: a ghost Button sized from the group */\n/* ------------------------------------------------------------------ */\n\nexport type InputGroupButtonProps = Omit<ButtonProps, \"color\" | \"size\"> & {\n /**\n * Color for the button\n * @default secondary\n */\n color?: ButtonProps[\"color\"]\n}\n\nconst InputGroupButton = ({\n color = \"secondary\",\n variant = \"ghost\",\n pill,\n disabled,\n className,\n ...restProps\n}: InputGroupButtonProps) => {\n const group = useContext(InputGroupContext)\n return (\n <Button\n color={color}\n variant={variant}\n size={BUTTON_SIZE[group?.size ?? \"md\"]}\n pill={pill ?? group?.pill}\n disabled={disabled ?? group?.disabled}\n className={clsx(s.Button, className)}\n {...restProps}\n />\n )\n}\n\n/* ------------------------------------------------------------------ */\n/* Text: plain text inside an addon (prefixes, units, counters) */\n/* ------------------------------------------------------------------ */\n\nexport type InputGroupTextProps = HTMLAttributes<HTMLSpanElement> & {\n ref?: Ref<HTMLSpanElement>\n}\n\nconst InputGroupText = ({ className, ref, ...restProps }: InputGroupTextProps) => (\n <span ref={ref} data-slot=\"input-group-text\" className={clsx(s.Text, className)} {...restProps} />\n)\n\n/* ------------------------------------------------------------------ */\n/* Export: compound API */\n/* ------------------------------------------------------------------ */\n\ntype InputGroupComponent = typeof InputGroupRoot & {\n Input: typeof InputGroupInput\n Textarea: typeof InputGroupTextarea\n Addon: typeof InputGroupAddon\n Button: typeof InputGroupButton\n Text: typeof InputGroupText\n}\n\nexport const InputGroup = InputGroupRoot as InputGroupComponent\nInputGroup.Input = InputGroupInput\nInputGroup.Textarea = InputGroupTextarea\nInputGroup.Addon = InputGroupAddon\nInputGroup.Button = InputGroupButton\nInputGroup.Text = InputGroupText\n"]}
1
+ {"version":3,"file":"InputGroup.js","sourceRoot":"","sources":["../../../../src/components/InputGroup/InputGroup.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport {\n createContext,\n useContext,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type Ref,\n type TextareaHTMLAttributes,\n} from \"react\"\nimport { type ControlSize, type Variants } from \"../../types\"\nimport { Button, type ButtonProps } from \"../Button\"\nimport s from \"@plexui/styles/components/InputGroup/InputGroup.module.css\"\n\ntype InputGroupContextValue = {\n size: ControlSize\n pill: boolean\n disabled: boolean\n invalid: boolean\n}\n\nconst InputGroupContext = createContext<InputGroupContextValue | null>(null)\n\nconst CONTROL_SELECTOR = \"[data-slot='input-group-control']\"\n\n/** Button size for each group size: the closest Button that fits inside the control */\nconst BUTTON_SIZE: Record<ControlSize, ControlSize> = {\n \"3xs\": \"3xs\",\n \"2xs\": \"3xs\",\n \"xs\": \"3xs\",\n \"sm\": \"3xs\",\n \"md\": \"2xs\",\n \"lg\": \"sm\",\n \"xl\": \"md\",\n \"2xl\": \"lg\",\n \"3xl\": \"xl\",\n}\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport type InputGroupProps = HTMLAttributes<HTMLDivElement> & {\n /**\n * Visual style of the group\n * @default outline\n */\n variant?: Variants<\"outline\" | \"soft\">\n /**\n * Controls the size of the group, on the same scale as Input\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n *\n * @default md\n */\n size?: ControlSize\n /**\n * Fully rounded group, with pill buttons inside\n * @default false\n */\n pill?: boolean\n /**\n * Disables the control and the buttons inside the group\n * @default false\n */\n disabled?: boolean\n /**\n * Mark the group as invalid\n * @default false\n */\n invalid?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\nconst InputGroupRoot = ({\n variant = \"outline\",\n size = \"md\",\n pill = false,\n disabled = false,\n invalid = false,\n className,\n onMouseDown,\n ref,\n ...restProps\n}: InputGroupProps) => {\n // Clicks on the frame, icons and text focus the control, as in Input\n const handleMouseDown = (evt: React.MouseEvent<HTMLDivElement>) => {\n onMouseDown?.(evt)\n const control = evt.currentTarget.querySelector<HTMLElement>(CONTROL_SELECTOR)\n const { target } = evt\n if (evt.defaultPrevented || !control || !(target instanceof Element) || control.contains(target)) {\n return\n }\n // Buttons, links, menus and other controls in the addons take their own clicks\n if (target.closest(\"button, a, input, textarea, select, [role='button'], [role='menuitem']\")) {\n return\n }\n evt.preventDefault()\n control.focus()\n }\n\n return (\n <InputGroupContext.Provider value={{ size, pill, disabled, invalid }}>\n <div\n ref={ref}\n data-slot=\"input-group\"\n data-variant={variant}\n data-size={size}\n data-pill={pill ? \"\" : undefined}\n data-disabled={disabled ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n className={clsx(s.InputGroup, className)}\n onMouseDown={handleMouseDown}\n {...restProps}\n />\n </InputGroupContext.Provider>\n )\n}\n\n/* ------------------------------------------------------------------ */\n/* Input / Textarea: the native control, framed by the group */\n/* ------------------------------------------------------------------ */\n\nexport type InputGroupInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, \"size\"> & {\n ref?: Ref<HTMLInputElement>\n}\n\nconst InputGroupInput = ({ type = \"text\", disabled, className, ref, ...restProps }: InputGroupInputProps) => {\n const group = useContext(InputGroupContext)\n return (\n <input\n ref={ref}\n type={type}\n data-slot=\"input-group-control\"\n className={clsx(s.Control, className)}\n disabled={disabled ?? group?.disabled}\n // Expose the group's invalid state to assistive tech; an explicit aria-invalid wins\n aria-invalid={restProps[\"aria-invalid\"] ?? (group?.invalid || undefined)}\n {...restProps}\n />\n )\n}\n\nexport type InputGroupTextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & {\n ref?: Ref<HTMLTextAreaElement>\n}\n\nconst InputGroupTextarea = ({ rows = 3, disabled, className, ref, ...restProps }: InputGroupTextareaProps) => {\n const group = useContext(InputGroupContext)\n return (\n <textarea\n ref={ref}\n rows={rows}\n data-slot=\"input-group-control\"\n className={clsx(s.Control, className)}\n disabled={disabled ?? group?.disabled}\n aria-invalid={restProps[\"aria-invalid\"] ?? (group?.invalid || undefined)}\n {...restProps}\n />\n )\n}\n\n/* ------------------------------------------------------------------ */\n/* Addon: icons, text and buttons beside, above or below the control */\n/* ------------------------------------------------------------------ */\n\nexport type InputGroupAddonAlign = \"inline-start\" | \"inline-end\" | \"block-start\" | \"block-end\"\n\nexport type InputGroupAddonProps = HTMLAttributes<HTMLDivElement> & {\n /**\n * Where the addon sits: before or after the control on its line, or as a\n * row above or below it. Inline addons suit `InputGroup.Input`, block\n * addons suit `InputGroup.Textarea` and labels.\n * @default \"inline-start\"\n */\n align?: InputGroupAddonAlign\n ref?: Ref<HTMLDivElement>\n}\n\nconst InputGroupAddon = ({ align = \"inline-start\", className, ref, ...restProps }: InputGroupAddonProps) => (\n <div\n ref={ref}\n data-slot=\"input-group-addon\"\n data-align={align}\n className={clsx(s.Addon, className)}\n {...restProps}\n />\n)\n\n/* ------------------------------------------------------------------ */\n/* Button: a ghost Button sized from the group */\n/* ------------------------------------------------------------------ */\n\nexport type InputGroupButtonProps = Omit<ButtonProps, \"color\" | \"size\"> & {\n /**\n * Color for the button\n * @default secondary\n */\n color?: ButtonProps[\"color\"]\n}\n\nconst InputGroupButton = ({\n color = \"secondary\",\n variant = \"ghost\",\n pill,\n disabled,\n className,\n ...restProps\n}: InputGroupButtonProps) => {\n const group = useContext(InputGroupContext)\n return (\n <Button\n color={color}\n variant={variant}\n size={BUTTON_SIZE[group?.size ?? \"md\"]}\n pill={pill ?? group?.pill}\n disabled={disabled ?? group?.disabled}\n className={clsx(s.Button, className)}\n {...restProps}\n />\n )\n}\n\n/* ------------------------------------------------------------------ */\n/* Text: plain text inside an addon (prefixes, units, counters) */\n/* ------------------------------------------------------------------ */\n\nexport type InputGroupTextProps = HTMLAttributes<HTMLSpanElement> & {\n ref?: Ref<HTMLSpanElement>\n}\n\nconst InputGroupText = ({ className, ref, ...restProps }: InputGroupTextProps) => (\n <span ref={ref} data-slot=\"input-group-text\" className={clsx(s.Text, className)} {...restProps} />\n)\n\n/* ------------------------------------------------------------------ */\n/* Export: compound API */\n/* ------------------------------------------------------------------ */\n\ntype InputGroupComponent = typeof InputGroupRoot & {\n Input: typeof InputGroupInput\n Textarea: typeof InputGroupTextarea\n Addon: typeof InputGroupAddon\n Button: typeof InputGroupButton\n Text: typeof InputGroupText\n}\n\nexport const InputGroup = InputGroupRoot as InputGroupComponent\nInputGroup.Input = InputGroupInput\nInputGroup.Textarea = InputGroupTextarea\nInputGroup.Addon = InputGroupAddon\nInputGroup.Button = InputGroupButton\nInputGroup.Text = InputGroupText\n"]}
@@ -5,11 +5,12 @@ import React, { createContext, useCallback, useContext, useMemo, useRef, useStat
5
5
  import clsx from "clsx";
6
6
  import { useEscCloseStack } from "../../hooks/useEscCloseStack.js";
7
7
  import { useLatestValue } from "../../hooks/useLatestValue.js";
8
- import { preventDefaultHandler, toCssVariables } from "../../lib/helpers.js";
8
+ import { keepMovedFocus, preventDefaultHandler, toCssVariables } from "../../lib/helpers.js";
9
9
  import { Button } from "../Button/index.js";
10
10
  import { Check, ChevronRight } from "../Icon/index.js";
11
11
  import { useLinkComponent } from "../PlexUIProvider/internal.js";
12
12
  import { TransitionGroup } from "../Transition/index.js";
13
+ import { createExitGuard, overlayTiming } from "../Transition/shared.js";
13
14
  import s from "@plexui/styles/components/Menu/Menu.module.css";
14
15
  const MenuContext = createContext(null);
15
16
  const useMenuContext = () => {
@@ -110,8 +111,12 @@ const Group = ({ className, children, }) => {
110
111
  };
111
112
  const Content = ({ children, side, sideOffset = 5, align, alignOffset, width, minWidth, maxHeight, pill = false, layout = "vertical", size, onCloseAutoFocus, }) => {
112
113
  const { open } = useMenuContext();
114
+ const [exitGuard] = useState(createExitGuard);
113
115
  const isHorizontal = layout === "horizontal";
114
- return (_jsx(DropdownMenu.Portal, { forceMount: true, children: _jsx(TransitionGroup, { className: s.Menu, enterDuration: 350, exitDuration: 200, disableAnimations: true, children: open && (_jsx(DropdownMenu.Content, { forceMount: true, className: s.MenuList, "data-pill": pill ? "" : undefined, side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset ?? (align === "center" ? 0 : -5), avoidCollisions: true, collisionPadding: { bottom: 30, top: 30, left: 12, right: 12 }, onEscapeKeyDown: preventDefaultHandler, onCloseAutoFocus: onCloseAutoFocus, "data-layout": isHorizontal ? "horizontal" : undefined, "data-size": isHorizontal && size ? size : undefined, style: toCssVariables({
116
+ return (_jsx(DropdownMenu.Portal, { forceMount: true, children: _jsx(TransitionGroup, { className: s.Menu, ...overlayTiming, ...exitGuard.transition, overlay: true, children: open && (_jsx(DropdownMenu.Content, { forceMount: true, className: s.MenuList, "data-pill": pill ? "" : undefined, side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset ?? (align === "center" ? 0 : -5), avoidCollisions: true, collisionPadding: { bottom: 30, top: 30, left: 12, right: 12 }, onEscapeKeyDown: preventDefaultHandler, onInteractOutside: exitGuard.onInteractOutside, onCloseAutoFocus: (event) => {
117
+ onCloseAutoFocus?.(event);
118
+ keepMovedFocus(event);
119
+ }, "data-layout": isHorizontal ? "horizontal" : undefined, "data-size": isHorizontal && size ? size : undefined, style: toCssVariables({
115
120
  "menu-width": width,
116
121
  "menu-min-width": isHorizontal ? "auto" : minWidth,
117
122
  "menu-max-height": maxHeight,
@@ -173,7 +178,7 @@ const SubTrigger = ({ className, children, disabled, }) => {
173
178
  };
174
179
  const SubContent = ({ children, sideOffset = 4, alignOffset = -6, width = "auto", minWidth = "auto", maxHeight, pill = false, }) => {
175
180
  const { open } = useSubmenuContext();
176
- return (_jsx(DropdownMenu.Portal, { forceMount: true, children: _jsx(TransitionGroup, { className: s.Menu, enterDuration: 350, exitDuration: 200, disableAnimations: true, children: open && (_jsx(DropdownMenu.SubContent, { className: s.MenuList, "data-pill": pill ? "" : undefined, sideOffset: sideOffset, alignOffset: alignOffset, avoidCollisions: true, collisionPadding: { bottom: 30, top: 30, left: 12, right: 12 }, onEscapeKeyDown: preventDefaultHandler, style: toCssVariables({
181
+ return (_jsx(DropdownMenu.Portal, { forceMount: true, children: _jsx(TransitionGroup, { className: s.Menu, ...overlayTiming, overlay: true, children: open && (_jsx(DropdownMenu.SubContent, { className: s.MenuList, "data-pill": pill ? "" : undefined, sideOffset: sideOffset, alignOffset: alignOffset, avoidCollisions: true, collisionPadding: { bottom: 30, top: 30, left: 12, right: 12 }, onEscapeKeyDown: preventDefaultHandler, style: toCssVariables({
177
182
  "menu-width": width,
178
183
  "menu-min-width": minWidth,
179
184
  "menu-max-height": maxHeight,
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.js","sourceRoot":"","sources":["../../../../src/components/Menu/Menu.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport { DropdownMenu } from \"radix-ui\"\nimport React, {\n type ComponentProps,\n type ComponentType,\n createContext,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from \"react\"\n\nimport clsx from \"clsx\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { preventDefaultHandler, toCssVariables } from \"../../lib/helpers\"\nimport { Button } from \"../Button\"\nimport { Check, ChevronRight } from \"../Icon\"\nimport { useLinkComponent } from \"../PlexUIProvider/internal\"\nimport { TransitionGroup } from \"../Transition\"\nimport s from \"@plexui/styles/components/Menu/Menu.module.css\"\n\ntype MenuContextValue = {\n open: boolean\n setOpen: (next: boolean) => void\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null)\n\nconst useMenuContext = () => {\n const context = useContext(MenuContext)\n\n if (!context) {\n throw new Error(\"Menu components must be wrapped in <Menu />\")\n }\n\n return context\n}\n\nexport type MenuProps = {\n children: React.ReactNode\n /** Force the menu to remain open or closed */\n forceOpen?: boolean\n /** Callback triggered when the modal is opened */\n onOpen?: () => void\n /** Callback triggered when the modal is closed */\n onClose?: () => void\n /**\n * When set to `true`, interaction with outside elements will be disabled and only menu content will be visible to screen readers.\n * @default false\n */\n modal?: boolean\n}\n\nexport const Menu = ({ children, forceOpen, onOpen, onClose, modal = false }: MenuProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const isOpen = forceOpen ?? open\n\n const latestOnOpen = useLatestValue(onOpen)\n const latestOnClose = useLatestValue(onClose)\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n setOpen(nextState)\n if (nextState) {\n latestOnOpen.current?.()\n } else {\n latestOnClose.current?.()\n }\n },\n [latestOnOpen, latestOnClose],\n )\n\n useEscCloseStack(open, () => {\n handleOpenChange(false)\n })\n\n const store = useMemo<MenuContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n }),\n [isOpen, handleOpenChange],\n )\n\n return (\n <MenuContext.Provider value={store}>\n <DropdownMenu.Root open={isOpen} onOpenChange={handleOpenChange} modal={modal}>\n {children}\n </DropdownMenu.Root>\n </MenuContext.Provider>\n )\n}\n\nexport type MenuItemProps = {\n className?: string\n children: React.ReactNode\n /**\n * Second line under the item's label: what this action does, or which\n * value it carries. The label goes semibold on its own, the same way a\n * Select option with a description does — same pattern, same anatomy.\n */\n description?: ReactNode\n /** Callback triggered when the item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Callback triggered when the item is clicked */\n onClick?: DropdownMenu.DropdownMenuItemProps[\"onClick\"]\n /** Disables the menu item */\n disabled?: boolean\n /** Marks a destructive action (delete, remove, leave): the item is drawn in the danger color */\n danger?: boolean\n}\n\nconst Item = ({ className, children, description, disabled, danger, onSelect, onClick }: MenuItemProps) => {\n const { open } = useMenuContext()\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we're always known to be closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n // A described item stacks its two lines; without a description the item\n // keeps the plain flex row that icons and ItemActions rely on.\n const content =\n description === undefined ? (\n children\n ) : (\n <div className={s.ItemLeading}>\n <div>{children}</div>\n <div className={s.ItemDescription}>{description}</div>\n </div>\n )\n\n // Custom click handlers: either callback makes the item interactive\n if (onSelect || onClick) {\n return (\n <DropdownMenu.Item\n className={clsx(s.MenuItem, className)}\n onSelect={onSelect}\n onClick={onClick}\n disabled={disabled}\n data-danger={danger ? \"\" : undefined}\n onPointerMove={handlePreventAfterClose}\n onPointerLeave={handlePreventAfterClose}\n >\n <div className={s.PressableInner}>{content}</div>\n </DropdownMenu.Item>\n )\n }\n\n // Read-only content - will not appear interactive.\n return <div className={clsx(s.MenuItemContent, className)}>{content}</div>\n}\n\nconst ItemActions = ({ className, children }: { className?: string; children: ReactNode }) => {\n return <div className={clsx(s.ItemActions, className)}>{children}</div>\n}\n\nconst ItemAction = ({\n children,\n onClick,\n \"aria-label\": ariaLabel,\n}: {\n children: ReactNode\n onClick: (evt: MouseEvent) => void\n /** Accessible name; the action is an icon-only button */\n \"aria-label\"?: string\n}) => {\n const { setOpen } = useMenuContext()\n\n return (\n <Button\n className=\"rounded-sm\"\n color=\"secondary\"\n size=\"xs\"\n uniform\n iconSize=\"sm\"\n variant=\"ghost\"\n aria-label={ariaLabel}\n onClick={(evt) => {\n evt.stopPropagation()\n setOpen(false)\n onClick(evt)\n }}\n >\n {children}\n </Button>\n )\n}\n\ntype MenuLinkProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\" | \"children\"> & {\n /** Content rendered inside the Link */\n children: React.ReactNode\n /** Disables the menu item */\n disabled?: boolean\n /** Marks a destructive destination: the item is drawn in the danger color */\n danger?: boolean\n}\n\ntype MenuLink = <\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends ComponentType<any> | \"a\" = PlexUI.LinkComponent,\n>(\n props: Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n MenuLinkProps & {\n /**\n * Override the default component used for the link. This is useful for\n * using a routing library, or SSR rendering.\n * purposes.\n *\n * @default 'a'\n */\n as?: T\n } & ComponentProps<T>,\n) => ReactNode\n\nconst Link = ((\n props: MenuLinkProps & { href?: string; to?: string; as?: PlexUI.LinkComponent },\n) => {\n const { className, children, href, to, disabled, danger, as: OverrideComponent, ...restProps } = props\n const { open } = useMenuContext()\n\n const propPath = href || to\n // When a path is not provided, default to an anchor\n const isExternal = propPath ? /^https?:\\/\\//.test(propPath) : true\n const DefaultComponent = useLinkComponent()\n const Component = OverrideComponent || (isExternal ? \"a\" : DefaultComponent)\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we're always known to be closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n const linkProps = isExternal\n ? { target: \"_blank\", rel: \"noopener noreferrer\", href: href ?? to }\n : { href, to }\n\n return (\n <DropdownMenu.Item\n asChild\n className={clsx(s.MenuItem, className)}\n disabled={disabled}\n data-danger={danger ? \"\" : undefined}\n onPointerMove={isExternal ? undefined : handlePreventAfterClose}\n onPointerLeave={isExternal ? undefined : handlePreventAfterClose}\n >\n <Component\n {...linkProps}\n {...restProps}\n onClick={(event: React.MouseEvent<HTMLAnchorElement>) => {\n restProps.onClick?.(event)\n // Radix skips selecting a disabled item, not the link's navigation\n if (disabled) event.preventDefault()\n }}\n >\n <span className={s.PressableInner}>{children}</span>\n </Component>\n </DropdownMenu.Item>\n )\n}) as MenuLink\n\nconst Separator = ({ className }: { className?: string }) => {\n return <DropdownMenu.Separator className={clsx(s.Separator, className)} role=\"separator\" />\n}\n\n\nconst Label = ({ className, children }: { className?: string; children: ReactNode }) => {\n return (\n <DropdownMenu.Label className={clsx(s.MenuLabel, className)}>\n {children}\n </DropdownMenu.Label>\n )\n}\n\nconst Group = ({\n className,\n children,\n}: {\n className?: string\n children: ReactNode\n}) => {\n return <DropdownMenu.Group className={className}>{children}</DropdownMenu.Group>\n}\n\nexport type MenuContentProps = {\n children: React.ReactNode\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default bottom\n */\n side?: DropdownMenu.DropdownMenuContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 5\n */\n sideOffset?: DropdownMenu.DropdownMenuContentProps[\"sideOffset\"]\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: DropdownMenu.DropdownMenuContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: DropdownMenu.DropdownMenuContentProps[\"alignOffset\"]\n /**\n * Defines the `width` property of the content\n * @default auto\n */\n width?: number | \"auto\"\n /**\n * Defines the `min-width` property of the content, in pixels.\n * @default 300\n */\n minWidth?: number | \"auto\"\n /**\n * Defines the `max-width` property of the content, in pixels.\n */\n maxHeight?: number\n /**\n * Rounder list with fully rounded rows, for menus that sit beside pill controls.\n * @default false\n */\n pill?: boolean\n /**\n * Layout direction of menu items.\n * Use `\"horizontal\"` for icon-based toolbars (iOS-style).\n * @default \"vertical\"\n */\n layout?: \"vertical\" | \"horizontal\"\n /**\n * Size of horizontal menu items. Controls icon size and padding.\n * Only applies when `layout=\"horizontal\"`.\n * @default \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\"\n /**\n * Event handler called when auto-focus tries to return to the trigger\n * after the menu closes. Call `event.preventDefault()` to prevent the\n * trigger from regaining focus (and its focus-visible ring).\n */\n onCloseAutoFocus?: DropdownMenu.DropdownMenuContentProps[\"onCloseAutoFocus\"]\n}\n\nconst Content = ({\n children,\n side,\n sideOffset = 5,\n align,\n alignOffset,\n width,\n minWidth,\n maxHeight,\n pill = false,\n layout = \"vertical\",\n size,\n onCloseAutoFocus,\n}: MenuContentProps) => {\n const { open } = useMenuContext()\n const isHorizontal = layout === \"horizontal\"\n\n return (\n <DropdownMenu.Portal forceMount>\n <TransitionGroup className={s.Menu} enterDuration={350} exitDuration={200} disableAnimations>\n {open && (\n <DropdownMenu.Content\n key=\"dropdown\"\n forceMount\n className={s.MenuList}\n data-pill={pill ? \"\" : undefined}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset ?? (align === \"center\" ? 0 : -5)}\n avoidCollisions\n collisionPadding={{ bottom: 30, top: 30, left: 12, right: 12 }}\n onEscapeKeyDown={preventDefaultHandler}\n onCloseAutoFocus={onCloseAutoFocus}\n data-layout={isHorizontal ? \"horizontal\" : undefined}\n data-size={isHorizontal && size ? size : undefined}\n style={toCssVariables({\n \"menu-width\": width,\n \"menu-min-width\": isHorizontal ? \"auto\" : minWidth,\n \"menu-max-height\": maxHeight,\n })}\n >\n {children}\n </DropdownMenu.Content>\n )}\n </TransitionGroup>\n </DropdownMenu.Portal>\n )\n}\n\nconst Trigger = ({\n children,\n disabled,\n ...restProps\n}: DropdownMenu.DropdownMenuTriggerProps & { ref?: React.Ref<HTMLButtonElement> }) => {\n // Always composes onto the child (asChild after the spread wins over a\n // caller's asChild); other props (aria-*, handlers, ref) reach it through\n // the Slot instead of being dropped\n return (\n <DropdownMenu.Trigger {...restProps} asChild disabled={disabled}>\n {children}\n </DropdownMenu.Trigger>\n )\n}\n\ntype SubmenuContextValue = {\n open: boolean\n setOpen: (next: boolean) => void\n triggerRef: React.RefObject<HTMLDivElement | null>\n}\n\nconst SubmenuContext = createContext<SubmenuContextValue | null>(null)\n\nconst useSubmenuContext = () => {\n const context = useContext(SubmenuContext)\n\n if (!context) {\n throw new Error(\"Submenu components must be wrapped in <Sub />\")\n }\n\n return context\n}\n\nexport type SubmenuProps = {\n children: React.ReactNode\n /** Force the menu to remain open or closed */\n forceOpen?: boolean\n /** Callback triggered when the modal is opened */\n onOpen?: () => void\n /** Callback triggered when the modal is closed */\n onClose?: () => void\n}\n\nconst Sub = ({ children, forceOpen, onOpen, onClose }: SubmenuProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const triggerRef = useRef<HTMLDivElement>(null)\n const isOpen = forceOpen ?? open\n\n const latestOnOpen = useLatestValue(onOpen)\n const latestOnClose = useLatestValue(onClose)\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n setOpen(nextState)\n if (nextState) {\n latestOnOpen.current?.()\n } else {\n latestOnClose.current?.()\n }\n },\n [latestOnOpen, latestOnClose],\n )\n\n useEscCloseStack(open, () => {\n handleOpenChange(false)\n // Ensure trigger is focused\n triggerRef.current?.focus()\n })\n\n const store = useMemo<SubmenuContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n triggerRef,\n }),\n [isOpen, handleOpenChange],\n )\n\n return (\n <SubmenuContext.Provider value={store}>\n <DropdownMenu.Sub open={isOpen} onOpenChange={handleOpenChange}>\n {children}\n </DropdownMenu.Sub>\n </SubmenuContext.Provider>\n )\n}\n\nconst SubTrigger = ({\n className,\n children,\n disabled,\n}: {\n className?: string\n children: ReactNode\n disabled?: boolean\n}) => {\n const { open } = useMenuContext()\n const { triggerRef } = useSubmenuContext()\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we know the outer menu is closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n return (\n <DropdownMenu.SubTrigger\n ref={triggerRef}\n className={clsx(s.MenuItem, s.SubMenuItem, className)}\n disabled={disabled}\n onPointerMove={handlePreventAfterClose}\n onPointerLeave={handlePreventAfterClose}\n >\n <div className={s.PressableInner}>\n {children}\n <ChevronRight width=\"16\" height=\"16\" className={s.SubTriggerIcon} />\n </div>\n </DropdownMenu.SubTrigger>\n )\n}\n\ntype SubContentProps = {\n children: ReactNode\n sideOffset?: DropdownMenu.DropdownMenuSubContentProps[\"sideOffset\"]\n alignOffset?: DropdownMenu.DropdownMenuSubContentProps[\"alignOffset\"]\n width?: number | \"auto\"\n minWidth?: number | \"auto\"\n maxHeight?: number\n pill?: boolean\n}\n\nconst SubContent = ({\n children,\n sideOffset = 4,\n alignOffset = -6,\n width = \"auto\",\n minWidth = \"auto\",\n maxHeight,\n pill = false,\n}: SubContentProps) => {\n const { open } = useSubmenuContext()\n\n return (\n <DropdownMenu.Portal forceMount>\n <TransitionGroup className={s.Menu} enterDuration={350} exitDuration={200} disableAnimations>\n {open && (\n <DropdownMenu.SubContent\n key=\"submenu\"\n className={s.MenuList}\n data-pill={pill ? \"\" : undefined}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n avoidCollisions\n collisionPadding={{ bottom: 30, top: 30, left: 12, right: 12 }}\n onEscapeKeyDown={preventDefaultHandler}\n style={toCssVariables({\n \"menu-width\": width,\n \"menu-min-width\": minWidth,\n \"menu-max-height\": maxHeight,\n })}\n >\n {children}\n </DropdownMenu.SubContent>\n )}\n </TransitionGroup>\n </DropdownMenu.Portal>\n )\n}\n\nexport type MenuRadioGroupProps<T extends string> = {\n /** Controlled value */\n value: T\n /** Fired when selection changes */\n onChange: (value: T) => void\n children: ReactNode\n /**\n * The orientation of the indicator within the radio item.\n * @default end\n */\n indicatorPosition?: \"start\" | \"end\"\n}\n\nconst RadioGroup = <T extends string>({\n children,\n value,\n onChange,\n indicatorPosition = \"end\",\n ...props\n}: MenuRadioGroupProps<T>) => (\n <DropdownMenu.RadioGroup\n {...props}\n value={value}\n onValueChange={(v: string) => onChange(v as T)}\n data-indicator-position={indicatorPosition}\n >\n {children}\n </DropdownMenu.RadioGroup>\n)\n\nexport type MenuRadioItemProps<T extends string> = {\n value: T\n /** Class applied to the radio item */\n className?: string\n children: ReactNode\n /** Callback triggered when the radio item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Disables the radio item */\n disabled?: boolean\n}\n\nconst RadioItem = <T extends string>({ className, children, ...props }: MenuRadioItemProps<T>) => (\n <DropdownMenu.RadioItem className={clsx(s.MenuItem, s.RadioItem, className)} {...props}>\n <div className={s.PressableInner}>\n <div className={s.RadioIndicator}>\n <DropdownMenu.ItemIndicator className={s.RadioIndicatorActive} />\n </div>\n {children}\n </div>\n </DropdownMenu.RadioItem>\n)\n\nexport type MenuCheckboxItemProps = {\n /** Controlled checked state of the checkbox item */\n checked?: DropdownMenu.DropdownMenuCheckboxItemProps[\"checked\"]\n /** Event handler called when the checked state changes */\n onCheckedChange?: DropdownMenu.DropdownMenuCheckboxItemProps[\"onCheckedChange\"]\n /** Class applied to the checkbox item */\n className?: string\n children: ReactNode\n /** Callback triggered when the checkbox item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Disables the checkbox item */\n disabled?: boolean\n /**\n * The orientation of the indicator within the checkbox item.\n * @default end\n */\n indicatorPosition?: \"start\" | \"end\"\n /**\n * Visual treatment for the checkbox indicator.\n * @default solid\n */\n indicatorVariant?: \"solid\" | \"ghost\"\n}\nconst CheckboxItem = ({\n className,\n children,\n indicatorPosition = \"end\",\n indicatorVariant = \"solid\",\n ...props\n}: MenuCheckboxItemProps) => (\n <DropdownMenu.CheckboxItem\n className={clsx(s.MenuItem, s.CheckboxItem, className)}\n {...props}\n data-indicator-position={indicatorPosition}\n data-indicator-variant={indicatorVariant}\n >\n <div className={s.PressableInner}>\n <div className={s.CheckboxIndicator}>\n <DropdownMenu.ItemIndicator>\n {indicatorVariant === \"ghost\" ? (\n <Check className=\"size-4\" />\n ) : (\n <div className={s.CheckboxCircle}>\n <Check className=\"size-4\" />\n </div>\n )}\n </DropdownMenu.ItemIndicator>\n </div>\n {children}\n </div>\n </DropdownMenu.CheckboxItem>\n)\n\nMenu.Content = Content\nMenu.Item = Item\nMenu.ItemActions = ItemActions\nMenu.ItemAction = ItemAction\nMenu.Link = Link\nMenu.Separator = Separator\nMenu.Trigger = Trigger\nMenu.Sub = Sub\nMenu.SubTrigger = SubTrigger\nMenu.SubContent = SubContent\nMenu.CheckboxItem = CheckboxItem\nMenu.RadioGroup = RadioGroup\nMenu.RadioItem = RadioItem\nMenu.Label = Label\nMenu.Group = Group\n"]}
1
+ {"version":3,"file":"Menu.js","sourceRoot":"","sources":["../../../../src/components/Menu/Menu.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport { DropdownMenu } from \"radix-ui\"\nimport React, {\n type ComponentProps,\n type ComponentType,\n createContext,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from \"react\"\n\nimport clsx from \"clsx\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { keepMovedFocus, preventDefaultHandler, toCssVariables } from \"../../lib/helpers\"\nimport { Button } from \"../Button\"\nimport { Check, ChevronRight } from \"../Icon\"\nimport { useLinkComponent } from \"../PlexUIProvider/internal\"\nimport { TransitionGroup } from \"../Transition\"\nimport { createExitGuard, overlayTiming } from \"../Transition/shared\"\nimport s from \"@plexui/styles/components/Menu/Menu.module.css\"\n\ntype MenuContextValue = {\n open: boolean\n setOpen: (next: boolean) => void\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null)\n\nconst useMenuContext = () => {\n const context = useContext(MenuContext)\n\n if (!context) {\n throw new Error(\"Menu components must be wrapped in <Menu />\")\n }\n\n return context\n}\n\nexport type MenuProps = {\n children: React.ReactNode\n /** Force the menu to remain open or closed */\n forceOpen?: boolean\n /** Callback triggered when the modal is opened */\n onOpen?: () => void\n /** Callback triggered when the modal is closed */\n onClose?: () => void\n /**\n * When set to `true`, interaction with outside elements will be disabled and only menu content will be visible to screen readers.\n * @default false\n */\n modal?: boolean\n}\n\nexport const Menu = ({ children, forceOpen, onOpen, onClose, modal = false }: MenuProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const isOpen = forceOpen ?? open\n\n const latestOnOpen = useLatestValue(onOpen)\n const latestOnClose = useLatestValue(onClose)\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n setOpen(nextState)\n if (nextState) {\n latestOnOpen.current?.()\n } else {\n latestOnClose.current?.()\n }\n },\n [latestOnOpen, latestOnClose],\n )\n\n useEscCloseStack(open, () => {\n handleOpenChange(false)\n })\n\n const store = useMemo<MenuContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n }),\n [isOpen, handleOpenChange],\n )\n\n return (\n <MenuContext.Provider value={store}>\n <DropdownMenu.Root open={isOpen} onOpenChange={handleOpenChange} modal={modal}>\n {children}\n </DropdownMenu.Root>\n </MenuContext.Provider>\n )\n}\n\nexport type MenuItemProps = {\n className?: string\n children: React.ReactNode\n /**\n * Second line under the item's label: what this action does, or which\n * value it carries. The label goes semibold on its own, the same way a\n * Select option with a description does — same pattern, same anatomy.\n */\n description?: ReactNode\n /** Callback triggered when the item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Callback triggered when the item is clicked */\n onClick?: DropdownMenu.DropdownMenuItemProps[\"onClick\"]\n /** Disables the menu item */\n disabled?: boolean\n /** Marks a destructive action (delete, remove, leave): the item is drawn in the danger color */\n danger?: boolean\n}\n\nconst Item = ({ className, children, description, disabled, danger, onSelect, onClick }: MenuItemProps) => {\n const { open } = useMenuContext()\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we're always known to be closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n // A described item stacks its two lines; without a description the item\n // keeps the plain flex row that icons and ItemActions rely on.\n const content =\n description === undefined ? (\n children\n ) : (\n <div className={s.ItemLeading}>\n <div>{children}</div>\n <div className={s.ItemDescription}>{description}</div>\n </div>\n )\n\n // Custom click handlers: either callback makes the item interactive\n if (onSelect || onClick) {\n return (\n <DropdownMenu.Item\n className={clsx(s.MenuItem, className)}\n onSelect={onSelect}\n onClick={onClick}\n disabled={disabled}\n data-danger={danger ? \"\" : undefined}\n onPointerMove={handlePreventAfterClose}\n onPointerLeave={handlePreventAfterClose}\n >\n <div className={s.PressableInner}>{content}</div>\n </DropdownMenu.Item>\n )\n }\n\n // Read-only content - will not appear interactive.\n return <div className={clsx(s.MenuItemContent, className)}>{content}</div>\n}\n\nconst ItemActions = ({ className, children }: { className?: string; children: ReactNode }) => {\n return <div className={clsx(s.ItemActions, className)}>{children}</div>\n}\n\nconst ItemAction = ({\n children,\n onClick,\n \"aria-label\": ariaLabel,\n}: {\n children: ReactNode\n onClick: (evt: MouseEvent) => void\n /** Accessible name; the action is an icon-only button */\n \"aria-label\"?: string\n}) => {\n const { setOpen } = useMenuContext()\n\n return (\n <Button\n className=\"rounded-sm\"\n color=\"secondary\"\n size=\"xs\"\n uniform\n iconSize=\"sm\"\n variant=\"ghost\"\n aria-label={ariaLabel}\n onClick={(evt) => {\n evt.stopPropagation()\n setOpen(false)\n onClick(evt)\n }}\n >\n {children}\n </Button>\n )\n}\n\ntype MenuLinkProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\" | \"children\"> & {\n /** Content rendered inside the Link */\n children: React.ReactNode\n /** Disables the menu item */\n disabled?: boolean\n /** Marks a destructive destination: the item is drawn in the danger color */\n danger?: boolean\n}\n\ntype MenuLink = <\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends ComponentType<any> | \"a\" = PlexUI.LinkComponent,\n>(\n props: Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n MenuLinkProps & {\n /**\n * Override the default component used for the link. This is useful for\n * using a routing library, or SSR rendering.\n * purposes.\n *\n * @default 'a'\n */\n as?: T\n } & ComponentProps<T>,\n) => ReactNode\n\nconst Link = ((\n props: MenuLinkProps & { href?: string; to?: string; as?: PlexUI.LinkComponent },\n) => {\n const { className, children, href, to, disabled, danger, as: OverrideComponent, ...restProps } = props\n const { open } = useMenuContext()\n\n const propPath = href || to\n // When a path is not provided, default to an anchor\n const isExternal = propPath ? /^https?:\\/\\//.test(propPath) : true\n const DefaultComponent = useLinkComponent()\n const Component = OverrideComponent || (isExternal ? \"a\" : DefaultComponent)\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we're always known to be closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n const linkProps = isExternal\n ? { target: \"_blank\", rel: \"noopener noreferrer\", href: href ?? to }\n : { href, to }\n\n return (\n <DropdownMenu.Item\n asChild\n className={clsx(s.MenuItem, className)}\n disabled={disabled}\n data-danger={danger ? \"\" : undefined}\n onPointerMove={isExternal ? undefined : handlePreventAfterClose}\n onPointerLeave={isExternal ? undefined : handlePreventAfterClose}\n >\n <Component\n {...linkProps}\n {...restProps}\n onClick={(event: React.MouseEvent<HTMLAnchorElement>) => {\n restProps.onClick?.(event)\n // Radix skips selecting a disabled item, not the link's navigation\n if (disabled) event.preventDefault()\n }}\n >\n <span className={s.PressableInner}>{children}</span>\n </Component>\n </DropdownMenu.Item>\n )\n}) as MenuLink\n\nconst Separator = ({ className }: { className?: string }) => {\n return <DropdownMenu.Separator className={clsx(s.Separator, className)} role=\"separator\" />\n}\n\n\nconst Label = ({ className, children }: { className?: string; children: ReactNode }) => {\n return (\n <DropdownMenu.Label className={clsx(s.MenuLabel, className)}>\n {children}\n </DropdownMenu.Label>\n )\n}\n\nconst Group = ({\n className,\n children,\n}: {\n className?: string\n children: ReactNode\n}) => {\n return <DropdownMenu.Group className={className}>{children}</DropdownMenu.Group>\n}\n\nexport type MenuContentProps = {\n children: React.ReactNode\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default bottom\n */\n side?: DropdownMenu.DropdownMenuContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 5\n */\n sideOffset?: DropdownMenu.DropdownMenuContentProps[\"sideOffset\"]\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: DropdownMenu.DropdownMenuContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: DropdownMenu.DropdownMenuContentProps[\"alignOffset\"]\n /**\n * Defines the `width` property of the content\n * @default auto\n */\n width?: number | \"auto\"\n /**\n * Defines the `min-width` property of the content, in pixels.\n * @default 300\n */\n minWidth?: number | \"auto\"\n /**\n * Defines the `max-width` property of the content, in pixels.\n */\n maxHeight?: number\n /**\n * Rounder list with fully rounded rows, for menus that sit beside pill controls.\n * @default false\n */\n pill?: boolean\n /**\n * Layout direction of menu items.\n * Use `\"horizontal\"` for icon-based toolbars (iOS-style).\n * @default \"vertical\"\n */\n layout?: \"vertical\" | \"horizontal\"\n /**\n * Size of horizontal menu items. Controls icon size and padding.\n * Only applies when `layout=\"horizontal\"`.\n * @default \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\"\n /**\n * Event handler called when auto-focus tries to return to the trigger\n * after the menu closes. Call `event.preventDefault()` to prevent the\n * trigger from regaining focus (and its focus-visible ring).\n */\n onCloseAutoFocus?: DropdownMenu.DropdownMenuContentProps[\"onCloseAutoFocus\"]\n}\n\nconst Content = ({\n children,\n side,\n sideOffset = 5,\n align,\n alignOffset,\n width,\n minWidth,\n maxHeight,\n pill = false,\n layout = \"vertical\",\n size,\n onCloseAutoFocus,\n}: MenuContentProps) => {\n const { open } = useMenuContext()\n const [exitGuard] = useState(createExitGuard)\n const isHorizontal = layout === \"horizontal\"\n\n return (\n <DropdownMenu.Portal forceMount>\n <TransitionGroup className={s.Menu} {...overlayTiming} {...exitGuard.transition} overlay>\n {open && (\n <DropdownMenu.Content\n key=\"dropdown\"\n forceMount\n className={s.MenuList}\n data-pill={pill ? \"\" : undefined}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset ?? (align === \"center\" ? 0 : -5)}\n avoidCollisions\n collisionPadding={{ bottom: 30, top: 30, left: 12, right: 12 }}\n onEscapeKeyDown={preventDefaultHandler}\n onInteractOutside={exitGuard.onInteractOutside}\n onCloseAutoFocus={(event) => {\n onCloseAutoFocus?.(event)\n keepMovedFocus(event)\n }}\n data-layout={isHorizontal ? \"horizontal\" : undefined}\n data-size={isHorizontal && size ? size : undefined}\n style={toCssVariables({\n \"menu-width\": width,\n \"menu-min-width\": isHorizontal ? \"auto\" : minWidth,\n \"menu-max-height\": maxHeight,\n })}\n >\n {children}\n </DropdownMenu.Content>\n )}\n </TransitionGroup>\n </DropdownMenu.Portal>\n )\n}\n\nconst Trigger = ({\n children,\n disabled,\n ...restProps\n}: DropdownMenu.DropdownMenuTriggerProps & { ref?: React.Ref<HTMLButtonElement> }) => {\n // Always composes onto the child (asChild after the spread wins over a\n // caller's asChild); other props (aria-*, handlers, ref) reach it through\n // the Slot instead of being dropped\n return (\n <DropdownMenu.Trigger {...restProps} asChild disabled={disabled}>\n {children}\n </DropdownMenu.Trigger>\n )\n}\n\ntype SubmenuContextValue = {\n open: boolean\n setOpen: (next: boolean) => void\n triggerRef: React.RefObject<HTMLDivElement | null>\n}\n\nconst SubmenuContext = createContext<SubmenuContextValue | null>(null)\n\nconst useSubmenuContext = () => {\n const context = useContext(SubmenuContext)\n\n if (!context) {\n throw new Error(\"Submenu components must be wrapped in <Sub />\")\n }\n\n return context\n}\n\nexport type SubmenuProps = {\n children: React.ReactNode\n /** Force the menu to remain open or closed */\n forceOpen?: boolean\n /** Callback triggered when the modal is opened */\n onOpen?: () => void\n /** Callback triggered when the modal is closed */\n onClose?: () => void\n}\n\nconst Sub = ({ children, forceOpen, onOpen, onClose }: SubmenuProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const triggerRef = useRef<HTMLDivElement>(null)\n const isOpen = forceOpen ?? open\n\n const latestOnOpen = useLatestValue(onOpen)\n const latestOnClose = useLatestValue(onClose)\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n setOpen(nextState)\n if (nextState) {\n latestOnOpen.current?.()\n } else {\n latestOnClose.current?.()\n }\n },\n [latestOnOpen, latestOnClose],\n )\n\n useEscCloseStack(open, () => {\n handleOpenChange(false)\n // Ensure trigger is focused\n triggerRef.current?.focus()\n })\n\n const store = useMemo<SubmenuContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n triggerRef,\n }),\n [isOpen, handleOpenChange],\n )\n\n return (\n <SubmenuContext.Provider value={store}>\n <DropdownMenu.Sub open={isOpen} onOpenChange={handleOpenChange}>\n {children}\n </DropdownMenu.Sub>\n </SubmenuContext.Provider>\n )\n}\n\nconst SubTrigger = ({\n className,\n children,\n disabled,\n}: {\n className?: string\n children: ReactNode\n disabled?: boolean\n}) => {\n const { open } = useMenuContext()\n const { triggerRef } = useSubmenuContext()\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we know the outer menu is closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n return (\n <DropdownMenu.SubTrigger\n ref={triggerRef}\n className={clsx(s.MenuItem, s.SubMenuItem, className)}\n disabled={disabled}\n onPointerMove={handlePreventAfterClose}\n onPointerLeave={handlePreventAfterClose}\n >\n <div className={s.PressableInner}>\n {children}\n <ChevronRight width=\"16\" height=\"16\" className={s.SubTriggerIcon} />\n </div>\n </DropdownMenu.SubTrigger>\n )\n}\n\ntype SubContentProps = {\n children: ReactNode\n sideOffset?: DropdownMenu.DropdownMenuSubContentProps[\"sideOffset\"]\n alignOffset?: DropdownMenu.DropdownMenuSubContentProps[\"alignOffset\"]\n width?: number | \"auto\"\n minWidth?: number | \"auto\"\n maxHeight?: number\n pill?: boolean\n}\n\nconst SubContent = ({\n children,\n sideOffset = 4,\n alignOffset = -6,\n width = \"auto\",\n minWidth = \"auto\",\n maxHeight,\n pill = false,\n}: SubContentProps) => {\n const { open } = useSubmenuContext()\n\n return (\n <DropdownMenu.Portal forceMount>\n <TransitionGroup className={s.Menu} {...overlayTiming} overlay>\n {open && (\n <DropdownMenu.SubContent\n key=\"submenu\"\n className={s.MenuList}\n data-pill={pill ? \"\" : undefined}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n avoidCollisions\n collisionPadding={{ bottom: 30, top: 30, left: 12, right: 12 }}\n onEscapeKeyDown={preventDefaultHandler}\n style={toCssVariables({\n \"menu-width\": width,\n \"menu-min-width\": minWidth,\n \"menu-max-height\": maxHeight,\n })}\n >\n {children}\n </DropdownMenu.SubContent>\n )}\n </TransitionGroup>\n </DropdownMenu.Portal>\n )\n}\n\nexport type MenuRadioGroupProps<T extends string> = {\n /** Controlled value */\n value: T\n /** Fired when selection changes */\n onChange: (value: T) => void\n children: ReactNode\n /**\n * The orientation of the indicator within the radio item.\n * @default end\n */\n indicatorPosition?: \"start\" | \"end\"\n}\n\nconst RadioGroup = <T extends string>({\n children,\n value,\n onChange,\n indicatorPosition = \"end\",\n ...props\n}: MenuRadioGroupProps<T>) => (\n <DropdownMenu.RadioGroup\n {...props}\n value={value}\n onValueChange={(v: string) => onChange(v as T)}\n data-indicator-position={indicatorPosition}\n >\n {children}\n </DropdownMenu.RadioGroup>\n)\n\nexport type MenuRadioItemProps<T extends string> = {\n value: T\n /** Class applied to the radio item */\n className?: string\n children: ReactNode\n /** Callback triggered when the radio item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Disables the radio item */\n disabled?: boolean\n}\n\nconst RadioItem = <T extends string>({ className, children, ...props }: MenuRadioItemProps<T>) => (\n <DropdownMenu.RadioItem className={clsx(s.MenuItem, s.RadioItem, className)} {...props}>\n <div className={s.PressableInner}>\n <div className={s.RadioIndicator}>\n <DropdownMenu.ItemIndicator className={s.RadioIndicatorActive} />\n </div>\n {children}\n </div>\n </DropdownMenu.RadioItem>\n)\n\nexport type MenuCheckboxItemProps = {\n /** Controlled checked state of the checkbox item */\n checked?: DropdownMenu.DropdownMenuCheckboxItemProps[\"checked\"]\n /** Event handler called when the checked state changes */\n onCheckedChange?: DropdownMenu.DropdownMenuCheckboxItemProps[\"onCheckedChange\"]\n /** Class applied to the checkbox item */\n className?: string\n children: ReactNode\n /** Callback triggered when the checkbox item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Disables the checkbox item */\n disabled?: boolean\n /**\n * The orientation of the indicator within the checkbox item.\n * @default end\n */\n indicatorPosition?: \"start\" | \"end\"\n /**\n * Visual treatment for the checkbox indicator.\n * @default solid\n */\n indicatorVariant?: \"solid\" | \"ghost\"\n}\nconst CheckboxItem = ({\n className,\n children,\n indicatorPosition = \"end\",\n indicatorVariant = \"solid\",\n ...props\n}: MenuCheckboxItemProps) => (\n <DropdownMenu.CheckboxItem\n className={clsx(s.MenuItem, s.CheckboxItem, className)}\n {...props}\n data-indicator-position={indicatorPosition}\n data-indicator-variant={indicatorVariant}\n >\n <div className={s.PressableInner}>\n <div className={s.CheckboxIndicator}>\n <DropdownMenu.ItemIndicator>\n {indicatorVariant === \"ghost\" ? (\n <Check className=\"size-4\" />\n ) : (\n <div className={s.CheckboxCircle}>\n <Check className=\"size-4\" />\n </div>\n )}\n </DropdownMenu.ItemIndicator>\n </div>\n {children}\n </div>\n </DropdownMenu.CheckboxItem>\n)\n\nMenu.Content = Content\nMenu.Item = Item\nMenu.ItemActions = ItemActions\nMenu.ItemAction = ItemAction\nMenu.Link = Link\nMenu.Separator = Separator\nMenu.Trigger = Trigger\nMenu.Sub = Sub\nMenu.SubTrigger = SubTrigger\nMenu.SubContent = SubContent\nMenu.CheckboxItem = CheckboxItem\nMenu.RadioGroup = RadioGroup\nMenu.RadioItem = RadioItem\nMenu.Label = Label\nMenu.Group = Group\n"]}
@@ -6,8 +6,9 @@ import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
6
6
  import { useTimeout } from "usehooks-ts";
7
7
  import { useEscCloseStack } from "../../hooks/useEscCloseStack.js";
8
8
  import { useLatestValue } from "../../hooks/useLatestValue.js";
9
- import { focusableElements, preventDefaultHandler, toCssVariables } from "../../lib/helpers.js";
9
+ import { dataAttributes, focusableElements, keepMovedFocus, preventDefaultHandler, toCssVariables } from "../../lib/helpers.js";
10
10
  import { TransitionGroup } from "../Transition/index.js";
11
+ import { overlayTiming } from "../Transition/shared.js";
11
12
  import { createPointerIntentArea, isPointInPolygon } from "./pointerIntent.js";
12
13
  import s from "@plexui/styles/components/Popover/Popover.module.css";
13
14
  import { PopoverContext, usePopoverContext } from "./usePopoverContext.js";
@@ -133,7 +134,7 @@ const Trigger = ({ children, onPointerDown, onClick, }) => {
133
134
  }
134
135
  : undefined, children: children }));
135
136
  };
136
- const ContentImpl = ({ children, avoidCollisions, width, minWidth, maxWidth, side, sideOffset = 8, align, alignOffset, translucent, className, autoFocus = true, }) => {
137
+ const ContentImpl = ({ children, avoidCollisions, width, minWidth, maxWidth, side, sideOffset = 8, align, alignOffset, translucent, className, autoFocus = true, ...restProps }) => {
137
138
  const { showOnHover, shake, contentRef } = usePopoverContext();
138
139
  const handleKeyDown = (evt) => {
139
140
  const contentElement = contentRef.current;
@@ -169,20 +170,23 @@ const ContentImpl = ({ children, avoidCollisions, width, minWidth, maxWidth, sid
169
170
  // Our focus isn't in the content area - move it there.
170
171
  // NOTE: Don't automatically shift focus on hover popovers
171
172
  if (!showOnHover) {
172
- contentElement.focus({ preventScroll: true });
173
+ // In a microtask: until Radix's focus scope here has registered, a Dialog
174
+ // around this content sends the focus straight back, and the content
175
+ // takes that for focus moving outside and closes.
176
+ queueMicrotask(() => contentElement.focus({ preventScroll: true }));
173
177
  }
174
178
  }, [contentRef, showOnHover, autoFocus]);
175
- return (_jsx(RadixPopover.Content, { forceMount: true, ref: contentRef, className: clsx(s.Popover, className), style: toCssVariables({
179
+ return (_jsx(RadixPopover.Content, { ...dataAttributes(restProps), forceMount: true, ref: contentRef, className: clsx(s.Popover, className), style: toCssVariables({
176
180
  "popover-width": width,
177
181
  "popover-min-width": minWidth,
178
182
  "popover-max-width": maxWidth,
179
- }), onCloseAutoFocus: showOnHover ? preventDefaultHandler : undefined, "data-animate": shake ? "shake" : undefined, "data-translucent": translucent ? "true" : undefined, side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset ?? (align === "center" ? 0 : -5), avoidCollisions: avoidCollisions ?? true, hideWhenDetached: true, collisionPadding: 20, onOpenAutoFocus: preventDefaultHandler,
183
+ }), onCloseAutoFocus: showOnHover ? preventDefaultHandler : keepMovedFocus, "data-animate": shake ? "shake" : undefined, "data-translucent": translucent ? "true" : undefined, side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset ?? (align === "center" ? 0 : -5), avoidCollisions: avoidCollisions ?? true, hideWhenDetached: true, collisionPadding: 20, onOpenAutoFocus: preventDefaultHandler,
180
184
  // Use custom esc listener because default Radix is bound to the document
181
185
  // and cannot have propagation stopped.
182
186
  onEscapeKeyDown: preventDefaultHandler, onKeyDown: handleKeyDown, children: children }));
183
187
  };
184
188
  const ContentHoverable = (props) => {
185
- const { setOpen, triggerRef, contentRef, isPointerInTransitRef, hoverOpenFocusedWithTab } = usePopoverContext();
189
+ const { open, setOpen, triggerRef, contentRef, isPointerInTransitRef, hoverOpenFocusedWithTab } = usePopoverContext();
186
190
  const [pointerGraceArea, setPointerGraceArea] = useState(null);
187
191
  const handleRemoveGraceArea = useCallback(() => {
188
192
  setPointerGraceArea(null);
@@ -239,6 +243,10 @@ const ContentHoverable = (props) => {
239
243
  // If this is open, and tab is pressed, and focusableElements() has an element, prevent default behavior and focus it
240
244
  // Then set a flag (probably in context) that tells us to restore focus to the trigger on close (e.g., not execute the onCloseAutoFocus handler)
241
245
  useEffect(() => {
246
+ // Closed and still leaving: Tab belongs to the page again
247
+ if (!open) {
248
+ return;
249
+ }
242
250
  const handleKeyDown = (evt) => {
243
251
  if (!contentRef.current) {
244
252
  return;
@@ -258,7 +266,7 @@ const ContentHoverable = (props) => {
258
266
  return () => {
259
267
  document.removeEventListener("keydown", handleKeyDown);
260
268
  };
261
- }, [contentRef, hoverOpenFocusedWithTab]);
269
+ }, [open, contentRef, hoverOpenFocusedWithTab]);
262
270
  return _jsx(ContentImpl, { ...props });
263
271
  };
264
272
  const Content = (props) => {
@@ -266,7 +274,7 @@ const Content = (props) => {
266
274
  useEscCloseStack(open, () => {
267
275
  setOpen(false);
268
276
  });
269
- return (_jsx(RadixPopover.Portal, { forceMount: true, children: _jsx(TransitionGroup, { enterDuration: 600, exitDuration: 300, className: s.Transition, disableAnimations: true, children: open &&
277
+ return (_jsx(RadixPopover.Portal, { forceMount: true, children: _jsx(TransitionGroup, { ...overlayTiming, className: s.Transition, overlay: true, children: open &&
270
278
  (showOnHover ? (_jsx(ContentHoverable, { ...props }, "popover-hover")) : (_jsx(ContentImpl, { ...props }, "popover"))) }) }));
271
279
  };
272
280
  Popover.Trigger = Trigger;
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.js","sourceRoot":"","sources":["../../../../src/components/Popover/Popover.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { Popover as RadixPopover } from \"radix-ui\"\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEventHandler,\n type MouseEventHandler,\n type PointerEventHandler,\n type ReactNode,\n} from \"react\"\nimport { useTimeout } from \"usehooks-ts\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { focusableElements, preventDefaultHandler, toCssVariables } from \"../../lib/helpers\"\nimport { TransitionGroup } from \"../Transition\"\nimport { createPointerIntentArea, isPointInPolygon, type Polygon } from \"./pointerIntent\"\nimport s from \"@plexui/styles/components/Popover/Popover.module.css\"\nimport { PopoverContext, usePopoverContext, type PopoverContextValue } from \"./usePopoverContext\"\n\nexport type PopoverProps = {\n /** Sets controlled visibility state */\n open?: boolean\n /** Callback invoked when visibility state changes */\n onOpenChange?: (nextState: boolean) => void\n showOnHover?: boolean\n hoverOpenDelay?: number\n children: React.ReactNode\n}\n\nexport const Popover = ({\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n showOnHover = false,\n hoverOpenDelay = 150,\n children,\n}: PopoverProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const [shake, setShake] = useState<boolean>(false)\n const triggerRef = useRef<HTMLButtonElement>(null)\n const contentRef = useRef<HTMLDivElement>(null)\n const openTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined)\n const hoverOpenFocusedWithTab = useRef<boolean>(false)\n const isPointerInTransitRef = useRef<boolean>(false)\n const isOpen = controlledOpen ?? open\n\n const [temporarilyPreventClickToClose, setTemporarilyPreventClickToClose] =\n useState<boolean>(false)\n useTimeout(\n () => setTemporarilyPreventClickToClose(false),\n temporarilyPreventClickToClose ? 500 : null,\n )\n\n const latestOpenChange = useLatestValue(controlledOnOpenChange)\n\n const handleOpenChangeImpl = useLatestValue((nextState: boolean) => {\n clearTimeout(openTimerRef.current)\n\n // No-op if the state is not changing\n if (isOpen === nextState) {\n return\n }\n\n if (!nextState) {\n // clear any running shake animation on close\n setShake(false)\n\n // Check for specific hover conditions where focus should be\n // immediately restored to the trigger before closing\n if (showOnHover && hoverOpenFocusedWithTab.current) {\n triggerRef.current?.focus()\n }\n\n // Always cleanup this state\n hoverOpenFocusedWithTab.current = false\n }\n\n latestOpenChange.current?.(nextState)\n setOpen(nextState)\n\n if (showOnHover) {\n setTemporarilyPreventClickToClose(nextState)\n }\n })\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n handleOpenChangeImpl.current(nextState)\n },\n [handleOpenChangeImpl],\n )\n\n const handleTriggerEnter = useCallback(() => {\n openTimerRef.current = setTimeout(() => handleOpenChange(true), hoverOpenDelay)\n }, [handleOpenChange, hoverOpenDelay])\n\n const handleTriggerLeave = useCallback(() => {\n clearTimeout(openTimerRef.current)\n }, [])\n\n useEffect(() => {\n return () => {\n clearTimeout(openTimerRef.current)\n }\n }, [])\n\n const store = useMemo<PopoverContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n shake,\n setShake,\n showOnHover,\n temporarilyPreventClickToClose,\n onTriggerEnter: handleTriggerEnter,\n onTriggerLeave: handleTriggerLeave,\n isPointerInTransitRef,\n triggerRef,\n contentRef,\n hoverOpenFocusedWithTab,\n }),\n [\n isOpen,\n handleOpenChange,\n shake,\n setShake,\n showOnHover,\n temporarilyPreventClickToClose,\n hoverOpenFocusedWithTab,\n isPointerInTransitRef,\n handleTriggerEnter,\n handleTriggerLeave,\n ],\n )\n\n return (\n <PopoverContext value={store}>\n <RadixPopover.Root open={isOpen} onOpenChange={handleOpenChange} modal={false}>\n {children}\n </RadixPopover.Root>\n </PopoverContext>\n )\n}\n\nconst Trigger = ({\n children,\n onPointerDown,\n onClick,\n}: {\n children: React.ReactNode\n onPointerDown?: PointerEventHandler\n onClick?: MouseEventHandler\n}) => {\n const {\n setOpen,\n showOnHover,\n temporarilyPreventClickToClose,\n onTriggerEnter,\n onTriggerLeave,\n isPointerInTransitRef,\n triggerRef,\n contentRef,\n } = usePopoverContext()\n const hasPointerMoveOpenedRef = useRef<boolean>(false)\n\n const maybePreventClickClose = (evt: React.MouseEvent) => {\n // Don't prevent temporary close if the trigger is an anchor tag itself\n const isLink = evt.currentTarget.nodeName.toLocaleLowerCase() === \"a\"\n\n if (!isLink && temporarilyPreventClickToClose) {\n // Prevents tooltip listeners from closing\n evt.preventDefault()\n evt.stopPropagation()\n }\n }\n\n const handlePointerMove = (evt: React.PointerEvent) => {\n if (evt.pointerType === \"touch\") {\n return\n }\n\n if (!hasPointerMoveOpenedRef.current && !isPointerInTransitRef.current) {\n onTriggerEnter()\n hasPointerMoveOpenedRef.current = true\n }\n }\n\n const handlePointerLeave = () => {\n if (!hasPointerMoveOpenedRef.current) {\n return\n }\n\n onTriggerLeave()\n hasPointerMoveOpenedRef.current = false\n }\n\n return (\n <RadixPopover.Trigger\n asChild\n ref={triggerRef}\n onPointerDown={(evt) => {\n maybePreventClickClose(evt)\n onPointerDown?.(evt)\n }}\n onClick={(evt) => {\n maybePreventClickClose(evt)\n onClick?.(evt)\n }}\n onPointerMove={showOnHover ? handlePointerMove : undefined}\n onPointerLeave={showOnHover ? handlePointerLeave : undefined}\n onFocus={showOnHover ? () => setOpen(true) : undefined}\n onBlur={\n showOnHover\n ? () => {\n setTimeout(() => {\n // Ignore this handler if focus has moved into the popover\n if (contentRef.current?.contains(document.activeElement)) {\n return\n }\n\n setOpen(false)\n }, 50)\n }\n : undefined\n }\n >\n {children}\n </RadixPopover.Trigger>\n )\n}\n\nexport type PopoverContentProps = {\n children: ReactNode\n /**\n * Whether to avoid collisions with vieport/scroll containersw.\n * @default true\n */\n avoidCollisions?: boolean\n /**\n * Set the `width` of the popover, in pixels.\n * @default auto\n */\n width?: number | \"auto\"\n /**\n * Set the `min-width` of the popover, in pixels.\n * @default 300\n */\n minWidth?: number | \"auto\"\n /**\n * Set the `max-width` of the popover, in pixels.\n */\n maxWidth?: number\n /**\n * Background style for the popover\n * @default default\n */\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default bottom\n */\n side?: RadixPopover.PopoverContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 8\n */\n sideOffset?: RadixPopover.PopoverContentProps[\"sideOffset\"]\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: RadixPopover.PopoverContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: RadixPopover.PopoverContentProps[\"alignOffset\"]\n /**\n * Whether the popover surface should be translucent.\n * @default false\n */\n translucent?: boolean\n /** Additional class name to apply to the popover content, you usually don't want to set this, but ag-grid needs it to render a custom editor properly */\n className?: string\n /**\n * Auto focus the popover content when it is opened.\n * @default true\n */\n autoFocus?: boolean\n}\n\nconst ContentImpl = ({\n children,\n avoidCollisions,\n width,\n minWidth,\n maxWidth,\n side,\n sideOffset = 8,\n align,\n alignOffset,\n translucent,\n className,\n autoFocus = true,\n}: PopoverContentProps) => {\n const { showOnHover, shake, contentRef } = usePopoverContext()\n\n const handleKeyDown: KeyboardEventHandler<HTMLDivElement> = (evt) => {\n const contentElement = contentRef.current\n\n if (\n // When the current target is our container\n contentElement &&\n evt.target === contentElement &&\n // We know that shift key tabs will lead to closing the popover (because we don't use `modal`)\n evt.key === \"Tab\" &&\n evt.shiftKey\n ) {\n // Prevent that from happening\n evt.preventDefault()\n evt.stopPropagation()\n\n // Move focus to the last focusable element, placing the user in the focus loop\n const focusable = focusableElements(contentElement)\n const lastFocusable = focusable[focusable.length - 1]\n lastFocusable?.focus()\n }\n }\n\n // Important that we send initial focus into the popover, placing it onto the container.\n // This allows focus looping to begin, as well as capturing scoped key presses.\n // We prevent Radix's default behavior of focusing an element, because this can have adverse side-effects.\n useEffect(() => {\n const contentElement = contentRef.current\n\n if (!contentElement || !autoFocus) {\n return\n }\n\n // If we're already focused within the content area, no-op.\n // This would be true if some inner component declares autoFocus\n if (contentElement?.contains(document.activeElement)) {\n return\n }\n\n // Our focus isn't in the content area - move it there.\n // NOTE: Don't automatically shift focus on hover popovers\n if (!showOnHover) {\n contentElement.focus({ preventScroll: true })\n }\n }, [contentRef, showOnHover, autoFocus])\n\n return (\n <RadixPopover.Content\n forceMount\n ref={contentRef}\n className={clsx(s.Popover, className)}\n style={toCssVariables({\n \"popover-width\": width,\n \"popover-min-width\": minWidth,\n \"popover-max-width\": maxWidth,\n })}\n onCloseAutoFocus={showOnHover ? preventDefaultHandler : undefined}\n // data-surface={surface}\n data-animate={shake ? \"shake\" : undefined}\n data-translucent={translucent ? \"true\" : undefined}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset ?? (align === \"center\" ? 0 : -5)}\n avoidCollisions={avoidCollisions ?? true}\n hideWhenDetached\n collisionPadding={20}\n onOpenAutoFocus={preventDefaultHandler}\n // Use custom esc listener because default Radix is bound to the document\n // and cannot have propagation stopped.\n onEscapeKeyDown={preventDefaultHandler}\n onKeyDown={handleKeyDown}\n >\n {children}\n </RadixPopover.Content>\n )\n}\n\nconst ContentHoverable = (props: PopoverContentProps) => {\n const { setOpen, triggerRef, contentRef, isPointerInTransitRef, hoverOpenFocusedWithTab } =\n usePopoverContext()\n const [pointerGraceArea, setPointerGraceArea] = useState<Polygon | null>(null)\n\n const handleRemoveGraceArea = useCallback(() => {\n setPointerGraceArea(null)\n isPointerInTransitRef.current = false\n }, [isPointerInTransitRef])\n\n const handleCreateGraceArea = useCallback(\n (event: PointerEvent, hoverTarget: HTMLElement) => {\n const graceArea = createPointerIntentArea(event, hoverTarget)\n setPointerGraceArea(graceArea)\n isPointerInTransitRef.current = true\n },\n [isPointerInTransitRef],\n )\n\n useEffect(() => {\n return () => handleRemoveGraceArea()\n }, [handleRemoveGraceArea])\n\n useEffect(() => {\n const trigger = triggerRef.current\n const content = contentRef.current\n\n if (!trigger || !content) {\n return\n }\n\n const handleTriggerLeave = (event: PointerEvent) => handleCreateGraceArea(event, content)\n const handleContentLeave = (event: PointerEvent) => handleCreateGraceArea(event, trigger)\n\n trigger.addEventListener(\"pointerleave\", handleTriggerLeave)\n content.addEventListener(\"pointerleave\", handleContentLeave)\n return () => {\n trigger.removeEventListener(\"pointerleave\", handleTriggerLeave)\n content.removeEventListener(\"pointerleave\", handleContentLeave)\n }\n }, [contentRef, triggerRef, handleCreateGraceArea, handleRemoveGraceArea])\n\n useEffect(() => {\n if (!pointerGraceArea) {\n return\n }\n\n const handleTrackPointerGrace = (event: PointerEvent) => {\n const trigger = triggerRef.current\n const content = contentRef.current\n const target = event.target as HTMLElement\n const pointerPosition = { x: event.clientX, y: event.clientY }\n const hasEnteredTarget = trigger?.contains(target) || content?.contains(target)\n const isPointerOutsideGraceArea = !isPointInPolygon(pointerPosition, pointerGraceArea)\n // Stop considering grace areas when the pointer runs into other control triggers\n const targetHasPopup = target.hasAttribute(\"aria-haspopup\")\n\n if (hasEnteredTarget) {\n handleRemoveGraceArea()\n } else if (isPointerOutsideGraceArea || targetHasPopup) {\n handleRemoveGraceArea()\n setOpen(false)\n }\n }\n document.addEventListener(\"pointermove\", handleTrackPointerGrace)\n return () => document.removeEventListener(\"pointermove\", handleTrackPointerGrace)\n }, [pointerGraceArea, setOpen, handleRemoveGraceArea, triggerRef, contentRef])\n\n // Hoverable doesn't place focus in the popover by default\n // If this is open, and tab is pressed, and focusableElements() has an element, prevent default behavior and focus it\n // Then set a flag (probably in context) that tells us to restore focus to the trigger on close (e.g., not execute the onCloseAutoFocus handler)\n\n useEffect(() => {\n const handleKeyDown = (evt: KeyboardEvent) => {\n if (!contentRef.current) {\n return\n }\n\n // Only assume forward tab is attempting to move into the popup\n if (evt.key === \"Tab\" && !evt.shiftKey) {\n const [firstFocusable] = focusableElements(contentRef.current)\n if (firstFocusable) {\n evt.preventDefault()\n firstFocusable.focus()\n hoverOpenFocusedWithTab.current = true\n document.removeEventListener(\"keydown\", handleKeyDown)\n }\n }\n }\n document.addEventListener(\"keydown\", handleKeyDown)\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown)\n }\n }, [contentRef, hoverOpenFocusedWithTab])\n\n return <ContentImpl {...props} />\n}\n\nconst Content = (props: PopoverContentProps) => {\n const { open, showOnHover, setOpen } = usePopoverContext()\n\n useEscCloseStack(open, () => {\n setOpen(false)\n })\n\n return (\n <RadixPopover.Portal forceMount>\n <TransitionGroup\n enterDuration={600}\n exitDuration={300}\n className={s.Transition}\n disableAnimations\n >\n {open &&\n (showOnHover ? (\n <ContentHoverable key=\"popover-hover\" {...props} />\n ) : (\n <ContentImpl key=\"popover\" {...props} />\n ))}\n </TransitionGroup>\n </RadixPopover.Portal>\n )\n}\n\nPopover.Trigger = Trigger\nPopover.Content = Content\n"]}
1
+ {"version":3,"file":"Popover.js","sourceRoot":"","sources":["../../../../src/components/Popover/Popover.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EACL,WAAW,EACX,SAAS,EACT,OAAO,EACP,MAAM,EACN,QAAQ,GAKT,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAC5H,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAgB,MAAM,iBAAiB,CAAA;AACzF,OAAO,CAAC,MAAM,sDAAsD,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAA4B,MAAM,qBAAqB,CAAA;AAYjG,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,EACtB,IAAI,EAAE,cAAc,EACpB,YAAY,EAAE,sBAAsB,EACpC,WAAW,GAAG,KAAK,EACnB,cAAc,GAAG,GAAG,EACpB,QAAQ,GACK,EAAE,EAAE;IACjB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAA;IAChD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAA;IAClD,MAAM,UAAU,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAA;IAClD,MAAM,UAAU,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAA;IAC/C,MAAM,YAAY,GAAG,MAAM,CAAgC,SAAS,CAAC,CAAA;IACrE,MAAM,uBAAuB,GAAG,MAAM,CAAU,KAAK,CAAC,CAAA;IACtD,MAAM,qBAAqB,GAAG,MAAM,CAAU,KAAK,CAAC,CAAA;IACpD,MAAM,MAAM,GAAG,cAAc,IAAI,IAAI,CAAA;IAErC,MAAM,CAAC,8BAA8B,EAAE,iCAAiC,CAAC,GACvE,QAAQ,CAAU,KAAK,CAAC,CAAA;IAC1B,UAAU,CACR,GAAG,EAAE,CAAC,iCAAiC,CAAC,KAAK,CAAC,EAC9C,8BAA8B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAC5C,CAAA;IAED,MAAM,gBAAgB,GAAG,cAAc,CAAC,sBAAsB,CAAC,CAAA;IAE/D,MAAM,oBAAoB,GAAG,cAAc,CAAC,CAAC,SAAkB,EAAE,EAAE;QACjE,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;QAElC,qCAAqC;QACrC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAM;QACR,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,6CAA6C;YAC7C,QAAQ,CAAC,KAAK,CAAC,CAAA;YAEf,4DAA4D;YAC5D,qDAAqD;YACrD,IAAI,WAAW,IAAI,uBAAuB,CAAC,OAAO,EAAE,CAAC;gBACnD,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;YAC7B,CAAC;YAED,4BAA4B;YAC5B,uBAAuB,CAAC,OAAO,GAAG,KAAK,CAAA;QACzC,CAAC;QAED,gBAAgB,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAA;QACrC,OAAO,CAAC,SAAS,CAAC,CAAA;QAElB,IAAI,WAAW,EAAE,CAAC;YAChB,iCAAiC,CAAC,SAAS,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,gBAAgB,GAAG,WAAW,CAClC,CAAC,SAAkB,EAAE,EAAE;QACrB,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACzC,CAAC,EACD,CAAC,oBAAoB,CAAC,CACvB,CAAA;IAED,MAAM,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC1C,YAAY,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,CAAA;IACjF,CAAC,EAAE,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC,CAAA;IAEtC,MAAM,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC1C,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;IACpC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;QACpC,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC;QACL,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,gBAAgB;QACzB,KAAK;QACL,QAAQ;QACR,WAAW;QACX,8BAA8B;QAC9B,cAAc,EAAE,kBAAkB;QAClC,cAAc,EAAE,kBAAkB;QAClC,qBAAqB;QACrB,UAAU;QACV,UAAU;QACV,uBAAuB;KACxB,CAAC,EACF;QACE,MAAM;QACN,gBAAgB;QAChB,KAAK;QACL,QAAQ;QACR,WAAW;QACX,8BAA8B;QAC9B,uBAAuB;QACvB,qBAAqB;QACrB,kBAAkB;QAClB,kBAAkB;KACnB,CACF,CAAA;IAED,OAAO,CACL,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,YAC1B,KAAC,YAAY,CAAC,IAAI,IAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,YAC1E,QAAQ,GACS,GACL,CAClB,CAAA;AACH,CAAC,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,EACf,QAAQ,EACR,aAAa,EACb,OAAO,GAKR,EAAE,EAAE;IACH,MAAM,EACJ,OAAO,EACP,WAAW,EACX,8BAA8B,EAC9B,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,UAAU,EACV,UAAU,GACX,GAAG,iBAAiB,EAAE,CAAA;IACvB,MAAM,uBAAuB,GAAG,MAAM,CAAU,KAAK,CAAC,CAAA;IAEtD,MAAM,sBAAsB,GAAG,CAAC,GAAqB,EAAE,EAAE;QACvD,uEAAuE;QACvE,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,EAAE,KAAK,GAAG,CAAA;QAErE,IAAI,CAAC,MAAM,IAAI,8BAA8B,EAAE,CAAC;YAC9C,0CAA0C;YAC1C,GAAG,CAAC,cAAc,EAAE,CAAA;YACpB,GAAG,CAAC,eAAe,EAAE,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,iBAAiB,GAAG,CAAC,GAAuB,EAAE,EAAE;QACpD,IAAI,GAAG,CAAC,WAAW,KAAK,OAAO,EAAE,CAAC;YAChC,OAAM;QACR,CAAC;QAED,IAAI,CAAC,uBAAuB,CAAC,OAAO,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,CAAC;YACvE,cAAc,EAAE,CAAA;YAChB,uBAAuB,CAAC,OAAO,GAAG,IAAI,CAAA;QACxC,CAAC;IACH,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG,GAAG,EAAE;QAC9B,IAAI,CAAC,uBAAuB,CAAC,OAAO,EAAE,CAAC;YACrC,OAAM;QACR,CAAC;QAED,cAAc,EAAE,CAAA;QAChB,uBAAuB,CAAC,OAAO,GAAG,KAAK,CAAA;IACzC,CAAC,CAAA;IAED,OAAO,CACL,KAAC,YAAY,CAAC,OAAO,IACnB,OAAO,QACP,GAAG,EAAE,UAAU,EACf,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE;YACrB,sBAAsB,CAAC,GAAG,CAAC,CAAA;YAC3B,aAAa,EAAE,CAAC,GAAG,CAAC,CAAA;QACtB,CAAC,EACD,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACf,sBAAsB,CAAC,GAAG,CAAC,CAAA;YAC3B,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;QAChB,CAAC,EACD,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,EAC1D,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,EAC5D,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EACtD,MAAM,EACJ,WAAW;YACT,CAAC,CAAC,GAAG,EAAE;gBACH,UAAU,CAAC,GAAG,EAAE;oBACd,0DAA0D;oBAC1D,IAAI,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;wBACzD,OAAM;oBACR,CAAC;oBAED,OAAO,CAAC,KAAK,CAAC,CAAA;gBAChB,CAAC,EAAE,EAAE,CAAC,CAAA;YACR,CAAC;YACH,CAAC,CAAC,SAAS,YAGd,QAAQ,GACY,CACxB,CAAA;AACH,CAAC,CAAA;AA+DD,MAAM,WAAW,GAAG,CAAC,EACnB,QAAQ,EACR,eAAe,EACf,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,UAAU,GAAG,CAAC,EACd,KAAK,EACL,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,GAAG,IAAI,EAChB,GAAG,SAAS,EACQ,EAAE,EAAE;IACxB,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,iBAAiB,EAAE,CAAA;IAE9D,MAAM,aAAa,GAAyC,CAAC,GAAG,EAAE,EAAE;QAClE,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAA;QAEzC;QACE,2CAA2C;QAC3C,cAAc;YACd,GAAG,CAAC,MAAM,KAAK,cAAc;YAC7B,8FAA8F;YAC9F,GAAG,CAAC,GAAG,KAAK,KAAK;YACjB,GAAG,CAAC,QAAQ,EACZ,CAAC;YACD,8BAA8B;YAC9B,GAAG,CAAC,cAAc,EAAE,CAAA;YACpB,GAAG,CAAC,eAAe,EAAE,CAAA;YAErB,+EAA+E;YAC/E,MAAM,SAAS,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAA;YACnD,MAAM,aAAa,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YACrD,aAAa,EAAE,KAAK,EAAE,CAAA;QACxB,CAAC;IACH,CAAC,CAAA;IAED,wFAAwF;IACxF,+EAA+E;IAC/E,0GAA0G;IAC1G,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAA;QAEzC,IAAI,CAAC,cAAc,IAAI,CAAC,SAAS,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QAED,2DAA2D;QAC3D,gEAAgE;QAChE,IAAI,cAAc,EAAE,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YACrD,OAAM;QACR,CAAC;QAED,uDAAuD;QACvD,0DAA0D;QAC1D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,0EAA0E;YAC1E,qEAAqE;YACrE,kDAAkD;YAClD,cAAc,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACrE,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,CAAA;IAExC,OAAO,CACL,KAAC,YAAY,CAAC,OAAO,OACf,cAAc,CAAC,SAAS,CAAC,EAC7B,UAAU,QACV,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EACrC,KAAK,EAAE,cAAc,CAAC;YACpB,eAAe,EAAE,KAAK;YACtB,mBAAmB,EAAE,QAAQ;YAC7B,mBAAmB,EAAE,QAAQ;SAC9B,CAAC,EACF,gBAAgB,EAAE,WAAW,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,cAAc,kBAExD,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,sBACvB,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAClD,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACzD,eAAe,EAAE,eAAe,IAAI,IAAI,EACxC,gBAAgB,QAChB,gBAAgB,EAAE,EAAE,EACpB,eAAe,EAAE,qBAAqB;QACtC,yEAAyE;QACzE,uCAAuC;QACvC,eAAe,EAAE,qBAAqB,EACtC,SAAS,EAAE,aAAa,YAEvB,QAAQ,GACY,CACxB,CAAA;AACH,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,CAAC,KAA0B,EAAE,EAAE;IACtD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,GAC7F,iBAAiB,EAAE,CAAA;IACrB,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC,CAAA;IAE9E,MAAM,qBAAqB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7C,mBAAmB,CAAC,IAAI,CAAC,CAAA;QACzB,qBAAqB,CAAC,OAAO,GAAG,KAAK,CAAA;IACvC,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAA;IAE3B,MAAM,qBAAqB,GAAG,WAAW,CACvC,CAAC,KAAmB,EAAE,WAAwB,EAAE,EAAE;QAChD,MAAM,SAAS,GAAG,uBAAuB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;QAC7D,mBAAmB,CAAC,SAAS,CAAC,CAAA;QAC9B,qBAAqB,CAAC,OAAO,GAAG,IAAI,CAAA;IACtC,CAAC,EACD,CAAC,qBAAqB,CAAC,CACxB,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE,CAAC,qBAAqB,EAAE,CAAA;IACtC,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAA;IAE3B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAA;QAClC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAA;QAElC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;YACzB,OAAM;QACR,CAAC;QAED,MAAM,kBAAkB,GAAG,CAAC,KAAmB,EAAE,EAAE,CAAC,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QACzF,MAAM,kBAAkB,GAAG,CAAC,KAAmB,EAAE,EAAE,CAAC,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAEzF,OAAO,CAAC,gBAAgB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAA;QAC5D,OAAO,CAAC,gBAAgB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAA;QAC5D,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,mBAAmB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAA;YAC/D,OAAO,CAAC,mBAAmB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAA;QACjE,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,qBAAqB,EAAE,qBAAqB,CAAC,CAAC,CAAA;IAE1E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QAED,MAAM,uBAAuB,GAAG,CAAC,KAAmB,EAAE,EAAE;YACtD,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAA;YAClC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAA;YAClC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB,CAAA;YAC1C,MAAM,eAAe,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;YAC9D,MAAM,gBAAgB,GAAG,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;YAC/E,MAAM,yBAAyB,GAAG,CAAC,gBAAgB,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAA;YACtF,iFAAiF;YACjF,MAAM,cAAc,GAAG,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAA;YAE3D,IAAI,gBAAgB,EAAE,CAAC;gBACrB,qBAAqB,EAAE,CAAA;YACzB,CAAC;iBAAM,IAAI,yBAAyB,IAAI,cAAc,EAAE,CAAC;gBACvD,qBAAqB,EAAE,CAAA;gBACvB,OAAO,CAAC,KAAK,CAAC,CAAA;YAChB,CAAC;QACH,CAAC,CAAA;QACD,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,uBAAuB,CAAC,CAAA;QACjE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,uBAAuB,CAAC,CAAA;IACnF,CAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAA;IAE9E,0DAA0D;IAC1D,qHAAqH;IACrH,gJAAgJ;IAEhJ,SAAS,CAAC,GAAG,EAAE;QACb,0DAA0D;QAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAM;QACR,CAAC;QAED,MAAM,aAAa,GAAG,CAAC,GAAkB,EAAE,EAAE;YAC3C,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;gBACxB,OAAM;YACR,CAAC;YAED,+DAA+D;YAC/D,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACvC,MAAM,CAAC,cAAc,CAAC,GAAG,iBAAiB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;gBAC9D,IAAI,cAAc,EAAE,CAAC;oBACnB,GAAG,CAAC,cAAc,EAAE,CAAA;oBACpB,cAAc,CAAC,KAAK,EAAE,CAAA;oBACtB,uBAAuB,CAAC,OAAO,GAAG,IAAI,CAAA;oBACtC,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;gBACxD,CAAC;YACH,CAAC;QACH,CAAC,CAAA;QACD,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;QACnD,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;QACxD,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,uBAAuB,CAAC,CAAC,CAAA;IAE/C,OAAO,KAAC,WAAW,OAAK,KAAK,GAAI,CAAA;AACnC,CAAC,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,KAA0B,EAAE,EAAE;IAC7C,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,iBAAiB,EAAE,CAAA;IAE1D,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,CAAA;IAChB,CAAC,CAAC,CAAA;IAEF,OAAO,CACL,KAAC,YAAY,CAAC,MAAM,IAAC,UAAU,kBAC7B,KAAC,eAAe,OAAK,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,UAAU,EAAE,OAAO,kBACjE,IAAI;gBACH,CAAC,WAAW,CAAC,CAAC,CAAC,CACb,KAAC,gBAAgB,OAAyB,KAAK,IAAzB,eAAe,CAAc,CACpD,CAAC,CAAC,CAAC,CACF,KAAC,WAAW,OAAmB,KAAK,IAAnB,SAAS,CAAc,CACzC,CAAC,GACY,GACE,CACvB,CAAA;AACH,CAAC,CAAA;AAED,OAAO,CAAC,OAAO,GAAG,OAAO,CAAA;AACzB,OAAO,CAAC,OAAO,GAAG,OAAO,CAAA","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { Popover as RadixPopover } from \"radix-ui\"\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEventHandler,\n type MouseEventHandler,\n type PointerEventHandler,\n type ReactNode,\n} from \"react\"\nimport { useTimeout } from \"usehooks-ts\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { dataAttributes, focusableElements, keepMovedFocus, preventDefaultHandler, toCssVariables } from \"../../lib/helpers\"\nimport { TransitionGroup } from \"../Transition\"\nimport { overlayTiming } from \"../Transition/shared\"\nimport { createPointerIntentArea, isPointInPolygon, type Polygon } from \"./pointerIntent\"\nimport s from \"@plexui/styles/components/Popover/Popover.module.css\"\nimport { PopoverContext, usePopoverContext, type PopoverContextValue } from \"./usePopoverContext\"\n\nexport type PopoverProps = {\n /** Sets controlled visibility state */\n open?: boolean\n /** Callback invoked when visibility state changes */\n onOpenChange?: (nextState: boolean) => void\n showOnHover?: boolean\n hoverOpenDelay?: number\n children: React.ReactNode\n}\n\nexport const Popover = ({\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n showOnHover = false,\n hoverOpenDelay = 150,\n children,\n}: PopoverProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const [shake, setShake] = useState<boolean>(false)\n const triggerRef = useRef<HTMLButtonElement>(null)\n const contentRef = useRef<HTMLDivElement>(null)\n const openTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined)\n const hoverOpenFocusedWithTab = useRef<boolean>(false)\n const isPointerInTransitRef = useRef<boolean>(false)\n const isOpen = controlledOpen ?? open\n\n const [temporarilyPreventClickToClose, setTemporarilyPreventClickToClose] =\n useState<boolean>(false)\n useTimeout(\n () => setTemporarilyPreventClickToClose(false),\n temporarilyPreventClickToClose ? 500 : null,\n )\n\n const latestOpenChange = useLatestValue(controlledOnOpenChange)\n\n const handleOpenChangeImpl = useLatestValue((nextState: boolean) => {\n clearTimeout(openTimerRef.current)\n\n // No-op if the state is not changing\n if (isOpen === nextState) {\n return\n }\n\n if (!nextState) {\n // clear any running shake animation on close\n setShake(false)\n\n // Check for specific hover conditions where focus should be\n // immediately restored to the trigger before closing\n if (showOnHover && hoverOpenFocusedWithTab.current) {\n triggerRef.current?.focus()\n }\n\n // Always cleanup this state\n hoverOpenFocusedWithTab.current = false\n }\n\n latestOpenChange.current?.(nextState)\n setOpen(nextState)\n\n if (showOnHover) {\n setTemporarilyPreventClickToClose(nextState)\n }\n })\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n handleOpenChangeImpl.current(nextState)\n },\n [handleOpenChangeImpl],\n )\n\n const handleTriggerEnter = useCallback(() => {\n openTimerRef.current = setTimeout(() => handleOpenChange(true), hoverOpenDelay)\n }, [handleOpenChange, hoverOpenDelay])\n\n const handleTriggerLeave = useCallback(() => {\n clearTimeout(openTimerRef.current)\n }, [])\n\n useEffect(() => {\n return () => {\n clearTimeout(openTimerRef.current)\n }\n }, [])\n\n const store = useMemo<PopoverContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n shake,\n setShake,\n showOnHover,\n temporarilyPreventClickToClose,\n onTriggerEnter: handleTriggerEnter,\n onTriggerLeave: handleTriggerLeave,\n isPointerInTransitRef,\n triggerRef,\n contentRef,\n hoverOpenFocusedWithTab,\n }),\n [\n isOpen,\n handleOpenChange,\n shake,\n setShake,\n showOnHover,\n temporarilyPreventClickToClose,\n hoverOpenFocusedWithTab,\n isPointerInTransitRef,\n handleTriggerEnter,\n handleTriggerLeave,\n ],\n )\n\n return (\n <PopoverContext value={store}>\n <RadixPopover.Root open={isOpen} onOpenChange={handleOpenChange} modal={false}>\n {children}\n </RadixPopover.Root>\n </PopoverContext>\n )\n}\n\nconst Trigger = ({\n children,\n onPointerDown,\n onClick,\n}: {\n children: React.ReactNode\n onPointerDown?: PointerEventHandler\n onClick?: MouseEventHandler\n}) => {\n const {\n setOpen,\n showOnHover,\n temporarilyPreventClickToClose,\n onTriggerEnter,\n onTriggerLeave,\n isPointerInTransitRef,\n triggerRef,\n contentRef,\n } = usePopoverContext()\n const hasPointerMoveOpenedRef = useRef<boolean>(false)\n\n const maybePreventClickClose = (evt: React.MouseEvent) => {\n // Don't prevent temporary close if the trigger is an anchor tag itself\n const isLink = evt.currentTarget.nodeName.toLocaleLowerCase() === \"a\"\n\n if (!isLink && temporarilyPreventClickToClose) {\n // Prevents tooltip listeners from closing\n evt.preventDefault()\n evt.stopPropagation()\n }\n }\n\n const handlePointerMove = (evt: React.PointerEvent) => {\n if (evt.pointerType === \"touch\") {\n return\n }\n\n if (!hasPointerMoveOpenedRef.current && !isPointerInTransitRef.current) {\n onTriggerEnter()\n hasPointerMoveOpenedRef.current = true\n }\n }\n\n const handlePointerLeave = () => {\n if (!hasPointerMoveOpenedRef.current) {\n return\n }\n\n onTriggerLeave()\n hasPointerMoveOpenedRef.current = false\n }\n\n return (\n <RadixPopover.Trigger\n asChild\n ref={triggerRef}\n onPointerDown={(evt) => {\n maybePreventClickClose(evt)\n onPointerDown?.(evt)\n }}\n onClick={(evt) => {\n maybePreventClickClose(evt)\n onClick?.(evt)\n }}\n onPointerMove={showOnHover ? handlePointerMove : undefined}\n onPointerLeave={showOnHover ? handlePointerLeave : undefined}\n onFocus={showOnHover ? () => setOpen(true) : undefined}\n onBlur={\n showOnHover\n ? () => {\n setTimeout(() => {\n // Ignore this handler if focus has moved into the popover\n if (contentRef.current?.contains(document.activeElement)) {\n return\n }\n\n setOpen(false)\n }, 50)\n }\n : undefined\n }\n >\n {children}\n </RadixPopover.Trigger>\n )\n}\n\nexport type PopoverContentProps = {\n children: ReactNode\n /**\n * Whether to avoid collisions with vieport/scroll containersw.\n * @default true\n */\n avoidCollisions?: boolean\n /**\n * Set the `width` of the popover, in pixels.\n * @default auto\n */\n width?: number | \"auto\"\n /**\n * Set the `min-width` of the popover, in pixels.\n * @default 300\n */\n minWidth?: number | \"auto\"\n /**\n * Set the `max-width` of the popover, in pixels.\n */\n maxWidth?: number\n /**\n * Background style for the popover\n * @default default\n */\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default bottom\n */\n side?: RadixPopover.PopoverContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 8\n */\n sideOffset?: RadixPopover.PopoverContentProps[\"sideOffset\"]\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: RadixPopover.PopoverContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: RadixPopover.PopoverContentProps[\"alignOffset\"]\n /**\n * Whether the popover surface should be translucent.\n * @default false\n */\n translucent?: boolean\n /** Additional class name to apply to the popover content, you usually don't want to set this, but ag-grid needs it to render a custom editor properly */\n className?: string\n /**\n * Auto focus the popover content when it is opened.\n * @default true\n */\n autoFocus?: boolean\n /** `data-*` attributes land on the popover */\n [dataAttribute: `data-${string}`]: unknown\n}\n\nconst ContentImpl = ({\n children,\n avoidCollisions,\n width,\n minWidth,\n maxWidth,\n side,\n sideOffset = 8,\n align,\n alignOffset,\n translucent,\n className,\n autoFocus = true,\n ...restProps\n}: PopoverContentProps) => {\n const { showOnHover, shake, contentRef } = usePopoverContext()\n\n const handleKeyDown: KeyboardEventHandler<HTMLDivElement> = (evt) => {\n const contentElement = contentRef.current\n\n if (\n // When the current target is our container\n contentElement &&\n evt.target === contentElement &&\n // We know that shift key tabs will lead to closing the popover (because we don't use `modal`)\n evt.key === \"Tab\" &&\n evt.shiftKey\n ) {\n // Prevent that from happening\n evt.preventDefault()\n evt.stopPropagation()\n\n // Move focus to the last focusable element, placing the user in the focus loop\n const focusable = focusableElements(contentElement)\n const lastFocusable = focusable[focusable.length - 1]\n lastFocusable?.focus()\n }\n }\n\n // Important that we send initial focus into the popover, placing it onto the container.\n // This allows focus looping to begin, as well as capturing scoped key presses.\n // We prevent Radix's default behavior of focusing an element, because this can have adverse side-effects.\n useEffect(() => {\n const contentElement = contentRef.current\n\n if (!contentElement || !autoFocus) {\n return\n }\n\n // If we're already focused within the content area, no-op.\n // This would be true if some inner component declares autoFocus\n if (contentElement?.contains(document.activeElement)) {\n return\n }\n\n // Our focus isn't in the content area - move it there.\n // NOTE: Don't automatically shift focus on hover popovers\n if (!showOnHover) {\n // In a microtask: until Radix's focus scope here has registered, a Dialog\n // around this content sends the focus straight back, and the content\n // takes that for focus moving outside and closes.\n queueMicrotask(() => contentElement.focus({ preventScroll: true }))\n }\n }, [contentRef, showOnHover, autoFocus])\n\n return (\n <RadixPopover.Content\n {...dataAttributes(restProps)}\n forceMount\n ref={contentRef}\n className={clsx(s.Popover, className)}\n style={toCssVariables({\n \"popover-width\": width,\n \"popover-min-width\": minWidth,\n \"popover-max-width\": maxWidth,\n })}\n onCloseAutoFocus={showOnHover ? preventDefaultHandler : keepMovedFocus}\n // data-surface={surface}\n data-animate={shake ? \"shake\" : undefined}\n data-translucent={translucent ? \"true\" : undefined}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset ?? (align === \"center\" ? 0 : -5)}\n avoidCollisions={avoidCollisions ?? true}\n hideWhenDetached\n collisionPadding={20}\n onOpenAutoFocus={preventDefaultHandler}\n // Use custom esc listener because default Radix is bound to the document\n // and cannot have propagation stopped.\n onEscapeKeyDown={preventDefaultHandler}\n onKeyDown={handleKeyDown}\n >\n {children}\n </RadixPopover.Content>\n )\n}\n\nconst ContentHoverable = (props: PopoverContentProps) => {\n const { open, setOpen, triggerRef, contentRef, isPointerInTransitRef, hoverOpenFocusedWithTab } =\n usePopoverContext()\n const [pointerGraceArea, setPointerGraceArea] = useState<Polygon | null>(null)\n\n const handleRemoveGraceArea = useCallback(() => {\n setPointerGraceArea(null)\n isPointerInTransitRef.current = false\n }, [isPointerInTransitRef])\n\n const handleCreateGraceArea = useCallback(\n (event: PointerEvent, hoverTarget: HTMLElement) => {\n const graceArea = createPointerIntentArea(event, hoverTarget)\n setPointerGraceArea(graceArea)\n isPointerInTransitRef.current = true\n },\n [isPointerInTransitRef],\n )\n\n useEffect(() => {\n return () => handleRemoveGraceArea()\n }, [handleRemoveGraceArea])\n\n useEffect(() => {\n const trigger = triggerRef.current\n const content = contentRef.current\n\n if (!trigger || !content) {\n return\n }\n\n const handleTriggerLeave = (event: PointerEvent) => handleCreateGraceArea(event, content)\n const handleContentLeave = (event: PointerEvent) => handleCreateGraceArea(event, trigger)\n\n trigger.addEventListener(\"pointerleave\", handleTriggerLeave)\n content.addEventListener(\"pointerleave\", handleContentLeave)\n return () => {\n trigger.removeEventListener(\"pointerleave\", handleTriggerLeave)\n content.removeEventListener(\"pointerleave\", handleContentLeave)\n }\n }, [contentRef, triggerRef, handleCreateGraceArea, handleRemoveGraceArea])\n\n useEffect(() => {\n if (!pointerGraceArea) {\n return\n }\n\n const handleTrackPointerGrace = (event: PointerEvent) => {\n const trigger = triggerRef.current\n const content = contentRef.current\n const target = event.target as HTMLElement\n const pointerPosition = { x: event.clientX, y: event.clientY }\n const hasEnteredTarget = trigger?.contains(target) || content?.contains(target)\n const isPointerOutsideGraceArea = !isPointInPolygon(pointerPosition, pointerGraceArea)\n // Stop considering grace areas when the pointer runs into other control triggers\n const targetHasPopup = target.hasAttribute(\"aria-haspopup\")\n\n if (hasEnteredTarget) {\n handleRemoveGraceArea()\n } else if (isPointerOutsideGraceArea || targetHasPopup) {\n handleRemoveGraceArea()\n setOpen(false)\n }\n }\n document.addEventListener(\"pointermove\", handleTrackPointerGrace)\n return () => document.removeEventListener(\"pointermove\", handleTrackPointerGrace)\n }, [pointerGraceArea, setOpen, handleRemoveGraceArea, triggerRef, contentRef])\n\n // Hoverable doesn't place focus in the popover by default\n // If this is open, and tab is pressed, and focusableElements() has an element, prevent default behavior and focus it\n // Then set a flag (probably in context) that tells us to restore focus to the trigger on close (e.g., not execute the onCloseAutoFocus handler)\n\n useEffect(() => {\n // Closed and still leaving: Tab belongs to the page again\n if (!open) {\n return\n }\n\n const handleKeyDown = (evt: KeyboardEvent) => {\n if (!contentRef.current) {\n return\n }\n\n // Only assume forward tab is attempting to move into the popup\n if (evt.key === \"Tab\" && !evt.shiftKey) {\n const [firstFocusable] = focusableElements(contentRef.current)\n if (firstFocusable) {\n evt.preventDefault()\n firstFocusable.focus()\n hoverOpenFocusedWithTab.current = true\n document.removeEventListener(\"keydown\", handleKeyDown)\n }\n }\n }\n document.addEventListener(\"keydown\", handleKeyDown)\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown)\n }\n }, [open, contentRef, hoverOpenFocusedWithTab])\n\n return <ContentImpl {...props} />\n}\n\nconst Content = (props: PopoverContentProps) => {\n const { open, showOnHover, setOpen } = usePopoverContext()\n\n useEscCloseStack(open, () => {\n setOpen(false)\n })\n\n return (\n <RadixPopover.Portal forceMount>\n <TransitionGroup {...overlayTiming} className={s.Transition} overlay>\n {open &&\n (showOnHover ? (\n <ContentHoverable key=\"popover-hover\" {...props} />\n ) : (\n <ContentImpl key=\"popover\" {...props} />\n ))}\n </TransitionGroup>\n </RadixPopover.Portal>\n )\n}\n\nPopover.Trigger = Trigger\nPopover.Content = Content\n"]}