useMuiInputLabelAdapter
Returns props for an MUI InputLabel that follows a React Hook Form field's error state without registering a value.
useMuiInputLabelAdapter returns props for MUI's floating InputLabel that reflect the state of a field registered by another hook. It's what MuiInputLabelElement uses internally.
Use the hook inside a custom field component built from FormControl, InputLabel, an input and FormHelperText, so the floating label turns red with the input without passing error around by hand.
Import
import { useMuiInputLabelAdapter } from "@piplup/rhf-adapters/mui-material";Usage
PromoCodeField uses useMuiInputAdapterProps for the input and this hook for the label. The code is uppercased as you type. Enter SAVE24 and submit to see the label, underline and helper text switch to the error state.
"use client";import { type ChangeEvent, useId } from "react";import Stack from "@mui/material/Stack";import FormControl from "@mui/material/FormControl";import FormHelperText from "@mui/material/FormHelperText";import Input from "@mui/material/Input";import InputLabel from "@mui/material/InputLabel";import { MuiButtonElement, useMuiInputAdapterProps, useMuiInputLabelAdapter,} from "@piplup/rhf-adapters/mui-material";import { type Control, useForm } from "react-hook-form";type FormValues = { promoCode: string };// The floating label turns red when the promo code is invalid. The label// hook does not register anything; it only reads the field's error.function PromoCodeField({ control }: { control: Control<FormValues> }) { const id = useId(); const { helperText: _labelHelperText, ...label } = useMuiInputLabelAdapter< FormValues, "promoCode", HTMLLabelElement >({ control, name: "promoCode", }); const { ref, helperText, ...input } = useMuiInputAdapterProps({ control, name: "promoCode", pattern: /^[A-Z]{4}-\d{4}$/, composeHelperText: true, helperText: "Optional, e.g. SAVE-2024", messages: { pattern: "Codes look like SAVE-2024" }, transform: { output: (event: ChangeEvent<HTMLInputElement>) => event.target.value.toUpperCase(), }, }); return ( <FormControl variant="standard"> <InputLabel {...label} htmlFor={id}> Promo code </InputLabel> <Input {...input} id={id} inputRef={ref} /> <FormHelperText error={input.error}>{helperText}</FormHelperText> </FormControl> );}export default function Page() { const { control, handleSubmit } = useForm<FormValues>({ defaultValues: { promoCode: "" }, }); return ( <form noValidate onSubmit={handleSubmit((values) => alert(JSON.stringify(values, null, 2)), )} > <Stack direction="column" spacing={2}> <PromoCodeField control={control} /> <div> <MuiButtonElement control={control} variant="contained" type="submit"> Apply </MuiButtonElement> </div> </Stack> </form> );}How it works
The hook reads the field's state by name and registers nothing, exactly like useMuiFormLabelAdapter. That page covers the returned props and the cases the label can't see, such as an input disabled through its own disabled prop.
What differs from the FormLabel hook. This hook doesn't read MUI's FormControl. It always returns disabled as a boolean, and InputLabel lets that value override the control's state. Inside <FormControl disabled>, the label keeps its normal color unless you also pass disabled to this hook. The same applies to error.
InputLabel still takes required, focused, variant and size from the FormControl, so the asterisk, the focus color and the floating position work as usual. Shrinking follows the input's value through the FormControl, not this hook.
Types. Remove helperText from the result before spreading, since InputLabel doesn't accept it. If TypeScript rejects the returned ref, pass the element type as the third generic: useMuiInputLabelAdapter<FormValues, "promoCode", HTMLLabelElement>(...).
Props
Prop
Type
Return value
Prop
Type
useMuiInputBaseAdapter
Returns adapter props for building custom MUI InputBase fields with React Hook Form, including number handling, transforms and validation rules.
useMuiOutlinedInputAdapter
Returns adapter props for building custom MUI OutlinedInput fields with React Hook Form, such as a password field with a show/hide toggle.