Skip to content

Stamp data-card-field on rendered field boundaries - #5901

Open
lukemelia wants to merge 2 commits into
mainfrom
cs-12091-stamp-data-card-field-on-rendered-field-boundaries
Open

Stamp data-card-field on rendered field boundaries#5901
lukemelia wants to merge 2 commits into
mainfrom
cs-12091-stamp-data-card-field-on-rendered-field-boundaries

Conversation

@lukemelia

Copy link
Copy Markdown
Contributor

Selector-based screenshot capture (target) and region inventory (discover) need to address rendered fields in templates that never opted into any capture markup. Authored data-* attributes already survive into the indexed per-format HTML, so the base realm's field rendering now stamps the boundary attribute those capabilities will consume.

Changes

Every rendered field boundary carries data-card-field="<fieldName>":

  • packages/base/field-component.gts — on the card-as-field container (the element carrying .field-component-card) and on the compound-field wrapper.
  • packages/base/contains-many-component.gts / links-to-many-component.gts — on the plural *-field wrappers. Each plural item boundary repeats the plural field's name (a linksToMany item renders through the card-as-field container with the plural field as its context), since every item is a rendered boundary of that field.

The attribute is stamped unconditionally and is inert for CSS. Two deliberate boundaries of the contract:

  • The card root carries no data-card-field — it has no field context. This also keeps the exact-HTML snapshot assertions in realm-indexing-test byte-identical (they cover root renders only).
  • Primitive leaf fields are unstamped — they render bare, with no wrapper element; introducing one would not be CSS-inert. Region discovery addresses the wrapper-level boundaries: card fields, compound fields, and plurals.

data-card-format on the card root was considered and skipped: the root already carries data-boxel-card-format into rendered and indexed HTML, so a second format attribute would duplicate it without a consumer.

Testing

New integration test in card-basics-test.gts renders a card with all four boundary kinds (compound contains, containsMany, linksTo, linksToMany) and asserts the attribute on each wrapper, the repeated name on plural item boundaries, and its absence on the card root.

Verified against the dev stack: the new test 6/6; full Integration | card-basics 437/437; Integration | realm indexing (the exact-HTML snapshot suite) 145/145.

🤖 Generated with Claude Code

Selector-based screenshot capture and region discovery need to address
fields in templates that never opted into any capture markup. Every
rendered field boundary now carries data-card-field=<fieldName>:

- the card-as-field container and the compound-field wrapper in
  field-component.gts
- the plural-field wrappers in contains-many-component.gts and
  links-to-many-component.gts (each plural item boundary repeats the
  plural field's name, since every item is a boundary of that field)

The attribute is stamped unconditionally and is inert for CSS. A card
rendered at the root has no field context, so it carries no
data-card-field — which also keeps the exact-HTML snapshot assertions in
realm-indexing-test byte-identical (they cover root renders only).

data-card-format on the card root was considered and skipped: the root
already carries data-boxel-card-format into rendered and indexed HTML,
so a second format attribute would duplicate it without a consumer.

Primitive leaf fields render bare (no wrapper element), so they are
deliberately unstamped — adding a wrapper would not be CSS-inert.

New integration test covers all four boundary kinds plus the
root-carries-nothing case. Verified against the dev stack:
card-basics 437/437, realm indexing 145/145.

Includes prettier reflow of one pre-existing over-width line in each
plural component.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Preview deployments

Host Test Results

    1 files  ±0      1 suites  ±0   2h 16m 40s ⏱️ - 4m 17s
4 547 tests +2  4 533 ✅ +2  14 💤 ±0  0 ❌ ±0 
4 566 runs  +2  4 552 ✅ +2  14 💤 ±0  0 ❌ ±0 

Results for commit 12b9754. ± Comparison against earlier commit b3543a8.

Realm Server Test Results

    1 files  ±0      1 suites  ±0   15m 20s ⏱️ + 2m 1s
2 336 tests ±0  2 336 ✅ ±0  0 💤 ±0  0 ❌ ±0 
2 419 runs  ±0  2 419 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 12b9754. ± Comparison against earlier commit b3543a8.

@lukemelia lukemelia left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] Self-review focused on the completeness of the data-card-field boundary set — whether region discovery (the downstream consumer) can address every field kind — and on the exact-HTML snapshot suites the stamp could disturb. It did not re-run the full host suite beyond the two modules already verified.

Bottom line: no blocking issues; one coverage asymmetry worth a decision before the discovery consumer lands. The view-format set is complete and correct — card-as-field, compound, and both plural wrappers are stamped; the card root and primitive leaves are correctly bare; and the snapshot assertions stay byte-identical because they only cover root renders. The gap is edit format: the two plural editors carry no data-card-field, so a containsMany(StringField) shown in edit has no boundary naming the field at all.

One finding, in the inline thread: decide whether discovery is expected to run on edit surfaces, and either stamp the two *-editor wrappers or scope the contract to view.

CI: only the routine Percy snapshot-approval gate is red; host suites and typecheck are green.

Comment thread packages/base/field-component.gts Outdated
}}
{{#if (isCard model.value)}}
{{#let model.value as |card|}}
{{! Every rendered field boundary carries

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] This comment opens "Every rendered field boundary carries data-card-field", but the edit-format plural boundaries don't — and one field kind ends up with no boundary at all. containsMany renders through contains-many-editor and linksToMany through links-to-many-editor in edit format (both in their own components), and neither carries data-card-field; only their view-format plural-field siblings, stamped here, do. For a plural of cards the individual items still get an inner .field-component-card[data-card-field] in edit, but for a plural of primitivescontainsMany(StringField) — the items render bare, so in edit format nothing anywhere names that field. Region discovery inventorying [data-card-field] can't address it.

The singular editors are fine: LinksToEditor passes its field to getBoxComponent, so the inner card boundary is stamped in edit too — it's only the two plural editors that are unstamped.

The decision this turns on: is discover expected to run on edit surfaces, or only on the view formats screenshots are taken of? If edit matters, stamp data-card-field={{@field.name}} on the contains-many-editor and links-to-many-editor wrappers (one line each). If it doesn't, soften this comment's "Every rendered field boundary" to name the view boundaries it actually covers, so the next reader doesn't take edit coverage as given.

Class: this PR — a coverage/wording gap, not a regression (nothing reads data-card-field yet). Non-blocking; the ticket scoped to the view *-field wrappers, so shipping view-only is defensible with the comment corrected.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] Resolved in 12b9754 — stamped data-card-field on the contains-many-editor and links-to-many-editor wrappers, so discovery addresses plural fields in edit format too (and a containsMany of primitives, which has no per-item boundary, is now nameable via the editor wrapper). This comment is corrected to name the view+edit boundaries it actually covers and the render-bare cases it omits. The boundary test now renders the card in edit format and asserts both editor wrappers; card-basics 439/439 against the dev stack.

The view-format plural wrappers carried data-card-field but their
edit-format counterparts did not, so region discovery over
[data-card-field] could not address a containsMany/linksToMany field
shown in edit format — and a containsMany of primitives had no boundary
naming the field anywhere in edit, since its items render bare. Stamp
contains-many-editor and links-to-many-editor to match, giving the
contract one shape across both formats.

The field-component.gts comment is corrected to match: it previously
read "Every rendered field boundary carries data-card-field", which
overclaimed against this gap and against primitive leaves that render
with no wrapper to carry it.

The boundary test now renders the same card in edit format and asserts
both editor wrappers carry the field name. card-basics 439/439 against
the dev stack.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lukemelia
lukemelia requested review from a team and burieberry August 26, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants