Preanimate

Per-component skeleton swap. Renders a placeholder until ready flips, then mounts the real content — so its entrance animations (SplitReveal, Stagger, etc.) fire exactly when the skeleton disappears, not while it's still on screen.

Usage

import { PreanimateProvider, Preanimate, Skeleton, SplitReveal } from '@bwo-ui/react';

<PreanimateProvider duration={900}>
  <Preanimate skeleton={<Skeleton height={48} style={{ width: 320 }} />}>
    <SplitReveal as="h1" type="words" stagger={0.04}>
      Real title that animates in
    </SplitReveal>
  </Preanimate>
</PreanimateProvider>

Pair multiple Preanimate swaps under a single PreanimateProvider so they share one ready signal and flip in sync.

PreanimateProvider props

PropTypeDefaultDescription
durationnumber1000Auto-flip ready=true after this many ms.
readybooleanExternal control. When set, `duration` is ignored.

Preanimate props

PropTypeDefaultDescription
skeletonReactNodeRendered while not ready. Should occupy the same dimensions as the real content.
childrenReactNodeReal content. Not mounted until ready — entrance animations fire on swap.
delaynumberExtra ms to wait *after* the provider's base ready flips before mounting children. Use to cascade entrances (e.g. cards waiting for the hero typewriter to finish).

Cascading entrances

Each Preanimate under one provider can stage its own ready time with delay. Total wait per section is provider.duration + delay.

<PreanimateProvider duration={900}>
  {/* mounts at 900ms — hero starts typing */}
  <Preanimate skeleton={<TitleSkeleton />}>
    <Typewriter lines={[...]} />
  </Preanimate>

  {/* mounts at 900 + 1500 = 2400ms — by then the typewriter is well into reveal */}
  <Preanimate skeleton={<ShowcaseSkeleton />} delay={1500}>
    <Stagger>...cards...</Stagger>
  </Preanimate>
</PreanimateProvider>

usePreanimate()

Drop-in hook returning the shared ready boolean. Useful when you need to conditionally swap parts of a single component:

function Card() {
  const ready = usePreanimate();
  return ready ? <RealCard /> : <CardSkeleton />;
}