docs / sula / sula-loader

SulaLoader

a loading moment made of liquid glass. each loop stages one physical event: a bead tears free and returns, drops gather and scatter, or two masses trade momentum through a bridge. the loader unmounts the moment the work lands.

intensity · assertsrsc · client

provenance

authored in usva

layer

sula

intensity

asserts · one per region. it is the focal point

composition

the big wait: a route change, a splash, an empty panel, a hero settling inone per screen. it is the focal point while nothing else existsnot the spinner for a button, a table row, or a validating field. that is Spinnernever left looping behind a finished page

a11y

role="status" with aria-busy, announces its label · the field is aria-hidden · reduced motion gets the stilljest-axe

dependencies

motion · ogl · sula-core from the same package
live demo · try it out
Loading

recoil, release, return

customize
motionwhich looping event it stages
sizesquare side in px
96
speedloop-rate multiplier
1
labelthe announced status
fluidoff renders the static still
shine0 matte glass, 1 full neon rim
0.7
usagecopy
import { SulaLoader } from "@usva-ui/react/sula/sula-loader";

<SulaLoader />
the still · fluid={false}, reduced motion, or no WebGL2
Loading
Loading
Loading

props

proptypedefaultnotes
sizenumber96square side in px. the blobs scale off it, so this is the only sizing knob.
motion"orbit" | "cluster" | "twin""orbit"orbit relays a released bead; cluster gathers three unequal drops; twin exchanges momentum between two masses.
speednumber1loop-rate multiplier. higher is faster.
labelstring"Loading"the status text a screen reader announces.
fluidbooleantruefalse renders a static still and mounts no canvas.
accentColorstringrim light and glow on the droplets. defaults to the accent token.
backdropstringthe colour the glass tints against. defaults to the bg token.
tintstringthe glass itself. defaults to the surface-2 token.
shinenumber0 is flat matte glass, 1 is the full neon rim. derived from the backdrop when unset.

get it

bun add @usva-ui/reactcopy
usagecopy
import { SulaLoader } from "@usva-ui/react/sula/sula-loader";

{isPending ? <SulaLoader label="Loading dashboard" /> : <Dashboard />}