{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "core-popover",
  "type": "registry:ui",
  "title": "Popover",
  "description": "Portable Base UI popovers with overridable collision avoidance, available-space sizing and document/fullscreen-aware portals.",
  "dependencies": [
    "@base-ui/react",
    "maruaudio@>=0.0.3 <0.1.0"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "components/ui/popover.tsx",
      "content": "/**\n * Source: https://maru.audio/ui-kit/popover\n * Copyright © [Maru](https://maru.audio)\n *\n * Maru UI Kit — https://maru.audio/ui-kit\n *\n * Installed from the Maru UI registry. This file is yours now: edit it\n * freely, it will not be overwritten unless you re-run the add command.\n *\n * Keep this item’s companion files and CSS imports together. Dependencies\n * declared by the registry are installed with the source.\n */\n\"use client\"\n\nimport {\n  type ComponentProps,\n  useCallback,\n  useImperativeHandle,\n  useRef,\n  useState,\n} from \"react\"\nimport { Popover as BasePopover } from \"@base-ui/react/popover\"\nimport { cn } from \"maruaudio/ui/shared/shadcn-utils\"\nimport {\n  OVERLAY_BAR_COLLISION_AVOIDANCE,\n  OVERLAY_POSITIONER_DEFAULTS,\n  OverlayOwnerProvider,\n  useFrameFocusDismiss,\n  useOverlayTriggerRef,\n  useOverlayPortalContainer,\n  mergeOverlayPopupStyle,\n} from \"maruaudio/ui/shared/overlay-container\"\nimport { UI_KIT_PORTABLE_STYLES } from \"maruaudio/ui/shared/portable-styles\"\n\nexport type PopoverRootProps<Payload = unknown> =\n  BasePopover.Root.Props<Payload> & {\n    /**\n     * Close when focus moves into an iframe of this document (a press inside a\n     * hosted face, an embed or a preview never reaches Base UI's outside-press\n     * listener). Reported to `onOpenChange` as an `\"outside-press\"` dismissal\n     * whose `event` is the window `blur` FocusEvent, and cancelable like any\n     * other. Paused while `suppressFrameDismiss` is held.\n     * @default true\n     */\n    dismissOnFrameFocus?: boolean\n  }\n\n/** The window-blur check applies outside-press semantics through Base UI's\n * own close path, so controlled roots see one `onOpenChange(false, …)` and can\n * cancel it, and uncontrolled roots close internally. */\nfunction frameDismissDetails(\n  details: BasePopover.Root.ChangeEventDetails,\n  event: FocusEvent\n): BasePopover.Root.ChangeEventDetails {\n  return {\n    reason: \"outside-press\",\n    // Base UI types outside-press events as pointer events; a frame focus has\n    // no pointer of its own, so consumers receive the window blur event.\n    event: event as unknown as MouseEvent,\n    trigger: details.trigger,\n    get isCanceled() {\n      return details.isCanceled\n    },\n    get isPropagationAllowed() {\n      return details.isPropagationAllowed\n    },\n    cancel: () => details.cancel(),\n    allowPropagation: () => details.allowPropagation(),\n    preventUnmountOnClose: () => details.preventUnmountOnClose(),\n  }\n}\n\nfunction Root<Payload = unknown>({\n  onOpenChange,\n  onOpenChangeComplete,\n  actionsRef,\n  dismissOnFrameFocus = true,\n  ...props\n}: PopoverRootProps<Payload>) {\n  const actions = useRef<BasePopover.Root.Actions | null>(null)\n  useImperativeHandle(\n    actionsRef,\n    () => ({\n      close: () => actions.current?.close(),\n      unmount: () => actions.current?.unmount(),\n    }),\n    []\n  )\n  // Uncontrolled roots: mirror Base UI's accepted open state so the frame\n  // listener only runs while the popup is actually open.\n  const [uncontrolledOpen, setUncontrolledOpen] = useState(\n    props.defaultOpen ?? false\n  )\n  const open = props.open ?? uncontrolledOpen\n  const pendingFrameDismiss = useRef<FocusEvent | null>(null)\n  const dismissFromFrame = useCallback((event: FocusEvent) => {\n    pendingFrameDismiss.current = event\n    try {\n      actions.current?.close()\n    } finally {\n      pendingFrameDismiss.current = null\n    }\n  }, [])\n  useFrameFocusDismiss({\n    open,\n    enabled: dismissOnFrameFocus,\n    onDismiss: dismissFromFrame,\n  })\n  return (\n    <OverlayOwnerProvider\n      triggerId={props.triggerId}\n      defaultTriggerId={props.defaultTriggerId}\n    >\n      {(register) => (\n        <BasePopover.Root\n          {...props}\n          actionsRef={actions}\n          onOpenChange={(nextOpen, details) => {\n            const frameEvent = nextOpen ? null : pendingFrameDismiss.current\n            onOpenChange?.(\n              nextOpen,\n              frameEvent ? frameDismissDetails(details, frameEvent) : details\n            )\n            if (details.isCanceled) return\n            setUncontrolledOpen(nextOpen)\n            if (nextOpen && details.trigger) register(details.trigger)\n          }}\n          onOpenChangeComplete={(nextOpen) => {\n            if (!nextOpen) setUncontrolledOpen(false)\n            onOpenChangeComplete?.(nextOpen)\n          }}\n        />\n      )}\n    </OverlayOwnerProvider>\n  )\n}\n\nfunction Trigger({\n  ref,\n  ...props\n}: ComponentProps<typeof BasePopover.Trigger>) {\n  const triggerRef = useOverlayTriggerRef(ref)\n  return <BasePopover.Trigger ref={triggerRef} {...props} />\n}\n\nfunction Portal({\n  container,\n  ...props\n}: ComponentProps<typeof BasePopover.Portal>) {\n  const target = useOverlayPortalContainer(container)\n  return <BasePopover.Portal {...props} container={target} />\n}\n\n/** Every native Positioner option remains available, including disabling\n * collisions or supplying an explicit boundary. Overrides win over defaults. */\nfunction Positioner(props: ComponentProps<typeof BasePopover.Positioner>) {\n  return <BasePopover.Positioner {...OVERLAY_POSITIONER_DEFAULTS} {...props} />\n}\n\nfunction Popup({\n  style,\n  children,\n  ...props\n}: ComponentProps<typeof BasePopover.Popup>) {\n  return (\n    <BasePopover.Popup {...props} style={mergeOverlayPopupStyle(style)}>\n      {children}\n    </BasePopover.Popup>\n  )\n}\n\n/** Portable compound parts for product faces; all other Base UI parts,\n * handles, refs, accessibility and lifecycle semantics remain Base UI-owned. */\nexport const PopoverParts = {\n  ...BasePopover,\n  Root,\n  Trigger,\n  Portal,\n  Positioner,\n  Popup,\n}\n\nexport const Popover = Root\nexport {\n  OVERLAY_BAR_COLLISION_AVOIDANCE,\n  OVERLAY_BAR_POSITIONER,\n  FRAME_DISMISS_IGNORE_ATTR,\n  suppressFrameDismiss,\n  useSuppressFrameDismiss,\n  isFrameDismissSuppressed,\n  type FrameDismissRelease,\n} from \"maruaudio/ui/shared/overlay-container\"\nexport const PopoverClose = BasePopover.Close\nexport function PopoverTrigger(\n  props: ComponentProps<typeof BasePopover.Trigger>\n) {\n  return <Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\n/** Collision presets for `PopoverContent`. `\"default\"` keeps the product\n * defaults (`OVERLAY_POSITIONER_DEFAULTS`: flip side, shift alignment). */\nexport type PopoverPlacement = \"default\" | \"bar\"\n\nexport type PopoverContentProps = ComponentProps<typeof BasePopover.Popup> &\n  Pick<\n    BasePopover.Positioner.Props,\n    | \"anchor\"\n    | \"align\"\n    | \"alignOffset\"\n    | \"side\"\n    | \"sideOffset\"\n    | \"collisionAvoidance\"\n    | \"collisionBoundary\"\n    | \"collisionPadding\"\n    | \"positionMethod\"\n    | \"sticky\"\n  > & {\n    /** Full Base UI positioning API, including tracking and refs. */\n    positionerProps?: Omit<\n      ComponentProps<typeof BasePopover.Positioner>,\n      \"children\"\n    >\n    portalProps?: Omit<ComponentProps<typeof BasePopover.Portal>, \"children\">\n    /**\n     * `\"bar\"` keeps the preferred side while open and only shifts along the\n     * anchor (`OVERLAY_BAR_COLLISION_AVOIDANCE`), for overlays anchored to a\n     * persistent bar. An explicit `collisionAvoidance` still wins.\n     * @default \"default\"\n     */\n    placement?: PopoverPlacement\n    /** Isolated faces need the portable stylesheet. Already styled app hosts\n     * can omit it so opening a popup never reskins unrelated page controls. */\n    portableStyles?: boolean\n  }\n\nexport function PopoverContent({\n  anchor,\n  align = \"end\",\n  alignOffset = 0,\n  side = \"bottom\",\n  sideOffset = 6,\n  collisionAvoidance,\n  collisionBoundary,\n  collisionPadding,\n  positionMethod,\n  sticky,\n  positionerProps,\n  portalProps,\n  placement = \"default\",\n  portableStyles = true,\n  className,\n  children,\n  ...props\n}: PopoverContentProps) {\n  const resolvedCollisionAvoidance =\n    collisionAvoidance ??\n    (placement === \"bar\" ? OVERLAY_BAR_COLLISION_AVOIDANCE : undefined)\n  const overrides = {\n    ...(resolvedCollisionAvoidance === undefined\n      ? {}\n      : { collisionAvoidance: resolvedCollisionAvoidance }),\n    ...(collisionPadding === undefined ? {} : { collisionPadding }),\n    ...(collisionBoundary === undefined ? {} : { collisionBoundary }),\n    ...(positionMethod === undefined ? {} : { positionMethod }),\n    ...(sticky === undefined ? {} : { sticky }),\n  }\n  return (\n    <Portal {...portalProps}>\n      <Positioner\n        className=\"isolate z-50 outline-none\"\n        style={{ zIndex: 50 }}\n        anchor={anchor}\n        align={align}\n        alignOffset={alignOffset}\n        side={side}\n        sideOffset={sideOffset}\n        {...overrides}\n        {...positionerProps}\n      >\n        <Popup\n          data-slot=\"popover-content\"\n          className={cn(\n            \"z-50 w-80 origin-(--transform-origin) rounded-lg bg-popover p-4 text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n            className\n          )}\n          {...props}\n        >\n          {portableStyles ? (\n            <style data-maru-ui-kit-portable>{UI_KIT_PORTABLE_STYLES}</style>\n          ) : null}\n          {children}\n        </Popup>\n      </Positioner>\n    </Portal>\n  )\n}\n\nexport function PopoverHeader({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"popover-header\"\n      className={cn(\"flex flex-col gap-0.5 text-sm\", className)}\n      {...props}\n    />\n  )\n}\nexport function PopoverTitle({\n  className,\n  ...props\n}: ComponentProps<typeof BasePopover.Title>) {\n  return (\n    <BasePopover.Title\n      data-slot=\"popover-title\"\n      className={cn(\"text-sm font-medium\", className)}\n      {...props}\n    />\n  )\n}\nexport function PopoverDescription({\n  className,\n  ...props\n}: ComponentProps<typeof BasePopover.Description>) {\n  return (\n    <BasePopover.Description\n      data-slot=\"popover-description\"\n      className={cn(\"text-xs text-muted-foreground\", className)}\n      {...props}\n    />\n  )\n}\n",
      "type": "registry:component",
      "target": "@ui/popover.tsx"
    }
  ]
}
