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

useMuiXTimeClockAdapter

Returns adapter props for building custom MUI X TimeClock integrations with React Hook Form, with time validation and errors rendered outside the clock.

useMuiXTimeClockAdapter connects a field to React Hook Form and returns props you spread onto MUI X's analog TimeClock. It's what MuiXTimeClockElement uses internally.

The element shows the clock only and drops the error message. Use the hook when the clock sits inline in a form, such as an alarm or reminder setting, and you need to show why the stored value was rejected.

Import

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

Usage

This WakeUpClock rejects times before 06:00. The form starts with a saved value of 05:30. The clock disables hours before 06:00, but the stored value is still checked: submit straight away to see the error, then pick a new time.

001234567891011121314151617181920212223

"use client";import dayjs, { type Dayjs } from "dayjs";import FormHelperText from "@mui/material/FormHelperText";import Stack from "@mui/material/Stack";import { LocalizationProvider, TimeClock } from "@mui/x-date-pickers";import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";import { MuiButtonElement } from "@piplup/rhf-adapters/mui-material";import { useMuiXTimeClockAdapter } from "@piplup/rhf-adapters/mui-x-date-pickers";import { type Control, useForm } from "react-hook-form";type FormValues = { wakeUp: Dayjs | null };const earliest = dayjs().hour(6).minute(0);// TimeClock has no text field and no `error` or `helperText` props, so they are// pulled out of the adapter and rendered below the clock instead.function WakeUpClock({ control }: { control: Control<FormValues> }) {  const {    error,    helperText,    required: _required,    ...adapter  } = useMuiXTimeClockAdapter<Dayjs, FormValues, "wakeUp", HTMLDivElement>({    control,    name: "wakeUp",    required: true,    composeHelperText: true,    minTime: earliest,    messages: {      required: "Set a wake-up time",      minTime: "Alarms can't be set before 06:00",    },  });  return (    <div>      <TimeClock ampm={false} views={["hours", "minutes"]} {...adapter} />      <FormHelperText error={error}>{helperText}</FormHelperText>    </div>  );}export default function Page() {  // The saved value (05:30) is earlier than `minTime`. The clock disables those  // hours, but submitting still reports the stored value as invalid.  const { control, handleSubmit } = useForm<FormValues>({    defaultValues: { wakeUp: dayjs().hour(5).minute(30) },  });  return (    <LocalizationProvider dateAdapter={AdapterDayjs}>      <form        noValidate        onSubmit={handleSubmit((values) => alert(values.wakeUp?.format("HH:mm")))}      >        <Stack direction="column" spacing={2}>          <WakeUpClock control={control} />          <div>            <MuiButtonElement control={control} variant="contained" type="submit">              Set alarm            </MuiButtonElement>          </div>        </Stack>      </form>    </LocalizationProvider>  );}

How it works

Validation and default messages are the same as useMuiXTimePickerAdapter. The clock disables the hours and minutes that minTime, maxTime, minutesStep and shouldDisableTime reject, because the hook returns those props. That only limits new picks. A value that is already in the form, from defaultValues, reset or setValue, is validated as-is.

The result is shaped for a component with no text field:

  • error, helperText and required are plain values. TimeClock does not accept these props and passes unknown props to its root element, so take them out of the result before spreading it. The element does the same.
  • With composeHelperText: true, helperText holds the error message while the field is invalid, and your helperText prop otherwise.
  • There is no slotProps, inputRef or onClose. The hook's second argument is merged with React Hook Form's ref and returned as ref, which ends up on the clock's root element.

Touched. The hook does not accept an onBlur prop. The returned onBlur is React Hook Form's own, and TimeClock puts it on its root element. React blur events bubble, so the field is marked as touched when focus leaves any element inside the clock, for example after picking an hour with the keyboard.

TimeClock updates the value at each step: moving the hour hand already sets a full time, before the user reaches the minutes view. With mode: "onChange", an error can show while the user is still picking minutes.

Props

Prop

Type

Return value

Prop

Type

On this page