Files
skills/docs/ui/react/react-ui/src/components/skeleton/skeleton.md
2026-05-29 08:20:56 +01:00

5.9 KiB

Skeleton

(no submodules)

- skeleton.variants — `skeletonVariants` is the cva (…
  • skeleton.variants — skeletonVariants is the cva (class-variance-authority) configuration that powers every <Skeleton> render. It is spl…

  • skeleton.variants — skeletonVariants is the cva (…

  • skeleton.variants — skeletonVariants is the cva (class-variance-authority) configuration that powers every <Skeleton> render. It is spl…

  • skeleton.variants — skeletonVariants is the cva (…

  • skeleton.variants — skeletonVariants is the cva (class-variance-authority) configuration that powers every <Skeleton> render. It is spl…

  • skeleton.variants — skeletonVariants is the cva (…

  • skeleton.variants — skeletonVariants is the cva (class-variance-authority) configuration that powers every <Skeleton> render. It is spl…

  • skeleton.variants — skeletonVariants is the cva (class-variance-authority) configuration that powers every <Skeleton> render. It is spl…

Purpose

<Skeleton> is the chassis loading-placeholder primitive for @suaveplan/react-ui. It renders a muted-background <div> with a pulse animation that occupies the layout space of content the consumer has not yet finished loading. The pulse animation is gated behind motion-safe:animate-pulse so users with prefers-reduced-motion: reduce see a static placeholder block; everyone else gets the standard shadcn pulse.

The component is a pure visual placeholder — sizing, layout, and aspect-ratio control come from consumer-supplied className (h-4 w-32, h-12 w-12 rounded-full for an avatar placeholder, etc.). The chassis surface is intentionally minimal so consumers can compose any skeleton layout they need without fighting opinionated defaults.

Features

  • Single default cva variant; consumer-supplied className carries the sizing.
  • motion-safe:animate-pulse + motion-reduce:animate-none — animation is gated by prefers-reduced-motion so reduced-motion users see a static placeholder.
  • data-skeleton="true" attribute on the rendered element so tests / screen-readers / consumer CSS can target every skeleton placeholder via a single selector.
  • Forwards refs to the underlying <div>.
  • All native HTMLAttributes are forwarded as-is so consumers can drop aria-hidden, role, id, aria-label, etc.
  • Theme variant overrides via useThemedVariants("Skeleton", skeletonVariants). A ThemePlugin.variantOverrides.Skeleton may add brand-new variants (e.g. variant: "shimmer" for a more elaborate animation).

Usage: Basic Example

import { Skeleton } from "@suaveplan/react-ui";

export function PostPreview() {
    return (
        <div className="flex flex-col gap-2">
            <Skeleton className="h-4 w-3/4" />
            <Skeleton className="h-4 w-full" />
            <Skeleton className="h-4 w-1/2" />
        </div>
    );
}

Usage: Advanced Example

import { Skeleton } from "@suaveplan/react-ui";

export function UserCardSkeleton() {
    return (
        <div className="flex items-center gap-3" role="status" aria-busy="true">
            <Skeleton
                className="h-12 w-12 rounded-full"
                aria-label="loading-avatar"
            />
            <div className="flex flex-col gap-2">
                <Skeleton className="h-4 w-32" />
                <Skeleton className="h-4 w-48" />
            </div>
        </div>
    );
}

API Reference

<Skeleton>

forwardRef<HTMLDivElement, SkeletonProps> — renders a <div> with the variant classes + consumer-supplied className merged via cn().

SkeletonProps

Prop Type Default Description
variant "default" "default" Visual variant; the chassis ships only default so themes carry the variation.
all HTMLAttributes<HTMLDivElement> native native Forwarded as-is (className, style, id, aria-*, role, etc.).

skeletonVariants

The bare cva resolver. Exported so external consumers (@suaveplan/react-ui-theme-*, ejected source under npx shadcn@latest add @suaveplan/skeleton) can re-use the variants directly without going through useThemedVariants.

Errors

The Skeleton component does NOT call useTranslation() so it does not interact with the i18n provider at all. It is safe to render outside a <TranslationProvider> / <ReactUiProvider>.

Implementation Notes

  • The chassis hardcodes motion-safe:animate-pulse and motion-reduce:animate-none into the cva base rather than driving them off motionTokens.respectReducedMotion because Tailwind's motion-safe / motion-reduce variants honour prefers-reduced-motion natively at the CSS layer — no JS reactivity required.
  • data-skeleton="true" is always written so consumer CSS / tests can target every skeleton via [data-skeleton="true"]. The chassis does not omit it when other attributes change.
  • The variants module is intentionally separate (skeleton.variants.ts) so an ejected source copy keeps the cva config in a dedicated file, mirroring the upstream shadcn convention.
  • useThemedVariants("Skeleton", skeletonVariants) is called unconditionally so the hook order is stable across renders. The hook's memoisation key is (themeName, "Skeleton") so a re-render with the same theme returns the same resolver reference.
  • bg-muted is the cva-applied background colour; the actual colour value comes from the active theme's cssVariables.muted token.
  • The chassis does NOT inject role="status" automatically — consumer composition decides whether the surrounding container should be an ARIA live region. A user-card skeleton is typically wrapped in <div role="status" aria-busy="true"> so AT announces the loading state once for the whole group, not once per skeleton primitive.