Skip to main content
react-md

Native Time Field

The NativeTimeField can be used as a lightweight wrapper around the TextField utilizing the useTimeField hook.

Simple Example

The NativeTimeField requires a name and an optional label or aria-label for accessibility.

import { NativeTimeField } from "@react-md/core/datetime/NativeTimeField";
import { type ReactElement } from "react";

export default function SimpleExample(): ReactElement {
  return <NativeTimeField label="Appointment" name="appointment" />;
}

Press Enter to start editing.

Getting the Value

Unlike other input elements, the onChange function will only be called once the full time has been typed and will always be in the format of HH:mm (24h time).

The defaultValue can also be provided using the HH:mm format.

The current value is: 15:30

The current value is:

"use client";

import { box } from "@react-md/core/box/styles";
import { NativeTimeField } from "@react-md/core/datetime/NativeTimeField";
import { Form } from "@react-md/core/form/Form";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement, useState } from "react";

export default function GettingTheValueExample(): ReactElement {
  const [value1, setValue1] = useState("15:30");
  const [value2, setValue2] = useState("");
  return (
    <Form
      className={box({ fullWidth: true, disablePadding: true, align: "start" })}
    >
      <Typography margin="none">{`The current value is: ${value1}`}</Typography>
      <NativeTimeField
        label="Time"
        name="time"
        defaultValue="15:30"
        onChange={(event) => {
          setValue1(event.currentTarget.value);
        }}
      />
      <Typography margin="top">{`The current value is: ${value2}`}</Typography>
      <NativeTimeField
        label="Time"
        name="time"
        onChange={(event) => {
          setValue2(event.currentTarget.value);
        }}
      />
    </Form>
  );
}

Press Enter to start editing.

Controlling the Value

Due to how the native <input type="time"> works, the value cannot be controlled since it reduces the user experience. The onChange event fires when the user fully types all the time parts, changes any value afterwards, or removes a time part. Removing a time part would result in the input having a value of "" and wiping out the other fields which is not desired.

Try deleting the minutes portion in the following example to see what happens.

"use client";

import { TextField } from "@react-md/core/form/TextField";
import { type ReactElement, useState } from "react";

export default function ControllingTheValueExample(): ReactElement {
  const [value, setValue] = useState("08:30");
  return (
    <TextField
      label="Time"
      type="time"
      value={value}
      onChange={(event) => setValue(event.currentTarget.value)}
    />
  );
}

Press Enter to start editing.

Validation

The NativeTimeField supports validation through the min, max, step, and required props. The min and max props need to be in the format of HH:mm (24h time) and the step will be shown in the specific time intervals instead.

Min and Max Time

import { Box } from "@react-md/core/box/Box";
import { box } from "@react-md/core/box/styles";
import { Button } from "@react-md/core/button/Button";
import { NativeTimeField } from "@react-md/core/datetime/NativeTimeField";
import { Form } from "@react-md/core/form/Form";
import { type ReactElement } from "react";

export default function MinAndMaxTimeExample(): ReactElement {
  return (
    <Form className={box({ stacked: true, fullWidth: true })}>
      <NativeTimeField
        label="Appointment time"
        min="09:00"
        max="18:00"
        name="appointment"
        required
      />
      <Box align="start" fullWidth disablePadding>
        <Button type="reset" theme="warning" themeType="outline">
          Reset
        </Button>
        <Button type="submit" theme="primary" themeType="contained">
          Confirm
        </Button>
      </Box>
    </Form>
  );
}

Press Enter to start editing.

Specific Time Intervals

For time inputs, the value of step is given in seconds, with a scaling factor of 1000 (since the underlying numeric value is in milliseconds). The default value of step is 60, indicating 60 seconds(or 1 minute, or 60,000 milliseconds).

When any is set as the value for step, the default 60 seconds is used, and the seconds value is not displayed in the UI.

Step attribute

Here are a few examples:

Since this might be a bit confusing, the values can be provided in an object instead:

The min and max props must be provided alongside the step prop for it to work correctly.

import { Box } from "@react-md/core/box/Box";
import { box } from "@react-md/core/box/styles";
import { Button } from "@react-md/core/button/Button";
import { NativeTimeField } from "@react-md/core/datetime/NativeTimeField";
import { Form } from "@react-md/core/form/Form";
import { type ReactElement } from "react";

export default function SpecificTimeIntervalsExample(): ReactElement {
  return (
    <Form className={box({ stacked: true, fullWidth: true })}>
      <NativeTimeField
        label="Time"
        name="time"
        min="08:00"
        max="17:00"
        step={{ minutes: 15 }}
        required
      />
      <Box justify="end" fullWidth disablePadding>
        <Button type="reset" theme="warning" themeType="outline">
          Reset
        </Button>
        <Button type="submit" theme="primary" themeType="contained">
          Submit
        </Button>
      </Box>
    </Form>
  );
}

Press Enter to start editing.

Suggested Times

Suggested times can be provided using the datalist element. For browsers that support this feature, clicking the time picker at the end of the input will show these values.

Firefox does not support the datalist element for date and time inputs at this time.

import { NativeTimeField } from "@react-md/core/datetime/NativeTimeField";
import { type ReactElement, useId } from "react";

export default function SuggestedTimesExample(): ReactElement {
  const datalistId = useId();
  return (
    <>
      <NativeTimeField label="Time" name="time" list={datalistId} />
      <datalist id={datalistId}>
        <option value="09:00" />
        <option value="12:30" />
        <option value="15:00" />
        <option value="18:45" />
      </datalist>
    </>
  );
}

Press Enter to start editing.