{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "stat",
  "type": "registry:ui",
  "title": "Stat",
  "description": "One number with its label, as part of a description list. You can give a spoken form for abbreviated values.",
  "categories": [
    "atom"
  ],
  "registryDependencies": [
    "https://facadeui.dev/r/utils.json"
  ],
  "files": [
    {
      "path": "src/ui/stat.tsx",
      "type": "registry:ui",
      "target": "components/ui/stat.tsx",
      "content": "/**\n * Stat — one figure and its label, as a description-list group.\n *\n * DOM order is `<dt>` (label) then `<dd>` (value) because that is the only order\n * a definition list permits; `flex-col-reverse` puts the number on top visually.\n * Reading order and visual order therefore differ by one line, which is the\n * right trade: the value is meaningless to a screen reader without its label\n * arriving first.\n *\n * Must be rendered inside a `<dl>` — the `Stats` section does that for you.\n *\n * `as` exists because of a constraint a `<dl>` actually enforces: it may contain\n * `dt`/`dd` pairs wrapped in at most **one** level of `div`. Wrapping `Stat` in\n * another element to style or animate it puts the pair two levels deep, which\n * is invalid and which axe flags as `definition-list` plus `dlitem`. So the\n * caller replaces this wrapper instead of adding one around it.\n *\n * a11y: `value` should include its own unit (\"99.9%\", \"$2.4M\"). Pass `srValue`\n * when the display form is an abbreviation a screen reader would mangle.\n *\n * Dependencies: react, @/lib/utils.\n */\n\nimport type { ElementType, ReactNode } from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface StatItem {\n  /** The figure, including its unit or symbol. */\n  value: string\n  label: string\n  /** Optional sentence of context below the label. */\n  description?: string\n  /** Spoken form, when `value` is an abbreviation (\"1.2K\" -> \"1200\"). */\n  srValue?: string\n}\n\nexport interface StatProps extends StatItem {\n  /** The group wrapper. Defaults to `\"div\"`, the only element a `<dl>` allows. */\n  as?: ElementType\n  size?: \"sm\" | \"md\" | \"lg\"\n  align?: \"start\" | \"center\"\n  className?: string\n  children?: ReactNode\n}\n\nconst valueSizes = {\n  sm: \"text-3xl\",\n  md: \"text-display-sm\",\n  lg: \"text-display-md\",\n} as const\n\nexport function Stat({\n  value,\n  label,\n  description,\n  srValue,\n  as,\n  size = \"md\",\n  align = \"start\",\n  className,\n  children,\n}: StatProps) {\n  const Root = (as ?? \"div\") as ElementType\n\n  return (\n    <Root\n      className={cn(\n        \"flex flex-col-reverse gap-2\",\n        align === \"center\" && \"items-center text-center\",\n        className,\n      )}\n    >\n      <dt className=\"text-muted-foreground text-sm font-medium\">\n        {label}\n        {description ? (\n          <span className=\"text-muted-foreground mt-1 block text-pretty text-sm font-normal\">\n            {description}\n          </span>\n        ) : null}\n      </dt>\n      <dd\n        className={cn(\"text-foreground font-semibold tracking-tight\", valueSizes[size])}\n      >\n        {srValue ? (\n          <>\n            <span aria-hidden>{value}</span>\n            <span className=\"sr-only\">{srValue}</span>\n          </>\n        ) : (\n          value\n        )}\n        {children}\n      </dd>\n    </Root>\n  )\n}\n"
    }
  ],
  "docs": "Import styles/facade-tokens.css in your global stylesheet, after @import \"tailwindcss\". Docs: https://facadeui.dev/components/stat"
}
