Kinetic Text

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/ui

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

PropTypeDefault
textstring–
as?React.ElementType–
by?"letter" | "word"'word'
stagger?number45
className?string''

Still, Deskhand and Hollis are fictional brands. The coffee photographs are original generated artwork. @brand-studio/ui is MIT licensed.