Standalone label component returned by useFormBridge. Renders a field's label and required mark, reading both directly from the schema descriptor.
- Label text comes from
field.x('Label text')in the schema - the component stays in sync automatically, so you don't duplicate strings in JSX - Required mark is driven by
.required()on the builder. Flip the schema and the asterisk appears/disappears everywhere htmlFordefaults to the fieldname, which matches the id emitted by the generated fields - click the label, the input focuses, accessibility wired for free- Use it when you render inputs through
form.fieldController(name)or when your design-system row layout keeps label / input / error as separate slots - Unlike
FormandForm.Submit,FieldLabelkeeps a deliberately focused API today instead of mirroring every native label attribute; if you need total control over the wrapper element, userender
FieldLabel.web.tsxtsx
| 1 | const schema = { |
| 2 | email: field.email('Email address').required(), |
| 3 | } |
| 4 | |
| 5 | const form = useFormBridge(schema) |
| 6 | |
| 7 | <form.Form onSubmit={save}> |
| 8 | <div className="form-row"> |
| 9 | <form.FieldLabel name="email" /> |
| 10 | <input |
| 11 | id="email" |
| 12 | name="email" |
| 13 | value={form.state.values.email} |
| 14 | onChange={(e) => form.setFieldValue('email', e.target.value)} |
| 15 | onBlur={() => form.setFieldTouched('email', true)} |
| 16 | /> |
| 17 | <form.FieldError name="email" /> |
| 18 | </div> |
| 19 | <form.Form.Submit>Save</form.Form.Submit> |
| 20 | </form.Form> |
Why it exists
The generated <form.fields.email /> component already renders its own label inline. <FieldLabel /> exists for the cases where that isn't enough:
- Custom layouts - you render the input yourself via
form.fieldController('email')and want a drop-in label slot without re-implementing the required-mark logic - Design-system rows - your form grid keeps label / input / error in separate columns, and each slot is its own component
- Single source of truth - the label text lives once in the schema; flipping a field between optional and required automatically updates every place
<FieldLabel />is mounted - Tooltips, icons, help popovers - use
renderto wrap the label in richer UI without giving up the typednamebinding or the required-mark automation
Props
| Method | Type | Description |
|---|---|---|
name | keyof Schema | Required. Typed field name. Autocompletes from the schema keys so renaming a field surfaces a type error at the usage site. |
children | ReactNode | Optional label override. When omitted, the component pulls label(...) straight from the schema descriptor - keep the text in one place instead of duplicating it in JSX. |
render | (ctx) => ReactNode | Custom render function. Receives { name, label, required, htmlFor } so you can build accessible labels with tooltips, icons, help popovers, etc. |
renderRequiredMark | () => ReactNode | Replaces the default red asterisk. Useful to swap for a localized (required) string or a design-system badge. |
htmlFor | string *(web only)* | Explicit for attribute. Defaults to the field name, which already matches the input id emitted by the generated fields. |
className | string *(web only)* | Class applied to the default <label> element. |
style | CSSProperties | StyleProp<TextStyle> | Inline style - CSSProperties on web, StyleProp<TextStyle> on native. |
render(...) for extra native attrs | (ctx) => ReactNode | If you need custom DOM/native attributes beyond the focused built-in surface, render the label element yourself via render and attach whatever your platform needs there. |
Recipes
- Schema-driven label → just
<form.FieldLabel name="email" />. The text comes fromfield.email('Email address')in the schema - Ad-hoc override → pass children:
<form.FieldLabel name="email">Work email</form.FieldLabel> - Localized required mark →
renderRequiredMark={() => <span>({t('required')})</span>} - Label with tooltip/help icon → use the
renderprop to wrap the label in your design-system tooltip - Shared row component → build a
<FormRow name="email" />wrapper that internally mountsFieldLabel,fieldController, andFieldError- the typednameflows through all three