{
  "schemaVersion": "1.0",
  "item": {
    "slug": "loading-state-patterns",
    "name": "Loading State Patterns",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/wpank/loading-state-patterns",
    "canonicalUrl": "https://clawhub.ai/wpank/loading-state-patterns",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/loading-state-patterns",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=loading-state-patterns",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/loading-state-patterns"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/loading-state-patterns",
    "agentPageUrl": "https://openagent3.xyz/skills/loading-state-patterns/agent",
    "manifestUrl": "https://openagent3.xyz/skills/loading-state-patterns/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/loading-state-patterns/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Loading State Patterns",
        "body": "Build loading states that feel intentional and match your design system aesthetic."
      },
      {
        "title": "When to Use",
        "body": "Building skeleton loaders for content areas\nNeed shimmer effects for streaming content\nWant progressive loading experiences\nBuilding premium loading UX"
      },
      {
        "title": "Pattern 1: Skeleton Base",
        "body": "import { cn } from '@/lib/utils';\n\ninterface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n  shimmer?: boolean;\n}\n\nexport function Skeleton({ className, shimmer = true, ...props }: SkeletonProps) {\n  return (\n    <div\n      className={cn(\n        'rounded-md bg-muted',\n        shimmer && 'animate-shimmer bg-gradient-to-r from-muted via-muted-foreground/10 to-muted bg-[length:200%_100%]',\n        className\n      )}\n      {...props}\n    />\n  );\n}"
      },
      {
        "title": "CSS Animation",
        "body": "@keyframes shimmer {\n  0% { background-position: 200% 0; }\n  100% { background-position: -200% 0; }\n}\n\n.animate-shimmer {\n  animation: shimmer 1.5s ease-in-out infinite;\n}"
      },
      {
        "title": "Card Skeleton",
        "body": "export function CardSkeleton() {\n  return (\n    <div className=\"rounded-lg border bg-card p-4 space-y-3\">\n      <div className=\"flex items-center gap-3\">\n        <Skeleton className=\"size-10 rounded-full\" />\n        <div className=\"space-y-1.5 flex-1\">\n          <Skeleton className=\"h-4 w-1/3\" />\n          <Skeleton className=\"h-3 w-1/4\" />\n        </div>\n      </div>\n      <Skeleton className=\"h-20 w-full\" />\n      <div className=\"flex gap-2\">\n        <Skeleton className=\"h-8 w-20\" />\n        <Skeleton className=\"h-8 w-20\" />\n      </div>\n    </div>\n  );\n}"
      },
      {
        "title": "Table Row Skeleton",
        "body": "export function TableRowSkeleton({ columns = 4 }: { columns?: number }) {\n  return (\n    <tr>\n      {Array.from({ length: columns }).map((_, i) => (\n        <td key={i} className=\"p-3\">\n          <Skeleton className=\"h-4 w-full\" />\n        </td>\n      ))}\n    </tr>\n  );\n}"
      },
      {
        "title": "Metric Skeleton",
        "body": "export function MetricSkeleton() {\n  return (\n    <div className=\"space-y-2\">\n      <Skeleton className=\"h-3 w-16\" />\n      <Skeleton className=\"h-8 w-24\" />\n    </div>\n  );\n}"
      },
      {
        "title": "Pattern 3: Design System Skeleton",
        "body": "Match skeleton to your aesthetic:\n\n// For retro-futuristic theme\nexport function CyberSkeleton({ className, ...props }: SkeletonProps) {\n  return (\n    <div\n      className={cn(\n        'rounded-md bg-tone-cadet/30',\n        'animate-pulse-glow',\n        'border border-tone-cyan/10',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\n// CSS\n@keyframes pulse-glow {\n  0%, 100% { opacity: 0.4; box-shadow: 0 0 0 0 rgba(var(--tone-cyan), 0); }\n  50% { opacity: 0.6; box-shadow: 0 0 8px 0 rgba(var(--tone-cyan), 0.1); }\n}"
      },
      {
        "title": "Pattern 4: Progressive Loading",
        "body": "Show content as it loads:\n\ninterface ProgressiveLoadProps {\n  isLoading: boolean;\n  skeleton: React.ReactNode;\n  children: React.ReactNode;\n}\n\nexport function ProgressiveLoad({\n  isLoading,\n  skeleton,\n  children,\n}: ProgressiveLoadProps) {\n  return (\n    <div className=\"relative\">\n      {isLoading ? (\n        skeleton\n      ) : (\n        <motion.div\n          initial={{ opacity: 0 }}\n          animate={{ opacity: 1 }}\n          transition={{ duration: 0.2 }}\n        >\n          {children}\n        </motion.div>\n      )}\n    </div>\n  );\n}"
      },
      {
        "title": "Pattern 5: Streaming Content Indicator",
        "body": "For AI/LLM content that streams:\n\nexport function StreamingIndicator() {\n  return (\n    <div className=\"flex items-center gap-1\">\n      {[0, 1, 2].map((i) => (\n        <motion.div\n          key={i}\n          className=\"size-1.5 rounded-full bg-primary\"\n          animate={{ scale: [1, 1.3, 1], opacity: [0.5, 1, 0.5] }}\n          transition={{\n            duration: 0.8,\n            repeat: Infinity,\n            delay: i * 0.15,\n          }}\n        />\n      ))}\n    </div>\n  );\n}"
      },
      {
        "title": "Pattern 6: Loading Progress Bar",
        "body": "interface LoadingProgressProps {\n  progress?: number; // 0-100, undefined = indeterminate\n}\n\nexport function LoadingProgress({ progress }: LoadingProgressProps) {\n  const isIndeterminate = progress === undefined;\n\n  return (\n    <div className=\"h-1 w-full bg-muted overflow-hidden rounded-full\">\n      <div\n        className={cn(\n          'h-full bg-primary transition-all duration-300',\n          isIndeterminate && 'animate-indeterminate'\n        )}\n        style={!isIndeterminate ? { width: `${progress}%` } : undefined}\n      />\n    </div>\n  );\n}\n\n// CSS\n@keyframes indeterminate {\n  0% { transform: translateX(-100%); width: 50%; }\n  100% { transform: translateX(200%); width: 50%; }\n}\n\n.animate-indeterminate {\n  animation: indeterminate 1.5s ease-in-out infinite;\n}"
      },
      {
        "title": "Pattern 7: Skeleton Grid",
        "body": "export function GridSkeleton({ \n  count = 6, \n  columns = 3 \n}: { \n  count?: number; \n  columns?: number;\n}) {\n  return (\n    <div \n      className=\"grid gap-4\" \n      style={{ gridTemplateColumns: `repeat(${columns}, 1fr)` }}\n    >\n      {Array.from({ length: count }).map((_, i) => (\n        <CardSkeleton key={i} />\n      ))}\n    </div>\n  );\n}"
      },
      {
        "title": "Related Skills",
        "body": "Meta-skill: ai/skills/meta/design-system-creation/ — Complete design system workflow\ndistinctive-design-systems — Aesthetic matching for themed skeletons"
      },
      {
        "title": "NEVER Do",
        "body": "Use gray skeletons on dark themes — Match your surface colors\nSkip shimmer animation — Static blocks look broken\nMake skeletons exact size — Slight size variation is natural\nForget aspect ratios — Images need consistent skeleton ratios\nShow skeleton forever — Add timeout fallbacks for errors"
      },
      {
        "title": "Quick Reference",
        "body": "// Basic skeleton\n<Skeleton className=\"h-4 w-full\" />\n\n// Avatar skeleton\n<Skeleton className=\"size-10 rounded-full\" />\n\n// Text lines\n<div className=\"space-y-2\">\n  <Skeleton className=\"h-4 w-3/4\" />\n  <Skeleton className=\"h-4 w-1/2\" />\n</div>\n\n// Card skeleton\n<div className=\"p-4 space-y-3\">\n  <Skeleton className=\"h-6 w-1/3\" />\n  <Skeleton className=\"h-20 w-full\" />\n</div>"
      }
    ],
    "body": "Loading State Patterns\n\nBuild loading states that feel intentional and match your design system aesthetic.\n\nWhen to Use\nBuilding skeleton loaders for content areas\nNeed shimmer effects for streaming content\nWant progressive loading experiences\nBuilding premium loading UX\nPattern 1: Skeleton Base\nimport { cn } from '@/lib/utils';\n\ninterface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n  shimmer?: boolean;\n}\n\nexport function Skeleton({ className, shimmer = true, ...props }: SkeletonProps) {\n  return (\n    <div\n      className={cn(\n        'rounded-md bg-muted',\n        shimmer && 'animate-shimmer bg-gradient-to-r from-muted via-muted-foreground/10 to-muted bg-[length:200%_100%]',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nCSS Animation\n@keyframes shimmer {\n  0% { background-position: 200% 0; }\n  100% { background-position: -200% 0; }\n}\n\n.animate-shimmer {\n  animation: shimmer 1.5s ease-in-out infinite;\n}\n\nPattern 2: Content Skeleton Layouts\nCard Skeleton\nexport function CardSkeleton() {\n  return (\n    <div className=\"rounded-lg border bg-card p-4 space-y-3\">\n      <div className=\"flex items-center gap-3\">\n        <Skeleton className=\"size-10 rounded-full\" />\n        <div className=\"space-y-1.5 flex-1\">\n          <Skeleton className=\"h-4 w-1/3\" />\n          <Skeleton className=\"h-3 w-1/4\" />\n        </div>\n      </div>\n      <Skeleton className=\"h-20 w-full\" />\n      <div className=\"flex gap-2\">\n        <Skeleton className=\"h-8 w-20\" />\n        <Skeleton className=\"h-8 w-20\" />\n      </div>\n    </div>\n  );\n}\n\nTable Row Skeleton\nexport function TableRowSkeleton({ columns = 4 }: { columns?: number }) {\n  return (\n    <tr>\n      {Array.from({ length: columns }).map((_, i) => (\n        <td key={i} className=\"p-3\">\n          <Skeleton className=\"h-4 w-full\" />\n        </td>\n      ))}\n    </tr>\n  );\n}\n\nMetric Skeleton\nexport function MetricSkeleton() {\n  return (\n    <div className=\"space-y-2\">\n      <Skeleton className=\"h-3 w-16\" />\n      <Skeleton className=\"h-8 w-24\" />\n    </div>\n  );\n}\n\nPattern 3: Design System Skeleton\n\nMatch skeleton to your aesthetic:\n\n// For retro-futuristic theme\nexport function CyberSkeleton({ className, ...props }: SkeletonProps) {\n  return (\n    <div\n      className={cn(\n        'rounded-md bg-tone-cadet/30',\n        'animate-pulse-glow',\n        'border border-tone-cyan/10',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\n// CSS\n@keyframes pulse-glow {\n  0%, 100% { opacity: 0.4; box-shadow: 0 0 0 0 rgba(var(--tone-cyan), 0); }\n  50% { opacity: 0.6; box-shadow: 0 0 8px 0 rgba(var(--tone-cyan), 0.1); }\n}\n\nPattern 4: Progressive Loading\n\nShow content as it loads:\n\ninterface ProgressiveLoadProps {\n  isLoading: boolean;\n  skeleton: React.ReactNode;\n  children: React.ReactNode;\n}\n\nexport function ProgressiveLoad({\n  isLoading,\n  skeleton,\n  children,\n}: ProgressiveLoadProps) {\n  return (\n    <div className=\"relative\">\n      {isLoading ? (\n        skeleton\n      ) : (\n        <motion.div\n          initial={{ opacity: 0 }}\n          animate={{ opacity: 1 }}\n          transition={{ duration: 0.2 }}\n        >\n          {children}\n        </motion.div>\n      )}\n    </div>\n  );\n}\n\nPattern 5: Streaming Content Indicator\n\nFor AI/LLM content that streams:\n\nexport function StreamingIndicator() {\n  return (\n    <div className=\"flex items-center gap-1\">\n      {[0, 1, 2].map((i) => (\n        <motion.div\n          key={i}\n          className=\"size-1.5 rounded-full bg-primary\"\n          animate={{ scale: [1, 1.3, 1], opacity: [0.5, 1, 0.5] }}\n          transition={{\n            duration: 0.8,\n            repeat: Infinity,\n            delay: i * 0.15,\n          }}\n        />\n      ))}\n    </div>\n  );\n}\n\nPattern 6: Loading Progress Bar\ninterface LoadingProgressProps {\n  progress?: number; // 0-100, undefined = indeterminate\n}\n\nexport function LoadingProgress({ progress }: LoadingProgressProps) {\n  const isIndeterminate = progress === undefined;\n\n  return (\n    <div className=\"h-1 w-full bg-muted overflow-hidden rounded-full\">\n      <div\n        className={cn(\n          'h-full bg-primary transition-all duration-300',\n          isIndeterminate && 'animate-indeterminate'\n        )}\n        style={!isIndeterminate ? { width: `${progress}%` } : undefined}\n      />\n    </div>\n  );\n}\n\n// CSS\n@keyframes indeterminate {\n  0% { transform: translateX(-100%); width: 50%; }\n  100% { transform: translateX(200%); width: 50%; }\n}\n\n.animate-indeterminate {\n  animation: indeterminate 1.5s ease-in-out infinite;\n}\n\nPattern 7: Skeleton Grid\nexport function GridSkeleton({ \n  count = 6, \n  columns = 3 \n}: { \n  count?: number; \n  columns?: number;\n}) {\n  return (\n    <div \n      className=\"grid gap-4\" \n      style={{ gridTemplateColumns: `repeat(${columns}, 1fr)` }}\n    >\n      {Array.from({ length: count }).map((_, i) => (\n        <CardSkeleton key={i} />\n      ))}\n    </div>\n  );\n}\n\nRelated Skills\nMeta-skill: ai/skills/meta/design-system-creation/ — Complete design system workflow\ndistinctive-design-systems — Aesthetic matching for themed skeletons\nNEVER Do\nUse gray skeletons on dark themes — Match your surface colors\nSkip shimmer animation — Static blocks look broken\nMake skeletons exact size — Slight size variation is natural\nForget aspect ratios — Images need consistent skeleton ratios\nShow skeleton forever — Add timeout fallbacks for errors\nQuick Reference\n// Basic skeleton\n<Skeleton className=\"h-4 w-full\" />\n\n// Avatar skeleton\n<Skeleton className=\"size-10 rounded-full\" />\n\n// Text lines\n<div className=\"space-y-2\">\n  <Skeleton className=\"h-4 w-3/4\" />\n  <Skeleton className=\"h-4 w-1/2\" />\n</div>\n\n// Card skeleton\n<div className=\"p-4 space-y-3\">\n  <Skeleton className=\"h-6 w-1/3\" />\n  <Skeleton className=\"h-20 w-full\" />\n</div>"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/wpank/loading-state-patterns",
    "publisherUrl": "https://clawhub.ai/wpank/loading-state-patterns",
    "owner": "wpank",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/loading-state-patterns",
    "downloadUrl": "https://openagent3.xyz/downloads/loading-state-patterns",
    "agentUrl": "https://openagent3.xyz/skills/loading-state-patterns/agent",
    "manifestUrl": "https://openagent3.xyz/skills/loading-state-patterns/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/loading-state-patterns/agent.md"
  }
}