Time Input
<quiet-time-input>
Collects a time of day through a segmented input and a popup time picker. Submits the time as a 24-hour ISO 8601 time string. Use a time input for appointments, alarms, meeting start times, business hours, and any form field that needs an exact time.
The time input collects a time of day through a segmented input — hour, minute, optional seconds, and optional AM/PM. Users type directly using the keyboard or step segments with the arrow keys.
The segment order and hour cycle are derived from the user's locale by default. US users see
hh:mm AM/PM, most of Europe sees hh:mm on a 24-hour clock, and Japanese users see
the day-period token before the time.
<quiet-time-input label="Reminder time" description="When should we ping you?" name="reminder" ></quiet-time-input>
Examples Jump to heading
Labels and descriptions Jump to heading
Use the label and description attributes to provide plain text labels and
descriptions. If you want to provide HTML, use the label and description slots
instead.
<quiet-time-input label="Appointment time" name="appointment"> <span slot="description"> Times are shown in your local time zone. </span> </quiet-time-input>
Providing an initial value Jump to heading
Use the value attribute to provide an initial value. The value is always a 24-hour ISO 8601
time string (HH:mm, or HH:mm:ss when with-seconds is set).
<quiet-time-input label="Meeting" value="14:30" ></quiet-time-input>
Submitting forms Jump to heading
When the form is submitted, the time input provides a 24-hour ISO 8601 time string under its
name. Without with-seconds, the value is HH:mm; with
with-seconds, it's HH:mm:ss. The format stays 24-hour regardless of the display's
hour-format, i.e. a 12-hour input showing 2:30 PM still submits
14:30.
Submit each form below to see the value in the new tab's query string.
<form action="about:blank" target="_blank"> <quiet-time-input name="meeting" label="Meeting" value="14:30" style="margin-block-end: 1rem;" ></quiet-time-input> <quiet-button type="submit">Submit</quiet-button> </form> <br> <form action="about:blank" target="_blank"> <quiet-time-input name="race-start" label="Race start" with-seconds value="09:30:00" style="margin-block-end: 1rem;" ></quiet-time-input> <quiet-button type="submit">Submit</quiet-button> </form>
Choosing the hour format Jump to heading
Set hour-format to 12 or 24 to force a specific hour cycle. The
default value auto derives the cycle from the user's locale.
<quiet-time-input label="12-hour" hour-format="12" value="07:00"></quiet-time-input> <br> <quiet-time-input label="24-hour" hour-format="24" value="18:45"></quiet-time-input>
Including seconds Jump to heading
Use the with-seconds attribute to render an additional seconds segment. The value format
becomes HH:mm:ss.
<quiet-time-input label="Race start" with-seconds value="09:30:00" ></quiet-time-input>
Setting a minimum and maximum time Jump to heading
Use the min and max attributes to restrict the time range. Both accept 24-hour ISO
time strings. Values outside the range will mark the input as invalid.
<quiet-time-input label="Pickup window" description="Pickups are available between 9 AM and 5 PM." min="09:00" max="17:00" ></quiet-time-input>
Restricting the step Jump to heading
Use the step attribute to constrain the time to fixed intervals, in seconds. For example,
step="900" allows 15-minute increments, and step="3600" allows
only on-the-hour times. The picker shows only step-aligned options, arrow keys move by the corresponding
amount, and off-step typed values are flagged as invalid.
<quiet-time-input label="Appointment time" description="Appointments are scheduled every 15 minutes." step="900" ></quiet-time-input>
Adding a clear button Jump to heading
To add a clear button to the time input, use the with-clear attribute. The clear button appears
once the time input has a value.
<quiet-time-input label="Bedtime" name="bedtime" value="22:00" with-clear ></quiet-time-input>
Start and end content Jump to heading
Use the start and end slots to add presentational icons or text. Avoid interactive
elements such as buttons, links, etc. Works well with
<quiet-icon> and <svg> elements.
<quiet-time-input label="Alarm" name="alarm"> <quiet-icon slot="start" name="alarm"></quiet-icon> </quiet-time-input> <br> <quiet-time-input label="Meeting" name="meeting"> <quiet-icon slot="end" name="users"></quiet-icon> </quiet-time-input>
Localization Jump to heading
The time input's segment order, hour cycle, labels, and error messages are localized using the component's
lang attribute. Import the corresponding translation so the UI strings are available. The
segment order and hour cycle are derived automatically from the locale via Intl.
<quiet-time-input lang="en-US" label="English (US)" value="14:30"></quiet-time-input> <quiet-time-input lang="ja" label="Japanese" value="14:30"></quiet-time-input> <script type="module"> import '/dist/translations/ja.js'; </script>
Changing the appearance Jump to heading
Time inputs support multiple visual styles through the appearance attribute.
<quiet-time-input label="Normal" appearance="normal"></quiet-time-input> <br> <quiet-time-input label="Filled" appearance="filled"></quiet-time-input> <br> <quiet-time-input label="Unstyled" appearance="unstyled"></quiet-time-input>
Pill-shaped time inputs Jump to heading
Time inputs can be rendered with pill-shaped edges by adding the pill attribute.
<quiet-time-input pill label="Pill-shaped"></quiet-time-input>
Changing the size Jump to heading
Use the size attribute to change the time input's size.
<quiet-time-input size="xs" label="Extra small"></quiet-time-input><br> <quiet-time-input size="sm" label="Small"></quiet-time-input><br> <quiet-time-input size="md" label="Medium"></quiet-time-input><br> <quiet-time-input size="lg" label="Large"></quiet-time-input><br> <quiet-time-input size="xl" label="Extra large"></quiet-time-input>
Disabling Jump to heading
Use the disabled attribute to disable the time input.
<quiet-time-input label="Disabled time input" disabled value="12:00" ></quiet-time-input>
Read-only Jump to heading
Use the readonly attribute to make the time input read-only. Users can move between segments
but can't change the value.
<quiet-time-input label="Read-only time input" readonly value="12:00" ></quiet-time-input>
Showing labels on the side Jump to heading
With the
quiet-side-label utility, you can
show labels on the side instead of on top of the time input.
<quiet-time-input class="quiet-side-label" style="--label-width: 10ch;" name="start" label="Start time" description="When does the event begin?" ></quiet-time-input> <br> <quiet-time-input class="quiet-side-label" style="--label-width: 10ch;" name="end" label="End time" description="When does the event end?" ></quiet-time-input>
Required time Jump to heading
Use the required attribute to require a complete time before form submission.
<form action="about:blank" target="_blank"> <quiet-time-input name="time" label="Start time" required style="margin-block-end: 1rem;" ></quiet-time-input> <quiet-button type="submit">Submit</quiet-button> </form>
Validation Jump to heading
The required attribute can be applied to enable validation using the
Constraint Validation
. This will prevent form submission when the time input is missing a value.
<form action="about:blank" target="_blank"> <quiet-time-input name="time" label="Pick a time" required style="margin-block-end: 1rem;" ></quiet-time-input> <quiet-button type="submit">Submit</quiet-button> </form>
Using custom validation Jump to heading
Use the setCustomValidity() method to make the time input invalid and show a custom error
message on submit. This will override all other validation parameters. To clear the error, set it to an
empty string.
<form action="about:blank" method="get" target="_blank" id="time-input__custom"> <quiet-time-input name="time" label="Pick a time" description="This field will be invalid until custom validation is removed" ></quiet-time-input> <br> <quiet-button type="submit" variant="primary">Submit</quiet-button> </form> <script type="module"> import { allDefined } from '/dist/quiet.js'; await allDefined(); const form = document.getElementById('time-input__custom'); const timeInput = form.querySelector('quiet-time-input'); timeInput.setCustomValidity('Please pick a different time!'); </script>
Styling validation Jump to heading
You can style valid and invalid time inputs using the :valid and :invalid pseudo
classes. More often than not, you'll want to use the user-valid and user-invalid
custom states instead so validation styles are only shown after the user has
interacted with the field.
<form action="about:blank" method="get" target="_blank" class="time-input__validation-custom"> <quiet-time-input name="time" label="Pick a time" description="This field is required" required ></quiet-time-input> <br> <quiet-button type="submit" variant="primary">Submit</quiet-button> <quiet-button type="reset">Reset</quiet-button> </form> <style> .time-input__validation-custom { quiet-time-input:state(user-valid) { outline: solid 2px var(--quiet-constructive-stroke-mid); outline-offset: .5rem; } quiet-time-input:state(user-invalid) { outline: solid 2px var(--quiet-destructive-stroke-mid); outline-offset: .5rem; } } </style>
API Jump to heading
Importing Jump to heading
The autoloader is the recommended way to import components but, if you prefer to do it manually, the following code snippets will be helpful.
To manually import <quiet-time-input> from the CDN, use the following code.
import 'https://cdn.quietui.org/v5.2.0/components/time-input/time-input.js';
To manually import <quiet-time-input> from a self-hosted distribution, use the
following code. Remember to replace /path/to/quiet with the appropriate local path.
import '/path/to/quiet/components/time-input/time-input.js';
Slots Jump to heading
Time Input supports the following slots. Learn more about using slots
| Name | Description |
|---|---|
label
|
The time input's label. For plain-text labels, you can use the label attribute instead.
|
description
|
The time input's description. For plain-text descriptions, you can use the
description attribute instead.
|
start
|
An icon or similar element to place before the segments. Works great with
<quiet-icon>.
|
end
|
An icon or similar element to place after the segments. Works great with
<quiet-icon>.
|
Properties Jump to heading
Time Input has the following properties that can be set with corresponding attributes. In many cases, the attribute's name is the same as the property's name. If an attribute is different, it will be displayed after the property. Learn more about attributes and properties
| Property | Description | Reflects | Type | Default |
|---|---|---|---|---|
label
|
The time input's label. If you need to provide HTML in the label, use the label slot
instead.
|
|
string
|
|
description
|
The time input's description. If you need to provide HTML in the description, use the
description slot.
|
|
string
|
|
name
|
The name of the time input. This will be submitted with the form as a name/value pair. |
|
string
|
|
value
|
The time input's value as a 24-hour ISO 8601 time string. HH:mm by default, or
HH:mm:ss when with-seconds is set. Empty when the value isn't complete.
|
|
string
|
''
|
disabled
|
Disables the time input. |
|
boolean
|
false
|
readonly
|
Makes the time input a read-only field. |
|
boolean
|
false
|
withClear
with-clear
|
Adds a clear button to the time input when it's not blank. |
|
boolean
|
false
|
withSeconds
with-seconds
|
Renders a seconds segment in addition to the hour and minute segments. |
|
boolean
|
false
|
hourFormat
hour-format
|
Selects the hour cycle. auto uses the user's locale (12- or 24-hour).
12 forces a 12-hour cycle with an AM/PM segment; 24 forces a 24-hour cycle
with no AM/PM segment.
|
|
'auto' |
'12' |
'24'
|
'auto'
|
appearance
|
The type of time input to render. |
|
'normal' |
'filled' |
'unstyled'
|
'normal'
|
size
|
The time input's size. |
|
'xs' |
'sm' |
'md' |
'lg' |
'xl'
|
'md'
|
pill
|
Draws the time input in a pill shape. |
|
boolean
|
false
|
min
|
The earliest selectable time as a 24-hour ISO string (HH:mm or HH:mm:ss).
|
|
string
|
|
max
|
The latest selectable time as a 24-hour ISO string (HH:mm or HH:mm:ss).
|
|
string
|
|
step
|
Restricts time values to multiples of this step, in seconds, counted from min (or
midnight when min is not set). For example, step="900" allows
15-minute intervals; step="3600" allows hour-only times. The picker shows
only step-aligned options, arrow keys step by the corresponding increment, and off-step values are
flagged with stepMismatch on validation.
|
|
number
|
60
|
placement
|
The placement of the time picker popover in reference to the time input. The popover will shift to a more optimal location if the preferred placement doesn't have enough room. |
|
'top' |
'top-start' |
'top-end' |
'bottom' |
'bottom-start' |
'bottom-end' |
'right' |
'right-start' |
'right-end' |
'left' |
'left-start' |
'left-end'
|
'bottom-start'
|
distance
|
The distance of the popover from its trigger. |
|
number
|
0
|
offset
|
The offset of the popover along its trigger. |
|
number
|
0
|
form
|
The form to associate this control with. If omitted, the closest containing
<form> will be used. The value of this attribute must be an ID of a form in the
same document or shadow root.
|
|
string
|
|
required
|
Makes the time input required. Form submission will not be allowed when the time input is blank. |
|
boolean
|
false
|
autofocus
|
Tells the browser to focus the time input when the page loads or a dialog is shown. |
|
boolean
|
|
autocomplete
|
Hints at the type of autocomplete information the browser should provide. |
|
string
|
|
hour
|
The hour component of the current value (0-23), or null if not set. |
|
number |
null
|
|
minute
|
The minute component of the current value (0-59), or null if not set. |
|
number |
null
|
|
second
|
The second component of the current value (0-59), or null if not set. |
|
number |
null
|
Methods Jump to heading
Time Input supports the following methods. You can obtain a reference to the element and call them like functions in JavaScript. Learn more about methods
| Name | Description | Arguments |
|---|---|---|
getSegmentOrder() |
Returns the visual order of segments derived from the user's locale. | |
getSegmentMaxLength() |
Returns the max digit length for a segment. |
_seg: SegmentName
|
getSegmentBounds() |
Returns the bounds for a numeric segment in the active hour cycle. Returns null for dayPeriod. |
seg: SegmentName
|
setSegmentBuffer() |
Updates a single segment's buffer and recomposes the value when possible. Returns true when the
segment's buffer actually changed, so callers can decide whether to dispatch an
input event for the user's edit — even when the partially-typed value doesn't yet
compose to a full ISO time.
|
seg: SegmentName, raw: string
|
getSegmentElement() |
Returns the segment element for a given segment, or null if not yet rendered. |
seg: SegmentName
|
getSegmentBuffer() |
Returns the current text buffer for a segment. |
seg: SegmentName
|
areSegmentsEqual() |
True when two segment identities refer to the same segment. |
a: SegmentName, b: SegmentName
|
classifyDigit() |
Classifies what a digit keypress should do, given the segment's current state. |
seg: SegmentName, digit: string
|
stepSegment() |
Steps a segment by delta. Numeric segments wrap on bounds; dayPeriod toggles AM/PM.
|
seg: SegmentName, delta: number
|
getPageStepDelta() |
Returns the PageUp/PageDown delta for the given segment. |
seg: SegmentName, direction:
1 |
-1
|
getSeparatorKeys() |
Returns the keys that should advance focus to the next segment when the current buffer is non-empty. | |
tryPasteValue() |
Attempts to parse a pasted string as a whole time value and populate every segment. |
text: string
|
handleSegmentFocus() |
Override to dispatch QuietFocusEvent after the mixin tracks focus state. |
seg: SegmentName, event: FocusEvent
|
handleSegmentBlur() |
Override to dispatch QuietBlurEvent after the mixin tracks blur state. |
seg: SegmentName, event: FocusEvent
|
handleSegmentShortcut() |
Host-specific shortcut keys: Alt+ArrowDown opens picker, Escape/Enter close it, 'a'/'p' toggle AM/PM. |
seg: SegmentName, event:
KeyboardEvent
|
blur() |
Removes focus from the time input. | |
focus() |
Sets focus to the time input's first segment. | |
showPicker() |
Shows the time picker. | |
hidePicker() |
Hides the time picker. | |
checkValidity() |
Checks if the form control has any restraints and whether it satisfies them. If invalid,
false will be returned and the invalid event will be dispatched. If valid,
true will be returned.
|
|
reportValidity() |
Checks if the form control has any restraints and whether it satisfies them. If invalid,
false will be returned and the invalid event will be dispatched. In
addition, the problem will be reported to the user. If valid, true will be returned.
|
|
setCustomValidity()
|
Sets a custom validation message for the form control. If this message is not an empty string, then the form control is considered invalid and the specified message will be displayed to the user when reporting validity. Setting an empty string clears the custom validity state. | message: string |
Events Jump to heading
Time Input dispatches the following custom events. You can listen to them the same way was native events. Learn more about custom events
| Name | Description |
|---|---|
quiet-blur |
Emitted when the time input loses focus. This event does not bubble. |
quiet-change |
Emitted when the user commits changes to the time input's value. |
quiet-focus |
Emitted when the time input receives focus. This event does not bubble. |
quiet-input |
Emitted when the time input's value changes. |
CSS custom properties Jump to heading
Time Input supports the following CSS custom properties. You can style them like any other CSS property. Learn more about CSS custom properties
| Name | Description | Default |
|---|---|---|
--show-duration |
The duration of the show/hide animation. |
50ms
|
--column-width |
The width of each picker column. |
3em
|
--picker-height |
The visible height of each picker column. |
11em
|
CSS parts Jump to heading
Time Input exposes internal elements that can be styled with CSS using the selectors shown below. Learn more about CSS parts
| Name | Description | CSS selector |
|---|---|---|
label |
The element that contains the time input's label. |
::part(label)
|
description |
The element that contains the time input's description. |
::part(description)
|
visual-box |
The element that wraps the internal segments and trailing buttons. |
::part(visual-box)
|
segments |
The container that wraps all of the time segments. |
::part(segments)
|
segment |
An individual time segment. Use the data-segment attribute to target a specific one
(e.g. [data-segment="hour"]).
|
::part(segment)
|
separator |
A separator rendered between numeric segments (e.g. :).
|
::part(separator)
|
clear-button |
The clear button (shown when with-clear is set and the input isn't blank).
|
::part(clear-button)
|
trigger |
The trigger button that toggles the popover. |
::part(trigger)
|
trigger-icon |
The icon inside the trigger button. |
::part(trigger-icon)
|
picker |
The popover that holds the scrollable hour/minute/second/AM-PM columns. |
::part(picker)
|
column |
A single scrollable column in the picker. Use data-segment to target a specific one.
|
::part(column)
|
option |
An individual option within a column. |
::part(option)
|
Custom States Jump to heading
Time Input has the following custom states. You can target them with CSS using the selectors shown below. Learn more about custom states
| Name | Description | CSS selector |
|---|---|---|
disabled |
Applied when the time input is disabled. |
:state(disabled)
|
blank |
Applied when the time input has a blank value. |
:state(blank)
|
focused |
Applied when any segment has focus. |
:state(focused)
|
open |
Applied when the picker is open. |
:state(open)
|
user-valid |
Applied when the time input is valid and the user has sufficiently interacted with it. |
:state(user-valid)
|
user-invalid |
Applied when the time input is invalid and the user has sufficiently interacted with it. |
:state(user-invalid)
|
Dependencies Jump to heading
Time Input automatically imports the following elements. Sub-dependencies are also included in this list.