useMuiSwitchAdapter
Returns adapter props for building custom MUI Switch fields with React Hook Form, with boolean checked handling and custom stored values.
useMuiSwitchAdapter connects a field to React Hook Form and returns props you spread onto MUI's Switch. It's what MuiSwitchElement uses internally.
The element drops the error state and has no place for a message. Use the hook when a switch must show why it's invalid, like a required terms switch, or when the form should store something other than true/false.
Import
import { useMuiSwitchAdapter } from "@piplup/rhf-adapters/mui-material";Usage
The terms switch must be on to submit. The newsletter switch stores "subscribed" or "unsubscribed" instead of a boolean.
"use client";import type { ChangeEvent } from "react";import Stack from "@mui/material/Stack";import Switch from "@mui/material/Switch";import FormControlLabel from "@mui/material/FormControlLabel";import FormHelperText from "@mui/material/FormHelperText";import { MuiButtonElement, useMuiSwitchAdapter,} from "@piplup/rhf-adapters/mui-material";import { type Control, useForm } from "react-hook-form";type FormValues = { terms: boolean; newsletter: "subscribed" | "unsubscribed";};// A switch that must be on. `false` fails the `required` rule.function TermsSwitch({ control }: { control: Control<FormValues> }) { const { helperText, error, ...adapter } = useMuiSwitchAdapter< boolean, FormValues, "terms" >({ control, name: "terms", required: true, composeHelperText: true, messages: { required: "You need to accept the terms to continue" }, }); return ( <div> <FormControlLabel control={<Switch {...adapter} />} label="I accept the terms of service" /> {error && <FormHelperText error>{helperText}</FormHelperText>} </div> );}// A switch that stores a string instead of a boolean.function NewsletterSwitch({ control }: { control: Control<FormValues> }) { const { helperText: _helperText, error: _error, ...adapter } = useMuiSwitchAdapter<boolean, FormValues, "newsletter">({ control, name: "newsletter", transform: { input: (value) => value === "subscribed", output: (event: ChangeEvent<HTMLInputElement>) => event.target.checked ? "subscribed" : "unsubscribed", }, }); return ( <FormControlLabel control={<Switch {...adapter} />} label="Send me the monthly newsletter" /> );}export default function Page() { const { control, handleSubmit } = useForm<FormValues>({ defaultValues: { terms: false, newsletter: "unsubscribed" }, }); return ( <form noValidate onSubmit={handleSubmit((values) => alert(JSON.stringify(values, null, 2)), )} > <Stack direction="column" spacing={1}> <TermsSwitch control={control} /> <NewsletterSwitch control={control} /> <div> <MuiButtonElement control={control} variant="contained" type="submit"> Continue </MuiButtonElement> </div> </Stack> </form> );}How it works
Checked, not value. The hook returns checked instead of value. By default, checked is the field value converted to a boolean (!!value), and a toggle stores event.target.checked. So undefined, null, 0 and "" all show as off, and the form always stores a boolean after the first toggle.
Storing other values. transform.input maps the stored value to checked, and transform.output maps the change event to the stored value. Each replaces its default separately, so when the form stores anything other than a boolean, pass both. With only output, the default !!value still runs, and a stored "unsubscribed" shows as on because it's a non-empty string.
Required. required: true adds a rule with the message "Please fill out this field.", which you can change through messages.required. React Hook Form treats false as empty for required, so a boolean switch must be on to pass. With a transform that stores strings, both strings are non-empty and required never fails. Use rules.validate in that case, e.g. validate: (value) => value === "subscribed" || "Please subscribe".
The text rules (min, max, minLength, maxLength, pattern) are accepted but have nothing useful to check on a switch.
Errors and helper text. The result includes error and helperText, but Switch has neither prop. Take them out before spreading and render the message yourself, for example in a FormHelperText. With composeHelperText: true, helperText holds the error message while the field is invalid.
Generics. Without a transform, TypeScript can't infer the type of checked. Pass the generics explicitly: useMuiSwitchAdapter<boolean, FormValues, "terms">(...).
Props
Prop
Type
Return value
Prop
Type
useMuiSliderAdapter
Returns props that connect an MUI Slider to React Hook Form, for single and range sliders, with fallbacks for empty values and transforms for custom shapes.
useMuiTextFieldAdapter
Returns adapter props for building custom MUI TextField components with React Hook Form, with the field ref routed to the inner input.