Skip to content
Tier

Typed text

Pro

The app's own words (a heading, an empty state, a first-run greeting) typed out once as the page first draws, when the brand turns it on with the Pro motion-drawings item's --cd-show-typing: type. It is motion for show: the whole text is in the page from the start, read by screen readers and found by search, with the part not yet typed drawn transparent in its place, so nothing moves as it types and nothing is hidden from assistive technology. It types at about 30 ms a character, 900 ms at most in all, only inside the page's first-draw window (a heading that appears later, after a filter or a tab, is simply there), and never under reduced motion, data-motion="calm" or "none", or at the Off level. A press, a key or a focus anywhere finishes it at once.

Never use it for a model's reply: a reply arrives in pieces already, and StreamingText draws those pieces as they come. Without the Pro item, or without the brand's value, it is plain text.

Markdown
Version 5.2.0· other versions

This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).

Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 2.5.1, 2.6.0, 2.6.1, 2.6.2, 2.7.0, 2.8.0, 2.9.0, 2.10.0, 3.0.0, 4.0.0, 4.0.1, 4.0.2, 4.1.0, 4.2.0 and 4.3.0: the page came later, or had another name then.

Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.

Preview

Loading the preview

Install

With the Candor CLI

First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/typed-text

Brings in: motion, tokens, utils · npm: @base-ui/react@^1.9.0

Usage

TSX · The example above
"use client"

import { TypedText } from "@/components/candor/typed-text"

/*
 * Plain text until the brand turns it on with the Pro motion-drawings item (`--cd-show-typing: type` on :root); then the
 * heading types once as the page first draws. The whole heading is in the page from the start. A model's reply never
 * goes here: use StreamingText, which draws its pieces as they arrive.
 */
export default function Example() {
  return (
    <div className="flex flex-col gap-1">
      {/* `render` draws it as any element, as the kit's other parts take it; `as="h2"` does the same for a few tags. */}
      {/* oxlint-disable-next-line jsx-a11y/heading-has-content -- TypedText gives the heading its words */}
      <TypedText render={<h2 />} className="text-lg font-semibold" text="Welcome back, here is what changed while you were away" />
      <p className="text-sm text-muted-foreground">Three runs finished and one needs you.</p>
    </div>
  )
}

<TypedText>

PropTypeDefaultDescription
textrequiredstring—The app's own words. Never a model's or another site's text.
as"span" | "p" | "h1" | "h2" | "h3" | undefined"span"The element it is: `span` (the default), `p`, `h1`, `h2` or `h3`. `render` does the same for any element.
renderuseRender.RenderProp | undefined—The element to draw it as, as the kit's other parts take it: `render={<h2 className="…" />}`, or a function given the props. The text is its children; `data-slot` and the typing state stay on it. Given, it wins over `as`.
classNamestring | undefined—Classes, merged with Candor's.

Terms used here

Calm level
What Candor's motion does for a person whose operating system asks for reduced motion: the highest-precedence setting, above the app's own motion level (none, calm, subtle or expressive) and the brand file. A theme tunes how a change looks, never when it happens, so nothing depends on seeing the motion.

Every term is defined in the glossary (Markdown).