0% found this document useful (0 votes)
61 views11 pages

Form - Radix Primitives

Uploaded by

SupremeMugwump
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views11 pages

Form - Radix Primitives

Uploaded by

SupremeMugwump
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

7/25/24, 5:14 PM Form – Radix Primitives

Form
Collect information from your users using validation rules.

Email

Question

Post question

index.jsx tailwind.config.js Tailwind CSS

https://www.radix-ui.com/primitives/docs/components/form 1/11
7/25/24, 5:14 PM Form – Radix Primitives

className="box-border w-full bg-blackA2 shadow-blackA6 inline-flex appear


required
/>
</Form.Control>
</Form.Field>
<Form.Submit asChild>
<button className="box-border w-full text-violet11 shadow-blackA4 hover:bg-ma
Post question
</button>
</Form.Submit>
</Form.Root>
);

export default FormDemo;

Collapse code

Features

Built on top of the native browser constraint validation API.

Supports built-in validation.

Supports custom validation.

Full customization of validation messages.

Accessible validation messages.

Supports client-side and server-side scenarios.

Focus is fully managed.

0.1.0 (latest)

Size: 4.71 kB

View source

View on npm

Report an issue

Installation
https://www.radix-ui.com/primitives/docs/components/form 2/11
7/25/24, 5:14 PM Form – Radix Primitives

Install the component from your command line.

npm install @radix-ui/react-form

Anatomy
Import all parts and piece them together.

import * as Form from '@radix-ui/react-form';

export default () => (


<Form.Root>
<Form.Field>
<Form.Label />
<Form.Control />
<Form.Message />
<Form.ValidityState />
</Form.Field>

<Form.Message />
<Form.ValidityState />

<Form.Submit />
</Form.Root>
);

API Reference

Root
Contains all the parts of a form.

Prop Type Default

asChild boolean false

onClearServerErrors function

https://www.radix-ui.com/primitives/docs/components/form 3/11
7/25/24, 5:14 PM Form – Radix Primitives

Field
The wrapper for a field. It handles id/name and label accessibility automatically.

Prop Type Default

asChild boolean false

name* string

serverInvalid boolean

Data attribute Values

[data-invalid] Present when the field is invalid

[data-valid] Present when the field is valid

Label
A label element which is automatically wired when nested inside a Field part.

Prop Type Default

asChild boolean false

Data attribute Values

[data-invalid] Present when the field is invalid

[data-valid] Present when the field is valid

Control
A control element (by default an input ) which is automatically wired when nested inside a
Field part.

https://www.radix-ui.com/primitives/docs/components/form 4/11
7/25/24, 5:14 PM Form – Radix Primitives

Prop Type Default

asChild boolean false

Data attribute Values

[data-invalid] Present when the field is invalid

[data-valid] Present when the field is valid

Message
A validation message which is automatically wired (functionality and accessibility) to a
given control when nested inside a Field part. It can be used for built-in and custom
client-side validation, as well as server-side validation. When used outside a Field you
must pass a name prop matching a field.

Form.Message accepts a match prop which is used to determine when the message should
show. It matches the native HTML validity state ( ValidityState on MDN ) which
validates against attributes such as required , min , max . The message will show if the
given match is true on the control’s validity state.

You can also pass a function to match to provide custom validation rules.

Prop Type Default

asChild boolean false

match Matcher

forceMatch boolean false

name string

ValidityState
Use this render-prop component to access a given field’s validity state in render (see
ValidityState on MDN ). A field's validity is available automatically when nested inside
a Field part, otherwise you must pass a name prop to associate it.

https://www.radix-ui.com/primitives/docs/components/form 5/11
7/25/24, 5:14 PM Form – Radix Primitives

Prop Type Default

children function

name string

Submit
The submit button.

Prop Type Default

asChild boolean false

Examples

Composing with your own components


Using asChild you can compose the Form primitive parts with your own components.

<Form.Field name="name">
<Form.Label>Full name</Form.Label>
<Form.Control asChild>
<TextField.Input variant="primary" />
</Form.Control>
</Form.Field>

It can also be used to compose other types of controls, such as a select :

<Form.Field name="country">
<Form.Label>Country</Form.Label>
<Form.Control asChild>
<select>
<option value="uk">United Kingdom</option>…
</select>
</Form.Control>
</Form.Field>

https://www.radix-ui.com/primitives/docs/components/form 6/11
7/25/24, 5:14 PM Form – Radix Primitives

Note: At the moment, it is not possible to compose Form with Radix's other form
primitives such as Checkbox , Select , etc. We are working on a solution for this.

Providing your own validation messages


When no children are provided, Form.Message will render a default error message for the
given match .

// will yield "This value is missing"


<Form.Message match="missingValue" />

You can provide a more meaningful message by passing your own children . This is also
useful for internationalization.

// will yield "Please provide a name"


<Form.Message match="missingValue">Please provide a name</Form.Message>

Custom validation
On top of all the built-in client-side validation matches described above you can also
provide your own custom validation whilst still making use of the platform's validation
abilities. It uses the customError type present in the constraint validition API .

You can pass your own validation function into the match prop on Form.Message . Here's an
example:

<Form.Field name="name">
<Form.Label>Full name</Form.Label>
<Form.Control />
<Form.Message match={(value, formData) => value !== 'John'}>
Only John is allowed.
</Form.Message>
</Form.Field>

match will be called with the current value of the control as first argument and the entire
FormData as second argument. match can also be an async function (or return a
promise) to perform async validation.

https://www.radix-ui.com/primitives/docs/components/form 7/11
7/25/24, 5:14 PM Form – Radix Primitives

Styling based on validity


We add data-valid and data-invalid attributes to the relevant parts. Use it to style your
components accordingly. Here is an example styling the Label part.

//index.jsx
import * as React from 'react';
import Form from '@radix-ui/react-form';

export default () => (


<Form.Root>
<Form.Field name="email">
<Form.Label className="FormLabel">Email</Form.Label>
<Form.Control type="email" />
</Form.Field>
</Form.Root>
);

/* styles.css */
.FormLabel[data-invalid] {
color: red;
}
.FormLabel[data-valid] {
color: green;
}

Accessing the validity state for more control


You may need to access the raw validity state of a field in order to display your own icons, or
interface with a component library via it's defined props. You can do this by using the
Form.ValidityState part:

<Form.Field name="name">
<Form.Label>Full name</Form.Label>
<Form.ValidityState>
{(validity) => (
<Form.Control asChild>
<TextField.Input
variant="primary"
state={getTextFieldInputState(validity)}
/>

https://www.radix-ui.com/primitives/docs/components/form 8/11
7/25/24, 5:14 PM Form – Radix Primitives

</Form.Control>
)}
</Form.ValidityState>
</Form.Field>

Server-side validation
The component also supports server-side validation using the same Form.Message
component. You can re-use the same messages you defined for client-side errors by
passing a forceMatch prop which will force the message to show regardless of the client-
side matching logic.

If the message doesn't exist on the client-side, you can render a Form.Message without a
match too. The field is marked as invalid by passing a serverInvalid boolean prop to the
Form.Field part.

Here's an example with server-side error handling:

import * as React from 'react';


import * as Form from '@radix-ui/react-form';

function Page() {
const [serverErrors, setServerErrors] = React.useState({
email: false,
password: false,
});

return (
<Form.Root
// `onSubmit` only triggered if it passes client-side validation
onSubmit={(event) => {
const data = Object.fromEntries(new FormData(event.currentTarget));

// Submit form data and catch errors in the response


submitForm(data)
.then(() => {})
/**
* Map errors from your server response into a structure you'd like to wo
* In this case resulting in this object: `{ email: false, password: true
*/
.catch((errors) => setServerErrors(mapServerErrors(errors)));

// prevent default form submission

https://www.radix-ui.com/primitives/docs/components/form 9/11
7/25/24, 5:14 PM Form – Radix Primitives

event.preventDefault();
}}
onClearServerErrors={() =>
setServerErrors({ email: false, password: false })
}
>
<Form.Field name="email" serverInvalid={serverErrors.email}>
<Form.Label>Email address</Form.Label>
<Form.Control type="email" required />
<Form.Message match="valueMissing">
Please enter your email.
</Form.Message>
<Form.Message match="typeMismatch" forceMatch={serverErrors.email}>
Please provide a valid email.
</Form.Message>
</Form.Field>

<Form.Field name="password" serverInvalid={serverErrors.password}>


<Form.Label>Password</Form.Label>
<Form.Control type="password" required />
<Form.Message match="valueMissing">
Please enter a password.
</Form.Message>
{serverErrors.password && (
<Form.Message>
Please provide a valid password. It should contain at least 1 number
and 1 special character.
</Form.Message>
)}
</Form.Field>

<Form.Submit>Submit</Form.Submit>
</Form.Root>
);
}

You should clear the server errors using the onClearServerErrors callback prop on the
Form.Root part. It will clear the server errors before the form is re-submitted, and when the
form is reset.

In addition, this provides control over when to reset single server errors. For example you
could reset the email server error as soon as the user edits it:

https://www.radix-ui.com/primitives/docs/components/form 10/11
7/25/24, 5:14 PM Form – Radix Primitives

<Form.Field name="email" serverInvalid={serverErrors.email}>


<Form.Label>Email address</Form.Label>
<Form.Control
type="email"
onChange={() => setServerErrors((prev) => ({ ...prev, email: false }))}
/>
<Form.Message match="missingValue">Please enter your email.</Form.Message>
<Form.Message match="typeMismatch" forceMatch={serverErrors.email}>
Please provide a valid email.
</Form.Message>
</Form.Field>

Accessibility
The component follows the "inline errors" pattern for validation:

Label and control are associated using the name provided on Form.Field
When one or more client-side error messages display, they are automatically associated
with their matching control and announced accordingly
Focus is moved to the first invalid control

Previous Next
Dropdown Menu Hover Card

Edit this page on GitHub.

https://www.radix-ui.com/primitives/docs/components/form 11/11

You might also like