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" />;
}
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.
"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>
);
}
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)}
/>
);
}
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>
);
}
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.
Here are a few examples:
15
-> 15 seconds60
-> 1 minute900
-> 15 minutes3600
-> 1 hour
Since 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
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>
</>
);
}