# Forms URL: https://ark-ui.com/docs/guides/forms Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/guides/forms.mdx A guide to building forms with Ark Ripple components. --- Ark Ripple provides the `Field` and `Fieldset` components for integrating with native `form` element or any form library. ## Field Context Form components in Ark Ripple automatically integrate with `Field` through context. When nested inside a `Field.Root`, they inherit `disabled`, `invalid`, `required`, and `readOnly` states automatically. ```ripple import { Field } from 'ark-ripple/field' import { NumberInput } from 'ark-ripple/number-input' component Demo() { // NumberInput will be disabled } ``` ### Accessible Labels When building accessible forms, you need to ensure that they are properly labeled and described. - `Field.Label`: Used to provide an accessible label the input. - `Field.HelperText`: Used to provide additional instructions about the input. These components are automatically linked to the input element via the `aria-describedby` attribute. > **Best practice**: Make sure that labels are visible (and not just used as placeholders) for screen readers to read > them. ```ripple import { Field } from 'ark-ripple/field' component Demo() {
{"Username"} {"This will be your public display name."}
} ``` ### Error Handling and Validation When the input is invalid, you can use the `Field.ErrorText` component to provide an error message for the input, and pass the `invalid` prop to the `Field.Root` component. > **Best practice**: Make sure to provide clear, specific error messages that are easy to understand and fix. ```ripple import { Field } from 'ark-ripple/field' component Demo() {
{"Username"} {"Username is required."}
} ``` ### Required Fields To indicate that a field is required, you can pass the `required` prop to the `Field.Root` component. Optionally, you can use the `Field.RequiredIndicator` component to indicate that the field is required. > **Best practice**: Don't rely solely on color to indicate required status ```ripple import { Field } from 'ark-ripple/field' export component Demo() {
{"Username"} {"(required)"} {"Username is required."}
} ``` To indicate that a field is optional, use the `fallback` prop on the `Field.RequiredIndicator` component. ```ripple {"(required)"} ``` ### Native Controls Field supports native HTML form controls including `input`, `textarea`, and `select`: ```ripple import { Field } from 'ark-ripple/field' export component Demo(){
// Input {"Email"} // Textarea {"Bio"} // Select {"Country"}
} ``` ### Form Reset When the `reset` event is triggered on a form, all Ark Ripple components automatically sync their internal state with the form's reset values. > **Note**: For this to work correctly, always include the `HiddenInput` component in your form controls. The hidden > input participates in the native form reset mechanism, and Ark Ripple listens for this to sync the component state. ```ripple import { Checkbox } from 'ark-ripple/checkbox' component Demo() {
{"I agree to the terms"} // Clicking reset will restore checkbox to defaultChecked state
} ``` ## Fieldset Context When you have multiple fields in a form or a component that renders multiple `input` elements, you can use the `Fieldset` component to group them together. Common use cases checkbox group, radio group, input + select composition, etc. ### Checkbox Group ```ripple import { Fieldset } from 'ark-ripple/fieldset' const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] component Demo() { {"Frameworks"} for (const item of items; key item.value) { } {"Choose your preferred frameworks"} } ``` ### Radio Group ```ripple import { Fieldset } from 'ark-ripple/fieldset' import { RadioGroup } from 'ark-ripple/radio-group' const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] component Demo() { {"Frameworks"} for (const item of items; key item.value) { } {"Choose your preferred framework"} } ```