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📚 Storybook Preview🧪 Sandbox PreviewModified ComponentsDateInput (@astryxdesign/core) · View in Storybook
DateTimeInput (@astryxdesign/core) · View in Storybook
TimeInput (@astryxdesign/core) · View in Storybook
Component Size
Sizes are gzip. Import counts the JavaScript the import loads eagerly; CSS counts the package stylesheet rules referenced by the modules it can load from its own package, lazily loaded ones included.
|
| Component | JavaScript | CSS |
|---|---|---|
| core/DateInput | +46.9KB |
+355B |
| core/DateTimeInput | +49.2KB |
+444B |
| core/PowerSearch | +48.5KB |
+384B |
| core/TimeInput | +29.7KB |
+19B |
Bundle Size Summary
Gzip figures measure each package's entry file, not the code an import pulls in.
| Package | Entry (ESM) | Entry gzip before | Entry gzip after | Delta |
|---|---|---|---|---|
| @astryxdesign/core | 4.9KB | 1.2KB | 1.2KB | 0B |
| Package stylesheet | Gzip before | Gzip after | Delta |
|---|---|---|---|
| @astryxdesign/core | 34.6KB | 34.9KB | +337B |
Accessibility Audit
Status: No accessibility violations detected.
Visual Regression
55 of 502 shot(s) changed.
A change here is a question, not a failure: check whether the after is the
picture you intended. Record that review on the PR. Baseline maintenance is an
explicit dispatch of CI; this report never rewrites the baseline or adds a release gate.
| component | story | theme | mode | pixels |
|---|---|---|---|---|
| Selector | Indicator Space Bottom Sheet Narrow End RTL | neutral | light | 753,933 |
| Selector | Indicator Space Bottom Sheet Wide Start | neutral | light | 740,072 |
| RichTextEditor | Markdown parity: side by side | probe | dark | 558,840 |
| RichTextEditor | Markdown parity: side by side | probe | light | 540,756 |
| Chat | Full AI Chat | probe | light | 230,823 |
| Chat | Full AI Chat | probe | dark | 229,805 |
| AppShell | With Mobile Nav | probe | light | 217,010 |
| AppShell | With Mobile Nav | probe | dark | 216,960 |
| Collapsible | Dividers | probe | dark | 66,445 |
| Collapsible | Dividers | probe | light | 66,445 |
| AppShell | Playground | neutral | dark | 65,198 |
| AppShell | Playground | neutral | light | 63,788 |
| Chat | Default | neutral | dark | 36,304 |
| Chat | Default | neutral | light | 35,767 |
| Chat | Empty State | probe | light | 23,531 |
| Chat | Empty State | probe | dark | 22,622 |
| ChatAutoScroll | Scroll Behavior Comparison | neutral | dark | 15,378 |
| ChatAutoScroll | Scroll Behavior Comparison | neutral | light | 14,107 |
| Chat | With Attachments | probe | light | 13,406 |
| Chat | With Attachments | probe | dark | 11,232 |
and 35 more.
Generated by PR Enrichment workflow | Storybook | Sandbox | View full report
There was a problem hiding this comment.
This review is on hold for a spec decision: whether the month and year wheels in the DateInput and DateTimeInput bottom sheets should change the chosen date, as iOS's inline date picker does, has no approved spec yet (component:DateInput and component:DateTimeInput are draft, and the pull request marks it as pending owner review), and the new draft spec:AST-094 would also amend the current spec:AST-025 FR14 and design:user-states DR1. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request, and the author may do so if they are an engineering owner. Independently of that decision, these changes are needed before approval:
- Reduce this pull request's diff to its own commit: it currently carries the whole stack, about 36,700 changed lines, so land the predecessors first or base the branch on #8206.
- In DateTimeInput, the stepped time wheels round 23:59 to 12:00 AM without moving the date, so a turn of the minute wheel commits a time about 23 hours earlier on the same day.
spec:AST-094FR7 citesspec:AST-090, which does not exist in the repository, and the newdateConstraintsrefusal on the wheel path has no test.
[Automated review]
| } | ||
| const minutes = time.hour * 60 + time.minute + time.second / 60; | ||
| const rounded = Math.round(minutes / interval) * interval; | ||
| return partsOf(rounded * 60); |
There was a problem hiding this comment.
In DateTimeInput this wrap drops a day: with timeIncrement={15}, a value of 2026-03-21T23:59 shows 12:00 AM, and turning the minute wheel to :45 commits 2026-03-21T00:45, because commitWheelTime keeps the date. Rounding down near midnight in the DateTimeInput sheet, or carrying the rounding into the date, avoids it; a test at 23:59 with a 15-minute step would pin it.
| 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.
spec:AST-090 does not exist at this head or on main, so the departure this requirement asks owners to accept cannot be checked. Drop the reference, or cite the record where it lives.
There was a problem hiding this comment.
This branch no longer edits the AST-094 record (#8378 on main carries it).
| min != null ? plainDateFromISO(min) : null, | ||
| max != null ? plainDateFromISO(max) : null, | ||
| ); | ||
| if (!plainDateIsEqual(moved, selectedDate) && !isDateDisabled(moved)) { |
There was a problem hiding this comment.
This refusal branch has no test in either sheet (TouchDateTimeField.tsx:834 too). A test where dateConstraints refuses the moved date, asserting that onChange is not called while the calendar still moves, would protect it.
There was a problem hiding this comment.
Added: both sheets test a refused date (May 21); head 0c6ff10.
ba61d2a to
e8f8953
Compare
There was a problem hiding this comment.
This review is on hold for a spec decision: whether the month and year wheels in the DateInput and DateTimeInput bottom sheets should change the chosen date, as iOS's inline date picker does, has no approved spec yet (component:DateInput and component:DateTimeInput are draft), and the new draft spec:AST-094 would also amend the current spec:AST-025 FR14 and design:user-states DR1. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request, and the author may do so if they are an engineering owner. Independently of that decision, these changes are needed before approval:
- Reduce this pull request's diff to its own commit: it still carries the whole stack, about 36,500 changed lines, so land the predecessors first or base the branch on #8206.
- In DateTimeInput, the stepped time wheels round 23:59 to 12:00 AM without moving the date, so a turn of the minute wheel commits a time about 23 hours earlier on the same day.
spec:AST-094FR7 citesspec:AST-090, which does not exist in the repository, and the newdateConstraintsrefusal on the wheel path has no test.
[Automated review]
| } | ||
| const minutes = time.hour * 60 + time.minute + time.second / 60; | ||
| const rounded = Math.round(minutes / interval) * interval; | ||
| return partsOf(rounded * 60); |
There was a problem hiding this comment.
In DateTimeInput this wrap drops a day: with timeIncrement={15}, a value of 2026-03-21T23:59 shows 12:00 AM, and turning the minute wheel to :45 commits 2026-03-21T00:45, because commitWheelTime keeps the date. Rounding down near midnight in the DateTimeInput sheet, or carrying the rounding into the date, avoids it; a test at 23:59 with a 15-minute step would pin it.
| 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.
spec:AST-090 does not exist at this head or on main, so the departure this requirement asks owners to accept cannot be checked. Drop the reference, or cite the record where it lives.
There was a problem hiding this comment.
This branch no longer edits the AST-094 record.
| min != null ? plainDateFromISO(min) : null, | ||
| max != null ? plainDateFromISO(max) : null, | ||
| ); | ||
| if (!plainDateIsEqual(moved, selectedDate) && !isDateDisabled(moved)) { |
There was a problem hiding this comment.
This refusal branch has no test in either sheet (TouchDateTimeField.tsx:834 too). A test where dateConstraints refuses the moved date, asserting that onChange is not called while the calendar still moves, would protect it.
There was a problem hiding this comment.
Added: both sheets test a refused date; head 0c6ff10.
|
|
||
| useEffect(() => { | ||
| if (index != null && index !== pager.index) { | ||
| pager.goTo(index, {reason: 'controlled'}); |
There was a problem hiding this comment.
goTo reports synchronously through the caller's onIndexChange, so this Effect echoes a controlled move back to the owner, the Effect-driven callback the React runtime rules forbid, and its comment names no system it synchronizes. No caller passes index yet; skipping the report for a controlled move, or dropping the unused path, keeps it from biting later.
e8f8953 to
4f517fd
Compare
4f517fd to
a05d1b1
Compare
There was a problem hiding this comment.
This review is on hold for a spec decision: whether the month and year wheels in the DateInput and DateTimeInput bottom sheets should change the chosen date, as iOS's inline date picker does, has no approved spec yet (component:DateInput and component:DateTimeInput are draft), and draft spec:AST-094 in this range would also amend the current spec:AST-025 FR14 and design:user-states DR1. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request, and the author may do so if they are an engineering owner. Independently of that decision, these changes are needed before approval:
- Reduce this pull request's diff to its own commit: it still carries the whole stack, about 37,200 changed lines, so land the predecessors first or base the branch on #8206.
- In DateTimeInput, the stepped time wheels round 23:59 to 12:00 AM without moving the date, so a turn of the minute wheel commits a time about 23 hours earlier on the same day.
spec:AST-094FR7 citesspec:AST-090, which does not exist in the repository, and thedateConstraintsrefusal on the new wheel path has no test in either sheet.
[Automated review]
| return hasSeconds ? time : {...time, second: 0}; | ||
| } | ||
| const minutes = time.hour * 60 + time.minute + time.second / 60; | ||
| const rounded = Math.round(minutes / interval) * interval; |
There was a problem hiding this comment.
In DateTimeInput this wrap drops a day: with timeIncrement={15}, a value of 2026-03-21T23:59 shows 12:00 AM, and turning the minute wheel to :45 commits 2026-03-21T00:45, because restOn turns from the shown time and commitWheelTime keeps the date (TouchDateTimeField.tsx:832-844). Rounding down at the end of the day, or carrying the rounding into the date, avoids it; a test at 23:59 with a 15-minute step would pin it.
| 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.
spec:AST-090 does not exist at this head or on main, so the departure this requirement asks owners to accept cannot be checked. Drop the reference, or cite the record where it lives once it lands (the current-state impact at lines 234-236 names it too).
| min != null ? plainDateFromISO(min) : null, | ||
| max != null ? plainDateFromISO(max) : null, | ||
| ); | ||
| if (!plainDateIsEqual(moved, selectedDate) && !isDateDisabled(moved)) { |
There was a problem hiding this comment.
This refusal branch has no test in either sheet (TouchDateTimeField.tsx:825 too). A test where dateConstraints refuses the moved date, asserting that onChange is not called while the calendar still moves, would cover the promise that a refused date never reaches the caller.
There was a problem hiding this comment.
Added in 278a61a: both sheets have a test where dateConstraints refuses the moved date (May 21). The date stays unchosen while the calendar moves.
| useEffect(() => { | ||
| if (index != null && index !== pager.index) { | ||
| pager.goTo(index, {reason: 'controlled'}); | ||
| } | ||
| }, [pager, index]); |
There was a problem hiding this comment.
goTo reports synchronously through the caller's onIndexChange, so this Effect echoes a controlled move back to the owner, the Effect-driven callback the React component runtime contract rules out, and its comment names no external system. Naming the pager engine and skipping the report for a controlled move, or dropping the unused controlled path, would fix it.
a05d1b1 to
246ee17
Compare
There was a problem hiding this comment.
This pull request is on hold for a spec decision: no approved spec says whether the month and year wheels in the DateInput and DateTimeInput bottom sheets should change the chosen date (component:DateInput and component:DateTimeInput are draft), and the draft spec:AST-094 carried in this range would also amend current scrolling and press-state specs. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request, and the author may do so if they are an engineering owner. Independently of that decision, these changes are needed before approval:
- Reduce the diff to this pull request's own commit: it still carries the whole stack, about 37,500 changed lines, so land the predecessors first or base the branch on #8206.
- In the DateTimeInput sheet, a stepped minute wheel rounds 23:59 to 12:00 AM without moving the date, so turning it commits a time about 23 hours earlier on the same day (
timeWheelRules.ts,TouchDateTimeField.tsx). spec:AST-094FR7 citesspec:AST-090, which does not exist; thedateConstraintsrefusal on the new wheel path has no test in either sheet; andusePager's controlled-index Effect callsonIndexChangefrom an Effect.
[Automated review]
246ee17 to
278a61a
Compare
…nto uikit/c21-wheel-short-loop
…nto uikit/c21-wheel-rest-and-spin
…o their own changesets In the same release meta#8179's time columns loop, so "no shipped column loops yet" would contradict it; the columns that loop say so themselves.
…heirs) into uikit/c21-wheel-rest-and-spin
… while the toggle fades The header's arrows and Reset, and DateInput's footer actions, sit outside the shield that covers the panels during the month/year cross-fade, and their `inert` followed the panels' (deferred to the fade's end). During the opening fade a tap on Done fell through the still-inert Done to Save beneath it and closed the DateInput sheet, and DateTimeInput's fading arrows and Reset still paged the month or cleared the pick. These few controls now leave with the toggle and arrive with the fade's end; only the panels' own `inert` waits for the fade, since flipping it restyles a panel's whole subtree.
… the glyph is Under Reduce Motion on a touch screen, a second title tap within the 200 ms dip restarted it from opacity 1, flashing the chevron back to opaque. The new dip now starts from the running dip's presented opacity, read before it is cancelled (a style read only in that case).
…llows the toggle during render `useFadeInert` mirrored the toggle into state from a layout effect when the swap is not deferred, costing a second commit per toggle (architecture:react-component-runtime INV1, INV3). `settled` now follows `isWheelOpen` during render in that case; the effect keeps only the branch where the committed panel shows no exit can run (no Web Animations), with a reason naming that read.
…fect synchronizes with The effect waits on the browser's clock and idle time (a timer for the sheet's present motion, then an idle callback), and its cleanup cools the wheels for the next opening (architecture:react-component-runtime INV3).
…ged, and where it was measured The panels' `inert` swaps when the fade ends (not a frame later), the commit's restyle is described without claiming it changes no inherited style, the old chevron and the 0.01 s fade are DateInput's, and the iPhone and Android claims are narrowed to the iOS simulator measurement.
…s own spin meta#8527's `spinTo` no longer takes a duration or a curve, so a column the time wheels move by themselves turns on the wheel's own spin: an animated `setContentOffset`, 0.3 s on Core Animation's ease-in-ease-out (`picker.tapSpin`, the role `timing.curves.move`), resolved under the column when the turn starts (spec:AST-094 FR4). TimeWheels no longer plays the literal `datePicker.wheels.columnTurn`, and the browser proof samples the AM/PM column's turn against that spin.
…he wheel's own spin meta#8527's `spinTo` no longer takes a duration or a curve: the month wheel turns onto the nearest reachable month on the wheel's own spin (`picker.tapSpin` on the role `timing.curves.move`, UIKit's animated `setContentOffset`), resolved when the turn starts (spec:AST-094 FR4), not on the literal `datePicker.wheels.columnTurn`.
…he nearest enabled month around the seam With min 2025-11-01, max 2026-02-28 and January 25, 2026 chosen, one ArrowUp from January crosses the seam onto December 2026, past max; around the loop the nearest enabled month is January itself, so nothing moves or commits. It went to February 25 before meta#8527's seam-aware rest and key step (f4386c5).
There was a problem hiding this comment.
This pull request is on hold for an engineering owner's decision on four draft spec rules it writes, which no current spec or owner comment states: component:DateInput PR2's month pager reporting the visible month once per half-month crossed, AR8's Shift+PageUp/Shift+PageDown moving the calendar by a year, FR13's rule that a wheel resting back on its committed out-of-range row commits nothing, and FR13's (and component:DateTimeInput FR8's) rule that a shown wheel turns onto a value changed from outside instead of jumping. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request, and the author may do so as an engineering owner, or the text can leave with the pull requests it comes from. Independently, the diff against main is 50,072 authored lines around this pull request's own 634-line change, so the predecessor pull requests need to land first and the branch rebased before it can be approved. The month and year wheels' date change itself is settled under spec:AST-094 DEC-1, and the looping month wheel now keeps the nearest enabled month across its seam when min and max cut the year.
[Automated review]
| | FR10 | Standalone mode MUST compose Field; admitted InputGroup mode MUST remove competing Field chrome while preserving name, description, value, keyboard, focus, and editing semantics. | `family:input-fields/FR3`; current source and InputGroup tests | Settled shared rule and verified adoption | | ||
| | FR11 | Clear MUST emit `undefined` through the ordinary change pipeline. The pointer and bottom-sheet surfaces restore field focus using their shipped timing; the native surface MUST NOT reclaim focus because doing so reopens the OS picker. Implementation gap: when the field becomes disabled or busy while its clear control holds focus, the control unmounts and focus falls to the document body; `spec:AST-085/FR4` requires focus to stay or move to a destination this record names. | Current source and focused clear tests; `spec:AST-085/FR4` | Verified shipped behavior | | ||
| | FR12 | No surface renders native `disabled`. A disabled field MUST stay focusable with `aria-disabled`, block typing, picking, clearing, and opening, describe its disabled reason when one is given, and take disabled paint. While busy (`isLoading` or a pending Action) the pointer and bottom-sheet surfaces expose `aria-disabled` and `aria-busy`, stay focusable, and block new commits; the native surface does the same for `isLoading`, and during a pending Action stays editable so the OS picker remains attached but rejects additional commits until the Action settles. A busy field that is not disabled keeps its ordinary paint and Spinner, shows no hover ring while commits are blocked, and keeps its keyboard focus ring. | `spec:AST-085/FR1–FR6`; `family:input-fields/FR4–FR6`; `family:buttons/FR4`; current source and focused tests | Settled shared rule and verified adoption | | ||
| | FR13 | A bottom-sheet picker wheel that comes to rest on a disabled row (outside `min`/`max`) MUST continue to the nearest enabled row, a tie going toward the committed row, and select it there. A wheel resting on its committed row MUST NOT select or commit, even when that row is outside the bounds, so opening a bounded sheet never changes an untouched value: a committed value outside the bounds stays, and an empty field stays empty. A shown wheel whose value changes from outside, as when a bound clamps the time after another wheel turned, MUST turn onto the new row rather than jump to it. | DEC-1; UIDatePicker on the iOS 26.2 simulator; wheel unit and real-browser tests | Settled by DEC-1 | |
There was a problem hiding this comment.
Two clauses here go beyond the rest decision recorded for the picker wheels (a wheel at rest on a disabled row continues to the nearest allowed row; opening a bounded sheet never changes an untouched value): a committed out-of-range row that a drag rests back on commits nothing, and a shown wheel turns onto a value changed from outside instead of jumping. In this draft record they are proposals, so an engineering owner needs to approve or reject them, for example with /approve-spec <full head SHA>.
| On the month pager under a finger, a drag moves the month grid without a render, and the | ||
| visible month is reported once per half-month crossed, during the drag and the settle | ||
| that ends it. |
There was a problem hiding this comment.
This adds a requirement no current record states: on the month pager under a finger, the visible month is reported once per half-month crossed, during the drag and the settle that ends it. component:DateInput is draft, so an engineering owner needs to approve it (for example with /approve-spec <full head SHA>), or it can leave with the calendar-pager pull request it comes from.
| picks the focused day. Named exception: Shift+PageUp and Shift+PageDown move | ||
| by a year, as in the APG date picker dialog. |
There was a problem hiding this comment.
Shift+PageUp and Shift+PageDown by a year is an extra beyond the APG grid adoption rule, which spec:AST-020 FR15 asks the owning record to name as a named exception. While this record is draft the exception is proposed, not adopted, so it needs an engineering owner's approval.
| | FR5 | The two pointer segments share one row while each retains its intrinsic basis; when the container is narrower, flex wrapping moves them into separate full-width rows. | Public docs, current source, focused layout tests | Verify rendered geometry; class-level behavior covered | | ||
| | FR6 | Date-time bounds and date constraints MUST prevent invalid commits. Native controls MAY receive platform hints, but JavaScript validation remains the final commit boundary; calendar-only options MAY be unavailable on native surfaces. | Public docs, current source, focused presentation tests | Verified observation; owner approval pending | | ||
| | FR7 | A preset-time listbox MUST remain optional, preserve typed entry, expose one selected option independently from keyboard highlight, and limit offered values to the selected date's effective minimum and maximum. | Public docs, current source, focused interaction tests | Verified observation; owner approval pending | | ||
| | FR8 | Its bottom-sheet date and time wheels rest as `component:DateInput/FR13` requires: a wheel stopping on a disabled row continues to the nearest enabled row and selects it, opening a bounded sheet never changes an untouched value, and a shown wheel turns onto a value a bound clamps. | `component:DateInput/DEC-1`; wheel unit tests | Settled by `component:DateInput/DEC-1` | |
There was a problem hiding this comment.
The last clause (a shown wheel turns onto a value a bound clamps) repeats component:DateInput FR13's turn rule, which no owner decision or current record states yet; it waits on the same engineering-owner decision.
…names what it synchronizes The un-keyed layout effect that lands a far jump synchronizes the pager's position with the DOM: it can move only once the render that mounts the target's pane has committed it, and moves before paint (architecture:react-component-runtime INV3).
There was a problem hiding this comment.
This pull request stays on hold for an engineering owner's decision on four draft spec rules it writes that no current spec or owner decision states: component:DateInput PR2 (the month pager reports the visible month once per half-month crossed), AR8's Shift+PageUp/Shift+PageDown year step, and FR13's clauses that a rest back on a committed out-of-range row commits nothing and that a shown wheel turns onto a value changed from outside (repeated in component:DateTimeInput FR8). An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request, and the author may do so as an engineering owner, or the text can leave with the pull requests it comes from. Independently, the diff against main is 50,075 authored lines around this pull request's own 634-line change, so the predecessor pull requests need to land and the branch be rebased before it can be approved. The latest commit only documents what the month pager's layout Effect synchronizes and raises no new issue.
[Automated review]
Depends on #8206 and #8162. Review only this PR's change: vjeux/astryx@c4d5c04...46e8eae
User need
Under a finger, the DateInput and DateTimeInput sheets' calendar title opens month and year wheels. Today they only move the calendar: after turning to May the user still has to tap a day. UIDatePicker's inline calendar moves the date itself (measured for #8178). One touch model (
spec:AST-094FR13); a mouse keeps today's wheels.Evidence
Recorded on the iOS 26.2 simulator and the Android emulator (Chromium 158) from these heads; Overlays: JS clock, Reduce Motion, finger. No real device was available to the test rig. Before: #8206 + #8162.
minNovember 1, 2025Before: the month list ends at December, so both taps land past it; the year moves only the calendar, to November 2025, the field at October 15. This PR: October to February across the December/January loop, then May, the field reading May 15, 2026; the year moves the date to November 15, 2025, the month wheel turning onto November.
Problem and solution fit
minandmax; DateTimeInput keeps the time. With no date chosen, or onedateConstraintsrefuses, the wheels only move the calendar.Current specification
Settled (cixzhang, Oct 25):
spec:AST-094DEC-1, with FR11 and FR14 amending DR1, andspec:AST-025FR14 (the wheels commit live).spec:AST-094FR1, FR2 source the rules (datePicker.calendar.monthYearWheels,wheels.dayClampsToMonth).Public delta and caller burden
onChangewhen a date is chosen; no API or type change.analyze-pr.js), import gzip, base → head: DateInput 150.2 → 150.8 KB, DateTimeInput 163.0 → 163.2 KB; component CSS unchanged.Design and alternatives
dateInMonth(monthGeometry.ts) holds the rule as a pure function, shared by both sheets.Scope
Testing
min/maxcut (2025-11-01 to 2026-02-28, January 25 chosen), one ArrowUp on the month wheel stays on January and commits nothing; it went to February 25 before feat(Wheel): an owner's rest rule and turns from script for the picker wheel #8527's new head.onChangethenchangeAction, shows at once and is busy while the Action runs.dateConstraintsrefuses left unchosen while the calendar moves (both sheets), DateTimeInput keeping 09:30; with a mouse, today's wheels move only the calendar.MonthYearWheels.interaction.browser.spec.ts, Chromium 3/3 and WebKit 3/3.pnpm buildthen the rootpnpm typecheck;CI=true pnpm lint; the full core suite at 16 workers, 15,518 of 15,520 (the two Selector and MultiSelector bottom-sheet cases are test(Selector, MultiSelector): wait for the on-demand sheet module before the first open #8642's load red); the node project (its known reds, andtouch-support-bundle, which test(core): a touch component's import carries its gesture code, and nothing else does #8671 replaces: this head passes test(core): a touch component's import carries its gesture code, and nothing else does #8671's version, 8 of 8); interaction specs (MonthYearToggle, TimeWheels, MonthYearWheels, MonthScroller, MonthPager, WheelActivation) twice over: Chromium 93 of 94 (feat(Wheel): an owner's rest rule and turns from script for the picker wheel #8527's WheelActivation load red), WebKit 84 plus 10 skips.check:changesets.scripts/touch-support-bundle.test.mjs"is absent from the root entry" fails for every touch component under main's current test; test(core): a touch component's import carries its gesture code, and nothing else does #8671 replaces it with the per-component check, which lists DateInput, DateTimeInput, PowerSearch and TimeInput.Stack (merge in this order): … → #8178 → #8179 → #8146 → #8496 → #8200 → #8206 → #8162 → this PR (the full order is in #8156).