Feedback loadingskeleton

Skeleton Loader

Placeholder content for loading feeds.

Preview

Usage

Copy the full block below to use this component with its imports.

astro
---
import { SkeletonLoader } from 'astro-component-kit';
---

<SkeletonList count={4} />
--- import { SkeletonLoader } from 'astro-component-kit'; --- <SkeletonList count={4} />

Manual Installation

If you are not using the npm package, create a new file src/components/lib/SkeletonLoader.astro and paste the following code:

astro
---
/**
 * SkeletonList — Shimmering loading placeholder for lists or feed items.
 * 
 * @param {number} count - Number of skeleton items to render. Default is 3.
 */
interface Props {
  count?: number;
}

const { count = 3 } = Astro.props;
---

<div class="skeleton-list" aria-hidden="true">
  {Array.from({ length: count }).map(() => (
    <div class="skeleton-item">
      <div class="skeleton-avatar"></div>
      <div class="skeleton-content">
        <div class="skeleton-line skeleton-line--title"></div>
        <div class="skeleton-line skeleton-line--body"></div>
      </div>
    </div>
  ))}
</div>

<style>
  .skeleton-list { display: flex; flex-direction: column; width: 100%; }
  
  .skeleton-item { 
    display: flex; gap: var(--sp-4, 1rem); 
    padding: var(--sp-4, 1rem) 0; 
    border-bottom: 1px solid var(--c-border, rgba(255,255,255,0.05)); 
  }
  
  .skeleton-avatar { 
    width: 48px; height: 48px; 
    border-radius: var(--r-full, 50%); 
    background: var(--c-bg-elev, rgba(255,255,255,0.05)); 
    flex-shrink: 0;
  }
  
  .skeleton-content { flex: 1; display: flex; flex-direction: column; gap: 10px; justify-content: center; }
  
  .skeleton-line { 
    height: 12px; 
    background: var(--c-bg-elev, rgba(255,255,255,0.05)); 
    border-radius: var(--r-sm, 6px); 
    position: relative; overflow: hidden;
  }

  .skeleton-line--title { width: 40%; height: 14px; }
  .skeleton-line--body { width: 85%; }
  
  .skeleton-item div::after { 
    content: ""; 
    position: absolute; 
    inset: 0; 
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.04), transparent); 
    animation: skeleton-shimmer 1.8s infinite; 
    transform: translateX(-100%);
  }
  
  @keyframes skeleton-shimmer { 
    100% { transform: translateX(100%); } 
  }
</style>
--- /** * SkeletonList — Shimmering loading placeholder for lists or feed items. * * @param {number} count - Number of skeleton items to render. Default is 3. */ interface Props { count?: number; } const { count = 3 } = Astro.props; --- <div class="skeleton-list" aria-hidden="true"> {Array.from({ length: count }).map(() => ( <div class="skeleton-item"> <div class="skeleton-avatar"></div> <div class="skeleton-content"> <div class="skeleton-line skeleton-line--title"></div> <div class="skeleton-line skeleton-line--body"></div> </div> </div> ))} </div> <style> .skeleton-list { display: flex; flex-direction: column; width: 100%; } .skeleton-item { display: flex; gap: var(--sp-4, 1rem); padding: var(--sp-4, 1rem) 0; border-bottom: 1px solid var(--c-border, rgba(255,255,255,0.05)); } .skeleton-avatar { width: 48px; height: 48px; border-radius: var(--r-full, 50%); background: var(--c-bg-elev, rgba(255,255,255,0.05)); flex-shrink: 0; } .skeleton-content { flex: 1; display: flex; flex-direction: column; gap: 10px; justify-content: center; } .skeleton-line { height: 12px; background: var(--c-bg-elev, rgba(255,255,255,0.05)); border-radius: var(--r-sm, 6px); position: relative; overflow: hidden; } .skeleton-line--title { width: 40%; height: 14px; } .skeleton-line--body { width: 85%; } .skeleton-item div::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.04), transparent); animation: skeleton-shimmer 1.8s infinite; transform: translateX(-100%); } @keyframes skeleton-shimmer { 100% { transform: translateX(100%); } } </style>

Quick Info

Category
Feedback
Filename
SkeletonLoader.astro
Dependencies
None — pure Astro + CSS
Tags
loadingskeleton