Skip to content

fix(DateInput, DateTimeInput): the sheet calendar's toggle and day tap under a finger - #8206

Draft
vjeux wants to merge 39 commits into
meta:mainfrom
vjeux:uikit/c22-calendar-motion
Draft

vjeux wants to merge 39 commits into
meta:mainfrom
vjeux:uikit/c22-calendar-motion

Conversation

@vjeux

@vjeux vjeux commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Batch: B4 · DateInput and DateTimeInput calendar toggle and selection

Stack: #8209 → #8200 → #8206

Depends on #8200. Review only this pull request's change: vjeux/astryx@feca481...e4c6e2b

User impact

Under a finger, DateInput's month/year toggle fades linearly with a 180° flip, and DateTimeInput's swaps at once. Now both cross-fade on --duration-medium-min (225 ms in the neutral theme), and the chevron points along the reading direction and turns a quarter. A finger's tap selects a day at once. A mouse keeps the current toggle.

Visual authority

spec:AST-094 FR45: "In a component whose main interaction is a tap", a tap-started motion with a measured duration "plays the theme duration token whose value in the Storybook theme (neutral) is nearest that measurement, with the easing for its kind (entrance, exit or move)"; "an in-place toggle cross-fade is not an exit". The toggle plays --duration-medium-min (225 ms in neutral; UIKit's 250 ms stays the reference), arriving on --ease-entrance, leaving on --ease-exit; the chevron turns on --ease-move. The day-tap rule is a specs decision (FR9).

For the owner: component:DateInput FR24 records the chevron's reading direction, its quarter turn and its Reduce Motion dip, and now its timing under FR45 with the 250 ms reference. component:DateTimeInput FR15 follows it and records Done's focus hand-off; its verification row now also cites the mouse case. FR9 now records the day-tap rule. FR25 records the toggle's tap shield and focus hand-off; DateTimeInput FR15 cites it. All need /approve-spec at this head.

Commit 7, the tab-stop fix, stays here: it changes #8200's MonthPane.tsx and turns this pull request's FR15 test green.

State matrix

  • Both sheets, opening and closing, under a finger.
  • RTL: the chevron is mirrored, ending down.
  • Reduced Motion: under a finger, a 200 ms cross-fade and a chevron dip (playReducedMotionDip) whose turn lands mid-dip; with a mouse, at once.
  • Size (INV6, analyze-pr.js): added here when the build lands.
  • Batch size: 3,468 added lines, 2,297 of them tests; the toggle, the selection and their proofs are one intent.

Writing rubric results

Over component:DateInput FR9, FR24 and FR25, component:DateTimeInput FR15 and their verification rows: R1 narration, R2 research, R4 rejected alternatives, R5 change references, R6 open questions: none. R3 evidence: test names only.

Scope

  • Appearance is the primary intent.
  • Behavior, API, interaction model, and unrelated layout changes were removed or split.
  • The evidence shows the changed pixels actively running, not only source or computed styles.
  • Public text and artifacts contain no internal Meta context.

Testing

This head, e4c6e2b, merges #8200's merge with main 24d845b into the earlier head d84ec6e (see "Changed by the merge with #10231" below), then adds one test commit and the changeset commit.

The pre-merge head d84ec6e sits on #8200's head c6b74ea. It holds the earlier head 664ed1a's twelve commits, rebased past #9643/#9842 (see "Changed by the rebase onto #9643/#9842" below), then two merges with main (one hand edit: DateTimeInputTouch.test.tsx keeps this pull request's testing-library import beside main's getOnlyButton import), then one changeset commit.

  • The pre-merge changeset commit narrowed one line: the wheels' warm-up lays them out once the sheet settles. This head's changeset commit ends it "so a toggle after that does not lay them out": DateInput's panel also flips pointer-events with the toggle. It no longer says the fade shows from near its start; see "The fade on iOS" below.

  • At this head's merge, b1fb87b (the same tree as a712d60): pnpm -F @astryxdesign/core typecheck 0; CI=true pnpm lint 0 errors; Prettier clean over the stack's files; the DateInput and DateTimeInput unit tests: 1,024 passed. At this head: check:changesets 0.

  • Measured on this head's preview (Chromium, a touch pointer, a tap on the title, the neutral theme at its default tempo): every toggle transition runs 225 ms; start to end 217.5–217.7 ms in DateInput and 221.2–221.3 ms in DateTimeInput.

  • MonthYearWheels, MonthPager, MonthYearToggle, MonthScroller and MonthScrollerSteps against Storybook built at de6c245, this product code on main e657e2e: Chromium 44 passed, 2 skipped; WebKit (--cpus=4, LP_NUM_THREADS=4) 43 passed, 3 skipped.

  • The FR45 timing, useFadeInert's red-first case, the toggle spec's waits, the per-pointer day-tap rule and the focus hand-off's two red-first tests are as in their commits; the rebase changed none of them.

Before and after

real-device iOS: card 36's re-feel at d84ec6e is pending with Cindy (her earlier pass of card 36 was at 64c547e, before the timing moved to theme tokens), and this pull request's motion code is unchanged since d84ec6e; Android: Code Quality's DEC-27 set passes at this head (below)

Android, at this head e4c6e2b (Code Quality's DEC-27 set). Chrome 133 with Gboard on the Android 16 emulator, against this head's own deployment (its version.json checked), on the core-dateinput--bottom-sheet-calendar story; the Japanese case is on calendar-system-presentations. Each claim ran at normal speed, at 4× CPU and with the system's Remove animations on.

This pull request's own change, the day tap under a finger: a tap on 18 moved the value from October 15 to October 18, 2026 with exactly one trusted click and no second change, in 6 of 6 takes (two at each setting), and the sheet opened on the first tap in every take.

Claim normal 4× CPU Remove animations
A slow drag of 1/3 of the width springs back, with no page pass 4/4 pass 3/3 pass 2/2
› pages one month per tap pass 4/4 pass 3/3 pass 2/2
A slow drag past half pages one month back pass 4/4 pass 3/3 pass 2/2
A fast flick (150 ms or less, released at 0.8 px/ms or more) pages one month back pass 2/2 — pass 1/1
A mostly-down drag moves only the sheet: the month stays, the sheet stays open pass 4/4 pass 3/3 pass 2/2
Japanese calendar: each swipe pages one month pass 2/2 — —
The day tap selects that day, with at most one click and one change pass 2/2 pass 2/2 pass 2/2

A take counts only when its gesture is valid: the 1/3 drag takes 400 ms or more, and the flick is one 80 ms swipe (150 ms or less from down to up, 60 ms or less from the last move to up). An interleaved flick-back comparison against #8200's head feca481, on the same story and emulator, shows the same threshold on both heads: the month pages when a flick is released at about 0.8 px/ms or more (from the last two pointer moves), and stays below about 0.6 px/ms or when the swipe reaches the page with 0–1 moves (#8200: 6 of 6 at 0.77 px/ms or more paged; #8206: 7 of 7 at 0.95 px/ms or more paged). So the flick row counts only flicks released at 0.8 px/ms or more; one earlier miss on this head, at 0.78 px/ms, sits at that threshold.

At d84ec6e, before the merge with main 24d845b, on the iOS 26.2 Simulator (iPhone 17 Pro, Mobile Safari), against main ddedd4c; a red ring marks the finger:

Path main this PR
DateInput title tap and back
DateTimeInput title tap and back
A finger's day tap

Recorded on the iOS 26.2 simulator and the Android emulator at the earlier head c4d5c04, with UIKit's 0.25 s ease-in-ease-out; this head plays the theme's tokens below.

Path before this PR
Title tap and back
RTL
Reduce Motion
DateTimeInput title tap and back

The fade on iOS. Mobile Safari clocks a transition from the style change, so the toggle's commit flips no inherited property on the panels. Their inert swaps when the fade ends, aria-hidden and focus move with the toggle, and a shield takes touches meanwhile. The hidden wheels are laid out once the sheet settles. The toggle's commit still holds the main thread for about 45 ms on the iOS Simulator, as on main: BottomSheetPanel reads window.innerHeight in the commit, which forces a layout. So the fade's first frame shows it partly done. Share of the change shown in the first frame, on the Simulator at low load, 3 takes each, against main:

Toggle main this PR
DateInput, to the wheels 47–54 % (linear fade) 54–82 %
DateInput, back 27–77 % 16–43 %
DateTimeInput, to the wheels 100 % (swaps at once) 56–64 %
DateTimeInput, back 100 % 39–42 %
First frame after the tap 39–48 ms 37–52 ms

Focus. The toggle's own handler decides the focus hand-off (useFadeInert's followFocus), so focus inside the outgoing panel moves in the toggle's commit; no Effect decides it afterwards. Done hands it to the shown month's tab stop, retrying each frame until the calendar can take focus.

Changed by the merge with #10231

Main's #10231 took DateInput FR22 for the touch sheet's month arrows and gave them a focus hand-off at the range end. This pull request's records renumber again, with their text unchanged: the chevron is FR24 and the tap shield and focus hand-off FR25 (#8209's wheel rule is FR23), and DateTimeInput FR15 cites FR24 and FR25.

