Skip to content

kind:'html' page source loses the space between a text run and an adjacent inline element — A <strong>x</strong> page renders as Axpage #5661

Description

@os-sales

Found while implementing #5470 (rewriting apps/console/src/sdui-tiers-preview.tsx's
page sources off Tailwind). Filing rather than fixing — outside that card's declared file
surface, and it is in packages/sdui-parser, not the console.

What happens

packages/sdui-parser/src/parse.ts:177, inside the children loop:

consttext=this.readTextRun();consttrimmed=text.replace(/\s+/g,' ').trim();if(trimmed)children.push(trimmed);

The collapse (\s+ → one space) is correct and matches HTML's own whitespace model.
The .trim() is not: it deletes the leading and trailing space of every text run,
including the space that separates that run from an adjacent inline element. HTML
collapses a whitespace run to one space; it does not remove it.

Measured

Rendered through the real PageRenderer in Chromium against
apps/console/sdui-tiers-preview.html (vite dev), reading textContent:

sourcerendered
A <strong …>kind:'html'</strong> page — …Akind:'html'page — …
Full HTML tag set in the <em …>html</em> tier.Full HTML tag set in thehtmltier.
A trusted <a …>react tier</a> behind a flag.A trustedreact tierbehind a flag.

Present before and after#5470's change, byte-for-byte identical output — measured by
checking out apps/console/src/sdui-tiers-preview.tsx at 7e811687a (26 classNames in
its page sources, i.e. the pre-change file) and re-rendering the same page:

NEW "intro": "Akind:'html'page — native HTML tags and the blocks' structured props, …"
BASE "intro": "Akind:'html'page — plain native HTML tags, Tailwind classes, …"

So this is not a regression from that card — it is the tier's own behaviour, and it has
been visible in the repo's own worked example for as long as the example has existed.

Why it matters beyond the preview

kind:'html' is the tier the guide tells authors and AI agents to reach for by default
(content/docs/guide/react-pages.md §Choosing between them), and the tag set it advertises
is exactly the prose set — strong, em, a, code, b, i, abbr, q, cite
(packages/components/src/renderers/basic/html-elements.tsx). Any authored sentence with
emphasis or a link inside it renders with the words run together. It is silent: the page
renders, the structure is right, nothing reports anything.

What needs deciding

The fix is small but the exact rule is worth stating rather than guessing, because it is a
save-time parse that pins metadata:

  • (a) Replace .trim() with HTML's rule — collapse the run to a single space, and drop
    a run only when it is entirely whitespace and sits between block-level boundaries.
    Highest fidelity; needs a decision about what counts as a boundary in a schema tree that
    has no block/inline distinction of its own.
  • (b) Narrower: keep one leading/trailing space whenever the run is adjacent to a
    sibling element (rather than to the start/end of the parent). Mechanical, no boundary
    taxonomy, slightly over-generous inside block containers like <ul>.

Either way this changes parser output for existing sources, so it wants a pin in
packages/sdui-parser/src/__tests__ and a look at whether any snapshot depends on the
current trimming.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions