Repository navigation
chore(core): UIDatePicker's wheel rules, measured on iOS 26.2 - #8178
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
PR Analysis Report🔎 Preview ·
|
| Component | Size | LoC | Visual · A11y · RTL |
|---|---|---|---|
| DateInput · Storybook | 146.9 kB (0) · 15.4 kB CSS (0) | 5,002 (0) | ✓ · ✓ · ✓ |
| DateTimeInput | 167.5 kB (0) · 17.1 kB CSS (0) | — | — · — · — |
| PowerSearch | 235.8 kB (0) · 21.7 kB CSS (0) | — | — · — · — |
1 more component
| Component | Size | LoC | Visual · A11y · RTL |
|---|---|---|---|
| TimeInput | 131.3 kB (0) · 14.4 kB CSS (0) | — | — · — · — |
Package size: @astryxdesign/core 6.31 MB packed (+3.2 kB); no new dependencies.
API changes: none in this pull request
Committed API report behind this build: core 5 rows, theme-butter 1 row, theme-chocolate 1 row, theme-gothic 1 row, theme-matcha 1 row, theme-neutral 1 row, theme-stone 1 row, theme-y2k 1 row; run pnpm api:report.
Touched components checked; add ci:run-visual, ci:run-a11y or ci:run-rtl to run the full suites.
Generated by PR Enrichment workflow | View full report
There was a problem hiding this comment.
Approval is on hold until an engineering owner decides on spec:AST-094: the new datePicker table rests on its FR1 and FR2, but the record is a draft this branch adds (approved_by: null, not yet on main). An engineering owner records that decision by commenting /approve-spec 7931cc3be44b0d85c178c5208d840e0f6cb3426e on this pull request, and the author may do so as an engineering owner. Whatever the decision, these need changes before merge:
- The branch carries its unmerged stack (#8043-#8045, #8052-#8056, #8067), 13,285 authored lines for a 351-line change, so land those first or rebase so the diff is this commit alone.
lintruns out of JavaScript heap ineslint .on this head, as on every stack head from #8045 on, while it passes onmain.datePicker.tsnamespaging.release,paging.integrator,paging.animatedScrolland apickertable that only #8145 and #8156 add, so stack on those or drop the references.- The description needs the
## Writing rubric resultsthat a pull request creating a record must report.
[Automated review]
| * A release picks its month by the paging rule and settles on the | ||
| * paging integrator (`paging.release`, `paging.integrator`): slow | ||
| * drags released at 30 % and 50 % of a page settle back, at 70 % on | ||
| * the next month; a drag toward a month past `maximumDate` stays. | ||
| * @source measured: UIKit lab, iOS 26.2 simulator, `.date` `.inline`, | ||
| * the grid's `UICollectionView` (`isPagingEnabled`, | ||
| * `decelerationRate` 0.998) read and its offsets logged per frame | ||
| * for slow drags released at 30, 50 and 70 % and a drag past the | ||
| * last allowed month, Oct 23 2026 | ||
| */ | ||
| release: 'paging', |
There was a problem hiding this comment.
paging.release and paging.integrator do not exist at this head: motion/uikit has no paging domain, and scroll.paging holds only projectionRate (a GUESS of 0.99) and snap (a GUESS 0.5 s spring). They are added by #8145 (uikit/paging.ts), which is not in this branch's merge order. Stack on #8145, or drop the reference and this leaf until it lands.
| * `setContentOffset(_:animated:)`'s curve (`paging.animatedScroll`: | ||
| * 0.3 s, sinusoidal), starting in the same frame. | ||
| * @source measured: UIKit lab, iOS 26.2 simulator, `.date` `.inline`, | ||
| * a tap on Next: the title changed in the first frame after the | ||
| * lift and the offset ran 960 → 1280 on the 0.3 s sinusoid from that | ||
| * frame (9.67, 21.33, 80, 160, 240, 298.67, 317.67 pt at 33, 50, 100, | ||
| * 150, 200, 250, 284 ms), Oct 23 2026 | ||
| */ | ||
| step: 'animatedScroll', |
There was a problem hiding this comment.
Same here: paging.animatedScroll, the 0.3 s sinusoid this leaf names, only exists in #8145, so step: 'animatedScroll' resolves to nothing on this branch.
| * In the first or last month `minimumDate` and `maximumDate` allow, | ||
| * the chevron toward the outside is disabled, not hidden: it stays in | ||
| * place, a touch on it goes to the header behind it, and its glyph | ||
| * takes the secondary label colour. |
There was a problem hiding this comment.
The measured tint below, rgba(0.235, 0.235, 0.263, 0.298) (#C5C5C7 on white), is UIKit's light tertiaryLabel (60, 60, 67 at 30 %); secondaryLabel is the same colour at 60 % (#8A8A8E on white). Suggest "takes the tertiary label colour".
There was a problem hiding this comment.
Fixed in ef989eb: thanks, #C5C5C7 is tertiaryLabel (60, 60, 67 at 30 %); the leaf now says the glyph takes the tertiary label colour.
7931cc3 to
8528591
Compare
There was a problem hiding this comment.
Approval is on hold until an engineering owner decides on spec:AST-094. The new datePicker table rests on its draft FR1 and FR2, and registerMotionTable('datePicker', …) makes seven of its values theme-retunable motion roles, which the same record's FR4 and DEC-1 rule out. An engineering owner records an approval by commenting /approve-spec 8528591da149de284d216d27a605213e0a51f48d on this pull request, with FR4 and DEC-1 amended if themes may retune touch motion, and the author may do so as an engineering owner. Whatever the decision, these need changes before merge:
- The branch carries its unmerged stack (#8043-#8045, #8052-#8076, #8062): 28,896 authored lines for a 454-line change, including
[feat]changes to the adaptive presentation and the theme API, so land those first or rebase so the diff is this commit alone. - The
platformadaptation condition (themeAdaptations.ts:82) adds an axis to the setspec:AST-012FR2 keeps closed, without amending that record. uikit.datePickeris exported from@astryxdesign/core/motion/experimental, so its changeset needs[experimental]instead of[chore] Internal.astryx docs motionsays components play these roles, but no component reads them yet, anddatePicker.tsstill points atpagingandpickertables that only #8145 and #8156 add.- The description needs the
## Writing rubric resultsthat a pull request creating a record must report.
[Automated review]
|
|
||
| // Each spring, duration and curve above is a motion role a theme may retune | ||
| // (motion/roles.ts). | ||
| registerMotionTable('datePicker', datePicker); |
There was a problem hiding this comment.
This call makes seven of the table's springs, durations and curves into motion roles that a theme can retune. The draft the table rests on says the opposite: spec:AST-094 FR4 ("Physics are not themable in touch presentations") and DEC-1 ("Rejected: tuning touch motion per theme"). Either an engineering owner amends FR4 and DEC-1, or this call and the seven astryx docs motion rows come out.
There was a problem hiding this comment.
Narrowed in ef989eb: only the three roles a component in this stack plays are registered (the month/year toggle's fade in #8206, the wheels' column turn in #8179 and #8209); the selection spring and the compact popover's springs are excluded until a component plays them. Whether themes may retune touch motion at all is the AST-094 FR4 / DEC-1 decision, which stays with that record's engineering owner.
| * is everything else. Pair `ios` with `pointer: 'coarse'` for a touch | ||
| * profile, such as touch motion tuned per platform. | ||
| */ | ||
| platform?: 'ios' | 'other'; |
There was a problem hiding this comment.
spec:AST-012 FR2 keeps the when vocabulary closed: "A when object may contain width, pointer, contrast, and motion … Future environment fields require explicit additions to this closed vocabulary." This adds platform without amending AST-012, so it needs an owner-approved amendment, which belongs in #8257 rather than on this branch.
There was a problem hiding this comment.
The platform condition comes from #8257 in this stack, not from this commit; its AST-012 amendment belongs to that pull request.
| '@astryxdesign/cli': patch | ||
| --- | ||
|
|
||
| [chore] Internal: UIDatePicker's values measured on iOS 26.2 join the UIKit constants table. For the inline calendar they cover how a day tap selects, the animated selection's spring, the title following a drag, the month grid's release rule, the chevron's step and its retarget, the disabled chevron at a bound, and the month/year toggle's fades and chevron turn. For the wheels they cover the AM/PM column following the hour, the looping hour and minute columns, minutes that do not carry, the turn back onto a bound, the day clamped to the month and the minute interval. The compact popover's springs are included too. Each value comes with its source. Not exported from the package entry point; no component reads it yet. |
There was a problem hiding this comment.
@astryxdesign/core/motion/experimental exports the whole table as uikit (motion/experimental.ts:65), so uikit.datePicker ships on an experimental subpath. spec:AST-017 FR22 asks for an [experimental] changeset when an experimental surface gains something. Calling the table internal does not keep it private once it is reachable from a package path, so the changeset should also say where it is exported.
There was a problem hiding this comment.
Fixed in ef989eb: the changeset is now [experimental] and says the table is reachable as uikit.datePicker from @astryxdesign/core/motion/experimental.
| content: [ | ||
| { | ||
| type: 'prose', | ||
| text: 'On a touch screen, sheets, alerts, menus, navigation and scrolling play the springs, durations and curves measured from iOS. Each value is a motion role named by its table path, such as `springs.sheetPresent` or `timing.curves.easeInOut`. A theme retunes a role through `motion.springs`, `motion.durations` or `motion.curves`, at its root or in an adaptation rule; a role it leaves alone keeps its measured default.', |
There was a problem hiding this comment.
No component plays these values yet. Nothing outside packages/core/src/motion and theme reads a --motion-* variable or calls resolveMotion, and BottomSheet still settles on the theme's CSS transition. A theme author who follows this page, or sets one of the seven datePicker.* rows below, would see no change. Could this say that no component plays touch motion roles yet?
8528591 to
ef989eb
Compare
|
Replies to the automated reviews on ef989eb (the inline comments are answered in their threads):
|
There was a problem hiding this comment.
Approval is on hold until an engineering owner decides on spec:AST-094: the new datePicker table rests on its draft FR1 and FR2, and registering three of its values as theme-retunable motion roles conflicts with the same draft’s FR4 and DEC-1. An engineering owner records that decision by commenting /approve-spec ef989ebc160e50325f7470c5d2adbb1b72063917 on this pull request (with FR4 and DEC-1 amended if themes may retune touch motion), and the author may do so as an engineering owner. Whatever the decision, these need changes before merge:
- The branch still carries its unmerged stack (29,043 authored lines for a 411-line commit), so land the predecessors first or rebase so the diff is this commit alone.
- The touch resolver’s own 744 px compact width (
utils/touchPresentation.ts:75-79) contradictsspec:AST-012FR9, which now sets compact at width belowmdor height below 500 through the theme’s exported definition. - The
platformadaptation condition (themeAdaptations.ts:82) extends the closed vocabulary ofspec:AST-012FR2 without an amendment. - Draft AST-094 FR8 still prescribes 0.5 s cross-fades and springs under Reduce Motion, which
design:reduced-motionDR1 and DR2 rule out. - The theme-roles changeset,
astryx docs motionandMEASUREMENTS.mddescribe roles and leaves that are gone or that nothing reads, and the description needs## Writing rubric resultsfor the record it creates.
[Automated review]
| export const COMPACT_QUERY = '(width < 744px), (height < 500px)'; | ||
|
|
||
| /** Both: presentations such as a sheet in place of a popover. */ | ||
| export const COMPACT_TOUCH_QUERY = | ||
| '(width < 744px) and (pointer: coarse), (height < 500px) and (pointer: coarse)'; |
There was a problem hiding this comment.
Current spec:AST-012 FR9 (on main since this branch was cut) makes compact "width below the effective md point (FR1) or … height below 500" for every resolver, "including the web touch presentation resolver … none keeps size numbers of its own", and DEC-6 rejects mapping compact to platform size classes. With 744 px here, a coarse-pointer screen 744-767 px wide opens the popover where FR9 promises the sheet, and a theme that overrides md cannot move the edge. After rebasing, could this build the query from the theme’s exported compactDefinition instead?
| * is everything else. Pair `ios` with `pointer: 'coarse'` for a touch | ||
| * profile, such as touch motion tuned per platform. | ||
| */ | ||
| platform?: 'ios' | 'other'; |
There was a problem hiding this comment.
spec:AST-012 FR2 still keeps when closed to width, height, pointer, contrast and motion ("Future environment fields require explicit additions to this closed vocabulary"), so platform needs an owner-approved FR2 amendment before it ships as stable theme API.
| - **FR8 — Reduce Motion substitutes, never jumps.** Under | ||
| `prefers-reduced-motion: reduce`, a touch presentation MUST behave as its | ||
| UIKit counterpart does with Reduce Motion and Prefer Cross-Fade Transitions | ||
| on: a transition that travels becomes a cross-fade carrying the same change | ||
| of state. An entrance lands in place and fades in, an exit fades out in | ||
| place, and any other move fades through. A navigation push or pop | ||
| cross-fades over 0.5 s on the ease-in-out curve; a sheet, a full-screen | ||
| modal or an alert fades on its own presentation spring and drops its travel | ||
| and scale; menus open and close on UIKit's Reduce Motion spring. Motion that | ||
| follows a finger, such as a throw, MUST keep its motion. **Proposed; pending | ||
| owner review:** this is the minimally moving form the draft `design:motion` | ||
| DR5 asks for, for touch presentations (owners: ernestt, cixzhang); the | ||
| alternative is UIKit's Reduce Motion alone, which keeps the slides of | ||
| navigation, sheets and modals. |
There was a problem hiding this comment.
Current design:reduced-motion (on main) now decides this: DR1 forbids springing content under reduced motion and DR2 limits a touch transition to "opacity only … 200 ms or less", with an immediate change on other pointers (DR3). The 0.5 s navigation cross-fade and the presentation and menu springs here contradict it, while the branch’s animator already follows the current record. Could FR8 defer to DR1-DR4?
There was a problem hiding this comment.
This branch no longer edits the AST-094 record; #8378 (on main) carries it.
| '@astryxdesign/cli': patch | ||
| --- | ||
|
|
||
| [feat] Themes can retune touch motion. `defineTheme({motion})` takes `springs`, `durations` and `curves` keyed by motion role, the table path of a value touch presentations play (`springs.sheetPresent`, `timing.reducedMotionCrossFadeMs`), at the root or in an adaptation rule. A role the theme leaves out keeps its measured default, and the duration scale (`fast`, `medium`, `ratio`) is optional when a theme sets only roles. Adaptation rules gain a `platform` condition, `ios` or `other`. `astryx docs motion` lists every motion role with its CSS variable and default, and the theme authoring guide and template describe the new fields. |
There was a problem hiding this comment.
timing.reducedMotionCrossFadeMs is no longer a role (uikit/timing.ts:158 excludes it, as design:reduced-motion DR4 requires), and unregistered ids pass defineTheme silently, so a theme author following this note gets no error and no effect. Another example role would keep the note true.
| content: [ | ||
| { | ||
| type: 'prose', | ||
| text: 'On a touch screen, sheets, alerts, menus, navigation and scrolling play the springs, durations and curves measured from iOS. Each value is a motion role named by its table path, such as `springs.sheetPresent` or `timing.curves.easeInOut`. A theme retunes a role through `motion.springs`, `motion.durations` or `motion.curves`, at its root or in an adaptation rule; a role it leaves alone keeps its measured default.', |
There was a problem hiding this comment.
At this head no component reads a --motion-* variable or calls resolveMotion, so none of the 48 listed roles changes anything yet, including the three datePicker.* rows. Could the page say no component plays touch motion roles yet, and could each role be registered in the pull request whose component plays it?
There was a problem hiding this comment.
The three datePicker.* rows are played in this stack: the column turn by TimeWheels (#8179) and MonthYearWheels (#8209), and the toggle's fade by #8206. Since 7ec94d0 nothing registers on import: registerDatePickerTable() runs from that touch code right before a role resolves. The page's general line about roles is #8076's.
| their own table (`uikit/datePicker.ts`); the month grid is a paging scroll view | ||
| and the wheels are UIPickerView's, so those parts use the paging and picker | ||
| values. | ||
|
|
||
| Done (UIKit lab, iOS 26.2 simulator, Oct 23 2026; in the date picker's table): | ||
| a day tap and `setDate(_:animated:)`, the title following the drag, the release | ||
| rule, the chevron step and its retarget, the chevron at a bound, the month/year |
There was a problem hiding this comment.
The release rule and the chevron step moved to #8200, and this branch has no picker table (scroll.paging holds two GUESS values), so this paragraph lists leaves the date picker’s table no longer holds.
There was a problem hiding this comment.
Fixed in 7ec94d0: the paragraph lists only the leaves this table holds, and names the release and arrow step as the pager's.
ef989eb to
4a19283
Compare
4a19283 to
d6646b4
Compare
4897a6e to
b7519f1
Compare
|
/approve-spec b7519f1 |
There was a problem hiding this comment.
Changes are needed before approval. An engineering owner's /approve-spec covers this head's component:DateInput and spec:AST-094 record changes, so no spec decision is pending.
Required change:
- This branch carries #8159's commits, 6,398 authored lines for this pull request's own 99-line change, so merging it would ship #8159's touch wheel under this title; land #8159 first, then update this branch from
mainso it holds only its own two commits. - The DateInput record's Compatibility row (
DateInput.spec.md, line 64) still says "no API, default, or DOM change", though the touch column's markup and the wheel keys change; say what changes instead.
[Automated review]
b7519f1 to
77309d5
Compare
|
/approve-spec 77309d5 |
There was a problem hiding this comment.
Changes are needed before this can merge. An engineering owner's /approve-spec covers this head's component:DateInput and spec:AST-094 record changes, so no spec decision is pending.
- The branch still carries #8159 (6,459 authored lines for this pull request's 117-line change), so merging it would ship #8159's touch wheel and its
[feat]and[fix]changesets under this title; land #8159 first, then update this branch frommain. wheelPhysics.tsedgeCurveand the past-edgereturnplan (:181-241,:293-299) writemotion/coast.ts's coast into an edge and its spring back a second time, and the copies already settle at different thresholds; extendmotion/coast.tswith a pure per-axis helper that both call, and export the animator's 30 s limit instead of restating it.
A small wording suggestion: the record's Compatibility row puts FR17's key order under "Under a finger", while FR17 applies under every pointer.
[Automated review]
| * A coast that runs into an end: the normal decay until the offset reaches | ||
| * `edge`, then the bounce spring with the velocity it has there. | ||
| */ | ||
| export function edgeCurve( |
There was a problem hiding this comment.
This edge coast (decay until the edge, then scroll.bounce with the contact velocity) and the past-edge return plan through bounceCurve repeat coast() in motion/coast.ts (its edge and past-edge branches). The two already settle at different thresholds (0.05 px there, 0.146 px here). Could motion/coast.ts export a pure per-axis edge helper that coast() and planRelease both call? The picker's own projection, row coast and snap would stay here.
| | Behavior | `presentation` selects the picker surface; an omitted value is `adaptive-native`; `presentation` wins over deprecated `nativePicker`; every committed path emits the same controlled ISO-date value and action feedback. | | ||
| | End-user impact | People type or pick one date using a surface suited to the primary pointer. Disabled and busy fields stay focusable; a busy field keeps its ordinary paint with a Spinner while new commits are blocked. | | ||
| | Builder impact | None. `changeAction` runs after `onChange` with optimistic busy feedback on every surface. | | ||
| | Compatibility/readiness | No API or default change. Under a finger, the sheet wheels' markup changes (one strip of flat rows, faded by a layer inside the column), and keys step through the values in time order (FR17). Caller handlers while disabled, fixed field height, the English-only typed parser, a clear control that drops focus, and month paging in the touch calendar are listed under Current-state impact. | |
There was a problem hiding this comment.
Non-blocking: "Under a finger, … and keys step through the values in time order (FR17)" reads as if the key change applied only under a finger, but FR17 says "under every presentation". A separate sentence ("Under every pointer, keys step …") would match.
77309d5 to
c75f524
Compare
|
/approve-spec c75f524 |
There was a problem hiding this comment.
Changes are needed before this can merge. An engineering owner's /approve-spec covers this head's component:DateInput changes, and the new datePicker table meets spec:AST-094 FR2, so no spec decision is pending.
Required change:
docs/specs/components/DateInput/DateInput.spec.md:79-80, the body's Compatibility class, which the record calls authoritative, still says "no public prop, default, export, or DOM change", while the Compatibility row at:64now says the sheet wheels' markup changes under a finger; rewrite the body line to match the row.
Suggestion (non-blocking):
- The row puts FR17's keys under "Under a finger", but FR17 applies under every presentation; one wording in both places fixes that too.
[Automated review]
| | Behavior | `presentation` selects the picker surface; an omitted value is `adaptive-native`; `presentation` wins over deprecated `nativePicker`; every committed path emits the same controlled ISO-date value and action feedback. | | ||
| | End-user impact | People type or pick one date using a surface suited to the primary pointer. Disabled and busy fields stay focusable; a busy field keeps its ordinary paint with a Spinner while new commits are blocked. | | ||
| | Builder impact | None. `changeAction` runs after `onChange` with optimistic busy feedback on every surface. | | ||
| | Compatibility/readiness | No API or default change. Under a finger, the sheet wheels' markup changes (one strip of flat rows, faded by a layer inside the column), and keys step through the values in time order (FR17). Caller handlers while disabled, fixed field height, the English-only typed parser, a clear control that drops focus, and month paging in the touch calendar are listed under Current-state impact. | |
There was a problem hiding this comment.
This row now names the touch markup change, but the body's Compatibility class (lines 79-80) still says "records shipped behavior; no public prop, default, export, or DOM change", and line 68 makes the body authoritative. Please rewrite lines 79-80 to match, for example: "no public prop, default, or export change; under a finger the sheet wheels' markup changes, and under every presentation keys step in time order (FR17)".
|
/approve-spec fdc1ee1 |
There was a problem hiding this comment.
This looks ready to approve. An engineering owner's /approve-spec covers this head's component:DateInput changes, the new datePicker table meets spec:AST-094 FR2 (every rule names its measurement), and the Compatibility class now matches the Compatibility row.
Suggestion (non-blocking):
component:DateInputdoes not yet say what a screen reader hears while the touch wheel moves (the listbox keeps the committed row as its active option until the wheel rests, while the mouse column follows the band); one sentence in its accessibility rows would settle it.
[Automated review]
|
/approve-spec 0763d1f |
There was a problem hiding this comment.
This looks ready to approve. An engineering owner's /approve-spec covers this head's component:DateInput changes, and the new datePicker table meets spec:AST-094 FR2: every rule names its iOS 26.2 measurement.
- Stack: #8179's branch still sits on this pull request's commits from before the rebase, so it no longer contains this head; rebase the rest of the stack onto this head before it lands.
[Automated review]
The date picker domain of the UIKit constants table, each rule sourced: the month/year wheels change the date, keeping the day; the AM/PM column follows the hour; a column that comes to rest past a bound turns back onto it; and a day the month lacks clamps to its last day. The date and time touch sheets follow these rules. Nothing is exported from the package entry point.
…heel The mouse column turns by the browser's smooth scroll and marks each row as it scrolls, so FR14's tap-spin sentence and FR18 start with "Under a finger". The record's scope line lists FR17 and FR18. Two comments that restated the function below them are gone, and two changesets no longer present behavior that already shipped as new.
…w does The record's body is authoritative, and its Compatibility class still said no DOM change. It now names the sheet wheels' markup under a finger, and FR17's key order under every presentation, as the row does.
|
/approve-spec 0fcb39b |
There was a problem hiding this comment.
This looks ready to approve, and CI passes on this head. An engineering owner's /approve-spec covers this head's component:DateInput changes (FR14 and FR18 scoped to a finger, and the Compatibility row and class), and each rule in the new internal datePicker table names its iOS 26.2 measurement, as spec:AST-094 FR2 requires.
- Non-blocking:
datePicker.ts:33says the AM/PM column flips "and back", but its source records only the 11 to 12 turn; name that measurement or drop "and back". - Stack: #8179's branch still sits on this pull request's commits from before the rebase, so it does not contain this head; rebase the rest of the stack onto this head.
[Automated review]
| wheels: { | ||
| /** | ||
| * In 12-hour time the AM/PM column follows the hour. Turning the hour from | ||
| * 11 to 12 turns the time from AM to PM, and back. From 12 to 1 it keeps |
There was a problem hiding this comment.
Non-blocking: "and back" says turning the hour from 12 to 11 flips PM back to AM, but the @source below records only the 11 to 12 turn and the minute wheel's carry from 12 to 1. Under spec:AST-094 FR2 the doc reads as measured, so either name the backward turn's measurement or drop "and back".
Batch: B4 · Wheel / picker (DateInput, TimeInput, DateTimeInput)
Stack: #8178 → #8179 → #8209 → #8200 → #8206
#8159 is merged, so this pull request's diff is its own change.
Maintainer impact
The B4 wheel pull requests make the touch sheets follow four UIDatePicker rules. This adds them to the UIKit constants table, each with its measurement (
spec:AST-094FR1, FR2), so the sheets cite one sourced table.Intended invariant
Every leaf in
motion/uikit/names an allowed source, whichuikit.test.tschecks. No runtime value changes, and nothing new is exported from the package entry point.Change
motion/uikit/datePicker.ts, measured on the iOS 26.2 simulator, holds four rules:calendar.monthYearWheels.changesDate: turning the month or year wheel changes the date and keeps the day (fix(DateInput, DateTimeInput): under a finger the month/year wheels move the date like UIDatePicker's #8209).wheels.meridiemFollowsHour: in 12-hour time the AM/PM column follows the hour (fix(TimeInput, DateTimeInput): under a finger the AM/PM wheel follows the hour #8179).wheels.restPastBound: a column at rest past a bound turns back onto it (fix(Wheel): a wheel that stops outside the bounds rests on the nearest value inside them #8131, fix(TimeInput, DateTimeInput): under a finger the AM/PM wheel follows the hour #8179).wheels.dayClampsToMonth: a day the month lacks clamps to its last day (fix(DateInput, DateTimeInput): under a finger the month/year wheels move the date like UIDatePicker's #8209).motion/MEASUREMENTS.mdrecords the captures, andmotion/README.mdlists the file. The calendar's other values ship with the pull requests that play them.A second commit settles the bot's review of #8159's wheel text, which this stack carries.
component:DateInputFR14's tap-spin sentence and FR18 start with "Under a finger", and the record's scope line lists FR17 and FR18. Two comments that restated their function are gone, and two changesets no longer announce shipped behavior as new.A third and a fourth commit answer the bot's reviews: the Compatibility/readiness row and the body's Compatibility class said "no DOM change". Both now name the wheels' markup under a finger, and FR17's key order under every presentation.
That Compatibility text is new in this pull request; AST-094's "starved page … (start-at-call)" line is main's text from #9733, and this pull request does not touch AST-094.
For the owner: FR18 narrows your Nov 2 sentence "While a wheel coasts, snaps or turns, no row carries the selection band's accent mark; the mark returns on the row that comes to rest, as UIPickerView does (
spec:AST-094FR3)." to "Under a finger, while a wheel coasts, …". The reason: the mouse column marks each row as it scrolls, so the sentence as written bound it too. The Compatibility row and class also changed; all need/approve-specat this head.Evidence
uikit.test.tschecks each new leaf's source and measurement date.Scope
Earlier review threads: each is answered on its thread.
Writing rubric results
Over FR14's tap-spin sentence, FR18, the scope line, the Compatibility/readiness row and the Compatibility class: R1 narration, R2 research, R4 rejected alternatives, R5 change references, R6 open questions: none.
Testing
This head, 0fcb39b, rebases fdc1ee1 onto main 787b696. There #9824 added
component:DateInputFR19 (the weekday row) beside this pull request's FR18, and #9838 added FR14's sentence on when a tapped row commits. The one conflict resolves to this FR14 with main's new sentence kept, this FR18, and main's FR19.git range-diffshows three commits equal and the FR14/FR18 commit changed only by main's lines; the code patch is byte-identical.pnpm install --frozen-lockfile0;pnpm -F @astryxdesign/core typecheck0; strict ESLint on the touched files 0;pnpm review:pre0; the DateInput, DateTimeInput, TimeInput, motion, utils and hooks unit suites: 3,395 passed.check:knowledge0;check:changesets0;pnpm review:pre0.pnpm -F @astryxdesign/core typecheck0;check:knowledge0;check:changesets0;pnpm review:pre0; the DateInput, TimeInput, DateTimeInput and Calendar unit suites: 1,115 passed.pnpm test:uiandpnpm test:node, the DateInput accessibility contracts and the browser specs run at the stack's top head; this section gets their results when they land.