In TouchDateField, the hand-off runs through what the toggle keeps. The memoized month arrows take #10231's refs and its focus-handing step, and the month grid's callback, still read through a ref, runs #10231's hand-off on a settled month. The title button takes #10231's ref and this pull request's chevron ref through useMergedRefs. Two tests check the hand-off after a toggle; each fails if the toggle re-renders what it keeps or if the hand-off is lost.

Changed by the rebase onto #9643/#9842

Main took DateInput FR20 and FR21 and DateTimeInput FR11–FR13 (#9643/#9842), so this pull request's records renumber, with their text unchanged. The memoized month/year wheels also take main's monthModel and keptDay.

Rule Was Now
DateInput: the title chevron FR21 FR24
DateInput: the toggle's tap shield and focus hand-off FR22 FR25
DateTimeInput: the chevron and Done's focus hand-off FR12 FR15

@vercel

vercel Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Nov 7, 2026 9:45am UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 24, 2026
@astracat-bot

astracat-bot Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟡 Reviewed (for maintainers only) Nov 7, 2026, 10:26 AM UTC

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

Current run: The current CI run concluded skipped. Current analysis is unavailable.


Generated by PR Enrichment workflow | View current CI run

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering owner's decision. The calendar toggle's timing moves from the theme's motion tokens to UIKit constants under draft AST-094 (FR1, FR4), which would narrow the current theme-tokens architecture (INV3) for touch presentations, and the reading-direction chevron that turns down has no governing spec yet. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request once the records say what is approved; the author may do so as an engineering owner. Whatever is decided, these need changing:

  • Land the stacked predecessors first, so this pull request's compare holds its own 371-line commit instead of 36,310 lines.
  • Make the lint check pass: ESLint runs out of memory on this head but passes on main.
  • Add real-browser evidence for DateTimeInput's new cross-fade and chevron turn and for the RTL chevron (AST-013 FR10), since the browser spec covers only the DateInput story in LTR.
  • Tag .changeset/calendar-toggle-uidatepicker-timing.md [feat] rather than [fix] and name the old chevron, because it changes visual direction (AST-017 FR3).

[Automated review]

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering owner's decision: the calendar toggle's timing moves from the theme's motion tokens to UIKit constants under draft AST-094 (FR1, FR4), which would narrow the current theme-tokens architecture (INV3) for touch presentations, and the reading-direction chevron that turns down has no governing spec yet. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request once the records say what is approved; the author may do so as an engineering owner. Whatever is decided, these still need changing:

  • Land the stacked predecessors first, so this pull request's compare holds its own 371-line commit instead of 36,158 lines.
  • Tag .changeset/calendar-toggle-uidatepicker-timing.md [feat] rather than [fix] and name the old chevron, because it changes visual direction (AST-017 FR3).
  • AST-094 FR7 cites AST-090, which only #8003 proposes, so land that first or qualify the sentence.

[Automated review]

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering owner's decision: the calendar toggle's timing moves from the theme's motion tokens to UIKit constants under draft AST-094 (FR1, FR4), which would narrow the current theme-tokens architecture (INV3) for touch presentations, while the reading-direction chevron and keeping the full 250 ms fade and 90° turn under Reduce Motion (draft FR8) have no governing spec yet. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request once the records say what is approved; the author may do so as an engineering owner. Whatever is decided, these still need changing:

  • Land the stacked predecessors first, so this pull request's compare holds its own 671-line commit instead of 36,863 lines.
  • Tag .changeset/calendar-toggle-uidatepicker-timing.md [feat] rather than [fix] and name the old chevron and the old 0.01 s Reduce Motion timing, because it changes visual direction (AST-017 FR3).
  • AST-094 FR7 cites AST-090, which only #8003 proposes, so land that first or qualify the sentence.

[Automated review]

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering owner's decision: the calendar toggle's timing moves from the theme's motion tokens to UIKit constants under draft AST-094 (FR1, FR4), which would narrow the current theme-tokens architecture (INV3) for touch presentations, while the reading-direction chevron and keeping the full 250 ms fade and 90° turn under Reduce Motion (draft FR8) have no governing spec yet. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request once the records say what is approved; the author may do so as an engineering owner. Whatever is decided, these still need changing:

  • Land the stacked predecessors first, so this pull request's compare holds its own 1,001 lines instead of 37,193.
  • Attach an iOS simulator recording of the CSS fade jumping after a busy commit, or keep the fades as CSS transitions, because moving them into an Effect needs that Mobile Safari evidence (component-style-authoring INV2, AST-013 FR10).
  • Tag .changeset/calendar-toggle-uidatepicker-timing.md [feat] rather than [fix] and name the old chevron and the old 0.01 s Reduce Motion timing (AST-017 FR3).
  • AST-094 FR7 cites AST-090, which only #8003 proposes, so land that first or qualify the sentence.

[Automated review]

vjeux added 10 commits November 5, 2026 02:15
…nd the chevron dips on the shared dip

Done handed focus to the first focusable day of the calendar, a month
mounted off-screen, and in Chromium the calendar was still hidden then, so
focus fell to the page. It now takes the shown month's tab stop, retrying
each frame until the calendar can take focus. Under Reduced Motion the
chevron's dip is playReducedMotionDip, and its turn lands in the dip's
landing callback instead of on a CSS delay.
…nd-off

DateInput FR23 records the title chevron's direction, its quarter turn and
its Reduced Motion dip under a finger. DateTimeInput FR15 follows it, and
records that Done hands focus to the shown month's tab stop.
On a loaded runner the 0.25 s fade could end before the test's hold
reached the page. The page now arms the hold before the tap (armHold),
and the storyboard films what it held.
The mouse calendar gives every mounted month a tab stop, so Done focused the
first mounted month's day, off-screen. The hand-off now takes the tab stop
inside the panel's box. Under a finger the pager has one tab stop, so nothing
changes there. The hand-off uses the shared focusable selector.
…so Done's hand-off costs no render

Done hands focus from the wheels to the shown month's tab stop. The
day's focus handler recorded that day, so React rendered once more after
the toggle's commit. The tab stop already names the day that a recorded
focus would name. So while no day is recorded, its focus now records
nothing.

The test "Done hands focus from the wheels to the calendar in the
toggle's commit" checks it. It fails at the parent (2 commits against 1)
and passes here. Main's useTooltip change (meta#9756) removed an extra
render that hid this one.
…s tokens

`spec:AST-094` FR45 has motion a tap starts play the theme duration
token nearest its platform measurement in the Storybook theme, with the
easing for its kind, and FR1 keeps measured values out of it. Under a
finger the toggle's fades and the chevron's quarter turn played UIKit's
0.25 s ease-in-ease-out through the `timing.stateChangeMs` and
`timing.curves.move` roles.

The toggle now plays `--duration-medium-min`, 225 ms in the Storybook
theme against the measured 250 ms. The wheels and the header's actions
arrive on `--ease-entrance` and leave on `--ease-exit`: a transition
takes the curve of the state it goes to, so the hidden styles carry the
exit curve. The chevron's turn takes `--ease-move`. A unit test holds
the token to the nearest of neutral's durations, and the browser specs
read the tokens from the page. DateInput FR23, two browser test names
and the changeset follow; Reduced Motion's cross-fade and the chevron's
dip stay.
…ds its cross-fade

The panels swap `inert` when the cross-fade ends, on either panel's own
transition end. Once the sheet settles, the wheels' warm-up turns their
`visibility` on, on the toggle's duration. A toggle soon after it saw
that transition end mid-fade: the shield came off and the panels swapped
`inert` while they still faded. The hook now counts only the transitions
that run after the toggle (`transitionrun`), and their ends end the
fade.

A cancel whose property runs again at once is a replacement, not an end,
so the replacement's own end ends the fade.
…warm-up to end

The toggle spec's opening waited for the sheet and the warmed-up wheels
with `waitForRest`, which needs three still frames within 5 s. A starved
runner can present one frame in seconds, so the wait failed with "still
moving" while nothing moved. It now waits for each one's resting value,
checked once a frame with no deadline of its own, and then for each
animation's own `finished` promise, as the month and year wheels' spec
does.
… keeps the fade, in any presentation

The owner ruled on the day-tap fade per pointer: a finger's tapped day
selects at once, as UIDatePicker's does and as the owner felt it on a
device; a mouse or pen selection keeps main's fade, in any presentation.
In either presentation the last press's pointer decides the fade, so a
trackpad click or a stylus tap in the pager keeps it and a finger's tap
in the scroller drops it. Before any press, as for a keyboard pick, the
presentation's own default holds. DateInput FR9 records the rule. Unit
cases press with each pointer type in both presentations, and browser
cases tap with a finger, pick with a pen in the touch sheet and click
with a mouse.
DateInput FR24 states what the month/year toggle does under a finger:
no tap reaches either panel while it cross-fades, the actions that leave
with the toggle stop taking taps at once, and the incoming ones take
taps when the outgoing panel's fade ends. It also states the focus
hand-off: when the title or Done toggles while focus is inside the
outgoing panel, focus moves into the incoming one. DateTimeInput FR15
points its toggle at FR24.

Two tests complete FR24's evidence: DateInput's Done and DateTimeInput's
title hand focus to the incoming panel in the toggle's commit. Both fail
on the parent pull request's head.

The changeset scopes the duration token to the neutral theme, where it
is the token nearest iOS's 0.25 s.
@cixzhang

cixzhang commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 664ed1a

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested on this stack: #8209 is approved, and #8200 and #8206 each need the phone evidence the touch-presentation spec requires. A pull request lands only when it and every pull request below it are approved.

#8209

Approved; no blocking findings.

#8200

Changes needed:

  • The month pager's touch behaviour is shown only on the iOS simulator and in Android emulator runs from earlier heads, but spec:AST-094 Platform support and DEC-27 require real-device iOS Safari evidence and Chrome with Gboard in the Android emulator at this head, with animations at normal scale and removed, plus a slow-device profile.

#8206

Changes needed:

  • Miss: the toggle's Mobile Safari claims (.changeset/calendar-toggle-uidatepicker-timing.md line 8, "the fade shows from near its start", and the description's first-frame table) rest on the iOS simulator at an earlier head, while spec:AST-094 requires real-device iOS Safari evidence and Android emulator runs at this head, which the description notes are still requested.

Whole stack

Fails on the same missing phone evidence. Otherwise the three pull requests are consistent, every spec edit has an engineering owner's approval at its exact head, and no code defect was found.

[Automated review]

vjeux added 5 commits November 6, 2026 08:53
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.
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#8200's merge with main, so the stack
is tested and merged together. Its 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.
@cixzhang

cixzhang commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

/approve-spec a712d60

@astracat-bot astracat-bot Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested. The spec edits carry an engineering owner's approval at this head; three things still need fixing:

  • Regression: #8209's and #8200's bodies declare Stack: #8209 → #8200 while this one declares Stack: #8209 → #8200 → #8206, so this pull request is reviewed on its own and its 7,673-line compare has no size exemption; put the identical three-PR Stack: line in #8209's and #8200's bodies.
  • Miss: the toggle's Mobile Safari claim (.changeset/calendar-toggle-uidatepicker-timing.md line 8) needs the real-device iOS result the description only names as "card 36" (device, head and outcome) and Android emulator runs at this head (animations at normal scale and removed, plus a slow-device profile), which the touch-presentation spec requires and the description defers to the final head.
  • Miss: the pager's touch claims (.changeset/calendar-pages-like-uidatepicker.md) have the owner's real-device iOS check but no Android emulator runs at this head either.

