Skip to content
WANCRAFT

C.43Typography & Text

Circular Text

A rotating ring of type around a centre slot — the classic “available for work” badge.

NewReactSVGTailwindbasic

Overview

Circular Text sets a phrase on an SVG textPath and turns it slowly around a centre slot that holds anything: an arrow, a logo, an avatar. The phrase repeats to fill the circumference with an accent-coloured separator, and textLength justifies it so the seam always closes. Rotation runs on the Web Animations API with an eased playback rate, so hovering (or keyboard focus on a link) can smoothly pause or accelerate it. Pass href and the whole badge becomes a link. It pauses offscreen and in background tabs, and stands still with reduced motion.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/circular-text.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/circular-text.json

Method 02 · Copy and paste

  1. 1. No extra dependencies — React and Tailwind CSS only.
  2. 2. Copy the source from the Code tab into components/ui/circular-text.tsx.
  3. 3. Import it and adjust props.
Dependencies
None
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { CircularText } from "@/components/ui/circular-text";

export function CircularTextExample() {
  return (
    <CircularText href="#contact">
      <span aria-hidden="true" className="text-xl">↓</span>
    </CircularText>
  );
}

03Props

PropTypeDefaultDescription
textstring"Available for work"Phrase set around the circle; also the accessible name.
separatorstring" • "Inserted between repetitions, drawn in the accent colour.
repeatnumber—Times the phrase repeats. Estimated from the circumference when omitted.
sizenumber168Outer diameter in px.
fontSizenumber11Ring font size in px.
speednumber24Rotation speed in degrees per second (0 = still).
direction"clockwise" | "counterclockwise""clockwise"Rotation direction.
hover"none" | "pause" | "accelerate""accelerate"What hover (or keyboard focus on a link) does to the rotation; the speed eases between states.
ringbooleantrueHairline ring between the text and the centre slot.
accentstring"#FF7448"Separator, ring and focus ring colour.
hrefstring—Renders the badge as a link (target and rel are forwarded).
labelstring—Accessible name; defaults to text.
textClassNamestring"font-mono uppercase"Classes for the ring text.
childrenReactNode—Centre slot content, e.g. an arrow icon.

04Features

  • 01SVG textPath ring that repeats the phrase to fill the circumference
  • 02textLength justification so the seam always closes
  • 03Web Animations rotation with an eased playback rate on hover
  • 04Centre slot for icons, logos or avatars
  • 05Works as a link badge with a visible focus ring
  • 06Paused offscreen and in background tabs
motion · continuousinput · hoverinput · focus

05Accessibility

  • The phrase is exposed once — as the link's aria-label, or as visually hidden text — and the repeated SVG text is aria-hidden.
  • As a link it is a single focusable element with a focus-visible ring; keyboard focus triggers the same hover behaviour.
  • With prefers-reduced-motion the ring does not rotate.

06Limitations

  • Repetitions are estimated from an average glyph width; pass repeat for very wide or narrow typefaces.