Repository navigation
Conversation
List's FR2 keeps the `padded` treatment's row geometry everywhere. Under a coarse primary pointer, a new FR10 lets a default or spacious ListItem row reach the iOS 26.2 UITableView row heights: at least 52 px, and 62 px with a description. Compact rows and fine pointers keep their geometry, and a theme's `min-height` on the `list-item` target still wins. FR2, the allowed variations, the `padded` representative state and the verification map name the exception.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
There was a problem hiding this comment.
This spec change needs an engineering owner's decision before it can be approved: FR10 and the narrowed FR2 change the current component:List row-geometry contract, including whether a theme min-height on list-item becomes a guaranteed override, and this head has no owner approval yet. 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; because a new commit resets that approval, it is worth making the fixes below first.
- Compatibility and migration (line 66) and the Contract at a glance row (line 48) still say omission keeps current ListItem geometry, so they should state that
balancedandspaciousrows grow under a coarse pointer and that a thememin-heightonlist-itemkeeps the released height. - The FR10 verification row (line 205) fills three of the map's five cells and needs its failure expectation and audit section.
- FR10, the allowed-variation bullet and the verification row say "default" where List's density value is
balanced(the default).
[Automated review]
| | ID | Invariant | Basis | Status | | ||
| | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | | ||
| | FR1 | List MUST own `edge` and apply one treatment to every ListItem row, interactive or not; ListItem MUST NOT expose a parallel public prop. A defined `edge` MUST win over `edgeCompensation`, and `edgeCompensation="inline"` with `edge` undefined MUST resolve to `outset`. | `component:List/DEC-1`, `component:List/DEC-3` | Accepted contract | | ||
| | FR2 | `padded` MUST preserve current header, list, and row geometry, apart from FR10's minimum row height under a finger. No treatment MAY move the header or change row block padding, gap, markers, start and end content, semantics, or hit target relative to the row box. | Owner direction | Accepted contract | |
There was a problem hiding this comment.
With this carve-out, a List that sets no props changes row height under a coarse pointer, but Compatibility and migration (line 66) still says "Released default preserved: yes; omission keeps current List and ListItem geometry", and the Contract at a glance row (line 48) says "omission keeps current geometry". Could both state that balanced and spacious rows grow to FR10's floor under a coarse pointer, and that a theme min-height on list-item keeps the released height?
| | FR7 | Each row's retained inset MUST come from the same private density- and theme-derived source as Item's applied inline padding. A theme `item.paddingInline` override takes precedence over every treatment's row padding, as it does over density. A consumer override of row padding through `xstyle`, `className`, or `style` is outside the alignment guarantee. | Shared two-owner geometry contract | Accepted contract | | ||
| | FR8 | `outset` and `bleed` are valid only under a host state whose published inline inset matches its applied padding: a visually neutral host, such as a Layout region with explicit padding or a padded ScrollableArea, or the content area of a Card, Section (any variant), Dialog, or BottomSheet. Those hosts bound their padding with a border, background, or clip; FR6 keeps row paint inside the padding edge, so it never covers the border or changes the host's outline. Automatic LayoutContent/LayoutPanel states with a known publication mismatch are not eligible until that gap is fixed, and Drawer's content area is not admitted until it has its own evidence. | `architecture:container-padding/INV8–INV11`; real-browser evidence in each admitted host | Accepted contract | | ||
| | FR9 | The list element containing the rows MUST clip in the inline axis with `overflow-inline: clip`, never `hidden`. Under `outset` and `bleed` its inline edges MUST reach the host's padding edge, so the clip never cuts resting row paint and a swiped row paints no further than that edge. | `spec:AST-057/FR9` | Verified by `List.test.tsx` and real-browser geometry | | ||
| | FR10 | Under a coarse primary pointer (`spec:AST-094` FR13), a ListItem row at the default or spacious density MUST be at least 52 px tall, and at least 62 px when it has a description; its content keeps its alignment in the taller row. A compact row keeps its geometry, and a fine pointer keeps every row's geometry. A theme's `min-height` on the `list-item` target takes precedence. | iOS 26.2 `UITableView` row heights: 52 pt, and 62 pt with a subtitle; owner direction that dense lists keep their density | Accepted contract | |
There was a problem hiding this comment.
List's density values are compact, balanced and spacious, with balanced the default (ListContext.tsx, List.tsx). Naming balanced here, and in the allowed-variation bullet and the verification row, makes it explicit that a List passing density="balanced" is covered too.
| | ------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | | ||
| | FR1–FR7, FR9 | List, Item, and theme-registry tests | every treatment; all densities; static and interactive rows; header; deprecated alias alone and with `edge`; ListItem outside a List | Removing context propagation, using one host edge for both inline edges, zeroing padding without the shared inset source, or dropping the list's reach or clip fails | `audit:List/layout` | | ||
| | FR2–FR6, FR8–FR9, AR1–AR2 | Real-browser List geometry evidence | each treatment in a Card at two paddings, a Section, an inline Dialog with and without Layout, a BottomSheet, a padded ScrollableArea scrolling vertically and in both axes, a LayoutContent with explicit padding, and standalone; header and dividers; LTR/RTL; hovered and selected rows; a swiped row under `outset` and `bleed` | Header movement, content off the expected line, paint past the host's padding edge, clipped resting paint, or a changed row box fails | `audit:List/visual` | | ||
| | FR10 | List tests of the touch rule and the built stylesheet; real-browser row heights | default, spacious, and compact densities; a row with a description; a fine pointer; a theme `min-height` | |
There was a problem hiding this comment.
This row fills three of the map's five cells. Could it state the failure expectation and audit section, for example "A balanced or spacious row under 52 px (62 px with a description) under a coarse pointer, a changed compact or fine-pointer row, or a theme min-height that loses, fails" and audit:List/layout?
|
Posted by Cindy's agent on her behalf. Thanks for measuring the iOS table rows. Cindy's decision on List rows on phones: no row-height change. Under a touch pointer only, a List row guarantees a 44 px hit target through padding or a hit area, with no visual change. Taller iOS-style row heights are being collected with other phone size differences, to be handled through mobile theme adaptations later, not in the List component. Could you rework this record PR to state the 44 px touch target instead of the 52/62 px minimums? |
|
/approve-spec d7ab924 |
|
/approve-spec b5d035a |
There was a problem hiding this comment.
The direction of FR10 and the FR2 carve-out is approved for this head, but two record fixes are needed, and the fixed head will need a fresh /approve-spec <full head SHA> comment from an engineering owner (the author may record it as one).
- The allowed-variation bullet (lines 132–133) promises every row a 44 px target, while FR10's room condition and half-gap clamp leave a 40 px default row on a phone at 42 px; cite FR10 with its condition or drop the bullet.
- The FR10 verification row (line 205) still needs its failure expectation and audit section.
- The writing-rubric results in the description describe the superseded 52/62 px record; please re-run them for this text.
[Automated review]
| - Under a coarse primary pointer, every row's hit target is at least 44 px | ||
| tall (FR10); row geometry and appearance are unchanged. |
There was a problem hiding this comment.
This restates FR10 without its condition: FR10 grants 44 px only where neighbours leave room and clamps the target to half a gap, so a 40 px default row on a phone, 2 px from the next row, gets 42 px, and a compact row with dividers keeps its box. Could it cite FR10 with the condition, for example "Under a coarse primary pointer, a row's hit target grows toward 44 px where its neighbors leave room (FR10); row geometry and appearance are unchanged", or be dropped?
| | ------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | | ||
| | FR1–FR7, FR9 | List, Item, and theme-registry tests | every treatment; all densities; static and interactive rows; header; deprecated alias alone and with `edge`; ListItem outside a List | Removing context propagation, using one host edge for both inline edges, zeroing padding without the shared inset source, or dropping the list's reach or clip fails | `audit:List/layout` | | ||
| | FR2–FR6, FR8–FR9, AR1–AR2 | Real-browser List geometry evidence | each treatment in a Card at two paddings, a Section, an inline Dialog with and without Layout, a BottomSheet, a padded ScrollableArea scrolling vertically and in both axes, a LayoutContent with explicit padding, and standalone; header and dividers; LTR/RTL; hovered and selected rows; a swiped row under `outset` and `bleed` | Header movement, content off the expected line, paint past the host's padding edge, clipped resting paint, or a changed row box fails | `audit:List/visual` | | ||
| | FR10 | List tests of the touch hit target and real-browser hit-testing | every density; a row with a description; compact rows packed closer than 44 px; a row with an end control; a coarse and a fine pointer; a theme row padding | |
There was a problem hiding this comment.
This row still fills three of the map's five cells. Could it state the failure expectation and audit section, for example "A coarse-pointer row whose target stays at its box where its neighbors leave room, a target that reaches a neighboring row's or control's target, a changed row box, or a changed fine-pointer target fails" and audit:List/layout?
…rification row states failure and audit The allowed-variation bullet promised every row a 44 px target, while FR10 grows a row's target toward 44 px only where its neighbors leave room and clamps it to half a gap: it now says so and cites FR10. FR10's verification row gains its failure expectation and its audit section (`audit:List/layout`), like the map's other rows.
There was a problem hiding this comment.
This spec change needs an engineering owner's decision on this exact head before it can be approved: FR10 and the FR2 carve-out are new component:List requirements, and the earlier /approve-spec comments name previous commits, so the latest commit reset that approval. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request, and the author may do so as an engineering owner; because a new commit resets approval again, it is worth making these two fixes first:
- Name FR10's coarse-pointer hit target in List's ownership boundary (the Owns list, and line 188, which still says List owns only the collection-level treatment and row placement) and in the Contract at a glance, including that it is specified and not implemented yet.
- Re-run the writing rubric for this text and update
## Writing rubric results, which still describe the 52/62 px record; FR10's "A fine pointer keeps today's hit target" is the kind of day-relative wording R1 catches.
[Automated review]
| | FR7 | Each row's retained inset MUST come from the same private density- and theme-derived source as Item's applied inline padding. A theme `item.paddingInline` override takes precedence over every treatment's row padding, as it does over density. A consumer override of row padding through `xstyle`, `className`, or `style` is outside the alignment guarantee. | Shared two-owner geometry contract | Accepted contract | | ||
| | FR8 | `outset` and `bleed` are valid only under a host state whose published inline inset matches its applied padding: a visually neutral host, such as a Layout region with explicit padding or a padded ScrollableArea, or the content area of a Card, Section (any variant), Dialog, or BottomSheet. Those hosts bound their padding with a border, background, or clip; FR6 keeps row paint inside the padding edge, so it never covers the border or changes the host's outline. Automatic LayoutContent/LayoutPanel states with a known publication mismatch are not eligible until that gap is fixed, and Drawer's content area is not admitted until it has its own evidence. | `architecture:container-padding/INV8–INV11`; real-browser evidence in each admitted host | Accepted contract | | ||
| | FR9 | The list element containing the rows MUST clip in the inline axis with `overflow-inline: clip`, never `hidden`. Under `outset` and `bleed` its inline edges MUST reach the host's padding edge, so the clip never cuts resting row paint and a swiped row paints no further than that edge. | `spec:AST-057/FR9` | Verified by `List.test.tsx` and real-browser geometry | | ||
| | FR10 | Under a coarse primary pointer (`spec:AST-094` FR13), every ListItem row MUST offer a hit target at least 44 px tall, through its padding or an invisible hit area, with no visual change, where its neighbors leave room: the hit area never overlaps a neighboring row's or control's target, and between close neighbors it is clamped to half the gap; row height and geometry stay as they are at every density. A fine pointer keeps today's hit target. | Owner decision, 2026-10-26: no row-height change, a 44 px touch target | Accepted contract | |
There was a problem hiding this comment.
FR10 adds a row hit-target rule, but the record's ownership boundary still says List owns only "the collection-level treatment and row placement" (line 188, and the Owns list), and the Contract at a glance never mentions FR10 or that it is specified and not implemented yet. Naming the target in both places keeps FR10 inside the boundary that architecture:knowledge-contracts INV14 scopes authority to. Separately, "A fine pointer keeps today's hit target" is day-relative; "A fine pointer's hit target stays the row box" says the same thing durably.
|
/approve-spec 55b54e5 |
|
Closing: this record's FR10 text is already on main, word for word, from #8687 (merged Oct 27), so merging main leaves this pull request with no changes. |
Exact decision needed
List's FR2 keeps
paddedrow geometry everywhere. Under a finger, may a default or spacious row be at least 52 px tall (62 px with a description), the iOS 26.2 table row heights, while compact rows and fine pointers keep theirs?Existing authority searched
component:List(FR2 rules a touch row height out; FR7, variations, states, verification map) andspec:AST-094FR13 (the touch query). No open pull request amends core'sList.spec.md;component:swift/Listis a separate record. #8085 implements this.Decision
FR2 keeps
paddedgeometry apart from a new FR10: under a coarse primary pointer, a default or spacious row is at least 52 px tall (62 px with a description), its content aligned as before; compact rows and fine pointers keep their geometry; a theme'smin-heightonlist-itemwins. The variations, thepaddedstate and the verification map name FR10.Rejected alternatives
Claim scope and non-goals
Touch row minimum heights only; not Dynamic Type, padding, dividers or markers.
Evidence and implementation relationship
iOS 26.2
UITableViewrows read from the views: 52 pt, 62 pt with a subtitle. #8085 implements it under@media (pointer: coarse)with unit, stylesheet and browser proofs, after an engineering owner's spec approval of this record. Prettier re-pads the FR table forFR10; only FR2 and FR10 change text.Writing rubric results
Re-run on the current record (FR2's carve-out, FR10, the allowed-variation bullet, the
paddedstate, FR10's verification row):Scope
Validation
pnpm check:knowledge(aligned), Prettier andgit diff --check: clean.