{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dialog",
  "type": "registry:ui",
  "title": "Dialog",
  "description": "Every dialog needs a DialogTitle. Hide it visually with `<DialogTitle isHidden>` when the design has no heading.",
  "dependencies": [
    "@radix-ui/react-dialog@^1.3.1",
    "tailwind-variants@^1.0.0"
  ],
  "registryDependencies": [
    "https://junco.madebytobi.com/r/icons.json",
    "https://junco.madebytobi.com/r/junco-theme.json",
    "https://junco.madebytobi.com/r/utils.json"
  ],
  "files": [
    {
      "path": "registry/junco/ui/dialog.tsx",
      "type": "registry:ui",
      "content": "import * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"@/lib/utils\";\nimport { XIcon } from \"@/lib/junco/icons\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\n\n/**\n *   <Dialog>\n *     <DialogTrigger asChild><Button>Edit profile</Button></DialogTrigger>\n *     <DialogContent>\n *       <DialogHeader>\n *         <DialogTitle>Edit profile</DialogTitle>\n *         <DialogDescription>Changes show up for your whole team.</DialogDescription>\n *       </DialogHeader>\n *       ...\n *       <DialogFooter><DialogClose asChild><Button variant=\"outline\">Cancel</Button></DialogClose></DialogFooter>\n *     </DialogContent>\n *   </Dialog>\n *\n * Every dialog needs a DialogTitle. Hide it visually with `<DialogTitle isHidden>` when the design has no heading.\n */\nexport const Dialog = DialogPrimitive.Root;\nexport const DialogTrigger = DialogPrimitive.Trigger;\nexport const DialogClose = DialogPrimitive.Close;\nexport const DialogPortal = DialogPrimitive.Portal;\n\n/** The dimmed scrim behind dialogs and sheets. */\nexport const DialogOverlay = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Overlay>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n  <DialogPrimitive.Overlay\n    ref={ref}\n    className={cn(\n      \"fixed inset-0 z-overlay bg-overlay\",\n      \"data-[state=open]:animate-overlay-in data-[state=closed]:animate-overlay-out\",\n      className,\n    )}\n    {...props}\n  />\n));\nDialogOverlay.displayName = \"DialogOverlay\";\n\nexport const dialogVariants = tv({\n  slots: {\n    content: [\n      \"fixed top-1/2 left-1/2 z-overlay grid max-h-[calc(100dvh-2rem)] w-[calc(100vw-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 overflow-y-auto\",\n      \"rounded-card border border-border bg-popover p-6 text-popover-foreground shadow-overlay\",\n      \"focus-visible:outline-none\",\n      \"data-[state=open]:animate-pop-in data-[state=closed]:animate-pop-out\",\n    ],\n    close: [\n      \"absolute top-3 right-3 grid size-8 place-items-center rounded-control text-muted-foreground\",\n      \"transition-colors duration-fast ease-standard hover:bg-accent hover:text-foreground\",\n      \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\",\n    ],\n  },\n  variants: {\n    size: {\n      sm: { content: \"max-w-sm\" },\n      md: { content: \"max-w-lg\" },\n      lg: { content: \"max-w-2xl\" },\n      xl: { content: \"max-w-4xl\" },\n      full: { content: \"h-[calc(100dvh-2rem)] max-w-none\" },\n    },\n  },\n  defaultVariants: { size: \"md\" },\n});\n\nexport interface DialogContentProps\n  extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>,\n    VariantProps<typeof dialogVariants> {\n  /** Show the × button in the corner. Default true. */\n  showClose?: boolean;\n  /** Accessible name for the × button. Default \"Close\". */\n  closeLabel?: string;\n  classNames?: { overlay?: string; content?: string; close?: string };\n}\n\n/**\n * Radix returns focus to a DialogTrigger on close. Dialogs and sheets opened without one (a\n * shortcut, a controlled `open`, CommandDialog) would drop focus on <body>, so remember what had\n * focus when they opened and go back there. With a trigger, that element is the trigger.\n * Shared by DialogContent and SheetContent.\n */\nexport function useReturnFocus(\n  onOpenAutoFocus?: (event: Event) => void,\n  onCloseAutoFocus?: (event: Event) => void,\n) {\n  const returnFocusRef = React.useRef<HTMLElement | null>(null);\n  return {\n    onOpenAutoFocus: (event: Event) => {\n      const active = document.activeElement;\n      returnFocusRef.current = active instanceof HTMLElement && active !== document.body ? active : null;\n      onOpenAutoFocus?.(event);\n    },\n    onCloseAutoFocus: (event: Event) => {\n      onCloseAutoFocus?.(event);\n      const target = returnFocusRef.current;\n      returnFocusRef.current = null;\n      if (event.defaultPrevented || !target?.isConnected) return;\n      event.preventDefault();\n      target.focus();\n    },\n  };\n}\n\nexport const DialogContent = React.forwardRef<React.ElementRef<typeof DialogPrimitive.Content>, DialogContentProps>(\n  (\n    { className, classNames, size, showClose = true, closeLabel = \"Close\", onOpenAutoFocus, onCloseAutoFocus, children, ...props },\n    ref,\n  ) => {\n    const styles = dialogVariants({ size });\n    const focus = useReturnFocus(onOpenAutoFocus, onCloseAutoFocus);\n    return (\n      <DialogPortal>\n        <DialogOverlay className={classNames?.overlay} />\n        <DialogPrimitive.Content\n          ref={ref}\n          className={styles.content({ className: cn(classNames?.content, className) })}\n          {...focus}\n          {...props}\n        >\n          {children}\n          {showClose && (\n            <DialogPrimitive.Close className={styles.close({ className: classNames?.close })} aria-label={closeLabel}>\n              <XIcon className=\"size-4\" />\n            </DialogPrimitive.Close>\n          )}\n        </DialogPrimitive.Content>\n      </DialogPortal>\n    );\n  },\n);\nDialogContent.displayName = \"DialogContent\";\n\nexport function DialogHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  return <div className={cn(\"grid gap-1.5 pr-8\", className)} {...props} />;\n}\n\nexport function DialogFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  return <div className={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)} {...props} />;\n}\n\nexport interface DialogTitleProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title> {\n  /** Keep the title for screen readers but hide it on screen. */\n  isHidden?: boolean;\n}\n\nexport const DialogTitle = React.forwardRef<React.ElementRef<typeof DialogPrimitive.Title>, DialogTitleProps>(\n  ({ className, isHidden, ...props }, ref) => (\n    <DialogPrimitive.Title\n      ref={ref}\n      className={cn(\"text-lg leading-6 font-semibold tracking-tight\", isHidden && \"sr-only\", className)}\n      {...props}\n    />\n  ),\n);\nDialogTitle.displayName = \"DialogTitle\";\n\nexport const DialogDescription = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n  <DialogPrimitive.Description ref={ref} className={cn(\"text-sm text-muted-foreground\", className)} {...props} />\n));\nDialogDescription.displayName = \"DialogDescription\";\n"
    }
  ],
  "docs": "Docs and examples: https://junco.madebytobi.com/docs/components/dialog",
  "meta": {
    "hash": "826f9299a485103f",
    "source": "packages/react/src/components/dialog.tsx",
    "exports": [
      "Dialog",
      "DialogTrigger",
      "DialogClose",
      "DialogPortal",
      "DialogOverlay",
      "dialogVariants",
      "DialogContentProps",
      "useReturnFocus",
      "DialogContent",
      "DialogHeader",
      "DialogFooter",
      "DialogTitleProps",
      "DialogTitle",
      "DialogDescription"
    ],
    "props": {
      "DialogContent": {
        "extends": "React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof dialogVariants>",
        "props": [
          {
            "name": "showClose",
            "optional": true,
            "type": "boolean",
            "description": "Show the × button in the corner. Default true."
          },
          {
            "name": "closeLabel",
            "optional": true,
            "type": "string",
            "description": "Accessible name for the × button. Default \"Close\"."
          },
          {
            "name": "classNames",
            "optional": true,
            "type": "{ overlay?: string; content?: string; close?: string }"
          }
        ]
      },
      "DialogTitle": {
        "extends": "React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>",
        "props": [
          {
            "name": "isHidden",
            "optional": true,
            "type": "boolean",
            "description": "Keep the title for screen readers but hide it on screen."
          }
        ]
      }
    },
    "variants": {
      "variants": {
        "size": [
          "sm",
          "md",
          "lg",
          "xl",
          "full"
        ]
      },
      "defaultVariants": {
        "size": "md"
      }
    },
    "usage": "<Dialog>\n  <DialogTrigger asChild><Button>Edit profile</Button></DialogTrigger>\n  <DialogContent>\n    <DialogHeader>\n      <DialogTitle>Edit profile</DialogTitle>\n      <DialogDescription>Changes show up for your whole team.</DialogDescription>\n    </DialogHeader>\n    ...\n    <DialogFooter><DialogClose asChild><Button variant=\"outline\">Cancel</Button></DialogClose></DialogFooter>\n  </DialogContent>\n</Dialog>",
    "docsUrl": "https://junco.madebytobi.com/docs/components/dialog"
  }
}
