Skip to content

Add bool() support for boolean attributes in component templates#55

Merged
JosunLP merged 7 commits intodevelopmentfrom
copilot/add-boolean-attribute-shorthand
Mar 13, 2026
Merged

Add bool() support for boolean attributes in component templates#55
JosunLP merged 7 commits intodevelopmentfrom
copilot/add-boolean-attribute-shorthand

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 13, 2026

@bquery/bquery/component's html tag treated interpolations as plain string concatenation, which made boolean attributes awkward to author and pushed Storybook usage toward Lit. This change adds a native boolean-attribute helper for component templates without changing the existing template API shape.

  • Template API

    • Adds bool(name, enabled) to @bquery/bquery/component
    • html and safeHtml now recognize the helper and emit bare boolean attributes when enabled
  • Exports

    • Re-exports bool from the component entrypoint
    • Re-exports bool from the full bundle to keep public API surfaces aligned
  • Behavior

    • Truthy values render the attribute name with no value
    • Falsy values render an empty string and preserve surrounding template whitespace
    • Invalid attribute names are rejected early
  • Coverage

    • Adds focused tests for:
      • multiple enabled boolean attributes
      • omitted disabled attributes
      • safeHtml compatibility
      • invalid attribute-name rejection
import { html, bool } from '@bquery/bquery/component';

html`<button ${bool('disabled', props.disabled)} ${bool('loading', props.loading)}>
  Save
</button>`;

📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

Copilot AI and others added 2 commits March 13, 2026 10:57
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Copilot AI changed the title [WIP] [FR-1] Add boolean-attribute shorthand for html Add bool() support for boolean attributes in component templates Mar 13, 2026
Copilot AI requested a review from JosunLP March 13, 2026 11:00
@github-actions github-actions bot added component Changes to the component module tests Chenges to the tests labels Mar 13, 2026
@JosunLP JosunLP marked this pull request as ready for review March 13, 2026 11:17
Copilot AI review requested due to automatic review settings March 13, 2026 11:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class boolean-attribute support to the component template tag functions so authors can emit bare boolean attributes (e.g., disabled) without awkward string concatenation, improving ergonomics for @bquery/bquery/component templates while keeping export surfaces aligned.

Changes:

  • Introduces bool(name, enabled) helper consumed by html/safeHtml to emit bare boolean attributes or omit them.
  • Re-exports bool from the component entrypoint and the full bundle entrypoint.
  • Adds targeted unit tests covering enabled/disabled rendering, safeHtml compatibility, and invalid name rejection.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
tests/component.test.ts Adds unit tests for bool() rendering behavior and validation.
src/component/html.ts Implements boolean-attribute marker support in html/safeHtml and adds the bool() helper.
src/component/index.ts Re-exports bool from the component module entrypoint.
src/full.ts Re-exports bool from the full bundle to keep API surfaces aligned.

@JosunLP
Copy link
Copy Markdown
Collaborator

JosunLP commented Mar 13, 2026

@copilot apply changes based on the comments in this thread

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 13, 2026

@copilot apply changes based on the comments in this thread

Applied the review-thread fixes in 4136921: the internal marker now uses a unique symbol, and the html JSDoc now sits directly on the exported template tag. I re-ran focused typecheck/component tests successfully. Screenshot: https://github.com/user-attachments/assets/1f82408a-c3b3-44b4-bfee-d95329aa7a64

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class boolean-attribute authoring support to the component template tags so component templates can emit bare boolean attributes (e.g., disabled) without awkward string concatenation, and keeps the public export surface aligned across entrypoints.

Changes:

  • Introduces bool(name, enabled) helper and teaches html/safeHtml to render it as a bare attribute name (or empty string).
  • Re-exports bool from @bquery/bquery/component and from the full bundle.
  • Adds focused tests covering enabled/disabled cases, safeHtml compatibility, and invalid-name rejection.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/component/html.ts Adds the bool() marker helper and updates template interpolation to recognize it in html/safeHtml.
src/component/index.ts Re-exports bool from the component module entrypoint.
src/full.ts Re-exports bool from the full bundle to keep APIs aligned.
tests/component.test.ts Adds unit tests for boolean attribute rendering and validation behavior.

@JosunLP
Copy link
Copy Markdown
Collaborator

JosunLP commented Mar 13, 2026

