Range Time Input
Range Time Input widgets are Input Fields that allow the user to enter one or more time-of-day ranges using segmented keyboard inputs (hh:mm), with no dropdown. Each completed range is displayed as a pill that can be removed. Whether the widget renders in 12-hour or 24-hour mode follows the user’s locale, and in 12-hour mode an AM/PM segment is rendered at the locale’s position.
The widget emits an array of { start, end } objects, each holding an ISO time string (HH:mm:ss). The end time of every range must be strictly after its start time. To enter a single time, use the Time Input; for whole-day ranges, use the Range Date Input.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.rangeTimeInput('timeRanges', { label: 'Time Ranges', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "rangeTimeInput", "path": "timeRanges", "label": "Time Ranges" } ]}Use these props to customize your Range Time Input widget.
| prop | type | description |
|---|---|---|
endTimeAriaLabel | string | Aria label for the end time field group. Defaults to End time |
hint | string | A description to display below the input |
hourFormat | '12' | '24' | Force 12- or 24-hour entry. Defaults to the user’s locale |
icon | string | A css class to display an icon inside the input |
maxTime | string | Latest allowed time (ISO time, inclusive) |
maxTimeMessage | string | Localizable | Error shown when a typed time is after maxTime |
minTime | string | Earliest allowed time (ISO time, inclusive) |
minTimeMessage | string | Localizable | Error shown when a typed time is before minTime |
minuteStep | number | Granularity of the minute segment |
rangeOrderMessage | string | Localizable | Error shown when the end time is not strictly after the start time |
removePillAriaLabel | string | Aria label for the remove pill action. Defaults to Remove time |
separator | string | The separator between start and end time fields. Defaults to - |
startTimeAriaLabel | string | Aria label for the start time field group. Defaults to Start time |
Use the property hint to add a description or validation instructions.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.rangeTimeInput('timeRanges', { hint: 'Enter one or more time ranges', label: 'Time Ranges', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "rangeTimeInput", "path": "timeRanges", "label": "Time Ranges", "props": { "hint": "Enter one or more time ranges" } } ]}Use the property icon to add an icon to the widget. The value of icon represents a set of CSS classes separated by spaces. The icon is displayed inside the input border.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.rangeTimeInput('timeRanges', { icon: 'schedule', label: 'Time Ranges', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "rangeTimeInput", "path": "timeRanges", "label": "Time Ranges", "props": { "icon": "schedule" } } ]}Separator
Section titled “Separator”Use the property separator to customize the text displayed between the start time and end time fields. By default the separator is -.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.rangeTimeInput('timeRanges', { separator: 'to', label: 'Time Ranges', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "rangeTimeInput", "path": "timeRanges", "label": "Time Ranges", "props": { "separator": "to" } } ]}Hour Format
Section titled “Hour Format”By default the 12-hour/24-hour layout comes from the locale’s hour cycle. Use the property hourFormat ('12' or '24') to force one of them.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.rangeTimeInput('timeRanges', { hourFormat: '24', label: 'Time Ranges', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "rangeTimeInput", "path": "timeRanges", "label": "Time Ranges", "props": { "hourFormat": "24" } } ]}Minute Step
Section titled “Minute Step”Use the property minuteStep to control the ArrowUp/ArrowDown increment of the minute segment, useful for appointment-style forms where times snap to a grid (e.g. every 15 minutes). Typing a value is not restricted by the step. The default is 1.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.rangeTimeInput('timeRanges', { minuteStep: 15, label: 'Time Ranges', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "rangeTimeInput", "path": "timeRanges", "label": "Time Ranges", "props": { "minuteStep": 15 } } ]}Min and Max Times
Section titled “Min and Max Times”Use the properties minTime and maxTime (ISO times, both inclusive) to specify the boundaries for accepted times. A completed time outside the boundaries raises an input error instead of a value; customize (and localize) the messages with minTimeMessage and maxTimeMessage. The end time of each range must be strictly after its start time, otherwise the rangeOrderMessage error is shown.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.rangeTimeInput('timeRanges', { hint: 'Office hours are 9:00 to 18:00', minTime: '09:00:00', maxTime: '18:00:00', minuteStep: 15, minTimeMessage: 'Office not open until 9:00', maxTimeMessage: 'Office closed from 18:00', rangeOrderMessage: 'End time must be after the start time', label: 'Time Ranges', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "rangeTimeInput", "path": "timeRanges", "label": "Time Ranges", "props": { "hint": "Office hours are 9:00 to 18:00", "minTime": "09:00:00", "maxTime": "18:00:00", "minuteStep": 15, "minTimeMessage": "Office not open until 9:00", "maxTimeMessage": "Office closed from 18:00", "rangeOrderMessage": "End time must be after the start time" } } ]}Aria Labels
Section titled “Aria Labels”Use the properties removePillAriaLabel, startTimeAriaLabel and endTimeAriaLabel to customize the accessibility labels for screen readers. These properties are localizable.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.rangeTimeInput('timeRanges', { removePillAriaLabel: 'Delete range', startTimeAriaLabel: 'From time', endTimeAriaLabel: 'To time', label: 'Time Ranges', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "rangeTimeInput", "path": "timeRanges", "label": "Time Ranges", "props": { "removePillAriaLabel": "Delete range", "startTimeAriaLabel": "From time", "endTimeAriaLabel": "To time" } } ]}Styling
Section titled “Styling”Range Time Inputs can be styled as explained in the Styling Guide.
CSS Variables
Section titled “CSS Variables”Following you will find a list with the CSS Variables and a quick description of what you will style.
| CSS Variable | Description |
|---|---|
--gui-intent-error | Border and focus shadow color when invalid |
--gui-border-focus | Border color when a pill or time segment is focused |
--gui-shadow-focus | Box shadow when a pill or time segment is focused |
--gui-intent-primary | Pill background color |
--gui-color-white | Pill text and remove button color |
--gui-border-default | Pills wrapper border and separator border color |
--gui-bg-default | Scroll shadow gradient color and dropdown background color |
--gui-text-default | Active piece (hour/minute) visual underline color |
--gui-radius-md | Pill and dropdown border radius |
--gui-radius-full | Pill count button and remove button border radius |
Anatomy
Section titled “Anatomy”This is the anatomy of the Range Time Input Widget in case you want to use your CSS styles.
<gui-range-time> <label for="fieldUid"> Label <div class="gui-widget-hint" id="fieldUid_hint">Hint</div> </label>
<div class="gui-widget"> <div class="gui-widget-input gui-parts-ring gui-range-time-input gui-range-time-input--icon" role="group" aria-label="Time range input"> <span class="gui-widget-icon schedule" data-icon="schedule"></span>
<!-- Completed ranges render as removable pills via the shared gui-pills element --> <gui-pills class="gui-range-time-input__pills" role="list"> <div class="gui-pills__pill" role="listitem" tabindex="0"> <span class="gui-pills__pill-text">9:00 AM - 11:00 AM</span> <button type="button" class="gui-pills__pill-remove" tabindex="-1" aria-label="Remove time">×</button> </div> <div class="gui-pills__pill" role="listitem" tabindex="0"> <span class="gui-pills__pill-text">2:00 PM - 2:30 PM</span> <button type="button" class="gui-pills__pill-remove" tabindex="-1" aria-label="Remove time">×</button> </div> <!-- Collapsed into a count button when the pills overflow --> <button type="button" class="gui-pills__pill gui-pills__pill--count">2</button> </gui-pills>
<div class="gui-range-time-input__inputs"> <div class="gui-parts gui-range-time-input__field" role="group" aria-label="Start time"> <div class="gui-parts__touch-target gui-range-time-input__touch-target"> <input type="text" inputmode="numeric" class="gui-parts__part gui-range-time-input__part" data-type="hour" data-group="start" maxlength="2" placeholder="hh" tabindex="0"> <div class="gui-parts__visual-underline gui-range-time-input__visual-underline"></div> </div> <span class="gui-range-time-input__separator">:</span> <div class="gui-parts__touch-target gui-range-time-input__touch-target"> <input type="text" inputmode="numeric" class="gui-parts__part gui-range-time-input__part" data-type="minute" data-group="start" maxlength="2" placeholder="mm" tabindex="-1"> <div class="gui-parts__visual-underline gui-range-time-input__visual-underline"></div> </div> <!-- Only rendered in 12-hour mode, at the locale's position --> <div class="gui-parts__touch-target gui-range-time-input__touch-target"> <button type="button" class="gui-parts__part gui-parts__dayperiod gui-range-time-input__part gui-range-time-input__dayperiod" data-type="dayPeriod" data-group="start" tabindex="-1" aria-label="AM/PM">AM</button> <div class="gui-parts__visual-underline gui-range-time-input__visual-underline"></div> </div> </div>
<span class="gui-range-time-input__separator">-</span>
<div class="gui-parts gui-range-time-input__field" role="group" aria-label="End time"> <div class="gui-parts__touch-target gui-range-time-input__touch-target"> <input type="text" inputmode="numeric" class="gui-parts__part gui-range-time-input__part" data-type="hour" data-group="end" maxlength="2" placeholder="hh" tabindex="-1"> <div class="gui-parts__visual-underline gui-range-time-input__visual-underline"></div> </div> <span class="gui-range-time-input__separator">:</span> <div class="gui-parts__touch-target gui-range-time-input__touch-target"> <input type="text" inputmode="numeric" class="gui-parts__part gui-range-time-input__part" data-type="minute" data-group="end" maxlength="2" placeholder="mm" tabindex="-1"> <div class="gui-parts__visual-underline gui-range-time-input__visual-underline"></div> </div> <div class="gui-parts__touch-target gui-range-time-input__touch-target"> <button type="button" class="gui-parts__part gui-parts__dayperiod gui-range-time-input__part gui-range-time-input__dayperiod" data-type="dayPeriod" data-group="end" tabindex="-1" aria-label="AM/PM">AM</button> <div class="gui-parts__visual-underline gui-range-time-input__visual-underline"></div> </div> </div> </div> </div> </div></gui-range-time>