{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "empty-state",
  "type": "registry:component",
  "title": "Empty State",
  "description": "Centered placeholder for empty lists, tables, and search results with sm/md/lg sizes.",
  "dependencies": [
    "@vllnt/ui@^0.2.1",
    "class-variance-authority"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/empty-state/empty-state.tsx",
      "content": "import {\n  type ComponentPropsWithoutRef,\n  forwardRef,\n  type ReactNode,\n} from \"react\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@vllnt/ui\";\n\nconst emptyStateVariants = cva(\n  \"flex flex-col items-center justify-center gap-3 text-center text-foreground\",\n  {\n    defaultVariants: {\n      size: \"md\",\n    },\n    variants: {\n      size: {\n        lg: \"px-6 py-16\",\n        md: \"px-4 py-10\",\n        sm: \"px-3 py-6\",\n      },\n    },\n  },\n);\n\nconst titleVariants = cva(\"font-semibold tracking-tight\", {\n  defaultVariants: {\n    size: \"md\",\n  },\n  variants: {\n    size: {\n      lg: \"text-xl\",\n      md: \"text-lg\",\n      sm: \"text-base\",\n    },\n  },\n});\n\nconst descriptionVariants = cva(\"max-w-prose text-muted-foreground\", {\n  defaultVariants: {\n    size: \"md\",\n  },\n  variants: {\n    size: {\n      lg: \"text-base\",\n      md: \"text-sm\",\n      sm: \"text-xs\",\n    },\n  },\n});\n\nconst iconVariants = cva(\n  \"mb-1 flex items-center justify-center rounded-full bg-muted text-muted-foreground [&_svg]:h-1/2 [&_svg]:w-1/2\",\n  {\n    defaultVariants: {\n      size: \"md\",\n    },\n    variants: {\n      size: {\n        lg: \"size-16\",\n        md: \"size-12\",\n        sm: \"size-8\",\n      },\n    },\n  },\n);\n\n/**\n * Visual size for {@link EmptyState}.\n *\n * - `sm` — inline, suitable for compact lists or cards\n * - `md` — section-level (default)\n * - `lg` — full-page placeholder\n *\n * @public\n */\nexport type EmptyStateSize = \"lg\" | \"md\" | \"sm\";\n\n/**\n * Props for {@link EmptyState}.\n *\n * @public\n */\nexport type EmptyStateProps = {\n  /**\n   * Action slot rendered below the description. Compose with `Button` or any\n   * interactive element.\n   */\n  children?: ReactNode;\n  /** Optional secondary text describing the empty condition. */\n  description?: ReactNode;\n  /** Optional icon or illustration shown above the title. */\n  icon?: ReactNode;\n  /** Headline rendered as a heading element. */\n  title?: ReactNode;\n} & ComponentPropsWithoutRef<\"div\"> &\n  VariantProps<typeof emptyStateVariants>;\n\n/**\n * Placeholder for empty lists, tables, and search results. Composes a\n * centered icon, title, description, and an action slot. Announces itself\n * via `role=\"status\"` so assistive tech can pick up state changes\n * (e.g. when filters clear results).\n *\n * @example\n * ```tsx\n * <EmptyState\n *   icon={<Inbox />}\n *   title=\"No results found\"\n *   description=\"Try adjusting your search or filters.\"\n * >\n *   <Button variant=\"outline\" onClick={clearFilters}>Clear filters</Button>\n * </EmptyState>\n * ```\n *\n * @public\n */\nexport const EmptyState = forwardRef<HTMLDivElement, EmptyStateProps>(\n  (\n    {\n      children,\n      className,\n      description,\n      icon,\n      role: roleOverride,\n      size,\n      title,\n      ...rest\n    },\n    ref,\n  ) => {\n    return (\n      <div\n        className={cn(emptyStateVariants({ size }), className)}\n        ref={ref}\n        role={roleOverride ?? \"status\"}\n        {...rest}\n      >\n        {icon ? (\n          <span aria-hidden=\"true\" className={cn(iconVariants({ size }))}>\n            {icon}\n          </span>\n        ) : null}\n        {title ? (\n          <h3 className={cn(titleVariants({ size }))}>{title}</h3>\n        ) : null}\n        {description ? (\n          <p className={cn(descriptionVariants({ size }))}>{description}</p>\n        ) : null}\n        {children ? (\n          <div className=\"mt-2 flex flex-wrap items-center justify-center gap-2\">\n            {children}\n          </div>\n        ) : null}\n      </div>\n    );\n  },\n);\nEmptyState.displayName = \"EmptyState\";\n\nexport { emptyStateVariants };\n",
      "type": "registry:component"
    }
  ],
  "version": "0.2.1",
  "stability": "stable",
  "examples": [
    {
      "title": "Default",
      "description": "Empty state for an empty list — explain what's empty + offer a single primary action.",
      "code": "import { Button, EmptyState } from \"@vllnt/ui\";\nimport { Inbox } from \"lucide-react\";\n\nexport function Demo() {\n  return (\n    <EmptyState\n      icon={<Inbox className=\"h-8 w-8\" />}\n      title=\"No tickets yet\"\n      description=\"Create your first support ticket to start tracking conversations.\"\n      action={<Button>Create ticket</Button>}\n    />\n  );\n}\n",
      "framework": "react"
    }
  ]
}
