Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
PR Analysis Report
Generated by PR Enrichment workflow | View current CI run |
There was a problem hiding this comment.
This review waits on an engineering owner: one month per release with the 45° sheet split, the reworded draft PR2 in DateInput.spec.md and the new draft spec:AST-094 have no current spec authority, so an engineering owner needs to approve or reject them by commenting /approve-spec 39408932bf15c4b71cf42bb94ee91e9fe674496f on this pull request, which the author may do as an engineering owner. Whatever that decision, please also make these changes:
- Land the predecessor pull requests, or rebase onto them, so this one carries only its own commit.
- Keep the
usePagereffects at lines 681-683 and 698-702 from callingonIndexChange, and name the system each synchronizes. - Correct the changeset's 45° line: drags between about 26.6° and 45° move neither the sheet nor the calendar.
[Automated review]
| pager.pan.setEnabled(isPanEnabled); | ||
| }, [pager, isPanEnabled]); | ||
|
|
||
| useEffect(() => { |
There was a problem hiding this comment.
This effect (and the setOptions effect at lines 681-683) can call the owner's onIndexChange through goTo(..., {reason: 'controlled'}), and neither names the system it synchronizes. Current architecture:react-component-runtime INV2 keeps consumer callbacks out of effects and INV3 asks each effect to name its external system: name the pager here and keep a 'controlled' move from calling onIndexChange, or drop the unused controlled index option.
| - A swipe moves at most one month, chosen at the lift by iOS's paging rule (a quick flick, or past half a month). It settles on iOS's paging curve instead of letting a fling run across several months. | ||
| - The month title follows the drag. It changes when the next month is more than half in view. | ||
| - The arrows scroll the month in 0.3 s; a second tap mid-scroll goes on to the month after. | ||
| - Inside the sheet, a drag steeper than 45° moves the sheet, and a flatter one stays with the calendar. |
There was a problem hiding this comment.
Drags between about 26.6° and 45° move neither the sheet nor the calendar (MonthScroller.tsx lines 457-464), so "a flatter one stays with the calendar" promises a response that does not happen. Suggest: "a drag steeper than 45° moves the sheet, one flatter than about 27° pages the calendar, and one in between moves neither, as on iOS."
There was a problem hiding this comment.
The changeset now says it: a drag steeper than 45° moves the sheet, one flatter than about 27° pages the calendar, and one in between moves neither, as on iOS.
| } | ||
| } else if (state === 'ended' || state === 'cancelled') { | ||
| // The release has chosen its month by now. | ||
| report(pager.virtualIndex); |
There was a problem hiding this comment.
This reports the release month synchronously at the end of the pan, so when a flick pages before the drag crossed half a month the owner's render runs inside the lift handler. usePager.ts lines 307-314 defer the pager's own report by two frames for exactly that Mobile Safari case; reporting from the deferred onIndexChange('drag') (lines 366-375) would keep the two consistent.
There was a problem hiding this comment.
Fixed in 68b7c0c: the title changes at half a month, not at the lift (see the newer thread).
| // Typed-field only: the wheels step by their own options and the sheet | ||
| // opens on tap, so neither reaches this surface. | ||
| increment: _increment, | ||
| increment, |
There was a problem hiding this comment.
The comment above ("Typed-field only ... neither reaches this surface") no longer holds: increment now steps the sheet's minute wheel.
| hourFormat = '12h', | ||
| // Desktop-only: mobile uses wheels instead of typed arrow stepping or a preset list. | ||
| timeIncrement: _timeIncrement, | ||
| timeIncrement, |
There was a problem hiding this comment.
The comment above ("Desktop-only: mobile uses wheels instead of typed arrow stepping") no longer holds: timeIncrement now steps the sheet's minute wheel.
3940893 to
2631091
Compare
There was a problem hiding this comment.
This review waits on an engineering owner: one month per release with the 45° sheet split, the reworded draft PR2 in DateInput.spec.md and the new draft spec:AST-094 have no current spec authority, so an engineering owner needs to approve or reject them by commenting /approve-spec <full head SHA> on this pull request, which the author may do as an engineering owner. Whatever that decision, these changes are still needed:
- Land the predecessor pull requests or rebase onto them, so this one carries only its own commit.
- Keep the
usePagereffects at lines 681-683 and 698-702 from callingonIndexChange, and name the system each synchronizes. - Stop naming the release month at the lift in
MonthScroller.tsx(lines 418-421), which turns the title earlier than the measured UIKit behavior and the changeset describe. - Page on a horizontal trackpad or wheel gesture again (
MonthScroller.tsxline 106), and correct the changeset's 45° line, the two staleincrement/timeIncrementcomments and the citation of a missing AST-090 inspec:AST-094.
[Automated review]
| } | ||
| } else if (state === 'ended' || state === 'cancelled') { | ||
| // The release has chosen its month by now. | ||
| report(pager.virtualIndex); |
There was a problem hiding this comment.
This names the release month at the lift, so a flick released before half a month turns the title then. The head's own UIKit table says the title changes "when the content crosses half a page, during the drag (and during a settle), not at the lift" (motion/uikit/datePicker.ts lines 64-67), and the changeset says it changes "when the next month is more than half in view". Letting the pager's deferred onIndexChange('drag') (lines 366-375) report the release would also keep the owner's render out of the touch handler, as usePager.ts lines 307-314 intend.
There was a problem hiding this comment.
Fixed in 68b7c0c: under a finger the calendar is MonthPager. Its title follows the drag and the settle and changes at half a month, not at the lift (interaction spec: the title at half a month).
| // nothing to fight over, and a downward drag on the calendar can go back | ||
| // to meaning swipe-to-dismiss. | ||
| touchAction: 'pan-x', | ||
| overflow: 'hidden', |
There was a problem hiding this comment.
With the viewport overflow: 'hidden' and no wheel handling in the pager or the gesture host, a two-finger trackpad swipe or Shift+wheel over the calendar no longer pages; on the base it scrolled the months natively. Mapping a horizontal wheel gesture onto pager.goTo one month at a time would keep that path.
There was a problem hiding this comment.
Fixed in 68b7c0c: MonthPager pages one month per horizontal trackpad swipe or Shift+wheel gesture (interaction spec).
| follows. | ||
| - **FR7 — Exits animate as UIKit's do.** A touch presentation MUST play the | ||
| exit its UIKit counterpart plays. **Proposed; pending owner review:** this | ||
| departs from the draft `spec:AST-090` FR1 (exits off by default) and FR10 |
There was a problem hiding this comment.
Neither main nor this branch has an AST-090 record, so this amendment (and the one at line 235) points at text a reader cannot open; cite it once the record exists, or drop it.
2631091 to
161f142
Compare
There was a problem hiding this comment.
This review waits on an engineering owner: one month per release with the 45° sheet split, the reworded draft PR2 in DateInput.spec.md and the new draft spec:AST-094 have no current spec authority, so an engineering owner needs to approve or reject them by commenting /approve-spec <full head SHA> on this pull request, which the author may do as an engineering owner. Whatever that decision, these changes are still needed:
- Land the predecessor pull requests or rebase onto them, so this one carries only its own commit.
- Keep the
usePagereffects at lines 681-683 and 698-702 from callingonIndexChange, and name the system each synchronizes. - Stop naming the release month at the lift in
MonthScroller.tsx(lines 418-421), or document it, so the title, the changeset and the measured UIKit behavior agree. - Page on a horizontal trackpad or wheel gesture again (
MonthScroller.tsxline 106), and correct the changeset's 45° line, the two staleincrement/timeIncrementcomments and the citation of a missing AST-090 inspec:AST-094.
[Automated review]
|
Posted by Cindy's agent on her behalf. Parts of this PR re-implement behavior that already exists, or is being specified, as a shared part of core. Converging keeps one implementation per behavior:
This is about where the behavior lives, not about the PR's intent. |
|
Agreed: one implementation.
|
161f142 to
68b7c0c
Compare
|
/approve-spec ea7ceae |
There was a problem hiding this comment.
Changes are needed before this can be approved. The month pager follows the current DateInput spec (PR2, AR8) and the touch-presentation spec, and the record edits it carries (DateInput FR20, DateTimeInput FR11, the Compatibility rows and the arrow step's recorded gap) have an engineering owner's approval at this head.
Required changes:
- The branch is 3,977 authored lines without a valid stack: #8206's body still lists the merged #8179 and #8206 does not sit on this head, so re-parent it with the same
Stack: #8209 → #8200 → #8206line, or land #8209 first. - The phone behaviour still lacks the evidence the touch-presentation spec requires: real-device iOS Safari recordings, and Android emulator runs at this head with animations at normal scale and removed plus a slow-device profile.
Fixed since the last review: the arrow step's curve is recorded as the shared pager's gap and no longer promised in the changeset, and the title reads the pager's own page geometry. A new commit here needs a fresh /approve-spec.
[Automated review]
| // No native pan on either axis: horizontal drags are the pager's and | ||
| // vertical ones the sheet's, both in JavaScript, as on the sheet's own | ||
| // surface. The pager leaves the viewport `pan-y`. In a sheet that lets the | ||
| // browser start a vertical scroll and throttle the sheet's drag moves. | ||
| // Pinch-zoom stays the browser's. |
There was a problem hiding this comment.
Non-blocking (INV29): "In a sheet that lets the browser start a vertical scroll and throttle the sheet's drag moves" has no clear subject. Shorter:
// The pager would leave the viewport `pan-y`. In a sheet, `pan-y` lets the
// browser start a vertical scroll and throttle the sheet's drag. So the track
// takes no native pan. Pinch-zoom stays the browser's.There was a problem hiding this comment.
This pull request is reviewed as part of its stack; see the review on #8206.
There was a problem hiding this comment.
Changes are needed before this can be approved. The month pager follows the current DateInput spec (PR2, AR8) and the touch-presentation spec, the stack line now holds, and an engineering owner approved the record edits at this head. What remains:
- Regression: the branch no longer merges with
main, and the newMonthPane.tsx,MonthPager.tsxanduseMonthGridFocus.tspage Gregorian months where main's DateInput FR21 now requires the sheet to show the selected calendar's months, so rebase, carry main'smonthModelinto the shared pane, the pager and the focus hook, and ask for a new/approve-specon the rebased head. - Miss:
DateInputTouch.test.tsx:2632("a trackpad swipe past half a page pages one month") waits 8 ms on real timers against the gesture host's 220 ms trackpad end, so it fails on a loaded runner; drive it with fake timers. - The phone behaviour still lacks the evidence the touch-presentation spec requires: real-device iOS Safari recordings, and Android emulator runs at this head with animations at normal scale and removed plus a slow-device profile.
This pull request lands only when it and #8209 below it are approved.
[Automated review]
| paneStyle, | ||
| }: MonthPaneProps) { | ||
| const locale = useLocale(); | ||
| const {year, month} = fromMonthIndex(monthIndex); |
There was a problem hiding this comment.
Main's MonthScroller pane now lays out monthModel.monthAt(monthIndex) with calendarYearMonthOf, formatCalendarMonthLabel, isInCalendarMonth and formatCalendarDate (DateInput FR21). This pane was extracted before that, so the rebase has to give it monthModel too; otherwise the pager shows Gregorian months under a finger for a Persian or Hebrew calendar.
There was a problem hiding this comment.
Done in the rebased stack: MonthPane, MonthPager and useMonthGridFocus take main's monthModel, and PageUp/PageDown move by the calendar's months (calendarShiftMonths, calendarShiftYears). 00d9d68 adds "pages the keyboard focus by calendar months, and by calendar years with Shift" (Hebrew, across Adar I and II).
| // 40 steps of 6.5 px: 260 px toward the next month. | ||
| for (let i = 0; i < 40; i++) { | ||
| act(() => trackpadScroll(scroller, 6.5)); | ||
| await wait(8); |
There was a problem hiding this comment.
These 8 ms waits run on real timers, and the gesture host ends a horizontal trackpad stream after 220 ms with no wheel (WHEEL_FOLLOW_END_MS). One stall past that ends the swipe short of half a page; this case failed that way once in a four-worker run. vi.useFakeTimers() with vi.advanceTimersByTime(8) keeps it deterministic, as the file already does elsewhere.
There was a problem hiding this comment.
Done in 3704441: both trackpad cases run on fake timers. A real 300 ms stall halfway fails the old case 3 of 3 and leaves the new one green; 1,000 ms of fake time halfway still fails it, so it is not vacuous.
…ove the date like UIDatePicker's Under a finger, turning the month or year wheel behind the sheet calendar's title moves a chosen date to the wheels' month and keeps its day: October 15 becomes May 15, and a day the month lacks becomes its last day (January 31 becomes February 28), inside min and max, by the months of the calendar the sheet shows; DateTimeInput keeps the time. A date dateConstraints refuses is not chosen, and with no date chosen the wheels move only the calendar. With a mouse the wheels move the calendar only, as today. The month wheel does not loop. DateInput FR22 records the rule under a coarse primary pointer, and DateTimeInput FR14 does the same and keeps the time. Each has a verification row.
…n end, not on still frames before a deadline
`openWheels` waited for the sheet, and then for the wheels, with the
harness's `waitForRest`: three still frames within 5 s. On a loaded
runner the page can present no frame for 6 s right after the sheet
opens, so the wait ran out with nothing moving ("still moving", while
the page held no animation). The proof now checks the sheet's open
transform, and then the wheels' full opacity, once a frame with no
deadline of its own, and waits on each animation's `finished` promise.
A starved runner only makes it later.
The comments above both sheets' handleWheelChange keep only the reason: UIDatePicker moves a chosen date with the wheels. The day and bound clamps read from dateInMonth itself, which moves the date by the calendar's own months through calendarShiftMonths.
…nScrollGesture useSheetAxisSplit kept a bottom sheet off the month pager's drags beside useOwnScrollGesture, which does that job for the wheels and the month scroller. Its rule, UIKit's 10 px decision with touch pointers held, is now useOwnScrollGesture's 'pager' mode, and the separate hook goes.
…s pane width uses the shared resize observer Each of MonthPager's Effects now names the system it syncs. Its pane width comes from observeResize instead of its own ResizeObserver, and the owner's callback is read through a ref written in render, with no Effect.
… pager alone MonthPager paged a month after 25 px of horizontal wheel travel, beside usePager's own trackpad pan, so a slow 30 px swipe paged the month. The listener, its constants and their pending measurement go: the pager follows a trackpad's scroll and pages on its release. The Chromium-only wheel test goes too, since Chromium's driven wheels read as a mouse's wheel, which the pager leaves to the page.
MonthPane.tsx now holds the month grid, its day styles and the grid keys that MonthScroller and MonthPager each kept a copy of, in step by a SYNC comment. Each surface passes its own pane style (the scroller's snap, the pager's layer) and whether the pane takes a tab stop. Nothing renders differently.
…cus hook useMonthGridFocus holds the focused day, the grid keys and the focus restore that MonthScroller and MonthPager each kept a copy of. Nothing behaves differently.
The proof read the sheet and the grid with two evaluates per touch move. On a loaded runner that slowed the script, and the fast flick lost the speed that pages it. The page now samples both itself, every frame.
…ads the pager's page `spec:AST-094` FR45, now on main, has motion a tap starts play the theme's duration and easing tokens. An arrow's step plays the shared pager's animated scroll, UIKit's 300 ms sinusoid, which AST-094 FR4 already records as the pager's gap. DateInput's record now names that gap, and the changeset, the story and the browser spec stop promising 0.3 s. The arrow's proof checks that the step travels one month, one way, without fitting the curve. The title read the nearest month from MonthPager's own pane width. It now reads the pager's own page geometry through `nearestPage`.
…nner's timing WebKit stamps an injected touch when it arrives, so on a loaded runner the moves after a stalled dispatch arrive back to back and read as a much faster finger, and a late lift reads as a resting one. Four proofs failed this way. "An arrow tapped right after a release" claims the title's order, so its drag now rests before the lift and releases at no speed: the settle runs by position. The page holds that settle as soon as it runs, so the arrow lands mid-settle on any runner. The sheet split claims who takes the drag, so each of its drags now counts the moves that reach the sheet, which the split keeps from it for the grid's drags. Where the fast 55° drag then rests is read, not asserted, and the 60° drag is checked against it. "The arrow names the month at the tap" holds the step's motion to sample it. Its hold is now armed in the page before the tap, so a busy page holds the step as soon as it runs instead of after it has ended. "A flick released before half a month" lifts right after its last move, at 2500 px/s. WebKit still reads a slower release after a long stall, so there the proof checks the title at the lift, and Chromium, where the script sets each touch's time, also checks that the release pages. The spec's opening waits for the sheet's resting transform, checked once a frame with no deadline of its own, and then for each animation's own `finished` promise, instead of three still frames within 5 s. The two storyboards film a step and a settle. Each now arms its hold in the page before the action, so a busy page holds the motion before it ends.
The grid's PageUp and PageDown move by the active calendar's months, and with Shift by its years. Every paging case so far was Gregorian, so a Gregorian or twelve-month mutant passed them all. Two Hebrew cases pin it: a month back from 1 Nisan 5784 is Adar II, and a year back from Shevat 5785 is Shevat 5784, 13 months back across Adar I. Gregorian month arithmetic fails the first, and twelve calendar months for Shift fail the second. The AR8 verification row cites the case.
The two trackpad cases stepped their wheels on real timers, 8 ms and 40 ms apart. The gesture host ends a trackpad swipe 220 ms after its last wheel, so one runner stall past that ended the fast case's swipe short of half a page, and it read March, not April. Both cases now advance fake timers, which the host's clock, its timers and the events' time stamps all read, so no stall of the runner can end a swipe. A real 300 ms stall halfway turns the old fast case red and leaves the new one green. 1000 ms of fake time halfway still ends the swipe short, and a 205 px slow swipe still pages, so neither case passes vacuously.
There was a problem hiding this comment.
Approval waits on an engineering owner's decision on the record edits, and changes are needed either way. The month pager follows the current DateInput spec (PR2, AR8) and the touch-presentation spec, and after the rebase it pages the active calendar's months and the branch merges with main.
Spec decision needed: the rebase renumbered the two new requirements to component:DateInput FR22 and component:DateTimeInput FR14, with the words of the approved FR20 and FR11, and the earlier /approve-spec names the previous head. Any engineering owner, the author included if they are one, records approval by commenting /approve-spec <full head SHA> on this pull request.
Required changes:
- The branch is 4,065 authored lines without a valid stack, because #8206's head still sits on this pull request's previous head; re-parent #8206 onto this head with the same
Stack: #8209 → #8200 → #8206line, or land #8209 first. - Miss:
DateInputTouch.test.tsx:3160("the month/year toggle leaves the calendar's days alone") spies onuseCalendarDaysthrough../Calendar, butMonthPane.tsximports it from../Calendar/hooks/useCalendarDays, so the spy records no call and the test cannot fail; mock the moduleMonthPaneimports and first check that opening the sheet records calls. - The phone behaviour still lacks the evidence the touch-presentation spec requires: real-device iOS Safari recordings, and Android emulator runs at this head with animations at normal scale and removed plus a slow-device profile.
[Automated review]
| renderAndOpen(); | ||
| vi.mocked(useCalendarDays).mockClear(); | ||
| fireEvent.click(document.querySelector('[data-title="month-year"]')!); | ||
| expect(vi.mocked(useCalendarDays)).not.toHaveBeenCalled(); |
There was a problem hiding this comment.
Miss: this spy never sees a month pane. vi.mock('../Calendar') wraps the Calendar index's useCalendarDays, but MonthPane.tsx imports it from ../Calendar/hooks/useCalendarDays, so a rendered MonthPane records no call and this assertion passes even if every pane re-renders on the toggle. Mock ../Calendar/hooks/useCalendarDays instead, and first assert that opening the sheet records calls.
There was a problem hiding this comment.
Done in 9797905: the spy wraps ../Calendar/hooks/useCalendarDays, and the case first checks that opening the sheet records calls. With MonthPane unmemoized, the old case passed and the new one fails (3 calls).
"the month/year toggle leaves the calendar's days alone" spied on `useCalendarDays` through `../Calendar`, but `MonthPane` imports it from `../Calendar/hooks/useCalendarDays`, so the spy saw no pane and the case could not fail. The spy now wraps that module, and the case first checks that opening the sheet records calls. With `MonthPane` unmemoized, so every pane re-renders on the toggle, the old case still passes and the new one fails (3 calls).
|
/approve-spec 9797905 |
There was a problem hiding this comment.
Changes requested on this stack: #8209 is approved, and #8200 needs the Android evidence the touch-presentation spec requires. A pull request lands only when it and every pull request below it are approved.
#8209
Approved pending CI: no blocking findings; CI has not run on its head yet and runs once a maintainer adds the ci:run label.
#8200
Changes needed:
- The month pager's touch behaviour has no Android run at this head, while
spec:AST-094Platform support and DEC-27 require Chrome with Gboard in the Android emulator at the exact head under review, with animations at normal scale and removed, plus a slow-device profile; the description places that run at the final head, so record it on this pull request at the head that merges.
The engineering owner's iPhone check now covers the real-device iOS requirement. Non-blocking: MonthScroller.tsx keeps a coarse-pointer Reduced Motion dip that can no longer run now that the scroller renders only for a fine pointer.
Whole stack
Fails on the missing Android evidence; otherwise the two pull requests are consistent and each spec edit has an engineering owner's approval at its exact head.
[Automated review]
|
Specs & Decisions agent for Cindy: real-device iOS for this paging is card 35 (passed on Cindy's iPhone at 5025fd7; carried: the calendar-months change is a DateInput FR21 defect fix, verified on the iOS Simulator and in unit tests); Android: Code Quality at the final head. |
Main gained meta#10285, which adds a `getOnlyButton` import beside the testing-library import this pull request widens in DateTimeInputTouch.test.tsx. The merge keeps both imports; this pull request's own changes are unchanged.
Main gained meta#10285, which adds a `getOnlyButton` import beside the testing-library import this pull request widens in DateTimeInputTouch.test.tsx. The merge keeps both imports; this pull request's own changes are unchanged.
This pull request now sits on meta#8209's merge with main, so the stack is tested and merged together. Its own changes are unchanged.
|
/approve-spec c6b74ea |
There was a problem hiding this comment.
Changes requested on this stack; a pull request lands only when it and every pull request below it are approved.
#8209
Approved pending CI: no blocking findings. CI has not run a build or test on this head (the run found no room under the CI ceiling), so a maintainer re-runs it.
#8200
Changes needed:
- The month pager's touch behaviour has no Android run at this head, while
spec:AST-094Platform support and DEC-27 require Chrome with Gboard in the Android emulator at the exact head under review, with animations at normal scale and removed, plus a slow-device profile, so record that run on this pull request at the head that merges.
Non-blocking: MonthScroller.tsx keeps a coarse-pointer Reduced Motion dip that can no longer run, DateInputTouch.test.tsx:194 carries a stray doc comment above beforeAll, and DateInput FR22 does not say whether the moved date is announced.
Whole stack
Fails on the missing Android evidence; otherwise the two pull requests are consistent, and each record edit carries an engineering owner's approval at its exact head.
[Automated review]
Batch: B4 · DateInput calendar month pager
Stack: #8209 → #8200
Depends on #8209. Review only this pull request's change: vjeux/astryx@a98a089...9797905
User need
Under a finger, the sheets' calendar scrolls natively, so a 300 pt flick can cross two months. A mouse keeps the scroller.
Problem and solution fit
Under a finger,
MonthPagerpages the months on the shared pager (usePager) with UIDatePicker's measured values:useOwnScrollGesture's'pager'mode).MonthPane.tsxanduseMonthGridFocus.ts, for the scroller and the pager.Current specification
spec:AST-094FR2, FR17 and FR36 (settled Oct 25).component:DateInputPR2 and AR8 already state the pager and the keys.For the owner: main's
component:DateInputstill says neither is built: AR8's "Implementation gap: PageUp and PageDown do not page by a month…" and PR2's "Implementation gap: under a finger the touch calendar moves through the native month scroller…", with their Current-state bullets. This removes those gap lines, cites the new tests in the two verification rows, and adds MonthPager's markup to the Compatibility/readiness row and Compatibility class. It also adds the Current-state bullet "Arrow step motion": an arrow's step plays the pager's 300 ms sinusoid, not the motionspec:AST-094FR45 asks for, the pager's own gap under FR4. It needs/approve-specat this head.Public delta and caller burden
analyze-pr.js): added here when the build lands.Writing rubric results
Over the removed gap lines, the two verification rows, the Compatibility/readiness row and the Compatibility class: R1 narration, R2 research, R4 rejected alternatives, R5 change references, R6 open questions: none. R3 evidence: test names only.
Scope
Testing
This head, 9797905, has twelve commits on #8209's head a98a089: the earlier head ea7ceae's nine, rebased past #9643/#9842 (see "Changed by the rebase onto #9643/#9842" below), then three test commits: the Hebrew paging case, the trackpad cases on fake timers, and the toggle proof's spy.
spec:AST-094FR45 asks for", which holds under main's FR45 and under the rewrite docs(AST-094, AST-057): motion guidance; gesture springs; swipe-row returns #9915 proposes.useCalendarDaysthrough../Calendar, butMonthPaneimports it from../Calendar/hooks/useCalendarDays, so the case could not fail. It now spies on that module, and first checks that opening the sheet records calls. WithMonthPaneunmemoized, the old case passes and the new one fails with 3 calls (commits 82842b2 and e9c1933, not part of the stack).check:knowledge0;check:changesets0;check:motion-roles0;pnpm -F @astryxdesign/core typecheck0;CI=true pnpm lint0 errors; the DateInput, TimeInput, DateTimeInput, Calendar, utils and hooks unit tests: 3,500 passed;pnpm review:pre0.pnpm install --frozen-lockfile0;MonthPager,MonthScroller,MonthScrollerStepsandMonthYearWheelsagainst Storybook built there: Chromium 23 passed, 2 skipped; WebKit (--cpus=4,LP_NUM_THREADS=4), twice: 48 passed, 2 skipped.Evidence
real-device iOS: card 35, carried; Android: Code Quality at the final head
At this pull request's preview, the deploy of 3704441, whose product code this head keeps (it adds one test commit): iOS 26.2 Simulator, Mobile Safari, iPhone 17 Pro. The preview carries no touch overlay, so each row names its stroke; a stroke reaches the page every 16 ms. I reviewed every frame against the paging rules above and the earlier recordings below; each row gives its largest frame gap during motion. Persian and Hebrew need
Temporal, which this Safari lacks, so the calendar row uses the Japanese calendar; the Hebrew months are the unit test's.Earlier, at 693fafc, against
main; the motion is unchanged since.Changed by the rebase onto #9643/#9842
Main renders each month pane in the active calendar (#9643/#9842). This head keeps that in the shared pane and in month paging:
MonthPanetakes themonthModeland reads its month throughmonthAt,useCalendarDayswith the calendar,formatCalendarMonthLabel,isInCalendarMonthandformatCalendarDate, as main's scroller pane did.monthGridKeyTargetmoves PageUp and PageDown by the calendar's months, and with Shift by its years (calendarShiftMonths,calendarShiftYears): a Hebrew leap year has 13 months.useMonthGridFocusindexes months through the model.DateInputTouch.calendar.test.tsx"pages the keyboard focus by calendar months, and by calendar years with Shift": PageUp from 1 Nisan 5784 lands in Adar II; Shift+PageUp from 10 Shevat 5785 lands on 10 Shevat 5784, 13 months back across Adar I. Gregorian month arithmetic fails the first case, and twelve calendar months for Shift fail the second.Rule-47 fix in this pull request's tests
DateInputTouch.test.tsx's two trackpad cases now run on fake timers: the gesture host ends a trackpad swipe 220 ms after its last wheel, and an 8 ms real-timer step let a runner stall end it early.Review notes
withLayoutAsyncleft abovebeforeAllinDateInputTouch.test.tsx, andMonthScroller's coarse-pointer Reduced Motion dip, which can no longer run now that the pager handles touch.