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

useMuiXStaticTimePickerAdapter

Returns adapter props for building custom MUI X StaticTimePicker integrations with React Hook Form, including how to show validation errors without a text field.

useMuiXStaticTimePickerAdapter connects a field to React Hook Form and returns props you spread onto MUI X's StaticTimePicker. It's what MuiXStaticTimePickerElement uses internally.

The element renders the picker only, so it never shows an error message. Use the hook when you want the always-visible picker and also want to show validation errors next to it.

Import

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

Usage

This ReportTimeField requires a time no later than 20:00 and shows the error below the picker. Submit without picking a time, or pick 21:00, to see it.

Select time
:
001234567891011121314151617181920212223

Reports go out once a day, no later than 20:00

"use client";import dayjs, { type Dayjs } from "dayjs";import FormHelperText from "@mui/material/FormHelperText";import Stack from "@mui/material/Stack";import { LocalizationProvider, StaticTimePicker } from "@mui/x-date-pickers";import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";import { MuiButtonElement } from "@piplup/rhf-adapters/mui-material";import { useMuiXStaticTimePickerAdapter } from "@piplup/rhf-adapters/mui-x-date-pickers";import { type Control, useForm } from "react-hook-form";type FormValues = { reportTime: Dayjs | null };const lastSend = dayjs().hour(20).minute(0);// A static picker has no text field, so this component renders the// error message itself, below the picker.function ReportTimeField({ control }: { control: Control<FormValues> }) {  const { error, helperText, ...adapter } = useMuiXStaticTimePickerAdapter<    Dayjs,    FormValues,    "reportTime",    HTMLDivElement  >({    control,    name: "reportTime",    required: true,    composeHelperText: true,    maxTime: lastSend,    messages: {      required: "Pick a time for the daily report",      maxTime: "Reports can't be sent after 20:00",    },  });  return (    <div>      <StaticTimePicker ampm={false} {...adapter} />      <FormHelperText error={error}>        {helperText || "Reports go out once a day, no later than 20:00"}      </FormHelperText>    </div>  );}export default function Page() {  const { control, handleSubmit } = useForm<FormValues>({    defaultValues: { reportTime: null },  });  return (    <LocalizationProvider dateAdapter={AdapterDayjs}>      <form        noValidate        onSubmit={handleSubmit((values) => alert(values.reportTime?.format("HH:mm")))}      >        <Stack direction="column" spacing={2}>          <ReportTimeField control={control} />          <div>            <MuiButtonElement control={control} variant="contained" type="submit">              Save schedule            </MuiButtonElement>          </div>        </Stack>      </form>    </LocalizationProvider>  );}

How it works

Validation, the default messages and value handling are the same as useMuiXTimePickerAdapter. The return value is different, because StaticTimePicker has no text field:

  • There is no slotProps, inputRef or onClose in the result, and the hook does not accept them.
  • The result has plain error and helperText values. With composeHelperText: true, helperText is the current error message, or undefined when the field is valid. There is no helperText prop, so put any hint in your own markup, as the example does with helperText || "...".
  • The hook's second argument is merged with React Hook Form's ref and returned as ref.

Take error and helperText out of the result before spreading it, and render them yourself, for example with FormHelperText. The element drops them for the same reason.

A static picker is never closed and has no input to blur, so nothing calls the returned onBlur and the field is never marked as touched. mode: "onBlur" and "onTouched" first validate on submit. Use mode: "onChange" to show errors while the user picks.

When the value changes. By default StaticTimePicker uses displayStaticWrapperAs="mobile": an analog clock with a toolbar. The value reaches the form through onChange each time the user changes the clock, not only when they accept it.

Props

Prop

Type

Return value

Prop

Type

On this page