useMuiXDesktopDateTimePickerAdapter
Returns adapter props for MUI X DesktopDateTimePicker with React Hook Form, with per-view time rules through shouldDisableTime.
useMuiXDesktopDateTimePickerAdapter returns React Hook Form props for MUI X's DesktopDateTimePicker. It's what MuiXDesktopDateTimePickerElement uses internally.
Use the element for most forms. Use the hook when you want a desktop date-time field with your own rules built in, for example one that always opens as a popover and blocks hours your team is not available.
Import
import { useMuiXDesktopDateTimePickerAdapter } from "@piplup/rhf-adapters/mui-x-date-pickers";Usage
This CallbackField only accepts hours between 08:00 and 20:00, skips the 13:00 lunch hour, and rejects past times. Open the picker to see the blocked hours, or type 13:15 and submit.
"use client";import dayjs, { type Dayjs } from "dayjs";import Stack from "@mui/material/Stack";import { DesktopDateTimePicker, LocalizationProvider } from "@mui/x-date-pickers";import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";import { MuiButtonElement } from "@piplup/rhf-adapters/mui-material";import { useMuiXDesktopDateTimePickerAdapter } from "@piplup/rhf-adapters/mui-x-date-pickers";import { type Control, useForm } from "react-hook-form";type FormValues = { callback: Dayjs | null };// Support calls happen between 08:00 and 20:00, never during the 13:00 lunch hour.function isClosedHour(hour: number) { return hour < 8 || hour >= 20 || hour === 13;}function CallbackField({ control }: { control: Control<FormValues> }) { const adapter = useMuiXDesktopDateTimePickerAdapter< Dayjs, FormValues, "callback", HTMLDivElement >({ control, name: "callback", required: true, composeHelperText: true, disablePast: true, minDate: dayjs(), maxDate: dayjs().add(14, "day"), shouldDisableTime: (value, view) => view === "hours" && isClosedHour(value.hour()), messages: { required: "When should we call you?", disablePast: "Pick a time in the future", maxDate: "We can call you within the next two weeks", "shouldDisableTime-hours": "We call between 08:00 and 20:00, except 13:00 to 14:00", }, // A function is called with the picker's owner state; the adapter adds its own // error, helperText and onBlur on top of what it returns. slotProps: { textField: () => ({ helperText: "Times are in your local time zone" }), }, }); return <DesktopDateTimePicker label="Call me back at" ampm={false} {...adapter} />;}export default function Page() { const { control, handleSubmit } = useForm<FormValues>({ defaultValues: { callback: null }, }); return ( <LocalizationProvider dateAdapter={AdapterDayjs}> <form noValidate onSubmit={handleSubmit((values) => alert(values.callback?.format("ddd D MMM, HH:mm")), )} > <Stack direction="column" spacing={2}> <CallbackField control={control} /> <div> <MuiButtonElement control={control} variant="contained" type="submit"> Request callback </MuiButtonElement> </div> </Stack> </form> </LocalizationProvider> );}How it works
This hook calls useMuiXDateTimePickerAdapter with the same props and returns its result unchanged. Validation rules, default messages and the minTime/maxTime behavior are documented there.
The difference is the component you spread the props onto. DateTimePicker picks the desktop or mobile layout with a @media (pointer: fine) query. DesktopDateTimePicker always uses the desktop layout: the calendar and time columns open in a popover next to the field.
shouldDisableTime runs once per time view. The hook calls shouldDisableTime(value, "hours"), then "minutes", then "seconds", and reports the first one that returns true under its own key: shouldDisableTime-hours, shouldDisableTime-minutes or shouldDisableTime-seconds. Check the view argument and only return true for the view your rule is about, as the example does. A rule that ignores view always fails on hours first, so only the hours message ever shows.
The same function greys out options in the popover's time columns, so users mostly hit the message when they type a time.
Errors and blur. error, helperText and onBlur go to the text field through slotProps.textField. You can pass slotProps.textField as a function of the picker's owner state, as the example does. The hook calls it and merges the result with its own props: an error message wins over your helperText, and both onBlur handlers run. Leaving the text field and closing the popover both mark the field as touched.
Props
Prop
Type
Return value
Prop
Type
useMuiXDesktopDatePickerAdapter
Returns adapter props for MUI X DesktopDatePicker with React Hook Form, with an example of limits that depend on another field.
useMuiXDesktopTimePickerAdapter
Returns adapter props for building custom MUI X DesktopTimePicker integrations with React Hook Form, where users mostly type times into the field.