Browse documentation

Components Labels & annotation

RichTextOverlay

Emphasize a short display statement with styled spans, one primary underline, and an optional marker.

Client directive required No provider required

Examples

Link to this example5 presentations

Two seed lines with cobalt text. The requested primary underline is clipped in this revision; see the usage note.

728 × 245 px · 100%
Clarity drives
better outcomes.
A short editorial statement. The requested final-line underline is clipped in this library revision.

Preview setting only: fitting scales this 728 px composition. Actual size preserves the copied wrapper and allows contained scrolling; it does not change component layout.

Preview only: surrounding canvas and spacing. All metrics are illustrative.

Usage

Use RichTextOverlay for a short editorial statement with deliberate line breaks. Default, WithMarker, and OnDark preserve all three seeds. WithMarker labels its 18.6% value as illustrative; Status adds the supported status-marker kind. FirstLineEmphasis demonstrates a visible primary underline before a lower-case second line.

Supply an array of lines, each containing inline text spans. Spaces are not inserted between spans: include them in the supplied text. Choose one phrase for primary emphasis across the entire overlay; the treatment requests a 3 px underline. At this revision, that underline can be clipped, as described below.

A value or status marker follows the final line. Both kinds share the same pill appearance; kind only sets data-kind. It does not produce a different layout or announce a live status. Use a short, self-explanatory marker and leave extra horizontal space for it.

This is static styled text, not an editable rich-text field or HTML renderer. For a smaller annotated message with a tail, see SpeechBubble; for a word underline without the display-text contract, see HandDrawnUnderline.

Text & geometry limits

Supply 1–3 lines, each with at least one span. Every span’s text must be a non-blank string without LF or CRLF line breaks. Each complete line may contain at most 32 Unicode code points across all its spans, including spaces; the implementation counts [...span.text].length. Multi-code-point emoji can consume several positions.

At most one span across all lines may set emphasis="primary". Unsupported emphasis, span tone, marker kind, marker tone, or fieldMode values throw. A marker’s label must be a non-blank string or finite number. Marker text is excluded from the line limit and has no separate length or line-break validation; keep it brief yourself.

Each line uses whiteSpace: nowrap at a fixed 72 px display size, line-height 0.94, and −1.4 px letter spacing. The root maxWidth is 680 px, but this does not shrink or wrap text: even a valid 32-character line can extend beyond it. The 728 px copied wrapper leaves 680 px inside its padding; measure your actual phrases and marker together.

Known limitation: final-line emphasis is clipped

With the bundled The Seasons font, the primary underline extends below the final line’s root box. The component’s own reveal clip-path still clips that area at revealProgress=1. Default and OnDark preserve this seed behavior: the primary span is present, but its underline is not visible. Increasing the surrounding wrapper’s padding does not fix a clip inside the component.

FirstLineEmphasis places the primary span on the first line and uses “once more.” as a lower-case continuation. This gives the underline room inside the existing clip without changing the package styles. Inspect your exact text: tall glyphs on the following line can overlap the underline at the fixed tight line-height.

Do not depend on this underline to communicate meaning. A separate HandDrawnUnderline composition is available when you need a visible underline. Review this limitation when upgrading the pinned library.

fieldMode accepts light or dark and changes text colors, not the background. Span tones accept neutral, accent, muted, positive, warning, or error; omitted tone resolves to neutral. Accent text uses cobalt on light and cornflower on dark. On light fields, warning/error keep navy text with a colored underline; primary emphasis draws its own underline. Marker tones use the video surface/text/border tokens.

Progress props default to 1 for the completed presentation. Finite inputs clamp to 0–1; NaN and infinities throw. They are scalar controls, not an animation scheduler. Keep the settled defaults for static documentation; respect reduced-motion preferences if you animate them in an application.

Props