@copilot apply changes based on the comments in this thread

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 13, 2026

@copilot apply changes based on the comments in this thread

Applied the follow-up fixes in 24b6f7a: bool() now returns a declaration-safe public type, the internal marker object is frozen, and the guard now verifies the marker value and expected fields. I re-ran lint:types, full build, focused component tests, and CodeQL successfully. Screenshot: https://github.com/user-attachments/assets/1f82408a-c3b3-44b4-bfee-d95329aa7a64

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class boolean attribute support to the component template tags (html / safeHtml) via a bool(name, enabled) helper, improving ergonomics for authoring component templates without changing the existing template API shape.

Changes:

  • Introduces bool() marker helper and template-value handling to emit bare boolean attributes when enabled.
  • Updates html/safeHtml interpolation logic to recognize boolean-attribute markers.
  • Re-exports bool through the component entrypoint and the full bundle, and adds targeted tests.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/component/html.ts Implements bool() helper + marker detection and updates html/safeHtml interpolation/escaping paths.
src/component/index.ts Re-exports bool from the component module entrypoint.
src/full.ts Re-exports bool from the full bundle to keep API surfaces aligned.
tests/component.test.ts Adds coverage for enabled/disabled boolean attributes, safeHtml compatibility, invalid names, and immutability.

@JosunLP
Copy link
Copy Markdown
Collaborator

JosunLP commented Mar 13, 2026

@copilot apply changes based on the comments in this thread

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 13, 2026

@copilot apply changes based on the comments in this thread

Applied the safeHtml follow-up in e2ac60e: boolean-attribute markers now bypass entity escaping and stay structural in safeHtml, with a regression test covering the escaped-name case. I re-ran lint:types, full build, focused component tests, and CodeQL successfully. Screenshot: https://github.com/user-attachments/assets/1f82408a-c3b3-44b4-bfee-d95329aa7a64

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class boolean-attribute support to the component template tags so authors can write ${bool('disabled', cond)} instead of manual string conditionals, while keeping the existing html/safeHtml API shape and aligning exports across entrypoints.

Changes:

  • Introduces bool(name, enabled) marker support in html and safeHtml template interpolation.
  • Re-exports bool from the component entrypoint and the full bundle entrypoint.
  • Adds targeted tests covering enabled/disabled behavior, safeHtml compatibility, name validation, and immutability.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/component/html.ts Implements bool() marker + recognition in html/safeHtml interpolation (including validation + immutability).
src/component/index.ts Re-exports bool from the component module entrypoint.
src/full.ts Re-exports bool from the full/CDN bundle to keep API surfaces aligned.
tests/component.test.ts Adds coverage for boolean attribute rendering, omission, safeHtml behavior, validation, and freezing.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Jonas Pfalzgraf <jolun.swtor@gmail.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class boolean-attribute authoring support to the component template tag functions, enabling ergonomic boolean attributes in html/safeHtml templates while keeping the existing template literal API shape intact.

Changes:

  • Introduces bool(name, enabled) boolean-attribute marker and teaches html/safeHtml to render it as a bare attribute name (or '' when disabled).
  • Re-exports bool from @bquery/bquery/component and from the full bundle entrypoint to keep public APIs aligned.
  • Adds focused unit tests covering enabled/disabled rendering, safeHtml compatibility, name validation, and immutability.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/component/html.ts Implements bool() marker + template rendering/escaping logic that recognizes the marker in html and safeHtml.
src/component/index.ts Re-exports bool from the component module entrypoint.
src/full.ts Re-exports bool from the full/CDN bundle entrypoint to keep APIs in sync.
tests/component.test.ts Adds tests validating boolean attribute rendering and validation behavior.

