Feedback & status
Skeleton
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
Loaded profile description.
Loaded profile description.
Recorded states
loadingrecorded state; no setterreduced motionrecorded state; no setter
Usage
Import
import '/components/skeleton/define.js';
// or register it yourself
import { DetentSkeleton } from '/components/skeleton/skeleton.js';
Attributes
linesloadingsize
Properties
linessizeloadingmode
Slots
defaultskeleton
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.tsxsha256 92a3332a97dc…
Native files
The native module and its artifacts:
src/components/skeleton/skeleton.tssrc/components/skeleton/styles.csssrc/components/skeleton/define.tsdocs/components/skeleton.mdsite/examples/skeleton.tstests/browser/skeleton.spec.tsevidence/components/skeleton.md
API
Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.
Attributes
| Attribute | Property | Type | Default | Notes |
|---|---|---|---|---|
lines | lines | number | 3 | Kebab-case attribute; camelCase property. |
loading | loading | boolean | undefined | Presence semantics: present means true, absent means false. |
size | size | number | 40 | Kebab-case attribute; camelCase property. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
lines | number | 3 | Property-only: assign from script; not accepted as an attribute. |
size | number | 40 | Property-only: assign from script; not accepted as an attribute. |
loading | boolean | undefined | Property-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
| Slot | Notes |
|---|---|
default | Consumer content; rendered through a slot, never re-created. |
skeleton | Consumer 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.