Repository navigation
feat(Calendar): show the months of the selected calendar system - #9622
nynexman4464 wants to merge 5 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
PR Analysis Report🔎 Preview ·
|
| Component | Size | LoC | Visual · A11y · RTL |
|---|---|---|---|
| DateInput · Storybook | 100.6 kB (+1.4 kB) · 15.3 kB CSS (0) | 3,650 (+1) | ✓ · ✓ · ✓ |
| DateTimeInput · Storybook | 112.5 kB (+1.3 kB) · 15.8 kB CSS (0) | 3,641 (+1) | ✓ · ✓ · ✓ |
| DateRangeInput · Storybook | 68.9 kB (+1.3 kB) · 11.7 kB CSS (0) | 638 (+1) | ✓ · ✓ · ✓ |
117 more components
| Component | Size | LoC | Visual · A11y · RTL |
|---|---|---|---|
| lab/MobilePowerSearch | 166.2 kB (+1.3 kB) · 1.2 kB CSS (0) | — | — · — · — |
| PowerSearch | 182.2 kB (+1.2 kB) · 20.5 kB CSS (0) | — | — · — · — |
| Calendar · Storybook | 53.3 kB (+1.1 kB) · 10.3 kB CSS (0) | 1,673 (+27) | ✓ · ✓ · ✓ |
| lab/ChatReactionBar | 63.5 kB (+2 B) · 1.1 kB CSS (0) | — | — · — · — |
| lab/Schedule | 57.8 kB (+2 B) · 3.9 kB CSS (0) | — | — · — · — |
| lab/CommentThread | 225.0 kB (+1 B) · 2.4 kB CSS (0) | — | — · — · — |
| charts/Chart | 60.9 kB (0) · 20 B CSS (0) | — | — · — · — |
| charts/ChartLegend | 50.4 kB (0) · 20 B CSS (0) | — | — · — · — |
| AlertDialog | 53.8 kB (0) · 12.7 kB CSS (0) | — | — · — · — |
| AppShell | 65.8 kB (0) · 12.1 kB CSS (0) | — | — · — · — |
| Avatar | 32.4 kB (0) · 6.5 kB CSS (0) | — | — · — · — |
| AvatarGroup | 35.2 kB (0) · 6.6 kB CSS (0) | — | — · — · — |
| AvatarGroupOverflow | 36.3 kB (0) · 6.5 kB CSS (0) | — | — · — · — |
| Banner | 44.6 kB (0) · 10.3 kB CSS (0) | — | — · — · — |
| BaseTypeahead | 53.2 kB (0) · 10.2 kB CSS (0) | — | — · — · — |
| BreadcrumbItem | 65.0 kB (0) · 11.4 kB CSS (0) | — | — · — · — |
| Breadcrumbs | 16.0 kB (0) · 3.4 kB CSS (0) | — | — · — · — |
| Button | 39.6 kB (0) · 9.5 kB CSS (0) | — | — · — · — |
| Carousel | 47.3 kB (0) · 10.5 kB CSS (0) | — | — · — · — |
| ChatComposer | 59.2 kB (0) · 11.2 kB CSS (0) | — | — · — · — |
| ChatComposerDrawer | 17.5 kB (0) · 4.7 kB CSS (0) | — | — · — · — |
| ChatComposerInput | 53.8 kB (0) · 10.4 kB CSS (0) | — | — · — · — |
| ChatComposerTokenElement | 53.8 kB (0) · 10.4 kB CSS (0) | — | — · — · — |
| ChatDictationButton | 43.2 kB (0) · 9.8 kB CSS (0) | — | — · — · — |
| ChatLayout | 45.7 kB (0) · 10.3 kB CSS (0) | — | — · — · — |
| ChatLayoutScrollButton | 43.1 kB (0) · 9.9 kB CSS (0) | — | — · — · — |
| ChatMessage | 16.7 kB (0) · 3.7 kB CSS (0) | — | — · — · — |
| ChatMessageList | 22.7 kB (0) · 7.9 kB CSS (0) | — | — · — · — |
| ChatMessageMetadata | 19.6 kB (0) · 4.1 kB CSS (0) | — | — · — · — |
| ChatSendButton | 42.4 kB (0) · 9.5 kB CSS (0) | — | — · — · — |
| ChatToolCalls | 25.8 kB (0) · 9.3 kB CSS (0) | — | — · — · — |
| CheckboxInput | 46.9 kB (0) · 9.7 kB CSS (0) | — | — · — · — |
| CheckboxList | 41.5 kB (0) · 8.6 kB CSS (0) | — | — · — · — |
| CheckboxListItem | 51.5 kB (0) · 11.0 kB CSS (0) | — | — · — · — |
| Citation | 19.9 kB (0) · 4.4 kB CSS (0) | — | — · — · — |
| CodeBlock | 57.0 kB (0) · 11.1 kB CSS (0) | — | — · — · — |
| CommandPalette | 48.2 kB (0) · 12.2 kB CSS (0) | — | — · — · — |
| CommandPaletteFooter | 17.0 kB (0) · 3.7 kB CSS (0) | — | — · — · — |
| CommandPaletteInput | 26.6 kB (0) · 8.5 kB CSS (0) | — | — · — · — |
| CommandPaletteList | 16.0 kB (0) · 3.4 kB CSS (0) | — | — · — · — |
| ComplexSelector | 53.5 kB (0) · 11.1 kB CSS (0) | — | — · — · — |
| ContextMenu | 73.1 kB (0) · 15.3 kB CSS (0) | — | — · — · — |
| DialogHeader | 45.6 kB (0) · 10.2 kB CSS (0) | — | — · — · — |
| DrawerHeader | 45.7 kB (0) · 11.6 kB CSS (0) | — | — · — · — |
| DropdownMenu | 70.8 kB (0) · 15.4 kB CSS (0) | — | — · — · — |
| DropdownMenuSubMenu | 55.9 kB (0) · 9.9 kB CSS (0) | — | — · — · — |
| Field | 39.6 kB (0) · 8.3 kB CSS (0) | — | — · — · — |
| FieldLabel | 33.3 kB (0) · 5.9 kB CSS (0) | — | — · — · — |
| FileInput | 51.8 kB (0) · 10.7 kB CSS (0) | — | — · — · — |
| IconButton | 39.6 kB (0) · 9.5 kB CSS (0) | — | — · — · — |
| InputGroup | 40.2 kB (0) · 8.4 kB CSS (0) | — | — · — · — |
| Kbd | 16.7 kB (0) · 3.6 kB CSS (0) | — | — · — · — |
| LayerProvider | 60.8 kB (0) · 10.5 kB CSS (0) | — | — · — · — |
| Lightbox | 48.3 kB (0) · 10.1 kB CSS (0) | — | — · — · — |
| Link | 40.2 kB (0) · 7.9 kB CSS (0) | — | — · — · — |
| ListItem | 50.9 kB (0) · 11.0 kB CSS (0) | — | — · — · — |
| Markdown | 143.7 kB (0) · 18.3 kB CSS (0) | — | — · — · — |
| MetadataList | 16.7 kB (0) · 3.8 kB CSS (0) | — | — · — · — |
| MobileNav | 48.0 kB (0) · 10.4 kB CSS (0) | — | — · — · — |
| MobileNavToggle | 43.0 kB (0) · 9.7 kB CSS (0) | — | — · — · — |
| MoreMenu | 71.1 kB (0) · 15.4 kB CSS (0) | — | — · — · — |
| MultiSelector | 70.9 kB (0) · 15.2 kB CSS (0) | — | — · — · — |
| NumberInput | 53.1 kB (0) · 11.2 kB CSS (0) | — | — · — · — |
| Outline | 24.2 kB (0) · 4.2 kB CSS (0) | — | — · — · — |
| Pagination | 84.1 kB (0) · 15.9 kB CSS (0) | — | — · — · — |
| Popover | 46.5 kB (0) · 12.4 kB CSS (0) | — | — · — · — |
| RadioList | 41.1 kB (0) · 8.3 kB CSS (0) | — | — · — · — |
| RadioListItem | 49.4 kB (0) · 10.1 kB CSS (0) | — | — · — · — |
| ResizeHandle | 18.7 kB (0) · 4.0 kB CSS (0) | — | — · — · — |
| SegmentedControl | 34.2 kB (0) · 6.5 kB CSS (0) | — | — · — · — |
| Selector | 75.1 kB (0) · 15.6 kB CSS (0) | — | — · — · — |
| SideNav | 63.4 kB (0) · 10.9 kB CSS (0) | — | — · — · — |
| SideNavCollapseButton | 43.4 kB (0) · 9.8 kB CSS (0) | — | — · — · — |
| SideNavHeading | 55.9 kB (0) · 10.5 kB CSS (0) | — | — · — · — |
| SideNavItem | 51.8 kB (0) · 10.4 kB CSS (0) | — | — · — · — |
| Slider | 44.4 kB (0) · 8.9 kB CSS (0) | — | — · — · — |
| Spinner | 18.5 kB (0) · 6.7 kB CSS (0) | — | — · — · — |
| Step | 27.8 kB (0) · 5.6 kB CSS (0) | — | — · — · — |
| Stepper | 44.2 kB (0) · 9.9 kB CSS (0) | — | — · — · — |
| Switch | 45.2 kB (0) · 9.7 kB CSS (0) | — | — · — · — |
| Table | 83.0 kB (0) · 16.0 kB CSS (0) | — | — · — · — |
| TableCell | 74.3 kB (0) · 15.8 kB CSS (0) | — | — · — · — |
| TableHeaderCell | 73.9 kB (0) · 15.5 kB CSS (0) | — | — · — · — |
| TableSelectionToolbar | 49.4 kB (0) · 11.5 kB CSS (0) | — | — · — · — |
| TabList | 35.4 kB (0) · 7.5 kB CSS (0) | — | — · — · — |
| TabMenu | 52.5 kB (0) · 10.4 kB CSS (0) | — | — · — · — |
| TextArea | 45.4 kB (0) · 9.8 kB CSS (0) | — | — · — · — |
| TextInput | 50.9 kB (0) · 10.9 kB CSS (0) | — | — · — · — |
| Thumbnail | 47.5 kB (0) · 11.3 kB CSS (0) | — | — · — · — |
| TimeInput | 86.5 kB (0) · 14.3 kB CSS (0) | — | — · — · — |
| Timestamp | 21.3 kB (0) · 9.9 kB CSS (0) | — | — · — · — |
| Toast | 56.7 kB (0) · 10.1 kB CSS (0) | — | — · — · — |
| ToggleButton | 40.5 kB (0) · 9.6 kB CSS (0) | — | — · — · — |
| Token | 25.0 kB (0) · 4.8 kB CSS (0) | — | — · — · — |
| Tokenizer | 68.3 kB (0) · 17.1 kB CSS (0) | — | — · — · — |
| Toolbar | 34.7 kB (0) · 7.9 kB CSS (0) | — | — · — · — |
| TopNav | 49.5 kB (0) · 10.7 kB CSS (0) | — | — · — · — |
| TopNavHeading | 55.4 kB (0) · 10.4 kB CSS (0) | — | — · — · — |
| TopNavMegaMenu | 51.4 kB (0) · 11.2 kB CSS (0) | — | — · — · — |
| TopNavMenu | 55.3 kB (0) · 10.5 kB CSS (0) | — | — · — · — |
| TreeList | 37.8 kB (0) · 5.0 kB CSS (0) | — | — · — · — |
| Typeahead | 61.0 kB (0) · 11.8 kB CSS (0) | — | — · — · — |
| lab/ChatTypingIndicator | 24.4 kB (0) · 612 B CSS (0) | — | — · — · — |
| lab/CommentComposer | 100.5 kB (0) · 1.9 kB CSS (0) | — | — · — · — |
| lab/CommentPin | 44.5 kB (0) · 1.2 kB CSS (0) | — | — · — · — |
| lab/DiffViewer | 67.9 kB (0) · 2.1 kB CSS (0) | — | — · — · — |
| lab/EmojiPicker | 68.3 kB (0) · 722 B CSS (0) | — | — · — · — |
| lab/ListInput | 80.0 kB (0) · 1.6 kB CSS (0) | — | — · — · — |
| lab/MobileTokenizer | 99.1 kB (0) · 880 B CSS (0) | — | — · — · — |
| lab/TourStep | 51.8 kB (0) · 590 B CSS (0) | — | — · — · — |
| lab/TransferList | 72.5 kB (0) · 1.7 kB CSS (0) | — | — · — · — |
| lab/TransferListSelector | 78.7 kB (0) · 1.9 kB CSS (0) | — | — · — · — |
| richtext/RichTextEditor | 274.3 kB (0) · 2.6 kB CSS (0) | — | — · — · — |
| richtext/RichTextEditorToolbar | 219.7 kB (0) · 454 B CSS (0) | — | — · — · — |
| richtext/RichTextView | 254.9 kB (0) · 2.3 kB CSS (0) | — | — · — · — |
| lab/Comments | 230.3 kB (−1 B) · 2.5 kB CSS (0) | — | — · — · — |
| lab/ChatEmojiPicker | 62.9 kB (−2 B) · 773 B CSS (0) | — | — · — · — |
Package size: @astryxdesign/core 5.83 MB packed (+13.5 kB); no new dependencies.
API changes: core +5 · ~2 · −0
Committed API report behind this build: core 18 rows; run pnpm api:report.
7 API changes (advisory)
| Package | Where | Signature | Usage | |
|---|---|---|---|---|
| + | core |
. · Components · component Calendar |
prop calendar?: CalendarSystem |
<Calendar calendar={…} /> |
| + | core |
. · Components · component InternationalizationProvider |
prop calendar?: CalendarSystem |
<InternationalizationProvider calendar={…} /> |
| + | core |
. · Types · type CalendarSystem |
type CalendarSystem = 'gregory' | 'iso8601' | 'buddhist' | 'roc' | 'japanese' | 'persian' | 'indian' | 'hebrew' | 'chinese' | 'dangi' | 'coptic' | 'ethiopic' | 'ethioaa' | 'islamic-c … #85e5f84c |
import type {CalendarSystem} from '@astryxdesign/core' |
| + | core |
. · Types · interface InternationalizationContextValue |
calendar?: CalendarSystem |
import type {InternationalizationContextValue} from '@astryxdesign/core'; const x: InternationalizationContextValue = {calendar: …} |
| + | core |
./i18n · Also exported from an earlier entry point · CalendarSystem |
CalendarSystem (.) |
import {CalendarSystem} from '@astryxdesign/core/i18n' |
| ~ | core |
. · Types · interface UseGridFocusOptions |
onPageDown?: () => void → onPageDown?: (event: React.KeyboardEvent) => void |
import type {UseGridFocusOptions} from '@astryxdesign/core'; const x: UseGridFocusOptions = {onPageDown: …} |
| ~ | core |
. · Types · interface UseGridFocusOptions |
onPageUp?: () => void → onPageUp?: (event: React.KeyboardEvent) => void |
import type {UseGridFocusOptions} from '@astryxdesign/core'; const x: UseGridFocusOptions = {onPageUp: …} |
Touched components checked; add ci:run-visual, ci:run-a11y or ci:run-rtl to run the full suites.
Current run: CI concluded failure; parts of this report may be missing.
Generated by PR Enrichment workflow | View full report
There was a problem hiding this comment.
This needs an engineering owner's spec decision before it can be approved. The calendar-system direction rests on the draft AST-111 and rewrites the current internationalization INV10, so an engineering owner (the author counts, as one) records approval of AST-111 and this PR's record changes by commenting /approve-spec <full head SHA>. Separately from that decision, these need changes:
DateInput,DateRangeInputandDateTimeInputrender the provider's calendar in their popovers but keep Gregorian field text, so one control shows two calendars.calendar="iso8601"passesiso8601straight toIntl, which drops the month name on Node.js and puts the year first in Chromium.- Calendar markup now depends on
Temporalduring server render and hydration, so it needs a server and client render pair plus the server-polyfill condition in the AST-013 exception and the docs. - Shift+PageUp/PageDown should go through
useGridFocusrather than a wrapper in front of it. - The provider docs should say only
Calendarfollows the calendar, and the 2,132-line change should split along #9609, #9610 and the stories.
[Automated review]
| onKeyDown, | ||
| ...rest | ||
| } = props; | ||
| const calendar = useCalendarSystem(calendarProp, 'Calendar'); |
There was a problem hiding this comment.
DateInput, DateRangeInput and DateTimeInput render <Calendar> without calendar, so this line gives their popovers the provider's calendar. Their field text, the touch MonthScroller and the DateRangeInput trigger stay Gregorian. Under calendar="persian", the field reads "October 30, 2026" over a popover reading "Aban 1405 AP". Until those fields follow the calendar, consider passing calendar="gregory" from them.
| * Japanese calendar an era can start inside a month, and most days of that | ||
| * month then belong to the era of its middle day. | ||
| */ | ||
| export function formatCalendarMonthLabel( |
There was a problem hiding this comment.
iso8601 reaches Intl.DateTimeFormat as-is. On Node.js 24 (ICU 78.3) the month disappears: the heading is "2026 " and the day name "2026 30, Friday". Chromium 149 gives "2026 October". Since ISO 8601 months are Gregorian, formatting iso8601 labels as gregory (here and in formatDateLabel) would fix both. A label test per Gregorian-aligned calendar would catch it.
| * provider's resolved calendar, else `gregory`. It resolves during render, so | ||
| * the server and the browser agree when both have `Temporal` or both lack it. | ||
| */ | ||
| export function useCalendarSystem( |
There was a problem hiding this comment.
This reads globalThis.Temporal during server render and the hydrating render. Node.js 24 has no Temporal while Chrome 144+ and Firefox 139+ do, so without a server polyfill the server renders the Gregorian month and the browser hydrates with the Persian one. AST-013 FR9 asks for identical hydration markup. The exception should state the server-polyfill condition, and a server and client render pair should cover it.
| // Shift+PageUp and Shift+PageDown move the focused day by a calendar year, | ||
| // as the APG date picker defines. The grid focus hook reads no modifier on | ||
| // a page key, so the year keys are handled before it. | ||
| const handleKeyDown = useCallback( |
There was a problem hiding this comment.
This handler runs in front of useGridFocus, which already owns the grid's page keys. Passing the event (or {shiftKey}) to onPageUp/onPageDown there is additive for existing callers. That keeps one page-key path instead of two that can drift apart.
There was a problem hiding this comment.
This needs an engineering owner's spec decision before it can be approved: the calendar-system direction rests on the draft AST-111 (#9605), rewrites the current internationalization INV10 and adds an AST-013 FR12 exception, so an engineering owner (the author counts, as one) records approval of AST-111, this PR's record changes and its new API rows, including the useGridFocus page-key event, by commenting /approve-spec <full head SHA>. The earlier date-field, iso8601, useGridFocus and provider-docs findings are fixed at this head. Separately from that decision, two changes are needed:
- A provider locale that already carries
-u-ca-now changes Calendar's output with no code change, which AST-017 FR1 treats as breaking, but the changeset ships it as a patch[feat]; drop the-u-ca-path here or classify it[breaking]with thecalendar="gregory"migration for a planned minor. - At 2,615 authored lines the PR is over the 2,000-line scope limit; land #9609 and #9610 first and move the Storybook stories to a follow-up, then split provider resolution from the grid change if it is still over.
[Automated review]
| @@ -0,0 +1,7 @@ | |||
| --- | |||
| '@astryxdesign/core': patch | |||
There was a problem hiding this comment.
A provider locale that already carries -u-ca- (for example en-u-ca-buddhist) now changes Calendar from "October 2026" to "October 2569 BE" with no code change. AST-017 FR1 classifies that as breaking, so a patch [feat] does not fit; drop the -u-ca- path from this PR or classify it [breaking] with the calendar="gregory" migration for a planned minor.
| export, or DOM change | ||
| - Released default preserved: `yes` — without a `calendar` prop or a | ||
| provider calendar, the grid shows Gregorian months | ||
| - Compatibility class: additive optional `calendar` prop; no default, export, |
There was a problem hiding this comment.
This holds for the prop, but not for a provider locale with -u-ca-: its Calendar output changes with no code change, which AST-017 FR1 counts as breaking. The compatibility class should say so, or the -u-ca- path should go.
| | ORD1, ORD2, PR1 | ORD1 and ORD2 are covered by the FR3–FR5 and AR1 rows. Evidence gap: no test asserts the absence of per-cell listeners | — | — | `audit:Calendar/behavior` | | ||
| | Contract | Verification | Representative states | Mutation or failure expectation | Audit section | | ||
| | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | | ||
| | FR1–FR5 | `Calendar.test.tsx` structure ("renders a valid APG grid: one grid, header row of columnheaders inside it, week rows of gridcells", "with week numbers, the header row's corner cell is a named columnheader, so every row child is a grid cell"), selection ("handles reverse range selection (end before start)", "caps the range highlight next to a disabled mid-range day (#2715)", "Escape cancels range selection in progress", "clears the in-progress start when the anchor is clicked again"), bounds ("prev button is disabled when focusDate month contains min", "next button is disabled when focusDate month contains max"), and navigation ("navigates to next month", "calls onFocusDateChange when navigating") suites | single, range, two months, bounded | A missing header row, a reverse pick that does not swap, a range highlight that reaches a disabled day, or a Previous/Next button enabled past `min`/`max` fails. Evidence gap: no test asserts locale digits for day or week numbers. | `audit:Calendar/behavior` | |
There was a problem hiding this comment.
Non-blocking: row 269 now lists a day-digit test, so this evidence gap applies to week numbers only.
| const baseMonth = useMemo(() => { | ||
| return plainDateSetFirstOfMonth(focusDate); | ||
| }, [focusDate]); | ||
| // The calendar month that holds the focus date. A controlled focus date is |
There was a problem hiding this comment.
Non-blocking (INV29): the first sentence restates calendarMonthOf. Suggest: "A controlled focus date is a new object on each render. Key the memo on its ISO string."
| // PageUp/PageDown move by a month, and with Shift by a year (APG date | ||
| // picker dialog). |
There was a problem hiding this comment.
Non-blocking (INV29): this narrates the handlers below. Suggest keeping only the reason: "Shift steps a year, as in the APG date picker dialog."
There was a problem hiding this comment.
This needs an engineering owner's spec decision before it can be approved, and two changes are required either way.
Spec decision. The calendar-system direction rests on the draft AST-111 (#9605) and rewrites the current internationalization INV10, which today keeps every Astryx grid and its navigation Gregorian and says non-Gregorian component semantics cannot be inferred from an implementation pull request. Approval needs an engineering owner to approve, in one decision:
- AST-111 as authority for calendar selection (prop, then provider, then an explicit
-u-ca-keyword, then Gregorian), Gregorian ISO values, and theTemporalboundary with its Gregorian fallback; - the new INV10 text, Calendar FR8–FR10 with the AR1 sentence and the AST-013 FR12 exception (reading
Temporalduring render and hydration), and InternationalizationProvider FR8, FR10 and ORD3; - the new API rows:
CalendarSystem, thecalendarprop onCalendarand onInternationalizationProvider,InternationalizationContextValue.calendar, and the key event now passed touseGridFocusonPageUp/onPageDown; - Shift+PageUp/PageDown stepping a year in the Gregorian calendar too.
An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request; as an engineering owner, the author may do so.
Required changes:
- A provider locale that already carries
-u-ca-(for exampleen-u-ca-buddhist) now turns Calendar's "October 2026" into "October 2569 BE" with no code change, which AST-017 FR1 classifies as breaking, but.changeset/calendar-systems-core.mdships it as a patch[feat]and the Calendar record calls the change additive: drop the-u-ca-path from this PR, or classify it[breaking]with thecalendar="gregory"migration under a declared minor and correct the record. - The change is 2,615 authored lines, over the 2,000-line limit with no exemption: land #9609 and #9610 first and rebase as planned, move the stories to a follow-up, and split provider resolution from the grid change if it is still over.
[Automated review]
| @@ -0,0 +1,7 @@ | |||
| --- | |||
| '@astryxdesign/core': patch | |||
There was a problem hiding this comment.
A provider locale that already carries -u-ca- (for example en-u-ca-buddhist) now changes Calendar from "October 2026" to "October 2569 BE" with no code change. AST-017 FR1 counts that as breaking, so a patch [feat] misclassifies it. Either drop the -u-ca- path from this PR, or mark it [breaking] with the calendar="gregory" migration and land it under a declared minor.
| export, or DOM change | ||
| - Released default preserved: `yes` — without a `calendar` prop or a | ||
| provider calendar, the grid shows Gregorian months | ||
| - Compatibility class: additive optional `calendar` prop; no default, export, |
There was a problem hiding this comment.
This holds for the calendar prop, but not for a provider locale with -u-ca-: its Calendar output changes with no code change. The compatibility class should say so once that path is kept or removed.
| | ORD1, ORD2, PR1 | ORD1 and ORD2 are covered by the FR3–FR5 and AR1 rows. Evidence gap: no test asserts the absence of per-cell listeners | — | — | `audit:Calendar/behavior` | | ||
| | Contract | Verification | Representative states | Mutation or failure expectation | Audit section | | ||
| | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | | ||
| | FR1–FR5 | `Calendar.test.tsx` structure ("renders a valid APG grid: one grid, header row of columnheaders inside it, week rows of gridcells", "with week numbers, the header row's corner cell is a named columnheader, so every row child is a grid cell"), selection ("handles reverse range selection (end before start)", "caps the range highlight next to a disabled mid-range day (#2715)", "Escape cancels range selection in progress", "clears the in-progress start when the anchor is clicked again"), bounds ("prev button is disabled when focusDate month contains min", "next button is disabled when focusDate month contains max"), and navigation ("navigates to next month", "calls onFocusDateChange when navigating") suites | single, range, two months, bounded | A missing header row, a reverse pick that does not swap, a range highlight that reaches a disabled day, or a Previous/Next button enabled past `min`/`max` fails. Evidence gap: no test asserts locale digits for day or week numbers. | `audit:Calendar/behavior` | |
There was a problem hiding this comment.
Non-blocking: the FR8–FR10 row now lists a day-digit test, so this evidence gap applies to week numbers only.
| locale: Locale; | ||
| direction: 'ltr' | 'rtl'; | ||
| /** | ||
| * The provider's calendar system, which `Calendar` shows. A context |
There was a problem hiding this comment.
Non-blocking: without Temporal, Calendar shows Gregorian while this field keeps the requested calendar, so "which Calendar shows" is not always true. Suggest: "The provider's requested calendar system."
| // The calendar month that holds the focus date. A controlled focus date is | ||
| // a new object on each render, so the memo keys on its ISO string. |
There was a problem hiding this comment.
Non-blocking (INV29): the first sentence restates calendarMonthOf. Suggest: "A controlled focus date is a new object on each render. Key the memo on its ISO string."
| // PageUp/PageDown move by a month, and with Shift by a year (APG date | ||
| // picker dialog). |
There was a problem hiding this comment.
Non-blocking (INV29): this narrates the handlers below. Suggest keeping only the reason: "Shift steps a year, as in the APG date picker dialog."
c13e940 to
53da574
Compare
There was a problem hiding this comment.
This needs an engineering owner's spec decision before it can be approved, and one change is needed either way.
Calendar showing other calendar systems rests on the draft AST-111 (#9605) and on #9791's provider calendar, and changes the current internationalization INV10, which keeps date grids and navigation Gregorian. An engineering owner needs to approve AST-111, the INV10 change, Calendar FR8–FR10 with its AST-013 FR12 exception, the provider record's FR10 change, and the new API (Calendar's calendar prop and the useGridFocus page-key event). An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request; as an engineering owner, the author may do so.
Required change:
- A provider locale that already carries
-u-ca-(for exampleen-u-ca-buddhist) now turns Calendar's "October 2026" into "October 2569 BE" with no code change, which AST-017 FR1 classifies as breaking, so drop that path from whatCalendarfollows or mark the changeset[breaking]with thecalendar="gregory"migration under a declared minor and correct the Calendar record's compatibility lines.
[Automated review]
20438bb to
158af09
Compare
53da574 to
fe3c951
Compare
There was a problem hiding this comment.
This needs an engineering owner's spec decision before it can be approved, and two changes are needed either way.
Spec decision. Calendar showing other calendar systems rests on the draft AST-111 (#9605) and on #9791's provider calendar. It also rewrites the current internationalization INV10, which keeps date grids and navigation Gregorian. An engineering owner needs to approve AST-111 as Calendar uses it, the INV10 rewrite, Calendar FR8–FR10 with the AST-013 FR12 exception, the provider FR10 sentence, and the new calendar prop. They record that by commenting /approve-spec <full head SHA> on this pull request; the author may do so as an engineering owner.
Required changes:
- A provider locale that already carries
-u-ca-(for exampleen-u-ca-buddhist) now changesCalendarfrom "October 2026" to "October 2569 BE" with no code change, which AST-017 FR1 counts as breaking and FR6 says approval cannot make nonbreaking, so the patch[feat]changeset and the "nonbreaking" line inCalendar.spec.mdneed to change: either follow only an explicitcalendarprop for now, or ship it as[breaking]in a declared minor with thecalendar="gregory"migration. - The description lists a
useGridFocusonPageUp/onPageDowntype change and says the branch will be rebased over #9609 and #9610, but this diff does not touchuseGridFocusand both are already in its base, so please drop those lines and say that the Gregorian year step and locale digits come frommain.
The focused tests, the typecheck and lint pass on this head, and values stay Gregorian ISO dates in every calendar.
[Automated review]
| @@ -0,0 +1,7 @@ | |||
| --- | |||
| '@astryxdesign/core': patch | |||
There was a problem hiding this comment.
This changes Calendar output for an existing provider locale with -u-ca- (en-u-ca-buddhist: "October 2026" becomes "October 2569 BE") with no code change. AST-017 FR1 counts that as breaking, and FR6 says engineering approval cannot make it nonbreaking. Either have Calendar follow only an explicit calendar prop for now, or ship this as [breaking] in a declared minor with the calendar="gregory" migration.
| - Compatibility class: additive optional `calendar` prop; no default, export, | ||
| or DOM structure change. A provider locale with an explicit `-u-ca-` keyword | ||
| shows that calendar; the keyword is the application's explicit request | ||
| (`spec:AST-111` DEC-2): nonbreaking; `calendar="gregory"` keeps Gregorian |
There was a problem hiding this comment.
"Nonbreaking" here rests on draft AST-111 DEC-2, but current AST-017 FR1 classes this output change as breaking, and FR6 says approval does not change that. Please state the class AST-017 gives it, or drop the -u-ca- path from what Calendar follows.
158af09 to
4c4fb22
Compare
fe3c951 to
0041c70
Compare
There was a problem hiding this comment.
This needs an engineering owner's spec decision before it can be approved, and three changes are needed either way.
Spec decision. Calendar showing other calendar systems rests on the draft AST-111 (#9605) and on #9791's provider calendar, rewrites the current internationalization INV10 (which keeps date grids and navigation Gregorian), and adds Calendar FR8–FR10, a spoken-date rule, an AST-013 FR12 exception and the new calendar prop on Calendar. An engineering owner records approval of that direction by commenting /approve-spec <full head SHA> on this pull request, and the author may do so as an engineering owner.
Required changes:
- A provider locale that already carries
-u-ca-(for exampleen-u-ca-buddhist) now changesCalendarfrom "October 2026" to "October 2569 BE" with no code change, which AST-017 FR1 classes as breaking, yet.changeset/calendar-systems-core.mdships it as a patch[feat]andCalendar.spec.mdcalls it nonbreaking, so please follow the revised AST-111 FR2 in #9605 and haveCalendarfollow only an explicitcalendarprop. - The description lists a
useGridFocushook-type change and pending rebases over #9609 and #9610, but those are already onmainand this diff does not touchuseGridFocus, so please drop those lines. - Miss: the rewritten INV10 in
docs/architecture/internationalization.mdsays every date component follows its own or the provider's calendar, butDateInput,DateRangeInputandDateTimeInputstill show Gregorian dates (as the provider's FR10 says), so please scope that sentence toCalendar.
Details and one smaller suggestion are inline.
[Automated review]
| @@ -0,0 +1,7 @@ | |||
| --- | |||
| '@astryxdesign/core': patch | |||
There was a problem hiding this comment.
This changes Calendar for an existing provider locale with -u-ca- (en-u-ca-buddhist: "October 2026" becomes "October 2569 BE") with no code change. AST-017 FR1 classes that as breaking, so patch [feat] does not fit, and the revised AST-111 FR2 in #9605 keeps that path Gregorian for now.
| - Compatibility class: additive optional `calendar` prop; no default, export, | ||
| or DOM structure change; the weekday header text follows DD1. A provider | ||
| locale with an explicit `-u-ca-` keyword shows that calendar; the keyword is | ||
| the application's explicit request (`spec:AST-111` DEC-2): nonbreaking; |
There was a problem hiding this comment.
"Nonbreaking" rests on AST-111 DEC-2, which #9605 now revises the other way: honoring the keyword waits for a minor release because AST-017 FR1 classes it as breaking. Please drop the -u-ca- sentence here and in the contract-at-a-glance row.
| `-u-ca-` keyword in its locale, and otherwise the Gregorian calendar | ||
| (`spec:AST-111` FR2). Astryx date components show Gregorian dates. | ||
| - **INV10 — The application selects the calendar; values stay Gregorian.** A | ||
| date component shows the calendar that it resolves from its own `calendar` |
There was a problem hiding this comment.
DateInput, DateRangeInput and DateTimeInput have no calendar prop and show Gregorian dates under any provider calendar, as this pull request's provider FR10 says, so this sentence holds only for Calendar. Suggest scoping it to Calendar and keeping "DateInput, DateRangeInput, and DateTimeInput show Gregorian dates".
| month start render that month differently, and React renders it again on | ||
| the client during hydration (`spec:AST-111` FR19). Day and month names | ||
| follow the month and day that the grid shows in every case. | ||
| - **Preserved obligations:** `spec:AST-013` FR7 and FR8, and FR9 outside the |
There was a problem hiding this comment.
Non-blocking: FR9 also fails when the server lacks Temporal and the browser has it, as the Reduction bullet above and the third Calendar.ssr.test.tsx case show. Suggest: "FR9 when the server and the browser agree on Temporal, outside the chinese and dangi mixed-implementation case."
0041c70 to
de34259
Compare
There was a problem hiding this comment.
This needs an engineering owner's spec decision before it can be approved, and two changes are needed either way.
Spec decision. Calendar showing other calendar systems rests on the draft AST-111 (#9605) and on #9791's provider calendar, rewrites the current internationalization INV10 (which keeps date grids and navigation Gregorian), and adds Calendar FR8–FR10, a spoken-date rule, an AST-013 FR12 exception and the new calendar prop on Calendar. An engineering owner records approval of that direction by commenting /approve-spec <full head SHA> on this pull request, and the author may do so as an engineering owner.
Required changes:
- The description still lists a
useGridFocushook-type change and pending rebases over #9609 and #9610, which are already onmainand not in this diff, and says INV10 lets a-u-ca-keyword select the calendar when the rewritten INV10 says it never does, so please drop those lines and reword the INV10 one. - The rewritten INV10 in
docs/architecture/internationalization.mdsays every date component shows the calendar from its own or the provider'scalendarprop, butDateInput,DateRangeInputandDateTimeInputstill show Gregorian dates (as the provider's FR10 says), so please scope that sentence toCalendar.
The earlier -u-ca- release-class request is resolved, and two smaller suggestions are inline.
[Automated review]
| Shared built-in date formatters pin the Gregorian calendar unless an Astryx | ||
| call site passes the resolved calendar. The low-level `plainDateFormat` | ||
| - **INV10 — The application selects the calendar; values stay Gregorian.** A | ||
| date component shows the calendar that it resolves from its own `calendar` |
There was a problem hiding this comment.
DateInput, DateRangeInput and DateTimeInput have no calendar prop and show Gregorian dates under any provider calendar, as this pull request's provider FR10 says. Suggest: "Calendar shows the calendar that it resolves from its own calendar prop or the provider's calendar prop, and otherwise the Gregorian calendar (…). DateInput, DateRangeInput, and DateTimeInput show Gregorian dates."
| month start render that month differently, and React renders it again on | ||
| the client during hydration (`spec:AST-111` FR19). Day and month names | ||
| follow the month and day that the grid shows in every case. | ||
| - **Preserved obligations:** `spec:AST-013` FR7 and FR8, and FR9 outside the |
There was a problem hiding this comment.
Non-blocking: FR9 also fails when the server lacks Temporal and the browser has it, as the Reduction bullet above and the third Calendar.ssr.test.tsx case show. Suggest: "FR9 whenever the server and the browser resolve the calendar the same way, outside the chinese and dangi case."
| export type CalendarProps = CalendarSingleProps | CalendarRangeProps; | ||
|
|
||
| /** The first day of `month`'s month that `isDisabled` allows, or null. */ | ||
| /** The first day of `month` that `isDisabled` allows, or null. */ |
There was a problem hiding this comment.
Non-blocking (INV29): this restates firstEnabledDayOfMonth and its return type. Suggest deleting the comment.
de34259 to
babf230
Compare
|
/approve-spec babf230 |
There was a problem hiding this comment.
Approved pending CI: GitHub CI has not run on this head yet, because the pull request targets #9791's branch. It runs once this pull request targets main after #9791 lands, so this lands only together with #9791.
An engineering owner's /approve-spec at this head covers the calendar-system record changes (INV10, Calendar FR8–FR10 and the spoken-date rule, the AST-013 FR12 exception, provider FR10 and the new calendar prop). The earlier requested changes to the description and to INV10 are done, the Calendar, i18n and date-input tests and the typecheck pass on this head, and Calendar without a calendar renders the same as before. spec:AST-111 itself still needs its own approval in #9605.
[Automated review]
Calendar takes a calendar prop and otherwise follows the provider's calendar. The grid, heading, day names, and announcements use the calendar, and navigation steps calendar months and years. Values stay Gregorian ISO dates. The date inputs pin their popover calendars to Gregorian.
…ion's request A provider locale with an explicit -u-ca- keyword shows that calendar; the Calendar record and the changeset state it as nonbreaking, with calendar="gregory" to keep Gregorian. The context field names the requested calendar, and a memo comment keeps only its reason.
…an dates The Calendar record, the changeset, and the story say that a provider locale with a -u-ca- keyword keeps Gregorian dates; set calendar to choose one.
DateInput, DateRangeInput, and DateTimeInput show Gregorian dates. The Calendar record's FR9 server-rendering obligation holds whenever the server and the browser resolve the calendar the same way.
babf230 to
5ec2dc4
Compare
This implements
spec:AST-111(approved in #9605) forCalendar: FR2 (its owncalendarprop over the provider's), FR3, FR4, FR5's fallback, FR6–FR8 and AR1, and thespec:AST-013FR12 exception forCalendar.User need
People who use a calendar other than the Gregorian calendar can't pick dates in it. A Persian user sees October instead of Aban, a Hebrew user never sees Adar I and Adar II, and a Thai user can't see Buddhist years. #9791 gives the provider a calendar, but no component shows it.
Problem and solution fit
Calendartakescalendar?: CalendarSystem, and otherwise shows the provider's calendar.Intland the runtime'sTemporaldisagree on a month start in the Chinese or Dangi calendar, the spoken date still matches the visible number.iso8601uses Gregorian names.DateInput,DateRangeInputandDateTimeInputpin their popover Calendar togregory, so it matches their Gregorian field text.useCalendarMonthDays. The publicuseCalendarDaysanduseCalendarNavigationhooks keep their Gregorian behavior.Current specification
spec:AST-111FR2–FR8 and AR1 (approved in spec(AST-111): date components use the calendar the application chooses #9605), and thespec:AST-013FR12 exception forCalendar.component:Calendarprojects them as FR8 (calendar months), FR9 (month and year steps), FR10 (ISO 8601 week numbers) and the spoken-date part of AR1, and records thespec:AST-013FR12 exception.component:InternationalizationProviderFR10 and its doc now state thatCalendarfollows the resolved calendar, with its own prop first, and that the date inputs show Gregorian dates.architecture:internationalizationINV10 now states thatCalendarshows the calendar it resolves from its owncalendarprop or the provider's, and otherwise Gregorian, and thatDateInput,DateRangeInputandDateTimeInputshow Gregorian dates; a locale, including a-u-ca-keyword, never selects the calendar.AST-111 is still a draft, so this PR waits for its approval.
Public delta and caller burden
Calendarcalendar?: CalendarSystem, defaulting to the provider's calendar, else'gregory'.Temporal, loads a polyfill on the server and in the browser.Design and alternatives
Temporalavailability render the same markup.Evidence
Calendar.calendarSystems.test.tsx):hasVariableRowCount, and a year step to the same month;max;min/maxby day;DateInput,DateTimeInputandDateRangeInputkeeping a Gregorian popover calendar under a Persian provider.calendarSystem.test.tsxcovers a component calendar over the provider calendar, and the no-Temporalfallback for a PersianCalendar.Temporal,Temporalremoved with the polyfill loaded, andTemporalremoved without a polyfill (Gregorian fallback and warning).Temporalbelow.renderToStringfollowed byhydrateRootunder a Persian provider produces no error when both sides haveTemporalor both lack it. A server without it and a browser with it produce a hydration error. The Calendar record keepsspec:AST-013FR9 whenever the server and the browser resolve the calendar the same way, outside thechineseanddangicase.Temporalrunning one day ahead ofIntlkeeps 2027-02-06 named "First Month 1". In Chromium 149, with nativeTemporal, every day name around the first month of the 2027chineseyear matches its visible number.Screenshots
Chromium 149 with native Temporal unless noted.
Scope
Testing
--maxWorkers=2, over the test files beside the changed sources (Calendar, i18n, utils and the date inputs) plusdocPropLiterals: 82 files, 2,036 of 2,037 tests passed. The one failure,hitArea.test.ts"batches every pending control into one frame: all reads, then all writes", fails the same way on themaincommit the stack sits on (d23d1fe438).pnpm exec tsc --noEmit -p packages/core: passes.pnpm check:knowledge,pnpm check:changesets: pass.node scripts/pre-review.mjs --base nynexman4464/feat/calendar-system-boundary: 1,416 authored lines.Temporal, with the polyfill, and with noTemporal.Writing rubric results
Records touched:
architecture:internationalization,component:Calendarandcomponent:InternationalizationProvider.Calendaras the component that follows the calendar and the three date inputs as Gregorian, matching FR10. The Calendar record's preserved obligation states FR9 as holding whenever the server and the browser resolve the calendar the same way.#2715in Calendar's test-case names is unchanged.