Repository navigation
feat(DateInput, DateTimeInput): a non-Gregorian calendar uses the Astryx picker - #9793
nynexman4464 wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
There was a problem hiding this comment.
Approval waits on an engineering owner's decision about the spec change this pull request makes; no blocking code defect was found.
- To settle: current
spec:AST-043FR2 says an explicitpresentation="native"always shows the native surface. This head rewrites FR1–FR3, addingcomponent:DateInputFR17 andcomponent:DateTimeInputFR11, so that outsidegregoryandiso8601such a field shows the Astryx popover or bottom sheet and warns in development. The rewrite citesspec:AST-111FR15 and DEC-7, which are still draft and not on main.
Any engineering owner, the author included if they are one, can record approval of that exception by commenting /approve-spec with the full head commit SHA. Two small non-blocking notes are inline: the matrix test titles leave out the expected surface, and the warning comment says once per calendar where the key is per component and calendar.
[Automated review]
|
|
||
| describe('DateInput surface in a calendar', () => { | ||
| it.each(CASES)( | ||
| '%s in %s on a %s pointer shows the %s', |
There was a problem hiding this comment.
Non-blocking: this format gets [name, props, calendar, pointer, surface], so a case reads "native in { presentation: 'native' } on a persian pointer shows the fine", and the expected surface never appears. Put props last in each CASES tuple so the four placeholders get name, calendar, pointer and surface. The same applies at line 256.
| // Synchronizes the development console. warnOnce makes a replay or a | ||
| // second field a no-op, so the warning appears once for each calendar. |
There was a problem hiding this comment.
Non-blocking: the key includes the component, so a Persian DateInput and a Persian DateTimeInput on one page each warn once. Suggested wording: "Synchronizes the development console. The key is the component and calendar, so a replay or a second field does not warn again."
302c777 to
bd1f569
Compare
There was a problem hiding this comment.
Approval waits on an engineering owner's decision about the spec change this pull request makes, and one code fix is needed after that.
- To settle: current
spec:AST-043FR2 says an explicitpresentation="native"always shows the native surface (and FR3 keepsnativePickerexactly as released), while this pull request rewrites FR1–FR3 and addscomponent:DateInputFR17 andcomponent:DateTimeInputFR11 so that outsidegregoryandiso8601those values show the Astryx popover or bottom sheet and an explicitnativewarns, citingspec:AST-111FR15 and DEC-7, which are still draft and not on main. - Required fix:
isGregorianCalendarinutils/calendarSystem.tsrepeats thegregory/iso8601test thatuseTypedDate.tskeeps inline at lines 114 and 218, so call the shared helper there and the presentation and typed-entry rules cannot drift apart.
Any engineering owner, the author included if they are one, can record approval of the spec change by commenting /approve-spec with the full head commit SHA. Two small non-blocking notes are inline.
[Automated review]
| * Whether `<input type="date">` can show the calendar. The native control is | ||
| * Gregorian by specification, so only `gregory` and `iso8601` qualify. | ||
| */ | ||
| export function isGregorianCalendar(calendar: CalendarSystem): boolean { |
There was a problem hiding this comment.
This predicate is the same test useTypedDate.ts keeps inline at lines 114 and 218 (calendar === 'gregory' || calendar === 'iso8601'). Please call isGregorianCalendar(calendar) and isGregorianCalendar(providerCalendar) there, so the presentation rule and the typed-entry rule share one definition of a Gregorian calendar.
|
|
||
| describe('DateInput surface in a calendar', () => { | ||
| it.each(CASES)( | ||
| '%s in %s on a %s pointer shows the %s', |
There was a problem hiding this comment.
Non-blocking: this format gets [name, props, calendar, pointer, surface], so a case reads "native in { presentation: 'native' } on a persian pointer shows the fine" and the expected surface never appears. Put props last in each CASES tuple so the four placeholders get name, calendar, pointer and surface (same at line 256).
| // Synchronizes the development console. warnOnce makes a replay or a | ||
| // second field a no-op, so the warning appears once for each calendar. |
There was a problem hiding this comment.
Non-blocking: the key includes the component, so a Persian DateInput and a Persian DateTimeInput on one page each warn once. Suggested wording: "Synchronizes the development console. The key is the component and calendar, so a replay or a second field does not warn again."
d3fbd62 to
2187c77
Compare
bd1f569 to
698fdd8
Compare
There was a problem hiding this comment.
Approval waits on an engineering owner's decision about the spec change this pull request makes, and one code fix is needed after that.
- To settle: current
spec:AST-043FR2 says an explicitpresentation="native"always shows the native surface (and FR3 keepsnativePickerexactly as released), while this pull request rewrites FR1–FR3 and addscomponent:DateInputFR17 andcomponent:DateTimeInputFR11 so that, outsidegregoryandiso8601, those values and the default show the Astryx popover or bottom sheet (for the time control too) and an explicitnativewarns, citingspec:AST-111FR15 and DEC-7, which are still draft and not on main. - Required fix:
isGregorianCalendarinutils/calendarSystem.tsrepeats thegregory/iso8601test thatuseTypedDate.tskeeps inline at lines 117 and 221, so call the shared helper there and the presentation and typed-entry rules cannot drift apart.
Any engineering owner, the author included if they are one, can record approval of the spec change by commenting /approve-spec with the full head commit SHA. A small non-blocking note is inline.
[Automated review]
| * Whether `<input type="date">` can show the calendar. The native control is | ||
| * Gregorian by specification, so only `gregory` and `iso8601` qualify. | ||
| */ | ||
| export function isGregorianCalendar(calendar: CalendarSystem): boolean { |
There was a problem hiding this comment.
This predicate is the same test useTypedDate.ts keeps inline at lines 117 and 221 (calendar === 'gregory' || calendar === 'iso8601'). Please call isGregorianCalendar(calendar) and isGregorianCalendar(providerCalendar) there, so the native-control rule and the typed-entry rule share one definition and cannot drift apart.
|
|
||
| describe('DateInput surface in a calendar', () => { | ||
| it.each(CASES)( | ||
| '%s in %s on a %s pointer shows the %s', |
There was a problem hiding this comment.
Non-blocking: this title format receives [name, props, calendar, pointer, surface], so a case reads "native in { presentation: 'native' } on a persian pointer shows the fine" and the expected surface never appears. Dropping props from the title, or putting it last in each CASES tuple, fixes it; the DateTimeInput block at line 256 uses the same format.
2187c77 to
b3b17f4
Compare
698fdd8 to
5576696
Compare
There was a problem hiding this comment.
Approval waits on an engineering owner's decision about the spec change this pull request makes, and one record fix is needed after that.
- To settle: current
spec:AST-043FR2 says an explicitpresentation="native"always shows the native surface (and FR3 keepsnativePickerexactly as released), while this pull request rewrites FR1–FR3 and addscomponent:DateInputFR18 andcomponent:DateTimeInputFR12 so that, outsidegregoryandiso8601, those values and the default show the Astryx popover or bottom sheet (for the time control too) and an explicitnativewarns, citingspec:AST-111FR15 and DEC-7, which are still draft and not on main. - Required fix: the new calendar requirement takes the id
component:DateInputFR18, which the current DateInput record on main already gives to the wheel accent-mark requirement, so give it the next free id when the stack rebases onto main and update its references in both records. - Non-blocking, from the base branch:
apps/storybook/stories/DateInput.stories.tsximportsInternationalizationProvidertwice, so Storybook does not start and the newCalendarSystemPresentationsstory cannot render until that is fixed.
Any engineering owner, the author included if they are one, can record approval of the spec change by commenting /approve-spec with the full head commit SHA. The earlier shared Gregorian-test finding is fixed.
[Automated review]
| | FR15 | Under a coarse primary pointer, a sheet wheel's pan takes a trackpad's two-finger scroll, as `spec:AST-094` FR43 allows a record to grant: the rows follow the fingers, coast on at the lift with the fingers' last speed, and rest on a row by FR13. A mouse-wheel notch turns the wheel one row, as an arrow key does, with no coast. A ctrl-scroll stays the page's zoom (`spec:AST-094` FR43). Implementation gap: the wheel is the browser's scroll-snap column for both inputs, so a trackpad's momentum runs at the browser's rate and a mouse-wheel notch moves the column by the browser's scroll step, several rows. | `spec:AST-094` FR43; current source | | ||
| | FR16 | Enter in the pointer field's text input commits typed text that has not been committed and is then held back, so a form never submits the value from before the commit. With no typed text pending, Enter is not prevented, so a form submits as it does from any text field, except on a disabled or busy field, where Enter does nothing (`spec:AST-085` FR2). | | ||
| | FR17 | The pointer field reads and writes typed dates in the resolved calendar (`spec:AST-111` FR2), and its Calendar shows that calendar. It reads the dates `Intl.DateTimeFormat` writes for the locale and calendar, in any Unicode decimal digits and with month and era names of the locale and English; in the Gregorian calendar, text that matches none of these forms, or that these forms read as a date the calendar does not have, still commits on Enter or blur when `parseDateInput` reads it, so `13/5/2026` in `en-US` commits as 13 May 2026 (`spec:AST-111` FR9). A typed year is a year of the calendar (`spec:AST-111` FR10). It rejects a date the calendar does not have and never adjusts it; a typed date outside `min`, `max`, or `dateConstraints` shows and announces an out-of-range error that writes the bounds in the calendar, and Enter or blur keeps both kinds of rejected text so the person can correct it, while unreadable text reverts (`spec:AST-111` FR11). While a person types, `onChange` fires only for complete input, at most once for each distinct value in one typing session, and a one-digit day stays open until another digit, Enter, or blur, so a day the month lacks is never reported as another date; a two-digit year and input without a year commit on Enter or blur, in every calendar including Gregorian, and a one-digit year is not a date: like other text the field cannot finish, Enter or blur keeps it and shows the unreadable message as the field status (`spec:AST-111` FR12, AR3). Each rejection is announced once: a shown status announces itself, and the field's alert carries only a rejection that no status shows. `date`, `date_long`, and `date_weekday` write the committed text in the calendar and read back as the same date; `system_date` stays Gregorian ISO and the field reads ISO input with it (`spec:AST-111` FR13). Text from a custom `format` function that the field cannot read back cannot be re-committed after an edit (`spec:AST-111` FR14). Values stay Gregorian ISO dates (`spec:AST-111` FR3). | `spec:AST-111` FR3, FR9–FR14; current source; parser, round-trip, and calendar typed-entry tests | | ||
| | FR18 | With a calendar other than `gregory` or `iso8601`, every presentation that would show the native control — `adaptive-native`, the default, deprecated `touch` and `always`, and an explicit `native` — shows the popover on a fine pointer and the bottom sheet on a coarse pointer, because the native control is Gregorian (`spec:AST-111` FR15). An explicit `native` also warns once in development. The bottom sheet shows Gregorian dates (Current-state impact). Values stay Gregorian ISO dates (`spec:AST-111` FR3). | `spec:AST-111` FR3, FR15; current source; calendar presentation and no-`Temporal` tests | |
There was a problem hiding this comment.
The current DateInput record on main already has an FR18 ("While a wheel coasts, snaps or turns, no row carries the selection band's accent mark"), and FR17 is the sheet wheel's key order. Please give this calendar requirement the next free id when the stack rebases onto main, and update its references in this record (FR2, the Behavior and Compatibility rows, ORD1, the AST-111 link, verification, Current-state impact) and in the DateTimeInput record.
…ryx picker The native date control shows only Gregorian dates. In a calendar other than gregory or iso8601, native and adaptive-native use the popover on a fine pointer and the bottom sheet on a coarse pointer, and an explicit native warns in development. AST-043 FR1 and FR3 name the exception.
…g and presentation useTypedDate calls isGregorianCalendar, the same test that decides when the native control can show the calendar. The presentation test names read the expected surface, and the warning comment says what keys it. The provider docs and record say that only the bottom sheet stays Gregorian, and the changeset says that an explicit -u-ca- locale selects the calendar the same way.
5576696 to
d1906f2
Compare
There was a problem hiding this comment.
Approval waits on an engineering owner's decision about the spec change this pull request makes, and one record fix is needed after that.
- To settle: current
spec:AST-043FR2 says an explicitpresentation="native"always shows the native surface (and FR3 keepsnativePickerexactly as released), while this pull request rewrites FR1–FR3 and addscomponent:DateInputFR18 andcomponent:DateTimeInputFR12 so that, outsidegregoryandiso8601, those values and the default show the Astryx popover or bottom sheet (for the time control too) and an explicitnativewarns, citingspec:AST-111FR15 and DEC-7, which are still draft and not on main; the owner also says whetherarchitecture:public-component-apiINV16, which lets a caller's explicit presentation choice win, needs a calendar exception. - Required fix: the new calendar requirement takes the id
component:DateInputFR18, which the current DateInput record on main already gives to the wheel accent-mark requirement, so give it the next free id when the stack rebases onto main and update its references in both records. - Non-blocking: the
calendarJSDoc inDateInput.tsxand the changeset say only the bottom sheet's months stay Gregorian, but on a touch screen the closed field also shows a Gregorian date; say that the field and its bottom sheet show Gregorian dates there.
Any engineering owner, the author included if they are one, can record approval of the spec change by commenting /approve-spec with the full head commit SHA.
[Automated review]
| | FR15 | Under a coarse primary pointer, a sheet wheel's pan takes a trackpad's two-finger scroll, as `spec:AST-094` FR43 allows a record to grant: the rows follow the fingers, coast on at the lift with the fingers' last speed, and rest on a row by FR13. A mouse-wheel notch turns the wheel one row, as an arrow key does, with no coast. A ctrl-scroll stays the page's zoom (`spec:AST-094` FR43). Implementation gap: the wheel is the browser's scroll-snap column for both inputs, so a trackpad's momentum runs at the browser's rate and a mouse-wheel notch moves the column by the browser's scroll step, several rows. | `spec:AST-094` FR43; current source | | ||
| | FR16 | Enter in the pointer field's text input commits typed text that has not been committed and is then held back, so a form never submits the value from before the commit. With no typed text pending, Enter is not prevented, so a form submits as it does from any text field, except on a disabled or busy field, where Enter does nothing (`spec:AST-085` FR2). | | ||
| | FR17 | The pointer field reads and writes typed dates in the resolved calendar (`spec:AST-111` FR2), and its Calendar shows that calendar. It reads the dates `Intl.DateTimeFormat` writes for the locale and calendar, in any Unicode decimal digits and with month and era names of the locale and English; in the Gregorian calendar, text that matches none of these forms, or that these forms read as a date the calendar does not have, still commits on Enter or blur when `parseDateInput` reads it, so `13/5/2026` in `en-US` commits as 13 May 2026 (`spec:AST-111` FR9). A typed year is a year of the calendar (`spec:AST-111` FR10). It rejects a date the calendar does not have and never adjusts it; a typed date outside `min`, `max`, or `dateConstraints` shows and announces an out-of-range error that writes the bounds in the calendar, and Enter or blur keeps both kinds of rejected text so the person can correct it, while unreadable text reverts (`spec:AST-111` FR11). While a person types, `onChange` fires only for complete input, at most once for each distinct value in one typing session, and a one-digit day stays open until another digit, Enter, or blur, so a day the month lacks is never reported as another date; a two-digit year and input without a year commit on Enter or blur, in every calendar including Gregorian, and a one-digit year is not a date: like other text the field cannot finish, Enter or blur keeps it and shows the unreadable message as the field status (`spec:AST-111` FR12, AR3). Each rejection is announced once: a shown status announces itself, and the field's alert carries only a rejection that no status shows. `date`, `date_long`, and `date_weekday` write the committed text in the calendar and read back as the same date; `system_date` stays Gregorian ISO and the field reads ISO input with it (`spec:AST-111` FR13). Text from a custom `format` function that the field cannot read back cannot be re-committed after an edit (`spec:AST-111` FR14). Values stay Gregorian ISO dates (`spec:AST-111` FR3). | `spec:AST-111` FR3, FR9–FR14; current source; parser, round-trip, and calendar typed-entry tests | | ||
| | FR18 | With a calendar other than `gregory` or `iso8601`, every presentation that would show the native control — `adaptive-native`, the default, deprecated `touch` and `always`, and an explicit `native` — shows the popover on a fine pointer and the bottom sheet on a coarse pointer, because the native control is Gregorian (`spec:AST-111` FR15). An explicit `native` also warns once in development. The bottom sheet shows Gregorian dates (Current-state impact). Values stay Gregorian ISO dates (`spec:AST-111` FR3). | `spec:AST-111` FR3, FR15; current source; calendar presentation and no-`Temporal` tests | |
There was a problem hiding this comment.
The current DateInput record on main already has an FR18 ("While a wheel coasts, snaps or turns, no row carries the selection band's accent mark"), and FR17 is the sheet wheel's key order. Please give this requirement the next free id when the stack rebases onto main, and update its references here (Behavior and Compatibility rows, the contract row, FR2, ORD1, the AST-111 link, verification and the Current-state gap) and in DateTimeInput.spec.md.
| * The native date control is Gregorian, so with a calendar other than | ||
| * `gregory` or `iso8601` every presentation that would show it uses the | ||
| * popover on a fine pointer and the bottom sheet on a coarse pointer. The | ||
| * bottom sheet's months and wheels stay Gregorian. |
There was a problem hiding this comment.
Non-blocking: on a coarse pointer the closed field also shows a Gregorian date (the sheet's field text is Gregorian), while the same field shows the calendar on a fine pointer. Suggested wording: "On a coarse pointer the field and its bottom sheet show Gregorian dates." The changeset says the same narrower thing.
This implements
spec:AST-111(draft, #9605) FR15 and DEC-7, with FR5's fallback, forDateInputandDateTimeInput.User need
A Persian, Hebrew, or Japanese user on a phone opens a date field and sees the native date picker. That picker is Gregorian (Android) or follows the device calendar (iOS), so the date they pick reads as a different date than the field shows. On a desktop, an explicit
presentation="native"has the same problem.Problem and solution fit
gregoryoriso8601, every presentation that would show<input type="date">uses the Astryx popover on a fine pointer and the bottom sheet on a coarse pointer. This coversadaptive-native(the default), the deprecatednativePickervalues, and an explicitpresentation="native", which also warns once in development (DEC-7). DateTimeInput's date and time surfaces follow the same rule.useCalendarPresentationresolves the calendar and the presentation policy it allows;calendarPickerPresentationininputPresentation.tsmapsnativeandadaptive-nativetoadaptive-bottom-sheet;isGregorianCalendarin the calendar-system utility names the calendars the native control can show.Temporal, calendars that need it fall back to Gregorian, and with them the native control (FR5).Current specification
spec:AST-111FR15, FR3, FR5 and DEC-7 (draft, spec(AST-111): date components use the calendar the application chooses #9605).spec:AST-043FR1–FR3 now name the one exception to an explicitnative: the calendar.component:DateInputFR17 andcomponent:DateTimeInputFR11, each with a Current-state gap for the Gregorian bottom sheet.Public delta and caller burden
nativewarns once in development.gregory/iso8601, and no change withoutTemporalfor the calendars that need it.Design and alternatives
spec:AST-111DEC-7): keeping an explicitnativenative. The device, not the application, would then choose the calendar.Evidence
nativePickervalue × Gregorian/Persian × fine/coarse pointer for DateInput and DateTimeInput, the provider calendar, and the explicit-native warning (once, and not for Gregorian or the defaults).Temporaltests: a Persian field becomes Gregorian with the native control and a warning; an explicitnativestays native; a Persian bottom sheet shows Gregorian months; a Persian DateTimeInput shows Gregorian native controls.Temporal, with the polyfill, and with noTemporal; WebKit (Safari 26.5) with the polyfill and with noTemporal.Screenshots
Chromium 149 with native Temporal unless noted.
Scope
Testing
pnpm exec vitest run packages/core/src/DateInput packages/core/src/DateTimeInput packages/core/src/DateRangeInput packages/core/src/Calendar packages/core/src/utils packages/core/src/docPropLiterals.test.ts: 78 files, 1910 tests passed.pnpm exec tsc --noEmit -p packages/core: clean apart from the existing missing generatedlocales/pseudo.json.pnpm check:knowledge,pnpm check:changesets: pass.pnpm review:pre --base nynexman4464/feat/calendar-typed-entry: 1,008 authored lines, no findings.Writing rubric results
spec:AST-043component:DateInput(#5074)is part of a quoted test title.component:DateTimeInput