Skip to content

feat(lab): ListInput reorders through core's createReorderable - #8163

Open
vjeux wants to merge 39 commits into
meta:mainfrom
vjeux:uikit/c13-listinput-reorder
Open

vjeux wants to merge 39 commits into
meta:mainfrom
vjeux:uikit/c13-listinput-reorder

Conversation

@vjeux

@vjeux vjeux commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Stack: #8139 → #8143 → #8163

This merges after #8143 and #8139. Review only this PR's change: vjeux/astryx@c66c799...d3b8e98. Main's disabled Button change (#7906) edits the lines beside this PR's disabled-handle case in ListInput.test.tsx: that case keeps main's aria-disabled assertion for Add and adds this PR's handle assertions.

Why

ListInput lets people build an ordered list of records, such as guests. Its grip grabbed every touch at once, so swiping over grips on a phone didn't scroll.

What led to it

This is part of the UIKit-parity program, which makes Astryx's components behave like their iOS counterparts on touch screens. Moving Lab's reorders onto core's is part of it. ListInput had its own drag code, duplicating core List's reorder. Following Cindy's direction (her 1272d6a is here), it takes reorderable, the createReorderable object, keyed by getItemKey. Each record ends with core's handle ("Reorder guest 2"), after Remove and in Remove's cell, so the handle is the one element the reorder adds to a record. The handle comes with the owner's object, so a ListInput without reorderable loads no reorder code. Each move goes to onReorder({key, to}), and disabled or loading lists keep their handles inert. The list takes the session's style, so its insertion line marks a drop, and a record's place in reorder mode. Lab reaches core's reorder session through @astryxdesign/core/internal/reorder, which gains the session for rows that are not ListItems. architecture:react-component-runtime INV13 lists that session among its known public-API gaps (#8143's record change), as spec:AST-107 FR7 asks. List and that session share the same two hooks, so the session's wiring lives in one place.

Before: <ListInput isReorderable onChange={...} />. After: <ListInput reorderable={createReorderable({onReorder})} getItemKey={...} />.

Options and tradeoffs

  • Keep ListInput's own drag, or reuse core's reorder and change the API.
  • Handle placement: before Remove, or after it.

Why this choice

Reusing core's reorder means one implementation, and ListInput gets the hold, the keyboard path, the hint and the announcements. The cost is the API change; Lab is private, so there's no changeset. The handle goes after Remove, where UIKit puts it. The design record drops the removed reorderStyles.ts path and its "Implementation gap" paragraph, which this closes, for Cindy's review.

The record columns

With reorderable, the Add row reused the records' auto control track, which is empty there, so the Add button ran 56 px past the record fields. Each handle and its focus ring also ended 8 px past the list: the handle reaches into a ListItem row's inline inset, and a record has none. The control track is now fixed (Remove, the gap and the 28 px handle), and records set that inset to zero. So the fields column is 8 px narrower than on the previous head, and the handle stays inside the list.

A record that stays put

A record that the owner's isReorderable keeps in place has no handle, so its control cell holds Remove alone. The cell centred it in the fixed control track, 16 px past every other record's Remove. The cell now starts its controls at the track's start, so every Remove sits in one column. A new fixture, A11y/ListInput › Fixed record, keeps its first record in place; it stays out of the visual matrix.

How to check it

In Storybook Lab/ListInput:

  1. On a phone, hold a grip and drag the record down two places. A flick scrolls, and a pinch zooms.
  2. Tab to a grip and press Enter: a line marks the record's place, and a hint shows ↑, ↓ and Done. Use the arrow keys: the record moves each time and stays in reorder mode, and its grip takes its new name. Press Escape to end.
  3. Loading: the grips do nothing, and dragging scrolls the page.

This head, d3b8e98, merges #8143's head (c66c799, which carries #8139's merge of main 3b8eb80) with no conflict, and leaves this pull request's own changes as they were. Merged up this way, the stack passes the Lab and List units (275), the TransferList and ListInput reorder specs (13), the full UI project (22,889 tests) and the node project (17,592 tests, no failures).

