Create React time fields with a section-based input mask. Users type the hour, minutes, and seconds in separate sections with automatic navigation and validation — like the native time input, but with full control over the format.
Available in Other JavaScript Frameworks
CoreUI React Time Input Component is also available for Bootstrap and Vue. Explore framework-specific implementations below:
Example
Added in v5.27.0The React Time Input component renders a masked time field. The mask is split into hour, minute, and — depending on the locale — AM/PM sections. Click or focus a section and type, use arrow keys to adjust values, and the caret moves to the next section automatically.
import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputExample = () => {
return (
<CRow>
<CCol className="mb-4 mb-sm-0" sm={6} lg={5}>
<CTimeInput label="Meeting time" locale="en-US" />
</CCol>
<CCol sm={6} lg={5}>
<CTimeInput label="Meeting time" locale="en-US" defaultTime="14:30" />
</CCol>
</CRow>
)
}import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputExample = () => {
return (
<CRow>
<CCol className="mb-4 mb-sm-0" sm={6} lg={5}>
<CTimeInput label="Meeting time" locale="en-US" />
</CCol>
<CCol sm={6} lg={5}>
<CTimeInput label="Meeting time" locale="en-US" defaultTime="14:30" />
</CCol>
</CRow>
)
}With form field
Wrap the control in <CFormField> to lay it out with its label and description, and to get validation feedback in the right place.
import React from 'react'
import { CFormField, CFormText } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputFormFieldExample = () => {
return (
<CFormField>
<span className="form-label">Meeting time</span>
<CTimeInput locale="en-US" name="meetingTime" />
<CFormText>Local time, in your own time zone.</CFormText>
</CFormField>
)
}import React from 'react'
import { CFormField, CFormText } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputFormFieldExample = () => {
return (
<CFormField>
<span className="form-label">Meeting time</span>
<CTimeInput locale="en-US" name="meetingTime" />
<CFormText>Local time, in your own time zone.</CFormText>
</CFormField>
)
}Formats
Set an explicit format with the format property: HH/H for the 23-hour cycle, hh/h for the 12-hour cycle, mm for minutes, ss for seconds, and A/a for the day period. Type a or p in the AM/PM section to switch it, or use the arrow keys.
import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputFormatsExample = () => {
return (
<CRow>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput format="HH:mm" label="HH:mm" />
</CCol>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput format="HH:mm:ss" label="HH:mm:ss" />
</CCol>
<CCol lg={4}>
<CTimeInput format="hh:mm A" label="hh:mm A" locale="en-US" />
</CCol>
</CRow>
)
}import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputFormatsExample = () => {
return (
<CRow>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput format="HH:mm" label="HH:mm" />
</CCol>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput format="HH:mm:ss" label="HH:mm:ss" />
</CCol>
<CCol lg={4}>
<CTimeInput format="hh:mm A" label="hh:mm A" locale="en-US" />
</CCol>
</CRow>
)
}Locale
Without an explicit format, the hour cycle and layout follow the locale set via the locale property — en-US gets a 12-hour clock with an AM/PM section, pl-PL or de-DE a 24-hour one.
import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputLocalesExample = () => {
return (
<CRow>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput label="en-US" locale="en-US" />
</CCol>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput label="pl-PL" locale="pl-PL" />
</CCol>
<CCol lg={4}>
<CTimeInput label="de-DE" locale="de-DE" />
</CCol>
</CRow>
)
}import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputLocalesExample = () => {
return (
<CRow>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput label="en-US" locale="en-US" />
</CCol>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput label="pl-PL" locale="pl-PL" />
</CCol>
<CCol lg={4}>
<CTimeInput label="de-DE" locale="de-DE" />
</CCol>
</CRow>
)
}Seconds
Without an explicit format, enable the seconds section with the seconds property.
import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputSecondsExample = () => {
return (
<CRow>
<CCol lg={5}>
<CTimeInput label="Time with seconds" seconds />
</CCol>
</CRow>
)
}import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputSecondsExample = () => {
return (
<CRow>
<CCol lg={5}>
<CTimeInput label="Time with seconds" seconds />
</CCol>
</CRow>
)
}Min and max times
Constrain the selectable range with minDate and maxDate — time strings work here too. A completed time outside the range gets the .is-invalid class and the component reports null, and submits no time, until the value is corrected.
import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputMinMaxExample = () => {
return (
<CRow>
<CCol lg={5}>
<CTimeInput
format="HH:mm"
label="Business hours (09:00–17:00)"
maxDate="17:00"
minDate="09:00"
defaultTime="09:30"
/>
</CCol>
</CRow>
)
}import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputMinMaxExample = () => {
return (
<CRow>
<CCol lg={5}>
<CTimeInput
format="HH:mm"
label="Business hours (09:00–17:00)"
maxDate="17:00"
minDate="09:00"
defaultTime="09:30"
/>
</CCol>
</CRow>
)
}Validation
The field takes its validation state the same way as the date input: a completed time outside minDate/maxDate makes it invalid whatever else is set, then validationState, then a validation that reported the field, and in a form with the validate property of <CForm> the :user-invalid state of its value field, with validate="valid" also its :user-valid state. A given state is a verdict on the time it was given for: when the user changes the time, or the form is reset, the component calls onValidationStateChange(undefined), while a change your code makes through time asks nothing. A given 'invalid' blocks the submit with the text of the linked message, or Invalid value. when there is none. The feedbackValid/feedbackInvalid texts render like for any other form control, and while the field is invalid the error, its own or one you render after the field, describes every section.
import React, { useState } from 'react'
import { CButton, CCol, CForm, CTimeInput } from '@coreui/react-pro'
export const TimeInputValidationExample = () => {
const [roomState, setRoomState] = useState<string | undefined>('invalid')
return (
<CForm className="row g-4" noValidate validate>
<CCol sm={6} lg={5}>
<CTimeInput
feedbackInvalid="Please provide a meeting time."
format="HH:mm"
label="Meeting time (required)"
name="meeting"
required
/>
</CCol>
<CCol sm={6} lg={5}>
<CTimeInput
defaultTime="12:30"
feedback="The room is taken at this time."
format="HH:mm"
label="Room booking"
name="room"
onValidationStateChange={setRoomState}
validationState={roomState}
/>
</CCol>
<CCol xs={12}>
<CButton color="primary" type="submit">
Submit
</CButton>
</CCol>
</CForm>
)
}import React, { useState } from 'react'
import { CButton, CCol, CForm, CTimeInput } from '@coreui/react-pro'
export const TimeInputValidationExample = () => {
const [roomState, setRoomState] = useState<string | undefined>('invalid')
return (
<CForm className="row g-4" noValidate validate>
<CCol sm={6} lg={5}>
<CTimeInput
feedbackInvalid="Please provide a meeting time."
format="HH:mm"
label="Meeting time (required)"
name="meeting"
required
/>
</CCol>
<CCol sm={6} lg={5}>
<CTimeInput
defaultTime="12:30"
feedback="The room is taken at this time."
format="HH:mm"
label="Room booking"
name="room"
onValidationStateChange={setRoomState}
validationState={roomState}
/>
</CCol>
<CCol xs={12}>
<CButton color="primary" type="submit">
Submit
</CButton>
</CCol>
</CForm>
)
}Floating labels
Use the floatingLabel property. When the field is empty and not focused, the mask placeholders are hidden so the label can rest inside the field; focusing the field floats the label and reveals the mask.
import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputFloatingLabelsExample = () => {
return (
<CRow>
<CCol lg={5}>
<CTimeInput floatingLabel="Meeting time" format="HH:mm" id="floatingTimeInput" />
</CCol>
</CRow>
)
}import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputFloatingLabelsExample = () => {
return (
<CRow>
<CCol lg={5}>
<CTimeInput floatingLabel="Meeting time" format="HH:mm" id="floatingTimeInput" />
</CCol>
</CRow>
)
}Set floatingLabelAlways to keep the label always floating with the mask showing.
Sizing
The field renders as a .form-control, so the standard sizing works — set the size property to lg or sm.
import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputSizingExample = () => {
return (
<CRow>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput format="HH:mm" label="Large" size="lg" />
</CCol>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput format="HH:mm" label="Default" />
</CCol>
<CCol lg={4}>
<CTimeInput format="HH:mm" label="Small" size="sm" />
</CCol>
</CRow>
)
}import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputSizingExample = () => {
return (
<CRow>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput format="HH:mm" label="Large" size="lg" />
</CCol>
<CCol className="mb-4 mb-lg-0" lg={4}>
<CTimeInput format="HH:mm" label="Default" />
</CCol>
<CCol lg={4}>
<CTimeInput format="HH:mm" label="Small" size="sm" />
</CCol>
</CRow>
)
}Disabled and readonly
Set the disabled property to disable the field, or readOnly to make it focusable but non-editable.
import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputDisabledReadonlyExample = () => {
return (
<CRow>
<CCol className="mb-4 mb-sm-0" sm={6} lg={5}>
<CTimeInput disabled format="HH:mm" label="Disabled" defaultTime="14:30" />
</CCol>
<CCol sm={6} lg={5}>
<CTimeInput format="HH:mm" label="Readonly" readOnly defaultTime="14:30" />
</CCol>
</CRow>
)
}import React from 'react'
import { CCol, CRow } from '@coreui/react'
import { CTimeInput } from '@coreui/react-pro'
export const TimeInputDisabledReadonlyExample = () => {
return (
<CRow>
<CCol className="mb-4 mb-sm-0" sm={6} lg={5}>
<CTimeInput disabled format="HH:mm" label="Disabled" defaultTime="14:30" />
</CCol>
<CCol sm={6} lg={5}>
<CTimeInput format="HH:mm" label="Readonly" readOnly defaultTime="14:30" />
</CCol>
</CRow>
)
}Value semantics
The component reports a Date object anchored to 1970-01-01 — the same convention as the CoreUI time picker — so only the time part is meaningful. minDate/maxDate therefore constrain the time of day. A native reset of the form puts back the time the field started with and calls onTimeChange when that changes it; with time set it only asks for the first time through onTimeChange.
Accessibility
The time input shares the accessibility model of the date input: role="group" on the container, named by label, a role="spinbutton" with full ARIA value attributes per section, a single tab stop with roving focus, and inputmode hints for mobile keyboards. Clicking the label that names the field moves focus to the first empty section. The AM/PM section announces its localized name via aria-valuetext and can be toggled with the A/P letters or arrow keys.
The keyboard support table applies unchanged, including Ctrl + A (select all), Ctrl + C (copy), and paste.
