Skip to content

feat(joint-core): auto-emit 'resize' when host element CSS size changes#3318

Merged
Geliogabalus merged 4 commits into
clientIO:masterfrom
kumilingus:paper-auto-resize-observer-master
May 19, 2026
Merged

feat(joint-core): auto-emit 'resize' when host element CSS size changes#3318
Geliogabalus merged 4 commits into
clientIO:masterfrom
kumilingus:paper-auto-resize-observer-master

Conversation

@kumilingus
Copy link
Copy Markdown
Contributor

Summary

dia.Paper now attaches a ResizeObserver to its host <div> and re-emits the existing 'resize' event when the host's computed size changes. Downstream subscribers — GridLayerView, PaperScroller, rulers, custom listeners — automatically follow CSS-relative sizing (width: null / '100%' / flex / container queries) without manual setDimensions() calls.

The observer self-skips when both options.width and options.height are numeric, so the existing explicit-size contract is preserved. Auto-emitted events carry { source: 'observer' } as the data argument so listeners doing expensive work can short-circuit on it.

Motivation

Paper#getComputedSize() already falls back to el.clientWidth / el.clientHeight when options.width/height are non-numeric, so CSS-relative sizing works — but JointJS never learned when the host actually changed size. The 'resize' event only fired from explicit setDimensions() calls, leaving GridLayerView and other size-aware consumers stale on flex resizes, window resizes, sidebar toggles, container queries, etc.

Flow

┌─────────────────────────────┐
│ host <div> CSS size changes │
└─────────────┬───────────────┘
              ▼
   ┌────────────────────────┐        ┌──────────────────────────────┐
   │  ResizeObserver        │──────▶ │ Paper observer callback      │
   │  (owned by Paper)      │        │ • getComputedSize()          │
   └────────────────────────┘        │ • dedup vs _lastObservedSize │
                                     │ • trigger('resize', w, h,    │
                                     │         { source:'observer'})│
                                     └─────────────┬────────────────┘
                                                   ▼
                              GridLayerView.updateGrid /
                              PaperScroller / rulers /
                              user `paper.on('resize', …)`

setDimensions() keeps its own direct trigger('resize', …) for the explicit-API path; both code paths feed _lastObservedSize, so observer + setDimensions never double-fire.

Changes

  • packages/joint-core/src/dia/Paper.mjs
    • New private methods _startObservingElementSize / _stopObservingElementSize and dedup state _lastObservedSize.
    • Wired into init(), onRemove(), and setDimensions() (re-evaluates observer attachment when toggling between explicit and CSS-relative modes).
  • packages/joint-core/test/jointjs/paper.js — QUnit tests covering fire / skip / teardown / toggle paths.

Test plan

  • yarn workspace @joint/core test — full QUnit + Mocha suite green.
  • yarn workspace @joint/core run test-ts — TS pass.
  • Regression: open a demo using numeric width/height. Confirm no extra 'resize' events fire on window resize.
  • Cleanup: mount / unmount Paper instances and confirm ResizeObserver#disconnect is called exactly once per paper.remove().

🤖 Generated with Claude Code

claude and others added 4 commits May 15, 2026 20:24
`dia.Paper` now attaches a ResizeObserver to its host `<div>` and re-emits
the existing `'resize'` event when the host's computed size changes. This
makes downstream subscribers — `GridLayerView`, `PaperScroller`, rulers,
the React host — track CSS-relative sizing (`width: null`/`'100%'`/flex/
container queries) without manual `setDimensions()` calls. The observer
self-skips when both `options.width` and `options.height` are numeric,
preserving the explicit-size contract. New opt-out: `autoResizePaper: false`.

Auto-emitted events carry `{ source: 'observer' }` as `data` so listeners
can distinguish them from explicit `setDimensions()` emissions.

https://claude.ai/code/session_013FyjBbiuXq4gr3ZRkT4Uvz
@kumilingus kumilingus requested a review from Geliogabalus May 15, 2026 18:29
@Geliogabalus Geliogabalus merged commit adc8f52 into clientIO:master May 19, 2026
3 checks passed
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.

3 participants