Gates at the top of the stack. The full run is at 4fd0951, on main 1c8292c, whose tree differs from this head only in the comment-provenance baseline and one file's formatting; at this head lint, the baseline check, typecheck and the List and Item units ran again:

  • Build, Core and Lab typecheck 0, ESLint (0 errors), INV29 0. check:knowledge, check:changesets, check:repo, check:i18n-catalog, check:i18n-runtime, check:use-client and check:package-boundaries: 0.
  • Units, after pnpm install --frozen-lockfile: every Lab test (TransferList, TransferListSelector and ListInput included), core List, motion, Layer, Core's utils and internal entries, the keyboard module, Button and createReorderable, 5,510 of 5,510. The full UI project passes, 22,672 tests. The full node project passes 17,448 tests; its one failure, a CLI block-picker case (build tree › "login form with single sign-on buttons"), fails the same way on main (1c8292c).
  • The record columns, red-first: a new Chromium case at 390 and 1024 px measures the Add button 56 px past the record fields, and each handle 8 px past its record and the list, on the head before that fix. Now both are inside.
  • A record that stays put, red-first: at 390 and 1024 px, its Remove sat 16 px past the others on the previous head (326 against 310 px, and 960 against 944 px). On this head every Remove is in one column.
  • Chromium browser specs: List's interaction specs, 90 passed and 1 skipped; Lab's, 21 of 21. WebKit, with CI's settings (four CPUs): List's reorder specs pass 22, and skip 12 Chromium-only cases.

Earlier, at ac07610:

  • Red-first: three new ListInput cases fail on the previous head and pass here. A move that renames its record keeps reorder mode and announces the new names; reordering adds one element to a record, the handle; and ListInput imports no handle. In Chromium, reorder mode's insertion line is missing on the previous head's build, and shows here through each move.
  • The accessibility audit over the List, ListItem, ListInput, TransferList and TransferListSelector stories: no new violations.
  • The CLI's search goldens (experimental-isolation, 44 of 44) pass: feat(core): createReorderable makes List rows reorderable #8139 counts its new hook doc in them.

Writing rubric results

For design:ordered-collection-reordering:

R1 narration: the deleted "Implementation gap" paragraph described Lab's own drags, which go here. Each of its claims now holds through core's tests: a key move's place is marked with the insertion line until the mode ends, reorder mode moves a record with the arrow keys through the owner's onReorder, and the other rows stay still during a drag.
R2 research: none.
R3 evidence: verified_by names a spec file, not a change.
R4 rejected alternatives: none added.
R5 change references: none.
R6 open questions: OQ1 to OQ3 are unanswered and keep their options.

Evidence

Before: the grip drags at once, and on iOS 26.2: after, hold, drag and drop, and loading: the grip is inert.

Pull request size

1,284 lines added and 1,587 removed in 16 files: 428 added of source and 679 of tests. ListInput's own drag code and the shared Lab reorder styles go.

@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 8, 2026 5:27pm UTC

Request Review

@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 8, 2026, 5:49 PM UTC

@github-actions github-actions Bot added the needs:design-review Affects visuals — Design should review label Oct 24, 2026
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 24, 2026
@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · d3b8e98

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC Visual · A11y · RTL
charts/Chart 198.7 kB (+865 B) · 494 B CSS (0) — — · — · —
charts/ChartTooltip 175.9 kB (+860 B) · 423 B CSS (0) — — · — · —
lab/Comments 339.3 kB (+792 B) · 2.5 kB CSS (0) — — · — · —
60 more components
Component Size LoC Visual · A11y · RTL
lab/CommentThread 332.4 kB (+765 B) · 2.4 kB CSS (0) — — · — · —
TableCell 108.1 kB (+615 B) · 17.6 kB CSS (0) — — · — · —
Table 117.0 kB (+612 B) · 17.9 kB CSS (0) — — · — · —
ContextMenu 106.9 kB (+590 B) · 17.2 kB CSS (0) — — · — · —
TableHeaderCell 107.7 kB (+589 B) · 17.3 kB CSS (0) — — · — · —
Markdown 180.1 kB (+579 B) · 20.2 kB CSS (0) — — · — · —
richtext/RichTextEditorToolbar 251.3 kB (+412 B) · 454 B CSS (0) — — · — · —
ListItem 69.1 kB (+390 B) · 11.3 kB CSS (0) — ✓ · ✓ · ✓
PowerSearch 283.1 kB (+381 B) · 23.7 kB CSS (0) — — · — · —
CheckboxListItem 70.1 kB (+340 B) · 11.3 kB CSS (0) — — · — · —
lab/CommentComposer 147.6 kB (+283 B) · 1.9 kB CSS (0) — — · — · —
lab/NavigationScreen 80.3 kB (+249 B) · 1.5 kB CSS (0) — — · — · —
lab/NavigationStack 80.3 kB (+249 B) · 1.5 kB CSS (0) — — · — · —
lab/TabBar 74.9 kB (+246 B) · 1.8 kB CSS (0) — — · — · —
lab/PageControl 73.4 kB (+242 B) · 709 B CSS (0) — — · — · —
CheckboxList 68.2 kB (+207 B) · 8.1 kB CSS (0) — — · — · —
List 17.9 kB (+207 B) · 651 B CSS (0) — ✓ · ✓ · —
DropdownMenuRadioItem 22.8 kB (+132 B) · 6.6 kB CSS (0) — — · — · —
Selector 98.4 kB (+132 B) · 17.3 kB CSS (0) — — · — · —
DropdownMenuSubMenu 69.1 kB (+123 B) · 9.7 kB CSS (0) — — · — · —
SegmentedControl 92.6 kB (+123 B) · 6.8 kB CSS (0) — — · — · —
BreadcrumbItem 83.5 kB (+114 B) · 12.1 kB CSS (0) — — · — · —
DropdownMenu 95.8 kB (+110 B) · 17.3 kB CSS (0) — — · — · —
DropdownMenuCheckboxItem 22.7 kB (+110 B) · 6.6 kB CSS (0) — — · — · —
Item · Storybook 17.5 kB (+110 B) · 5.5 kB CSS (0) 1,748 (+38) ✓ · ✓ · —
DropdownMenuItem 22.0 kB (+109 B) · 6.3 kB CSS (0) — — · — · —
Pagination 108.5 kB (+105 B) · 17.7 kB CSS (0) — — · — · —
MoreMenu 96.0 kB (+104 B) · 17.3 kB CSS (0) — — · — · —
ContextMenuItem 28.9 kB (+98 B) · 6.3 kB CSS (0) — — · — · —
RadioListItem 66.2 kB (+94 B) · 10.1 kB CSS (0) — — · — · —
Toolbar 42.3 kB (+92 B) · 8.1 kB CSS (0) — — · — · —
SelectorOption 20.9 kB (+87 B) · 6.1 kB CSS (0) — — · — · —
TableSelectionToolbar 69.4 kB (+79 B) · 13.1 kB CSS (0) — — · — · —
TabList 42.4 kB (+62 B) · 6.5 kB CSS (0) — — · — · —
Popover 87.9 kB (+33 B) · 14.1 kB CSS (0) — — · — · —
DateTimeInput 204.8 kB (+31 B) · 18.6 kB CSS (0) — — · — · —
AppShell 89.6 kB (+29 B) · 13.4 kB CSS (0) — — · — · —
lab/ChatReactionBar 103.6 kB (+27 B) · 1.1 kB CSS (0) — — · — · —
lab/ChatEmojiPicker 102.4 kB (+19 B) · 773 B CSS (0) — — · — · —
lab/TourStep 94.2 kB (+19 B) · 590 B CSS (0) — — · — · —
SideNav 110.9 kB (+8 B) · 11.3 kB CSS (0) — — · — · —
TimeInput 158.6 kB (+4 B) · 15.9 kB CSS (0) — — · — · —
ChatComposer 76.8 kB (0) · 12.0 kB CSS (0) — — · — · —
ChatComposerInput 74.4 kB (0) · 11.2 kB CSS (0) — — · — · —
ChatComposerTokenElement 74.4 kB (0) · 11.2 kB CSS (0) — — · — · —
ChatLayout 79.3 kB (0) · 10.5 kB CSS (0) — — · — · —
Collapsible 26.8 kB (0) · 4.5 kB CSS (0) — — · — · —
DateInput 183.0 kB (0) · 16.9 kB CSS (0) — — · — · —
Lightbox 119.3 kB (0) · 10.5 kB CSS (0) — — · — · —
MultiSelector 93.5 kB (0) · 16.8 kB CSS (0) — — · — · —
Outline 24.8 kB (0) · 4.1 kB CSS (0) — — · — · —
Slider 106.1 kB (0) · 8.8 kB CSS (0) — — · — · —
Switch 100.7 kB (0) · 9.9 kB CSS (0) — — · — · —
Tokenizer 90.2 kB (0) · 18.5 kB CSS (0) — — · — · —
TreeList 43.9 kB (0) · 5.6 kB CSS (0) — — · — · —
lab/TabBarItem 3.8 kB (0) · 1.8 kB CSS (0) — — · — · —
BottomSheet 65.8 kB (−2 B) · 7.6 kB CSS (0) — — · — · —
lab/TransferListSelector 107.6 kB (−5.4 kB) · 1.4 kB CSS (−500 B) — — · ✓ · ✓
lab/TransferList 100.1 kB (−6.3 kB) · 1.2 kB CSS (−529 B) — — · ✓ · ✓
lab/ListInput · Storybook 87.0 kB (−13.5 kB) · 922 B CSS (−763 B) 1,083 (−678) — · ✓ · —

Package size:

  • @astryxdesign/cli 3.52 MB packed (+347 B); no new dependencies
  • @astryxdesign/core 7.11 MB packed (+103.4 kB); no new dependencies

API changes: core +5 · ~0 · −0

Committed API report behind this build: cli 29 rows, core 35 rows, theme-butter 1 row, theme-y2k 1 row; run pnpm api:report.

5 API changes (advisory)
Package Where Signature Usage
+ core . · Components · component List prop reorderable?: Reorderable <List reorderable={…} />
+ core . · Functions · function createReorderable function createReorderable: <TKey extends string | number = string | number, TTo = number>(options: ReorderableOptions<TKey, TTo>) => Reorderable<TKey, TTo> import {createReorderable} from '@astryxdesign/core'; createReorderable(…)
+ core . · Types · interface ReorderMove interface ReorderMove<TKey extends string | number = string | number, TTo = number> import type {ReorderMove} from '@astryxdesign/core'
+ core . · Types · interface Reorderable interface Reorderable<TKey extends string | number = string | number, TTo = number> import type {Reorderable} from '@astryxdesign/core'
+ core . · Types · interface ReorderableOptions interface ReorderableOptions<TKey extends string | number = string | number, TTo = number> import type {ReorderableOptions} from '@astryxdesign/core'

Touched components checked; add ci:run-visual or ci:run-rtl to run the full suites.


Generated by PR Enrichment workflow | View full report

@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 on direction that no current spec covers: draft spec:AST-094 FR1–FR23 with DEC-1 and DEC-2, and the four ListInput decisions the description marks as pending owner review. 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. Whatever that decision is, these still need changes:

  • Land or retarget the stack so this diff is only the ListInput change; it now carries 34,464 authored lines, most of them from eight other pull requests.
  • Add the real-browser test that useListReorder.ts and ListReorder.test.tsx point to (ListReorder.interaction.browser.spec.ts), covering the slide, autoscroll, drop and pointer cancel.
  • Remove the document touch listeners ListReorderHandle installs once no handle needs them, and fix AST-094's references to a spec:AST-090 that does not exist.

[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 on direction no current spec covers: draft spec:AST-094 FR1–FR23 with DEC-1 and DEC-2, and the four ListInput decisions the description marks as pending owner review. 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. Whatever that decision is, these still need changes:

  • Land or retarget the stack so this diff is only the ListInput change; it now carries 34,443 authored lines, most of them from other pull requests.
  • Add the real-browser test that useListReorder.ts and ListReorder.test.tsx point to (ListReorder.interaction.browser.spec.ts), covering the slide, autoscroll, drop and cancel.
  • Remove the document touch listeners ListReorderHandle installs once no handle needs them, and fix AST-094's references to a spec:AST-090 that does not exist.

[Automated review]

@vjeux

vjeux commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

On the predecessor stack: this pull request is stacked, as its first line says, and only its last commit (79c4b3c, 5 files, +359 −1,392) is its own. It rebases onto main as each predecessor lands, and the diff then shrinks to that commit.

@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 on direction no current spec covers: draft spec:AST-094 FR1–FR23 with DEC-1 and DEC-2 (including whether FR4's untunable touch motion or the themable reorder.slide.spring stands) and the ListInput reorder decisions the description marks as pending owner review, now including the handle's moves menu. 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. Whatever that decision is, these still need changes:

  • Land or retarget the stack so this diff is only the ListInput change; it now carries 48,303 authored lines, most of them from ten other open pull requests.
  • The reorder handle announces itself as a menu button, but Enter and Space pick the record up and never open its moves menu; give that role its keyboard activation or drop aria-haspopup.
  • Add a browser test for the moves menu's focus path and the drag autoscroll, and correct the theme template's platform axis, the stale sentence in the touch-motion-theme-roles changeset, and AST-094's references to a spec:AST-090 that does not exist.

[Automated review]

Comment thread packages/cli/assets/theme.template.ts Resolved
Comment thread .changeset/touch-motion-theme-roles.md Resolved

@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 on direction no current spec covers: draft spec:AST-094 FR1–FR23 with DEC-1 and DEC-2 (including whether FR4's untunable touch motion or the themable reorder.slide.spring stands) and the ListInput reorder decisions the description marks as pending owner review, including the handle's new look and drag for mouse users. 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. Whatever that decision is, these still need changes:

  • Land or retarget the stack so this diff is only the ListInput change; it now carries 48,192 authored lines, most of them from nine other open pull requests.
  • The reorder handle announces itself as a menu button, but Enter and Space pick the record up and never open its moves menu; give that role its keyboard activation or drop aria-haspopup.
  • Add browser evidence for the moves menu's focus path, the drag autoscroll and the mouse drag after the change, and mark or drop the new @astryxdesign/core/motion/reducedMotion.stylex export.
  • Correct the changesets that say no component uses the gesture and motion code yet, and AST-094's references to a spec:AST-090 that does not exist.

[Automated review]

Comment thread packages/core/package.json Resolved
Comment thread .changeset/touch-motion-theme-roles.md Resolved
vjeux added 9 commits November 7, 2026 16:43
A disabled TransferList hid its reorder handles and moved the focus
from a focused handle to its row's Remove button. Now each selected
row is a disabled ListItem. Its handle keeps aria-disabled, its place
in the tab order and the focus, and core List ends a reorder mode or
sends a drag home. Each handle shows the "cannot be reordered" tooltip
on hover and keyboard focus, and its description reads it. A disabled
row still takes the pointer, so its disabled controls show their
tooltips. The row dims its Remove button, so Remove drops its own
disabled dim and reads at half opacity, as before.
TransferList's JSDoc and example sat above the private tooltip props,
so the component lost its documentation in editors and in the emitted
declarations. The tooltip code now comes before that block.

A disabled list's handle tooltip took the row's first toggle button. A
renderOption that renders its own toggle comes first, so that toggle
got the "cannot be reordered" description. The tooltip now takes the
row's last toggle, which is Core's handle at the row's end.
The spec owners kept reordering opt-in: with no reorderable, a
TransferList no longer reorders. Its migration guidance now leads with
that, and its last sentence, which said the same, goes.
spec:AST-103 FR4 makes the reorder-mode hint a part named in each
adopting collection's anatomy. TransferList shows it below a selected
row's handle, so its anatomy gains a Reorder hint entry, as List's
has. A test title that still said reordering is on by default now
says the handle comes with reorderable.
spec:AST-107 FR7 lets a Core or Lab component reach internals only for
a job the public layer does not expose, listed among INV13's known
public-API gaps. TransferList adapts its reorderable object to its own
values, and ListInput's rows are not ListItems. Both join List's
reorder session through Core's internal reorder entry, because
createReorderable's plain-element attach (spec:AST-103 FR4b) is not
built. INV13 now lists that job.
ListInput takes `reorderable`, the createReorderable object, keyed by
getItemKey. Each record ends with core List's reorder handle, after
Remove. A finger holds it a moment before it drags, so a flick scrolls
and a pinch zooms. A mouse drags at once. Reorder mode moves a record
from the keyboard or the hint's buttons, and each move goes to the
object's onReorder({key, to}). A disabled or loading list keeps its
handles, focusable but inert.

ListInput's own grip, pointer drag, drag preview and keyboard session
go, and with them the shared Lab reorder styles, which nothing uses
any more. Core's internal reorder entry gains the session for rows
that are not ListItems (useListReorderScope, ListReorderScope), which
runs the same engine a reorderable List runs.

The handle is the session's, so a ListInput without reorderable loads
no reorder code. It sits in Remove's cell, the one element the reorder
adds to a record, and its name comes from one catalog message. The
list takes the session's style, so its insertion line marks a drop and
a record in reorder mode.
With reorderable, the Add row reused the records' auto control track,
which is empty there, so the Add button ran 56 px past the record
fields. The control track is now fixed: Remove, the gap and the handle.

Each reorder handle and its focus ring also ended 8 px past the list,
because the handle reaches into a ListItem row's inline inset and a
record has none. Records now set that inset to zero.
On iOS, a TransferList panel's clip around the selected list's own
inline clip drew the row flush with the panel's bottom edge one point
off for the length of the drop's glide. In the phone layout the panel
body does not scroll, so the clip kept nothing in. The panel now clips
only in the wide layout, where its body scrolls.

In iOS Simulator takes of a six-row drag, the row at the edge sat 3
device pixels off for 14 and 15 frames on the previous head, and for 0
frames with this change. Every TransferList story at rest, and the
last row in reorder mode, keep the same pixels without the clip in
WebKit. A Chromium trace of the glide under a coarse pointer paints
nothing per frame, before and after.
With reorderable, a record that the owner's isReorderable keeps in
place has no reorder handle, so its control cell holds Remove alone.
The cell centred it in the fixed control track, 16 px past every other
record's Remove. The cell now starts its controls at the track's start.

A new fixture, A11y/ListInput › Fixed record, keeps its first record in
place. A browser case at 390 and 1024 px measures each record's Remove:
the fixed record's sat 16 px out before, and lines up now.
@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec c7702fb

@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.

This stack waits on one owner decision, in #8143; no code changes are needed. A pull request lands only when it and every pull request below it are approved.

#8139 — approve on its own. Every change matches the reorder spec or record text an engineering owner approved for this head. Non-blocking: a scroll of an ancestor of the list's scroller (for example the page, once the list's own box is at its end) is still not followed during a drag (listReorderEngine.tsx L1395), and the reorderable object's engine key and type brand are module-local (listReorderContext.ts L42, createReorderable.ts L66), so a swizzled List cannot read an object the package's createReorderable made.

#8143 — waits on an owner decision.

  • With default props a TransferList no longer reorders its selected rows with a mouse (TransferList.tsx L606; it used to be on by default), and the decision the description now cites gives a date but no time and no reference, so it needs the time it was given or its reference added to the description, or mouse reordering stays on by default.

#8163 — approve on its own. No blocking findings in its own changes; it carries #8143's change, so it lands once #8143 is settled. Non-blocking: the comment at ListInput.tsx L593-596 could keep only its constraint ("A disabled or loading list keeps its handles focusable but inert.").

Whole stack: no blocking findings remain; it waits on the #8143 decision.

[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.

Changes requested for this stack. A pull request lands only when it and every pull request below it are approved.

#8139 — request changes. Its record edits are now approved for its head; one fix remains:

  • Miss: each drop in a reorderable List, TransferList or ListInput, and each reorder-mode move on a touch screen, forces extra style recalculations because rebase() (lines 1721-1764) and slideCommitted() (lines 1703-1719) in listReorderEngine.tsx read each row's layout after writing an earlier row's transform; reading every row's layout first, then writing and skipping rows already at rest, keeps each change to one layout.

#8143 — approve on its own. Non-blocking: in a disabled TransferList only the selected panel dims.

#8163 — approve on its own. No blocking findings in its own changes. Non-blocking: the comment at ListInput.tsx L593-596 could keep only its constraint ("A disabled or loading list keeps its handles focusable but inert.").

Whole stack: changes requested, because #8139's layout reads reach every collection in the stack.

[Automated review]

vjeux added 2 commits November 8, 2026 04:49
A drop read each row's layout after writing the row before it, and
read the theme's motion tempo again for each gliding row. So it forced
one style pass per row: 30 for a 30-row list in Chromium. A reorder
mode key move read each row between glides too, then scrolled to the
row and placed the insertion line after the glides had started.

Both now read every row, the line's place and the scroll first, and
write after. A row left at rest at 0 takes no write, since each
animator write reads its style back. The scroll now runs before the
rows slide, so it brings the row's new place into view, not its old
one. A spring back reads the tempo once too.
Where the primary pointer is coarse, a reorder mode move forces one
style pass for each row that glides for the first time: the shared
animator reads the row's will-change then. The List record names this
as an implementation gap.
@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 3a1c5e5

cixzhang and others added 4 commits November 8, 2026 06:01
Main's meta#8215 rewrote the zoom section of motion/MEASUREMENTS.md, the
last section before the reorder section this pull request appends.
The resolution keeps main's zoom text and table, then the reorder
section as it was.
The reorder section and the reorder constants' sources named their
measurement batches by a label the repository never defines. They now
give the lab, device and date, as the other measured sources do.
@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec d858d64

@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.

Approved pending CI for the whole stack: the build and test workflow has not run on this head yet.

#8139 — approve. The drop and reorder-mode move now read every row before they write, and CI passes on its head.

#8143 — approve. Its own change is unchanged and still looks right.

#8163 — approve. Its own change is unchanged and still looks right.

Whole stack — passes. Next: packages/core/src/motion/MEASUREMENTS.md (#8139) now conflicts with main, where the Lightbox change appended its own table, so merging main into #8139 and up the stack lets CI run. A pull request lands only when it and every pull request below it are approved.

Non-blocking: the INV29 comment at ListInput.tsx:593-596 can keep only its constraint, and #8143's and #8163's descriptions still name the heads they merged before.

[Automated review]

@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec d3b8e98

@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.

Approved for the whole stack: CI passes on this head.

#8139 — approve. Merging main resolved the MEASUREMENTS.md conflict, and the reorder measurements now cite their lab, device and date; CI passes on its head.

#8143 — approve. Its own change is unchanged and still looks right, and this head now contains it, so the stack holds again; CI passes on its head.

#8163 — approve. Its own change is unchanged and still looks right.

Whole stack — passes. A pull request lands only when it and every pull request below it are approved.

Non-blocking: the comment at ListInput.tsx:593-596 can keep only its constraint, and this description still names the heads it merged before.

[Automated review]

@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec d3b8e98

1 similar comment
@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec d3b8e98

This branch was successfully deployed

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

Labels

ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) ci:run-a11y Run the accessibility suite on this PR; write access, next push (AST-030 FR12) 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