Gesso
Data display

Check mark

A stroke check that draws itself, down the short leg and up the long one.

Check mark is a check you watch arrive. It is Phosphor's Check geometry at bold weight, redrawn as one stroke so it can draw: the pen runs down the short leg to the vertex, then up the long leg to the top. checked drives it, so the same mark draws when a step finishes and clears when it is undone. Stepper swaps each finished step's number for one.

Inline with text at 1em

Usage

import { CheckMark } from '@/components/ui/check-mark';

<CheckMark checked={done} className="text-primary" />

The stroke is currentColor, so color it with a text class, and the size defaults to 1em so it sits in a line of text at the text's size. Pass size for a fixed one, as a number of pixels or any CSS length. The mark is a display-only icon, and it needs the motion package, which the install adds.

Motion

RuleWhat happens
DrawpathLength 0 to 1 in --duration-base on --ease-out, so the short leg lands quickly and the long leg settles.
Delaydelay (seconds) holds the draw, to sync with a parent's motion. Stepper passes the worm's 80ms trail delay.
ClearInstant. Undoing is not an event worth animating.
MountRenders at its current state, no play-in.
Reduced motionAppears and clears without drawing.

While the delay runs the stroke stays hidden, then it draws. Toggle the three marks below to see them land one after another.

Props

Check mark takes these props, and the rest of an <svg>'s go on the <svg>, which ref reaches.

PropTypeDefaultWhat it does
checkedbooleantrueDraws the check when true and clears it when false.
delaynumber0Seconds to wait before the draw starts. A clear is never delayed.
sizenumber | string"1em"The width and height, as pixels or any CSS length.
classNamestringAdded to the <svg>. Set a text color here.

Accessibility

  • The mark is aria-hidden, so a screen reader skips it. It decorates a state that its parent already names, like a step reading "completed" or a checkbox's own role, so give the state a text or an accessible name next to it. Given an aria-label, it is role="img" with that name instead.
  • It is not focusable and takes no input.
  • Color comes from currentColor, so it follows the text color, including the system colors in forced colors. The mark never carries the state alone when a text name sits beside it.
  • Under reduced motion it appears and clears without drawing. Otherwise the draw is 200ms, and it plays when checked turns true after mount.

When to use something else

  • Checkbox when a person can toggle the state. It is a real control with a role, a name, keyboard handling, and its own check that scales in, while Check mark only shows a state someone else set.
  • A plain Phosphor Check icon when the mark should not animate, like a bullet in a list.
  • Stepper for a row of steps. It uses Check mark for you.

Install

shadcn add @gesso/check-mark

On this page