{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "popover",
  "title": "Popover",
  "description": "A panel that opens from its trigger's transform-origin with a 5px directional offset, closes at half the distance in 150ms, and reverses mid-flight. Its trigger presses by colour, never by scale.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "https://eased.dev/r/eased-tokens.json",
    "https://eased.dev/r/eased-floating.json",
    "https://eased.dev/r/button.json"
  ],
  "files": [
    {
      "path": "src/registry/eased/popover/popover.tsx",
      "content": "\"use client\";\n\nimport { Popover as BasePopover } from \"@base-ui/react/popover\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n  FloatingLayer,\n  floatingSurface,\n  type FloatingAlign,\n  type FloatingMotion,\n  type FloatingSide,\n} from \"../_primitives/floating/floating\";\nimport { Button, type ButtonSize, type ButtonVariant } from \"../button/button\";\n\n/**\n * Groups a popover's parts and owns its open state. Uncontrolled by default (`defaultOpen`);\n * pass `open` and `onOpenChange` to control it. Non-modal unless `modal` is set.\n */\nexport const Popover = BasePopover.Root;\n\n/** Closes the popover. Use `render` to make any button a closer: `<PopoverClose render={<button … />} />`. */\nexport const PopoverClose = BasePopover.Close;\n\nexport type PopoverTriggerProps = Omit<ComponentProps<typeof BasePopover.Trigger>, \"className\"> & {\n  /** The Eased `Button` variant. Default \"secondary\". */\n  variant?: ButtonVariant;\n  /** The Eased `Button` size. Default \"sm\" (32px); `icon-sm` for a square icon trigger. */\n  size?: ButtonSize;\n  className?: string;\n};\n\n/**\n * The button that opens the popover: an Eased `Button`, which never scales as a popup\n * trigger (R64) so the popup's transform-origin stays fixed, and stays pressed (`aria-expanded`)\n * while the popover is open. Pass `render` to bring your own trigger (style it with\n * `floatingTrigger`). `openOnHover`, `delay` and `closeDelay` turn it into a hover-intent trigger.\n */\nexport function PopoverTrigger({ variant = \"secondary\", size = \"sm\", className = \"\", render, ...props }: PopoverTriggerProps) {\n  return <BasePopover.Trigger {...props} render={render ?? <Button variant={variant} size={size} className={className} />} />;\n}\n\nexport type PopoverContentProps = {\n  /** Preferred side; flips on collision and the enter direction follows. Default \"bottom\". */\n  side?: FloatingSide;\n  /** Default \"center\". */\n  align?: FloatingAlign;\n  /** Gap to the trigger, px. Default 6. */\n  sideOffset?: number;\n  alignOffset?: number;\n  /** Override the floating motion (distance, scale, fade, exit). */\n  motion?: Partial<FloatingMotion>;\n  /** Where focus goes on open. Default: the first tabbable element, else the popup. */\n  initialFocus?: ComponentProps<typeof BasePopover.Popup>[\"initialFocus\"];\n  /** Where focus returns on close. Default: the trigger. */\n  finalFocus?: ComponentProps<typeof BasePopover.Popup>[\"finalFocus\"];\n  container?: HTMLElement | null;\n  /** Stacking order. Default 50; raise it inside a higher layer such as a dialog. */\n  zIndex?: number;\n  /** Appended to the panel's classes; set a width here (default `w-80`, never wider than the viewport). */\n  className?: string;\n  children?: ReactNode;\n};\n\n/**\n * The panel. It opens from the trigger's transform-origin with a 5px offset toward the\n * trigger, and leaves half as far in 150ms. Open and close are transitions, so they reverse\n * mid-flight. A raised 16px panel with 16px padding; `--radius-outer` and `--pad` are exposed so\n * nested corners (see `PopoverFooter`) stay concentric.\n */\nexport function PopoverContent({\n  side = \"bottom\",\n  align = \"center\",\n  sideOffset,\n  alignOffset,\n  motion,\n  initialFocus,\n  finalFocus,\n  container,\n  zIndex,\n  className = \"\",\n  children,\n}: PopoverContentProps) {\n  return (\n    <FloatingLayer\n      parts={BasePopover}\n      role=\"popover\"\n      side={side}\n      align={align}\n      sideOffset={sideOffset}\n      alignOffset={alignOffset}\n      motion={motion}\n      container={container}\n      zIndex={zIndex}\n      popupProps={{ initialFocus, finalFocus }}\n      className={`${floatingSurface} flex w-80 max-w-(--available-width) flex-col overflow-hidden rounded-panel p-4 [--pad:16px] [--radius-outer:var(--eased-radius-panel)] ${className}`}\n    >\n      {children}\n    </FloatingLayer>\n  );\n}\n\n/** The popover's heading; labels the dialog for assistive tech. */\nexport function PopoverTitle({ className = \"\", children }: { className?: string; children: ReactNode }) {\n  return <BasePopover.Title className={`text-ui font-medium text-balance text-text ${className}`}>{children}</BasePopover.Title>;\n}\n\n/** One line of supporting text under the title; describes the dialog for assistive tech. */\nexport function PopoverDescription({ className = \"\", children }: { className?: string; children: ReactNode }) {\n  return (\n    <BasePopover.Description className={`mt-1 text-ui-sm text-pretty text-text-secondary ${className}`}>{children}</BasePopover.Description>\n  );\n}\n\n/**\n * A full-bleed action bar on a sunken strip at the bottom of the panel. It sets `--pad` to\n * 8px, so buttons inside that use `radius-nested` get the concentric 7px corner.\n */\nexport function PopoverFooter({ className = \"\", children }: { className?: string; children: ReactNode }) {\n  return (\n    <div\n      className={`-mx-4 mt-4 -mb-4 flex items-center justify-between gap-2 border-t border-line-subtle bg-surface-sunken p-2 [--pad:8px] ${className}`}\n    >\n      {children}\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@components/eased/popover/popover.tsx"
    }
  ],
  "type": "registry:ui"
}