components / 20
marked skeleton
loading should reserve the real layout without pretending to be light. solid marker passes show that the page is still being drawn.
shadcn
npx shadcn@latest add berkantay/cheez/marked-skeletonlive
solid ink, never shimmerplayground
loading preview
shape
motion
character
ink
<MarkedSkeletonGroup label="loading profile">
<MarkedSkeleton
shape="rounded"
motion="draw"
tone="purple"
character="rushed"
/>
<MarkedSkeletonText lines={3} tone="purple" />
</MarkedSkeletonGroup>geometry
each gets a different marker handfour useful shapes
copy
not every line ends togethertext has rhythm
motion
the geometry never movesthree levels of urgency
draw
active work
breathe
quiet waiting
none
motion disabled
composition
primitive pieces, stable dimensionsreal loading layouts
loading article
loading people
loading dashboard
lifecycle
no layout jumpsame box, real content
loading article
reference
primitive, text, and groupapi
| prop | type | default | purpose |
|---|---|---|---|
shape | "line" | "block" | "rounded" | "circle" | "line" | geometry and default drawing |
motion | "draw" | "breathe" | "none" | "draw" | solid ink movement |
tone | MarkedSkeletonTone | "neutral" | built-in ink palette |
color | string | tone color | custom ink override |
width | CSSProperties['width'] | shape-aware | reserved horizontal space |
height | CSSProperties['height'] | shape-aware | reserved vertical space |
mark | CheezType | shape-aware | marker drawing override |
character | CheezCharacter | "rushed" | drawing personality |
duration | number | 1800 | motion cycle in milliseconds |
delay | number | 0 | stagger offset in milliseconds |
Text.lines | number | 3 | number of generated rows |
Text.lineWidths | CSS width[] | full rows | explicit rhythm per row |
Text.lastLineWidth | CSS width | "68%" | automatic final row width |
Text.lineHeight | CSS height | 12 | height of each text row |
Text.gap | CSS gap | 8 | space between rows |
Group.label | string | "loading content" | single spoken loading message |
Group.busy | boolean | true | aria-busy state |
Group.politeness | "off" | "polite" | "assertive" | "polite" | live-region priority |
behavior notes
- the base reserves exact dimensions while a clipped Cheez marker pass redraws above it
- there is no shimmer, gradient, translated geometry, or dependency beyond Cheez
- individual placeholders are hidden from assistive technology
- MarkedSkeletonGroup announces one useful loading message and exposes aria-busy
- reduced-motion preferences keep the ink visible and stop every loop
- match final content dimensions to prevent cumulative layout shift