{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sheet",
  "title": "Sheet",
  "author": "AniBT <https://anibt.net>",
  "description": "AniBT edge panel: the floating paper sliding in from any side, a stitched header bar, one scrolling SheetBody and a stitched footer that stays reachable.",
  "dependencies": [
    "lucide-react",
    "radix-ui"
  ],
  "registryDependencies": [
    "@anibt/theme"
  ],
  "files": [
    {
      "path": "registry/anibt/ui/sheet.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { XIcon } from \"lucide-react\"\nimport { Dialog as SheetPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\n/**\n * Sheet — AniBT 「贴纸手账」: the panel that slides in from an edge (filters,\n * navigation, a phone's sidebar).\n *\n * The same floating paper, scrim and close square as Dialog. Only the corners\n * away from the edge are rounded (14). `SheetHeader` is the stitched bar,\n * `SheetBody` is the one region that scrolls, and `SheetFooter` sits at the\n * bottom over a stitched top edge, so its buttons are always reachable.\n *\n * Export names and props are shadcn's (`side`, `showCloseButton`), so this\n * file can replace `components/ui/sheet.tsx` — shadcn's sidebar opens its\n * phone layout in it.\n */\n\ntype RenderCompat = {\n  /** Base UI's `asChild`: render this element instead, with the part's props. */\n  render?: React.ReactElement\n  /** Base UI compatibility; ignored (Radix decides from the rendered element). */\n  nativeButton?: boolean\n}\n\n/** Maps Base UI's `render` onto Radix's `asChild`. */\nfunction renderAsChild<P extends { asChild?: boolean; children?: React.ReactNode }>({\n  render,\n  nativeButton: _nativeButton,\n  ...props\n}: P & RenderCompat): P {\n  void _nativeButton\n  if (!render) return props as P\n  const children = props.children === undefined ? render : React.cloneElement(render, undefined, props.children)\n  return { ...props, asChild: true, children } as P\n}\n\nfunction Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n  return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />\n}\n\nfunction SheetTrigger(props: React.ComponentProps<typeof SheetPrimitive.Trigger> & RenderCompat) {\n  return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...renderAsChild(props)} />\n}\n\nfunction SheetClose(props: React.ComponentProps<typeof SheetPrimitive.Close> & RenderCompat) {\n  return <SheetPrimitive.Close data-slot=\"sheet-close\" {...renderAsChild(props)} />\n}\n\nfunction SheetPortal({ ...props }: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n  return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n  return (\n    <SheetPrimitive.Overlay\n      data-slot=\"sheet-overlay\"\n      className={cn(\n        \"fixed inset-0 z-50 bg-anibt-scrim duration-200 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction SheetContent({\n  className,\n  children,\n  side = \"right\",\n  showCloseButton = true,\n  closeLabel = \"关闭\",\n  ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n  side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n  showCloseButton?: boolean\n  /** The close button's accessible name. */\n  closeLabel?: string\n}) {\n  return (\n    <SheetPortal>\n      <SheetOverlay />\n      <SheetPrimitive.Content\n        data-slot=\"sheet-content\"\n        data-side={side}\n        className={cn(\n          \"anibt-pop fixed z-50 flex flex-col overflow-y-auto overscroll-contain text-[14px] outline-none data-[state=closed]:animate-out data-[state=closed]:duration-200 data-[state=open]:animate-in data-[state=open]:duration-300 data-[state=open]:ease-anibt-out\",\n          side === \"right\" &&\n            \"inset-y-0 right-0 h-full w-3/4 rounded-r-none data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm\",\n          side === \"left\" &&\n            \"inset-y-0 left-0 h-full w-3/4 rounded-l-none data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm\",\n          side === \"top\" &&\n            \"inset-x-0 top-0 h-auto max-h-[80dvh] rounded-t-none data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n          side === \"bottom\" &&\n            \"inset-x-0 bottom-0 h-auto max-h-[80dvh] rounded-b-none pb-[env(safe-area-inset-bottom,0px)] data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        {showCloseButton ? (\n          <SheetPrimitive.Close\n            data-slot=\"sheet-close\"\n            className=\"anibt-icobtn anibt-icobtn-ghost absolute top-3 right-3 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:outline-solid disabled:pointer-events-none\"\n          >\n            <XIcon className=\"size-4\" />\n            <span className=\"sr-only\">{closeLabel}</span>\n          </SheetPrimitive.Close>\n        ) : null}\n      </SheetPrimitive.Content>\n    </SheetPortal>\n  )\n}\n\n/** The 56px stitched bar at the top; its end is kept clear of the close square. */\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"sheet-header\"\n      className={cn(\n        \"anibt-stitch-under flex min-h-14 shrink-0 flex-col justify-center gap-1 px-4 py-3 pe-14 text-left\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/** The one scrolling region of a sheet. */\nfunction SheetBody({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"sheet-body\"\n      className={cn(\"min-h-0 flex-1 overflow-y-auto overscroll-contain p-4\", className)}\n      {...props}\n    />\n  )\n}\n\n/** Buttons at the bottom over a stitched top edge. */\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"sheet-footer\"\n      className={cn(\"anibt-stitch-over mt-auto flex shrink-0 flex-col gap-2 p-4 sm:flex-row sm:justify-end\", className)}\n      {...props}\n    />\n  )\n}\n\n/** 16/800 ink. */\nfunction SheetTitle({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Title>) {\n  return (\n    <SheetPrimitive.Title\n      data-slot=\"sheet-title\"\n      className={cn(\"text-[16px] leading-snug font-extrabold text-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\n/** 12, muted. */\nfunction SheetDescription({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Description>) {\n  return (\n    <SheetPrimitive.Description\n      data-slot=\"sheet-description\"\n      className={cn(\"text-[12px] leading-normal text-muted-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\nexport { Sheet, SheetTrigger, SheetClose, SheetContent, SheetBody, SheetHeader, SheetFooter, SheetTitle, SheetDescription }\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "overlay"
  ],
  "type": "registry:ui"
}