-
Notifications
You must be signed in to change notification settings - Fork 0
Review 4590
#4590 · jiunshinn · aged-PR cleanup Step 3, batch 3, 2026-08-23
Verdict: changes requested + ruling
ListItem insets row content by a density-dependent 8/12px, so a list under a section heading reads as misaligned and consumers reach for negative-margin CSS (#2626).
A List.isEdgeAligned boolean applying a matching negative marginInline to the <ul>, mirroring Item's own --spacing-2 / --spacing-3.
-
List.isEdgeAligned?: boolean = false(public, core barrel)
no new theme targets
Class exists — Divider has isFullBleed, Table has an edge adjustment, and #3938 wants one on TabList. But every existing member is container-aware (calc(-1 * var(--container-padding-inline-start, 0px)) plus a width compensation, Divider.tsx:116-129) and spelled isFullBleed. This member picks a different name and a different mechanism, deliberately and with a written argument.
API no (new opt-in prop, default false) · Visual no for existing consumers; for opt-in the <ul> grows 8px past its parent on each side (measured 884 vs 868) · Theme no new targets, but see judgement
Chromium, core-list--edge-aligned at 900px on the PR head. Default theme: heading text and row text both at x=16 — the feature works. Inject .astryx-item{padding-inline:var(--spacing-3)} (the value butter already writes on eight targets): row text moves to x=20, heading stays at 16. Frames 4590__A-default.png and 4590__B-theme-item-spacing3.png, both opened and looked at.
request changes. [BLOCKS] the cancel margin mirrors a value Item owns and themes routinely change, so it is off by the difference under such a theme — the same off-by-4 the PR's own description flags in the detail-page template, one level up (R3d, same shape one step sideways). [ruling] naming and mechanism: Cindy's own comment on #2626 says isFullBleed is 'not quite accurate' and that this 'depends on container awareness'. The PR argues against the container-padding mechanism, well. That call is hers, not mine, and I said so on the PR rather than picking.
Needs a Rulings entry: does the edge-adjustment family take a second mechanism (cancel the item's own inset) alongside the container-padding one, and under what name?
See the review on #4590. Attribution: [Reviewed by Robohands].
(posted directly by the loop under the aged-PR brief; nothing edited)
f0422bfac22eabd2f710bb650ed1e1274b73f14e
- LOOP VERSION: 1.4.0
- AUDIT RUBRIC: 1.12
- LANE: full — prior changes-requested, public API, intended visible layout
A builder placing a List beneath a heading sees each row label begin 8/12px farther inward because Item owns an inline inset; custom negative-margin CSS is currently required to align them.
VERDICT: clear — #2626, the PR body, and the rendered 16px case demonstrate it.
List opts each ListItem into content compensation. Item publishes its density/theme-controlled inline inset; the row subtracts the smaller of that inset and the surrounding container padding, leaving its own padding and hover/selection paint intact.
1 decision · ~15 runtime lines of 228 changed lines: add optional List full-bleed compensation, with the Item inset var, theme-derived mapping, row clamp, docs, story, tests, and changeset as its evidence.
The current implementation uses the inline-start container value for both row margins. It is correct for symmetric and 0px containers, but not for the documented asymmetric container contract.
VERDICT: BLOCKS — the end margin is not clamped to the end-edge padding.
- OWNER: List/ListItem presentation, consuming the container-padding protocol
- SEAMS: themed Item padding, standalone ListItem, symmetric/zero/asymmetric containers, LTR and RTL
- BEHAVIOR UNIT: inline StyleX — one small deterministic layout rule; no hook or utility boundary is warranted
Placement is correct: the row is the only element that can read Item's own var, and ListContext owns the opt-in. Each margin must consume its matching container edge.
VERDICT: clear — owner and seam are settled; the value error is recorded below.
Existing callers are unchanged because isFullBleed defaults false. Opted-in callers with symmetric padding align correctly, and a 0px container now stays unchanged.
In a supported asymmetric 16px-start/4px-end container, the selected row over-cancels the end by 4px and paints 2px beyond the fixture's outer border. RTL mirrors the spill.
VERDICT: BLOCKS — a visible opt-in layout defect remains.
<List isFullBleed>
<ListItem label="Solstice Mug" />
</List>+ List.isFullBleed?: boolean = false — public through the existing @astryxdesign/core/List surface.
Ruling 3 settled the public name and meaning. Divider.isFullBleed is the landed sibling; List is the content-compensation member of that class.
VERDICT: clear — no API decision remains.
No theme target is added or removed. Item adds private --_item-inset-inline, documents it, and maps item.paddingInline through the derived-var registry.
VERDICT: BLOCKS — ListItem.tsx:136-137 expands the start-edge value onto both logical margins instead of reading the matching end-edge variable.
- API: no — optional prop, default false
- Visual: intentional for opted-in symmetric containers; asymmetric end padding currently over-pulls
- Theme: no target/token/override removed; one private derived var added, but the end-edge container override is ignored
- Behavior: no existing caller changes; opt-in only
VERDICT: BLOCKS — the documented asymmetric container path is wrong.
No effects, listeners, observers, layout reads, or dependencies. One boolean joins the existing memoized ListContext value; CSS min()/calc() owns the geometry.
VERDICT: clear.
VISUAL CHECK: manual frames required — the PR intentionally moves row geometry, and exact-head visual CI had no baseline for the new story.
The four frames that carry the remaining block were captured with captureWithSensors(), opened, and published below: one decisive LTR exact-head/control pair and the matching RTL control pair. The prior 0px finding is closed and its boundary pair is intentionally omitted from this minimal published set.
| Sensor | Exact head | Per-edge arm | Pass? |
|---|---|---|---|
| Build | f0422bfac22eabd2f710bb650ed1e1274b73f14e |
same SHA + per-edge-arm.diff
|
yes |
| Story | zzreview-list4590r3--asymmetric |
same | yes |
| Theme / mode |
review-4590-evidence / light |
same | yes |
| Direction | LTR pair: LTR; RTL pair: RTL | same per pair | yes |
| Viewport / media | 920×540@1; forced-colors off; reduced-motion off; fine pointer; hover | same | yes |
| Rendered state | asymmetric-16-4:enabled=true:rows=1:selected=1 |
same | yes |
| Subject geometry |
[data-capture] at x=16, y=16, 888×172.28125; visible and inside viewport |
same | yes |
| Settled / errors | fonts loaded; 0 animations; no Storybook or page error | same | yes |
| Image | LTR aa58acea…; RTL a65f3365…
|
LTR 9a34acf0…; RTL b1d9af4a…
|
nonblank, 920×540 |
Exact head f0422bf
|
Per-edge arm |
|---|---|
![]() |
![]() |
| −8px / −8px margins; label aligned; 2px logical-end spill | −8px / −4px margins; label aligned; spill 0 |
Exact head f0422bf
|
Per-edge arm |
|---|---|
![]() |
![]() |
| same logical-end spill, mirrored physically | same correction; spill 0 |
Receipts: exact-head LTR · arm LTR · exact-head RTL · arm RTL. Full compact receipt and arm provenance: assets/pr-4590/round-2/README.md.
The exact-head/control pixel change is confined to a 14×56 strip at logical end (252 pixels) in each direction.
VERDICT: BLOCKS — the 0px ask is fixed; the per-edge clamp is not.
The correction arm changed only the two logical margins; unrelated production delta: none.
fullBleed: {
- marginInline:
+ marginInlineStart:
'calc(-1 * min(var(--_item-inset-inline), var(--container-padding-inline-start, 0px)))',
+ marginInlineEnd:
+ 'calc(-1 * min(var(--_item-inset-inline), var(--container-padding-inline-end, 0px)))',
},The source worktree was restored to the exact head after capture.
No role, name, keyboard, focus, live-region, or user/AT string changes. Exact-head pr-a11y and pr-rtl are green; the direction-sensitive layout was driven manually in RTL.
VERDICT: clear.
- Focused List/theme run: 3 files, 185 tests passed
-
pnpm check:changesets: 29 valid -
git diff --check: clean - Exact-head CI: lint, test, build, Storybook, a11y, visual, RTL, docsite, dependency, and scope jobs green
- GitHub reports
CONFLICTING/DIRTY: #5288 landed List BaseProps forwarding on main; the rebase must preserve its...propsand externalaria-labelledbybehavior, plus both registry-test additions
- 2026-08-23 mirrored Item inset — fixed and deleted. The var, derived mapping, tests, and visible Item/List parity all hold.
- 2026-08-26 rename to
isFullBleed— fixed and deleted across API, docs, story, context, tests, and changeset. - 2026-08-26 clamp to container padding; 0px unchanged — partly fixed. Symmetric and 0px pass; the shorthand applies the start-edge value to the end edge.
- Current main movement — #5288 creates a conflict whose resolution must preserve the newly landed List passthrough behavior.
JUDGEMENT NEEDED: none — Ruling 3 already made the API/design decision; this is implementation correctness and integration.
-
BLOCKS:
marginInlineapplies the start-edge container padding to both edges (packages/core/src/List/ListItem.tsx:136-137). → In an opted-in 16px/4px container, the selected row paints beyond logical end in LTR and RTL. The isolated per-edge arm removes the spill while preserving alignment and 0px. - BLOCKS: current main conflicts with the branch. → The author must rebase while preserving both this change and List's newly landed BaseProps/label forwarding.
GOAL: partly met — symmetric padding aligns and 0px stays unchanged; asymmetric end padding remains over-cancelled.
DISPOSITION: both findings block this head.
ADVICE: proven remedy — use separate logical margins with matching per-edge variables, then resolve the main conflict preserving both behaviors.
AUTHOR CAN PROCEED: yes — acceptance is explicit: each logical edge clamps against its matching container var; 16/4 has no spill in LTR/RTL; 0px remains unchanged; the rebase retains ...props and external aria-labelledby; focused tests and required CI are green on the rebased head.
WORST OUTCOME: “With isFullBleed in an asymmetric 16px/4px container, the selected row paints beyond the outer border on logical end in both LTR and RTL.” → request changes.
Final verdict: request changes.
Thanks — f0422bf keeps the var-derived inset fix and closes my
isFullBleedand 0px-clamp asks.One clamp edge is still wrong.
ListItem.tsx:136applies--container-padding-inline-startto both margins. With 16px start/4px end padding, the selected row over-cancels the end by 4px and paints past the outer border; RTL mirrors the spill. Using the matching start/end vars removes it without changing label alignment or the 0px case.Main also moved under this in #5288, and GitHub now reports a conflict. Could you fix the end-edge clamp, then rebase while preserving List's new
...props/externalaria-labelledbyforwarding and both registry-test additions?If you'd rather talk it through with someone, we're in Discord.
[Reviewed by Robohands]
Pass 1 failed because JUDGEMENT lacked the numbered anchored consequence and receipt tables omitted exact subject geometry. The rewrite added both. Rewrite check: PASS — no remaining critic violations.
Wiki evidence publication completed under assets/pr-4590/round-2; no GitHub PR review, comment, code push, merge, auto-merge, or workflow approval was performed.



