Skip to content

feat(fast-html): support boolean attributes that have conditions#7330

Open
mohamedmansour wants to merge 5 commits intomicrosoft:mainfrom
mohamedmansour:feature/boolean-attributes
Open

feat(fast-html): support boolean attributes that have conditions#7330
mohamedmansour wants to merge 5 commits intomicrosoft:mainfrom
mohamedmansour:feature/boolean-attributes

Conversation

@mohamedmansour
Copy link
Contributor

Summary

Adds support for boolean attributes with comparison expressions in @microsoft/fast-html. Previously, attribute bindings only supported simple property access (e.g., {{type}}). Now, expressions like ?data-active="{{activeGroup == currentGroup}}" are correctly resolved — the boolean attribute is toggled based on the result of the comparison.

Changes

  • template.ts — When processing attribute bindings, the code now checks if the value is a comparison expression (via getExpressionChain). If the operator is not a simple "access", it routes through expressionResolver instead of bindingResolver, enabling condition evaluation for attributes.
  • attribute.spec.ts — Added a new Playwright test ("boolean attribute with comparison condition") that validates the attribute is present when the condition is true, removed when the condition becomes false, and re-added when it becomes true again.
  • index.html — Added a test-bool-condition fixture using ?data-active="{{activeGroup == currentGroup}}" with pre-rendered SSR shadow DOM.
  • main.ts — Registered TestBoolCondition component with activeGroup and currentGroup observed attributes.

What still works with attributes

  • Simple property access bindings like type="{{type}}" continue to use the existing bindingResolver path — no behavior change.
  • The disabled static attribute still renders correctly.
  • SSR pre-rendered shadow roots with data-fe-b-* markers hydrate as before.

<head>
<meta charset="utf-8" />
<title></title>
<script type="module" src="./main.ts"></script>
Copy link
Collaborator

Choose a reason for hiding this comment

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

This script should not be in the head, can we place this back to the end of the body?.


class TestBoolCondition extends FASTElement {
@attr({ attribute: "active-group" })
activeGroup: string = "";
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just as a precaution, I think these strings should be different between the activeGroup and currentGroup so that we don't get false positives.

type
);
// Check if the value is a comparison expression (e.g., "activeGroup == item")
const expressionChain = getExpressionChain(propName);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Feels like we should update the expressionResolver to resolve regular access paths if it does not already and simplify this to just call the expressionResolver without an if/else check.

mohamedmansour and others added 3 commits March 20, 2026 14:01
Co-authored-by: Jane Chu <7559015+janechu@users.noreply.github.com>
Co-authored-by: Jane Chu <7559015+janechu@users.noreply.github.com>
Co-authored-by: Jane Chu <7559015+janechu@users.noreply.github.com>
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.

2 participants