{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "skeleton",
  "type": "registry:ui",
  "title": "Skeleton",
  "description": "Where content will be before it arrives: blocks, lines and circles in the well's sunk look, shown after a beat with a soft sheen, swapped for the content on the settle spring.",
  "dependencies": [],
  "registryDependencies": [
    "https://metalui.dev/r/tokens.json"
  ],
  "files": [
    {
      "path": "packages/metalui/src/components/skeleton/skeleton.tsx",
      "type": "registry:ui",
      "target": "components/metalui/skeleton/skeleton.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\n\n/* ─────────────────────────────────────────────────────────\n * SKELETON, where content will be before it arrives\n *\n *     0 ms   mounted, invisible: a fast load never flashes it\n *   300 ms   the shapes fade in on the settle spring: blocks, lines, circles in the field well's\n *            sunk look, laid out where the content will stand\n *   always   a soft light passes across the wells (1.6 s, linear): a sheen on metal, not a pulse\n *   arrive   Skeleton.Swap: the shapes fade out and the content fades in on the settle spring,\n *            in the same place, so nothing below moves\n * Reduce Motion: no sheen; the fades stay.\n * A part: it has a look and no job. Slots: Skeleton (a block), Skeleton.Text, Skeleton.Circle,\n * Skeleton.Swap.\n * ───────────────────────────────────────────────────────── */\n\nconst SHAPE = 'mu-skeleton block recipe-well-field skeleton-sheen skeleton-arrive';\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLSpanElement> {\n  /** The size of what will be there (any CSS length); the host knows it. */\n  width?: number | string;\n  height?: number | string;\n}\n\n/** A block where something will be: an image, a card, a control. */\nfunction Block({ width = '100%', height, className, style, ...props }: SkeletonProps) {\n  const own = `${SHAPE} rounded-skeleton-radius`;\n  return <span aria-hidden className={className ? `${own} ${className}` : own} style={{ width, height: height ?? 'var(--mu-r-skeleton-self-line)', ...style }} {...props} />;\n}\n\n/** Lines of text; the last one is shorter, as text is. */\nfunction Text({ lines = 3, width = '100%', className }: { lines?: number; width?: number | string; className?: string }) {\n  return (\n    <span aria-hidden className={className ? `mu-skeleton-text grid gap-skeleton-line-gap ${className}` : 'mu-skeleton-text grid gap-skeleton-line-gap'} style={{ width }}>\n      {Array.from({ length: lines }, (_, i) => (\n        <span key={i} className={`${SHAPE} h-skeleton-line rounded-pill`} style={{ width: i === lines - 1 && lines > 1 ? 'calc(var(--mu-r-skeleton-self-last) * 100%)' : '100%' }} />\n      ))}\n    </span>\n  );\n}\n\n/** A circle where an avatar or a glyph will be. */\nfunction Circle({ size = 32, className }: { size?: number; className?: string }) {\n  const own = `${SHAPE} rounded-full flex-none`;\n  return <span aria-hidden className={className ? `${own} ${className}` : own} style={{ width: size, height: size }} />;\n}\n\nexport interface SkeletonSwapProps {\n  /** While true, the fallback (the shapes) stands where the content will be. */\n  loading: boolean;\n  /** The shapes: Skeleton, Skeleton.Text, Skeleton.Circle laid out like the content. */\n  fallback: React.ReactNode;\n  children: React.ReactNode;\n  /** What is loading, for assistive tech: \"Loading notes\". */\n  label?: string;\n}\n\n/** Shapes while loading; the content, faded in on the settle spring, once it arrives. */\nfunction Swap({ loading, fallback, children, label = 'Loading' }: SkeletonSwapProps) {\n  const was = React.useRef(loading);\n  const arrived = was.current && !loading;\n  React.useEffect(() => { if (loading) was.current = true; }, [loading]);\n  if (loading) return <div role=\"status\" aria-busy aria-label={label} className=\"mu-skeleton-swap\">{fallback}</div>;\n  return <div className={arrived ? 'mu-skeleton-swap skeleton-swap-in' : 'mu-skeleton-swap'}>{children}</div>;\n}\n\nexport const Skeleton = Object.assign(Block, { Text, Circle, Swap });\n"
    }
  ],
  "docs": "Agent guide: https://metalui.dev/r/skeleton.md. SwiftUI: MetalSkeleton in the MetalUI Swift package."
}
