{
  "name": "skeleton",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "skeleton.tsx",
      "content": "\"use client\";\r\n\r\nimport { createVariants, keyframes, themeVars as theme } from \"@yugnex/core\";\r\nimport type { CSSProperties, HTMLAttributes } from \"react\";\r\n\r\nconst pulse = keyframes({\r\n  \"0%, 100%\": { opacity: 1 },\r\n  \"50%\": { opacity: 0.45 },\r\n});\r\n\r\nconst shimmer = keyframes({\r\n  \"0%\": { backgroundPosition: \"200% 0\" },\r\n  \"100%\": { backgroundPosition: \"-200% 0\" },\r\n});\r\n\r\nconst skeletonVariants = createVariants({\r\n  base: {\r\n    display: \"block\",\r\n    backgroundColor: theme.color.muted,\r\n  },\r\n  variants: {\r\n    shape: {\r\n      text: { height: \"0.85em\", borderRadius: theme.radius.sm, margin: \"0.2em 0\" },\r\n      circle: { borderRadius: \"9999px\" },\r\n      rect: { borderRadius: theme.radius.md },\r\n    },\r\n    animation: {\r\n      pulse: { animation: `${pulse} 1.6s ease-in-out infinite` },\r\n      shimmer: {\r\n        backgroundImage: `linear-gradient(90deg, ${theme.color.muted} 0%, ${theme.color.border} 50%, ${theme.color.muted} 100%)`,\r\n        backgroundSize: \"200% 100%\",\r\n        animation: `${shimmer} 1.6s linear infinite`,\r\n      },\r\n      none: {},\r\n    },\r\n  },\r\n  defaultVariants: { shape: \"rect\", animation: \"shimmer\" },\r\n});\r\n\r\nexport interface SkeletonProps extends HTMLAttributes<HTMLSpanElement> {\r\n  shape?: \"text\" | \"circle\" | \"rect\";\r\n  animation?: \"pulse\" | \"shimmer\" | \"none\";\r\n  width?: CSSProperties[\"width\"];\r\n  height?: CSSProperties[\"height\"];\r\n  /** Render this many stacked text lines, the last one shortened like real prose. */\r\n  lines?: number;\r\n}\r\n\r\n/** A loading placeholder. Use `lines` for multi-line text blocks, `shape=\"circle\"` for avatars. */\r\nexport function Skeleton({\r\n  shape = \"rect\",\r\n  animation = \"shimmer\",\r\n  width,\r\n  height,\r\n  lines,\r\n  className,\r\n  style,\r\n  ...props\r\n}: SkeletonProps) {\r\n  if (lines && lines > 1) {\r\n    return (\r\n      <span aria-hidden=\"true\" style={{ display: \"block\", width }} {...props}>\r\n        {Array.from({ length: lines }, (_, i) => (\r\n          <span\r\n            key={i}\r\n            className={skeletonVariants({ shape: \"text\", animation })}\r\n            style={{ width: i === lines - 1 ? \"60%\" : \"100%\" }}\r\n          />\r\n        ))}\r\n      </span>\r\n    );\r\n  }\r\n\r\n  return (\r\n    <span\r\n      aria-hidden=\"true\"\r\n      className={skeletonVariants({ shape, animation, className })}\r\n      style={{ width, height, ...style }}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n",
      "type": "registry:component"
    }
  ]
}