@mortenbrudvik/waveui 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +157 -13
- package/dist/components/button/Link.cjs +1 -1
- package/dist/components/button/Link.cjs.map +1 -1
- package/dist/components/button/Link.mjs +4 -4
- package/dist/components/data-display/Avatar.cjs +1 -1
- package/dist/components/data-display/Avatar.cjs.map +1 -1
- package/dist/components/data-display/Avatar.colors.cjs +2 -0
- package/dist/components/data-display/Avatar.colors.cjs.map +1 -0
- package/dist/components/data-display/Avatar.colors.mjs +45 -0
- package/dist/components/data-display/Avatar.colors.mjs.map +1 -0
- package/dist/components/data-display/Avatar.context.cjs +1 -1
- package/dist/components/data-display/Avatar.context.cjs.map +1 -1
- package/dist/components/data-display/Avatar.context.mjs +4 -2
- package/dist/components/data-display/Avatar.context.mjs.map +1 -1
- package/dist/components/data-display/Avatar.mjs +103 -96
- package/dist/components/data-display/Avatar.mjs.map +1 -1
- package/dist/components/data-display/Avatar.sizes.cjs +2 -0
- package/dist/components/data-display/Avatar.sizes.cjs.map +1 -0
- package/dist/components/data-display/Avatar.sizes.mjs +41 -0
- package/dist/components/data-display/Avatar.sizes.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.cjs +1 -1
- package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
- package/dist/components/data-display/AvatarGroup.context.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.context.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.context.mjs +9 -0
- package/dist/components/data-display/AvatarGroup.context.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.mjs +65 -122
- package/dist/components/data-display/AvatarGroup.mjs.map +1 -1
- package/dist/components/data-display/AvatarGroup.partition.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.partition.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.partition.mjs +14 -0
- package/dist/components/data-display/AvatarGroup.partition.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.parts.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.parts.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.parts.mjs +178 -0
- package/dist/components/data-display/AvatarGroup.parts.mjs.map +1 -0
- package/dist/components/data-display/InfoButton.cjs +1 -1
- package/dist/components/data-display/InfoButton.cjs.map +1 -1
- package/dist/components/data-display/InfoButton.mjs +12 -12
- package/dist/components/data-display/InteractionTag.cjs +1 -1
- package/dist/components/data-display/InteractionTag.cjs.map +1 -1
- package/dist/components/data-display/InteractionTag.mjs +36 -33
- package/dist/components/data-display/InteractionTag.mjs.map +1 -1
- package/dist/components/data-display/Persona.cjs +1 -1
- package/dist/components/data-display/Persona.cjs.map +1 -1
- package/dist/components/data-display/Persona.mjs +96 -37
- package/dist/components/data-display/Persona.mjs.map +1 -1
- package/dist/components/data-display/PresenceBadge.cjs +1 -1
- package/dist/components/data-display/PresenceBadge.cjs.map +1 -1
- package/dist/components/data-display/PresenceBadge.mjs +42 -28
- package/dist/components/data-display/PresenceBadge.mjs.map +1 -1
- package/dist/components/data-display/Tag.cjs +1 -1
- package/dist/components/data-display/Tag.cjs.map +1 -1
- package/dist/components/data-display/Tag.mjs +111 -108
- package/dist/components/data-display/Tag.mjs.map +1 -1
- package/dist/components/feedback/Toaster.cjs +1 -1
- package/dist/components/feedback/Toaster.cjs.map +1 -1
- package/dist/components/feedback/Toaster.mjs +235 -235
- package/dist/components/feedback/Toaster.mjs.map +1 -1
- package/dist/components/input/Combobox.cjs +1 -1
- package/dist/components/input/Combobox.cjs.map +1 -1
- package/dist/components/input/Combobox.mjs +176 -175
- package/dist/components/input/Combobox.mjs.map +1 -1
- package/dist/components/input/DatePicker.cjs +1 -1
- package/dist/components/input/DatePicker.cjs.map +1 -1
- package/dist/components/input/DatePicker.mjs +188 -187
- package/dist/components/input/DatePicker.mjs.map +1 -1
- package/dist/components/input/Dropdown.cjs +1 -1
- package/dist/components/input/Dropdown.cjs.map +1 -1
- package/dist/components/input/Dropdown.mjs +41 -40
- package/dist/components/input/Dropdown.mjs.map +1 -1
- package/dist/components/input/Option.cjs +1 -1
- package/dist/components/input/Option.cjs.map +1 -1
- package/dist/components/input/Option.mjs +89 -87
- package/dist/components/input/Option.mjs.map +1 -1
- package/dist/components/input/TagPicker.root.cjs +1 -1
- package/dist/components/input/TagPicker.root.cjs.map +1 -1
- package/dist/components/input/TagPicker.root.mjs +136 -135
- package/dist/components/input/TagPicker.root.mjs.map +1 -1
- package/dist/components/input/TimePicker.cjs +1 -1
- package/dist/components/input/TimePicker.cjs.map +1 -1
- package/dist/components/input/TimePicker.mjs +156 -154
- package/dist/components/input/TimePicker.mjs.map +1 -1
- package/dist/components/layout/Card.cjs +1 -1
- package/dist/components/layout/Card.cjs.map +1 -1
- package/dist/components/layout/Card.context.cjs +2 -0
- package/dist/components/layout/Card.context.cjs.map +1 -0
- package/dist/components/layout/Card.context.mjs +14 -0
- package/dist/components/layout/Card.context.mjs.map +1 -0
- package/dist/components/layout/Card.mjs +138 -92
- package/dist/components/layout/Card.mjs.map +1 -1
- package/dist/components/layout/Card.preview.cjs +2 -0
- package/dist/components/layout/Card.preview.cjs.map +1 -0
- package/dist/components/layout/Card.preview.mjs +22 -0
- package/dist/components/layout/Card.preview.mjs.map +1 -0
- package/dist/components/layout/Carousel.button.cjs +2 -0
- package/dist/components/layout/Carousel.button.cjs.map +1 -0
- package/dist/components/layout/Carousel.button.mjs +34 -0
- package/dist/components/layout/Carousel.button.mjs.map +1 -0
- package/dist/components/layout/Carousel.cjs +1 -1
- package/dist/components/layout/Carousel.cjs.map +1 -1
- package/dist/components/layout/Carousel.context.cjs +2 -0
- package/dist/components/layout/Carousel.context.cjs.map +1 -0
- package/dist/components/layout/Carousel.context.mjs +24 -0
- package/dist/components/layout/Carousel.context.mjs.map +1 -0
- package/dist/components/layout/Carousel.drag.cjs +2 -0
- package/dist/components/layout/Carousel.drag.cjs.map +1 -0
- package/dist/components/layout/Carousel.drag.mjs +79 -0
- package/dist/components/layout/Carousel.drag.mjs.map +1 -0
- package/dist/components/layout/Carousel.groups.cjs +2 -0
- package/dist/components/layout/Carousel.groups.cjs.map +1 -0
- package/dist/components/layout/Carousel.groups.mjs +23 -0
- package/dist/components/layout/Carousel.groups.mjs.map +1 -0
- package/dist/components/layout/Carousel.mjs +288 -150
- package/dist/components/layout/Carousel.mjs.map +1 -1
- package/dist/components/layout/Carousel.styles.cjs +2 -0
- package/dist/components/layout/Carousel.styles.cjs.map +1 -0
- package/dist/components/layout/Carousel.styles.mjs +30 -0
- package/dist/components/layout/Carousel.styles.mjs.map +1 -0
- package/dist/components/layout/TabList.cjs +1 -1
- package/dist/components/layout/TabList.cjs.map +1 -1
- package/dist/components/layout/TabList.mjs +163 -124
- package/dist/components/layout/TabList.mjs.map +1 -1
- package/dist/components/navigation/Menu.popover.cjs +1 -1
- package/dist/components/navigation/Menu.popover.cjs.map +1 -1
- package/dist/components/navigation/Menu.popover.mjs +137 -127
- package/dist/components/navigation/Menu.popover.mjs.map +1 -1
- package/dist/components/navigation/Menu.root.cjs +1 -1
- package/dist/components/navigation/Menu.root.cjs.map +1 -1
- package/dist/components/navigation/Menu.root.mjs +4 -4
- package/dist/components/overlays/Dialog.cjs +1 -1
- package/dist/components/overlays/Dialog.cjs.map +1 -1
- package/dist/components/overlays/Dialog.mjs +123 -123
- package/dist/components/overlays/Dialog.mjs.map +1 -1
- package/dist/components/overlays/Drawer.panel.cjs +1 -1
- package/dist/components/overlays/Drawer.panel.cjs.map +1 -1
- package/dist/components/overlays/Drawer.panel.mjs +12 -12
- package/dist/components/overlays/Drawer.panel.mjs.map +1 -1
- package/dist/components/overlays/Popover.cjs +1 -1
- package/dist/components/overlays/Popover.cjs.map +1 -1
- package/dist/components/overlays/Popover.mjs +173 -162
- package/dist/components/overlays/Popover.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.cjs +1 -1
- package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.mjs +96 -91
- package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
- package/dist/components/overlays/Tooltip.cjs +1 -1
- package/dist/components/overlays/Tooltip.cjs.map +1 -1
- package/dist/components/overlays/Tooltip.mjs +47 -47
- package/dist/components/overlays/Tooltip.mjs.map +1 -1
- package/dist/components/portal/Portal.cjs +1 -1
- package/dist/components/portal/Portal.cjs.map +1 -1
- package/dist/components/portal/Portal.mjs +5 -5
- package/dist/components/table/DataGrid.cjs +1 -1
- package/dist/components/table/DataGrid.cjs.map +1 -1
- package/dist/components/table/DataGrid.mjs +1 -1
- package/dist/hooks/useDismiss.cjs.map +1 -1
- package/dist/hooks/useDismiss.mjs.map +1 -1
- package/dist/hooks/useFocusTrap.cjs.map +1 -1
- package/dist/hooks/useFocusTrap.mjs.map +1 -1
- package/dist/hooks/useFocusVisible.cjs +2 -0
- package/dist/hooks/useFocusVisible.cjs.map +1 -0
- package/dist/hooks/useFocusVisible.mjs +49 -0
- package/dist/hooks/useFocusVisible.mjs.map +1 -0
- package/dist/hooks/useFocusableGroup.cjs +2 -0
- package/dist/hooks/useFocusableGroup.cjs.map +1 -0
- package/dist/hooks/useFocusableGroup.mjs +70 -0
- package/dist/hooks/useFocusableGroup.mjs.map +1 -0
- package/dist/hooks/useModalLayer.cjs +1 -1
- package/dist/hooks/useModalLayer.cjs.map +1 -1
- package/dist/hooks/useModalLayer.mjs +4 -4
- package/dist/hooks/useModalOpen.cjs +2 -0
- package/dist/hooks/useModalOpen.cjs.map +1 -0
- package/dist/hooks/useModalOpen.mjs +14 -0
- package/dist/hooks/useModalOpen.mjs.map +1 -0
- package/dist/hooks/usePopupPosition.cjs +1 -1
- package/dist/hooks/usePopupPosition.cjs.map +1 -1
- package/dist/hooks/usePopupPosition.mjs +82 -53
- package/dist/hooks/usePopupPosition.mjs.map +1 -1
- package/dist/hooks/useResolvedTarget.cjs +2 -0
- package/dist/hooks/useResolvedTarget.cjs.map +1 -0
- package/dist/hooks/useResolvedTarget.mjs +37 -0
- package/dist/hooks/useResolvedTarget.mjs.map +1 -0
- package/dist/hooks/useRovingGrid.cjs +1 -1
- package/dist/hooks/useRovingGrid.cjs.map +1 -1
- package/dist/hooks/useRovingGrid.mjs +8 -57
- package/dist/hooks/useRovingGrid.mjs.map +1 -1
- package/dist/hooks/useRovingTabIndex.cjs +1 -1
- package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
- package/dist/hooks/useRovingTabIndex.mjs +142 -107
- package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1364 -66
- package/dist/index.d.ts +1364 -66
- package/dist/index.mjs +132 -115
- package/dist/lib/classNames.cjs +1 -1
- package/dist/lib/classNames.cjs.map +1 -1
- package/dist/lib/classNames.mjs +112 -92
- package/dist/lib/classNames.mjs.map +1 -1
- package/dist/lib/initials.cjs +2 -0
- package/dist/lib/initials.cjs.map +1 -0
- package/dist/lib/initials.mjs +21 -0
- package/dist/lib/initials.mjs.map +1 -0
- package/dist/lib/layers.cjs +1 -1
- package/dist/lib/layers.cjs.map +1 -1
- package/dist/lib/layers.mjs +112 -109
- package/dist/lib/layers.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/styles/tokens.css +102 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.panel.mjs","names":["InlinePanel","React","useDrawerOpen","isClient","useIsClient","type","openState","getDrawerSizeAxis","position","drawerSizeClasses","drawerEdgeClasses","overlayPlacementClasses","getOverlayInsetClasses","size","getOverlayPanelClasses","inlinePanelClasses","forcedColors","getInlinePanelClasses","axis","OVERLAY_PANEL_CLASSES","DrawerPanel","rest","inline","overlay","nonModal","modalType","nonModalOverlay","keptMounted","unmountOnClose","presenceRef","usePresence","open","overlayPanel","setOverlayPanel","inlinePanel","setInlinePanel","panelRef","attachOverlayPanel","node","attachInlinePanel","overlayRef","useMergedRefs","ref","inlineRef","trigger","portalRef","backdropPress","useBackdropPress","onDismiss","useModalDismiss","requestOpen","componentName","layer","useModalLayer","opener","useModalOpener","onTabOrderKeyDown","usePopoverTabOrder","getTabbableThrough","backdropIgnored","backdrop","warnOnce","coversUsablePage","isMounted","inlineAs","separator","presenceProps","cn","rootClassName","className","Portal","ModalBackdrop","backdropClassName","composeEventHandlers","onKeyDown"],"sources":["../../../src/components/overlays/Drawer.panel.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport type { Slot, SlotObject } from '../../lib/slot';\nimport { forcedColors } from '../../lib/styles';\nimport type { BackdropAppearance, ModalType } from '../../lib/types';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useModalLayer } from '../../hooks/useModalLayer';\nimport { usePresence } from '../../hooks/usePresence';\nimport { useRestoreFocus } from '../../hooks/useRestoreFocus';\nimport { Portal } from '../portal/Portal';\nimport {\n useBackdropPress,\n useModalDismiss,\n useModalOpener,\n useOpenInsideWarning,\n useRaiseOnOpen,\n type ModalRequestOpen,\n type ModalTrigger,\n} from './Dialog.shared';\nimport { ModalBackdrop } from './Dialog.slots';\nimport type { DrawerPosition, DrawerSize, DrawerType } from './Drawer.context';\nimport { getTabbableThrough, usePopoverTabOrder } from './Popover.shared';\n\n/*\n * The drawer panel shell (D108): the panel element of both drawer types with its machinery, its\n * open state, and its placement, size and safe-area classes. Drawer's root and NavDrawer render it.\n * Imports the context module only among the Drawer modules (never the root, the parts or\n * `Drawer.tsx`), and no Nav module.\n */\n\n/**\n * The open state a drawer reports (its triggers' `aria-expanded`, its contexts): an inline\n * drawer's state as it is; an overlay's `false` until the page has hydrated (the portal renders\n * only in the browser), so the server HTML never points `aria-controls` at a panel that is not\n * there.\n */\nexport function useDrawerOpen(type: DrawerType, openState: boolean): boolean {\n const isClient = useIsClient();\n return type === 'inline' ? openState : openState && isClient;\n}\n\n/** The axis a drawer's `size` applies to: the width at a side, the height at the bottom. */\ntype DrawerSizeAxis = 'width' | 'height';\n\n/** The axis `size` sets for a drawer at `position`. */\nfunction getDrawerSizeAxis(position: DrawerPosition): DrawerSizeAxis {\n return position === 'bottom' ? 'height' : 'width';\n}\n\n/**\n * The size classes, keyed by axis: 320px, 592px and 940px on the spacing scale (rem, so they\n * follow the user's font size), and `full` the whole axis. A width (height) class in the\n * consumer's `className` replaces the size, as the consumer's class comes last in `cn()`.\n */\nconst drawerSizeClasses: Readonly<Record<DrawerSizeAxis, Readonly<Record<DrawerSize, string>>>> = {\n width: { small: 'w-80', medium: 'w-148', large: 'w-235', full: 'w-full' },\n height: { small: 'h-80', medium: 'h-148', large: 'h-235', full: 'h-full' },\n};\n\n/**\n * A border on the panel's inner edge (the one facing the page): it marks the panel where the\n * shadow cannot, in high contrast (page, backdrop and panel are black) and in forced colors\n * (which drop shadows).\n */\nconst drawerEdgeClasses: Readonly<Record<DrawerPosition, string>> = {\n start: 'border-e',\n end: 'border-s',\n left: 'border-r', // wave-allow-physical: the consumer asked for the physical left edge\n right: 'border-l', // wave-allow-physical: the consumer asked for the physical right edge\n bottom: 'border-t',\n};\n\n/**\n * Where an overlay panel is pinned: a side panel spans the window's height, a bottom one its\n * width; neither grows past the window (a size larger than the screen acts as `full`).\n */\nconst overlayPlacementClasses: Readonly<Record<DrawerPosition, string>> = {\n start: 'start-0 top-0 h-full max-w-full',\n end: 'end-0 top-0 h-full max-w-full',\n left: 'left-0 top-0 h-full max-w-full', // wave-allow-physical: the consumer asked for the physical left edge\n right: 'right-0 top-0 h-full max-w-full', // wave-allow-physical: the consumer asked for the physical right edge\n bottom: 'inset-x-0 bottom-0 w-full max-h-full',\n};\n\n/**\n * The safe-area insets of the screen edges an overlay panel touches (the iOS home indicator, a\n * notch; `0` unless the page sets `viewport-fit=cover`). The panel has no padding of its own, so\n * the inset is the whole padding. A side panel touches the top and bottom edges; a bottom panel\n * the bottom edge, and the top one too at `full`. The side insets (a landscape notch) are not\n * padded.\n */\nfunction getOverlayInsetClasses(position: DrawerPosition, size: DrawerSize): string {\n if (position === 'bottom' && size !== 'full') return 'pb-[env(safe-area-inset-bottom)]';\n return 'pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)]';\n}\n\n/**\n * The classes that place and size an overlay panel at `position`: the placement, the inner-edge\n * border, the size on the position's axis and the safe-area insets. They go after the panel's\n * base classes and before the consumer's `className`.\n */\nfunction getOverlayPanelClasses(position: DrawerPosition, size: DrawerSize): string {\n return [\n overlayPlacementClasses[position],\n drawerEdgeClasses[position],\n drawerSizeClasses[getDrawerSizeAxis(position)][size],\n getOverlayInsetClasses(position, size),\n ].join(' ');\n}\n\n/**\n * The base classes of an inline panel: an element of the page layout that keeps its width in a\n * flex row and lets its body scroll once the layout bounds its height. Its inner edge is\n * transparent unless the Drawer has `separator` (`data-separator`), and always drawn in forced\n * colors.\n */\nconst inlinePanelClasses = [\n 'relative flex min-h-0 shrink-0 flex-col max-w-full bg-background text-foreground',\n 'border-transparent data-[separator]:border-border',\n forcedColors.border,\n].join(' ');\n\n/**\n * The classes that place and size an inline panel at `position`: the inner-edge border and the\n * size on the position's axis (a bottom panel is as wide as its container and never taller than\n * it). `full` is the container's width (height). No placement, insets or shadow: where the panel\n * sits is up to the page layout. They go after {@link inlinePanelClasses} and before the\n * consumer's `className`.\n */\nfunction getInlinePanelClasses(position: DrawerPosition, size: DrawerSize): string {\n const axis = getDrawerSizeAxis(position);\n return [\n drawerEdgeClasses[position],\n axis === 'height' ? 'w-full max-h-full' : '',\n drawerSizeClasses[axis][size],\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/** What the drawer panel shell renders and wires (the frozen contract of D108). */\nexport interface DrawerPanelProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The public component, for the warning keys and texts: `'Drawer'`, `'NavDrawer'`\n * (`<componentName>:open-inside`, `:backdrop-ignored`, `:focus-outside`, `:non-modal-full`).\n */\n componentName: string;\n /**\n * `'overlay'`: a portal, the backdrop, `role=\"dialog\"` and the modal or non-modal machinery;\n * `'inline'`: the panel in place, with the inline focus restore only.\n */\n type: DrawerType;\n /** The reported open state, from {@link useDrawerOpen}. */\n open: boolean;\n /** The root's request function (`useModalOpenState`): Escape and the backdrop ask through it. */\n requestOpen: ModalRequestOpen;\n /** Rendered as `data-position`; picks the overlay's edge or the inline panel's inner edge. */\n position: DrawerPosition;\n /** Rendered as `data-size` (always: the component resolves its own default). */\n size: DrawerSize;\n /** Inline only: draws the inner edge (`data-separator`). Ignored by an overlay. */\n separator: boolean;\n /**\n * Overlay only: `modal`, `alert` or `non-modal` (`data-modal-type`, the role and the layer kind).\n * Ignored inline.\n */\n modalType: ModalType;\n /** `false` keeps the panel mounted while closed, `hidden` and `inert`. */\n unmountOnClose: boolean;\n /**\n * The element of an inline panel: `'aside'` (Drawer, a complementary landmark) or `'div'`\n * (NavDrawer, whose `<nav>` is the landmark).\n */\n inlineAs: 'aside' | 'div';\n /**\n * The root's triggers (`useModalTrigger()`), or `inertModalTrigger` for a component without\n * trigger parts (the layer and the inline restore then capture the element that had focus).\n */\n trigger: ModalTrigger;\n /** Where focus goes when the panel closes, if it can take focus (the root's `finalFocusRef`). */\n finalFocusRef?: React.RefObject<HTMLElement | null>;\n /**\n * The panel's stable class(es), first in its `cn()`: `drawerClassNames.root`, followed by a\n * variant's root (`cn(drawerClassNames.root, navDrawerClassNames.root)`).\n */\n rootClassName: string;\n /**\n * The backdrop's stable class(es), first in its `cn()`: `drawerClassNames.backdrop`, followed by\n * a variant's (`cn(drawerClassNames.backdrop, navDrawerClassNames.backdrop)`).\n */\n backdropClassName: string;\n /**\n * The `backdrop` slot (overlay `modal` and `alert` only; a slot on a non-modal or inline panel\n * renders nothing and warns). `null` renders no backdrop.\n */\n backdrop?: Slot<'div'> | (SlotObject<'div'> & { appearance?: BackdropAppearance });\n /** The panel's id (always set: triggers point `aria-controls` at it). */\n id: string;\n /** Merged with the shell's own ref and the presence ref. */\n ref?: React.Ref<HTMLElement>;\n /** The panel's content, rendered as is: the shell adds no header, Close button or padding. */\n children?: React.ReactNode;\n}\n\n/**\n * The classes every overlay panel carries after its stable class: a fixed flex column on the\n * page's background with the overlay shadow, its inner edge in the border colour.\n */\nconst OVERLAY_PANEL_CLASSES =\n 'fixed flex flex-col border-border bg-background text-foreground shadow-64';\n\n/**\n * The drawer panel shell: the panel element of an overlay (in a portal, with its backdrop and the\n * modal or non-modal machinery) or of an inline drawer (in place, with the inline focus restore),\n * on the presence core, with the placement, size, separator and safe-area classes and the\n * `data-type`, `data-position`, `data-size`, `data-modal-type`, `data-separator` and\n * `data-presence` attributes. Returns `null` while unmounted. Its hooks key on `open`.\n *\n * It renders its `children` raw and provides no context: no header, title registry, Close button\n * or padding. The component that renders it holds the open state (`useModalOpenState`, then\n * {@link useDrawerOpen}), renders its triggers itself, names the panel, and calls\n * `useModalTriggerSession(trigger, open)` after rendering it (the shell's effects run first). A\n * change of `type` remounts the panel and its content.\n */\nexport const DrawerPanel = ({\n componentName,\n type,\n open,\n requestOpen,\n position,\n size,\n separator,\n modalType,\n unmountOnClose,\n inlineAs,\n trigger,\n finalFocusRef,\n rootClassName,\n backdropClassName,\n backdrop,\n id,\n className,\n onKeyDown,\n ref,\n children,\n ...rest\n}: DrawerPanelProps): React.ReactNode => {\n const inline = type === 'inline';\n const overlay = !inline;\n const nonModal = modalType === 'non-modal';\n const nonModalOverlay = overlay && nonModal;\n const keptMounted = !unmountOnClose;\n // The panel mounts through the presence core (D5, D103), with no motion of its own: kept mounted\n // while closed with `unmountOnClose={false}`, else removed once it has exited.\n const {\n isMounted,\n ref: presenceRef,\n presenceProps,\n } = usePresence(open, { unmountOnExit: unmountOnClose });\n\n // The panel element of each type, held in state through its own callback ref. A change of `type`\n // remounts the panel (D105): the overlay's hooks see only the portaled element and the inline\n // restore only the inline one, also in the commit that swaps them (the inline restore then still\n // knows the panel that focus was lost from).\n const [overlayPanel, setOverlayPanel] = React.useState<HTMLElement | null>(null);\n const [inlinePanel, setInlinePanel] = React.useState<HTMLElement | null>(null);\n // The mounted panel of either type; each element clears it only while it is still the one held.\n const panelRef = React.useRef<HTMLElement | null>(null);\n const attachOverlayPanel = React.useCallback((node: HTMLElement | null) => {\n if (!node) return undefined;\n panelRef.current = node;\n setOverlayPanel(node);\n return () => {\n if (panelRef.current === node) panelRef.current = null;\n setOverlayPanel(null);\n };\n }, []);\n const attachInlinePanel = React.useCallback((node: HTMLElement | null) => {\n if (!node) return undefined;\n panelRef.current = node;\n setInlinePanel(node);\n return () => {\n if (panelRef.current === node) panelRef.current = null;\n setInlinePanel(null);\n };\n }, []);\n const overlayRef = useMergedRefs<HTMLElement>(ref, attachOverlayPanel, presenceRef);\n const inlineRef = useMergedRefs<HTMLElement>(ref, attachInlinePanel, presenceRef);\n\n // An inline panel takes no focus on open and returns it on close only from inside (D101). Called\n // before useModalLayer: on a switch from inline to overlay it restores before the overlay's trap\n // moves focus in.\n useRestoreFocus({\n enabled: open && inline,\n container: inlinePanel,\n triggerRef: trigger.focusRef,\n finalFocusRef,\n requireFocusInside: true,\n });\n // The portal wrapper: a kept-mounted overlay moves to the top of its stack when it opens (D104),\n // before the layer registers and the trap moves focus in.\n const portalRef = React.useRef<HTMLDivElement | null>(null);\n useRaiseOnOpen(open && overlay, keptMounted, portalRef);\n\n // A backdrop press asks to close, except an alert's (Escape still does; useModalLayer registers\n // its layer without outside presses).\n const backdropPress = useBackdropPress(panelRef, modalType !== 'alert');\n const onDismiss = useModalDismiss(requestOpen, componentName, backdropPress.afterOutsidePress);\n // Only an overlay is a layer: an inline panel is page content (no trap, isolation, scroll lock,\n // Escape or outside press; toasts keep their corner). The overlay's layer is the one the Toaster\n // measures (`modal`, or `dialog` for a non-modal one).\n const layer = useModalLayer({\n open: open && overlay,\n modalType,\n onDismiss,\n refs: [panelRef],\n container: overlayPanel,\n triggerRef: trigger.focusRef,\n finalFocusRef,\n });\n // A non-modal overlay keeps its place in the page's keyboard order right after its opener\n // (D87.5). Both hooks are always called (C-HOOKS, D91). The opener is captured whenever the\n // overlay opens, so a modal panel that turns non-modal while open (focus inside it by then)\n // still knows it.\n const opener = useModalOpener(open && overlay, trigger, overlayPanel);\n const onTabOrderKeyDown = usePopoverTabOrder({\n enabled: open && nonModalOverlay,\n surface: overlayPanel,\n anchorRef: opener,\n getPreviousStop: getTabbableThrough,\n });\n // A popup opened inside a kept-mounted panel that is still open when the panel closes (D106).\n useOpenInsideWarning(open, keptMounted, layer.layerId, componentName, panelRef);\n // A non-modal or inline panel has no backdrop: a given slot (not undefined, null or a boolean)\n // is ignored.\n const backdropIgnored =\n (nonModal || inline) &&\n backdrop !== undefined &&\n backdrop !== null &&\n typeof backdrop !== 'boolean';\n React.useEffect(() => {\n if (!backdropIgnored) return;\n warnOnce(\n `${componentName}:backdrop-ignored`,\n `${componentName}: \\`backdrop\\` is ignored: a non-modal or inline drawer has no backdrop, so the page around it stays usable.`,\n );\n }, [backdropIgnored, componentName]);\n // A full non-modal overlay covers the page it leaves usable (D87.8).\n const coversUsablePage = open && nonModalOverlay && size === 'full';\n React.useEffect(() => {\n if (!coversUsablePage) return;\n warnOnce(\n `${componentName}:non-modal-full`,\n `${componentName}: \\`size=\"full\"\\` with \\`modalType=\"non-modal\"\\` covers the whole page while leaving it usable, so Tab reaches controls hidden behind the drawer. Use \\`modalType=\"modal\"\\`, \\`type=\"inline\"\\`, or a smaller size with its room reserved in the page layout.`,\n );\n }, [coversUsablePage, componentName]);\n\n if (!isMounted) return null;\n\n if (inline) {\n const InlinePanel = inlineAs;\n // In place: no role, tabIndex or modal attributes (D100). The presence attributes come after\n // the consumer's props: hidden and inert while kept closed.\n return (\n <InlinePanel\n ref={inlineRef}\n id={id}\n data-type=\"inline\"\n data-position={position}\n data-size={size}\n data-separator={separator ? '' : undefined}\n {...rest}\n {...presenceProps}\n onKeyDown={onKeyDown}\n className={cn(\n rootClassName,\n inlinePanelClasses,\n getInlinePanelClasses(position, size),\n className,\n )}\n >\n {children}\n </InlinePanel>\n );\n }\n\n return (\n <Portal ref={portalRef} layerId={layer.layerId}>\n {/* The backdrop of a modal or alert panel, the panel's sibling; a non-modal one has none.\n Both carry the presence attributes (D7, D103): hidden and inert while kept closed, so a\n closed panel leaves no backdrop over the page. */}\n {!nonModal && (\n <ModalBackdrop\n backdrop={backdrop}\n className={backdropClassName}\n layerId={layer.layerId}\n open={open}\n onMouseDown={backdropPress.onMouseDown}\n presenceProps={presenceProps}\n />\n )}\n <div\n ref={overlayRef}\n role={modalType === 'alert' ? 'alertdialog' : 'dialog'}\n id={id}\n tabIndex={-1}\n data-type=\"overlay\"\n data-position={position}\n data-size={size}\n data-modal-type={modalType}\n {...rest}\n {...presenceProps}\n onKeyDown={composeEventHandlers(onKeyDown, onTabOrderKeyDown)}\n className={cn(\n rootClassName,\n OVERLAY_PANEL_CLASSES,\n getOverlayPanelClasses(position, size),\n className,\n )}\n >\n {children}\n </div>\n </Portal>\n );\n};\nDrawerPanel.displayName = 'DrawerPanel';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Drawer.panel.mjs","names":["InlinePanel","React","useDrawerOpen","isClient","useIsClient","type","openState","getDrawerSizeAxis","position","drawerSizeClasses","drawerEdgeClasses","overlayPlacementClasses","getOverlayInsetClasses","size","getOverlayPanelClasses","inlinePanelClasses","forcedColors","getInlinePanelClasses","axis","OVERLAY_PANEL_CLASSES","DrawerPanel","rest","inline","overlay","nonModal","modalType","nonModalOverlay","keptMounted","unmountOnClose","presenceRef","usePresence","open","overlayPanel","setOverlayPanel","inlinePanel","setInlinePanel","panelRef","attachOverlayPanel","node","attachInlinePanel","overlayRef","useMergedRefs","ref","inlineRef","trigger","portalRef","backdropPress","useBackdropPress","onDismiss","useModalDismiss","requestOpen","componentName","layer","useModalLayer","opener","useModalOpener","onTabOrderKeyDown","usePopoverTabOrder","getTabbableThrough","backdropIgnored","backdrop","warnOnce","coversUsablePage","isMounted","inlineAs","separator","presenceProps","cn","rootClassName","className","Portal","ModalBackdrop","backdropClassName","composeEventHandlers","onKeyDown"],"sources":["../../../src/components/overlays/Drawer.panel.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport type { Slot, SlotObject } from '../../lib/slot';\nimport { forcedColors } from '../../lib/styles';\nimport type { BackdropAppearance, ModalType } from '../../lib/types';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useModalLayer } from '../../hooks/useModalLayer';\nimport { usePresence } from '../../hooks/usePresence';\nimport { useRestoreFocus } from '../../hooks/useRestoreFocus';\nimport { Portal } from '../portal/Portal';\nimport {\n useBackdropPress,\n useModalDismiss,\n useModalOpener,\n useOpenInsideWarning,\n useRaiseOnOpen,\n type ModalRequestOpen,\n type ModalTrigger,\n} from './Dialog.shared';\nimport { ModalBackdrop } from './Dialog.slots';\nimport type { DrawerPosition, DrawerSize, DrawerType } from './Drawer.context';\nimport { getTabbableThrough, usePopoverTabOrder } from './Popover.shared';\n\n/*\n * The drawer panel shell (D108): the panel element of both drawer types with its machinery, its\n * open state, and its placement, size and safe-area classes. Drawer's root and NavDrawer render it.\n * Imports the context module only among the Drawer modules (never the root, the parts or\n * `Drawer.tsx`), and no Nav module.\n */\n\n/**\n * The open state a drawer reports (its triggers' `aria-expanded`, its contexts): an inline\n * drawer's state as it is; an overlay's `false` until the page has hydrated (the portal renders\n * only in the browser), so the server HTML never points `aria-controls` at a panel that is not\n * there.\n */\nexport function useDrawerOpen(type: DrawerType, openState: boolean): boolean {\n const isClient = useIsClient();\n return type === 'inline' ? openState : openState && isClient;\n}\n\n/** The axis a drawer's `size` applies to: the width at a side, the height at the bottom. */\ntype DrawerSizeAxis = 'width' | 'height';\n\n/** The axis `size` sets for a drawer at `position`. */\nfunction getDrawerSizeAxis(position: DrawerPosition): DrawerSizeAxis {\n return position === 'bottom' ? 'height' : 'width';\n}\n\n/**\n * The size classes, keyed by axis: 320px, 592px and 940px on the spacing scale (rem, so they\n * follow the user's font size), and `full` the whole axis. A width (height) class in the\n * consumer's `className` replaces the size, as the consumer's class comes last in `cn()`.\n */\nconst drawerSizeClasses: Readonly<Record<DrawerSizeAxis, Readonly<Record<DrawerSize, string>>>> = {\n width: { small: 'w-80', medium: 'w-148', large: 'w-235', full: 'w-full' },\n height: { small: 'h-80', medium: 'h-148', large: 'h-235', full: 'h-full' },\n};\n\n/**\n * A border on the panel's inner edge (the one facing the page): it marks the panel where the\n * shadow cannot, in high contrast (page, backdrop and panel are black) and in forced colors\n * (which drop shadows).\n */\nconst drawerEdgeClasses: Readonly<Record<DrawerPosition, string>> = {\n start: 'border-e',\n end: 'border-s',\n left: 'border-r', // wave-allow-physical: the consumer asked for the physical left edge\n right: 'border-l', // wave-allow-physical: the consumer asked for the physical right edge\n bottom: 'border-t',\n};\n\n/**\n * Where an overlay panel is pinned: a side panel spans the window's height, a bottom one its\n * width; neither grows past the window (a size larger than the screen acts as `full`).\n */\nconst overlayPlacementClasses: Readonly<Record<DrawerPosition, string>> = {\n start: 'start-0 top-0 h-full max-w-full',\n end: 'end-0 top-0 h-full max-w-full',\n left: 'left-0 top-0 h-full max-w-full', // wave-allow-physical: the consumer asked for the physical left edge\n right: 'right-0 top-0 h-full max-w-full', // wave-allow-physical: the consumer asked for the physical right edge\n bottom: 'inset-x-0 bottom-0 w-full max-h-full',\n};\n\n/**\n * The safe-area insets of the screen edges an overlay panel touches (the iOS home indicator, a\n * notch; `0` unless the page sets `viewport-fit=cover`). The panel has no padding of its own, so\n * the inset is the whole padding. A side panel touches the top and bottom edges; a bottom panel\n * the bottom edge, and the top one too at `full`. The side insets (a landscape notch) are not\n * padded.\n */\nfunction getOverlayInsetClasses(position: DrawerPosition, size: DrawerSize): string {\n if (position === 'bottom' && size !== 'full') return 'pb-[env(safe-area-inset-bottom)]';\n return 'pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)]';\n}\n\n/**\n * The classes that place and size an overlay panel at `position`: the placement, the inner-edge\n * border, the size on the position's axis and the safe-area insets. They go after the panel's\n * base classes and before the consumer's `className`.\n */\nfunction getOverlayPanelClasses(position: DrawerPosition, size: DrawerSize): string {\n return [\n overlayPlacementClasses[position],\n drawerEdgeClasses[position],\n drawerSizeClasses[getDrawerSizeAxis(position)][size],\n getOverlayInsetClasses(position, size),\n ].join(' ');\n}\n\n/**\n * The base classes of an inline panel: an element of the page layout that keeps its width in a\n * flex row and lets its body scroll once the layout bounds its height. Its inner edge is\n * transparent unless the Drawer has `separator` (`data-separator`), and always drawn in forced\n * colors.\n */\nconst inlinePanelClasses = [\n 'relative flex min-h-0 shrink-0 flex-col max-w-full bg-background text-foreground',\n 'border-transparent data-[separator]:border-border',\n forcedColors.border,\n].join(' ');\n\n/**\n * The classes that place and size an inline panel at `position`: the inner-edge border and the\n * size on the position's axis (a bottom panel is as wide as its container and never taller than\n * it). `full` is the container's width (height). No placement, insets or shadow: where the panel\n * sits is up to the page layout. They go after {@link inlinePanelClasses} and before the\n * consumer's `className`.\n */\nfunction getInlinePanelClasses(position: DrawerPosition, size: DrawerSize): string {\n const axis = getDrawerSizeAxis(position);\n return [\n drawerEdgeClasses[position],\n axis === 'height' ? 'w-full max-h-full' : '',\n drawerSizeClasses[axis][size],\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/** What the drawer panel shell renders and wires (the frozen contract of D108). */\nexport interface DrawerPanelProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The public component, for the warning keys and texts: `'Drawer'`, `'NavDrawer'`\n * (`<componentName>:open-inside`, `:backdrop-ignored`, `:focus-outside`, `:non-modal-full`).\n */\n componentName: string;\n /**\n * `'overlay'`: a portal, the backdrop, `role=\"dialog\"` and the modal or non-modal machinery;\n * `'inline'`: the panel in place, with the inline focus restore only.\n */\n type: DrawerType;\n /** The reported open state, from {@link useDrawerOpen}. */\n open: boolean;\n /** The root's request function (`useModalOpenState`): Escape and the backdrop ask through it. */\n requestOpen: ModalRequestOpen;\n /** Rendered as `data-position`; picks the overlay's edge or the inline panel's inner edge. */\n position: DrawerPosition;\n /** Rendered as `data-size` (always: the component resolves its own default). */\n size: DrawerSize;\n /** Inline only: draws the inner edge (`data-separator`). Ignored by an overlay. */\n separator: boolean;\n /**\n * Overlay only: `modal`, `alert` or `non-modal` (`data-modal-type`, the role and the layer kind).\n * Ignored inline.\n */\n modalType: ModalType;\n /** `false` keeps the panel mounted while closed, `hidden` and `inert`. */\n unmountOnClose: boolean;\n /**\n * The element of an inline panel: `'aside'` (Drawer, a complementary landmark) or `'div'`\n * (NavDrawer, whose `<nav>` is the landmark).\n */\n inlineAs: 'aside' | 'div';\n /**\n * The root's triggers (`useModalTrigger()`), or `inertModalTrigger` for a component without\n * trigger parts (the layer and the inline restore then capture the element that had focus).\n */\n trigger: ModalTrigger;\n /** Where focus goes when the panel closes, if it can take focus (the root's `finalFocusRef`). */\n finalFocusRef?: React.RefObject<HTMLElement | null>;\n /**\n * The panel's stable class(es), first in its `cn()`: `drawerClassNames.root`, followed by a\n * variant's root (`cn(drawerClassNames.root, navDrawerClassNames.root)`).\n */\n rootClassName: string;\n /**\n * The backdrop's stable class(es), first in its `cn()`: `drawerClassNames.backdrop`, followed by\n * a variant's (`cn(drawerClassNames.backdrop, navDrawerClassNames.backdrop)`).\n */\n backdropClassName: string;\n /**\n * The `backdrop` slot (overlay `modal` and `alert` only; a slot on a non-modal or inline panel\n * renders nothing and warns). `null` renders no backdrop.\n */\n backdrop?: Slot<'div'> | (SlotObject<'div'> & { appearance?: BackdropAppearance });\n /** The panel's id (always set: triggers point `aria-controls` at it). */\n id: string;\n /** Merged with the shell's own ref and the presence ref. */\n ref?: React.Ref<HTMLElement>;\n /** The panel's content, rendered as is: the shell adds no header, Close button or padding. */\n children?: React.ReactNode;\n}\n\n/**\n * The classes every overlay panel carries after its stable class: a fixed flex column on the\n * page's background with the overlay shadow, its inner edge in the border colour.\n */\nconst OVERLAY_PANEL_CLASSES =\n 'fixed flex flex-col border-border bg-background text-foreground shadow-64';\n\n/**\n * The drawer panel shell: the panel element of an overlay (in a portal, with its backdrop and the\n * modal or non-modal machinery) or of an inline drawer (in place, with the inline focus restore),\n * on the presence core, with the placement, size, separator and safe-area classes and the\n * `data-type`, `data-position`, `data-size`, `data-modal-type`, `data-separator` and\n * `data-presence` attributes. Returns `null` while unmounted. Its hooks key on `open`.\n *\n * It renders its `children` raw and provides no context: no header, title registry, Close button\n * or padding. The component that renders it holds the open state (`useModalOpenState`, then\n * {@link useDrawerOpen}), renders its triggers itself, names the panel, and calls\n * `useModalTriggerSession(trigger, open)` after rendering it (the shell's effects run first). A\n * change of `type` remounts the panel and its content.\n */\nexport const DrawerPanel = ({\n componentName,\n type,\n open,\n requestOpen,\n position,\n size,\n separator,\n modalType,\n unmountOnClose,\n inlineAs,\n trigger,\n finalFocusRef,\n rootClassName,\n backdropClassName,\n backdrop,\n id,\n className,\n onKeyDown,\n ref,\n children,\n ...rest\n}: DrawerPanelProps): React.ReactNode => {\n const inline = type === 'inline';\n const overlay = !inline;\n const nonModal = modalType === 'non-modal';\n const nonModalOverlay = overlay && nonModal;\n const keptMounted = !unmountOnClose;\n // The panel mounts through the presence core (D5, D103), with no motion of its own: kept mounted\n // while closed with `unmountOnClose={false}`, else removed once it has exited.\n const {\n isMounted,\n ref: presenceRef,\n presenceProps,\n } = usePresence(open, { unmountOnExit: unmountOnClose });\n\n // The panel element of each type, held in state through its own callback ref. A change of `type`\n // remounts the panel (D105): the overlay's hooks see only the portaled element and the inline\n // restore only the inline one, also in the commit that swaps them (the inline restore then still\n // knows the panel that focus was lost from).\n const [overlayPanel, setOverlayPanel] = React.useState<HTMLElement | null>(null);\n const [inlinePanel, setInlinePanel] = React.useState<HTMLElement | null>(null);\n // The mounted panel of either type; each element clears it only while it is still the one held.\n const panelRef = React.useRef<HTMLElement | null>(null);\n const attachOverlayPanel = React.useCallback((node: HTMLElement | null) => {\n if (!node) return undefined;\n panelRef.current = node;\n setOverlayPanel(node);\n return () => {\n if (panelRef.current === node) panelRef.current = null;\n setOverlayPanel(null);\n };\n }, []);\n const attachInlinePanel = React.useCallback((node: HTMLElement | null) => {\n if (!node) return undefined;\n panelRef.current = node;\n setInlinePanel(node);\n return () => {\n if (panelRef.current === node) panelRef.current = null;\n setInlinePanel(null);\n };\n }, []);\n const overlayRef = useMergedRefs<HTMLElement>(ref, attachOverlayPanel, presenceRef);\n const inlineRef = useMergedRefs<HTMLElement>(ref, attachInlinePanel, presenceRef);\n\n // An inline panel takes no focus on open and returns it on close only from inside (D101). Called\n // before useModalLayer: on a switch from inline to overlay it restores before the overlay's trap\n // moves focus in.\n useRestoreFocus({\n enabled: open && inline,\n container: inlinePanel,\n triggerRef: trigger.focusRef,\n finalFocusRef,\n requireFocusInside: true,\n });\n // The portal wrapper: a kept-mounted overlay moves to the top of its stack when it opens (D104),\n // before the layer registers and the trap moves focus in.\n const portalRef = React.useRef<HTMLDivElement | null>(null);\n useRaiseOnOpen(open && overlay, keptMounted, portalRef);\n\n // A backdrop press asks to close, except an alert's (Escape still does; useModalLayer registers\n // its layer without outside presses).\n const backdropPress = useBackdropPress(panelRef, modalType !== 'alert');\n const onDismiss = useModalDismiss(requestOpen, componentName, backdropPress.afterOutsidePress);\n // Only an overlay is a layer: an inline panel is page content (no trap, isolation, scroll lock,\n // Escape or outside press; toasts keep their corner). The overlay's layer is the one the Toaster\n // measures (`modal`, or `dialog` for a non-modal one).\n const layer = useModalLayer({\n open: open && overlay,\n modalType,\n onDismiss,\n refs: [panelRef],\n container: overlayPanel,\n triggerRef: trigger.focusRef,\n finalFocusRef,\n });\n // A non-modal overlay keeps its place in the page's keyboard order right after its opener\n // (D87.5). Both hooks are always called (C-HOOKS, D91). The opener is captured whenever the\n // overlay opens, so a modal panel that turns non-modal while open (focus inside it by then)\n // still knows it.\n const opener = useModalOpener(open && overlay, trigger, overlayPanel);\n const onTabOrderKeyDown = usePopoverTabOrder({\n enabled: open && nonModalOverlay,\n surface: overlayPanel,\n anchorRef: opener,\n getPreviousStop: getTabbableThrough,\n });\n // A popup opened inside a kept-mounted panel that is still open when the panel closes (D106).\n useOpenInsideWarning(open, keptMounted, layer.layerId, componentName, panelRef);\n // A non-modal or inline panel has no backdrop: a given slot (not undefined, null or a boolean)\n // is ignored.\n const backdropIgnored =\n (nonModal || inline) &&\n backdrop !== undefined &&\n backdrop !== null &&\n typeof backdrop !== 'boolean';\n React.useEffect(() => {\n if (!backdropIgnored) return;\n warnOnce(\n `${componentName}:backdrop-ignored`,\n `${componentName}: \\`backdrop\\` is ignored: a non-modal or inline drawer has no backdrop, so the page around it stays usable.`,\n );\n }, [backdropIgnored, componentName]);\n // A full non-modal overlay covers the page it leaves usable (D87.8).\n const coversUsablePage = open && nonModalOverlay && size === 'full';\n React.useEffect(() => {\n if (!coversUsablePage) return;\n warnOnce(\n `${componentName}:non-modal-full`,\n `${componentName}: \\`size=\"full\"\\` with \\`modalType=\"non-modal\"\\` covers the whole page while leaving it usable, so Tab reaches controls hidden behind the drawer. Use \\`modalType=\"modal\"\\`, \\`type=\"inline\"\\`, or a smaller size with its room reserved in the page layout.`,\n );\n }, [coversUsablePage, componentName]);\n\n if (!isMounted) return null;\n\n if (inline) {\n const InlinePanel = inlineAs;\n // In place: no role, tabIndex or modal attributes (D100). The presence attributes come after\n // the consumer's props: hidden and inert while kept closed.\n return (\n <InlinePanel\n ref={inlineRef}\n id={id}\n data-type=\"inline\"\n data-position={position}\n data-size={size}\n data-separator={separator ? '' : undefined}\n {...rest}\n {...presenceProps}\n onKeyDown={onKeyDown}\n className={cn(\n rootClassName,\n inlinePanelClasses,\n getInlinePanelClasses(position, size),\n className,\n )}\n >\n {children}\n </InlinePanel>\n );\n }\n\n return (\n <Portal ref={portalRef} layerId={layer.layerId}>\n {/* The backdrop of a modal or alert panel, the panel's sibling; a non-modal one has none.\n Both carry the presence attributes (D7, D103): hidden and inert while kept closed, so a\n closed panel leaves no backdrop over the page. */}\n {!nonModal && (\n <ModalBackdrop\n backdrop={backdrop}\n className={backdropClassName}\n layerId={layer.layerId}\n open={open}\n onMouseDown={backdropPress.onMouseDown}\n presenceProps={presenceProps}\n />\n )}\n <div\n ref={overlayRef}\n role={modalType === 'alert' ? 'alertdialog' : 'dialog'}\n id={id}\n tabIndex={-1}\n data-type=\"overlay\"\n data-position={position}\n data-size={size}\n data-modal-type={modalType}\n {...rest}\n {...presenceProps}\n onKeyDown={composeEventHandlers(onKeyDown, onTabOrderKeyDown)}\n className={cn(\n rootClassName,\n OVERLAY_PANEL_CLASSES,\n getOverlayPanelClasses(position, size),\n className,\n )}\n >\n {children}\n </div>\n </Portal>\n );\n};\nDrawerPanel.displayName = 'DrawerPanel';\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/slot.cjs"),i=require("../../lib/composeEventHandlers.cjs"),a=require("../../lib/classNames.cjs"),o=require("../../hooks/useEventCallback.cjs"),s=require("../../hooks/useControllable.cjs"),c=require("../../hooks/useId.cjs"),l=require("../../lib/focus.cjs"),u=require("../../hooks/useMergedRefs.cjs"),d=require("../../hooks/useIsClient.cjs"),f=require("../../hooks/useDismiss.cjs"),p=require("../portal/Portal.cjs"),m=require("../../hooks/usePopupPosition.cjs"),ee=require("../../hooks/useRestoreFocus.cjs"),te=require("../../hooks/useHoverIntent.cjs"),h=require("./Popover.shared.cjs"),g=require("../../hooks/useTriggerElement.cjs"),_=require("../../hooks/useContextMenuAnchor.cjs");let v=require("react");v=e.__toESM(v,1);let y=require("react/jsx-runtime");var b=v.createContext(null);b.displayName=`PopoverContext`;var x=null;function S(){return x??={open:!1,setOpen:()=>{},contentId:`wave-popover-inert-content`,setCustomContentId:()=>{},triggerId:`wave-popover-inert-trigger`,resolvedTriggerId:void 0,setResolvedTriggerId:()=>{},triggerRef:{current:null},triggerElement:null,triggerElementRef:()=>{},surfaceElementRef:()=>{},arrowRef:{current:null},onTriggerClick:()=>{},onTriggerKeyDown:()=>{},hoverTriggerHandlers:null,hoverSurfaceHandlers:null,contextMode:!1,contextTriggerHandlers:null,onContentContextMenu:()=>{},keyboardContext:!1,onContentKeyDown:()=>{},layerId:`wave-popover-inert-layer`,floatingProps:{"data-side":`bottom`,"data-align":`start`,style:{}},arrowStyles:{},placedSide:`bottom`},x}function C(e){return v.useContext(b)||(n.reportMissingContext(e,`Popover`),S())}function w(e,t){let n=(t??``).split(/\s+/).filter(t=>t&&e.getElementById(t));return n.length>0?n.join(` `):void 0}function T(e,t){if(!e)return t;let n=e.ownerDocument,r=(t?n.getElementById(t):null)??g.getTriggerFocusTarget(e)??e;return w(n,r.getAttribute(`aria-labelledby`))??(r.id||e.id||void 0)}function ne(e,t){return t.split(/\s+/).some(t=>{let n=t?e.getElementById(t):null;return n?n.getAttribute(`aria-label`)?.trim()||n.textContent?.trim()?!0:!!n.querySelector(`[aria-label]:not([aria-label=""]), [alt]:not([alt=""]), [title]:not([title=""])`):!1})}var re=()=>()=>{};function E(e){return!!e&&typeof e.nodeType==`number`}function D(e){return{get current(){return e()}}}function O(e,t,n){return g.getTriggerFocusTarget(e)??h.getTabbableThrough(e,t,n)}var k=({open:e,defaultOpen:t,onOpenChange:r,side:i=`bottom`,align:a=`start`,ignoreOutsideRefs:p,openOnHover:x=!1,openDelay:S=250,closeDelay:C=500,openOnContext:w=!1,target:T,children:ne})=>{let[re,k]=s.useControllable(e,t??!1,r),A=v.useRef(!1),j=o.useEventCallback(e=>{A.current=!1,k(e)}),M=v.useCallback(()=>A.current,[]),N=d.useIsClient(),P=re&&N,[F,I]=v.useState(`other`),[L,R]=v.useState(!1),[ie,ae]=v.useState(P),z=F;P!==ie&&(ae(P),P&&(z=L?`hover`:`other`)),z!==F&&I(z),L&&R(!1);let oe=c.useId(`popover-content`),[B,V]=v.useState(void 0),H=B??oe,U=c.useId(`popover-trigger`),[W,se]=v.useState(void 0),[G,ce]=v.useState(null),[K,le]=v.useState(null),q=v.useRef(null),J=v.useRef(null),ue=v.useRef(null),de=E(T)?T:null,Y=v.useRef(null);v.useInsertionEffect(()=>{Y.current=de},[de]);let{setReference:fe,setFloating:pe,floatingProps:me,arrowStyles:he,side:ge}=m.usePopupPosition({open:P,side:i,align:a,offset:8,arrowRef:ue}),_e=v.useRef(null),ve=o.useEventCallback(()=>{let e=w?_e.current?.current:null;if(e&&l.isConnectedAndFocusable(e))return e;let t=q.current,n=t?g.getTriggerFocusTarget(t):null;if(n)return n;let r=Y.current;return r&&l.isConnectedAndFocusable(r)?r:t}),ye=v.useMemo(()=>D(ve),[ve]),be=o.useEventCallback(e=>!(e.ctrlKey&&q.current?.contains(e.target))),{layerId:X}=f.useDismiss({open:P,onDismiss:()=>j(!1),refs:w?[J,Y,...p??[]]:[J,q,Y,...p??[]],anchorRef:ye,kind:`popover`,outsidePress:!w||be}),Z=v.useRef(!1),{anchor:xe,fromContext:Se,origin:Ce,opener:Q,triggerHandlers:we,surfaceHandlers:Te}=_.useContextMenuAnchor({enabled:w,open:P,trigger:K,layerId:X,onOpen:e=>{Z.current=e===`keyboard`,j(!0)},onClose:()=>j(!1)});v.useInsertionEffect(()=>{_e.current=Q},[Q]);let Ee=g.useTriggerFocusRef(q);ee.useRestoreFocus({enabled:P,container:G,triggerRef:w?void 0:Ee,finalFocusRef:w?Q:void 0,fallback:ve,onlyIfFocusInside:!0,isHoverClose:M}),v.useLayoutEffect(()=>{P&&(A.current=!1)},[P]);let De=u.useMergedRefs(q,le),Oe=u.useMergedRefs(J,ce,pe);v.useLayoutEffect(()=>{fe(Se?xe??(K&&(g.getTriggerFocusTarget(K)??K)):T??K)},[xe,Se,T,K,fe]),v.useLayoutEffect(()=>{if(Z.current){if(!P){Z.current=!1;return}G&&(Z.current=!1,l.focusElement(l.getFirstTabbable(G)??G,{preventScroll:!0}))}}),v.useEffect(()=>{x&&w&&n.warnOnce(`Popover:hover-and-context`,"Popover: `openOnHover` is ignored with `openOnContext`: a context popover opens on a right click, Shift+F10 or the ContextMenu key, not on hover.")},[x,w]);let $=x&&!w,ke=o.useEventCallback(()=>z===`hover`&&!h.isFocusInSurfaceTree(J.current,X)),{triggerHandlers:Ae,surfaceHandlers:je,cancel:Me}=te.useHoverIntent({enabled:$,open:P,openDelay:S,closeDelay:C,trigger:K,surface:G,onOpen:()=>{R(!0),j(!0)},onClose:()=>{A.current=!0,k(!1)},canClose:ke}),Ne=o.useEventCallback(()=>{Me(),P&&z===`hover`?I(`other`):j(e=>!e)}),Pe=o.useEventCallback(()=>{let e=q.current,t=w?Q.current:null;return t&&e?.contains(t)?t:e??Y.current}),Fe=v.useMemo(()=>D(Pe),[Pe]),Ie=o.useEventCallback(e=>{if(e.key!==`Tab`||e.shiftKey||!P)return;if(w){let t=Pe();if(!t||e.target!==(g.getTriggerFocusTarget(t)??t))return}let t=J.current,n=t?l.getFirstTabbable(t):null;n&&(e.preventDefault(),n.focus())}),Le=h.usePopoverTabOrder({enabled:P,surface:G,anchorRef:Fe,getPreviousStop:O}),Re=Se&&Ce===`keyboard`,ze=v.useMemo(()=>({open:P,setOpen:j,contentId:H,setCustomContentId:V,triggerId:U,resolvedTriggerId:W,setResolvedTriggerId:se,triggerRef:q,triggerElement:K,triggerElementRef:De,surfaceElementRef:Oe,arrowRef:ue,onTriggerClick:Ne,onTriggerKeyDown:Ie,hoverTriggerHandlers:$?Ae:null,hoverSurfaceHandlers:$?je:null,contextMode:w,contextTriggerHandlers:w?we:null,onContentContextMenu:Te.onContextMenu,keyboardContext:Re,onContentKeyDown:Le,layerId:X,floatingProps:me,arrowStyles:he,placedSide:ge}),[P,j,H,U,W,K,De,Oe,Ne,Ie,$,Ae,je,w,we,Te,Re,Le,X,me,he,ge]);return(0,y.jsx)(b.Provider,{value:ze,children:ne})};k.displayName=`Popover`;var A=({children:e,asChild:t,id:n,onClick:r,onKeyDown:a,onContextMenu:o,onPointerEnter:s,onPointerMove:c,onPointerLeave:l,ref:d,...f})=>{let{open:p,contentId:m,triggerId:ee,triggerElementRef:te,setResolvedTriggerId:h,onTriggerClick:_,onTriggerKeyDown:v,hoverTriggerHandlers:y,contextMode:b,contextTriggerHandlers:x}=C(`Popover.Trigger`),S=u.useMergedRefs(d,te),w={...f,id:n??ee,"aria-haspopup":`dialog`,"aria-expanded":!b&&p,"aria-controls":p&&!b?m:void 0,onClick:i.composeEventHandlers(r,b?void 0:_),onKeyDown:i.composeEventHandlers(a,x?i.composeEventHandlers(x.onKeyDown,v):v),onContextMenu:x?i.composeEventHandlers(o,x.onContextMenu):o,onPointerEnter:y?i.composeEventHandlers(s,y.onPointerEnter):s,onPointerMove:y?i.composeEventHandlers(c,y.onPointerMove):c,onPointerLeave:y?i.composeEventHandlers(l,y.onPointerLeave):l,ref:S};return g.useTriggerElement(e,w,{componentName:`Popover.Trigger`,asChild:t,onResolvedId:h,omitStateAria:b})};A.displayName=`PopoverTrigger`;var j=({children:e,title:o,id:s,className:l,style:d,"aria-label":f,"aria-labelledby":m,onKeyDown:ee,onContextMenu:te,onPointerEnter:g,onPointerLeave:_,ref:b,...x})=>{let{open:S,contentId:w,setCustomContentId:E,resolvedTriggerId:D,triggerRef:O,triggerElement:k,surfaceElementRef:A,arrowRef:j,layerId:M,floatingProps:N,arrowStyles:P,placedSide:F,onContentKeyDown:I,hoverSurfaceHandlers:L,contextMode:R,onContentContextMenu:ie,keyboardContext:ae}=C(`Popover.Content`),z=c.useId(`popover-title`),oe=u.useMergedRefs(b,A),B=r.slotRendersContent(o),V=m===void 0&&!f&&!B,H=S&&V&&!R,U=v.useCallback(e=>{if(!H||!k||typeof MutationObserver>`u`)return re();let t=new MutationObserver(e);return t.observe(k,{attributes:!0,attributeFilter:[`id`,`aria-labelledby`],childList:!0,subtree:!0}),()=>t.disconnect()},[H,k]),W=v.useSyncExternalStore(U,()=>H?T(k,D):void 0,()=>H?D:void 0),se=m??(f?void 0:B?z:W),G=s||void 0;return v.useEffect(()=>(E(G),()=>E(void 0)),[G,E]),v.useEffect(()=>{S&&V&&R&&n.isDev&&n.warnOnce(`Popover.Content:name`,"Popover.Content: the popover has no accessible name. A context popover (openOnContext) is not named by its region: pass `title`, `aria-label` or `aria-labelledby`.")},[S,V,R]),v.useEffect(()=>{if(!H||!n.isDev)return;let e=O.current;if(!e){n.warnOnce(`Popover.Content:name`,"Popover.Content: the popover has no accessible name. Pass `title`, `aria-label` or `aria-labelledby`, or open it from a Popover.Trigger.");return}let t=T(e,D);t?ne(e.ownerDocument,t)||n.warnOnce(`Popover.Content:trigger-name`,"Popover.Content: the popover is named by its trigger, but the trigger has no text to name it (an icon-only trigger needs `aria-label`, or `aria-labelledby` pointing at text), so the popover has no accessible name. Name the trigger, or pass `title`, `aria-label` or `aria-labelledby`."):n.warnOnce(`Popover.Content:trigger-id`,"Popover.Content: the popover is named by its trigger, but the trigger element has no `id` (a render-prop child of Popover.Trigger must spread the `id` it receives), so the popover has no accessible name. Spread every trigger prop onto the element, or pass `title`, `aria-label` or `aria-labelledby`.")},[H,D,O,W]),S?(0,y.jsx)(p.Portal,{layerId:M,children:(0,y.jsxs)(`div`,{role:`dialog`,"aria-label":f,"aria-labelledby":se,tabIndex:ae?-1:void 0,...x,ref:oe,id:G??w,"data-side":N[`data-side`],"data-align":N[`data-align`],style:{...d,...N.style},onKeyDown:i.composeEventHandlers(ee,I),onContextMenu:i.composeEventHandlers(te,ie),onPointerEnter:L?i.composeEventHandlers(g,L.onPointerEnter):g,onPointerLeave:L?i.composeEventHandlers(_,L.onPointerLeave):_,className:t.cn(a.popoverContentClassNames.root,`w-64 rounded-md border border-border bg-background p-4 text-body-1 font-normal text-foreground normal-case tracking-normal text-start shadow-4`,l),children:[(0,y.jsx)(h.PopoverBeak,{ref:j,side:F,style:P,"data-wave-popover-arrow":``,className:a.popoverContentClassNames.beak}),B&&(0,y.jsx)(`h2`,{id:z,className:t.cn(a.popoverContentClassNames.title,`mb-2 text-subtitle-2 font-semibold`),children:o}),e]})}):null};j.displayName=`PopoverContent`;var M=Object.assign(k,{Trigger:A,Content:j});exports.Popover=M,exports.PopoverContent=j,exports.PopoverTrigger=A;
|
|
1
|
+
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/slot.cjs"),i=require("../../lib/composeEventHandlers.cjs"),a=require("../../lib/classNames.cjs"),o=require("../../hooks/useEventCallback.cjs"),s=require("../../hooks/useControllable.cjs"),c=require("../../hooks/useId.cjs"),l=require("../../lib/focus.cjs"),u=require("../../hooks/useMergedRefs.cjs"),ee=require("../../hooks/useIsClient.cjs"),d=require("../../hooks/usePopupPosition.cjs"),f=require("../../hooks/useDismiss.cjs"),te=require("../../hooks/useRestoreFocus.cjs"),p=require("../portal/Portal.cjs"),ne=require("../../hooks/useHoverIntent.cjs"),m=require("./Popover.shared.cjs"),h=require("../../hooks/useTriggerElement.cjs"),g=require("../../hooks/useResolvedTarget.cjs"),_=require("../../hooks/useContextMenuAnchor.cjs");let v=require("react");v=e.__toESM(v,1);let y=require("react/jsx-runtime");var b=v.createContext(null);b.displayName=`PopoverContext`;var x=null;function S(){return x??={open:!1,setOpen:()=>{},contentId:`wave-popover-inert-content`,setCustomContentId:()=>{},triggerId:`wave-popover-inert-trigger`,resolvedTriggerId:void 0,setResolvedTriggerId:()=>{},triggerRef:{current:null},triggerElement:null,triggerElementRef:()=>{},surfaceElementRef:()=>{},arrowRef:{current:null},onTriggerClick:()=>{},onTriggerKeyDown:()=>{},hoverTriggerHandlers:null,hoverSurfaceHandlers:null,contextMode:!1,contextTriggerHandlers:null,onContentContextMenu:()=>{},keyboardContext:!1,onContentKeyDown:()=>{},layerId:`wave-popover-inert-layer`,floatingProps:{"data-side":`bottom`,"data-align":`start`,style:{}},arrowStyles:{},placedSide:`bottom`,fitViewport:!1},x}function C(e){return v.useContext(b)||(n.reportMissingContext(e,`Popover`),S())}function w(e,t){let n=(t??``).split(/\s+/).filter(t=>t&&e.getElementById(t));return n.length>0?n.join(` `):void 0}function T(e,t){if(!e)return t;let n=e.ownerDocument,r=(t?n.getElementById(t):null)??h.getTriggerFocusTarget(e)??e;return w(n,r.getAttribute(`aria-labelledby`))??(r.id||e.id||void 0)}function E(e,t){return t.split(/\s+/).some(t=>{let n=t?e.getElementById(t):null;return n?n.getAttribute(`aria-label`)?.trim()||n.textContent?.trim()?!0:!!n.querySelector(`[aria-label]:not([aria-label=""]), [alt]:not([alt=""]), [title]:not([title=""])`):!1})}var re=()=>()=>{};function D(e){return!!e&&typeof e.nodeType==`number`}function O(e){return{get current(){return e()}}}function k(e,t,n){return h.getTriggerFocusTarget(e)??m.getTabbableThrough(e,t,n)}var A=({open:e,defaultOpen:t,onOpenChange:r,side:i=`bottom`,align:a=`start`,ignoreOutsideRefs:p,openOnHover:x=!1,openDelay:S=250,closeDelay:C=500,openOnContext:w=!1,target:T,positioning:E,children:re})=>{let{target:A,pending:j}=g.usePopupTarget(`Popover`,T,E),[M,N]=s.useControllable(e,t??!1,r),P=v.useRef(!1),F=o.useEventCallback(e=>{P.current=!1,N(e)}),ie=v.useCallback(()=>P.current,[]),ae=ee.useIsClient(),I=M&&ae,[L,oe]=v.useState(`other`),[se,R]=v.useState(!1),[ce,z]=v.useState(I),B=L;I!==ce&&(z(I),I&&(B=se?`hover`:`other`)),B!==L&&oe(B),se&&R(!1);let V=c.useId(`popover-content`),[le,ue]=v.useState(void 0),de=le??V,H=c.useId(`popover-trigger`),[U,fe]=v.useState(void 0),[W,pe]=v.useState(null),[G,me]=v.useState(null),K=v.useRef(null),q=v.useRef(null),he=v.useRef(null),ge=D(A)?A:null,J=v.useRef(null);v.useInsertionEffect(()=>{J.current=ge},[ge]);let{setReference:_e,setFloating:ve,floatingProps:Y,arrowStyles:ye,side:be}=d.usePopupPosition({open:I,side:i,align:a,arrowRef:he,...d.resolvePositioning(E,{offset:8})}),xe=v.useMemo(()=>j?{...Y,style:{...Y.style,visibility:`hidden`}}:Y,[j,Y]),Se=v.useRef(null),Ce=o.useEventCallback(()=>{let e=w?Se.current?.current:null;if(e&&l.isConnectedAndFocusable(e))return e;let t=K.current,n=t?h.getTriggerFocusTarget(t):null;if(n)return n;let r=J.current;return r&&l.isConnectedAndFocusable(r)?r:t}),we=v.useMemo(()=>O(Ce),[Ce]),Te=o.useEventCallback(e=>!(e.ctrlKey&&K.current?.contains(e.target))),{layerId:X}=f.useDismiss({open:I,onDismiss:()=>F(!1),refs:w?[q,J,...p??[]]:[q,K,J,...p??[]],anchorRef:we,kind:`popover`,outsidePress:!w||Te}),Z=v.useRef(!1),{anchor:Ee,fromContext:De,origin:Oe,opener:Q,triggerHandlers:ke,surfaceHandlers:Ae}=_.useContextMenuAnchor({enabled:w,open:I,trigger:G,layerId:X,onOpen:e=>{Z.current=e===`keyboard`,F(!0)},onClose:()=>F(!1)});v.useInsertionEffect(()=>{Se.current=Q},[Q]);let je=h.useTriggerFocusRef(K);te.useRestoreFocus({enabled:I,container:W,triggerRef:w?void 0:je,finalFocusRef:w?Q:void 0,fallback:Ce,onlyIfFocusInside:!0,isHoverClose:ie}),v.useLayoutEffect(()=>{I&&(P.current=!1)},[I]);let Me=u.useMergedRefs(K,me),Ne=u.useMergedRefs(q,pe,ve);v.useLayoutEffect(()=>{_e(De?Ee??(G&&(h.getTriggerFocusTarget(G)??G)):A??G)},[Ee,De,A,G,_e]),v.useLayoutEffect(()=>{if(Z.current){if(!I){Z.current=!1;return}W&&(Z.current=!1,l.focusElement(l.getFirstTabbable(W)??W,{preventScroll:!0}))}}),v.useEffect(()=>{x&&w&&n.warnOnce(`Popover:hover-and-context`,"Popover: `openOnHover` is ignored with `openOnContext`: a context popover opens on a right click, Shift+F10 or the ContextMenu key, not on hover.")},[x,w]);let $=x&&!w,Pe=o.useEventCallback(()=>B===`hover`&&!m.isFocusInSurfaceTree(q.current,X)),{triggerHandlers:Fe,surfaceHandlers:Ie,cancel:Le}=ne.useHoverIntent({enabled:$,open:I,openDelay:S,closeDelay:C,trigger:G,surface:W,onOpen:()=>{R(!0),F(!0)},onClose:()=>{P.current=!0,N(!1)},canClose:Pe}),Re=o.useEventCallback(()=>{Le(),I&&B===`hover`?oe(`other`):F(e=>!e)}),ze=o.useEventCallback(()=>{let e=K.current,t=w?Q.current:null;return t&&e?.contains(t)?t:e??J.current}),Be=v.useMemo(()=>O(ze),[ze]),Ve=o.useEventCallback(e=>{if(e.key!==`Tab`||e.shiftKey||!I)return;if(w){let t=ze();if(!t||e.target!==(h.getTriggerFocusTarget(t)??t))return}let t=q.current,n=t?l.getFirstTabbable(t):null;n&&(e.preventDefault(),n.focus())}),He=m.usePopoverTabOrder({enabled:I,surface:W,anchorRef:Be,getPreviousStop:k}),Ue=De&&Oe===`keyboard`,We=v.useMemo(()=>({open:I,setOpen:F,contentId:de,setCustomContentId:ue,triggerId:H,resolvedTriggerId:U,setResolvedTriggerId:fe,triggerRef:K,triggerElement:G,triggerElementRef:Me,surfaceElementRef:Ne,arrowRef:he,onTriggerClick:Re,onTriggerKeyDown:Ve,hoverTriggerHandlers:$?Fe:null,hoverSurfaceHandlers:$?Ie:null,contextMode:w,contextTriggerHandlers:w?ke:null,onContentContextMenu:Ae.onContextMenu,keyboardContext:Ue,onContentKeyDown:He,layerId:X,floatingProps:xe,arrowStyles:ye,placedSide:be,fitViewport:E?.fitViewport===!0}),[I,F,de,H,U,G,Me,Ne,Re,Ve,$,Fe,Ie,w,ke,Ae,Ue,He,X,xe,ye,be,E?.fitViewport]);return(0,y.jsx)(b.Provider,{value:We,children:re})};A.displayName=`Popover`;var j=({children:e,asChild:t,id:n,onClick:r,onKeyDown:a,onContextMenu:o,onPointerEnter:s,onPointerMove:c,onPointerLeave:l,ref:ee,...d})=>{let{open:f,contentId:te,triggerId:p,triggerElementRef:ne,setResolvedTriggerId:m,onTriggerClick:g,onTriggerKeyDown:_,hoverTriggerHandlers:v,contextMode:y,contextTriggerHandlers:b}=C(`Popover.Trigger`),x=u.useMergedRefs(ee,ne),S={...d,id:n??p,"aria-haspopup":`dialog`,"aria-expanded":!y&&f,"aria-controls":f&&!y?te:void 0,onClick:i.composeEventHandlers(r,y?void 0:g),onKeyDown:i.composeEventHandlers(a,b?i.composeEventHandlers(b.onKeyDown,_):_),onContextMenu:b?i.composeEventHandlers(o,b.onContextMenu):o,onPointerEnter:v?i.composeEventHandlers(s,v.onPointerEnter):s,onPointerMove:v?i.composeEventHandlers(c,v.onPointerMove):c,onPointerLeave:v?i.composeEventHandlers(l,v.onPointerLeave):l,ref:x};return h.useTriggerElement(e,S,{componentName:`Popover.Trigger`,asChild:t,onResolvedId:m,omitStateAria:y})};j.displayName=`PopoverTrigger`;var M=({children:e,title:o,id:s,className:l,style:ee,"aria-label":d,"aria-labelledby":f,onKeyDown:te,onContextMenu:ne,onPointerEnter:h,onPointerLeave:g,ref:_,...b})=>{let{open:x,contentId:S,setCustomContentId:w,resolvedTriggerId:D,triggerRef:O,triggerElement:k,surfaceElementRef:A,arrowRef:j,layerId:M,floatingProps:N,arrowStyles:P,placedSide:F,fitViewport:ie,onContentKeyDown:ae,hoverSurfaceHandlers:I,contextMode:L,onContentContextMenu:oe,keyboardContext:se}=C(`Popover.Content`),R=c.useId(`popover-title`),ce=u.useMergedRefs(_,A),z=r.slotRendersContent(o),B=f===void 0&&!d&&!z,V=x&&B&&!L,le=v.useCallback(e=>{if(!V||!k||typeof MutationObserver>`u`)return re();let t=new MutationObserver(e);return t.observe(k,{attributes:!0,attributeFilter:[`id`,`aria-labelledby`],childList:!0,subtree:!0}),()=>t.disconnect()},[V,k]),ue=v.useSyncExternalStore(le,()=>V?T(k,D):void 0,()=>V?D:void 0),de=f??(d?void 0:z?R:ue),H=s||void 0;if(v.useEffect(()=>(w(H),()=>w(void 0)),[H,w]),v.useEffect(()=>{x&&B&&L&&n.isDev&&n.warnOnce(`Popover.Content:name`,"Popover.Content: the popover has no accessible name. A context popover (openOnContext) is not named by its region: pass `title`, `aria-label` or `aria-labelledby`.")},[x,B,L]),v.useEffect(()=>{if(!V||!n.isDev)return;let e=O.current;if(!e){n.warnOnce(`Popover.Content:name`,"Popover.Content: the popover has no accessible name. Pass `title`, `aria-label` or `aria-labelledby`, or open it from a Popover.Trigger.");return}let t=T(e,D);t?E(e.ownerDocument,t)||n.warnOnce(`Popover.Content:trigger-name`,"Popover.Content: the popover is named by its trigger, but the trigger has no text to name it (an icon-only trigger needs `aria-label`, or `aria-labelledby` pointing at text), so the popover has no accessible name. Name the trigger, or pass `title`, `aria-label` or `aria-labelledby`."):n.warnOnce(`Popover.Content:trigger-id`,"Popover.Content: the popover is named by its trigger, but the trigger element has no `id` (a render-prop child of Popover.Trigger must spread the `id` it receives), so the popover has no accessible name. Spread every trigger prop onto the element, or pass `title`, `aria-label` or `aria-labelledby`.")},[V,D,O,ue]),!x)return null;let U=(0,y.jsxs)(y.Fragment,{children:[z&&(0,y.jsx)(`h2`,{id:R,className:t.cn(a.popoverContentClassNames.title,`mb-2 text-subtitle-2 font-semibold`),children:o}),e]});return(0,y.jsx)(p.Portal,{layerId:M,children:(0,y.jsxs)(`div`,{role:`dialog`,"aria-label":d,"aria-labelledby":de,tabIndex:se?-1:void 0,...b,ref:ce,id:H??S,"data-side":N[`data-side`],"data-align":N[`data-align`],style:{...ee,...N.style},onKeyDown:i.composeEventHandlers(te,ae),onContextMenu:i.composeEventHandlers(ne,oe),onPointerEnter:I?i.composeEventHandlers(h,I.onPointerEnter):h,onPointerLeave:I?i.composeEventHandlers(g,I.onPointerLeave):g,className:t.cn(a.popoverContentClassNames.root,`w-64 rounded-md border border-border bg-background p-4 text-body-1 font-normal text-foreground normal-case tracking-normal text-start shadow-4`,l),children:[(0,y.jsx)(m.PopoverBeak,{ref:j,side:F,style:P,"data-wave-popover-arrow":``,className:a.popoverContentClassNames.beak}),ie?(0,y.jsx)(`div`,{className:`overflow-y-auto max-h-[calc(var(--wave-popup-available-height)-2rem-2px)]`,children:U}):U]})})};M.displayName=`PopoverContent`;var N=Object.assign(A,{Trigger:j,Content:M});exports.Popover=N,exports.PopoverContent=M,exports.PopoverTrigger=j;
|
|
2
2
|
//# sourceMappingURL=Popover.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.cjs","names":["React","getTriggerFocusTarget","getTabbableThrough","useControllable","useEventCallback","useIsClient","useId","usePopupPosition","isConnectedAndFocusable","useDismiss","useContextMenuAnchor","useTriggerFocusRef","useMergedRefs","getFirstTabbable","isFocusInSurfaceTree","useHoverIntent","usePopoverTabOrder","composeEventHandlers","useTriggerElement","slotRendersContent","isDev","Portal","cn","popoverContentClassNames","PopoverBeak","require_runtime","require_cn","require_dev","require_slot","require_composeEventHandlers","require_classNames","require_useEventCallback","require_useControllable","require_useId","require_focus","require_useMergedRefs","require_useIsClient","require_useDismiss","require_Portal","require_usePopupPosition","require_useRestoreFocus","require_useHoverIntent","require_Popover_shared","require_useTriggerElement","require_useContextMenuAnchor","react","react_jsx_runtime","PopoverContext","inertContext","getInertContext","usePopoverContext","componentName","presentIds","present","ids","id","doc","findTriggerLabelId","trigger","resolvedId","named","referencesText","el","subscribeNothing","isElementTarget","target","createResolvedRef","resolve","getPopoverPreviousStop","anchor","surface","order","PopoverRoot","openProp","openState","setOpen","defaultOpen","onOpenChange","hoverCloseRef","requestOpen","next","isHoverClose","isClient","open","openReason","setOpenReason","hoverRequested","setHoverRequested","previousOpen","setPreviousOpen","reason","generatedContentId","customContentId","setCustomContentId","contentId","triggerId","resolvedTriggerId","setResolvedTriggerId","setSurface","triggerElement","setTriggerElement","triggerRef","surfaceRef","arrowRef","targetElement","targetRef","placedSide","contextOpenerRef","resolveFocusTarget","gestureOpener","openOnContext","triggerTarget","targetEl","focusTargetRef","isOutsidePress","event","ignoreOutsideRefs","focusContentRef","contextAnchor","contextOrigin","contextOpener","contextTriggerHandlers","contextSurfaceHandlers","origin","triggerFocusRef","triggerElementRef","surfaceElementRef","setFloating","setReference","fromContext","openOnHover","hoverEnabled","canHoverClose","layerId","hoverTriggerHandlers","hoverSurfaceHandlers","cancelHover","onTriggerClick","current","resolveTabAnchor","tabAnchorRef","onTriggerKeyDown","surfaceElement","first","onContentKeyDown","keyboardContext","context","floatingProps","arrowStyles","PopoverTrigger","idProp","rest","hover","gesture","elementRef","ref","triggerProps","contextMode","onClick","onKeyDown","onContextMenu","onPointerEnter","onPointerMove","onPointerLeave","children","PopoverContent","ariaLabel","ariaLabelledBy","titleId","hasTitle","title","unnamed","checkTrigger","subscribeTrigger","observer","onChange","triggerLabelId","labelledBy","customId","labelIds","style","onContentContextMenu","className","Popover"],"sources":["../../../src/components/overlays/Popover.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { popoverContentClassNames } from '../../lib/classNames';\nimport { isDev, reportMissingContext, warnOnce } from '../../lib/dev';\nimport { slotRendersContent } from '../../lib/slot';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { focusElement, getFirstTabbable, isConnectedAndFocusable } from '../../lib/focus';\nimport type { PopupAlign, PopupSide, PopupTarget } from '../../lib/types';\nimport { useId } from '../../hooks/useId';\nimport { useControllable, type SetValue } from '../../hooks/useControllable';\nimport { useContextMenuAnchor, type ContextMenuAnchor } from '../../hooks/useContextMenuAnchor';\nimport { useDismiss } from '../../hooks/useDismiss';\nimport { useHoverIntent, type HoverIntent } from '../../hooks/useHoverIntent';\nimport { useRestoreFocus } from '../../hooks/useRestoreFocus';\nimport { usePopupPosition } from '../../hooks/usePopupPosition';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport {\n getTriggerFocusTarget,\n useTriggerElement,\n useTriggerFocusRef,\n} from '../../hooks/useTriggerElement';\nimport { Portal } from '../portal/Portal';\nimport {\n getTabbableThrough,\n isFocusInSurfaceTree,\n PopoverBeak,\n usePopoverTabOrder,\n type PopoverPhysicalSide,\n} from './Popover.shared';\n\n/** Properties for the Popover component. */\nexport interface PopoverProps {\n /**\n * Controlled open state of the popover. The content renders only in the browser: an open\n * popover is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Default open state for uncontrolled usage. The content renders only in the browser: a\n * popover open by default is closed in the server HTML and opens once it has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Called with the requested open state when it differs from the current one: a trigger click,\n * Escape and an outside press; the hover opening and closing of `openOnHover`; and, with\n * `openOnContext`, a context gesture (a right click, a macOS Ctrl+click, Shift+F10 or the\n * ContextMenu key), a right click outside, and a scroll that moves the row it opened at.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Side of the trigger the content opens on. `start`/`end` follow the writing direction. The\n * content flips to the opposite side when there is not enough room.\n * @default 'bottom'\n */\n side?: PopupSide;\n /** Alignment of the content along the trigger's edge.\n * @default 'start'\n */\n align?: PopupAlign;\n /**\n * Elements outside the popover whose presses must not dismiss it, e.g. an external toggle\n * button that opens and closes the popover itself.\n */\n ignoreOutsideRefs?: ReadonlyArray<React.RefObject<HTMLElement | null>>;\n /**\n * Open the popover when a mouse pointer rests on its trigger (a hover card), and close it once\n * the pointer has been off the trigger and the content for `closeDelay` while focus is not\n * inside the content. A popover opened by hover does not take focus, and its hover close leaves\n * focus where it is; a click on its trigger keeps it open and keeps focus where it is (a second\n * click closes it, as without hover). After Escape or an outside press it does not reopen until\n * the pointer has left the trigger. Touch and pen never open it by hover, and an `aria-disabled`\n * trigger never opens. A triangle between the trigger and the content keeps it open while the\n * pointer moves diagonally into it. Ignored with `openOnContext` (development warning).\n * @default false\n */\n openOnHover?: boolean;\n /**\n * Milliseconds a hovering mouse pointer rests on the trigger before the popover opens (mouse\n * hover only).\n * @default 250\n */\n openDelay?: number;\n /**\n * Milliseconds before a hover-opened popover closes once the mouse pointer has left it and its\n * trigger (Fluent's `mouseLeaveDelay`; mouse hover only).\n * @default 500\n */\n closeDelay?: number;\n /**\n * Make `Popover.Trigger` a context-menu region (a list, a row, a canvas): a right click (a\n * Ctrl+click on macOS, a long press where the browser reports one) opens the popover at the\n * pointer and leaves focus where it is (Tab from that element enters the content), and\n * Shift+F10 or the ContextMenu key opens it at the focused element inside the region and moves\n * focus into the content, instead of a click. Focus returns to the element that had it. The\n * browser's context menu is suppressed there and inside the content, except in text fields\n * inside the region, which keep it. A press elsewhere, a right click outside or a scroll that\n * moves the row it opened at (the one under the pointer, or the focused one), as a scroll of\n * the region's own content does, closes it. The trigger gets no `aria-haspopup`/`aria-expanded`\n * (it is not a popover button; with a render-prop child, do not spread them): name the content\n * with `title`, `aria-label` or `aria-labelledby`, and consider `aria-keyshortcuts=\"Shift+F10\"`\n * on the region. iOS Safari reports no long press. `openOnHover` is ignored with it.\n * @default false\n */\n openOnContext?: boolean;\n /**\n * Where to place the content instead of next to `Popover.Trigger`: an element or a\n * `VirtualElement` (a rectangle, such as a point; an inline object is fine). With a controlled\n * `open`, a popover with a `target` needs no trigger; name it with `title`, `aria-label` or\n * `aria-labelledby`, and give a toggle button you use as the target `aria-haspopup=\"dialog\"`,\n * `aria-expanded` and `aria-controls` yourself. A press on a target element does not close the\n * popover, and Tab from it enters the content when there is no trigger. Hold the element in\n * state (a ref cannot be observed; TeachingPopover's `target` also takes a ref). A popover\n * opened by `openOnContext` is placed at the gesture instead.\n */\n target?: PopupTarget;\n /** `Popover.Trigger` and `Popover.Content`. */\n children: React.ReactNode;\n}\n\n/**\n * Props the trigger puts on its element; a render-prop child of `Popover.Trigger` receives them\n * (spread them onto the element that opens the popover). With `openOnContext` the element is a\n * context-menu region, not a popover button: do not spread `aria-haspopup`, `aria-expanded` and\n * `aria-controls` onto it (`aria-expanded` is then always `false`, `aria-controls` is absent and\n * `onClick` does nothing); spread ones are removed after each commit, with a development warning.\n */\nexport type PopoverTriggerChildProps = Omit<React.HTMLAttributes<HTMLElement>, 'children'> & {\n id: string;\n 'aria-haspopup': 'dialog';\n 'aria-expanded': boolean;\n /** The content's id, only while the popover is open (never with `openOnContext`). */\n 'aria-controls': string | undefined;\n onClick: React.MouseEventHandler<HTMLElement>;\n /**\n * Moves Tab from the open trigger into the portaled content (which lives at the end of the\n * document), so the keyboard order follows the trigger.\n */\n onKeyDown: React.KeyboardEventHandler<HTMLElement>;\n ref: React.RefCallback<HTMLElement>;\n};\n\n/** Properties for the PopoverTrigger sub-component. */\nexport interface PopoverTriggerProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that toggles the popover (its props are merged onto it), or a render function\n * that receives the trigger props.\n */\n children: React.ReactNode | ((props: PopoverTriggerChildProps) => React.ReactNode);\n /**\n * `false` renders the 0.4 wrapper `<span>` carrying the trigger props around the children\n * instead of merging them onto the child. `aria-haspopup`, `aria-expanded` and `aria-controls`,\n * which a generic element cannot carry, go to the first element in the tab order inside the\n * span. A render-prop child ignores `asChild` and receives every prop.\n * @default true\n */\n asChild?: boolean;\n /** Ref to the trigger element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\n/** Properties for the PopoverContent sub-component. */\nexport interface PopoverContentProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Content to render inside the popover. */\n children: React.ReactNode;\n /**\n * Visible heading rendered at the top of the popover; it names the dialog. Without `title`,\n * `aria-label` or `aria-labelledby`, the popover is labelled by its trigger, except with\n * `openOnContext` (a region's text is no name), where it needs one of them.\n */\n title?: React.ReactNode;\n /** Id of the surface; the trigger's `aria-controls` follows it. Defaults to a generated id. */\n id?: string;\n /** Ref to the popover surface. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\ninterface PopoverContextValue {\n open: boolean;\n setOpen: SetValue<boolean>;\n /** The content's id: the consumer's `Popover.Content` id when given, else a generated one. */\n contentId: string;\n /** `Popover.Content` reports the consumer's `id` so the trigger's `aria-controls` follows it. */\n setCustomContentId: (id: string | undefined) => void;\n triggerId: string;\n /** The id the trigger element ended up with (the child's own id wins). */\n resolvedTriggerId: string | undefined;\n setResolvedTriggerId: (id: string) => void;\n triggerRef: React.RefObject<HTMLElement | null>;\n /** The trigger element as state (read during render, e.g. to check the labelling id). */\n triggerElement: HTMLElement | null;\n /** Ref callback for the trigger element: focus-restore target and positioning anchor. */\n triggerElementRef: React.RefCallback<HTMLElement>;\n /** Ref callback for the surface: dismissal, focus restore and positioning. */\n surfaceElementRef: React.RefCallback<HTMLElement>;\n arrowRef: React.RefObject<HTMLDivElement | null>;\n /** The trigger's click: toggles the popover, or pins one that hover opened (keeps it open). */\n onTriggerClick: () => void;\n /** Tab from the open trigger enters the portaled content. */\n onTriggerKeyDown: React.KeyboardEventHandler<HTMLElement>;\n /** Hover opening (`openOnHover`): composed onto the trigger; `null` without it. */\n hoverTriggerHandlers: HoverIntent['triggerHandlers'] | null;\n /** Hover opening (`openOnHover`): composed onto the content; `null` without it. */\n hoverSurfaceHandlers: HoverIntent['surfaceHandlers'] | null;\n /** `openOnContext`: the trigger is a context-menu region, not a popover button. */\n contextMode: boolean;\n /** Context gestures (`openOnContext`): composed onto the trigger; `null` without it. */\n contextTriggerHandlers: ContextMenuAnchor['triggerHandlers'] | null;\n /** Composed onto the content: suppresses the browser's context menu there in context mode. */\n onContentContextMenu: React.MouseEventHandler<HTMLElement>;\n /** Opened by a keyboard context gesture: the content takes focus (itself when nothing can). */\n keyboardContext: boolean;\n /** Tab past the content's edges continues around the trigger in the page order. */\n onContentKeyDown: React.KeyboardEventHandler<HTMLElement>;\n layerId: string;\n floatingProps: { 'data-side': string; 'data-align': string; style: React.CSSProperties };\n arrowStyles: React.CSSProperties;\n placedSide: PopoverPhysicalSide;\n}\n\nconst PopoverContext = React.createContext<PopoverContextValue | null>(null);\nPopoverContext.displayName = 'PopoverContext';\n\nlet inertContext: PopoverContextValue | null = null;\n\n/** Production fallback for a misplaced sub-component: a closed popover that does nothing. */\nfunction getInertContext(): PopoverContextValue {\n inertContext ??= {\n open: false,\n setOpen: () => {},\n contentId: 'wave-popover-inert-content',\n setCustomContentId: () => {},\n triggerId: 'wave-popover-inert-trigger',\n resolvedTriggerId: undefined,\n setResolvedTriggerId: () => {},\n triggerRef: { current: null },\n triggerElement: null,\n triggerElementRef: () => {},\n surfaceElementRef: () => {},\n arrowRef: { current: null },\n onTriggerClick: () => {},\n onTriggerKeyDown: () => {},\n hoverTriggerHandlers: null,\n hoverSurfaceHandlers: null,\n contextMode: false,\n contextTriggerHandlers: null,\n onContentContextMenu: () => {},\n keyboardContext: false,\n onContentKeyDown: () => {},\n layerId: 'wave-popover-inert-layer',\n floatingProps: { 'data-side': 'bottom', 'data-align': 'start', style: {} },\n arrowStyles: {},\n placedSide: 'bottom',\n };\n return inertContext;\n}\n\nfunction usePopoverContext(componentName: string): PopoverContextValue {\n const context = React.useContext(PopoverContext);\n if (context) return context;\n reportMissingContext(componentName, 'Popover');\n return getInertContext();\n}\n\n/** The ids of an id list that exist in `doc`, joined; `undefined` when none does. */\nfunction presentIds(doc: Document, ids: string | null): string | undefined {\n const present = (ids ?? '').split(/\\s+/).filter((id) => id && doc.getElementById(id));\n return present.length > 0 ? present.join(' ') : undefined;\n}\n\n/**\n * The ids `Popover.Content`'s default `aria-labelledby` points at, so the popover gets its\n * trigger's name. The named element is the one with the resolved id when the document has it,\n * otherwise the trigger's focus target (for example the Button inside a Tooltip that sits between\n * `Popover.Trigger` and the Button, whose own id wins), else the trigger element. When that\n * element is itself named through `aria-labelledby` (an icon-only Button inside\n * `Tooltip relationship=\"label\"`, or a button labelled by a visible label), its label ids are\n * returned: a name computation does not follow a second `aria-labelledby` hop, so pointing at the\n * button would leave the popover unnamed. Otherwise the element's id, else the trigger's own.\n * `undefined` when none of them has an id (a render-prop child that does not spread `id`), so the\n * reference never dangles; only ids present in the document are returned. Before the trigger\n * element is known, the resolved id.\n */\nfunction findTriggerLabelId(\n trigger: HTMLElement | null,\n resolvedId: string | undefined,\n): string | undefined {\n if (!trigger) return resolvedId;\n const doc = trigger.ownerDocument;\n const named =\n (resolvedId ? doc.getElementById(resolvedId) : null) ??\n getTriggerFocusTarget(trigger) ??\n trigger;\n return (\n presentIds(doc, named.getAttribute('aria-labelledby')) ?? (named.id || trigger.id || undefined)\n );\n}\n\n/**\n * Whether one of the elements an id list references has text for a name: its own `aria-label`\n * or text, or a descendant's `aria-label`, `alt` or `title`. Deliberately lenient (it only drives\n * a development warning): content that assistive technology ignores still counts as text.\n */\nfunction referencesText(doc: Document, ids: string): boolean {\n return ids.split(/\\s+/).some((id) => {\n const el = id ? doc.getElementById(id) : null;\n if (!el) return false;\n if (el.getAttribute('aria-label')?.trim() || el.textContent?.trim()) return true;\n return !!el.querySelector(\n '[aria-label]:not([aria-label=\"\"]), [alt]:not([alt=\"\"]), [title]:not([title=\"\"])',\n );\n });\n}\n\nconst subscribeNothing = (): (() => void) => () => {};\n\n/** Why an open popover opened: hover (it closes by hover), or anything else (it is pinned). */\ntype OpenReason = 'hover' | 'other';\n\n/** Whether a `target` is an element rather than a VirtualElement (duck typed, any realm). */\nfunction isElementTarget(target: PopupTarget | undefined): target is HTMLElement {\n return !!target && typeof (target as Partial<Node>).nodeType === 'number';\n}\n\n/** A read-only ref whose `current` is `resolve()` at the time it is read (event time). */\nfunction createResolvedRef(resolve: () => HTMLElement | null): React.RefObject<HTMLElement | null> {\n return {\n get current() {\n return resolve();\n },\n };\n}\n\n/**\n * The content's previous stop: the focus target of the element it follows (the trigger, the row of\n * a context gesture, a `target` element), else the tab stop before that element.\n */\nfunction getPopoverPreviousStop(\n anchor: HTMLElement,\n surface: HTMLElement,\n order?: readonly HTMLElement[],\n): HTMLElement | null {\n return getTriggerFocusTarget(anchor) ?? getTabbableThrough(anchor, surface, order);\n}\n\n// A const arrow (like DialogRoot and DrawerRoot): its type can be named in consumers' declaration\n// files, e.g. a story's `satisfies Meta<typeof Popover>` (a function declaration's `typeof` cannot,\n// TS4023).\nconst PopoverRoot = ({\n open: openProp,\n defaultOpen,\n onOpenChange,\n side = 'bottom',\n align = 'start',\n ignoreOutsideRefs,\n openOnHover = false,\n openDelay = 250,\n closeDelay = 500,\n openOnContext = false,\n target,\n children,\n}: PopoverProps) => {\n const [openState, setOpen] = useControllable(openProp, defaultOpen ?? false, onOpenChange);\n // A hover close in flight (written in handlers, read when the popover closes): set when the hover\n // intent asks to close, so that close moves no focus even when a controlled parent applies it in\n // a later render (a transition). Every other request to open or close forgets it, and so does\n // the next opening.\n const hoverCloseRef = React.useRef(false);\n const requestOpen = useEventCallback<SetValue<boolean>>((next) => {\n hoverCloseRef.current = false;\n setOpen(next);\n });\n const isHoverClose = React.useCallback(() => hoverCloseRef.current, []);\n // The content lives in a portal, which renders only in the browser: until then (the server\n // HTML, hydration) the popover reports itself closed, so the trigger's aria-expanded and\n // aria-controls never describe content that is not there.\n const isClient = useIsClient();\n const open = openState && isClient;\n\n // Why the popover opened, decided when it opens (C-HOOKS: a previous-value state): `hover` when\n // hover asked for that open (a request consumed by the next render, so an open that a\n // controlled parent refused does not linger), else `other` (click, keys, a context gesture, a\n // controlled open).\n const [openReason, setOpenReason] = React.useState<OpenReason>('other');\n const [hoverRequested, setHoverRequested] = React.useState(false);\n const [previousOpen, setPreviousOpen] = React.useState(open);\n let reason = openReason;\n if (open !== previousOpen) {\n setPreviousOpen(open);\n if (open) reason = hoverRequested ? 'hover' : 'other';\n }\n if (reason !== openReason) setOpenReason(reason);\n if (hoverRequested) setHoverRequested(false);\n\n const generatedContentId = useId('popover-content');\n const [customContentId, setCustomContentId] = React.useState<string | undefined>(undefined);\n const contentId = customContentId ?? generatedContentId;\n const triggerId = useId('popover-trigger');\n const [resolvedTriggerId, setResolvedTriggerId] = React.useState<string | undefined>(undefined);\n const [surface, setSurface] = React.useState<HTMLElement | null>(null);\n const [triggerElement, setTriggerElement] = React.useState<HTMLElement | null>(null);\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const surfaceRef = React.useRef<HTMLElement | null>(null);\n const arrowRef = React.useRef<HTMLDivElement | null>(null);\n // A `target` element (not a VirtualElement) belongs to the dismiss layer, anchors the keyboard\n // order without a trigger and can take focus back.\n const targetElement = isElementTarget(target) ? target : null;\n const targetRef = React.useRef<HTMLElement | null>(null);\n React.useInsertionEffect(() => {\n targetRef.current = targetElement;\n }, [targetElement]);\n\n // Destructured: react-hooks/refs treats an object whose member is passed to `ref` as a ref.\n const {\n setReference,\n setFloating,\n floatingProps,\n arrowStyles,\n side: placedSide,\n } = usePopupPosition({ open, side, align, offset: 8, arrowRef });\n\n // The one focus resolver: the focus-return fallback and the layer's anchor (where a surface\n // opened from the content restores focus once its opener is gone). In context mode the element\n // focused at the gesture (the row) first; then the trigger's focus target (for a wrapper span,\n // the element inside it that carries the state ARIA), a focusable `target` element, and the\n // trigger itself. The context hook's opener ref is stable; it is filled in once the hook runs.\n const contextOpenerRef = React.useRef<React.RefObject<HTMLElement | null> | null>(null);\n const resolveFocusTarget = useEventCallback((): HTMLElement | null => {\n const gestureOpener = openOnContext ? contextOpenerRef.current?.current : null;\n if (gestureOpener && isConnectedAndFocusable(gestureOpener)) return gestureOpener;\n const trigger = triggerRef.current;\n const triggerTarget = trigger ? getTriggerFocusTarget(trigger) : null;\n if (triggerTarget) return triggerTarget;\n const targetEl = targetRef.current;\n if (targetEl && isConnectedAndFocusable(targetEl)) return targetEl;\n return trigger;\n });\n const focusTargetRef = React.useMemo(\n () => createResolvedRef(resolveFocusTarget),\n [resolveFocusTarget],\n );\n\n // In context mode the region is no part of the layer: a primary press elsewhere in it closes the\n // popover like any outside press. A Ctrl+press inside it is a macOS context click, whose\n // `contextmenu` moves the popover instead.\n const isOutsidePress = useEventCallback(\n (event: PointerEvent | MouseEvent) =>\n !(event.ctrlKey && triggerRef.current?.contains(event.target as Node)),\n );\n const { layerId } = useDismiss({\n open,\n onDismiss: () => requestOpen(false),\n refs: openOnContext\n ? [surfaceRef, targetRef, ...(ignoreOutsideRefs ?? [])]\n : [surfaceRef, triggerRef, targetRef, ...(ignoreOutsideRefs ?? [])],\n anchorRef: focusTargetRef,\n kind: 'popover',\n outsidePress: openOnContext ? isOutsidePress : true,\n });\n\n // A keyboard context gesture moves focus into the content, once it is there (see below).\n const focusContentRef = React.useRef(false);\n const {\n anchor: contextAnchor,\n fromContext,\n origin: contextOrigin,\n opener: contextOpener,\n triggerHandlers: contextTriggerHandlers,\n surfaceHandlers: contextSurfaceHandlers,\n } = useContextMenuAnchor({\n enabled: openOnContext,\n open,\n trigger: triggerElement,\n layerId,\n onOpen: (origin) => {\n focusContentRef.current = origin === 'keyboard';\n requestOpen(true);\n },\n onClose: () => requestOpen(false),\n });\n React.useInsertionEffect(() => {\n contextOpenerRef.current = contextOpener;\n }, [contextOpener]);\n\n // Focus returns to the element that takes focus for the trigger, as Shift+Tab from the content\n // does, when the popover closes while focus is inside it or on `<body>`; a hover close restores\n // only focus inside, so it never moves focus. In context mode it returns to the element focused\n // at the gesture (the row): the region is no restore target of its own (as `triggerRef` it\n // would be taken for the opener).\n const triggerFocusRef = useTriggerFocusRef(triggerRef);\n useRestoreFocus({\n enabled: open,\n container: surface,\n triggerRef: openOnContext ? undefined : triggerFocusRef,\n finalFocusRef: openOnContext ? contextOpener : undefined,\n fallback: resolveFocusTarget,\n onlyIfFocusInside: true,\n isHoverClose,\n });\n React.useLayoutEffect(() => {\n if (open) hoverCloseRef.current = false;\n }, [open]);\n\n const triggerElementRef = useMergedRefs<HTMLElement>(triggerRef, setTriggerElement);\n const surfaceElementRef = useMergedRefs<HTMLElement>(surfaceRef, setSurface, setFloating);\n\n // The positioning anchor: the context gesture (the pointer, or the focused row, else the\n // trigger's focus target, else the trigger) while the popover was opened by one, else `target`,\n // else the trigger. A new VirtualElement on every render repositions without a render loop.\n React.useLayoutEffect(() => {\n if (fromContext) {\n setReference(\n contextAnchor ??\n (triggerElement && (getTriggerFocusTarget(triggerElement) ?? triggerElement)),\n );\n } else {\n setReference(target ?? triggerElement);\n }\n }, [contextAnchor, fromContext, target, triggerElement, setReference]);\n\n // After the commit that has the surface (and after a gesture while open): focus its first\n // tabbable element, else the surface itself (it then has `tabIndex={-1}`). A gesture whose open\n // was refused leaves nothing pending. No deps: every commit, since a gesture always renders.\n React.useLayoutEffect(() => {\n if (!focusContentRef.current) return;\n if (!open) {\n focusContentRef.current = false;\n return;\n }\n if (!surface) return;\n focusContentRef.current = false;\n focusElement(getFirstTabbable(surface) ?? surface, { preventScroll: true });\n });\n\n React.useEffect(() => {\n if (!openOnHover || !openOnContext) return;\n warnOnce(\n 'Popover:hover-and-context',\n 'Popover: `openOnHover` is ignored with `openOnContext`: a context popover opens on a right click, Shift+F10 or the ContextMenu key, not on hover.',\n );\n }, [openOnHover, openOnContext]);\n\n // Hover opening: a popover that hover opened closes by hover until a click on the trigger pins\n // it; focus inside the content (or a layer opened from it) keeps it open, focus on the trigger\n // does not.\n const hoverEnabled = openOnHover && !openOnContext;\n const canHoverClose = useEventCallback(\n () => reason === 'hover' && !isFocusInSurfaceTree(surfaceRef.current, layerId),\n );\n const {\n triggerHandlers: hoverTriggerHandlers,\n surfaceHandlers: hoverSurfaceHandlers,\n cancel: cancelHover,\n } = useHoverIntent({\n enabled: hoverEnabled,\n open,\n openDelay,\n closeDelay,\n trigger: triggerElement,\n surface,\n onOpen: () => {\n setHoverRequested(true);\n requestOpen(true);\n },\n onClose: () => {\n // Before the request: a parent may apply it synchronously (flushSync).\n hoverCloseRef.current = true;\n setOpen(false);\n },\n canClose: canHoverClose,\n });\n\n const onTriggerClick = useEventCallback(() => {\n cancelHover();\n if (open && reason === 'hover') setOpenReason('other');\n else requestOpen((current) => !current);\n });\n\n // The element the content follows in the keyboard order: in context mode the element focused\n // at the gesture when it lies inside the region, else the trigger, else a `target` element.\n // With neither (a VirtualElement target and no trigger) the content keeps the portal's place.\n const resolveTabAnchor = useEventCallback((): HTMLElement | null => {\n const trigger = triggerRef.current;\n const gestureOpener = openOnContext ? contextOpener.current : null;\n if (gestureOpener && trigger?.contains(gestureOpener)) return gestureOpener;\n return trigger ?? targetRef.current;\n });\n const tabAnchorRef = React.useMemo(() => createResolvedRef(resolveTabAnchor), [resolveTabAnchor]);\n\n // Keyboard order of the portaled content (it lives at the end of the document), as if it\n // followed the trigger like 0.4's inline content: Tab from the open trigger enters it (here, in\n // the trigger's own `onKeyDown`, which runs before a dialog's focus trap), Tab past its last\n // element continues after the trigger, Shift+Tab from its first element returns to the trigger\n // (the element inside a wrapper span), and Shift+Tab from the element after the trigger enters\n // it at its last element. The end of the page does not visit it a second time where its portal\n // is, and no Tab cycle forms (see usePopoverTabOrder). In a context region only Tab from the\n // element the content follows enters it; Tab on the region's other rows moves on as usual.\n const onTriggerKeyDown = useEventCallback((event: React.KeyboardEvent<HTMLElement>) => {\n if (event.key !== 'Tab' || event.shiftKey || !open) return;\n if (openOnContext) {\n const anchor = resolveTabAnchor();\n if (!anchor || event.target !== (getTriggerFocusTarget(anchor) ?? anchor)) return;\n }\n const surfaceElement = surfaceRef.current;\n const first = surfaceElement ? getFirstTabbable(surfaceElement) : null;\n if (!first) return;\n event.preventDefault();\n first.focus();\n });\n\n const onContentKeyDown = usePopoverTabOrder({\n enabled: open,\n surface,\n anchorRef: tabAnchorRef,\n // Shift+Tab from the content's first element returns to the trigger (the element in a span),\n // or, when nothing in the trigger can take focus, to the tab stop before it.\n getPreviousStop: getPopoverPreviousStop,\n });\n\n const keyboardContext = fromContext && contextOrigin === 'keyboard';\n const context = React.useMemo<PopoverContextValue>(\n () => ({\n open,\n setOpen: requestOpen,\n contentId,\n setCustomContentId,\n triggerId,\n resolvedTriggerId,\n setResolvedTriggerId,\n triggerRef,\n triggerElement,\n triggerElementRef,\n surfaceElementRef,\n arrowRef,\n onTriggerClick,\n onTriggerKeyDown,\n hoverTriggerHandlers: hoverEnabled ? hoverTriggerHandlers : null,\n hoverSurfaceHandlers: hoverEnabled ? hoverSurfaceHandlers : null,\n contextMode: openOnContext,\n contextTriggerHandlers: openOnContext ? contextTriggerHandlers : null,\n onContentContextMenu: contextSurfaceHandlers.onContextMenu,\n keyboardContext,\n onContentKeyDown,\n layerId,\n floatingProps,\n arrowStyles,\n placedSide,\n }),\n [\n open,\n requestOpen,\n contentId,\n triggerId,\n resolvedTriggerId,\n triggerElement,\n triggerElementRef,\n surfaceElementRef,\n onTriggerClick,\n onTriggerKeyDown,\n hoverEnabled,\n hoverTriggerHandlers,\n hoverSurfaceHandlers,\n openOnContext,\n contextTriggerHandlers,\n contextSurfaceHandlers,\n keyboardContext,\n onContentKeyDown,\n layerId,\n floatingProps,\n arrowStyles,\n placedSide,\n ],\n );\n\n return <PopoverContext.Provider value={context}>{children}</PopoverContext.Provider>;\n};\n\nPopoverRoot.displayName = 'Popover';\n\n/**\n * The element that toggles the popover. Its props are merged onto the single child (no wrapper\n * element): `aria-haspopup=\"dialog\"`, `aria-expanded`, `aria-controls` (while open), an `id` that\n * labels the content, a composed `onClick` and the ref used as positioning anchor and focus-return\n * target. The child's own `id`, handlers and classes are kept; the live state ARIA always wins.\n * A render function receives the props instead (spread all of them, `id` included: the content is\n * named by it); `asChild={false}` renders the 0.4 wrapper span, and a custom child that neither\n * forwards `ref` nor spreads its props falls back to that span automatically (with a development\n * warning). On the span, the state ARIA goes to the first element in the tab order inside it, and\n * focus returns to that element (to the span when you made it the trigger with a `role` such as\n * `button` and `tabIndex={0}`, or when nothing inside it can take focus).\n *\n * With `openOnHover` a mouse pointer resting on it opens the popover, and a click pins a\n * hover-opened popover instead of closing it. With `openOnContext` it is a context-menu region (a\n * list, a row, a canvas) instead of a button: it receives its `id` and the context-menu and key\n * handlers, but no state ARIA and no click toggle (a render function still receives every prop:\n * do not spread the state ARIA then).\n *\n * A Tooltip goes between the trigger and the button: it passes the trigger's `id` and ARIA on to\n * the button, which the Tooltip also describes.\n *\n * @example\n * <Popover.Trigger>\n * <Tooltip content=\"Narrow the list\">\n * <Button>Filters</Button>\n * </Tooltip>\n * </Popover.Trigger>\n *\n * Also exported as `PopoverTrigger` for React Server Components, which cannot use the dotted\n * `Popover.Trigger` (that needs a client file).\n */\nexport const PopoverTrigger = ({\n children,\n asChild,\n id: idProp,\n onClick,\n onKeyDown,\n onContextMenu,\n onPointerEnter,\n onPointerMove,\n onPointerLeave,\n ref,\n ...rest\n}: PopoverTriggerProps) => {\n const {\n open,\n contentId,\n triggerId,\n triggerElementRef,\n setResolvedTriggerId,\n onTriggerClick,\n onTriggerKeyDown,\n hoverTriggerHandlers: hover,\n contextMode,\n contextTriggerHandlers: gesture,\n } = usePopoverContext('Popover.Trigger');\n const elementRef = useMergedRefs<HTMLElement>(ref, triggerElementRef);\n\n // On a wrapper span (`asChild={false}`, the automatic fallback) useTriggerElement moves the\n // state ARIA onto the first element in the tab order inside it. The hover handlers are there\n // only with `openOnHover`, the context handlers only with `openOnContext`. A context region is\n // no popover button: it gets no state ARIA and no click toggle (useTriggerElement\n // `omitStateAria`), and a render-prop child reads a constant closed state.\n const triggerProps = {\n ...rest,\n id: idProp ?? triggerId,\n 'aria-haspopup': 'dialog' as const,\n 'aria-expanded': contextMode ? false : open,\n 'aria-controls': open && !contextMode ? contentId : undefined,\n onClick: composeEventHandlers(onClick, contextMode ? undefined : onTriggerClick),\n onKeyDown: composeEventHandlers(\n onKeyDown,\n gesture ? composeEventHandlers(gesture.onKeyDown, onTriggerKeyDown) : onTriggerKeyDown,\n ),\n onContextMenu: gesture\n ? composeEventHandlers(onContextMenu, gesture.onContextMenu)\n : onContextMenu,\n onPointerEnter: hover\n ? composeEventHandlers(onPointerEnter, hover.onPointerEnter)\n : onPointerEnter,\n onPointerMove: hover ? composeEventHandlers(onPointerMove, hover.onPointerMove) : onPointerMove,\n onPointerLeave: hover\n ? composeEventHandlers(onPointerLeave, hover.onPointerLeave)\n : onPointerLeave,\n ref: elementRef,\n } as PopoverTriggerChildProps;\n\n return useTriggerElement(children, triggerProps, {\n componentName: 'Popover.Trigger',\n asChild,\n onResolvedId: setResolvedTriggerId,\n omitStateAria: contextMode,\n });\n};\nPopoverTrigger.displayName = 'PopoverTrigger';\n\n/**\n * The popover surface: a non-modal `role=\"dialog\"` rendered in a portal (so overflow containers\n * never clip it) and positioned next to the trigger with a beak, flipping and shifting to stay in\n * the viewport. It closes on Escape and on a press outside (presses inside nested overlays opened\n * from it count as inside), and focus returns to the trigger when it closes while focus was inside.\n * In the keyboard order it follows the trigger, like inline content: Tab from the open trigger\n * enters it, Tab past its last element continues after the trigger, and Shift+Tab from the element\n * after the trigger enters it at its last element. Tab from the last element of the page moves\n * past it, and Shift+Tab from outside the page reaches the page's last element first, so a lap\n * visits it once. For a trigger outside the tab order (nothing in it can take focus, or\n * `tabIndex={-1}`), Tab from the tab stop before the trigger enters it, and Shift+Tab from its\n * first element returns to the trigger, or to that tab stop when nothing in the trigger can take\n * focus. With no tab stop before the trigger, the content is reached at the end of the page.\n * Named by `title`, `aria-label`/`aria-labelledby`, or else by its trigger: `aria-labelledby`\n * points at the id the trigger element carries in the document, or at the trigger's own label\n * elements when the trigger is named through `aria-labelledby` (an icon-only Button inside\n * `Tooltip relationship=\"label\"`); never at a missing id. A development warning names the problem\n * when the trigger has no id or no text. With `openOnContext` it is never named by the trigger (a\n * region's text is no name): pass `title`, `aria-label` or `aria-labelledby` (a development\n * warning otherwise). A consumer `id` is kept, and the trigger's `aria-controls` follows it. The\n * beak inherits the surface's background and border colors, so a `className` that changes them\n * restyles the beak too.\n *\n * With `openOnContext` it opens at the pointer of a right click, or at the focused row for\n * Shift+F10 and the ContextMenu key, and it follows that row in the keyboard order; with a\n * `target` it is placed at the target and, without a trigger, follows a target element in the\n * keyboard order.\n *\n * Also exported as `PopoverContent` for React Server Components, which cannot use the dotted\n * `Popover.Content` (that needs a client file).\n */\nexport const PopoverContent = ({\n children,\n title,\n id: idProp,\n className,\n style,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n onKeyDown,\n onContextMenu,\n onPointerEnter,\n onPointerLeave,\n ref,\n ...rest\n}: PopoverContentProps) => {\n const {\n open,\n contentId,\n setCustomContentId,\n resolvedTriggerId,\n triggerRef,\n triggerElement,\n surfaceElementRef,\n arrowRef,\n layerId,\n floatingProps,\n arrowStyles,\n placedSide,\n onContentKeyDown,\n hoverSurfaceHandlers: hover,\n contextMode,\n onContentContextMenu,\n keyboardContext,\n } = usePopoverContext('Popover.Content');\n const titleId = useId('popover-title');\n const elementRef = useMergedRefs<HTMLDivElement>(ref, surfaceElementRef);\n const hasTitle = slotRendersContent(title);\n const unnamed = ariaLabelledBy === undefined && !ariaLabel && !hasTitle;\n // A context region is no popover button, and its whole text is no name: in context mode the\n // content is never labelled by the trigger.\n const checkTrigger = open && unnamed && !contextMode;\n\n // The trigger's label ids in the document, re-read when the trigger's ids or labels change: a\n // Tooltip between Popover.Trigger and the Button leaves the Button's own id in place (and with\n // `relationship=\"label\"` names it through `aria-labelledby`), and a render-prop child may not\n // spread `id` at all — never point aria-labelledby at an id that is not there.\n const subscribeTrigger = React.useCallback(\n (onChange: () => void) => {\n if (!checkTrigger || !triggerElement || typeof MutationObserver === 'undefined') {\n return subscribeNothing();\n }\n const observer = new MutationObserver(onChange);\n observer.observe(triggerElement, {\n attributes: true,\n attributeFilter: ['id', 'aria-labelledby'],\n childList: true,\n subtree: true,\n });\n return () => observer.disconnect();\n },\n [checkTrigger, triggerElement],\n );\n const triggerLabelId = React.useSyncExternalStore(\n subscribeTrigger,\n () => (checkTrigger ? findTriggerLabelId(triggerElement, resolvedTriggerId) : undefined),\n () => (checkTrigger ? resolvedTriggerId : undefined),\n );\n\n const labelledBy =\n ariaLabelledBy ?? (ariaLabel ? undefined : hasTitle ? titleId : triggerLabelId);\n const customId = idProp || undefined;\n\n // Report the consumer's id to the root so the trigger's `aria-controls` points at it.\n React.useEffect(() => {\n setCustomContentId(customId);\n return () => setCustomContentId(undefined);\n }, [customId, setCustomContentId]);\n\n React.useEffect(() => {\n if (!open || !unnamed || !contextMode || !isDev) return;\n warnOnce(\n 'Popover.Content:name',\n 'Popover.Content: the popover has no accessible name. A context popover (openOnContext) is not named by its region: pass `title`, `aria-label` or `aria-labelledby`.',\n );\n }, [open, unnamed, contextMode]);\n\n React.useEffect(() => {\n if (!checkTrigger || !isDev) return;\n // Read after commit: a trigger's ref is attached by now even before it reported its id.\n const trigger = triggerRef.current;\n if (!trigger) {\n warnOnce(\n 'Popover.Content:name',\n 'Popover.Content: the popover has no accessible name. Pass `title`, `aria-label` or `aria-labelledby`, or open it from a Popover.Trigger.',\n );\n return;\n }\n const labelIds = findTriggerLabelId(trigger, resolvedTriggerId);\n if (!labelIds) {\n warnOnce(\n 'Popover.Content:trigger-id',\n 'Popover.Content: the popover is named by its trigger, but the trigger element has no `id` (a render-prop child of Popover.Trigger must spread the `id` it receives), so the popover has no accessible name. Spread every trigger prop onto the element, or pass `title`, `aria-label` or `aria-labelledby`.',\n );\n } else if (!referencesText(trigger.ownerDocument, labelIds)) {\n warnOnce(\n 'Popover.Content:trigger-name',\n 'Popover.Content: the popover is named by its trigger, but the trigger has no text to name it (an icon-only trigger needs `aria-label`, or `aria-labelledby` pointing at text), so the popover has no accessible name. Name the trigger, or pass `title`, `aria-label` or `aria-labelledby`.',\n );\n }\n }, [checkTrigger, resolvedTriggerId, triggerRef, triggerLabelId]);\n\n if (!open) return null;\n\n return (\n <Portal layerId={layerId}>\n <div\n role=\"dialog\"\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n tabIndex={keyboardContext ? -1 : undefined}\n {...rest}\n ref={elementRef}\n id={customId ?? contentId}\n data-side={floatingProps['data-side']}\n data-align={floatingProps['data-align']}\n style={{ ...style, ...floatingProps.style }}\n onKeyDown={composeEventHandlers(onKeyDown, onContentKeyDown)}\n onContextMenu={composeEventHandlers(onContextMenu, onContentContextMenu)}\n onPointerEnter={\n hover ? composeEventHandlers(onPointerEnter, hover.onPointerEnter) : onPointerEnter\n }\n onPointerLeave={\n hover ? composeEventHandlers(onPointerLeave, hover.onPointerLeave) : onPointerLeave\n }\n className={cn(\n popoverContentClassNames.root,\n 'w-64 rounded-md border border-border bg-background p-4 text-body-1 font-normal text-foreground normal-case tracking-normal text-start shadow-4',\n className,\n )}\n >\n <PopoverBeak\n ref={arrowRef}\n side={placedSide}\n style={arrowStyles}\n data-wave-popover-arrow=\"\"\n className={popoverContentClassNames.beak}\n />\n {hasTitle && (\n <h2\n id={titleId}\n className={cn(popoverContentClassNames.title, 'mb-2 text-subtitle-2 font-semibold')}\n >\n {title}\n </h2>\n )}\n {children}\n </div>\n </Portal>\n );\n};\nPopoverContent.displayName = 'PopoverContent';\n\n/**\n * A non-modal popup anchored to a trigger: `Popover.Trigger` (merges its props onto the child\n * button) and `Popover.Content` (portaled, positioned `role=\"dialog\"` surface). Use it for custom\n * popups such as filters or details; for a menu button use `Menu.Trigger` and `Menu.Popover`,\n * which add menu semantics and keyboard support.\n *\n * Controlled (`open`/`onOpenChange`) or uncontrolled (`defaultOpen`); `side`/`align` place the\n * content, and `ignoreOutsideRefs` lists external elements (such as a toggle button) whose presses\n * do not dismiss it.\n *\n * - **Hover cards:** `openOnHover` opens it when a mouse pointer rests on the trigger\n * (`openDelay`) and closes it once the pointer has left the trigger and the content\n * (`closeDelay`), unless focus is inside; a click on the trigger pins it.\n * - **Context popovers:** `openOnContext` makes the trigger a context-menu region: a right click\n * opens it at the pointer, Shift+F10 or the ContextMenu key at the focused row (with focus\n * moving into the content). Name the content with `title` or `aria-label`.\n * - **Custom anchors:** `target` places it at another element or at a `VirtualElement` (a point, a\n * text selection); with a controlled `open` it needs no trigger.\n *\n * @example\n * <Popover>\n * <Popover.Trigger><Button>Details</Button></Popover.Trigger>\n * <Popover.Content title=\"Details\">…</Popover.Content>\n * </Popover>\n */\nexport const Popover = /* @__PURE__ */ Object.assign(PopoverRoot, {\n Trigger: PopoverTrigger,\n Content: PopoverContent,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Popover.cjs","names":["React","getTriggerFocusTarget","getTabbableThrough","usePopupTarget","useControllable","useEventCallback","useIsClient","useId","usePopupPosition","resolvePositioning","isConnectedAndFocusable","useDismiss","useContextMenuAnchor","useTriggerFocusRef","useMergedRefs","getFirstTabbable","isFocusInSurfaceTree","useHoverIntent","usePopoverTabOrder","composeEventHandlers","useTriggerElement","slotRendersContent","isDev","_Fragment","cn","popoverContentClassNames","Portal","PopoverBeak","require_runtime","require_cn","require_dev","require_slot","require_composeEventHandlers","require_classNames","require_useEventCallback","require_useControllable","require_useId","require_focus","require_useMergedRefs","require_useIsClient","require_usePopupPosition","require_useDismiss","require_useRestoreFocus","require_Portal","require_useHoverIntent","require_Popover_shared","require_useTriggerElement","require_useResolvedTarget","require_useContextMenuAnchor","react","react_jsx_runtime","PopoverContext","inertContext","getInertContext","usePopoverContext","componentName","presentIds","present","ids","id","doc","findTriggerLabelId","trigger","resolvedId","named","referencesText","el","subscribeNothing","isElementTarget","target","createResolvedRef","resolve","getPopoverPreviousStop","anchor","surface","order","PopoverRoot","openProp","targetProp","targetPending","positioning","openState","setOpen","defaultOpen","onOpenChange","hoverCloseRef","requestOpen","next","isHoverClose","isClient","open","openReason","setOpenReason","hoverRequested","setHoverRequested","previousOpen","setPreviousOpen","reason","generatedContentId","customContentId","setCustomContentId","contentId","triggerId","resolvedTriggerId","setResolvedTriggerId","setSurface","triggerElement","setTriggerElement","triggerRef","surfaceRef","arrowRef","targetElement","targetRef","positionedProps","placedSide","floatingProps","contextOpenerRef","resolveFocusTarget","gestureOpener","openOnContext","triggerTarget","targetEl","focusTargetRef","isOutsidePress","event","ignoreOutsideRefs","focusContentRef","contextAnchor","contextOrigin","contextOpener","contextTriggerHandlers","contextSurfaceHandlers","origin","triggerFocusRef","triggerElementRef","surfaceElementRef","setFloating","setReference","fromContext","openOnHover","hoverEnabled","canHoverClose","layerId","hoverTriggerHandlers","hoverSurfaceHandlers","cancelHover","onTriggerClick","current","resolveTabAnchor","tabAnchorRef","onTriggerKeyDown","surfaceElement","first","onContentKeyDown","keyboardContext","context","arrowStyles","PopoverTrigger","idProp","rest","hover","gesture","elementRef","ref","triggerProps","contextMode","onClick","onKeyDown","onContextMenu","onPointerEnter","onPointerMove","onPointerLeave","children","PopoverContent","ariaLabel","ariaLabelledBy","titleId","hasTitle","title","unnamed","checkTrigger","subscribeTrigger","observer","onChange","triggerLabelId","labelledBy","customId","labelIds","titleAndChildren","style","onContentContextMenu","className","fitViewport","Popover"],"sources":["../../../src/components/overlays/Popover.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { popoverContentClassNames } from '../../lib/classNames';\nimport { isDev, reportMissingContext, warnOnce } from '../../lib/dev';\nimport { slotRendersContent } from '../../lib/slot';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { focusElement, getFirstTabbable, isConnectedAndFocusable } from '../../lib/focus';\nimport type {\n PopupAlign,\n PopupPositioning,\n PopupSide,\n PopupTarget,\n PopupTargetInput,\n} from '../../lib/types';\nimport { usePopupTarget } from '../../hooks/useResolvedTarget';\nimport { useId } from '../../hooks/useId';\nimport { useControllable, type SetValue } from '../../hooks/useControllable';\nimport { useContextMenuAnchor, type ContextMenuAnchor } from '../../hooks/useContextMenuAnchor';\nimport { useDismiss } from '../../hooks/useDismiss';\nimport { useHoverIntent, type HoverIntent } from '../../hooks/useHoverIntent';\nimport { useRestoreFocus } from '../../hooks/useRestoreFocus';\nimport { resolvePositioning, usePopupPosition } from '../../hooks/usePopupPosition';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport {\n getTriggerFocusTarget,\n useTriggerElement,\n useTriggerFocusRef,\n} from '../../hooks/useTriggerElement';\nimport { Portal } from '../portal/Portal';\nimport {\n getTabbableThrough,\n isFocusInSurfaceTree,\n PopoverBeak,\n usePopoverTabOrder,\n type PopoverPhysicalSide,\n} from './Popover.shared';\n\n/** Properties for the Popover component. */\nexport interface PopoverProps {\n /**\n * Controlled open state of the popover. The content renders only in the browser: an open\n * popover is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Default open state for uncontrolled usage. The content renders only in the browser: a\n * popover open by default is closed in the server HTML and opens once it has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Called with the requested open state when it differs from the current one: a trigger click,\n * Escape and an outside press; the hover opening and closing of `openOnHover`; and, with\n * `openOnContext`, a context gesture (a right click, a macOS Ctrl+click, Shift+F10 or the\n * ContextMenu key), a right click outside, and a scroll that moves the row it opened at.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Side of the trigger the content opens on. `start`/`end` follow the writing direction. The\n * content flips to the opposite side when there is not enough room.\n * @default 'bottom'\n */\n side?: PopupSide;\n /** Alignment of the content along the trigger's edge.\n * @default 'start'\n */\n align?: PopupAlign;\n /**\n * Elements outside the popover whose presses must not dismiss it, e.g. an external toggle\n * button that opens and closes the popover itself.\n */\n ignoreOutsideRefs?: ReadonlyArray<React.RefObject<HTMLElement | null>>;\n /**\n * Open the popover when a mouse pointer rests on its trigger (a hover card), and close it once\n * the pointer has been off the trigger and the content for `closeDelay` while focus is not\n * inside the content. A popover opened by hover does not take focus, and its hover close leaves\n * focus where it is; a click on its trigger keeps it open and keeps focus where it is (a second\n * click closes it, as without hover). After Escape or an outside press it does not reopen until\n * the pointer has left the trigger. Touch and pen never open it by hover, and an `aria-disabled`\n * trigger never opens. A triangle between the trigger and the content keeps it open while the\n * pointer moves diagonally into it. Ignored with `openOnContext` (development warning).\n * @default false\n */\n openOnHover?: boolean;\n /**\n * Milliseconds a hovering mouse pointer rests on the trigger before the popover opens (mouse\n * hover only).\n * @default 250\n */\n openDelay?: number;\n /**\n * Milliseconds before a hover-opened popover closes once the mouse pointer has left it and its\n * trigger (Fluent's `mouseLeaveDelay`; mouse hover only).\n * @default 500\n */\n closeDelay?: number;\n /**\n * Make `Popover.Trigger` a context-menu region (a list, a row, a canvas): a right click (a\n * Ctrl+click on macOS, a long press where the browser reports one) opens the popover at the\n * pointer and leaves focus where it is (Tab from that element enters the content), and\n * Shift+F10 or the ContextMenu key opens it at the focused element inside the region and moves\n * focus into the content, instead of a click. Focus returns to the element that had it. The\n * browser's context menu is suppressed there and inside the content, except in text fields\n * inside the region, which keep it. A press elsewhere, a right click outside or a scroll that\n * moves the row it opened at (the one under the pointer, or the focused one), as a scroll of\n * the region's own content does, closes it. The trigger gets no `aria-haspopup`/`aria-expanded`\n * (it is not a popover button; with a render-prop child, do not spread them): name the content\n * with `title`, `aria-label` or `aria-labelledby`, and consider `aria-keyshortcuts=\"Shift+F10\"`\n * on the region. iOS Safari reports no long press. `openOnHover` is ignored with it.\n * @default false\n */\n openOnContext?: boolean;\n /**\n * Where to place the content instead of next to `Popover.Trigger`: an element or a\n * `VirtualElement` (a rectangle, such as a point; an inline object is fine). With a controlled\n * `open`, a popover with a `target` needs no trigger; name it with `title`, `aria-label` or\n * `aria-labelledby`, and give a toggle button you use as the target `aria-haspopup=\"dialog\"`,\n * `aria-expanded` and `aria-controls` yourself. A press on a target element does not close the\n * popover, and Tab from it enters the content when there is no trigger. Hold the element in\n * state, or pass a ref object (read after each render of the popover, so an element that attaches without it rendering is noticed on its next render). A popover\n * opened by `openOnContext` is placed at the gesture instead.\n */\n target?: PopupTargetInput;\n /**\n * Advanced positioning (Fluent's `positioning`): `offset` (px from the anchor), `fitViewport`\n * (limit the content to the space the viewport leaves; Fluent's `autoSize`), `matchReferenceWidth`,\n * `fallbackPlacements` (tried in order when the requested side has no room) and `target` (used\n * when the `target` prop is not set). `side` and `align` stay separate props.\n * @default `{ offset: 8 }`\n */\n positioning?: PopupPositioning;\n /** `Popover.Trigger` and `Popover.Content`. */\n children: React.ReactNode;\n}\n\n/**\n * Props the trigger puts on its element; a render-prop child of `Popover.Trigger` receives them\n * (spread them onto the element that opens the popover). With `openOnContext` the element is a\n * context-menu region, not a popover button: do not spread `aria-haspopup`, `aria-expanded` and\n * `aria-controls` onto it (`aria-expanded` is then always `false`, `aria-controls` is absent and\n * `onClick` does nothing); spread ones are removed after each commit, with a development warning.\n */\nexport type PopoverTriggerChildProps = Omit<React.HTMLAttributes<HTMLElement>, 'children'> & {\n id: string;\n 'aria-haspopup': 'dialog';\n 'aria-expanded': boolean;\n /** The content's id, only while the popover is open (never with `openOnContext`). */\n 'aria-controls': string | undefined;\n onClick: React.MouseEventHandler<HTMLElement>;\n /**\n * Moves Tab from the open trigger into the portaled content (which lives at the end of the\n * document), so the keyboard order follows the trigger.\n */\n onKeyDown: React.KeyboardEventHandler<HTMLElement>;\n ref: React.RefCallback<HTMLElement>;\n};\n\n/** Properties for the PopoverTrigger sub-component. */\nexport interface PopoverTriggerProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that toggles the popover (its props are merged onto it), or a render function\n * that receives the trigger props.\n */\n children: React.ReactNode | ((props: PopoverTriggerChildProps) => React.ReactNode);\n /**\n * `false` renders the 0.4 wrapper `<span>` carrying the trigger props around the children\n * instead of merging them onto the child. `aria-haspopup`, `aria-expanded` and `aria-controls`,\n * which a generic element cannot carry, go to the first element in the tab order inside the\n * span. A render-prop child ignores `asChild` and receives every prop.\n * @default true\n */\n asChild?: boolean;\n /** Ref to the trigger element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\n/** Properties for the PopoverContent sub-component. */\nexport interface PopoverContentProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Content to render inside the popover. */\n children: React.ReactNode;\n /**\n * Visible heading rendered at the top of the popover; it names the dialog. Without `title`,\n * `aria-label` or `aria-labelledby`, the popover is labelled by its trigger, except with\n * `openOnContext` (a region's text is no name), where it needs one of them.\n */\n title?: React.ReactNode;\n /** Id of the surface; the trigger's `aria-controls` follows it. Defaults to a generated id. */\n id?: string;\n /** Ref to the popover surface. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\ninterface PopoverContextValue {\n open: boolean;\n setOpen: SetValue<boolean>;\n /** The content's id: the consumer's `Popover.Content` id when given, else a generated one. */\n contentId: string;\n /** `Popover.Content` reports the consumer's `id` so the trigger's `aria-controls` follows it. */\n setCustomContentId: (id: string | undefined) => void;\n triggerId: string;\n /** The id the trigger element ended up with (the child's own id wins). */\n resolvedTriggerId: string | undefined;\n setResolvedTriggerId: (id: string) => void;\n triggerRef: React.RefObject<HTMLElement | null>;\n /** The trigger element as state (read during render, e.g. to check the labelling id). */\n triggerElement: HTMLElement | null;\n /** Ref callback for the trigger element: focus-restore target and positioning anchor. */\n triggerElementRef: React.RefCallback<HTMLElement>;\n /** Ref callback for the surface: dismissal, focus restore and positioning. */\n surfaceElementRef: React.RefCallback<HTMLElement>;\n arrowRef: React.RefObject<HTMLDivElement | null>;\n /** The trigger's click: toggles the popover, or pins one that hover opened (keeps it open). */\n onTriggerClick: () => void;\n /** Tab from the open trigger enters the portaled content. */\n onTriggerKeyDown: React.KeyboardEventHandler<HTMLElement>;\n /** Hover opening (`openOnHover`): composed onto the trigger; `null` without it. */\n hoverTriggerHandlers: HoverIntent['triggerHandlers'] | null;\n /** Hover opening (`openOnHover`): composed onto the content; `null` without it. */\n hoverSurfaceHandlers: HoverIntent['surfaceHandlers'] | null;\n /** `openOnContext`: the trigger is a context-menu region, not a popover button. */\n contextMode: boolean;\n /** Context gestures (`openOnContext`): composed onto the trigger; `null` without it. */\n contextTriggerHandlers: ContextMenuAnchor['triggerHandlers'] | null;\n /** Composed onto the content: suppresses the browser's context menu there in context mode. */\n onContentContextMenu: React.MouseEventHandler<HTMLElement>;\n /** Opened by a keyboard context gesture: the content takes focus (itself when nothing can). */\n keyboardContext: boolean;\n /** Tab past the content's edges continues around the trigger in the page order. */\n onContentKeyDown: React.KeyboardEventHandler<HTMLElement>;\n layerId: string;\n floatingProps: { 'data-side': string; 'data-align': string; style: React.CSSProperties };\n arrowStyles: React.CSSProperties;\n placedSide: PopoverPhysicalSide;\n /** `positioning.fitViewport`: the content scrolls inside the border when it is limited. */\n fitViewport: boolean;\n}\n\nconst PopoverContext = React.createContext<PopoverContextValue | null>(null);\nPopoverContext.displayName = 'PopoverContext';\n\nlet inertContext: PopoverContextValue | null = null;\n\n/** Production fallback for a misplaced sub-component: a closed popover that does nothing. */\nfunction getInertContext(): PopoverContextValue {\n inertContext ??= {\n open: false,\n setOpen: () => {},\n contentId: 'wave-popover-inert-content',\n setCustomContentId: () => {},\n triggerId: 'wave-popover-inert-trigger',\n resolvedTriggerId: undefined,\n setResolvedTriggerId: () => {},\n triggerRef: { current: null },\n triggerElement: null,\n triggerElementRef: () => {},\n surfaceElementRef: () => {},\n arrowRef: { current: null },\n onTriggerClick: () => {},\n onTriggerKeyDown: () => {},\n hoverTriggerHandlers: null,\n hoverSurfaceHandlers: null,\n contextMode: false,\n contextTriggerHandlers: null,\n onContentContextMenu: () => {},\n keyboardContext: false,\n onContentKeyDown: () => {},\n layerId: 'wave-popover-inert-layer',\n floatingProps: { 'data-side': 'bottom', 'data-align': 'start', style: {} },\n arrowStyles: {},\n placedSide: 'bottom',\n fitViewport: false,\n };\n return inertContext;\n}\n\nfunction usePopoverContext(componentName: string): PopoverContextValue {\n const context = React.useContext(PopoverContext);\n if (context) return context;\n reportMissingContext(componentName, 'Popover');\n return getInertContext();\n}\n\n/** The ids of an id list that exist in `doc`, joined; `undefined` when none does. */\nfunction presentIds(doc: Document, ids: string | null): string | undefined {\n const present = (ids ?? '').split(/\\s+/).filter((id) => id && doc.getElementById(id));\n return present.length > 0 ? present.join(' ') : undefined;\n}\n\n/**\n * The ids `Popover.Content`'s default `aria-labelledby` points at, so the popover gets its\n * trigger's name. The named element is the one with the resolved id when the document has it,\n * otherwise the trigger's focus target (for example the Button inside a Tooltip that sits between\n * `Popover.Trigger` and the Button, whose own id wins), else the trigger element. When that\n * element is itself named through `aria-labelledby` (an icon-only Button inside\n * `Tooltip relationship=\"label\"`, or a button labelled by a visible label), its label ids are\n * returned: a name computation does not follow a second `aria-labelledby` hop, so pointing at the\n * button would leave the popover unnamed. Otherwise the element's id, else the trigger's own.\n * `undefined` when none of them has an id (a render-prop child that does not spread `id`), so the\n * reference never dangles; only ids present in the document are returned. Before the trigger\n * element is known, the resolved id.\n */\nfunction findTriggerLabelId(\n trigger: HTMLElement | null,\n resolvedId: string | undefined,\n): string | undefined {\n if (!trigger) return resolvedId;\n const doc = trigger.ownerDocument;\n const named =\n (resolvedId ? doc.getElementById(resolvedId) : null) ??\n getTriggerFocusTarget(trigger) ??\n trigger;\n return (\n presentIds(doc, named.getAttribute('aria-labelledby')) ?? (named.id || trigger.id || undefined)\n );\n}\n\n/**\n * Whether one of the elements an id list references has text for a name: its own `aria-label`\n * or text, or a descendant's `aria-label`, `alt` or `title`. Deliberately lenient (it only drives\n * a development warning): content that assistive technology ignores still counts as text.\n */\nfunction referencesText(doc: Document, ids: string): boolean {\n return ids.split(/\\s+/).some((id) => {\n const el = id ? doc.getElementById(id) : null;\n if (!el) return false;\n if (el.getAttribute('aria-label')?.trim() || el.textContent?.trim()) return true;\n return !!el.querySelector(\n '[aria-label]:not([aria-label=\"\"]), [alt]:not([alt=\"\"]), [title]:not([title=\"\"])',\n );\n });\n}\n\nconst subscribeNothing = (): (() => void) => () => {};\n\n/** Why an open popover opened: hover (it closes by hover), or anything else (it is pinned). */\ntype OpenReason = 'hover' | 'other';\n\n/** Whether a `target` is an element rather than a VirtualElement (duck typed, any realm). */\nfunction isElementTarget(target: PopupTarget | undefined): target is HTMLElement {\n return !!target && typeof (target as Partial<Node>).nodeType === 'number';\n}\n\n/** A read-only ref whose `current` is `resolve()` at the time it is read (event time). */\nfunction createResolvedRef(resolve: () => HTMLElement | null): React.RefObject<HTMLElement | null> {\n return {\n get current() {\n return resolve();\n },\n };\n}\n\n/**\n * The content's previous stop: the focus target of the element it follows (the trigger, the row of\n * a context gesture, a `target` element), else the tab stop before that element.\n */\nfunction getPopoverPreviousStop(\n anchor: HTMLElement,\n surface: HTMLElement,\n order?: readonly HTMLElement[],\n): HTMLElement | null {\n return getTriggerFocusTarget(anchor) ?? getTabbableThrough(anchor, surface, order);\n}\n\n// A const arrow (like DialogRoot and DrawerRoot): its type can be named in consumers' declaration\n// files, e.g. a story's `satisfies Meta<typeof Popover>` (a function declaration's `typeof` cannot,\n// TS4023).\nconst PopoverRoot = ({\n open: openProp,\n defaultOpen,\n onOpenChange,\n side = 'bottom',\n align = 'start',\n ignoreOutsideRefs,\n openOnHover = false,\n openDelay = 250,\n closeDelay = 500,\n openOnContext = false,\n target: targetProp,\n positioning,\n children,\n}: PopoverProps) => {\n const { target, pending: targetPending } = usePopupTarget('Popover', targetProp, positioning);\n const [openState, setOpen] = useControllable(openProp, defaultOpen ?? false, onOpenChange);\n // A hover close in flight (written in handlers, read when the popover closes): set when the hover\n // intent asks to close, so that close moves no focus even when a controlled parent applies it in\n // a later render (a transition). Every other request to open or close forgets it, and so does\n // the next opening.\n const hoverCloseRef = React.useRef(false);\n const requestOpen = useEventCallback<SetValue<boolean>>((next) => {\n hoverCloseRef.current = false;\n setOpen(next);\n });\n const isHoverClose = React.useCallback(() => hoverCloseRef.current, []);\n // The content lives in a portal, which renders only in the browser: until then (the server\n // HTML, hydration) the popover reports itself closed, so the trigger's aria-expanded and\n // aria-controls never describe content that is not there.\n const isClient = useIsClient();\n const open = openState && isClient;\n\n // Why the popover opened, decided when it opens (C-HOOKS: a previous-value state): `hover` when\n // hover asked for that open (a request consumed by the next render, so an open that a\n // controlled parent refused does not linger), else `other` (click, keys, a context gesture, a\n // controlled open).\n const [openReason, setOpenReason] = React.useState<OpenReason>('other');\n const [hoverRequested, setHoverRequested] = React.useState(false);\n const [previousOpen, setPreviousOpen] = React.useState(open);\n let reason = openReason;\n if (open !== previousOpen) {\n setPreviousOpen(open);\n if (open) reason = hoverRequested ? 'hover' : 'other';\n }\n if (reason !== openReason) setOpenReason(reason);\n if (hoverRequested) setHoverRequested(false);\n\n const generatedContentId = useId('popover-content');\n const [customContentId, setCustomContentId] = React.useState<string | undefined>(undefined);\n const contentId = customContentId ?? generatedContentId;\n const triggerId = useId('popover-trigger');\n const [resolvedTriggerId, setResolvedTriggerId] = React.useState<string | undefined>(undefined);\n const [surface, setSurface] = React.useState<HTMLElement | null>(null);\n const [triggerElement, setTriggerElement] = React.useState<HTMLElement | null>(null);\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const surfaceRef = React.useRef<HTMLElement | null>(null);\n const arrowRef = React.useRef<HTMLDivElement | null>(null);\n // A `target` element (not a VirtualElement) belongs to the dismiss layer, anchors the keyboard\n // order without a trigger and can take focus back.\n const targetElement = isElementTarget(target) ? target : null;\n const targetRef = React.useRef<HTMLElement | null>(null);\n React.useInsertionEffect(() => {\n targetRef.current = targetElement;\n }, [targetElement]);\n\n // Destructured: react-hooks/refs treats an object whose member is passed to `ref` as a ref.\n const {\n setReference,\n setFloating,\n floatingProps: positionedProps,\n arrowStyles,\n side: placedSide,\n } = usePopupPosition({\n open,\n side,\n align,\n arrowRef,\n ...resolvePositioning(positioning, { offset: 8 }),\n });\n // A ref target that holds no element yet keeps the popup hidden (as TeachingPopover's is).\n const floatingProps = React.useMemo(\n () =>\n targetPending\n ? { ...positionedProps, style: { ...positionedProps.style, visibility: 'hidden' as const } }\n : positionedProps,\n [targetPending, positionedProps],\n );\n\n // The one focus resolver: the focus-return fallback and the layer's anchor (where a surface\n // opened from the content restores focus once its opener is gone). In context mode the element\n // focused at the gesture (the row) first; then the trigger's focus target (for a wrapper span,\n // the element inside it that carries the state ARIA), a focusable `target` element, and the\n // trigger itself. The context hook's opener ref is stable; it is filled in once the hook runs.\n const contextOpenerRef = React.useRef<React.RefObject<HTMLElement | null> | null>(null);\n const resolveFocusTarget = useEventCallback((): HTMLElement | null => {\n const gestureOpener = openOnContext ? contextOpenerRef.current?.current : null;\n if (gestureOpener && isConnectedAndFocusable(gestureOpener)) return gestureOpener;\n const trigger = triggerRef.current;\n const triggerTarget = trigger ? getTriggerFocusTarget(trigger) : null;\n if (triggerTarget) return triggerTarget;\n const targetEl = targetRef.current;\n if (targetEl && isConnectedAndFocusable(targetEl)) return targetEl;\n return trigger;\n });\n const focusTargetRef = React.useMemo(\n () => createResolvedRef(resolveFocusTarget),\n [resolveFocusTarget],\n );\n\n // In context mode the region is no part of the layer: a primary press elsewhere in it closes the\n // popover like any outside press. A Ctrl+press inside it is a macOS context click, whose\n // `contextmenu` moves the popover instead.\n const isOutsidePress = useEventCallback(\n (event: PointerEvent | MouseEvent) =>\n !(event.ctrlKey && triggerRef.current?.contains(event.target as Node)),\n );\n const { layerId } = useDismiss({\n open,\n onDismiss: () => requestOpen(false),\n refs: openOnContext\n ? [surfaceRef, targetRef, ...(ignoreOutsideRefs ?? [])]\n : [surfaceRef, triggerRef, targetRef, ...(ignoreOutsideRefs ?? [])],\n anchorRef: focusTargetRef,\n kind: 'popover',\n outsidePress: openOnContext ? isOutsidePress : true,\n });\n\n // A keyboard context gesture moves focus into the content, once it is there (see below).\n const focusContentRef = React.useRef(false);\n const {\n anchor: contextAnchor,\n fromContext,\n origin: contextOrigin,\n opener: contextOpener,\n triggerHandlers: contextTriggerHandlers,\n surfaceHandlers: contextSurfaceHandlers,\n } = useContextMenuAnchor({\n enabled: openOnContext,\n open,\n trigger: triggerElement,\n layerId,\n onOpen: (origin) => {\n focusContentRef.current = origin === 'keyboard';\n requestOpen(true);\n },\n onClose: () => requestOpen(false),\n });\n React.useInsertionEffect(() => {\n contextOpenerRef.current = contextOpener;\n }, [contextOpener]);\n\n // Focus returns to the element that takes focus for the trigger, as Shift+Tab from the content\n // does, when the popover closes while focus is inside it or on `<body>`; a hover close restores\n // only focus inside, so it never moves focus. In context mode it returns to the element focused\n // at the gesture (the row): the region is no restore target of its own (as `triggerRef` it\n // would be taken for the opener).\n const triggerFocusRef = useTriggerFocusRef(triggerRef);\n useRestoreFocus({\n enabled: open,\n container: surface,\n triggerRef: openOnContext ? undefined : triggerFocusRef,\n finalFocusRef: openOnContext ? contextOpener : undefined,\n fallback: resolveFocusTarget,\n onlyIfFocusInside: true,\n isHoverClose,\n });\n React.useLayoutEffect(() => {\n if (open) hoverCloseRef.current = false;\n }, [open]);\n\n const triggerElementRef = useMergedRefs<HTMLElement>(triggerRef, setTriggerElement);\n const surfaceElementRef = useMergedRefs<HTMLElement>(surfaceRef, setSurface, setFloating);\n\n // The positioning anchor: the context gesture (the pointer, or the focused row, else the\n // trigger's focus target, else the trigger) while the popover was opened by one, else `target`,\n // else the trigger. A new VirtualElement on every render repositions without a render loop.\n React.useLayoutEffect(() => {\n if (fromContext) {\n setReference(\n contextAnchor ??\n (triggerElement && (getTriggerFocusTarget(triggerElement) ?? triggerElement)),\n );\n } else {\n setReference(target ?? triggerElement);\n }\n }, [contextAnchor, fromContext, target, triggerElement, setReference]);\n\n // After the commit that has the surface (and after a gesture while open): focus its first\n // tabbable element, else the surface itself (it then has `tabIndex={-1}`). A gesture whose open\n // was refused leaves nothing pending. No deps: every commit, since a gesture always renders.\n React.useLayoutEffect(() => {\n if (!focusContentRef.current) return;\n if (!open) {\n focusContentRef.current = false;\n return;\n }\n if (!surface) return;\n focusContentRef.current = false;\n focusElement(getFirstTabbable(surface) ?? surface, { preventScroll: true });\n });\n\n React.useEffect(() => {\n if (!openOnHover || !openOnContext) return;\n warnOnce(\n 'Popover:hover-and-context',\n 'Popover: `openOnHover` is ignored with `openOnContext`: a context popover opens on a right click, Shift+F10 or the ContextMenu key, not on hover.',\n );\n }, [openOnHover, openOnContext]);\n\n // Hover opening: a popover that hover opened closes by hover until a click on the trigger pins\n // it; focus inside the content (or a layer opened from it) keeps it open, focus on the trigger\n // does not.\n const hoverEnabled = openOnHover && !openOnContext;\n const canHoverClose = useEventCallback(\n () => reason === 'hover' && !isFocusInSurfaceTree(surfaceRef.current, layerId),\n );\n const {\n triggerHandlers: hoverTriggerHandlers,\n surfaceHandlers: hoverSurfaceHandlers,\n cancel: cancelHover,\n } = useHoverIntent({\n enabled: hoverEnabled,\n open,\n openDelay,\n closeDelay,\n trigger: triggerElement,\n surface,\n onOpen: () => {\n setHoverRequested(true);\n requestOpen(true);\n },\n onClose: () => {\n // Before the request: a parent may apply it synchronously (flushSync).\n hoverCloseRef.current = true;\n setOpen(false);\n },\n canClose: canHoverClose,\n });\n\n const onTriggerClick = useEventCallback(() => {\n cancelHover();\n if (open && reason === 'hover') setOpenReason('other');\n else requestOpen((current) => !current);\n });\n\n // The element the content follows in the keyboard order: in context mode the element focused\n // at the gesture when it lies inside the region, else the trigger, else a `target` element.\n // With neither (a VirtualElement target and no trigger) the content keeps the portal's place.\n const resolveTabAnchor = useEventCallback((): HTMLElement | null => {\n const trigger = triggerRef.current;\n const gestureOpener = openOnContext ? contextOpener.current : null;\n if (gestureOpener && trigger?.contains(gestureOpener)) return gestureOpener;\n return trigger ?? targetRef.current;\n });\n const tabAnchorRef = React.useMemo(() => createResolvedRef(resolveTabAnchor), [resolveTabAnchor]);\n\n // Keyboard order of the portaled content (it lives at the end of the document), as if it\n // followed the trigger like 0.4's inline content: Tab from the open trigger enters it (here, in\n // the trigger's own `onKeyDown`, which runs before a dialog's focus trap), Tab past its last\n // element continues after the trigger, Shift+Tab from its first element returns to the trigger\n // (the element inside a wrapper span), and Shift+Tab from the element after the trigger enters\n // it at its last element. The end of the page does not visit it a second time where its portal\n // is, and no Tab cycle forms (see usePopoverTabOrder). In a context region only Tab from the\n // element the content follows enters it; Tab on the region's other rows moves on as usual.\n const onTriggerKeyDown = useEventCallback((event: React.KeyboardEvent<HTMLElement>) => {\n if (event.key !== 'Tab' || event.shiftKey || !open) return;\n if (openOnContext) {\n const anchor = resolveTabAnchor();\n if (!anchor || event.target !== (getTriggerFocusTarget(anchor) ?? anchor)) return;\n }\n const surfaceElement = surfaceRef.current;\n const first = surfaceElement ? getFirstTabbable(surfaceElement) : null;\n if (!first) return;\n event.preventDefault();\n first.focus();\n });\n\n const onContentKeyDown = usePopoverTabOrder({\n enabled: open,\n surface,\n anchorRef: tabAnchorRef,\n // Shift+Tab from the content's first element returns to the trigger (the element in a span),\n // or, when nothing in the trigger can take focus, to the tab stop before it.\n getPreviousStop: getPopoverPreviousStop,\n });\n\n const keyboardContext = fromContext && contextOrigin === 'keyboard';\n const context = React.useMemo<PopoverContextValue>(\n () => ({\n open,\n setOpen: requestOpen,\n contentId,\n setCustomContentId,\n triggerId,\n resolvedTriggerId,\n setResolvedTriggerId,\n triggerRef,\n triggerElement,\n triggerElementRef,\n surfaceElementRef,\n arrowRef,\n onTriggerClick,\n onTriggerKeyDown,\n hoverTriggerHandlers: hoverEnabled ? hoverTriggerHandlers : null,\n hoverSurfaceHandlers: hoverEnabled ? hoverSurfaceHandlers : null,\n contextMode: openOnContext,\n contextTriggerHandlers: openOnContext ? contextTriggerHandlers : null,\n onContentContextMenu: contextSurfaceHandlers.onContextMenu,\n keyboardContext,\n onContentKeyDown,\n layerId,\n floatingProps,\n arrowStyles,\n placedSide,\n fitViewport: positioning?.fitViewport === true,\n }),\n [\n open,\n requestOpen,\n contentId,\n triggerId,\n resolvedTriggerId,\n triggerElement,\n triggerElementRef,\n surfaceElementRef,\n onTriggerClick,\n onTriggerKeyDown,\n hoverEnabled,\n hoverTriggerHandlers,\n hoverSurfaceHandlers,\n openOnContext,\n contextTriggerHandlers,\n contextSurfaceHandlers,\n keyboardContext,\n onContentKeyDown,\n layerId,\n floatingProps,\n arrowStyles,\n placedSide,\n positioning?.fitViewport,\n ],\n );\n\n return <PopoverContext.Provider value={context}>{children}</PopoverContext.Provider>;\n};\n\nPopoverRoot.displayName = 'Popover';\n\n/**\n * The element that toggles the popover. Its props are merged onto the single child (no wrapper\n * element): `aria-haspopup=\"dialog\"`, `aria-expanded`, `aria-controls` (while open), an `id` that\n * labels the content, a composed `onClick` and the ref used as positioning anchor and focus-return\n * target. The child's own `id`, handlers and classes are kept; the live state ARIA always wins.\n * A render function receives the props instead (spread all of them, `id` included: the content is\n * named by it); `asChild={false}` renders the 0.4 wrapper span, and a custom child that neither\n * forwards `ref` nor spreads its props falls back to that span automatically (with a development\n * warning). On the span, the state ARIA goes to the first element in the tab order inside it, and\n * focus returns to that element (to the span when you made it the trigger with a `role` such as\n * `button` and `tabIndex={0}`, or when nothing inside it can take focus).\n *\n * With `openOnHover` a mouse pointer resting on it opens the popover, and a click pins a\n * hover-opened popover instead of closing it. With `openOnContext` it is a context-menu region (a\n * list, a row, a canvas) instead of a button: it receives its `id` and the context-menu and key\n * handlers, but no state ARIA and no click toggle (a render function still receives every prop:\n * do not spread the state ARIA then).\n *\n * A Tooltip goes between the trigger and the button: it passes the trigger's `id` and ARIA on to\n * the button, which the Tooltip also describes.\n *\n * @example\n * <Popover.Trigger>\n * <Tooltip content=\"Narrow the list\">\n * <Button>Filters</Button>\n * </Tooltip>\n * </Popover.Trigger>\n *\n * Also exported as `PopoverTrigger` for React Server Components, which cannot use the dotted\n * `Popover.Trigger` (that needs a client file).\n */\nexport const PopoverTrigger = ({\n children,\n asChild,\n id: idProp,\n onClick,\n onKeyDown,\n onContextMenu,\n onPointerEnter,\n onPointerMove,\n onPointerLeave,\n ref,\n ...rest\n}: PopoverTriggerProps) => {\n const {\n open,\n contentId,\n triggerId,\n triggerElementRef,\n setResolvedTriggerId,\n onTriggerClick,\n onTriggerKeyDown,\n hoverTriggerHandlers: hover,\n contextMode,\n contextTriggerHandlers: gesture,\n } = usePopoverContext('Popover.Trigger');\n const elementRef = useMergedRefs<HTMLElement>(ref, triggerElementRef);\n\n // On a wrapper span (`asChild={false}`, the automatic fallback) useTriggerElement moves the\n // state ARIA onto the first element in the tab order inside it. The hover handlers are there\n // only with `openOnHover`, the context handlers only with `openOnContext`. A context region is\n // no popover button: it gets no state ARIA and no click toggle (useTriggerElement\n // `omitStateAria`), and a render-prop child reads a constant closed state.\n const triggerProps = {\n ...rest,\n id: idProp ?? triggerId,\n 'aria-haspopup': 'dialog' as const,\n 'aria-expanded': contextMode ? false : open,\n 'aria-controls': open && !contextMode ? contentId : undefined,\n onClick: composeEventHandlers(onClick, contextMode ? undefined : onTriggerClick),\n onKeyDown: composeEventHandlers(\n onKeyDown,\n gesture ? composeEventHandlers(gesture.onKeyDown, onTriggerKeyDown) : onTriggerKeyDown,\n ),\n onContextMenu: gesture\n ? composeEventHandlers(onContextMenu, gesture.onContextMenu)\n : onContextMenu,\n onPointerEnter: hover\n ? composeEventHandlers(onPointerEnter, hover.onPointerEnter)\n : onPointerEnter,\n onPointerMove: hover ? composeEventHandlers(onPointerMove, hover.onPointerMove) : onPointerMove,\n onPointerLeave: hover\n ? composeEventHandlers(onPointerLeave, hover.onPointerLeave)\n : onPointerLeave,\n ref: elementRef,\n } as PopoverTriggerChildProps;\n\n return useTriggerElement(children, triggerProps, {\n componentName: 'Popover.Trigger',\n asChild,\n onResolvedId: setResolvedTriggerId,\n omitStateAria: contextMode,\n });\n};\nPopoverTrigger.displayName = 'PopoverTrigger';\n\n/**\n * The popover surface: a non-modal `role=\"dialog\"` rendered in a portal (so overflow containers\n * never clip it) and positioned next to the trigger with a beak, flipping and shifting to stay in\n * the viewport. It closes on Escape and on a press outside (presses inside nested overlays opened\n * from it count as inside), and focus returns to the trigger when it closes while focus was inside.\n * In the keyboard order it follows the trigger, like inline content: Tab from the open trigger\n * enters it, Tab past its last element continues after the trigger, and Shift+Tab from the element\n * after the trigger enters it at its last element. Tab from the last element of the page moves\n * past it, and Shift+Tab from outside the page reaches the page's last element first, so a lap\n * visits it once. For a trigger outside the tab order (nothing in it can take focus, or\n * `tabIndex={-1}`), Tab from the tab stop before the trigger enters it, and Shift+Tab from its\n * first element returns to the trigger, or to that tab stop when nothing in the trigger can take\n * focus. With no tab stop before the trigger, the content is reached at the end of the page.\n * Named by `title`, `aria-label`/`aria-labelledby`, or else by its trigger: `aria-labelledby`\n * points at the id the trigger element carries in the document, or at the trigger's own label\n * elements when the trigger is named through `aria-labelledby` (an icon-only Button inside\n * `Tooltip relationship=\"label\"`); never at a missing id. A development warning names the problem\n * when the trigger has no id or no text. With `openOnContext` it is never named by the trigger (a\n * region's text is no name): pass `title`, `aria-label` or `aria-labelledby` (a development\n * warning otherwise). A consumer `id` is kept, and the trigger's `aria-controls` follows it. The\n * beak inherits the surface's background and border colors, so a `className` that changes them\n * restyles the beak too.\n *\n * With `openOnContext` it opens at the pointer of a right click, or at the focused row for\n * Shift+F10 and the ContextMenu key, and it follows that row in the keyboard order; with a\n * `target` it is placed at the target and, without a trigger, follows a target element in the\n * keyboard order.\n *\n * Also exported as `PopoverContent` for React Server Components, which cannot use the dotted\n * `Popover.Content` (that needs a client file).\n */\nexport const PopoverContent = ({\n children,\n title,\n id: idProp,\n className,\n style,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n onKeyDown,\n onContextMenu,\n onPointerEnter,\n onPointerLeave,\n ref,\n ...rest\n}: PopoverContentProps) => {\n const {\n open,\n contentId,\n setCustomContentId,\n resolvedTriggerId,\n triggerRef,\n triggerElement,\n surfaceElementRef,\n arrowRef,\n layerId,\n floatingProps,\n arrowStyles,\n placedSide,\n fitViewport,\n onContentKeyDown,\n hoverSurfaceHandlers: hover,\n contextMode,\n onContentContextMenu,\n keyboardContext,\n } = usePopoverContext('Popover.Content');\n const titleId = useId('popover-title');\n const elementRef = useMergedRefs<HTMLDivElement>(ref, surfaceElementRef);\n const hasTitle = slotRendersContent(title);\n const unnamed = ariaLabelledBy === undefined && !ariaLabel && !hasTitle;\n // A context region is no popover button, and its whole text is no name: in context mode the\n // content is never labelled by the trigger.\n const checkTrigger = open && unnamed && !contextMode;\n\n // The trigger's label ids in the document, re-read when the trigger's ids or labels change: a\n // Tooltip between Popover.Trigger and the Button leaves the Button's own id in place (and with\n // `relationship=\"label\"` names it through `aria-labelledby`), and a render-prop child may not\n // spread `id` at all — never point aria-labelledby at an id that is not there.\n const subscribeTrigger = React.useCallback(\n (onChange: () => void) => {\n if (!checkTrigger || !triggerElement || typeof MutationObserver === 'undefined') {\n return subscribeNothing();\n }\n const observer = new MutationObserver(onChange);\n observer.observe(triggerElement, {\n attributes: true,\n attributeFilter: ['id', 'aria-labelledby'],\n childList: true,\n subtree: true,\n });\n return () => observer.disconnect();\n },\n [checkTrigger, triggerElement],\n );\n const triggerLabelId = React.useSyncExternalStore(\n subscribeTrigger,\n () => (checkTrigger ? findTriggerLabelId(triggerElement, resolvedTriggerId) : undefined),\n () => (checkTrigger ? resolvedTriggerId : undefined),\n );\n\n const labelledBy =\n ariaLabelledBy ?? (ariaLabel ? undefined : hasTitle ? titleId : triggerLabelId);\n const customId = idProp || undefined;\n\n // Report the consumer's id to the root so the trigger's `aria-controls` points at it.\n React.useEffect(() => {\n setCustomContentId(customId);\n return () => setCustomContentId(undefined);\n }, [customId, setCustomContentId]);\n\n React.useEffect(() => {\n if (!open || !unnamed || !contextMode || !isDev) return;\n warnOnce(\n 'Popover.Content:name',\n 'Popover.Content: the popover has no accessible name. A context popover (openOnContext) is not named by its region: pass `title`, `aria-label` or `aria-labelledby`.',\n );\n }, [open, unnamed, contextMode]);\n\n React.useEffect(() => {\n if (!checkTrigger || !isDev) return;\n // Read after commit: a trigger's ref is attached by now even before it reported its id.\n const trigger = triggerRef.current;\n if (!trigger) {\n warnOnce(\n 'Popover.Content:name',\n 'Popover.Content: the popover has no accessible name. Pass `title`, `aria-label` or `aria-labelledby`, or open it from a Popover.Trigger.',\n );\n return;\n }\n const labelIds = findTriggerLabelId(trigger, resolvedTriggerId);\n if (!labelIds) {\n warnOnce(\n 'Popover.Content:trigger-id',\n 'Popover.Content: the popover is named by its trigger, but the trigger element has no `id` (a render-prop child of Popover.Trigger must spread the `id` it receives), so the popover has no accessible name. Spread every trigger prop onto the element, or pass `title`, `aria-label` or `aria-labelledby`.',\n );\n } else if (!referencesText(trigger.ownerDocument, labelIds)) {\n warnOnce(\n 'Popover.Content:trigger-name',\n 'Popover.Content: the popover is named by its trigger, but the trigger has no text to name it (an icon-only trigger needs `aria-label`, or `aria-labelledby` pointing at text), so the popover has no accessible name. Name the trigger, or pass `title`, `aria-label` or `aria-labelledby`.',\n );\n }\n }, [checkTrigger, resolvedTriggerId, triggerRef, triggerLabelId]);\n\n if (!open) return null;\n\n const titleAndChildren = (\n <>\n {hasTitle && (\n <h2\n id={titleId}\n className={cn(popoverContentClassNames.title, 'mb-2 text-subtitle-2 font-semibold')}\n >\n {title}\n </h2>\n )}\n {children}\n </>\n );\n\n return (\n <Portal layerId={layerId}>\n <div\n role=\"dialog\"\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n tabIndex={keyboardContext ? -1 : undefined}\n {...rest}\n ref={elementRef}\n id={customId ?? contentId}\n data-side={floatingProps['data-side']}\n data-align={floatingProps['data-align']}\n style={{ ...style, ...floatingProps.style }}\n onKeyDown={composeEventHandlers(onKeyDown, onContentKeyDown)}\n onContextMenu={composeEventHandlers(onContextMenu, onContentContextMenu)}\n onPointerEnter={\n hover ? composeEventHandlers(onPointerEnter, hover.onPointerEnter) : onPointerEnter\n }\n onPointerLeave={\n hover ? composeEventHandlers(onPointerLeave, hover.onPointerLeave) : onPointerLeave\n }\n className={cn(\n popoverContentClassNames.root,\n 'w-64 rounded-md border border-border bg-background p-4 text-body-1 font-normal text-foreground normal-case tracking-normal text-start shadow-4',\n className,\n )}\n >\n <PopoverBeak\n ref={arrowRef}\n side={placedSide}\n style={arrowStyles}\n data-wave-popover-arrow=\"\"\n className={popoverContentClassNames.beak}\n />\n {fitViewport ? (\n // The beak sits half outside the border, so the scroller is inside it: the viewport\n // limit minus the content's padding (2 x 1rem) and border (2 x 1px).\n <div className=\"overflow-y-auto max-h-[calc(var(--wave-popup-available-height)-2rem-2px)]\">\n {titleAndChildren}\n </div>\n ) : (\n titleAndChildren\n )}\n </div>\n </Portal>\n );\n};\nPopoverContent.displayName = 'PopoverContent';\n\n/**\n * A non-modal popup anchored to a trigger: `Popover.Trigger` (merges its props onto the child\n * button) and `Popover.Content` (portaled, positioned `role=\"dialog\"` surface). Use it for custom\n * popups such as filters or details; for a menu button use `Menu.Trigger` and `Menu.Popover`,\n * which add menu semantics and keyboard support.\n *\n * Controlled (`open`/`onOpenChange`) or uncontrolled (`defaultOpen`); `side`/`align` place the\n * content, and `ignoreOutsideRefs` lists external elements (such as a toggle button) whose presses\n * do not dismiss it.\n *\n * - **Hover cards:** `openOnHover` opens it when a mouse pointer rests on the trigger\n * (`openDelay`) and closes it once the pointer has left the trigger and the content\n * (`closeDelay`), unless focus is inside; a click on the trigger pins it.\n * - **Context popovers:** `openOnContext` makes the trigger a context-menu region: a right click\n * opens it at the pointer, Shift+F10 or the ContextMenu key at the focused row (with focus\n * moving into the content). Name the content with `title` or `aria-label`.\n * - **Custom anchors:** `target` places it at another element or at a `VirtualElement` (a point, a\n * text selection); with a controlled `open` it needs no trigger.\n *\n * @example\n * <Popover>\n * <Popover.Trigger><Button>Details</Button></Popover.Trigger>\n * <Popover.Content title=\"Details\">…</Popover.Content>\n * </Popover>\n */\nexport const Popover = /* @__PURE__ */ Object.assign(PopoverRoot, {\n Trigger: PopoverTrigger,\n Content: PopoverContent,\n});\n"],"mappings":"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"}
|