useMuiXMobileDateTimePickerAdapter
Returns adapter props for MUI X MobileDateTimePicker with React Hook Form, including how to validate an earliest allowed date and time.
useMuiXMobileDateTimePickerAdapter returns React Hook Form props for MUI X's MobileDateTimePicker. It's what MuiXMobileDateTimePickerElement uses internally.
Use the element for most forms. Use the hook when you build a touch-first date-time field with rules that depend on the current moment, such as a pickup time that must be at least two hours away.
Import
import { useMuiXMobileDateTimePickerAdapter } from "@piplup/rhf-adapters/mui-x-date-pickers";Usage
This PickupField rejects anything earlier than two hours from now and only accepts half-hour slots. Open the dialog to see the earlier times greyed out, or submit without a value to see the required message.
"use client";import { useState } from "react";import dayjs, { type Dayjs } from "dayjs";import Stack from "@mui/material/Stack";import { LocalizationProvider, MobileDateTimePicker } from "@mui/x-date-pickers";import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";import { MuiButtonElement } from "@piplup/rhf-adapters/mui-material";import { useMuiXMobileDateTimePickerAdapter } from "@piplup/rhf-adapters/mui-x-date-pickers";import { type Control, useForm } from "react-hook-form";type FormValues = { pickup: Dayjs | null };// Orders need two hours to prepare. `disableIgnoringDatePartForTimeValidation`// makes the hook compare `minTime` against the full date and time, so it works as// a "not before this moment" rule instead of a daily opening time. `disablePast`// makes the picker do the same, so the views grey out the right times.function PickupField({ control }: { control: Control<FormValues> }) { const [earliest] = useState(() => dayjs().add(2, "hour").startOf("minute")); const adapter = useMuiXMobileDateTimePickerAdapter<Dayjs, FormValues, "pickup", HTMLDivElement>({ control, name: "pickup", required: true, composeHelperText: true, disablePast: true, minDate: earliest, maxDate: earliest.add(30, "day"), minTime: earliest, disableIgnoringDatePartForTimeValidation: true, minutesStep: 30, messages: { required: "Choose a pickup time", minDate: `Pickup can't be before ${earliest.format("ddd D MMM")}`, minTime: `The earliest pickup is ${earliest.format("ddd HH:mm")}`, maxDate: "Orders can be placed up to 30 days ahead", minutesStep: "Pickups are every half hour", }, slotProps: { textField: { helperText: "Tap to open the picker" }, }, }); return <MobileDateTimePicker label="Pickup" ampm={false} {...adapter} />;}export default function Page() { const { control, handleSubmit } = useForm<FormValues>({ defaultValues: { pickup: null }, }); return ( <LocalizationProvider dateAdapter={AdapterDayjs}> <form noValidate onSubmit={handleSubmit((values) => alert(values.pickup?.format("ddd D MMM, HH:mm")), )} > <Stack direction="column" spacing={2}> <PickupField control={control} /> <div> <MuiButtonElement control={control} variant="contained" type="submit"> Place order </MuiButtonElement> </div> </Stack> </form> </LocalizationProvider> );}How it works
This hook calls useMuiXDateTimePickerAdapter with the same props and returns its result unchanged. The validation keys and default messages are listed there.
The difference is the component. DateTimePicker switches between layouts with a media query. MobileDateTimePicker always opens the date and time views in a modal dialog with its own action buttons.
An earliest date and time. The hook does not read minDateTime. To validate "not before this moment", the example passes the same value to minDate and minTime and sets disableIgnoringDatePartForTimeValidation: true:
minDaterejects earlier days with theminDatemessage.minTimewith the flag compares the full date and time, so an earlier time on the same day fails with theminTimemessage. Without the flag,minTimewould act as a daily opening time: a limit of 14:30 would also reject 09:00 tomorrow.disablePastis set as well. MUI X's picker ignores the flag you pass and only compares full dates whendisablePast,disableFuture,minDateTimeormaxDateTimeis set. WithdisablePast, the dialog greys out the same times the form rejects.
Create the limit once, for example with useState(() => dayjs().add(2, "hour")). A new dayjs() on every render moves the limit forward while the user fills the form, so a value that passed a moment ago can fail on submit.
Errors and blur. The text field gets error, helperText and onBlur through slotProps.textField. The hook also wraps onClose, so closing the dialog marks the field as touched, whether the user confirms or cancels. With mode: "onTouched", opening and cancelling the dialog on an empty required field shows the required message straight away.
Props
Prop
Type
Return value
Prop
Type
useMuiXMobileDatePickerAdapter
Returns adapter props for MUI X MobileDatePicker with React Hook Form, with month-level rules through shouldDisableMonth.
useMuiXMobileTimePickerAdapter
Returns adapter props for building custom MUI X MobileTimePicker integrations with React Hook Form, where the time is chosen on an analog clock in a dialog.