Richtext Pencil

A small, decorative inline-SVG pencil mark for richtext emphasis. The stroke reads as a hand-drawn underline or marginal accent — a wobbly horizontal pencil line — and scales uniformly with the size prop.

Customize
Pencil
64px
1.5
accent

Installation

npx shadcn@latest add https://craftbits.dev/r/richtext-pencil.json

Usage

import { RichtextPencil } from "@craft-bits/core";
 
<RichtextPencil size={64} />

To theme via the surrounding text color, wrap in any text-cb-* utility.

Understanding the component

  1. Single hand-drawn path. The whole ornament is one cubic-Bezier stroke inside a 64x16 viewBox — soft lead-in, wobble across the midline, hooked finish. One size prop scales it uniformly while preserving the aspect ratio.
  2. Decorative, never announced. The root SVG carries aria-hidden="true", focusable={false}, and pointer-events: none so the ornament never enters the accessibility tree or steals focus.
  3. Color flows from the parent. accentColor defaults to currentColor, inheriting the wrapping text color — no theme prop drilling. Pass any CSS color to override.
  4. Static — no motion. Richtext Pencil is fully static. Motion (for example a pathLength reveal) belongs to the parent — wrap in a motion.span.
  5. Generalized from terminal-dreams. The source primitive was a span that tinted children with the accent color and widened letter-spacing. That coupled the mark to the inline text it adorned. This version splits the visual mark off into a composable SVG so it can stack under any inline element.

Variants

  • Default<RichtextPencil />
  • Explicit accent<RichtextPencil accentColor="#4A7BF7" />
  • Larger size<RichtextPencil size={128} />
  • Thinner stroke<RichtextPencil strokeWidth={1} />

Props

PropTypeDefaultDescription
sizenumber64Width in px (height scales to preserve aspect).
accentColorstring'currentColor'CSS color for the pencil stroke.
strokeWidthnumber1.5Stroke width in viewBox units.
classNamestringExtra classes merged onto the root SVG.

Accessibility

  • The root SVG carries aria-hidden="true" and focusable={false} — Richtext Pencil is purely decorative and screen readers skip it.
  • pointer-events: none and user-select: none are applied so the ornament never blocks clicks or text selection on layered content.
  • No motion is rendered — there is nothing to gate behind prefers-reduced-motion.
  • Color tinting flows from currentColor by default, so the mark inherits whatever contrast the wrapping text already meets.

Credits

  • Extracted from: terminal-dreams (src/components/ui/richtext-pencil.tsx).