{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "empty",
  "type": "registry:ui",
  "title": "Empty",
  "description": "Empty-state primitive — centered icon, title, description, and action slots for zero-data views.",
  "dependencies": [
    "@saasflare/ui",
    "class-variance-authority"
  ],
  "files": [
    {
      "path": "components/ui/empty.tsx",
      "type": "registry:ui",
      "content": "\"use client\"\n\n// @toreview\n/**\n * @fileoverview Empty primitive — placeholder UI for empty states with icon, title,\n * description, and action slots. Renders a dashed-border container centered in its\n * parent. Part of the Saasflare base component layer.\n * @module packages/ui/components/ui/empty\n * @layer core\n *\n * @component\n * @example\n * import { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent } from '@saasflare/ui';\n * <Empty>\n *   <EmptyHeader>\n *     <EmptyTitle>No items found</EmptyTitle>\n *     <EmptyDescription>Try adjusting your filters.</EmptyDescription>\n *   </EmptyHeader>\n *   <EmptyContent>Create one</EmptyContent>\n * </Empty>\n */\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@saasflare/ui\"\nimport { useSaasflareProps, type SaasflareComponentProps } from \"@saasflare/ui\"\n\n/**\n * Props for {@link Empty}.\n *\n * Extends {@link SaasflareComponentProps} so `surface`, `radius`, `animated`,\n * and `iconWeight` can be supplied per-instance or inherited from\n * <SaasflareProvider>.\n */\ninterface EmptyProps extends Omit<React.ComponentProps<\"div\">, keyof SaasflareComponentProps>, SaasflareComponentProps {}\n\n/**\n * Empty-state placeholder — a dashed-border container centered in its parent.\n * Use when a list, table, or search has nothing to show; compose with\n * {@link EmptyHeader}, {@link EmptyTitle}, {@link EmptyDescription}, and\n * {@link EmptyContent}.\n *\n * @component\n * @layer core\n *\n * @example\n * <Empty>\n *   <EmptyHeader>\n *     <EmptyTitle>No items found</EmptyTitle>\n *     <EmptyDescription>Try adjusting your filters.</EmptyDescription>\n *   </EmptyHeader>\n *   <EmptyContent>Create one</EmptyContent>\n * </Empty>\n */\nfunction Empty({ className, surface, radius, animated, iconWeight, ...props }: EmptyProps) {\n  const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n\n  return (\n    <div\n      {...props}\n      data-slot=\"empty\"\n      data-surface={sf.surface}\n      data-radius={sf.radius}\n      data-animated={String(sf.animated)}\n      className={cn(\n        \"flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12\",\n        className\n      )}\n    />\n  )\n}\n\n/**\n * Groups the media, title, and description at the top of an {@link Empty}.\n *\n * @component\n * @layer core\n */\nfunction EmptyHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"empty-header\"\n      className={cn(\n        \"flex max-w-sm flex-col items-center gap-2 text-center\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst emptyMediaVariants = cva(\n  \"mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-transparent\",\n        icon: \"flex size-10 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-6\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\n/**\n * Icon or illustration slot above the title. `variant=\"icon\"` wraps the icon\n * in a muted rounded tile.\n *\n * @component\n * @layer core\n */\nfunction EmptyMedia({\n  className,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof emptyMediaVariants>) {\n  return (\n    <div\n      data-slot=\"empty-icon\"\n      data-variant={variant}\n      className={cn(emptyMediaVariants({ variant, className }))}\n      {...props}\n    />\n  )\n}\n\n/**\n * Empty-state title text.\n *\n * @component\n * @layer core\n */\nfunction EmptyTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"empty-title\"\n      className={cn(\"text-lg font-medium tracking-tight\", className)}\n      {...props}\n    />\n  )\n}\n\n/**\n * Empty-state supporting text; nested links are underlined automatically.\n *\n * @component\n * @layer core\n */\nfunction EmptyDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n  return (\n    <p\n      data-slot=\"empty-description\"\n      className={cn(\n        \"text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/**\n * Action area of an {@link Empty} — holds buttons or links below the header.\n *\n * @component\n * @layer core\n */\nfunction EmptyContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"empty-content\"\n      className={cn(\n        \"flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Empty,\n  EmptyHeader,\n  EmptyTitle,\n  EmptyDescription,\n  EmptyContent,\n  EmptyMedia,\n  type EmptyProps,\n}\n",
      "target": "components/ui/empty.tsx"
    }
  ],
  "$meta": {
    "source": "https://ui.saasflare.io/r/empty.json"
  }
}
