Caption
The Caption component renders supplementary text below a form input — a short hint, a format requirement, or an error message that gives the field a little more context.
Variations
Caption passes className straight through, so you can recolor it to signal state — for example, a danger color for an error hint.
Installation
import { Caption } from '@harnessio/ui/components'
return ( <Caption>Use lowercase letters and hyphens only.</Caption>)Anatomy
Caption is a single, self-contained element — there are no parts to compose:
<Caption>Helper text</Caption>- It renders one
<span>through the Text primitive, styled as secondary body text (theforeground-2color) with a small top margin (mt-cn-3xs) so it sits snugly under the field above it. classNamemerges onto that span, so you can recolor it (e.g. for an error state) or tweak the spacing.- It’s presentational only — it renders text and nothing else, with no built-in link to any input.
Best practices
Do
- Use
Captionfor a brief hint or helper line directly beneath a single form field. - Keep it to one short sentence that reads clearly on its own.
- Recolor it via
classNameto reflect state (e.g. a danger color for an error), while keeping the text itself meaningful.
Don’t
- Don’t use
Captionas the field’s label — use Label for that. - Don’t put long paragraphs, links, or other interactive content inside it.
- Don’t rely on it as the only signal for an error — see the accessibility note below.
Content
- Write hints as plain guidance (“Use 8 or more characters”), and errors as what’s wrong plus how to fix it.
- Keep the language short and specific; the caption should add information the label doesn’t already give.
- Use sentence case.
Accessibility
Caption is visual-only: it renders a plain <span> of text and nothing more.
Labeling
- The text is readable on the page, but it is not announced as part of the field it sits under — there’s no semantic relationship between the two.
Known limitations
- The caption isn’t programmatically associated with any input.
Captionaccepts onlychildrenandclassName; even though its prop type extendsHTMLAttributes, the implementation doesn’t forwardidoraria-*, so you can’t point an input’saria-describedbyat it. Screen-reader users may not hear the hint when they focus the field. When the caption carries essential information (a format rule, an error), wire the description up yourself — render the hint with anidand setaria-describedbyon the input — or reach for the form-field components that handle that association for you. - Color alone isn’t meaning. If you recolor the caption to flag an error, that state is conveyed only by color. Keep the wording explicit (“This name is already taken”) and pair it with a proper description association so the error isn’t missed by people who don’t perceive the color.
Properties
Prop | Required | Default | Type |
|---|---|---|---|
| children | true | ReactNode | |
| className | false | string |
Note: although the props type extends HTMLAttributes<HTMLElement>, only children and className are applied — other attributes (id, aria-*, etc.) are not forwarded to the rendered <span>.