Circular Text

A line of text set around a slowly turning circle, with an icon or mark in the middle.

Roasted Monday. Yours by Friday.

This month’s lot is a washed Huila with stone fruit and brown sugar.

This month’s lot · Scroll to taste ·
import { CircularText } from '@brand-studio/ui';
import { ArrowDown } from 'lucide-react';

export default function CircularTextDemo() {
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 32, width: '100%', maxWidth: 640 }}>
      <div style={{ flex: '1 1 260px' }}>
        <h3 style={{ margin: '0 0 8px', fontSize: 'clamp(26px, 5vw, 40px)' }}>Roasted Monday. Yours by Friday.</h3>
        <p style={{ margin: 0, color: 'var(--bs-muted)' }}>This month’s lot is a washed Huila with stone fruit and brown sugar.</p>
      </div>
      <a href="#lots" aria-label="See this month’s lots" style={{ color: 'var(--bs-accent)' }}>
        <CircularText text="This month’s lot · Scroll to taste · " size={132}>
          <ArrowDown size={28} aria-hidden="true" />
        </CircularText>
      </a>
    </div>
  );
}

Installation

pnpm add @brand-studio/ui

Usage

import { CircularText } from '@brand-studio/ui';
<a href="#lots" aria-label="See this month’s lots">
  <CircularText text="This month’s lot · Scroll to taste · " size={132}>
    <ArrowDown aria-hidden="true" />
  </CircularText>
</a>

The text stretches to fill the circle, so end it with a separator to join the ends. duration is the seconds for one turn.

Accessibility

  • Screen readers hear the text once, in order; the ring is hidden from them.
  • As a link, give the link its own label: the ring text is decoration.
  • It stands still under reduced motion.

API Reference

PropTypeDefault
textstring–
size?number128
duration?number18
children?React.ReactNode–
className?string''

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