Gecko UIGecko UI

RHFTagInput

TagInput wired to React Hook Form

RHFTagInput

TagInput wired to React Hook Form.

Installation

import { RHFTagInput } from '@geckoui/geckoui';

Basic Usage

React

The form holds ["React"]

import { FormProvider, useForm } from 'react-hook-form';
import { RHFTagInput, TagInputOption } from '@geckoui/geckoui';

function ArticleForm() {
  const methods = useForm({ defaultValues: { tags: [] } });

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(save)}>
        <RHFTagInput name="tags" rules={{ validate: (tags) => tags.length > 0 || 'Add one' }}>
          <TagInputOption value="React">React</TagInputOption>
          <TagInputOption value="Vue">Vue</TagInputOption>
        </RHFTagInput>
      </form>
    </FormProvider>
  );
}

The field holds a string[]. A field the form has nothing for reads as an empty list, so the input never has to guard against it.

Props API

PropTypeDefaultDescription
namestringrequiredThe field path
controlControl-Taken from FormProvider when left out
rulesRegisterOptions-Validation rules
onChange(value: string[]) => void-Called alongside the form update
...restTagInputProps-Everything TagInput takes, except value, onChange and aria-invalid

aria-invalid is driven by the field's own error state, so it is not yours to set.

Two kinds of rule

They do different jobs and are worth keeping apart:

  • validate decides whether a single tag may be added at all. A tag it turns down never reaches the form.
  • rules is React Hook Form's, and judges the whole list on submit.
<RHFTagInput
  name="emails"
  validate={(tag) => tag.includes('@')}
  rules={{ validate: (emails) => emails.length <= 10 || 'Ten at most' }}
/>

Pair it with RHFError to show the message:

Add a tag
<RHFTagInput name="tags" rules={{ required: 'Add at least one tag' }} />
<RHFError name="tags" />