Conversation
Collaborator
Author
|
Updated to pass state attributes to the nested-when element. Now builds successfully with the renderer fix in #7396 (kebab-to-camelCase attribute mapping). |
8e19d1e to
6149a56
Compare
6149a56 to
dec13fa
Compare
There was a problem hiding this comment.
Pull request overview
Updates the @microsoft/fast-html fixture build pipeline to include the when fixture in SSR generation via @microsoft/fast-build, and adjusts microsoft-fast-build so entry-level (root) custom elements can render shadow templates using both root state and per-element attribute-derived state.
Changes:
- Add the
whenfixture topackages/fast-html/scripts/build-fixtures.jsand introducewhenfixture inputs (entry.html,templates.html,state.json) + regeneratedindex.html. - Change
microsoft-fast-buildroot custom element rendering to merge root JSON state with attribute-derived state for shadow template evaluation. - Update
microsoft-fast-builddocumentation (README + DESIGN) to describe merged-state behavior for entry rendering.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/fast-html/test/fixtures/when/templates.html | New <f-template> declarations for the when fixture used by fixture injection/hydration. |
| packages/fast-html/test/fixtures/when/state.json | New fixture state used for SSR generation. |
| packages/fast-html/test/fixtures/when/main.ts | Defines the fixture custom elements used by the templates/tests. |
| packages/fast-html/test/fixtures/when/index.html | Regenerated SSR output + injected templates for the fixture page. |
| packages/fast-html/test/fixtures/when/entry.html | New entry HTML input used by fast-build to generate the fixture SSR output. |
| packages/fast-html/scripts/build-fixtures.js | Adds when to the list of fixtures rendered via @microsoft/fast-build. |
| crates/microsoft-fast-build/src/directive.rs | Implements merged root+attribute state for entry-level custom elements. |
| crates/microsoft-fast-build/README.md | Updates docs to explain merged-state behavior and root-element attribute handling. |
| crates/microsoft-fast-build/DESIGN.md | Updates design notes for is_entry semantics to match merged-state behavior. |
| change/@microsoft-fast-html-when-00615379-81a9-4dd0-86af-bd600a8ab155.json | Records the @microsoft/fast-html change entry. |
Comments suppressed due to low confidence (1)
crates/microsoft-fast-build/src/directive.rs:285
build_attr_statecurrently skips all attributes that start with?. That avoids mis-resolving expressions like?disabled="{{!enableContinue}}", but it also means?attrboolean bindings on a custom element tag can never influence the element’s shadow-template rendering state (even though entry-tag rendering does evaluate?attr). Consider evaluating?attr="{{expr}}"withevaluate()and inserting a boolean into the child state (under the attr name without?), so SSR state and rendered HTML stay consistent.
let attrs = parse_element_attributes(open_tag_content);
let mut state_map = base.unwrap_or_default();
for (attr_name, value) in &attrs {
// Skip @event handlers — they are client-side only and have no meaning in SSR state.
// Also skip f-ref, f-slotted, f-children, and ?boolean-binding directives — all are
// resolved entirely by the FAST client runtime.
if attr_name.starts_with('@')
|| attr_name.starts_with('?')
|| attr_name.eq_ignore_ascii_case("f-ref")
|| attr_name.eq_ignore_ascii_case("f-slotted")
|| attr_name.eq_ignore_ascii_case("f-children")
{
continue;
}
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use lowercase no-dash attribute names (e.g. vara, thisvar, thatvar, showprogress, enablecontinue) to match the SSR crate's lowercasing behaviour and to avoid hyphen-separated state keys that would not match the camelCase template expressions. - main.ts: update @attr declarations to use no-dash attribute names - entry.html: replace dash-case attrs with lowercase no-dash equivalents - templates.html: update f-when expressions to use lowercase state keys - index.html: regenerated via npm run build:fixtures Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previously, entry-level root elements received only the full root state for child rendering. This broke elements with per-element attribute state (e.g. planet="earth", vara="3", boolean show) because those values were not present in the shared root state.json. Now entry elements start with the root state as a base and overlay their own attribute-derived values on top. This ensures both app-level context (error, showProgress) and per-element attributes (planet, vara, show) are available to the shadow template. Also update the nested-when template to use camelCase expressions (showProgress, enableContinue) matching the state.json keys and the element's @observable property names for correct FAST hydration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Entry custom elements now receive root state merged with their own attribute-derived state, rather than only the full root state. Update docs to reflect the new behaviour and corrected table/examples. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
FAST template bindings resolve against JS property names at hydration
time. Rename varA→vara and thisVar/thatVar→thisvar/thatvar so the
{{vara}}, {{thisvar}}, {{thatvar}} expressions in templates.html match
the actual observable properties and react correctly after hydration.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add five tests covering the new merge behaviour for entry-level custom elements: per-element attr available in template, attr overrides matching root key, root keys still accessible alongside attr, boolean attr resolves to true, and multiple root elements each with independent per-element attr values. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8a9e36e to
937ef5d
Compare
Add scope_prefix to HydrationScope so that f-when bodies produce marker IDs that are globally unique within a shadow DOM. Previously, render_when created a fresh child scope starting from 0, so a nested f-when produced the same marker (e.g. "when-1") as the outer f-when at the same index. The FAST client runtime scans siblings linearly for end markers by ID, so it matched the inner end marker first, giving the outer when-1 a truncated content range. Fix: child(parent_idx) now prefixes inner marker names with the parent's allocated index (e.g. "1-"), yielding "1-when-0" and "1-when-1" inside the outer when-1 body. The outer end-marker search for "when-1" no longer finds a false match, so the correct DOM range is captured and reactive updates work properly. All Rust tests pass (190 tests). Fixture index.html regenerated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
janechu
added a commit
that referenced
this pull request
Apr 8, 2026
Regenerate repeat/index.html after rebasing onto main (which includes PR #7403 entry-attribute stripping and PR #7380 when fixture). Changes reflect correct entry-element behavior: - Non-primitive binding attrs (list, someData) stripped from opening tag - test-element-no-item-repeat-binding now renders empty repeat since list="{{emptyList}}" overrides root list with [] in merged state Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
janechu
added a commit
that referenced
this pull request
Apr 8, 2026
Regenerate repeat-event/index.html after rebasing onto main (which includes #7381 repeat fixture, #7380 when fixture, and #7403 entry-attribute stripping). Non-primitive binding attrs (items) are now stripped from entry element opening tags; primitive attrs (show-names="true") are preserved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
📖 Description
Adds the
whentest fixture to the@microsoft/fast-htmlpackage'sbuild-fixtures.jsscript so it is generated by@microsoft/fast-buildSSR alongside the existingattribute,binding,event,ref, andslottedfixtures.This PR also includes a fix to
@microsoft/fast-buildwhere entry-level root custom elements now merge the full root state with their own per-element attribute-derived state when rendering their shadow template. Previously, entry elements received only the full root state, which broke elements whose template expressions depend on per-element HTML attributes (e.g.planet="earth",vara="3", booleanshow). Attribute-derived values take precedence over root state for overlapping keys.The
nested-whentemplate expressions are updated to use camelCase identifiers (showProgress,enableContinue) matching both thestate.jsonkeys and the element's@observableproperty names, ensuring correct server-side resolution and correct FAST hydration binding.📑 Test Plan
All existing Rust unit tests pass (
cargo testincrates/microsoft-fast-build). Fixture output verified by runningnpm run build:fixtures— only thewhenfixture changed (no regressions in attribute, binding, event, ref, or slotted fixtures). Thewhen/when.spec.tsPlaywright tests cover the full lifecycle: initial SSR state, FAST hydration, and reactive property changes.✅ Checklist
General
$ npm run change