Skip to content

finding: 9 catalog flex nodes still hand-write spacing as space-x-*, the one spelling #4891's sweep deliberately left behind #5690

Description

@os-sales

Observation-class finding, recorded while implementing #4891 + #4890 (the two-card catalog sweep). Not fixed there — that card's criterion was the token set it enumerated (items-* / justify-* / gap-N / flex-wrap / flex-row|col / max-w-* / mx-auto / p-N / space-y-N / grid-cols-N), and space-x-* is not in it. That is not an oversight in the card: excluding it is exactly why the card's headline figure re-measured to the digit (flex 221 tokens, container 7, stack 3 — 231 across 140 nodes).

The observation

Nine flex nodes in the catalog spell horizontal spacing as a Tailwind utility on a node whose own type declares gap:

  • auth/login-simple.children[0].children[2].children[0]className: "space-x-2"
  • auth/signup.children[0].children[3]className: "space-x-2"
  • dashboard/recent-activity-card.children[0].children[1].children[0].children[0]className: "space-x-4"
  • dashboard/recent-activity-card.children[0].children[1].children[1].children[0]className: "space-x-4"
  • dashboard/recent-activity-card.children[0].children[1].children[2].children[0]className: "space-x-4"
  • dashboard/recent-activity-card.children[0].children[1].children[3].children[0]className: "space-x-4"
  • dashboard/recent-activity-card.children[0].children[1].children[4].children[0]className: "space-x-4"
  • forms/newsletter-signup.children[0].children[2]className: "space-x-2"
  • forms/settings-form.children[1].children[0].children[3]className: "space-x-2"

(Five of those nine now carry align: "center" from the #4891 sweep, which took the items-center off the same class strings and left the space-x-* untouched. space-y-* on a stack: 0 nodes, measured — the sibling spelling is not present.)

Same reader-facing cost as #4891: these are shipped reference examples and an AI few-shot retrieval source, and what they demonstrate is spacing a first-class layout component by hand instead of with its gap.

Why it is a separate decision, not a rename #4891 could have absorbed

space-x-N and gap: N are not two spellings of one thing, so this cannot be waved through as mechanical the way spacinggap was:

  1. Different CSS.space-x-N compiles to a margin on & > :not(:last-child) ~ *; gap is the flexbox gap property. They diverge wherever the child list is not a simple static row — a wrapped line gets no space-x gutter between rows, and the selector is order-sensitive in a way gap is not.
  2. Different responsive behaviour.gap: N renders a mobile-first ladder in flex.tsx (gap: 3gap-2 sm:gap-3); space-x-4 is one dead value at every width. So a conversion is a real rendering change at small breakpoints, needing the same sampled-equivalence treatment catalog:140 个已经是 flex/stack/container 的节点,仍在 className 里手写自己已声明的 props #4891's conversions got — not a byte-equivalence claim.
  3. It may be deliberate somewhere. A node that genuinely wants "gutters between siblings but no gutter above a wrapped row" is asking for space-x. Whether any of these nine is that node has not been checked.

So the question triage owns is whether these nine are drift or intent, and that is a different question from the one #4891 answered.

Suggested shape, if triage rules it drift

If triage rules it intent, the honest close is the opposite edit: leave the nodes and record in that helper's docblock why space-x-* is excluded, so the next sweep does not re-litigate it.

References

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:queue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions