Pular para o conteúdo

Skeleton (loading placeholder)

components specs/components/skeleton.kmd

Skeleton placeholder primitives — block / line / circle / image — that mirror the final content shape during load. Reduces perceived load time and avoids cumulative layout shift on content swap. Modeled after Cedar (REI), Material 3, Polaris, Carbon.

Quando esta spec se aplica

Triggers primários

Todos os triggers

Corpo da especificação

Component — Skeleton

Status: v0.1.0 — Draft.

R1 — Primitives

PrimitiveDefault sizeUse for
KoderSkeletonBlockconfigurable W×H, rounded --kdr-radius-smCards, images, panels
KoderSkeletonLinefull width × --kdr-fs-base heightSingle line of text
KoderSkeletonCircleconfigurable radiusAvatars, status dots
KoderSkeletonImageconfigurable W×H, aspect-ratio preservedImage slots

Composers assemble these into placeholders mirroring the final layout (e.g., card skeleton = Image on top + 2 Lines + Block button).

R2 — Animation

  • Default: subtle shimmer — linear gradient sweep across the surface, 1.5s loop.
  • prefers-reduced-motion: reduce: static pulse (opacity 0.6 → 1.0 → 0.6, 2s loop). NO sweep.
  • prefers-reduced-motion: no-preference + battery saver / Data saver detected: also fall back to static pulse.

R3 — Shape mirroring

The skeleton MUST replace the final content's bounding box at the same dimensions. Acceptance: when content arrives and the skeleton is removed, NO layout shift on the surrounding page (CLS contribution = 0).

Anti-pattern: spinner-in-a-fixed-box → content fills box. That's NOT a skeleton; that's a spinner.

R4 — Accessibility

  • Surface wrapping the skeleton primitives carries aria-busy="true" and aria-label="Loading" (translatable per specs/i18n/contract.kmd).
  • Once content swaps in, aria-busy="false" and aria-label is removed.
  • Live-region MAY announce "Loading complete" on swap (per consumer choice; not mandated).

R5 — Color

  • Default light: --kdr-surface-2 for base + --kdr-surface for highlight.
  • Default dark: same tokens (which already swap per theme).
  • High-contrast / forced-colors media: skeleton uses Canvas and CanvasText system colors with a 1px border.

R6 — Composer pattern

For common shapes, KDS ships composer presets (in koder_kit / koder_web_kit):

  • KoderSkeletonCard
  • KoderSkeletonListRow
  • KoderSkeletonTableRow (consumed by data-table empty/loading per specs/components/data-table.kmd R12)
  • KoderSkeletonAvatar

R7 — OUIA

Per specs/testing/ouia-test-hooks.kmd:

  • data-ouia-component-type="Skeleton"
  • data-ouia-safe="false" always (skeleton IS the not-ready state).
  • The surface wrapping the skeleton ALSO carries the OUIA attrs of the eventual real component, with data-ouia-safe="false" until swap.

Não-escopo

  • Pre-fetched-content swap-in transitions (separate motion ticket).
  • Server-rendered skeletons (SSR) — out of v0; renders on client mount.

Referências