Types and required flags extracted from the installed @coreux/ui declarations.
Prop / typeDefaultDescription
linesRequiredreadonly RichTextLine[]RequiredRequired array of 1–3 RichTextLine objects. Each requires at least one span and at most 32 Unicode code points across all span text, including spaces. Lines never wrap. Marker text is excluded from the count.
markerRichTextMarkerundefinedOptional single marker after the last line. Both value and status use the same pill layout; kind sets data-kind, not a distinct semantic role. Allow additional width for the marker.
fieldMode"light" | "dark""light"light or dark selects the video-family appearance tokens. It does not paint the surrounding field; the copied wrapper supplies that background.
revealProgressnumber1Finite value clamped to 0–1. Controls opacity, a 14-to-0 px vertical offset, and the root clip-path reveal. NaN and infinities throw. The clip remains active at the settled default 1.
emphasisProgressnumber1Finite value clamped to 0–1 for primary underline scale and opacity. NaN and infinities throw. At most one primary span is allowed across the entire overlay.
opacityProgressnumber1Finite opacity multiplier clamped to 0–1, multiplied by revealProgress. NaN and infinities throw. Omitted means fully visible.

RichTextLine

Types and required flags extracted from the installed @coreux/ui declarations.
Prop / typeDefaultDescription
spansRequiredreadonly RichTextSpan[]RequiredOne or more inline spans in reading order. Text is concatenated without inserted spaces. Across all spans in one line, the maximum is 32 Unicode code points.

RichTextSpan

Types and required flags extracted from the installed @coreux/ui declarations.
Prop / typeDefaultDescription
textRequiredstringRequiredRequired non-blank string, without LF/CRLF line breaks. Use separate lines entries for line breaks. Spaces count toward the line limit; nested layout is rejected.
tone"neutral" | "accent" | "muted" | "positive" | "warning" | "error"undefinedWhen omitted, resolves to neutral. Accepts neutral, accent, muted, positive, warning, error. In light mode warning/error keep navy text and use a colored underline; primary emphasis uses its own underline treatment.
emphasis"primary"undefinedOnly primary is allowed when supplied. Requests a 3 px underline; the pinned implementation clips it on the final line with the bundled font. At most one span across all lines may use it; it does not add strong/em semantics.

RichTextMarker

Types and required flags extracted from the installed @coreux/ui declarations.
Prop / typeDefaultDescription
kindRequired"value" | "status"RequiredRequired value or status; unsupported values throw. Both render the same pill and expose this value in data-kind only.
labelRequiredstring | numberRequiredRequired non-blank string or finite number; other values throw. There is no character limit or separate line-break validation. Keep the label short enough to fit after the final no-wrap line.
toneRequired"neutral" | "accent" | "muted" | "positive" | "warning" | "error"RequiredRequired neutral, accent, muted, positive, warning, or error. Uses the selected fieldMode surface/text/border tokens. No default tone for a marker.

Accessibility & layout

The root and lines are divs, and the text, marker, and primary emphasis are spans. There are no heading, strong, em, alert, or status semantics. If this text serves as a page heading, provide a real heading in the surrounding document; styling alone does not establish hierarchy. See Typography.

Keep meaning in the words rather than relying on a color or underline. The examples use a figure caption for context, including the fictional baseline for the numeric marker. They do not announce changing numbers or states.

Fit to canvas visually scales the whole fixed-width example, which can make display text small on a phone. Actual size preserves the font and allows contained scrolling. Neither changes the line breaks or makes the component responsive. For normal responsive article text, use semantic HTML with appropriate typography.

See Color for structural and semantic roles. Check contrast against the actual field and preserve written labels alongside color.

Consumer setup

Browsing, previews, and copying are public. Installing the private @coreux/ui package requires repository read access and permission to use the bundled CoreUX brand fonts.

Follow the one-time installation guide for the pinned Git dependency, Tailwind v4 stylesheet setup, fonts, and troubleshooting. Keep the 'use client' directive in each example; no provider is required.

The quick start walks through a copied StatBlock in a minimal app.

Source & revision

This reference targets @coreux/ui version 0.1.0 at 06f42fd. Types come from its installed declarations; explanations and defaults are checked against this implementation.

Revision and upgrade notes · Contribution and coverage guide

View RichTextOverlay source (repository access required)