BreathingBox
Wraps any child in a subtle breathing scale animation. Ambient decoration — the component that makes the "components that breathe" tagline literal. Opacity never changes, so children with text remain readable. Respects prefers-reduced-motion automatically.
I breathe softly and infinitely.
Installation
npm install @bloomkit/reactUsage
import { BreathingBox } from "@bloomkit/react";
<BreathingBox>
<Card>
<CardContent>I breathe softly and infinitely.</CardContent>
</Card>
</BreathingBox>Intensity
Three levels of breath: subtle (1.01), soft (1.02, default), and bold (1.04).
subtle
soft
bold
<BreathingBox intensity="subtle">
<Logo />
</BreathingBox>asChild
Use asChild to merge the animation directly onto the child element (via Radix Slot) instead of rendering a wrapper <div>. Useful for components that care about their DOM shape, like buttons.
<BreathingBox asChild>
<Button variant="primary">Breathing CTA</Button>
</BreathingBox>Staggered group
Pass different delay values to stagger multiple boxes so they don't pulse in unison.
<div className="flex gap-4">
<BreathingBox delay={0}><Dot /></BreathingBox>
<BreathingBox delay={1}><Dot /></BreathingBox>
<BreathingBox delay={2}><Dot /></BreathingBox>
</div>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | The content to breathe |
| intensity | "subtle" | "soft" | "bold" | "soft" | How pronounced the scale is (1.01 / 1.02 / 1.04) |
| duration | number | 6 | Length of one full breath cycle, in seconds |
| delay | number | 0 | Seconds to delay the animation. Use to stagger multiple boxes so they don't pulse in unison |
| asChild | boolean | false | Merge the animation into the child element (via Radix Slot) instead of rendering a wrapper div |
| className | string | — | Extra Tailwind classes |
| style | CSSProperties | — | Extra inline styles. User styles win for non-animation-* properties |