Richtext Array

The string-parsing sibling of InlineArray. Accepts a literal text fragment — [1, 2, 3], {a, b}, [[3,6],[1,4]] — and renders the matching inline chip without the caller having to tokenise the payload first.

Useful when the source data already arrives as a string: MDX prose, lesson narration, LLM output, or any rich-text runtime where the array is already in literal form. Pair with InlineArray when the source is already typed.

The chip Array, 4 elements: 3, 6, 1, 4.3614 flows with prose at the surrounding baseline.

Customize
Shape
1D array
accent
Motion
0.00 s

Installation

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

Usage

import { RichtextArray } from "@craft-bits/core";
 
<p>
  Push <RichtextArray text="[1, 2, 3]" /> onto the frontier.
</p>

Cascade cells in for a staged reveal:

<RichtextArray text="[1, 2, 3, 4]" animate baseDelay={0.2} />

A 2D literal nests row-strips:

<RichtextArray text="[[3,6],[1,4],[8,10]]" tone="success" />

An empty set renders the placeholder glyph at the inline baseline:

<RichtextArray text="{}" tone="muted" />

Understanding the component

  1. One parser, three shapes. A leading [[ switches to the 2D branch; a leading { is a set (with the empty-set glyph fallback); anything else parses as a 1D array. Bad tokens drop out via Number.isNaN instead of throwing, so a malformed fragment still renders the surrounding chip.
  2. Inline sizing. The outer span is h: 1.55em with align-middle, tabular-nums, and a mono font so digits stay column-aligned and the chip's baseline matches the surrounding line of text.
  3. Tone via CSS variables. tone picks a cb-* semantic var (accent / success / warning / danger / muted); the border, fill, and ink all derive from that one variable via color-mix(…) so the chip themes correctly under light and dark mode.
  4. Cascade reveal. When animate is set, each cell pops in via SPRINGS.snap with a delay of baseDelay + i * 0.04 for 1D and baseDelay + ri * 0.08 + ci * 0.04 for 2D — the same sweep shape AlgoFlashcards used to land cells under staged prose.
  5. Reduced motion. When prefers-reduced-motion: reduce is set, the cell transition collapses to duration: 0 — cells snap in regardless of animate.

Variants

A static literal — no animation:

<p>
  Sort <RichtextArray text="[5, 2, 8, 1]" /> by ascending key.
</p>

A 2D literal in the warning palette:

<RichtextArray text="[[1,2],[3,4]]" tone="warning" />

The empty-set state:

<RichtextArray text="{}" tone="muted" />

A cascade-in reveal with a base delay so the chip lands after the prose around it:

<RichtextArray text="[10, 20, 30, 40]" animate baseDelay={0.3} />

Props

PropTypeDefaultDescription
textstringrequiredLiteral text fragment to parse.
toneRichtextArrayTone"accent"Resting tone — accent, success, warning, danger, muted.
animatebooleanfalseCascade cells in via fade-and-pop.
baseDelaynumber0Base delay (seconds) added to every cell's stagger.
transitionTransitionSPRINGS.snapOverride the cell transition.
emptyPlaceholderstring"{ }"Glyph for the empty-set state.
classNamestringMerged onto the root via cn().

Accessibility

  • The outer element is role="img" with a hidden summary like Array, 3 elements: 1, 2, 3. (or 2D array, 3 rows.) so screen readers hear the chip's contents instead of reading each digit in isolation.
  • Each chip carries data-state (array / set / 2d / empty) and data-tone so consumer apps can hook custom styles or assistive tooling.
  • The 2D comma separator is aria-hidden because the summary already conveys the row structure.
  • Color is never the only signal — every shape still renders its digits, and the empty-set state ships an explicit aria-label="Empty set".
  • Motion respects prefers-reduced-motion: reduce — cells snap in regardless of animate.

Credits

  • Extracted from: algoflashcards (src/platform/ui/richtext-array.tsx). The source parsed three literal shapes (1D array, set, 2D array) into bordered emerald chips using a hardcoded track-emerald palette and a SPRING.snappy cascade. The library version keeps the parser branches and the cascade math but swaps the emerald palette for the cb-* tone system, pulls the spring into SPRINGS.snap, exposes baseDelay as a prop so callers can land the chip under staged prose, and lifts the cell renderer into a shared Cell so 1D and 2D code paths share the same animation contract.