A headline whose words or letters rise out of a mask, one after another, as it scrolls into view.
Roasted on Monday, in your cup by Friday.
'use client';
import { useState } from 'react';
import { Button, KineticText } from '@brand-studio/ui';
export default function KineticTextDemo() {
const [run, setRun] = useState(0);
const [by, setBy] = useState<'word' | 'letter'>('word');
return (
<div style={{ width: '100%', maxWidth: 620, display: 'grid', gap: 24 }}>
<KineticText key={`${run}-${by}`} by={by} text="Roasted on Monday, in your cup by Friday." />
<div style={{ display: 'flex', gap: 8 }}>
<Button tone="secondary" onClick={() => setRun(run + 1)}>Replay</Button>
<Button tone="secondary" onClick={() => setBy(by === 'word' ? 'letter' : 'word')}>By {by === 'word' ? 'letter' : 'word'}</Button>
</div>
</div>
);
}Installation
pnpm add @brand-studio/uinpm install @brand-studio/uiyarn add @brand-studio/uibun add @brand-studio/uiInstall the peer dependencies
npm install react react-domImport the stylesheet once
import '@brand-studio/ui/styles.css';Wrap your app in a brand theme
import { BrandTheme, KineticText } from '@brand-studio/ui'; import brand from './brand.json'; <BrandTheme palette={brand.tokens} mode="system"> {/* your app */} </BrandTheme>
Usage
import { KineticText } from '@brand-studio/ui';<KineticText as="h1" by="letter" text="Roasted on Monday." />Accessibility
- Screen readers hear the whole text once; the moving pieces are hidden from them.
- A headline already on screen plays at once; one further down waits until it scrolls in.
- Without JavaScript or with reduced motion the text shows in place.
API Reference
| Prop | Type | Default |
|---|---|---|
text | string | – |
as? | React.ElementType | – |
by? | "letter" | "word" | 'word' |
stagger? | number | 45 |
className? | string | '' |