@JosunLP JosunLP merged commit 9b294cd into development Mar 13, 2026
13 of 14 checks passed
@JosunLP JosunLP deleted the copilot/add-boolean-attribute-shorthand branch March 13, 2026 12:07
JosunLP added a commit that referenced this pull request Mar 15, 2026
* Add `bool()` support for boolean attributes in component templates (#55)

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Jonas Pfalzgraf <info@josunlp.de>

* Add typed state generics to component definitions (#56)

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Jonas Pfalzgraf <info@josunlp.de>

* Pass attribute change metadata to component `updated()` hooks (#58)

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Jonas Pfalzgraf <info@josunlp.de>

* Add per-component sanitizer overrides for component render output (#57)

* Initial plan

* feat: add per-component sanitizer options

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* docs: clarify component sanitizer baseline

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* docs: warn about sensitive component sanitizer opts

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* test: cover sanitizer allowTags overrides

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* perf: precompute component sanitizer allowlists

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

---------

Signed-off-by: Jonas Pfalzgraf <info@josunlp.de>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Co-authored-by: Jonas Pfalzgraf <info@josunlp.de>

* Pass previous props into component `beforeUpdate` (#59)

* Initial plan

* Add previous props to beforeUpdate hook

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* Refine beforeUpdate old props implementation

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* Fix beforeUpdate typing regressions

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

---------

Signed-off-by: Jonas Pfalzgraf <info@josunlp.de>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Co-authored-by: Jonas Pfalzgraf <info@josunlp.de>

* Add explicit signal subscriptions to `component()` renders (#60)

* Initial plan

* feat: add component signal subscriptions

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* chore: document signal subscription tracking

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* fix: address signal integration review feedback

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* fix: tighten component signal typing

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* fix: resolve eslint failure in component signal test

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* fix: handle reconnect lifecycle and signal effect errors

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* fix: preserve reconnect signal wiring after hook errors

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* fix: skip beforeUpdate for signal rerenders

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

---------

Signed-off-by: Jonas Pfalzgraf <info@josunlp.de>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Co-authored-by: Jonas Pfalzgraf <info@josunlp.de>

* Add trusted sanitized fragments for `safeHtml` composition (#61)

* Initial plan

* feat: add trusted safeHtml fragment support

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* chore: finalize trusted safeHtml support

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* docs: address trusted safeHtml review feedback

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* docs: fix second trusted safeHtml review follow-up

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* refactor: split trusted html helpers from sanitizer

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* refactor: tighten trusted html branding

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* docs: tighten trusted html internals

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

---------

Signed-off-by: Jonas Pfalzgraf <info@josunlp.de>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Co-authored-by: Jonas Pfalzgraf <info@josunlp.de>

* Reuse component shadow-root style nodes across re-renders (#62)

* Initial plan

* fix: reuse component style element on rerender

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* chore: finalize component style reuse fix

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* test: tighten style reuse regression assertions

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* Add `@bquery/bquery/storybook` template helpers for Storybook stories (#63)

* Initial plan

* feat: add storybook template helper

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* docs: clarify storybook when fallback behavior

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* fix: keep storybook helpers out of full bundle

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* fix: sanitize storybook helper output

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* test: tighten storybook helper security coverage

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* feat: enhance storyHtml with improved boolean attribute handling and sanitization tests

* fix: update storyHtml example to reflect correct boolean attribute output

* fix: defensive tag delimiter and parser comments per code review

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* chore: release version 1.6.0

- Update CHANGELOG.md for version 1.6.0 release notes including added features, changes, fixes, and security improvements.
- Enhance README.md to document new boolean attribute helpers and Storybook integration.
- Update bun.lock to reflect dependency upgrades for Storybook and happy-dom.
- Modify definition.md to include new Storybook helpers and component state management features.
- Revise components.md to demonstrate new boolean attribute handling and typed state in components.
- Update getting-started.md with Storybook authoring examples and improved module descriptions.
- Enhance security.md to clarify sanitization practices and introduce trusted fragment handling.
- Revise index.md to highlight new Storybook helpers in the feature list.
- Update llms.txt to reflect the new version 1.6.0.
- Bump version in package.json to 1.6.0 and update devDependencies for Storybook.

* Address review feedback for test setup, test type coverage, and component state keys (#65)

* Initial plan

* Address review feedback for test typing and setup

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* Finalize review feedback fixes

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* Export component state key type

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* Default component state key generic

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* Tighten component/state update semantics and Storybook attribute sanitization (#66)

* Initial plan

* fix review follow-up for state updates and storybook sanitization

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* fix storybook attribute value scanning

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* fix storybook interpolation boundary parsing

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

* docs align storybook attribute scan jsdoc

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>

---------

Signed-off-by: Jonas Pfalzgraf <info@josunlp.de>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
JosunLP added a commit that referenced this pull request Mar 27, 2026
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Jonas Pfalzgraf <info@josunlp.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component Changes to the component module tests Chenges to the tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants