Skip to content

feat: add explicit f-host and f-shadow declarations - #7799

Open
Jane Chu (janechu) wants to merge 3 commits into
mainfrom
users/janechu/add-f-host
Open

Jane Chu (janechu) wants to merge 3 commits into
mainfrom
users/janechu/add-f-host

Conversation

@janechu

@janechu Jane Chu (janechu) commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Pull Request

📖 Description

Add optional direct-child metadata declarations: <f-host> for custom-element host defaults and bindings, and <f-shadow> for shadow-root configuration:

<f-template hidden name="my-button">
    <f-host role="button" tabindex="0" appearance="{{appearance}}"></f-host>
    <f-shadow shadowrootmode="open" shadowrootdelegatesfocus shadowrootclonable shadowrootserializable></f-shadow>
    <template>
        <slot></slot>
    </template>
</f-template>

The browser runtime consumes these declarations without registering or rendering metadata custom elements in the component. Static host attributes are defaults, preserving explicit instance attributes. Existing reactive bindings and event listeners continue through the normal template pipeline.

<f-shadow> accepts static shadowrootmode, shadowrootdelegatesfocus, shadowrootclonable, and shadowrootserializable options and defaults its mode to open. Attribute names match HTML's lowercase native DSD names without abbreviation or camel-casing. The same declaration configures browser-created roots, server-rendered native DSD, and conversion targets.

fast-build emits supported initial host values on the custom element before Declarative Shadow DOM, including streamed rendering, so CSS need not wait for client-side repair.

Remove legacy host-attribute forwarding from declarative definition/template elements. Update the authoring, design, SSR, and migration documentation and migrate the host-binding fixtures.

🎫 Issues

Closes #7797.

Follow-up compatibility removal: #7800, assigned to FAST Element vNext.

👩‍💻 Reviewer Notes

Breaking markup change: Move host attributes and bindings from declarative <f-template> / inner <template> elements onto <f-host>. The JavaScript html tagged-template host-binding API is unchanged.

Document only <f-shadow> for authored shadow-root options. Undocumented compatibility retains shadowroot* options on both outer <f-template> and inner <template> elements, with inner options taking precedence. An explicit <f-shadow> overrides legacy shadow configuration entirely. Browser, renderer, and converter compatibility paths carry TODO(#7800) comments for their breaking removal in vNext; this PR does not close #7800.

Native parse_f_templates now returns Result<Vec<FTemplate>, RenderError> so malformed host declarations can fail explicitly. Successful WASM metadata retains the existing hostAttributes shape. Conversion targets consume the same declaration rather than silently losing host attributes.

Keep document-embedded definitions hidden: these metadata elements are not browser-native inert elements before JavaScript executes. hidden on <f-template> is not forwarded to the component.

Both affected packages disallow major Beachball changes, so release notes use the repository-permitted minor type. The markup migration is documented explicitly for release review.

📑 Test Plan

  • Browser-runtime coverage for client rendering, default/instance precedence, reactive host attributes, events, legacy host-attribute removal, shadow options, legacy shadow compatibility, and invalid/duplicate declarations.
  • Declarative fixture coverage for SSR without JavaScript, hydration without host-attribute rewrites, and subsequent host/content updates.
  • Rust and fast-build coverage for parsing, binding metadata, host rendering, and streaming parity.
  • Passed full workspace build with npm run build -- --no-cache (bypasses stale local WASM cache entries).
  • Passed all native renderer/converter tests and all 166 fast-build Node/WASM/CLI tests, including canonical shadow configuration, compatibility, streaming, conversion, and diagnostics.
  • Initial full runtime browser run: 4,694 passed (7 skipped). Complete declarative suite after adding <f-shadow>: 624 passed. After aligning all <f-shadow> attributes with HTML-standard names, reran all 60 runtime declaration tests and 45 host fixture tests across Chromium, Firefox, and WebKit, including no-JavaScript SSR and hydration.
  • Passed dependent router tests and Biome checks.
  • The initial root test run encountered stale SSR fixtures and an outdated diagnostic assertion; both were fixed and the complete declarative suite was rerun successfully.
  • Passed branch formatting and direct Beachball validation. On Windows, the existing npm run checkchange wrapper fails with spawnSync npx ENOENT; npm exec -- beachball check --branch origin/main --no-fetch passes. Whole-crate rustfmt checks report pre-existing differences in unchanged files; changed Rust lines/new tests are formatted.

✅ Checklist

General

  • I have included a change request file using $ npm run change
  • I have added tests for my changes.
  • I have tested my changes.
  • I have updated the project documentation to reflect my changes.
  • I have read the CONTRIBUTING documentation and followed the standards for this project.

Agents

  • I have linked to an existing issue in this project that this change addresses
  • I have read the skills
  • I have read the DESIGN.md file(s) in packages relevant to my changes
  • I have updated the DESIGN.md file(s) in packages relevant to my changes

Use f-host for declarative host defaults and bindings in the browser runtime, SSR, and conversion pipelines. Remove legacy template host forwarding and document the migration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use f-shadow for canonical shadow-root options across runtime, SSR and converters. Retain outer and inner template shadowroot configuration with TODOs referencing #7800 for removal in FAST Element vNext.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@janechu Jane Chu (janechu) changed the title feat: add explicit f-host declarations feat: add explicit f-host and f-shadow declarations Nov 5, 2026
Use shadowrootmode, shadowrootdelegatesfocus, shadowrootclonable and shadowrootserializable consistently in runtime, SSR, converters, fixtures and documentation. Reject abbreviated aliases while preserving the existing legacy template compatibility paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

feat: add f-shadow-only configuration in FAST Element vNext feat: add the ability to define host element attributes to f-template

1 participant