5.9 KiB
Skeleton
(no submodules)
- skeleton.variants — `skeletonVariants` is the cva (…-
skeleton.variants —
skeletonVariantsis the cva (class-variance-authority) configuration that powers every<Skeleton>render. It is spl… -
skeleton.variants —
skeletonVariantsis the cva (… -
skeleton.variants —
skeletonVariantsis the cva (class-variance-authority) configuration that powers every<Skeleton>render. It is spl… -
skeleton.variants —
skeletonVariantsis the cva (… -
skeleton.variants —
skeletonVariantsis the cva (class-variance-authority) configuration that powers every<Skeleton>render. It is spl… -
skeleton.variants —
skeletonVariantsis the cva (… -
skeleton.variants —
skeletonVariantsis the cva (class-variance-authority) configuration that powers every<Skeleton>render. It is spl… -
skeleton.variants —
skeletonVariantsis 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
defaultcva variant; consumer-suppliedclassNamecarries the sizing. motion-safe:animate-pulse+motion-reduce:animate-none— animation is gated byprefers-reduced-motionso 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
HTMLAttributesare forwarded as-is so consumers can droparia-hidden,role,id,aria-label, etc. - Theme variant overrides via
useThemedVariants("Skeleton", skeletonVariants). AThemePlugin.variantOverrides.Skeletonmay 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-pulseandmotion-reduce:animate-noneinto the cva base rather than driving them offmotionTokens.respectReducedMotionbecause Tailwind'smotion-safe/motion-reducevariants honourprefers-reduced-motionnatively 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-mutedis the cva-applied background colour; the actual colour value comes from the active theme'scssVariables.mutedtoken.- 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.