MuiChipsInputElement
A mui-chips-input field connected to React Hook Form that stores chips as a string array, with per-chip and whole-array validation.
MuiChipsInputElement renders MuiChipsInput from mui-chips-input and stores its chips in React Hook Form as a string[]. It accepts all MuiChipsInput and TextField props. To build your own chips field, or store the chips in another shape, use useMuiChipsInputAdapter.
Import
import { MuiChipsInputElement } from "@piplup/rhf-adapters/mui-chips-input";Usage
"use client";import Stack from "@mui/material/Stack";import { MuiChipsInputElement } from "@piplup/rhf-adapters/mui-chips-input";import { MuiButtonElement } from "@piplup/rhf-adapters/mui-material";import { useForm } from "react-hook-form";export default function Page() { const { control, handleSubmit } = useForm({ defaultValues: { tags: ["react"] }, }); return ( <form onSubmit={handleSubmit((values) => alert(JSON.stringify(values, null, 2)), )} > <Stack direction="column" spacing={2}> <MuiChipsInputElement control={control} name="tags" label="Tags" /> <div> <MuiButtonElement control={control} variant="contained" type="submit"> Submit </MuiButtonElement> </div> </Stack> </form> );}Validating each chip
Chips can be checked in two places, and you usually want both:
validate(aMuiChipsInputprop) runs when the user presses Enter. A chip that fails is not added. If it returns{ isError: true, textError }, the input showstextErroras its helper text until the user types again.validateChipValues(fn)turns the same function into a React Hook Form rule that checks every chip already in the value. That coversdefaultValues,setValueandreset, which never go through the input.
In this demo, ben@example comes from defaultValues, so only the form rule catches it. Submit to see the error, then remove the chip. The form also limits the list to three recipients.
"use client";import Stack from "@mui/material/Stack";import { MuiChipsInputElement, validateChipValues } from "@piplup/rhf-adapters/mui-chips-input";import { MuiButtonElement } from "@piplup/rhf-adapters/mui-material";import { useForm } from "react-hook-form";// One check, used twice: by the input (blocks new chips)// and by the form (catches values that are already there).const isEmail = (chip: string) => /^\S+@\S+\.\S+$/.test(chip) || { isError: true, textError: `${chip} is not an email address`, };export default function Page() { const { control, handleSubmit } = useForm({ // "ben@example" never went through the input, so only the form rule sees it. defaultValues: { recipients: ["ana@example.com", "ben@example"] }, }); return ( <form noValidate onSubmit={handleSubmit((values) => alert(JSON.stringify(values, null, 2)))} > <Stack direction="column" spacing={2}> <MuiChipsInputElement control={control} name="recipients" label="Recipients" helperText="Up to 3 email addresses" required messages={{ required: "Add at least one recipient" }} validate={isEmail} rules={{ validate: { emails: validateChipValues(isEmail), count: (value) => value.length <= 3 || "You can add up to 3 recipients", }, }} /> <div> <MuiButtonElement control={control} variant="contained" type="submit"> Send </MuiButtonElement> </div> </Stack> </form> );}validateChipValues skips non-string entries and returns the first failing chip's textError. If your function returns false, or an empty textError, the field is marked invalid with an empty message, so the red state shows but your helperText stays. Return a textError to get a message.
How it works
Value. The form value is passed to MuiChipsInput as value, and onChange stores the new array. An undefined value shows no chips.
Rules. required fails for an empty array, with the default message "Please fill out this field." (override it with messages.required). Length and range props (minLength, maxLength, min, max, pattern) are not supported, because they would apply to the array. Count chips in rules.validate instead, as in the demo.
Errors and helper text. The element always shows the field's error message in place of helperText while the field is invalid. A textError from the validate prop takes priority over both while it is showing.
Refs. inputRef reaches the text input and is merged with React Hook Form's ref, so the input gets focus when the field fails validation on submit. A ref on the element goes to the MuiChipsInput root.
Props
Prop
Type