Skip to content

feat(react-timepicker-preview): add TimePicker component - #36813

Draft
Victor Genaev (mainframev) wants to merge 5 commits into
timepicker-preview/time-utilsfrom
timepicker-preview/component
Draft

Victor Genaev (mainframev) wants to merge 5 commits into
timepicker-preview/time-utilsfrom
timepicker-preview/component

Conversation

@mainframev

@mainframev Victor Genaev (mainframev) commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Stack: #36811 scaffold (merged) → #36845 spec → #36812 time utilities → #36813 TimePicker → #36814 headless TimePicker

Previous Behavior

The compat TimePicker:

  • wraps the styled useCombobox_unstable and mutates its state;
  • uses a non-standard onTimeChange(event, data) callback;
  • types formatDateToTimeString as (date) => string, although it is called with format options.

New Behavior

Adds a v9 TimePicker built on Combobox with the same behavior:

  • Selection follows the v9 form control convention: value / defaultValue (Date | null), optional displayValue for controlled input text, and onChange: EventHandler<TimePickerOnChangeData> firing on commit. The data is a discriminated EventData union (click | keydown | change | blur), so type narrows event. The native input value, defaultValue and onChange are omitted from the props.
  • The input text is derived from value with formatDateToTimeString, so it no longer has to be controlled alongside the selection. Typed freeform text is kept after a commit so the user can correct it.
  • The default dateAnchor is captured once from the initial value and does not move when a controlled selection is accepted.
  • Leaving the input after clearing no longer reports required-input.
  • useCustomStyleHook_unstable('useTimePickerStyles_unstable') is applied; the hook name is registered in react-shared-contexts (minor).
  • formatDateToTimeString(date, options) gets the options it is called with.
  • useTimePickerBase_unstable returns state with no appearance/size, default icons or Tabster.
  • The time logic is split into two hooks that work with any Combobox state hook: useTimePickerSelection_unstable (options, selection, Combobox props) and useTimePickerComboboxState_unstable (freeform commit on Enter or blur, clear handling, Field labelling). The headless package reuses them in feat(react-headless-components-preview): add headless TimePicker #36814 without pulling in react-positioning.
  • Combobox state is no longer mutated after it is created; callbacks and refs are merged instead.
  • The Field-labelled chevron now also gets the id that its aria-labelledby points to.
  • Time utilities are exported.

Other props (startHour, endHour, increment, dateAnchor, hourCycle, showSeconds, freeform, parseTimeStringToDate) are unchanged. Compat's selectedTime / defaultSelectedTime / onTimeChange map to value / defaultValue / onChange, see the spec's migration table.

The compat unit and Cypress tests are ported, and base-hook tests are added. Stories are ported under Preview Components/TimePicker, and the package is added to public-docsite-v9

@github-actions

Copy link
Copy Markdown

Pull request demo site: URL

@mainframev
Victor Genaev (mainframev) force-pushed the timepicker-preview/component branch 2 times, most recently from 9c5c742 to adc54d5 Compare October 5, 2026 09:25
@mainframev
Victor Genaev (mainframev) removed this pull request from stack #36815 October 5, 2026 09:26
@mainframev
Victor Genaev (mainframev) added this pull request to stack #36832 October 5, 2026 09:26
@mainframev
Victor Genaev (mainframev) force-pushed the timepicker-preview/component branch 2 times, most recently from 504ecf8 to ea4bd1f Compare October 6, 2026 16:29
@mainframev
Victor Genaev (mainframev) removed this pull request from stack #36832 October 7, 2026 10:54
@mainframev
Victor Genaev (mainframev) added this pull request to stack #36846 October 7, 2026 10:55
@mainframev
Victor Genaev (mainframev) removed this pull request from stack #36846 October 8, 2026 15:00
@mainframev
Victor Genaev (mainframev) added this pull request to stack #36857 October 8, 2026 15:00
@mainframev
Victor Genaev (mainframev) removed this pull request from stack #36857 October 8, 2026 15:21
@mainframev
Victor Genaev (mainframev) added this pull request to stack #36858 October 8, 2026 15:22
@mainframev
Victor Genaev (mainframev) force-pushed the timepicker-preview/component branch 4 times, most recently from 69a75f5 to 0a6218e Compare October 20, 2026 19:44
…the spec

- compare typed text with the display text after the last change, so
  leaving the input without typing or after an external value change does
  not commit, and deleting the initial text does
- report the formatted text as displayValue for a valid commit and '' for
  an empty one; an empty commit is not parsed
- ignore Combobox clearing the selection while typing in a basic TimePicker
- read required from the input or the Field, not Field first
- export HourCycle
- fix the custom parsing story crash and story wording
…skip repeated selects

- the expand icon stays in the tab order as in Combobox; focus leaving the
  input or the expand icon to outside the TimePicker commits
- selecting the option that is already selected is not a change
- add time range and hour cycle stories
- spec: document select on Tab and blur, empty commits, DST gaps, the
  chevron tab stop, TimePickerTimeState and the exported types
…election hooks and re-export Combobox type aliases

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant