Skip to content

components skeleton

GitHub Actions edited this page Sep 18, 2026 · 2 revisions

components/skeleton

Import: import { Skeleton, SkeletonTable, SkeletonCard } from "@tundralibs/ui/skeleton"

Rendered in every variant on the catalogue (deno task build:demos, then demo/index.html). Guides: Getting started · rAPId integration · Theming.

Functions

Skeleton

Skeleton(props = : SkeletonProps): Html

Pairs with data-load: render the skeleton server-side, let the lazy GET swap in the real fragment. Match the real content's box or it will jump.

SkeletonTable

SkeletonTable(props = : SkeletonTableProps): Html

SkeletonCard

SkeletonCard(): Html

Types

SkeletonWidth

Width steps map to .skeleton--w-* classes (see skeleton.css) — a fixed scale rather than an arbitrary length, so no inline style is ever emitted (CSP). Pick the step closest to the content's box.

  • "xs"
  • "sm"
  • "md"
  • "lg"
  • "xl"
  • "half"
  • "full"

SkeletonProps

Prop Type Required Description
variant `"text" "title" "block"
width SkeletonWidth

SkeletonTableProps

Prop Type Required Description
rows number
columns SkeletonWidth[][]

Usage

Each example as the rAPId call and the HTML it renders — the markup a plain page writes by hand. Icons are inline SVG in the real output; they are shortened to <svg …>…</svg> here.

A table region while it loads

Render it as the initial content of a data-load region; the server's fragment replaces it.

html`<div id="orders" data-load data-action="/fragments/orders">${
  SkeletonTable({ rows: 3, columns: [["lg", "sm", "xs"], ["lg", "sm", "xs"]] })
}</div>`
<div id="orders" data-load data-action="/fragments/orders">
  <div class="skeleton-table" aria-busy="true">
    <div class="skeleton-table__head">
      <span class="skeleton skeleton--text skeleton--w-sm" aria-hidden="true"></span>
      <span class="skeleton skeleton--text skeleton--w-xs" aria-hidden="true"></span>
    </div>
    <div class="skeleton-table__row">
      <span class="skeleton skeleton--text skeleton--w-lg" aria-hidden="true"></span>
      <span class="skeleton skeleton--text skeleton--w-sm" aria-hidden="true"></span>
      <span class="skeleton skeleton--text skeleton--w-xs" aria-hidden="true"></span>
    </div>
    <div class="skeleton-table__row">
      <span class="skeleton skeleton--text skeleton--w-lg" aria-hidden="true"></span>
      <span class="skeleton skeleton--text skeleton--w-sm" aria-hidden="true"></span>
      <span class="skeleton skeleton--text skeleton--w-xs" aria-hidden="true"></span>
    </div>
    <div class="skeleton-table__row">
      <span class="skeleton skeleton--text skeleton--w-lg" aria-hidden="true"></span>
      <span class="skeleton skeleton--text skeleton--w-sm" aria-hidden="true"></span>
      <span class="skeleton skeleton--text skeleton--w-xs" aria-hidden="true"></span>
    </div>
  </div>
</div>

A card placeholder

SkeletonCard()
<div class="skeleton-card" aria-busy="true">
  <span class="skeleton skeleton--block" aria-hidden="true"></span>
  <span class="skeleton skeleton--title" aria-hidden="true"></span>
  <span class="skeleton skeleton--text skeleton--w-full" aria-hidden="true"></span>
  <span class="skeleton skeleton--text skeleton--w-half" aria-hidden="true"></span>
</div>

CSS hooks

Classes defined by components/skeleton/skeleton.css — structural, token-driven; override from an unlayered stylesheet (see Theming):

.skeleton, .skeleton--avatar, .skeleton--block, .skeleton--circle, .skeleton--text, .skeleton--title, .skeleton--w-full, .skeleton--w-half, .skeleton--w-lg, .skeleton--w-md, .skeleton--w-sm, .skeleton--w-xl, .skeleton--w-xs, .skeleton-card, .skeleton-row, .skeleton-stack, .skeleton-table, .skeleton-table__head, .skeleton-table__row

Clone this wiki locally