{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "skeleton-table",
  "title": "Table skeleton",
  "description": "Styled skeleton: the Table set. 5 decorative skeleton variations (RowsSkeleton, ColumnsSkeleton, TableGridSkeleton, HeaderSkeleton, CompactSkeleton) on the ai2 token system, powered by framer-motion, reduced-motion aware and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "motion@^12.42.2"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/skeleton-table.tsx",
      "content": "\"use client\"\n\nimport type * as React from \"react\"\nimport { motion, useReducedMotion } from \"motion/react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Table skeleton family: 5 table and row layouts (rows, columns, grid, table with a header, dense list). The difference is not in the ANIMATION but in the STRUCTURE - the row and column layout changes; the pulse is the same calm token pulse in all of them. The cell widths are picked by index from a fixed list (NO Math.random, deterministic SSR). Colour comes ONLY from tokens. Skeletons are decorative: the root is aria-hidden. The pulse stops under reduced motion. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\ntype Props = React.ComponentProps<\"div\"> & { size?: StyledSize }\n\n/* Shared calm pulse (framer-motion, NO keyframes). */\nfunction Block({ className, delay = 0 }: { className?: string; delay?: number }) {\n  const reduce = useReducedMotion()\n  return (\n    <motion.span\n      className={cn(\"block rounded-md bg-secondary\", className)}\n      animate={reduce ? undefined : { opacity: [0.5, 1, 0.5] }}\n      transition={\n        reduce ? undefined : { duration: 1.6, ease: \"easeInOut\", repeat: Infinity, delay }\n      }\n    />\n  )\n}\n\nconst cell: Record<StyledSize, string> = {\n  sm: \"h-2.5\",\n  md: \"h-3\",\n  lg: \"h-3.5\",\n  xl: \"h-4\",\n}\n\nconst bar: Record<StyledSize, string> = {\n  sm: \"h-3\",\n  md: \"h-4\",\n  lg: \"h-5\",\n  xl: \"h-6\",\n}\n\nconst gap: Record<StyledSize, string> = {\n  sm: \"gap-2\",\n  md: \"gap-3\",\n  lg: \"gap-3.5\",\n  xl: \"gap-4\",\n}\n\nconst pad: Record<StyledSize, string> = {\n  sm: \"p-3\",\n  md: \"p-4\",\n  lg: \"p-5\",\n  xl: \"p-6\",\n}\n\n/* Hucre genisligi ritmi: sabit liste, index ile secilir. */\nconst cellWidths = [\"w-full\", \"w-4/5\", \"w-2/3\", \"w-11/12\", \"w-3/4\", \"w-1/2\"]\n\nconst frame = \"flex w-full flex-col rounded-xl border border-border bg-card\"\n\n/* Rows: a full-width stack of rows of varying length. */\nexport function RowsSkeleton({\n  className,\n  size = \"md\",\n  count = 5,\n  ...props\n}: Props & { count?: number }) {\n  return (\n    <div\n      data-slot=\"styled-skeleton\"\n      aria-hidden=\"true\"\n      className={cn(frame, gap[size], pad[size], className)}\n      {...props}\n    >\n      {Array.from({ length: count }, (_, i) => (\n        <Block\n          key={i}\n          delay={i * 0.1}\n          className={cn(bar[size], cellWidths[i % cellWidths.length])}\n        />\n      ))}\n    </div>\n  )\n}\n\n/* Columns: three columns, each with its own stack of cells. */\nexport function ColumnsSkeleton({\n  className,\n  size = \"md\",\n  count = 3,\n  ...props\n}: Props & { count?: number }) {\n  return (\n    <div\n      data-slot=\"styled-skeleton\"\n      aria-hidden=\"true\"\n      className={cn(frame, \"flex-row\", gap[size], pad[size], className)}\n      {...props}\n    >\n      {Array.from({ length: count }, (_, col) => (\n        <div key={col} className={cn(\"flex min-w-0 flex-1 flex-col\", gap[size])}>\n          <Block className={cn(\"w-2/3\", bar[size])} delay={col * 0.1} />\n          {[0, 1, 2, 3].map((r) => (\n            <Block\n              key={r}\n              delay={col * 0.1 + (r + 1) * 0.08}\n              className={cn(cell[size], cellWidths[(col + r) % cellWidths.length])}\n            />\n          ))}\n        </div>\n      ))}\n    </div>\n  )\n}\n\n/* TableGrid: a row-by-column cell grid, a bordered table body. */\nexport function TableGridSkeleton({\n  className,\n  size = \"md\",\n  rows = 4,\n  ...props\n}: Props & { rows?: number }) {\n  return (\n    <div\n      data-slot=\"styled-skeleton\"\n      aria-hidden=\"true\"\n      className={cn(frame, \"overflow-hidden\", className)}\n      {...props}\n    >\n      {Array.from({ length: rows }, (_, r) => (\n        <div\n          key={r}\n          className={cn(\n            \"grid grid-cols-4 items-center border-b border-border last:border-b-0\",\n            gap[size],\n            pad[size]\n          )}\n        >\n          {[0, 1, 2, 3].map((c) => (\n            <Block\n              key={c}\n              delay={(r * 4 + c) * 0.05}\n              className={cn(cell[size], cellWidths[(r + c) % cellWidths.length])}\n            />\n          ))}\n        </div>\n      ))}\n    </div>\n  )\n}\n\n/* Header: a pronounced header row (with its own surface) + body rows beneath it. */\nexport function HeaderSkeleton({\n  className,\n  size = \"md\",\n  rows = 4,\n  ...props\n}: Props & { rows?: number }) {\n  return (\n    <div\n      data-slot=\"styled-skeleton\"\n      aria-hidden=\"true\"\n      className={cn(frame, \"overflow-hidden\", className)}\n      {...props}\n    >\n      <div\n        className={cn(\n          \"grid grid-cols-4 items-center border-b border-border bg-muted\",\n          gap[size],\n          pad[size]\n        )}\n      >\n        {[0, 1, 2, 3].map((c) => (\n          <Block\n            key={c}\n            delay={c * 0.08}\n            className={cn(\n              \"bg-[color-mix(in_oklab,var(--color-foreground)_22%,transparent)]\",\n              cell[size],\n              c === 0 ? \"w-full\" : \"w-2/3\"\n            )}\n          />\n        ))}\n      </div>\n      <div className={cn(\"flex flex-col\", gap[size], pad[size])}>\n        {Array.from({ length: rows }, (_, r) => (\n          <div key={r} className={cn(\"grid grid-cols-4 items-center\", gap[size])}>\n            {[0, 1, 2, 3].map((c) => (\n              <Block\n                key={c}\n                delay={(r * 4 + c) * 0.05 + 0.3}\n                className={cn(cell[size], cellWidths[(r + c) % cellWidths.length])}\n              />\n            ))}\n          </div>\n        ))}\n      </div>\n    </div>\n  )\n}\n\n/* Compact: cerceve yok, yogun aralikli ince satirlar (dar panel listesi). */\nexport function CompactSkeleton({\n  className,\n  size = \"md\",\n  count = 6,\n  ...props\n}: Props & { count?: number }) {\n  return (\n    <div\n      data-slot=\"styled-skeleton\"\n      aria-hidden=\"true\"\n      className={cn(\"flex w-full flex-col gap-1.5\", className)}\n      {...props}\n    >\n      {Array.from({ length: count }, (_, i) => (\n        <div key={i} className=\"flex w-full items-center gap-2\">\n          <Block className=\"size-1.5 shrink-0 rounded-full\" delay={i * 0.08} />\n          <Block\n            delay={i * 0.08 + 0.04}\n            className={cn(cell[size], cellWidths[i % cellWidths.length])}\n          />\n        </div>\n      ))}\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/skeleton-table.tsx"
    }
  ],
  "categories": [
    "styled",
    "skeleton"
  ],
  "type": "registry:component"
}