{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "loaders-skeleton",
  "title": "Skeleton loaders",
  "description": "Styled loaders: the Skeleton set. 5 decorative loaders variations (LineSkeleton, CardSkeleton, AvatarSkeleton, TextSkeleton, ListSkeleton) 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/loaders-skeleton.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/* Skeleton loader family: 5 skeleton indicators with a token shimmer sweep. The blocks are bg-secondary; a foreground-derived highlight moves left to right across them (NOT a keyframe but a motion.span - the registry stays self-contained). Colour comes ONLY from tokens. Size = the overall scale (height and width are measured sensibly). role=status. DELIBERATE: it keeps sweeping under reduced-motion too (a stopped skeleton reads as \"hung\"). */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst box: Record<StyledSize, string> = {\n  sm: \"size-4\",\n  md: \"size-5\",\n  lg: \"size-6\",\n  xl: \"size-8\",\n}\n\nconst scale: Record<StyledSize, string> = {\n  sm: \"w-40\",\n  md: \"w-56\",\n  lg: \"w-72\",\n  xl: \"w-96\",\n}\n\ntype Props = React.ComponentProps<\"div\"> & { size?: StyledSize; label?: string }\n\nconst SHIMMER =\n  \"bg-[linear-gradient(90deg,transparent,color-mix(in_oklab,var(--color-foreground)_10%,transparent),transparent)]\"\n\n/* Tekrar kullanilabilen iskelet blok: bg-secondary + hareketli shimmer overlay. */\nfunction Block({ className }: { className?: string }) {\n  return (\n    <span className={cn(\"relative block overflow-hidden rounded-md bg-secondary\", className)}>\n      <motion.span\n        aria-hidden=\"true\"\n        className={cn(\"absolute inset-y-0 left-0 w-2/3\", SHIMMER)}\n        animate={{ x: [\"-100%\", \"250%\"] }}\n        transition={{ duration: 1.4, ease: \"easeInOut\", repeat: Infinity }}\n      />\n    </span>\n  )\n}\n\n/* Line: tek yuvarlatilmis cubuk + token shimmer supurmesi. */\nexport function LineSkeleton({ className, size = \"md\", label = \"Loading\", ...props }: Props) {\n  return (\n    <div\n      data-slot=\"styled-loader\"\n      role=\"status\"\n      aria-label={label}\n      className={cn(\"inline-block max-w-full\", scale[size], className)}\n      {...props}\n    >\n      <Block className=\"h-4 w-full\" />\n    </div>\n  )\n}\n\n/* Card: one block plus two lines. */\nexport function CardSkeleton({ className, size = \"md\", label = \"Loading\", ...props }: Props) {\n  return (\n    <div\n      data-slot=\"styled-loader\"\n      role=\"status\"\n      aria-label={label}\n      className={cn(\"inline-flex max-w-full flex-col gap-3\", scale[size], className)}\n      {...props}\n    >\n      <Block className=\"h-24 w-full\" />\n      <Block className=\"h-3 w-full\" />\n      <Block className=\"h-3 w-4/5\" />\n    </div>\n  )\n}\n\n/* Avatar: a circle plus two lines beside it. */\nexport function AvatarSkeleton({ className, size = \"md\", label = \"Loading\", ...props }: Props) {\n  return (\n    <div\n      data-slot=\"styled-loader\"\n      role=\"status\"\n      aria-label={label}\n      className={cn(\"inline-flex max-w-full items-center gap-3\", scale[size], className)}\n      {...props}\n    >\n      <Block className=\"size-10 shrink-0 rounded-full\" />\n      <div className=\"flex flex-1 flex-col gap-2\">\n        <Block className=\"h-3 w-3/4\" />\n        <Block className=\"h-3 w-1/2\" />\n      </div>\n    </div>\n  )\n}\n\n/* Text: 3-4 lines of varying width. */\nexport function TextSkeleton({ className, size = \"md\", label = \"Loading\", ...props }: Props) {\n  const widths = [\"w-full\", \"w-11/12\", \"w-4/5\", \"w-2/3\"]\n  return (\n    <div\n      data-slot=\"styled-loader\"\n      role=\"status\"\n      aria-label={label}\n      className={cn(\"inline-flex max-w-full flex-col gap-2\", scale[size], className)}\n      {...props}\n    >\n      {widths.map((w, i) => (\n        <Block key={i} className={cn(\"h-3\", w)} />\n      ))}\n    </div>\n  )\n}\n\n/* List: 3 rows, each a small circle plus a line. */\nexport function ListSkeleton({ className, size = \"md\", label = \"Loading\", ...props }: Props) {\n  const rows = [0, 1, 2]\n  return (\n    <div\n      data-slot=\"styled-loader\"\n      role=\"status\"\n      aria-label={label}\n      className={cn(\"inline-flex max-w-full flex-col gap-3\", scale[size], className)}\n      {...props}\n    >\n      {rows.map((i) => (\n        <div key={i} className=\"flex items-center gap-3\">\n          <Block className=\"size-6 shrink-0 rounded-full\" />\n          <Block className=\"h-3 flex-1\" />\n        </div>\n      ))}\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/loaders-skeleton.tsx"
    }
  ],
  "categories": [
    "styled",
    "loaders"
  ],
  "type": "registry:component"
}