{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sheet",
  "title": "Sheet",
  "description": "Sheet and dialog primitives.",
  "dependencies": [
    "class-variance-authority",
    "vaul"
  ],
  "registryDependencies": [
    "@circle-ui/overlay-action",
    "@circle-ui/utils"
  ],
  "files": [
    {
      "path": "registry/berlin/circle-ui/sheet.tsx",
      "content": "// Generated from packages/ui/src/components/sheet.tsx\n\"use client\";\n\nimport * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Drawer as DrawerPrimitive } from \"vaul\";\n\nimport { OverlayAction } from \"@/registry/berlin/circle-ui/overlay-action\";\nimport { cn } from \"@/registry/berlin/lib/utils\";\n\nlet activeBodyScrollLocks = 0;\nlet originalBodyOverflow = \"\";\nlet originalBodyPaddingRight = \"\";\n\nfunction useBodyScrollLock(isLocked: boolean) {\n  React.useEffect(() => {\n    if (!isLocked || typeof document === \"undefined\") return;\n\n    const body = document.body;\n    const documentElement = document.documentElement;\n    const shouldLockBody = activeBodyScrollLocks === 0;\n\n    activeBodyScrollLocks += 1;\n\n    if (shouldLockBody) {\n      originalBodyOverflow = body.style.overflow;\n      originalBodyPaddingRight = body.style.paddingRight;\n\n      const scrollbarGap = window.innerWidth - documentElement.clientWidth;\n      body.style.overflow = \"hidden\";\n      if (scrollbarGap > 0) body.style.paddingRight = `${scrollbarGap}px`;\n    }\n\n    return () => {\n      activeBodyScrollLocks = Math.max(0, activeBodyScrollLocks - 1);\n\n      if (activeBodyScrollLocks === 0) {\n        body.style.overflow = originalBodyOverflow;\n        body.style.paddingRight = originalBodyPaddingRight;\n      }\n    };\n  }, [isLocked]);\n}\n\nfunction CloseIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      className={className}\n      viewBox=\"0 0 16 16\"\n      fill=\"none\"\n      aria-hidden=\"true\"\n    >\n      <path\n        d=\"m4 4 8 8m0-8-8 8\"\n        stroke=\"currentColor\"\n        strokeWidth=\"1.5\"\n        strokeLinecap=\"round\"\n      />\n    </svg>\n  );\n}\n\nconst sheetTimingClass =\n  \"[animation-duration:320ms] [animation-timing-function:cubic-bezier(0.65,0.05,0.36,1)] [transition-duration:320ms] [transition-timing-function:cubic-bezier(0.65,0.05,0.36,1)]\";\n\nexport const sheetVariants = cva(\n  cn(\n    \"pointer-events-auto relative z-50 flex w-full max-w-[480px] flex-col bg-card px-6 pb-6 pt-14 shadow-[var(--shadow-elevated)] outline-none transition-[transform,opacity] data-[state=closed]:pointer-events-none data-[state=closed]:opacity-0 data-[state=open]:opacity-100 after:hidden\",\n    sheetTimingClass,\n  ),\n  {\n    variants: {\n      variant: {\n        sheet:\n          \"rounded-[28px] data-[state=closed]:translate-y-[20%] data-[state=open]:translate-y-0\",\n        modal:\n          \"rounded-[28px] data-[state=closed]:translate-y-[20%] data-[state=open]:translate-y-0 md:data-[state=closed]:translate-y-0 md:data-[state=closed]:scale-95 md:data-[state=open]:scale-100\",\n      },\n    },\n    defaultVariants: {\n      variant: \"sheet\",\n    },\n  },\n);\n\nconst sheetPositionerVariants = cva(\n  \"fixed inset-0 z-50 overflow-y-auto\",\n  {\n    variants: {\n      variant: {\n        sheet:\n          \"flex min-h-full w-full flex-col items-center justify-end px-3 pb-3 pt-6 md:justify-center md:px-0 md:py-12\",\n        modal:\n          \"flex min-h-full w-full flex-col items-center justify-end px-3 pb-3 pt-6 md:justify-center md:px-0 md:py-12\",\n      },\n    },\n    defaultVariants: {\n      variant: \"sheet\",\n    },\n  },\n);\n\nexport const SheetRoot = DrawerPrimitive.Root;\nexport const SheetTrigger = DrawerPrimitive.Trigger;\nexport const SheetPortal = DrawerPrimitive.Portal;\nexport const SheetClose = DrawerPrimitive.Close;\n\nexport const SheetOverlay = React.forwardRef<\n  React.ElementRef<typeof DrawerPrimitive.Overlay>,\n  React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n  <DrawerPrimitive.Overlay\n    ref={ref}\n    className={cn(\n      \"fixed inset-0 z-50 bg-overlay transition-opacity data-[state=closed]:pointer-events-none data-[state=closed]:opacity-0 data-[state=open]:opacity-100\",\n      sheetTimingClass,\n      className,\n    )}\n    {...props}\n  />\n));\n\nSheetOverlay.displayName = DrawerPrimitive.Overlay.displayName;\n\nexport interface SheetContentProps\n  extends\n    React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>,\n    VariantProps<typeof sheetVariants> {\n  dismissible?: boolean;\n}\n\nexport const SheetContent = React.forwardRef<\n  React.ElementRef<typeof DrawerPrimitive.Content>,\n  SheetContentProps\n>(({ className, children, dismissible = true, variant, ...props }, ref) => (\n  <SheetPortal>\n    <SheetOverlay forceMount />\n    <div className={cn(\"pointer-events-none\", sheetPositionerVariants({ variant }))}>\n      <DrawerPrimitive.Content\n        forceMount\n        ref={ref}\n        className={cn(\n          sheetVariants({ variant }),\n          variant === \"modal\" &&\n            \"max-h-[90dvh] max-w-none overflow-y-auto overscroll-contain md:max-h-[min(90dvh,720px)] md:max-w-[480px]\",\n          className,\n        )}\n        {...props}\n      >\n        {dismissible ? (\n          <div className=\"sticky top-4 z-10 -mx-6 -mt-10 mb-[-2rem] flex justify-end px-4\">\n            <DrawerPrimitive.Close asChild>\n              <OverlayAction\n                aria-label=\"Close dialog\"\n                tone=\"dark\"\n                className=\"pointer-events-auto focus-visible:ring-2 focus-visible:ring-ring/60 focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n              >\n                <CloseIcon className=\"size-4\" />\n              </OverlayAction>\n            </DrawerPrimitive.Close>\n          </div>\n        ) : null}\n        {children}\n      </DrawerPrimitive.Content>\n    </div>\n  </SheetPortal>\n));\n\nSheetContent.displayName = DrawerPrimitive.Content.displayName;\n\nexport const SheetHeader = ({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex flex-col gap-2 pr-10\", className)} {...props} />\n);\n\nexport const SheetFooter = ({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      \"mt-6 flex flex-col gap-3 sm:flex-row sm:justify-end\",\n      className,\n    )}\n    {...props}\n  />\n);\n\nexport const SheetTitle = React.forwardRef<\n  React.ElementRef<typeof DrawerPrimitive.Title>,\n  React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>\n>(({ className, ...props }, ref) => (\n  <DrawerPrimitive.Title\n    ref={ref}\n    className={cn(\"text-xl font-semibold tracking-tight\", className)}\n    {...props}\n  />\n));\n\nSheetTitle.displayName = DrawerPrimitive.Title.displayName;\n\nexport const SheetDescription = React.forwardRef<\n  React.ElementRef<typeof DrawerPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>\n>(({ className, ...props }, ref) => (\n  <DrawerPrimitive.Description\n    ref={ref}\n    className={cn(\"text-sm leading-6 text-muted-foreground\", className)}\n    {...props}\n  />\n));\n\nSheetDescription.displayName = DrawerPrimitive.Description.displayName;\n\nexport interface SheetProps {\n  isOpen: boolean;\n  onClose: () => void;\n  children: React.ReactNode;\n  modal?: boolean;\n  dismissible?: boolean;\n  className?: string;\n  id?: string;\n}\n\nexport function Sheet({\n  isOpen,\n  onClose,\n  children,\n  modal = false,\n  dismissible = true,\n  className,\n  id,\n}: SheetProps) {\n  useBodyScrollLock(isOpen);\n\n  return (\n    <SheetRoot\n      open={isOpen}\n      dismissible={dismissible}\n      noBodyStyles\n      onOpenChange={(open) => {\n        if (!open) onClose();\n      }}\n    >\n      <SheetContent\n        id={id}\n        variant={modal ? \"modal\" : \"sheet\"}\n        dismissible={dismissible}\n        className={className}\n      >\n        {children}\n      </SheetContent>\n    </SheetRoot>\n  );\n}\n",
      "type": "registry:ui",
      "target": "src/components/circle/ui/sheet.tsx"
    }
  ],
  "type": "registry:ui"
}