Skip to content

feat: re-measure measured bones on DOM mutations (BON-5) - #38

Merged
hunterbecton merged 3 commits into
mainfrom
hunter/bon-5-measured-mutation-observer
Aug 24, 2026
Merged

feat: re-measure measured bones on DOM mutations (BON-5)#38
hunterbecton merged 3 commits into
mainfrom
hunter/bon-5-measured-mutation-observer

Conversation

@hunterbecton

@hunterbecton hunterbecton commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Closes the stale-bars case the BON-4 design deferred to Phase 4: content that changes while busy without resizing the boundary kept its previous bars until the next resize. Streaming makes mid-busy child swaps the norm, so MeasuredOverlay now pairs its ResizeObserver with a MutationObserver (childList, subtree, characterData on the light subtree, active-overlay lifetime only).

  • Bar rendering happens in the shadow root, which a light-tree observer never reports, so re-rendering cannot re-trigger the observer. A browser test pins this by asserting bar node identity is stable after a swap settles.
  • Attribute mutations are excluded on purpose: observing them would fire on every class or style tick inside the boundary. The docs page now states that remaining stale case.
  • New browser tests pin the host height so only the MutationObserver can drive the re-measure.

Part of BON-5 (PR 1 of 3). No visual baselines change.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Measured progress bars now update when boundary content or text changes, including streamed and dynamic content swaps.
    • Empty boundaries automatically fall back to CSS-based rendering during the active display period.
  • Bug Fixes

    • Improved progress-bar positioning after content updates while preserving efficient handling of unrelated attribute changes.
  • Documentation

    • Updated guidance to cover re-measurement behavior, fixed-size content, scrolling, and fallback rendering.

hunterbecton and others added 2 commits August 24, 2026 13:12
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The three re-measure tests mutated in the same tick as mount, so
ResizeObserver's spec-mandated first callback (fired regardless of any real
resize) supplied the re-measure instead of the MutationObserver under test.
Settle past that guaranteed delivery before mutating so only DOM changes can
drive the re-measure, add a test pinning that attribute mutations are
excluded, and document the empty-then-refilled-subtree edge in the docs
bullet per the controller's ruling (overlay.ts behavior unchanged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3ebc17c6-e33c-4c4a-a862-ba71adca07ff

📥 Commits

Reviewing files that changed from the base of the PR and between e4bb74c and 4263ab3.

📒 Files selected for processing (1)
  • apps/docs/content/docs/api/bones-boundary.mdx

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Measured bones now re-measure after light-DOM child or text changes. Mutation observation ignores attributes, cleans up with resize observation, and falls back to CSS rendering when the boundary becomes empty.

Changes

Measured overlay mutations

Layer / File(s) Summary
Overlay observation and invalidation
packages/bones/src/element/overlay.ts
MeasuredOverlay now manages ResizeObserver and MutationObserver. Child-list and character-data changes trigger invalidation and remeasurement. Attribute changes remain ignored. Empty content deactivates measured rendering.
Mutation behavior validation and documentation
packages/bones/tests/browser/mutation.test.ts, apps/docs/content/docs/api/bones-boundary.mdx, .changeset/measured-mutation-observer.md
Browser tests cover child replacement, text edits, empty boundaries, shadow-root isolation, and class changes. Documentation and the changeset describe the updated behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 4263a

This change re-measures measured bones when light-subtree content changes during busy state, preventing stale bars without observing attribute updates. No actionable merge-blocking risk remains beyond normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: re-measuring measured bones when DOM mutations occur.
Description check ✅ Passed The description explains the purpose, implementation, testing coverage, scope, and remaining limitations, although it does not use the template headings.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (1 skipped: 1 unsupported.)
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hunter/bon-5-measured-mutation-observer

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hunterbecton
hunterbecton merged commit 9361a44 into main Aug 24, 2026
10 checks passed
@github-actions github-actions Bot mentioned this pull request Aug 24, 2026
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.

1 participant