Skip to content

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

Merged
JosunLP merged 4 commits intodevelopmentfrom
copilot/update-updated-hook-attributes
Mar 13, 2026
Merged

Pass attribute change metadata to component updated() hooks#58
JosunLP merged 4 commits intodevelopmentfrom
copilot/update-updated-hook-attributes

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 13, 2026

updated() was invoked after attribute-driven rerenders but had no visibility into what changed. This updates the component lifecycle API so attribute-triggered updates can inspect the changed attribute directly without maintaining manual prop snapshots.

  • API surface

    • Adds a public AttributeChange type:
      type AttributeChange = {
        name: string;
        oldValue: string | null;
        newValue: string | null;
      };
    • Updates ComponentDefinition.updated to accept an optional change object:
      updated?: (this: HTMLElement, change?: AttributeChange) => void;
  • Runtime behavior

    • Threads { name, oldValue, newValue } from attributeChangedCallback() into updated() for attribute-triggered rerenders.
    • Keeps non-attribute updates unchanged at the call site by passing undefined when a rerender is triggered through other paths (for example, internal state updates).
  • Exports

    • Re-exports AttributeChange from the component entrypoint and full bundle so the new type is available to consumers across import styles.
  • Coverage

    • Extends component tests to verify:
      • updated() receives the correct attribute change payload after an observed attribute changes
      • updated() receives undefined for non-attribute rerenders

Example:

component('focus-dialog', {
  props: {
    open: { type: Boolean, default: false },
  },
  updated(change) {
    if (change?.name === 'open' && change.newValue !== null) {
      this.trapFocus();
    }
  },
  render: () => '<div><slot></slot></div>',
});

📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.

Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Copilot AI changed the title [WIP] [FR-4] Update updated() hook to receive changed-attribute info Pass attribute change metadata to component updated() hooks Mar 13, 2026
Copilot AI requested a review from JosunLP March 13, 2026 11:20
@JosunLP JosunLP marked this pull request as ready for review March 13, 2026 11:26
Copilot AI review requested due to automatic review settings March 13, 2026 11:26
@github-actions github-actions bot added component Changes to the component module tests Chenges to the tests labels Mar 13, 2026
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

This PR extends the Web Component lifecycle API to provide richer context to updated() by optionally passing details about the attribute change that triggered an update, and exposes the new type publicly for consumers.

Changes:

  • Introduces a new exported AttributeChange type describing observed attribute updates.
  • Updates the ComponentDefinition.updated hook to accept an optional AttributeChange argument and wires it through from attributeChangedCallback.
  • Adds/extends component tests to verify updated(change) receives attribute details for attribute-driven re-renders and undefined for non-attribute updates (e.g., setState).

Reviewed changes

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

Show a summary per file
File Description
tests/component.test.ts Adds coverage for updated(change) behavior for attribute vs. state-driven updates.
src/component/component.ts Passes { name, oldValue, newValue } into updated() when re-render is triggered by an observed attribute change.
src/component/types.ts Defines AttributeChange and updates updated hook typing/documentation.
src/component/index.ts Re-exports AttributeChange from the component module entrypoint.
src/full.ts Re-exports AttributeChange from the full bundle type exports.

Signed-off-by: Jonas Pfalzgraf <info@josunlp.de>
@JosunLP
Copy link
Copy Markdown
Collaborator

JosunLP commented Mar 13, 2026

die actions schlagen fehl @copilot

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

Copilot AI commented Mar 13, 2026

die actions schlagen fehl @copilot

Ich habe den CI-Fehler behoben. Ursache war der zusätzliche test:types-Check in GitHub Actions: Die generischen Component-Typen für updated(change) waren noch nicht vollständig verdrahtet. Fix ist in 6164eef und der lokale Workflow-äquivalente Check (test:types, Tests, Build) läuft jetzt sauber.

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

This PR extends the component lifecycle API so the updated hook can receive details about the observed attribute change that triggered an update render, while preserving the existing behavior for non-attribute-driven updates.

Changes:

  • Introduces a new public AttributeChange type and re-exports it from bquery/component and the full bundle.
  • Passes { name, oldValue, newValue } into definition.updated(...) when updates are triggered via attributeChangedCallback.
  • Adds/updates component tests to assert updated(change) receives attribute change info, and undefined for state-driven updates.

Reviewed changes

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

Show a summary per file
File Description
tests/component.test.ts Adds assertions for updated receiving AttributeChange on attribute updates and undefined on state updates.
src/component/component.ts Threads optional AttributeChange data through render() and into the updated hook for attribute-driven re-renders.
src/component/types.ts Defines AttributeChange and updates updated hook typing to accept an optional change argument.
src/component/index.ts Re-exports AttributeChange from the component module entrypoint.
src/full.ts Re-exports AttributeChange from the full/CDN bundle type exports.

@JosunLP JosunLP merged commit e3a36f8 into development Mar 13, 2026
14 checks passed
@JosunLP JosunLP deleted the copilot/update-updated-hook-attributes branch March 13, 2026 15:38
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-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