{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "empty-state",
  "type": "registry:ui",
  "title": "Empty state",
  "description": "Icon or illustration, title, a balanced description and the action under it; framed with a dashed rim on a page, plain inside a card.",
  "registryDependencies": [
    "@wibo/utils"
  ],
  "files": [
    {
      "path": "src/components/empty-state.tsx",
      "type": "registry:ui",
      "content": "import type { ComponentProps, ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\ntype EmptyStateVariant = \"framed\" | \"plain\";\n\ninterface EmptyStateProps extends Omit<ComponentProps<\"div\">, \"title\"> {\n  /** A Lucide icon element, shown in a bordered tile. */\n  icon?: ReactNode;\n  /** A line illustration; replaces the icon tile when both are set. */\n  illustration?: ReactNode;\n  title: ReactNode;\n  /** One sentence on why it is empty or what will appear; its lines are balanced. */\n  description?: ReactNode;\n  /**\n   * What the viewer can do about the emptiness, under the description:\n   * usually one `Button`, the verb that fills the list (\"Create key\",\n   * opening its sheet) or a way out (\"Clear filters\"). Omit it when the\n   * viewer can do nothing about it.\n   */\n  action?: ReactNode;\n  /** Heading level of the title. */\n  headingLevel?: 2 | 3 | 4;\n  /**\n   * `framed` (default): a full-width panel with a dashed rim, for an empty\n   * state that stands on the page or in a section of it, where the list,\n   * table or cards would be. `plain`: no rim, for an empty state already\n   * inside a card, a table, a sheet, a dialog or a chat thread.\n   */\n  variant?: EmptyStateVariant;\n}\n\n/** First-use or no-results block: visual, title, one sentence, the action that fills it. */\nfunction EmptyState({\n  icon,\n  illustration,\n  title,\n  description,\n  action,\n  headingLevel = 3,\n  variant = \"framed\",\n  className,\n  ...props\n}: EmptyStateProps) {\n  const Heading = `h${headingLevel}` as const;\n  return (\n    <div\n      data-slot=\"empty-state\"\n      data-variant={variant}\n      className={cn(\n        \"flex w-full min-w-0 flex-col items-center px-4 py-12 text-center\",\n        variant === \"framed\" && \"rounded-xl border border-dashed border-input sm:px-6\",\n        className,\n      )}\n      {...props}\n    >\n      {illustration ? (\n        <div aria-hidden=\"true\" className=\"mb-5 text-muted-foreground [&_svg]:h-auto [&_svg]:max-w-40\">\n          {illustration}\n        </div>\n      ) : icon ? (\n        <div\n          aria-hidden=\"true\"\n          className=\"mb-4 flex size-10 items-center justify-center rounded-lg border border-border bg-card text-muted-foreground shadow-card [&_svg]:size-5\"\n        >\n          {icon}\n        </div>\n      ) : null}\n      <Heading className=\"max-w-md text-sm font-medium text-balance text-foreground\">{title}</Heading>\n      {description ? <p className=\"mt-1 max-w-md text-sm text-balance text-muted-foreground\">{description}</p> : null}\n      {action ? <div className=\"mt-5 flex flex-wrap items-center justify-center gap-2\">{action}</div> : null}\n    </div>\n  );\n}\n\nexport { EmptyState };\nexport type { EmptyStateProps, EmptyStateVariant };\n"
    }
  ]
}
