{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "empty-error",
  "title": "Error empty",
  "description": "Styled empty: the Error set. 5 decorative empty variations (ErrorEmpty, OfflineEmpty, DeniedEmpty, TimeoutEmpty, BrokenEmpty) on the ai2 token system, driven by CSS token transitions and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/empty-error.tsx",
      "content": "\"use client\"\n\nimport type * as React from \"react\"\nimport {\n  CloudOff,\n  Lock,\n  RefreshCw,\n  ServerCrash,\n  TimerReset,\n  Unplug,\n} from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Error empty family: 5 error, offline and permission empty states. Every variant drives one semantic tone family (danger / warning / muted) and shows it in the icon badge; its root carries data-tone. Colour comes ONLY from semantic tokens (transparency via color-mix), size = the padding plus icon and text scale. Renders without props too. Static - no motion. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\ntype Scale = {\n  root: string\n  icon: string\n  badge: string\n  title: string\n  description: string\n}\n\nconst scales: Record<StyledSize, Scale> = {\n  sm: {\n    root: \"gap-2 p-6\",\n    icon: \"size-6\",\n    badge: \"size-12\",\n    title: \"text-sm\",\n    description: \"text-xs\",\n  },\n  md: {\n    root: \"gap-3 p-8\",\n    icon: \"size-8\",\n    badge: \"size-16\",\n    title: \"text-base\",\n    description: \"text-sm\",\n  },\n  lg: {\n    root: \"gap-3.5 p-10\",\n    icon: \"size-10\",\n    badge: \"size-20\",\n    title: \"text-lg\",\n    description: \"text-sm\",\n  },\n  xl: {\n    root: \"gap-4 p-12\",\n    icon: \"size-12\",\n    badge: \"size-24\",\n    title: \"text-xl\",\n    description: \"text-base\",\n  },\n}\n\ninterface EmptyProps {\n  className?: string\n  size?: StyledSize\n  icon?: React.ReactNode\n  title?: React.ReactNode\n  description?: React.ReactNode\n  action?: React.ReactNode\n}\n\ntype Tone = \"danger\" | \"warning\" | \"muted\"\n\n/* Ton haritasi: rozet zemini + on-plan rengi + kenar. danger/warning gercek\n   -soft token'larini kullanir; muted notr yuzeydir. */\nconst toneBadge: Record<Tone, string> = {\n  danger:\n    \"bg-danger-soft text-danger-soft-foreground [border-color:color-mix(in_oklab,var(--color-danger)_28%,transparent)]\",\n  warning:\n    \"bg-warning-soft text-warning-soft-foreground [border-color:color-mix(in_oklab,var(--color-warning)_28%,transparent)]\",\n  muted: \"bg-muted text-muted-foreground border-border\",\n}\n\nconst rootBase = \"flex flex-col items-center justify-center text-center\"\n\nconst iconBase = \"[&_i]:leading-none [&_svg]:size-full\"\n\nconst retryBtn =\n  \"inline-flex h-9 items-center justify-center gap-2 rounded-md border border-border bg-transparent px-4 text-sm font-medium text-foreground outline-none transition-colors duration-(--motion-base) ease-(--motion-ease) hover:bg-[color-mix(in_oklab,var(--color-foreground)_6%,transparent)] focus-visible:ring-[3px] focus-visible:ring-ring/50 motion-reduce:transition-none [&_i]:text-base [&_i]:leading-none [&_svg]:size-4 [&_svg]:shrink-0\"\n\n/* Shared shell: a toned badge plus title plus description plus an optional action. */\nfunction ErrorShell({\n  tone,\n  fallbackIcon,\n  className,\n  size = \"md\",\n  icon,\n  title,\n  description,\n  action,\n  defaultAction,\n}: EmptyProps & {\n  tone: Tone\n  fallbackIcon: React.ReactNode\n  defaultAction?: React.ReactNode\n}) {\n  const s = scales[size]\n  return (\n    <div\n      data-slot=\"styled-empty\"\n      data-tone={tone}\n      className={cn(rootBase, s.root, className)}\n    >\n      <span\n        aria-hidden=\"true\"\n        className={cn(\n          \"flex items-center justify-center rounded-full border\",\n          toneBadge[tone],\n          s.badge\n        )}\n      >\n        <span className={cn(iconBase, s.icon)}>{icon ?? fallbackIcon}</span>\n      </span>\n      <p className={cn(\"font-semibold text-foreground\", s.title)}>{title}</p>\n      {description ? (\n        <p className={cn(\"max-w-prose text-muted-foreground\", s.description)}>\n          {description}\n        </p>\n      ) : null}\n      {action ?? defaultAction ? (\n        <div className=\"mt-2\">{action ?? defaultAction}</div>\n      ) : null}\n    </div>\n  )\n}\n\n/* ErrorEmpty: genel sunucu hatasi, danger tonu + tekrar dene aksiyonu. */\nexport function ErrorEmpty({\n  title = \"Something went wrong\",\n  description = \"We could not load this content. Try again in a moment.\",\n  ...props\n}: EmptyProps) {\n  return (\n    <ErrorShell\n      tone=\"danger\"\n      fallbackIcon={<ServerCrash />}\n      title={title}\n      description={description}\n      defaultAction={\n        <button type=\"button\" data-slot=\"styled-empty-action\" className={retryBtn}>\n          <RefreshCw />\n          Try again\n        </button>\n      }\n      {...props}\n    />\n  )\n}\n\n/* OfflineEmpty: baglanti yok, warning tonu + yeniden baglan aksiyonu. */\nexport function OfflineEmpty({\n  title = \"You are offline\",\n  description = \"Check your connection. Your changes will sync once you are back online.\",\n  ...props\n}: EmptyProps) {\n  return (\n    <ErrorShell\n      tone=\"warning\"\n      fallbackIcon={<CloudOff />}\n      title={title}\n      description={description}\n      defaultAction={\n        <button type=\"button\" data-slot=\"styled-empty-action\" className={retryBtn}>\n          <RefreshCw />\n          Reconnect\n        </button>\n      }\n      {...props}\n    />\n  )\n}\n\n/* DeniedEmpty: yetki yok, danger tonu + erisim isteme aksiyonu. */\nexport function DeniedEmpty({\n  title = \"You do not have access\",\n  description = \"Ask a workspace admin to grant you permission to view this page.\",\n  ...props\n}: EmptyProps) {\n  return (\n    <ErrorShell\n      tone=\"danger\"\n      fallbackIcon={<Lock />}\n      title={title}\n      description={description}\n      defaultAction={\n        <button type=\"button\" data-slot=\"styled-empty-action\" className={retryBtn}>\n          <Lock />\n          Request access\n        </button>\n      }\n      {...props}\n    />\n  )\n}\n\n/* TimeoutEmpty: istek zaman asimi, warning tonu + yeniden yukle aksiyonu. */\nexport function TimeoutEmpty({\n  title = \"This is taking too long\",\n  description = \"The request timed out before it finished. Reload to give it another go.\",\n  ...props\n}: EmptyProps) {\n  return (\n    <ErrorShell\n      tone=\"warning\"\n      fallbackIcon={<TimerReset />}\n      title={title}\n      description={description}\n      defaultAction={\n        <button type=\"button\" data-slot=\"styled-empty-action\" className={retryBtn}>\n          <RefreshCw />\n          Reload\n        </button>\n      }\n      {...props}\n    />\n  )\n}\n\n/* BrokenEmpty: kirik/eksik kaynak, muted notr ton, aksiyon yok. */\nexport function BrokenEmpty({\n  title = \"This link is broken\",\n  description = \"The page you are looking for was moved or deleted.\",\n  ...props\n}: EmptyProps) {\n  return (\n    <ErrorShell\n      tone=\"muted\"\n      fallbackIcon={<Unplug />}\n      title={title}\n      description={description}\n      {...props}\n    />\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/empty-error.tsx"
    }
  ],
  "categories": [
    "styled",
    "empty"
  ],
  "type": "registry:component"
}