CI has not run on this draft head. Optional: the comment "Under a finger the fade plays the toggle's tokens" repeats above four style blocks in TouchDateField.tsx; one copy beside TOGGLE_DURATION keeps the reason.

[Automated review]

'@astryxdesign/core': patch
---

[fix] Under a finger, the calendar in the DateInput and DateTimeInput bottom sheets now pages its months like the iOS date picker:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Miss: this tells consumers the touch calendar pages like the iOS date picker (one month per swipe, the 10 px sheet split, the trackpad pan), but the description shows no real-device iOS Safari evidence and no Android emulator run at this head. spec:AST-094 Platform support and DEC-27 ask for real-device evidence for every iOS Safari claim and, for Android Chrome, Chrome with Gboard in the Android emulator at the exact head, with animations at normal scale and removed, plus a slow-device profile.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Route: real-device iOS for this paging is card 35, carried (the specs comment on #8200), and Android is Code Quality at the final head. This changeset is #8200's: #8209 and #8200 merge first, then this pull request redeclares the three-PR stack, so until then its compare carries their files.

The note said the warm-up makes the fade show from near its start. On
the iOS Simulator at this head it does not: the toggle's commit holds
the main thread for about 45 ms, as it does on main, and Mobile Safari
clocks the fade from the style change, so its first frame shows it
54-82 % done. The note now says only what the warm-up does: the wheels
are laid out once the sheet settles, so a toggle after that only
changes their opacity.
@cixzhang

cixzhang commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

/approve-spec d84ec6e

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested. The spec edits carry an engineering owner's approval at this head; three things still need fixing:

  • Regression: #8209's and #8200's bodies declare Stack: #8209 → #8200 while this one declares Stack: #8209 → #8200 → #8206, so this pull request is reviewed on its own and its 7,673-line compare has no size exemption; put the identical three-PR Stack: line in #8209's and #8200's bodies.
  • Miss: the toggle still lacks the phone evidence spec:AST-094 asks for (Platform support, DEC-27): the description's iOS table (9–23 % of the fade lost before its first frame) contradicts the 54–82 % the newest commit measures at this head, card 36's real-device result is not stated, and there are no Android emulator runs at this head (animations at normal scale and removed, plus a slow-device profile).
  • Miss: the pager's touch claims (.changeset/calendar-pages-like-uidatepicker.md) have the owner's real-device iOS check but no Android emulator runs at this head either.

CI has not run on this draft head. Optional: the comment "Under a finger the fade plays the toggle's tokens" repeats above four style blocks in TouchDateField.tsx, and DateInput's wheels panel still flips pointer-events on each toggle, so the new "only changes their opacity" line is broader than the code.

[Automated review]

'@astryxdesign/core': patch
---

[feat] Under a finger, the calendar in the DateInput and DateTimeInput bottom sheets now toggles to its month and year wheels like the iOS date picker:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Miss: these touch claims still have no Android emulator run at this head, and the description's iOS table (9–23 % of the fade lost before its first frame) contradicts the 54–82 % the newest commit measures here, with card 36's real-device result unstated. spec:AST-094 Platform support and DEC-27 ask for real-device iOS evidence and, for Android Chrome, Chrome with Gboard in the emulator at the exact head, with animations at normal scale and removed, plus a slow-device profile.

vjeux added 6 commits November 7, 2026 01:12
Main gained meta#10231, which adds DateInput FR22 for the touch sheet's
month arrows. This pull request's month/year wheel requirement moves
from FR22 to FR23, with its verification row, the Bottom-sheet
calendar row, the scope line and DateTimeInput FR14's two citations.
Only the numbers change; this pull request's own changes are otherwise
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.
Under a primary finger the calendar is now MonthPager, which a scroll
event does not move, so meta#10231's swipe hand-off test never reached the
range end. It runs as the other native-scroller tests here do: on a
touchscreen laptop with the sheet pinned. MonthPager reports its
settled month to the same callback.

meta#10386 has an armed hold name the motion it judges. The pager's four
holds judge the track's translate, which a step and a settle move.
This pull request now sits on meta#8200's merge with main, so the stack
is tested and merged together.

Main gained meta#10231. It adds DateInput FR22 for the touch sheet's month
arrows, so this pull request's chevron and toggle requirements move
from FR23 and FR24 to FR24 and FR25, after the wheels' FR23: their
verification rows, the Bottom-sheet calendar row and DateTimeInput
FR15's citations follow. Only the numbers change.

meta#10231 also gives the month arrows a focus hand-off at the range end.
The merge keeps it inside this pull request's memoized arrows (their
refs and stepMonthFromArrow), and a swipe hands focus on through the
month grid's callback, which still reads the wheels' state through a
ref, so the toggle leaves it unchanged. The title button takes main's
ref for that hand-off and this pull request's chevron ref through
useMergedRefs.
meta#10231 moves focus off a month arrow that hides at the range end. Two
tests check that the hand-off still runs through what the toggle keeps:

- the arrows, which the toggle does not re-render: a press after the
  toggle still moves focus to the other arrow;
- the month grid's callback, which the toggle leaves unchanged, so the
  memoized pager does not re-render: a month the pager settles on
  after the toggle still moves focus the same way.

Each test fails if the toggle re-renders what it keeps, or if the
hand-off is lost.

meta#10386 has an armed hold name the motion it judges. The toggle
storyboard's hold judges the wheels' opacity, which the fade moves.
DateInput's panel also flips pointer-events with the toggle, so a
toggle after the warm-up changes more than the wheels' opacity. The
line now says what the warm-up spares the toggle: laying the wheels
out.
@cixzhang

cixzhang commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

/approve-spec e4c6e2b

@astracat-bot astracat-bot Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested. The spec edits carry an engineering owner's approval at this head; three things still need fixing:

  • Regression: #8209's and #8200's bodies declare Stack: #8209 → #8200 while this one declares Stack: #8209 → #8200 → #8206, so this pull request is reviewed on its own and its 7,753-line compare has no size exemption; put the identical three-PR Stack: line in #8209's and #8200's bodies.
  • Miss: the toggle's touch claims (.changeset/calendar-toggle-uidatepicker-timing.md) still lack the phone evidence spec:AST-094 asks for (Platform support, DEC-27): the real-device iOS check is named without an outcome, and there are no Android emulator runs at this head (animations at normal scale and removed, plus a slow-device profile).
  • Miss: the pager's touch claims (.changeset/calendar-pages-like-uidatepicker.md) have no Android emulator runs at this head either.

CI has not run on this draft head. Optional: rename the browser test "the toggle's commit flips no inherited property on the panels", or drop the pointer-events flip on DateInput's wheels panel that it misses, and keep one copy of the repeated "Under a finger the fade plays the toggle's tokens" comment.

[Automated review]

This branch was successfully deployed

1 active deployment
Preview — e4c6e2bf Deployed Nov 7, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants