Time Picker
Time Picker widgets are Input Fields that let the user pick a time from a drop-down list of slots. The slots are generated from minTime to maxTime (inclusive) stepping minuteStep minutes, with their labels localized to the user’s 12-hour or 24-hour convention. By default the field is read-only and values come only from the list; set allowCustomTime to also let the user type a time. The list closes with the Esc key.
The widget emits an ISO time string (HH:mm:ss) on change — pair it with the { format: 'time' } validator.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.timePicker('meetingTime', { label: 'Meeting Time', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "timePicker", "path": "meetingTime", "label": "Meeting Time" } ]}Use these props to customize your Time Picker widget.
| prop | type | description |
|---|---|---|
allowCustomTime | boolean | Allows typing a time in the input; when false (default) values come only from the list |
disabledRangeMessage | string | Localizable | Error message shown when a typed time falls inside a disabled range |
disabledRanges | array | { start, end } ISO time ranges (both ends inclusive) whose slots render disabled |
height | number | Total height of the drop-down list viewport. Defaults to 300 |
hint | string | A description to display below the input |
hourFormat | '12' | '24' | Forces 12-hour or 24-hour slot labels and typing mode; when omitted the locale decides |
icon | string | A css class to display an icon inside the input |
itemHeight | number | Fixed height of each slot row. Defaults to 40 |
maxTime | string | Last selectable slot (ISO time, inclusive). Defaults to 23:59:59 |
maxTimeMessage | string | Localizable | Error message shown when a typed time is after maxTime |
minTime | string | First selectable slot (ISO time, inclusive). Defaults to 00:00:00 |
minTimeMessage | string | Localizable | Error message shown when a typed time is before minTime |
minuteStep | number | Minutes between generated slots, also the arrow-key minute increment when typing. Defaults to 30 |
noAvailableTimesMessage | string | Localizable | Shown in the list when the bounds yield no slots. Defaults to No available times |
Use the property hint to add a description or validation instructions.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.timePicker('meetingTime', { hint: 'Please pick the meeting start time', label: 'Meeting Time', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "timePicker", "path": "meetingTime", "label": "Meeting Time", "props": { "hint": "Please pick the meeting start time" } } ]}Use the property icon to add an icon, which appears next to the toggle chevron. The value of icon represents a set of CSS classes separated by spaces.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.timePicker('meetingTime', { icon: 'schedule', label: 'Meeting Time', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "timePicker", "path": "meetingTime", "label": "Meeting Time", "props": { "icon": "schedule" } } ]}Hour Format
Section titled “Hour Format”By default the 12-hour/24-hour convention comes from the locale’s hour cycle and drives both the slot labels (e.g. 9:30 AM vs 09:30) and the typing mode. Use the property hourFormat ('12' or '24') to force one of them.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.timePicker('meetingTime12', { hourFormat: '12', label: 'Meeting Time (12h)', }), gui.inputs.timePicker('meetingTime24', { hourFormat: '24', label: 'Meeting Time (24h)', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "timePicker", "path": "meetingTime12", "label": "Meeting Time (12h)", "props": { "hourFormat": "12" } }, { "kind": "input", "type": "timePicker", "path": "meetingTime24", "label": "Meeting Time (24h)", "props": { "hourFormat": "24" } } ]}Time Slots
Section titled “Time Slots”Use minTime, maxTime and minuteStep to control which slots are generated, and disabledRanges to grey out slots inside { start, end } ranges (both ends inclusive). Disabled slots are skipped by keyboard navigation and cannot be selected.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.timePicker('meetingTime', { hint: '30m slots from 9:00 to 18:00, lunch break disabled', minTime: '09:00:00', maxTime: '18:00:00', minuteStep: 30, disabledRanges: [ { start: '13:00:00', end: '14:00:00', }, ], label: 'Pick a time slot', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "timePicker", "path": "meetingTime", "label": "Pick a time slot", "props": { "hint": "30m slots from 9:00 to 18:00, lunch break disabled", "minTime": "09:00:00", "maxTime": "18:00:00", "minuteStep": 30, "disabledRanges": [ { "start": "13:00:00", "end": "14:00:00" } ] } } ]}List Size
Section titled “List Size”Use height to set the drop-down list viewport height (default 300) and itemHeight to set the height of each slot row (default 40). Both are in pixels; the list scrolls when the slots exceed the viewport.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.timePicker('meetingTime', { hint: 'A shorter 200px viewport with taller 56px rows', minTime: '09:00:00', maxTime: '18:00:00', minuteStep: 30, height: 200, itemHeight: 56, label: 'Meeting Time', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "timePicker", "path": "meetingTime", "label": "Meeting Time", "props": { "hint": "A shorter 200px viewport with taller 56px rows", "minTime": "09:00:00", "maxTime": "18:00:00", "minuteStep": 30, "height": 200, "itemHeight": 56 } } ]}Custom Time
Section titled “Custom Time”Use the property allowCustomTime to let the user type any time directly in the input, in addition to picking a slot. Typed times are still validated against minTime, maxTime and disabledRanges: a violation raises an input error whose message you can customize (and localize) with minTimeMessage, maxTimeMessage and disabledRangeMessage.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.timePicker('meetingTime', { hint: 'Type any time between 9:00 and 18:00 or pick a slot', allowCustomTime: true, minTime: '09:00:00', maxTime: '18:00:00', disabledRanges: [ { start: '13:00:00', end: '14:00:00', }, ], minTimeMessage: 'Office not open until 9:00', maxTimeMessage: 'Office closed from 18:00', disabledRangeMessage: 'Lunch break is not available', label: 'Meeting Time', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "timePicker", "path": "meetingTime", "label": "Meeting Time", "props": { "hint": "Type any time between 9:00 and 18:00 or pick a slot", "allowCustomTime": true, "minTime": "09:00:00", "maxTime": "18:00:00", "disabledRanges": [ { "start": "13:00:00", "end": "14:00:00" } ], "minTimeMessage": "Office not open until 9:00", "maxTimeMessage": "Office closed from 18:00", "disabledRangeMessage": "Lunch break is not available" } } ]}No Available Times
Section titled “No Available Times”When minTime and maxTime generate no slots, the drop-down list shows an empty-state message. Use noAvailableTimesMessage to customize (and localize) it (it defaults to No available times).
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.timePicker('meetingTime', { hint: 'These bounds generate no slots, so the list shows the empty-state message', minTime: '18:00:00', maxTime: '09:00:00', noAvailableTimesMessage: 'No slots available', label: 'Meeting Time', }),];{ "$schema": "https://golemui.com/schemas/form.schema.json", "form": [ { "kind": "input", "type": "timePicker", "path": "meetingTime", "label": "Meeting Time", "props": { "hint": "These bounds generate no slots, so the list shows the empty-state message", "minTime": "18:00:00", "maxTime": "09:00:00", "noAvailableTimesMessage": "No slots available" } } ]}Styling
Section titled “Styling”Time Pickers can be styled as explained in the Styling Guide. The typed field and the slot list each have their own styling variables.
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-text-default | Input and slot text color, active piece (hour/minute) underline |
--gui-intent-error | Input border color when invalid |
--gui-border-focus | Input border and focused slot outline color |
--gui-bg-default | Background color for the drop-down list container |
--gui-border-default | Border color for the drop-down list container |
--gui-radius-md | Border radius for the drop-down list container |
--gui-intent-primary | Background color for the selected slot |
--gui-intent-primary-hover | Background color for slots on hover |
--gui-intent-primary-text | Text color for the selected and hovered slots |
--gui-bg-disabled | Background color for disabled slots |
--gui-text-muted | Text color of the “no available times” message |
Anatomy
Section titled “Anatomy”This is the anatomy of the Time Picker Widget in case you want to use your CSS styles.
<gui-time-picker class="gui-time-picker gui-field"> <label class="gui-label" for="fieldUid" id="fieldUid_label"> Label <div class="gui-widget-hint" id="fieldUid_hint">Hint</div> </label>
<div role="button" tabindex="-1" class="gui-widget" aria-expanded="false"> <!-- The typing surface is a Time Input; readonly unless allowCustomTime --> <gui-time id="time-input" class="gui-calendar--icon"> <div class="gui-widget"> <div class="gui-widget-input gui-time-input" role="group"> <div class="gui-time-input__touch-target"> <input type="text" inputmode="numeric" class="gui-time-input__part" data-type="hour" maxlength="2" placeholder="hh" tabindex="0" value="09"> <div class="gui-time-input__visual-underline"></div> </div> <span class="gui-time-input__separator">:</span>
<div class="gui-time-input__touch-target"> <input type="text" inputmode="numeric" class="gui-time-input__part" data-type="minute" maxlength="2" placeholder="mm" tabindex="-1" value="30"> <div class="gui-time-input__visual-underline"></div> </div>
<!-- Only rendered in 12-hour mode, at the locale's position --> <div class="gui-time-input__touch-target"> <button type="button" class="gui-time-input__part gui-time-input__dayperiod" data-type="dayPeriod" tabindex="-1" aria-label="AM/PM">AM</button> <div class="gui-time-input__visual-underline"></div> </div> </div> <span class="gui-widget-icon schedule" data-icon="schedule"></span> </div> </gui-time>
<span class="gui-time-picker__arrow"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 256 256"><path d="..."></path></svg> </span>
<!-- Drop-down list of time slots --> <gui-time-list> <div class="gui-time-list__viewport" role="listbox" style="--gui-time-list-height: 300px; --gui-time-list-item-height: 40px; --gui-time-list-columns: 1;"> <button type="button" role="option" class="gui-time-list__option gui-time-list__option--selected" tabindex="0" data-value="09:30:00" aria-selected="true" aria-disabled="false">9:30 AM</button> <button type="button" role="option" class="gui-time-list__option" tabindex="-1" data-value="10:00:00" aria-selected="false" aria-disabled="true" disabled>10:00 AM</button> </div> <!-- When minTime/maxTime yield no slots, the viewport is replaced by: --> <!-- <div class="gui-time-list__empty">No available times</div> --> </gui-time-list> </div></gui-time-picker>