The NativeTimeField can be used as a lightweight wrapper around the
TextField utilizing the useTimeField hook.
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" />;
}
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.
"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>
);
}
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)}
/>
);
}
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.
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>
);
}
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.
Here are a few examples:
15 -> 15 seconds60 -> 1 minute900 -> 15 minutes3600 -> 1 hourSince this might be a bit confusing, the values can be provided in an object instead:
step={{ seconds: 30 }}step={{ minutes: 1 }}step={{ minutes: 15 }}step={{ hours: 1 }}step={{ seconds: 15, minutes: 30, hours: 1 }} 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>
);
}
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>
</>
);
}