{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "popover-accent",
  "title": "Accent popover",
  "description": "Styled popover: the Accent set. 5 decorative popover variations (BorderPopover, GlowPopover, RingPopover, TopBarPopover, FillPopover) on the ai2 token system, powered by framer-motion, reduced-motion aware and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "motion@^12.42.2",
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/popover-accent.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Droplet, Focus, PanelTop, Sparkles, SquareDashed } from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Accent popover family: 5 anchored panels in a token accent color. Each export is\n   a complete popover and SELF-CONTAINED (no radix, no portal): a relative\n   inline-flex wrapper + a panel absolutely positioned BELOW the trigger (top-full\n   mt-2). The trigger toggles on CLICK; it closes on an outside click (window\n   pointerdown, with inner clicks ignored via the wrapper ref) and on Escape. The\n   trigger is a real button. AnimatePresence fade+scale (from above); only a fade\n   under reduced motion. Color comes ONLY from tokens; transparency ONLY via\n   color-mix(in oklab, var(--color-x) N%, transparent). The accent color is the\n   primary token; the variants apply the accent to a DIFFERENT part of the panel: a\n   pronounced border, a glow box-shadow, a double-ring box-shadow, a top strip, a\n   soft filled surface. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst panelSize: Record<StyledSize, string> = {\n  sm: \"w-56\",\n  md: \"w-64\",\n  lg: \"w-72\",\n  xl: \"w-80\",\n}\n\ninterface PopoverProps {\n  size?: StyledSize\n  trigger?: React.ReactNode\n  children?: React.ReactNode\n  className?: string\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (o: boolean) => void\n}\n\nconst panelBase =\n  \"absolute left-0 top-full z-50 mt-2 origin-top rounded-xl border border-border bg-popover p-4 text-sm text-popover-foreground shadow-lg outline-none\"\n\nconst triggerBtn =\n  \"inline-flex h-9 shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-lg border border-border bg-secondary px-4 text-sm font-medium text-secondary-foreground outline-none transition-colors hover:bg-[color-mix(in_oklab,var(--color-foreground)_6%,transparent)] focus-visible:ring-[3px] focus-visible:ring-ring/50 [&_svg]:size-4 [&_svg]:shrink-0 [&_i]:text-base [&_i]:leading-none\"\n\n/* Panel basligindaki aksan ikon kabugu: lucide <svg> ve remixicon <i> ikisiyle de\n   dogru boyutlanir (token primary renkte). */\nconst iconWrap =\n  \"flex size-7 shrink-0 items-center justify-center rounded-md bg-[color-mix(in_oklab,var(--color-primary)_12%,transparent)] text-primary [&_svg]:size-4 [&_svg]:shrink-0 [&_i]:text-base [&_i]:leading-none\"\n\n/* Controlled/uncontrolled acik durum yonetimi. */\nfunction usePopoverState(props: PopoverProps) {\n  const { open, defaultOpen, onOpenChange } = props\n  const isControlled = open !== undefined\n  const [internal, setInternal] = React.useState(defaultOpen ?? false)\n  const isOpen = isControlled ? open : internal\n\n  const setOpen = React.useCallback(\n    (next: boolean) => {\n      if (!isControlled) setInternal(next)\n      onOpenChange?.(next)\n    },\n    [isControlled, onOpenChange]\n  )\n\n  return { isOpen, setOpen }\n}\n\nconst panelMotion = {\n  initial: { opacity: 0, scale: 0.96, y: -6 },\n  animate: { opacity: 1, scale: 1, y: 0 },\n  exit: { opacity: 0, scale: 0.96, y: -6 },\n  transition: { type: \"spring\" as const, stiffness: 340, damping: 26 },\n}\n\ntype AccentCoreProps = PopoverProps & {\n  /** Panelin cerceve / box-shadow / dolgu aksan siniflari. */\n  panelClassName?: string\n  /** The decorative layer added inside the panel (a top strip and so on). */\n  accent?: React.ReactNode\n  icon: React.ReactNode\n  title: React.ReactNode\n}\n\n/* Shared shell: a relative wrapper plus trigger plus an AnimatePresence panel. The accent carries the panel's frame, shadow and fill styling through panelClassName, and an extra decorative layer through accent. */\nfunction AccentPopover({\n  size = \"md\",\n  trigger,\n  children,\n  className,\n  panelClassName,\n  accent,\n  icon,\n  title,\n  ...state\n}: AccentCoreProps) {\n  const { isOpen, setOpen } = usePopoverState(state)\n  const reduce = useReducedMotion()\n  const wrapperRef = React.useRef<HTMLDivElement>(null)\n\n  React.useEffect(() => {\n    if (!isOpen) return\n    const onKey = (e: KeyboardEvent) => {\n      if (e.key === \"Escape\") setOpen(false)\n    }\n    const onPointer = (e: PointerEvent) => {\n      const node = wrapperRef.current\n      if (node && e.target instanceof Node && !node.contains(e.target)) {\n        setOpen(false)\n      }\n    }\n    window.addEventListener(\"keydown\", onKey)\n    window.addEventListener(\"pointerdown\", onPointer)\n    return () => {\n      window.removeEventListener(\"keydown\", onKey)\n      window.removeEventListener(\"pointerdown\", onPointer)\n    }\n  }, [isOpen, setOpen])\n\n  const fade = { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 } }\n  const motionProps = reduce ? fade : panelMotion\n\n  return (\n    <div ref={wrapperRef} data-slot=\"styled-popover\" className=\"relative inline-flex\">\n      <span\n        data-slot=\"styled-popover-trigger\"\n        className=\"inline-flex\"\n        onClick={() => setOpen(!isOpen)}\n      >\n        {trigger ?? (\n          <button\n            type=\"button\"\n            aria-haspopup=\"dialog\"\n            aria-expanded={isOpen}\n            className={triggerBtn}\n          >\n            Open\n          </button>\n        )}\n      </span>\n\n      <AnimatePresence>\n        {isOpen ? (\n          <motion.div\n            role=\"dialog\"\n            className={cn(panelBase, panelSize[size], panelClassName, className)}\n            initial={motionProps.initial}\n            animate={motionProps.animate}\n            exit={motionProps.exit}\n            transition={reduce ? { duration: 0.16, ease: \"easeOut\" } : panelMotion.transition}\n          >\n            {accent}\n            <div className=\"relative flex gap-3\">\n              <span data-slot=\"styled-popover-icon\" className={iconWrap}>\n                {icon}\n              </span>\n              <div className=\"min-w-0 flex-1\">\n                <div className=\"text-sm font-semibold text-foreground\">{title}</div>\n                <p className=\"mt-1 text-sm text-muted-foreground\">\n                  {children ?? \"A token accent treatment on a self-contained anchored panel.\"}\n                </p>\n              </div>\n            </div>\n          </motion.div>\n        ) : null}\n      </AnimatePresence>\n    </div>\n  )\n}\n\n/* BorderPopover: belirgin primary token cerceve (guclu color-mix border rengi). */\nexport function BorderPopover(props: PopoverProps) {\n  return (\n    <AccentPopover\n      icon={<SquareDashed />}\n      title=\"Border accent\"\n      panelClassName=\"border-[color-mix(in_oklab,var(--color-primary)_55%,transparent)]\"\n      {...props}\n    />\n  )\n}\n\n/* GlowPopover: panel etrafinda genis, dusuk yogunluklu primary token glow. */\nexport function GlowPopover(props: PopoverProps) {\n  return (\n    <AccentPopover\n      icon={<Sparkles />}\n      title=\"Glow accent\"\n      panelClassName=\"border-[color-mix(in_oklab,var(--color-primary)_35%,transparent)] shadow-[0_0_35px_color-mix(in_oklab,var(--color-primary)_28%,transparent),0_0_0_1px_color-mix(in_oklab,var(--color-primary)_20%,transparent)]\"\n      {...props}\n    />\n  )\n}\n\n/* RingPopover: panel etrafinda cift halka. Border + iki azalan yogunlukta primary\n   token box-shadow cizgisi (color-mix ile). */\nexport function RingPopover(props: PopoverProps) {\n  return (\n    <AccentPopover\n      icon={<Focus />}\n      title=\"Ring accent\"\n      panelClassName=\"border-[color-mix(in_oklab,var(--color-primary)_40%,transparent)] shadow-[0_0_0_1px_color-mix(in_oklab,var(--color-primary)_45%,transparent),0_0_0_5px_color-mix(in_oklab,var(--color-primary)_18%,transparent)]\"\n      {...props}\n    />\n  )\n}\n\n/* TopBarPopover: a full-width primary token accent strip above the panel (h-1); overflow-hidden clips the top corners to match the panel. */\nexport function TopBarPopover(props: PopoverProps) {\n  return (\n    <AccentPopover\n      icon={<PanelTop />}\n      title=\"Top bar accent\"\n      panelClassName=\"overflow-hidden\"\n      accent={\n        <span\n          aria-hidden=\"true\"\n          className=\"pointer-events-none absolute inset-x-0 top-0 h-1 bg-primary\"\n        />\n      }\n      {...props}\n    />\n  )\n}\n\n/* FillPopover: the panel background is a light primary token soft fill (mixed over\n   popover with color-mix), plus a thin accent border. */\nexport function FillPopover(props: PopoverProps) {\n  return (\n    <AccentPopover\n      icon={<Droplet />}\n      title=\"Fill accent\"\n      panelClassName=\"border-[color-mix(in_oklab,var(--color-primary)_30%,transparent)] bg-[color-mix(in_oklab,var(--color-primary)_6%,var(--color-popover))]\"\n      {...props}\n    />\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/popover-accent.tsx"
    }
  ],
  "categories": [
    "styled",
    "popover"
  ],
  "type": "registry:component"
}