Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
560 lines (389 sloc) 18.1 KB
path experimental redirect_from
/docs/form/
true
/components/field/
/components/input/
/components/label/

Form

This is experimental and may have breaking changes in minor or patch version updates. Issues for this module will have lower priority. Even so, if you use it, feel free to give us feedback.

Form is a component with a collection of other components, such as FormLabel and FormInput.

Installation

npm install reakit

Learn more in Get started.

Usage

import { Group } from "reakit/Group";
import {
  unstable_Form as Form,
  unstable_FormLabel as FormLabel,
  unstable_FormCheckbox as FormCheckbox,
  unstable_FormGroup as FormGroup,
  unstable_FormRadioGroup as FormRadioGroup,
  unstable_FormRadio as FormRadio,
  unstable_FormRemoveButton as FormRemoveButton,
  unstable_FormPushButton as FormPushButton,
  unstable_FormSubmitButton as FormSubmitButton,
  unstable_FormInput as FormInput,
  unstable_FormMessage as FormMessage,
  unstable_useFormState as useFormState
} from "reakit/Form";

function Example() {
  const form = useFormState({
    values: {
      name: "",
      emails: [],
      accepted: false,
      preferences: [],
      choice: ""
    },
    onValidate: values => {
      if (values.name !== "a") {
        const result = { name: "no" };
        throw result;
      }
    }
  });
  return (
    <Form {...form}>
      <FormLabel name="name" {...form}>
        Name
      </FormLabel>
      <FormInput name="name" placeholder="Name" {...form} />
      <FormMessage name="name" {...form} />
      <FormCheckbox name="accepted" {...form} />
      <FormLabel name="accepted" {...form}>
        Accept
      </FormLabel>
      <FormGroup name="preferences" {...form}>
        <FormLabel as="legend" name="preferences" {...form}>
          Preferences
        </FormLabel>
        <label>
          <FormCheckbox name="preferences" value="html" {...form} /> HTML
        </label>
        <label>
          <FormCheckbox name="preferences" value="css" {...form} /> CSS
        </label>
        <label>
          <FormCheckbox name="preferences" value="JS" {...form} /> JS
        </label>
      </FormGroup>
      <FormRadioGroup name="choice" {...form}>
        <FormLabel as="legend" name="choice" {...form}>
          Choice
        </FormLabel>
        <label>
          <FormRadio name="choice" value="html" {...form} /> HTML
        </label>
        <label>
          <FormRadio name="choice" value="css" {...form} /> CSS
        </label>
        <label>
          <FormRadio name="choice" value="js" {...form} /> JS
        </label>
      </FormRadioGroup>
      {form.values.emails.map((_, i) => (
        <Group key={i}>
          <FormInput name={["emails", i, "name"]} {...form} />
          <FormInput type="email" name={["emails", i, "email"]} {...form} />
          <FormRemoveButton name="emails" index={i} {...form}>
            x
          </FormRemoveButton>
        </Group>
      ))}
      <FormPushButton name="emails" value={{ name: "", email: "" }} {...form}>
        Add email
      </FormPushButton>
      <FormSubmitButton {...form}>Subscribe</FormSubmitButton>
      <pre>{JSON.stringify(form, null, 2)}</pre>
    </Form>
  );
}

Accessibility

  • Form has role form.
  • Clicking on FormSubmitButton on a form with errors will move focus to the first failed input.
  • Clicking on FormPushButton will move focus to the first input in the added row.
  • Clicking on FormRemoveButton will move focus to the first input in the next row. If there's no next row, it will move focus to the first input in the previous row. If there's no previous row, it will move focus to FormPushButton.

Learn more in Accessibility.

Composition

  • Form uses Box.
  • FormCheckbox uses Checkbox.
  • FormGroup uses Group.
  • FormInput uses Tabbable.
  • FormLabel uses Box.
  • FormMessage uses Box.
  • FormPushButton uses Button.
  • FormRadio uses Radio.
  • FormRadioGroup uses FormGroup.
  • FormRemoveButton uses Button.
  • FormSubmitButton uses Button.

Learn more in Composition.

Props

useFormState

  • baseId string

    An ID that will serve as a base for the form elements.

  • values V

    Form values.

  • validateOnBlur boolean | undefined

    Whether the form should trigger onValidate on blur.

  • validateOnChange boolean | undefined

    Whether the form should trigger onValidate on change.

  • resetOnSubmitSucceed boolean | undefined

    Whether the form should reset when it has been successfully submitted.

  • resetOnUnmount boolean | undefined

    Whether the form should reset when the component (which called useFormState) has been unmounted.

  • onValidate ((values: V) => ValidateReturn<V>) | undefined

    A function that receives form.values and return or throw messages. If it returns, messages will be interpreted as successful messages. If it throws, they will be interpreted as errors. It can also return a promise for asynchronous validation.

  • onSubmit ((values: V) => ValidateReturn<V>) | undefined

    A function that receives form.values and performs form submission. If it's triggered by form.submit(), onValidate will be called before. If onValidate throws, onSubmit will not be called. onSubmit can also return promises, messages and throw error messages just like onValidate. The only difference is that this validation will only occur on submit.

Form

  • submit () => void

    Triggers form submission (calling onValidate and onSubmit underneath).

