Detent web components
By Shane Logsdon

Feedback & status

Skeleton

Implemented

Shimmering placeholder that reveals content

detent-skeleton

Port status
Catalog status
implemented
Origin
upstream
Phase
2
Wave
phase-2-feedback
Group
Feedback & status

3.1 KB gzip for the class module

Variants

block
text preset
avatar preset
reveal while loading

Loaded profile description.

reveal after loading

Loaded profile description.

Recorded states

  • loading recorded state; no setter
  • reduced motion recorded state; no setter

Usage

Import

import '/components/skeleton/define.js';

// or register it yourself
import { DetentSkeleton } from '/components/skeleton/skeleton.js';

Attributes

  • lines
  • loading
  • size

Properties

  • lines
  • size
  • loading
  • mode

Slots

  • default
  • skeleton

Events

No events are recorded for this component.

Example

Runnable example: site/examples/skeleton.ts. The snippet below is generated from the catalogued attributes.

<detent-skeleton
  lines="3"
  loading
  size="40"
></detent-skeleton>

Source

The pinned upstream source for this row:

  • src/components/ui/skeleton.tsx sha256 92a3332a97dc…

Native files

The native module and its artifacts:

  • src/components/skeleton/skeleton.ts
  • src/components/skeleton/styles.css
  • src/components/skeleton/define.ts
  • docs/components/skeleton.md
  • site/examples/skeleton.ts
  • tests/browser/skeleton.spec.ts
  • evidence/components/skeleton.md

API

Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.

Attributes

Attributes
AttributePropertyTypeDefaultNotes
lineslinesnumber3Kebab-case attribute; camelCase property.
loadingloadingbooleanundefinedPresence semantics: present means true, absent means false.
sizesizenumber40Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
linesnumber3Property-only: assign from script; not accepted as an attribute.
sizenumber40Property-only: assign from script; not accepted as an attribute.
loadingbooleanundefinedProperty-only: assign from script; not accepted as an attribute.
mode——Recorded in the catalog without a top-level type; pinned from source when the row is ported.

Events

No custom events are recorded for this component.

Slots

Slots
SlotNotes
defaultConsumer content; rendered through a slot, never re-created.
skeletonConsumer content; rendered through a slot, never re-created.

CSS customisation

  • React `children`/`ReactNode` props become DOM slots; caller content stays light DOM.
  • `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • Upstream's four exports (Skeleton, SkeletonText, SkeletonAvatar, SkeletonReveal) map to four documented modes of one tag (`mode="block"|"text"|"avatar"|"reveal"`), because `define.ts` registers exactly one tag (PC-13.1).
  • `lines` (default 3) and `size` (default 40) are property defaults and are not reflected into attributes, so a bare element stays the single-block Skeleton instead of always rendering text lines.
  • `children` becomes the default slot and `skeleton` the `skeleton` slot; the default slot renders only in reveal mode.
  • The shimmer is a CSS keyframe sweep (1.6s ease-in-out, 0.2s delay) and the reveal is a WAAPI fade/rise/un-blur (0.3s, cubic-bezier(0.32,0.72,0,1)); no spring is involved so PC-10.4 is not engaged.
  • `AnimatePresence` subtree swapping is replaced by persistent wrappers + `hidden`, so consumer nodes are never removed or re-created.
  • Accessibility correction: upstream renders both `aria-label="Loading"` and an sr-only label (duplicate announcement); this port sets the live-region label only while loading.

What it does

Quiet shimmer placeholders and a reveal wrapper that swaps a placeholder for live content.

Upstream behaviour
  • Quiet shimmer blocks with smooth gradient light sweep animation
  • SkeletonReveal transitions seamlessly to live content using fade, subtle rise, and un-blur
  • Convenient SkeletonText preset with natural staggered line length distribution
  • SkeletonAvatar preset for profile pictures and user thumbnails
  • Clean reduced-motion fallback that disables continuous sweeping
Differences from upstream
  • React `children`/`ReactNode` props become DOM slots; caller content stays light DOM.
  • `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • Upstream's four exports (Skeleton, SkeletonText, SkeletonAvatar, SkeletonReveal) map to four documented modes of one tag (`mode="block"|"text"|"avatar"|"reveal"`), because `define.ts` registers exactly one tag (PC-13.1).
  • `lines` (default 3) and `size` (default 40) are property defaults and are not reflected into attributes, so a bare element stays the single-block Skeleton instead of always rendering text lines.
  • `children` becomes the default slot and `skeleton` the `skeleton` slot; the default slot renders only in reveal mode.
  • The shimmer is a CSS keyframe sweep (1.6s ease-in-out, 0.2s delay) and the reveal is a WAAPI fade/rise/un-blur (0.3s, cubic-bezier(0.32,0.72,0,1)); no spring is involved so PC-10.4 is not engaged.
  • `AnimatePresence` subtree swapping is replaced by persistent wrappers + `hidden`, so consumer nodes are never removed or re-created.
  • Accessibility correction: upstream renders both `aria-label="Loading"` and an sr-only label (duplicate announcement); this port sets the live-region label only while loading.
Previous: Sign Up Next: SlidePagination

Docs

Components

Project