Piplup
@piplup/rhf-adaptersmui-x-date-pickersHooks

useMuiXDatePickerAdapter

Returns adapter props for building custom MUI X DatePicker integrations with React Hook Form.

useMuiXDatePickerAdapter connects a field to React Hook Form and returns props you spread onto MUI X's DatePicker. It's what MuiXDatePickerElement uses internally.

Use the element for most forms. Reach for the hook when you want to build your own date field component, for example to bake in project-wide rules, wrap the picker in extra layout, or render a different picker variant with the same form wiring.

Import

import { useMuiXDatePickerAdapter } from "@piplup/rhf-adapters/mui-x-date-pickers";

Usage

This AppointmentField only accepts future weekdays and uses its own error messages. Submit the form empty, or pick a weekend date by typing it, to see the validation.

MM/DD/YYYY

Weekdays only

"use client";import type { Dayjs } from "dayjs";import Stack from "@mui/material/Stack";import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers";import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";import { MuiButtonElement } from "@piplup/rhf-adapters/mui-material";import { useMuiXDatePickerAdapter } from "@piplup/rhf-adapters/mui-x-date-pickers";import { type Control, useForm } from "react-hook-form";type FormValues = { appointment: Dayjs | null };// A reusable field with project-wide defaults baked in: weekdays only,// no past dates, and custom validation messages.function AppointmentField({ control }: { control: Control<FormValues> }) {  const adapter = useMuiXDatePickerAdapter<Dayjs, FormValues, "appointment", HTMLDivElement>({    control,    name: "appointment",    required: true,    composeHelperText: true,    disablePast: true,    shouldDisableDate: (date) => date.day() === 0 || date.day() === 6,    messages: {      required: "Pick a date for your appointment",      disablePast: "Appointments can't be in the past",      shouldDisableDate: "We're closed on weekends",    },    slotProps: {      textField: { helperText: "Weekdays only" },    },  });  return <DatePicker label="Appointment" {...adapter} />;}export default function Page() {  const { control, handleSubmit } = useForm<FormValues>({    defaultValues: { appointment: null },  });  return (    <LocalizationProvider dateAdapter={AdapterDayjs}>      <form        noValidate        onSubmit={handleSubmit((values) =>          alert(values.appointment?.format("dddd, D MMMM YYYY")),        )}      >        <Stack direction="column" spacing={2}>          <AppointmentField control={control} />          <div>            <MuiButtonElement control={control} variant="contained" type="submit">              Book            </MuiButtonElement>          </div>        </Stack>      </form>    </LocalizationProvider>  );}

The hook must run inside a LocalizationProvider, because it reads the date adapter to validate values and apply the default minDate/maxDate.

How it works

Value. The field value is passed to the picker as-is, with undefined converted to null so the picker stays controlled. Store date objects from your date library (e.g. Dayjs), not strings: the built-in validation runs on the stored value, and a string stored through transform makes it throw. Convert to a string when you submit instead.

Validation. The hook runs MUI X's own validateDate against minDate, maxDate, disablePast, disableFuture, shouldDisableDate, shouldDisableMonth and shouldDisableYear. Any failure becomes a React Hook Form error, so it blocks submission like any other rule. Empty values pass this check; add required to reject them.

Each failure has a default message, which you can replace through messages:

KeyDefault message
requiredPlease fill out this field.
invalidDateDate is not a valid date
disablePastPast date is not allowed
disableFutureFuture date is not allowed
minDateDate must be later than the minimum allowed date
maxDateDate should be earlier than the maximum allowed date
shouldDisableDateDate is not allowed
shouldDisableMonthMonth is not allowed
shouldDisableYearYear is not allowed

Errors and blur. The returned slotProps.textField sets error and helperText from the field state, and calls React Hook Form's onBlur so the field is marked as touched. Your own slotProps.textField (an object or a function) is merged in: an error message takes priority over your helperText, which shows when the field is valid. Closing the picker also counts as a blur.

Custom messages and rules.validate. Messages can be strings or functions. A function receives the value, and for minDate and maxDate also the limit, for example (value, minDate) => "Pick a date after " + minDate.format("LL"). A validate function or object in rules runs next to the built-in date validation, not instead of it.

Set composeHelperText: true to show the error message as the helper text, as the element does. Without it, only the error state is applied.

Props

Prop

Type

Return value

Prop

Type

On this page