Label, Help, FieldError
The three text pieces around a control, usable on their own when you compose a field by hand.
Field renders these for you. Import them when you assemble a field yourself, or to change the words without touching the schema.
Preview
Usage
import { Form, Label, Help, FieldControl, FieldError, Submit } from '@trymirio/mirio';
<Form schema={schema} client={mirio}>
<div className="flex flex-col gap-1.5">
<Label name="company">Company name</Label> {/* children override the schema label */}
<Help name="company" />
<FieldControl name="company" />
<FieldError name="company" />
</div>
<Submit />
</Form>
Props
Label
| Prop | Type | Default | Description |
|---|---|---|---|
name |
string |
required | The field key. |
children |
ReactNode |
field.label |
Replaces the label text. |
requiredIndicator |
ReactNode | null |
from Form/MirioProvider, else nothing |
What to append when field.required. |
optionalIndicator |
ReactNode | null |
from Form/MirioProvider, else a small muted "Optional" |
What to append when the field isn't required; null renders nothing. |
className |
string |
text-sm font-medium leading-none text-mirio-fg |
Merged onto the element. |
…<label> attributes |
Spread on the <label>. |
Renders <label for="<control id>" id="<label id>" data-mirio="label">. For grouped controls (single_choice, multiple_choice, yes_no, rating) it renders a <span id data-mirio="label"> instead, because the group is labelled through aria-labelledby rather than for.
Help
| Prop | Type | Default | Description |
|---|---|---|---|
name |
string |
required | The field key. |
children |
ReactNode |
field.help |
Replaces the help text. Renders nothing when there is none. |
className |
string |
text-sm text-mirio-muted-fg |
Merged onto the <p>. |
…<p> attributes |
Spread on the <p>. |
Renders <p id="<help id>" data-mirio="help">; the id is in the control's aria-describedby. Field places it under the label, and under the checkbox row for consent fields.
FieldError
| Prop | Type | Default | Description |
|---|---|---|---|
name |
string |
required | The field key. |
className |
string |
text-sm text-mirio-error |
Merged onto the <p>. |
…<p> attributes |
Spread on the <p>. |
Renders <p id="<error id>" role="alert" data-mirio="error">message</p> while the field has an error, nothing otherwise. Messages come from Mirio's validator (client and server use the same one), e.g. "This field is required", "Enter a valid email address", "Choose at most 2".
Variants and states
Required and optional marks (since 0.1.3): by default optional fields get a small, muted "Optional" after the label and required fields get no mark. Most fields on a short form are required, so a mark on each says little; screen readers hear "Optional" with the label, and required controls carry aria-required. Set either mark once for every form, or per label:
<Form schema={schema} client={mirio}> // the default
<Field name="email" />
</Form>
<MirioProvider
client={mirio}
requiredIndicator={<span aria-hidden className="ml-0.5 text-mirio-error">*</span>} // asterisks instead
optionalIndicator={null}
>
<Form schema={schema}>…</Form>
</MirioProvider>
<Label name="company" optionalIndicator={null}>Company</Label> // one label
Resolution order for each: the Label prop, then the nearest Form/MirioProvider that set one, then the default (nothing for required, "Optional" for optional). A required consent checkbox uses requiredIndicator; an optional one has no mark.
Customization
- Tokens:
--mirio-fg(label),--mirio-muted-fg(help and the "Optional" mark),--mirio-error(error). className="text-base font-semibold"onLabelreplaces the size and weight.FieldErrorwithclassName="text-xs"shrinks the message.- CSS hooks:
[data-mirio="label"],[data-mirio="help"],[data-mirio="error"]. - Label and help text are part of the schema (and its hash): changing them is a schema change that
mirio pushrecords as a new version; overriding withchildrenis a display-only change.
Accessibility
Label targets the control with for (or labels a group through aria-labelledby). Help and FieldError ids are joined into the control's aria-describedby, so screen readers read help on focus and the error with the control. FieldError is a live region (role="alert"), so a new message is announced when it appears, and Mirio also moves focus to the first invalid control after a failed submit. The default * is aria-hidden; required state is conveyed by aria-required on the control.