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

useMuiXMultiSectionDigitalClockAdapter

Returns adapter props for building custom MUI X MultiSectionDigitalClock integrations with React Hook Form, with per-section (hours, minutes, seconds) validation messages.

useMuiXMultiSectionDigitalClockAdapter connects a field to React Hook Form and returns props you spread onto MUI X's MultiSectionDigitalClock, which shows one scrollable column per section (hours, minutes, seconds, AM/PM). It's what MuiXMultiSectionDigitalClockElement uses internally.

The element shows the columns only and drops the error message. Use the hook when the clock is inline in your form and you want a separate message for each column's rule, for example one for minutes and one for seconds.

Import

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

Usage

This DepartureClock allows departures every 5 minutes, at :00 or :30 seconds. The columns only list valid values, so submit without picking a time to see the required error below the clock.

  • 00
  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 00
  • 05
  • 10
  • 15
  • 20
  • 25
  • 30
  • 35
  • 40
  • 45
  • 50
  • 55
  • 00
  • 30

"use client";import type { Dayjs } from "dayjs";import FormHelperText from "@mui/material/FormHelperText";import Stack from "@mui/material/Stack";import { LocalizationProvider, MultiSectionDigitalClock } from "@mui/x-date-pickers";import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";import { MuiButtonElement } from "@piplup/rhf-adapters/mui-material";import { useMuiXMultiSectionDigitalClockAdapter } from "@piplup/rhf-adapters/mui-x-date-pickers";import { type Control, useForm } from "react-hook-form";type FormValues = { departure: Dayjs | null };// Departures leave every 5 minutes, at :00 or :30 seconds past the minute.// Each column is checked separately, so each section gets its own message.function DepartureClock({ control }: { control: Control<FormValues> }) {  const {    error,    helperText,    required: _required,    ...adapter  } = useMuiXMultiSectionDigitalClockAdapter<Dayjs, FormValues, "departure", HTMLDivElement>({    control,    name: "departure",    required: true,    composeHelperText: true,    minutesStep: 5,    shouldDisableTime: (value, view) => view === "seconds" && value.second() % 30 !== 0,    messages: {      required: "Pick a departure time",      minutesStep: "Departures leave every 5 minutes",      "shouldDisableTime-seconds": "Only :00 or :30 seconds",    },  });  return (    <div>      <MultiSectionDigitalClock        ampm={false}        views={["hours", "minutes", "seconds"]}        timeSteps={{ minutes: 5, seconds: 30 }}        {...adapter}      />      <FormHelperText error={error}>{helperText}</FormHelperText>    </div>  );}export default function Page() {  const { control, handleSubmit } = useForm<FormValues>({    defaultValues: { departure: null },  });  return (    <LocalizationProvider dateAdapter={AdapterDayjs}>      <form        noValidate        onSubmit={handleSubmit((values) => alert(values.departure?.format("HH:mm:ss")))}      >        <Stack direction="column" spacing={2}>          <DepartureClock control={control} />          <div>            <MuiButtonElement control={control} variant="contained" type="submit">              Save departure            </MuiButtonElement>          </div>        </Stack>      </form>    </LocalizationProvider>  );}

How it works

Validation and default messages are the same as useMuiXTimePickerAdapter. The result is shaped like the useMuiXTimeClockAdapter one: take error, helperText and required out before spreading, render the message yourself, and expect the field to become touched when focus leaves the columns.

One rule per column. MultiSectionDigitalClock checks each column with the matching view: hour options with shouldDisableTime(value, "hours"), minute options with "minutes" and second options with "seconds". Validation uses the same three views, so a rule written for one view disables options in that column and reports the matching key:

Rule in shouldDisableTimeDisables options inMessage key
view === "hours"hours columnshouldDisableTime-hours
view === "minutes"minutes columnshouldDisableTime-minutes
view === "seconds"seconds columnshouldDisableTime-seconds

Validation reports only the first failing check, in the order hours, minutes, seconds, then minutesStep. In the example, a value at 08:07:15 reports the seconds message, not the minutesStep one.

timeSteps and minutesStep are separate. timeSteps is a MultiSectionDigitalClock prop that only controls which options each column lists. minutesStep is a validation prop that the hook returns, so it also disables minute options. The example sets both so the minutes column and validation agree.

Props

Prop

Type

Return value

Prop

Type

On this page