FormCheckbox

  • disabled boolean | undefined

    Same as the HTML attribute.

  • focusable boolean | undefined

    When an element is disabled, it may still be focusable. It works similarly to readOnly on form elements. In this case, only aria-disabled will be set.

  • checked boolean | undefined

    Checkbox's checked state. If present, it's used instead of state.

  • baseId string

    An ID that will serve as a base for the form elements.

  • values V

    Form values.

  • update Update<V>

    Updates a form value.

  • blur <P extends DeepPath<V, P>>(name: P) => void

    Sets field's touched state to true.

  • touched { [P in keyof DeepMap<V, boolean>]?: (DeepMap<V...

    An object with the same shape as form.values with boolean values. This keeps the touched state of each field. That is, whether a field has been blurred.

  • errors { [P in keyof DeepMap<V, string | void | null>]...

    An object with the same shape as form.values with string error messages. This stores the error messages throwed by onValidate and onSubmit.

  • name P

    Checkbox's name as in form values.

  • value ArrayValue<DeepPathValue<V, P>> | undefined

    Checkbox's value is going to be used when multiple checkboxes share the same state. Checking a checkbox with value will add it to the state array.

FormGroup

  • baseId string

    An ID that will serve as a base for the form elements.

  • touched { [P in keyof DeepMap<V, boolean>]?: (DeepMap<V...

    An object with the same shape as form.values with boolean values. This keeps the touched state of each field. That is, whether a field has been blurred.

  • errors { [P in keyof DeepMap<V, string | void | null>]...

    An object with the same shape as form.values with string error messages. This stores the error messages throwed by onValidate and onSubmit.

  • name P

    FormGroup's name as in form values.

FormInput

  • disabled boolean | undefined

    Same as the HTML attribute.

  • focusable boolean | undefined

    When an element is disabled, it may still be focusable. It works similarly to readOnly on form elements. In this case, only aria-disabled will be set.

  • baseId string

    An ID that will serve as a base for the form elements.

  • values V

    Form values.

  • update Update<V>

    Updates a form value.

  • blur <P extends DeepPath<V, P>>(name: P) => void

    Sets field's touched state to true.

  • touched { [P in keyof DeepMap<V, boolean>]?: (DeepMap<V...

    An object with the same shape as form.values with boolean values. This keeps the touched state of each field. That is, whether a field has been blurred.

  • errors { [P in keyof DeepMap<V, string | void | null>]...

    An object with the same shape as form.values with string error messages. This stores the error messages throwed by onValidate and onSubmit.

  • name P

    FormInput's name as in form values.

FormLabel

  • baseId string

    An ID that will serve as a base for the form elements.

  • values V

    Form values.

  • name P

    FormInput's name as in form values.

  • label any

    Label can be passed as the label prop or children.

FormMessage

  • baseId string

    An ID that will serve as a base for the form elements.

  • touched { [P in keyof DeepMap<V, boolean>]?: (DeepMap<V...

    An object with the same shape as form.values with boolean values. This keeps the touched state of each field. That is, whether a field has been blurred.

  • errors { [P in keyof DeepMap<V, string | void | null>]...

    An object with the same shape as form.values with string error messages. This stores the error messages throwed by onValidate and onSubmit.

  • messages { [P in keyof DeepMap<V, string | void | null>]...

    An object with the same shape as form.values with string messages. This stores the messages returned by onValidate and onSubmit.

  • name P

    FormInput's name as in form values.

FormPushButton

  • disabled boolean | undefined

    Same as the HTML attribute.

  • focusable boolean | undefined

    When an element is disabled, it may still be focusable. It works similarly to readOnly on form elements. In this case, only aria-disabled will be set.

  • baseId string

    An ID that will serve as a base for the form elements.

  • values V

    Form values.

  • push <P extends DeepPath<V, P>>(name: P, value?: Arr...

    Pushes a new item into form.values[name], which should be an array.

  • name P

    FormInput's name as in form values. This should point to array value.

  • value DeepPathValue<V, P> extends (infer U)[] ? U : n...

    The value that is going to be pushed to form.values[name].

FormRadio

  • values V

    Form values.

  • update Update<V>

    Updates a form value.

  • blur <P extends DeepPath<V, P>>(name: P) => void

    Sets field's touched state to true.

  • name P

    FormRadio's name as in form values.

  • value P extends DeepPathArray<V, P> ? DeepPathArrayVa...

    FormRadio's value.

FormRadioGroup

  • baseId string

    An ID that will serve as a base for the form elements.

  • touched { [P in keyof DeepMap<V, boolean>]?: (DeepMap<V...

    An object with the same shape as form.values with boolean values. This keeps the touched state of each field. That is, whether a field has been blurred.

  • errors { [P in keyof DeepMap<V, string | void | null>]...

    An object with the same shape as form.values with string error messages. This stores the error messages throwed by onValidate and onSubmit.

  • name P

    FormGroup's name as in form values.

FormRemoveButton

  • disabled boolean | undefined

    Same as the HTML attribute.

  • focusable boolean | undefined

    When an element is disabled, it may still be focusable. It works similarly to readOnly on form elements. In this case, only aria-disabled will be set.

  • baseId string

    An ID that will serve as a base for the form elements.

  • values V

    Form values.

  • remove <P extends DeepPath<V, P>>(name: P, index: numb...

    Removes form.values[name][index].

  • name P

    FormInput's name as in form values. This should point to array value.

  • index number

    The index in form.values[name] that will be removed.

FormSubmitButton

  • disabled boolean | undefined

    Same as the HTML attribute.

  • focusable boolean | undefined

    When an element is disabled, it may still be focusable. It works similarly to readOnly on form elements. In this case, only aria-disabled will be set.

  • submitting boolean

    Whether form is submitting or not.

  • baseId string

    An ID that will serve as a base for the form elements.

  • submit () => void

    Triggers form submission (calling onValidate and onSubmit underneath).

You can’t perform that action at this time.