TimeZonePicker
TimeZonePicker selects an IANA zone such as America/Sao_Paulo, not a fixed GMT offset. Choose it
when an appointment, availability rule or booking needs a durable zone identifier; choose Combobox
when the choices are not time zones and do not need daylight-saving-aware offsets.
Examples
Store an IANA zone
The selected value is the IANA identifier, while the trigger presents a readable city label and its current offset. Keep the identifier in application state rather than persisting a display string.
Offsets for a meeting date
Set referenceDate to the date being planned. The displayed GMT offset is derived for that date,
so a zone such as New York correctly differs between winter and summer. Recent zones are
deduplicated and removed from their regional list.
When to use
Use TimeZonePicker whenever a person chooses the location whose local clock gives a scheduled value meaning.
Reach for something else when:
- The list is an unrelated set of searchable records — use Combobox and supply its own options.
- The time zone is already known from the account or event — show the resolved local time instead of asking for a second choice.
- The task is choosing a time within a known zone — use TimePicker or TimeInput alongside the known zone.
Accessibility
- TimeZonePicker composes Combobox. Its trigger exposes listbox state; when opened, focus moves to the
search input, which uses
aria-activedescendantto identify the active option. - Arrow Up/Down, Home and End move the active result; Enter selects it; Escape closes the popup and returns focus to the trigger. The regional, detected and recent headings are presentational group labels.
labelnames the search input.hintorerrordescribes both controls, anderrorreplaces the hint.- Search folds diacritics in both labels and keywords:
cafecan findcafé. Options also match their IANA identifier and displayed offset even though those search terms need not be visible.
Styling hook
.lyra-tzpicker is a selection hook with no styling of its own. It marks the picker root (next to .lyra-combobox, which carries all appearance) so your CSS and scripts can target it, as SlotPicker does internally. Use className to extend it rather than restyling .lyra-combobox.
API and code
| Name | Type | Required | Description |
|---|---|---|---|
value | string | — | Controlled IANA zone identifier, for example `"America/Sao_Paulo"`. |
defaultValue | string | — | Initial IANA zone identifier in uncontrolled mode. |
onChange | (zone: string) => void | — | Called with the selected IANA zone identifier. |
referenceDate | string | Date | — | Date used to derive the displayed GMT offset. Defaults to the current time. |
recentZones | string[] | — | IANA zones pinned under the recent-zones heading. |
detectedZone | string | — | IANA zone pinned under the detected-zone heading. |
zones | TimeZoneOption[] | — | Replaces the curated default zone list. |
locale | string | — | BCP 47 locale used for each option's live local time. Default: `"en-US"`. |
label | string | — | Label rendered above the picker. |
hint | string | — | Helper text rendered below the picker. |
error | string | — | Error message that replaces `hint` and enables error styling. |
placeholder | string | — | Trigger text when no zone is selected. Defaults to `labels.placeholder`. |
labels | TimeZonePickerLabels | — | Translatable visible and accessible labels, merged over English defaults. |
disabled | boolean | — | Disables the picker trigger. |
className | string | — | Additional class name appended to `.lyra-tzpicker`. |
x-data="lyraTimeZonePicker({ … })"
| Option | Type | Required | Description |
|---|---|---|---|
zones | readonly LyraTimeZonePickerOption[] | — | IANA zones that replace {@link TIME_ZONE_PICKER_ZONES}. |
recentZones | readonly string[] | — | IANA zones pinned after the detected zone. Default: `[]`. |
detectedZone | string | — | IANA zone pinned before recent zones. |
referenceDate | string | Date | — | Date used to derive GMT offsets. A `YYYY-MM-DD` value becomes local noon. |
locale | string | — | BCP 47 locale used for each option's live local time. Default: `"en-US"`. |
labels | LyraTimeZonePickerLabels | — | Labels merged over the English defaults. |
placeholder | string | — | Trigger text when no zone is selected; overrides `labels.placeholder`. |
Without React, use the Combobox structure and derive the zone's offset for the intended date yourself:
<div class="lyra-field">
<label class="lyra-label" id="time-zone-label" for="time-zone">Time zone</label>
<span class="lyra-combobox lyra-tzpicker">
<button
class="lyra-input lyra-combobox__trigger"
id="time-zone"
type="button"
aria-haspopup="listbox"
aria-expanded="true"
aria-controls="time-zone-listbox"
>
<span class="lyra-combobox__value">New York (GMT-5)</span>
</button>
<div class="lyra-combobox__pop">
<div class="lyra-combobox__search">
<input
role="combobox"
aria-labelledby="time-zone-label"
aria-controls="time-zone-listbox"
/>
</div>
<div class="lyra-combobox__list" id="time-zone-listbox" role="listbox">
<span class="lyra-combobox__group" role="presentation">Americas</span>
<button class="lyra-combobox__option" type="button" role="option" aria-selected="true">
New York (GMT-5)
</button>
</div>
</div>
</span>
</div><lyra:time-zone-picker> Generated from lyra-ds/blade v0.10.0.
The behavior comes from lyraTimeZonePicker() — install @lyra-ds/alpine and see the HTML + Alpine tab.
| Prop | Default | Required | Example values |
|---|---|---|---|
value | null | — | — |
zones | null | — | — |
recentZones | [] | — | — |
detectedZone | null | — | — |
referenceDate | null | — | — |
label | null | — | Time zone |
hint | null | — | Choose one |
error | null | — | Required |
placeholder | null | — | — |
locale | 'en-US' | — | — |
labels | [] | — | — |
disabled | false | — | — |
<lyra:time-zone-picker
label="Time zone"
value="America/Sao_Paulo"
detected-zone="America/Sao_Paulo"
:recent-zones="['Europe/Lisbon', 'America/New_York']"
locale="en-US"
/>