Repository navigation
Conversation
…ment writes, not application resizes
- Introduced a new measurement generation system in GraphStore to track resets and initial measurement passes. - Updated `useOnElementsMeasured` to deliver events based on settled changes, ensuring accurate measurement reporting. - Modified the measurement observer to handle cases where elements are added without sizes and to trigger events when they are measured. - Improved test coverage for measurement events, including scenarios for element resets and size changes. - Refactored size change handling to differentiate between application-resized elements and those measured by the observer. - Ensured that the `markElementRendered` function correctly settles elements that arrive without sizes.
…ter content rendering
…ed elements - Updated the measurement handling logic in useOnElementsMeasured to account for elements that are not rendered by the paper or are zero-sized. - Introduced new tests to cover scenarios where elements are culled or removed before measurement. - Improved the flush function to ensure all rendering and measurement processes are settled before events are delivered. - Refactored GraphStore to manage outstanding elements more effectively, ensuring that elements not rendered by any paper do not block measurement events. - Added a settleUnrenderedElements method to clear outstanding elements that are not accounted for by any paper. - Enhanced documentation to clarify the behavior of the measurement system regarding application-written sizes and unmeasured elements.
… change without pending measurements
- Removed the export of create-elements-size-observer from index.ts. - Introduced a new measurement.ts file to manage element size measurements. - Updated paper-store.ts to integrate with the new measurement system. - Modified state-container.ts to adjust import paths for selector utilities. - Enhanced scheduler tests to handle callback errors and cascading callbacks. - Replaced useOnElementsMeasured with useOnCellsChange in various examples and stories to reflect the new measurement approach. - Added warnings for selector misuse and cascading callbacks in dev-warnings.ts. - Updated examples to utilize the new selectMeasuredState selector for layout adjustments based on element sizes.
samuelgja
requested review from
kumilingus
and
a balanced review from Copilot
and removed request for
Copilot
October 7, 2026 07:17
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Selection deduplication mishandles NaN, and the feature changeset violates the repository’s single-line format.
Review effort: Balanced
Findings: 1
Open (3)
What changed in this PR
Centralizes @joint/react measurement handling, adds measurement selectors and useOnCellsChange, and improves callback scheduling reliability.
Changes:
- Introduces the measurement controller, selectors, and effect-like cell change hook.
- Migrates stories and deprecates
useOnElementsMeasured. - Hardens scheduler and graph projection behavior with expanded tests.
| File | Description |
|---|---|
stories/examples/measured-state/story.tsx |
Registers the measurement example. |
stories/examples/measured-state/code.tsx |
Demonstrates the new selectors and hook. |
stories/examples/introduction/code.tsx |
Migrates minimap measurement handling. |
stories/examples/flowchart/code.tsx |
Fits measured flowchart content. |
stories/examples/element-controls/story.tsx |
Updates the API documentation link. |
stories/examples/element-controls/code.tsx |
Migrates control initialization. |
stories/examples/dynamic-status-icons/story.tsx |
Updates the API documentation link. |
stories/examples/dynamic-status-icons/code.tsx |
Migrates status-list initialization. |
stories/examples/collapsible-subtrees/code.tsx |
Migrates initial tree layout. |
stories/examples/automatic-layout/story.tsx |
Updates the API documentation link. |
stories/examples/automatic-layout/code.tsx |
Uses measured-state change callbacks. |
stories/examples/automatic-layout-storage/story.tsx |
Updates the API documentation link. |
stories/examples/automatic-layout-storage/code.tsx |
Migrates persistent-layout measurement handling. |
src/utils/scheduler.ts |
Isolates failures and bounds cascades. |
src/utils/dev-warnings.ts |
Adds selector and cascade warnings. |
src/utils/__tests__/scheduler.test.ts |
Tests failure and cascade handling. |
src/store/state-container.ts |
Updates selector utility imports. |
src/store/paper-store.ts |
Connects papers to measurement settling. |
src/store/measurement.ts |
Centralizes measurement state and observation. |
src/store/index.ts |
Removes the obsolete observer export. |
src/store/graph-store.ts |
Delegates measurement to the controller. |
src/store/graph-projection.ts |
Preserves reentrant graph changes. |
src/store/graph-changes.ts |
Removes measurement-specific forwarding. |
src/store/create-elements-size-observer.ts |
Deletes the superseded observer. |
src/store/clear-view.ts |
Removes unused view helpers. |
src/store/__tests__/measurement.test.ts |
Covers the measurement controller. |
src/store/__tests__/graph-store.test.ts |
Updates measurement integration tests. |
src/store/__tests__/graph-store-features.test.ts |
Uses the new observer interface. |
src/store/__tests__/graph-changes.test.ts |
Removes obsolete callback tests. |
src/store/__tests__/create-elements-size-observer.test.ts |
Deletes superseded observer tests. |
src/store/__tests__/clear-view.test.ts |
Removes deleted-helper tests. |
src/state/data-mapping/cell-record-merge.ts |
Updates selector utility imports. |
src/selectors/store-selectors.ts |
Extracts internal store selectors. |
src/selectors/source-selector.ts |
Adds store-backed selector infrastructure. |
src/selectors/selector-utils.ts |
Relocates equality helpers. |
src/selectors/measurement-selectors.ts |
Adds public measurement selectors. |
src/selectors/index.ts |
Exports reorganized selectors. |
src/selectors/__tests__/store-selectors.test.ts |
Updates internal selector tests. |
src/selectors/__tests__/source-selector.test.ts |
Tests source-selector behavior. |
src/selectors/__tests__/selector-utils.test.ts |
Adds equality-helper coverage. |
src/internal.ts |
Preserves internal auto-size exports. |
src/index.ts |
Exports the new public API. |
src/hooks/use-on-elements-measured.ts |
Deprecates and reimplements the old hook. |
src/hooks/use-on-cells-change.ts |
Adds the effect-like change hook. |
src/hooks/use-measure-element.tsx |
Uses centralized measurement and cache clearing. |
src/hooks/use-create-portal-paper.tsx |
Removes global measured-state rendering. |
src/hooks/use-cells.ts |
Shares source selection and subscriptions. |
src/hooks/use-are-elements-measured.ts |
Deletes the obsolete internal hook. |
src/hooks/index.ts |
Exports useOnCellsChange. |
src/hooks/__tests__/use-on-elements-measured.test.tsx |
Updates deprecated-hook tests. |
src/hooks/__tests__/use-on-cells-change.test.tsx |
Covers the new hook and selectors. |
src/hooks/__tests__/use-measure-element.test.tsx |
Tests targeted cache clearing. |
src/hooks/__tests__/measurement-settling.test.tsx |
Covers additional settling cases. |
src/hooks/__tests__/measurement-events.test.tsx |
Ports settled-event specifications. |
src/components/paper/render-element/paper-element-item.tsx |
Reports committed element content. |
src/components/paper/render-element/__tests__/paper-element-item.test.tsx |
Updates portal-item tests. |
src/components/graph/graph-provider.tsx |
Updates measurement type imports. |
src/components/graph/__tests__/graph-provider-hot-reload.test.tsx |
Migrates hot-reload measurement coverage. |
.changeset/react-store-callbacks.md |
Records scheduler and callback fixes. |
.changeset/react-on-cells-change.md |
Records the new hook and selectors. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Added `graph-state.ts` to manage the state of the graph, including cell records and sizing version. - Updated measurement logic in `measurement.ts` to use a versioning system instead of a state flag. - Removed the deprecated `collection-subscription.ts` utility. - Refactored various components to utilize the new `useGraphState` and `useOnGraphStateChange` hooks. - Updated examples and stories to reflect changes in state management and measurement handling. - Enhanced dev warnings for reading graph state outside of selectors.
…s commit - measurement: deliver one scheduler round after the graph events that settle an element, so a subscriber of the new sizing version reads committed cells - measurement: re-check the delivery when a paper is removed, so elements that only waited for the last paper settle - useCells / useOnCellsChange: name the called hook in the unstable-selector dev warning; compute the target key once per render - docs: StrictMode mount call note, examples on the callback and selector types
…seOnElementsMeasured - store/measurement.ts replaces create-elements-size-observer.ts and the measurement code in graph-store, graph-changes and graph-projection; the ResizeObserver is created by the first observe() - useOnElementsMeasured: one event per settled change, a removal included; zero-sized elements count as measured; elements of an external graph are tracked from the start; an unmounted measured node no longer blocks events; the event is announced once the measured sizes are in the store - useCells runs on an internal graph-state reader that subscribes to what its selector reads; an inline selector capturing a changed prop is re-run - scheduler: a throwing callback no longer stops the flush; cascading callbacks continue on a later task; a graph change made by a subscriber during notification is no longer dropped
…re-module Stack the new hooks and selectors on the measurement fixes: this branch now adds only the public API (useGraphState, useOnGraphStateChange, useOnCellsChange, the sizing selectors) and the useOnElementsMeasured deprecation on top of fix/react-measurement-module.
…ntsMeasured; format
Merge latest dev while retaining the graph-state APIs and the legacy measurement callback contract. Preserve regression coverage and correct selector equality and detached-record cache behavior.
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Detached collections can retain stale snapshots after same-ID model replacements, and colliding array/string target keys can leave hooks using the wrong target or return shape without restarting watches.
2 open issues
3 resolved since last review
Review effort: Balanced
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Description
Expose graph state through
useGraphState(selector, isEqual?), withuseOnGraphStateChange()anduseOnCellsChange()for callbacks without rerendering. Selectors subscribe only to the cells, collections, or sizing version they read. Public exports includeGraphState, selector/callback types,selectGraphSizingVersion, andselectIsGraphSizingComplete.useOnElementsMeasuredremains supported and is deprecated in favor of the general graph-state API. The sizing selectors return zero/incomplete after the last element is removed; the legacy hook keeps its existing initialization contract: empty/re-add is an ordinary change, while a graph reset starts a new history.The branch is synchronized with current
dev, including the released measurement fixes from master. It preserves first-report waiting, retained-node remeasurement after reset/re-add, late subscription and reentrant reset handling, render-idle settling, and deferred-transaction notification ordering. Original measurement regression suites are retained alongside the new graph-state suites.Verified selector regressions are also corrected:
Object.is, handlingNaNand signed zero consistently.Stories demonstrate the general hooks and selectors, including the measured-state example. Changesets cover the new API, deprecation, and fixes affecting existing
useCellsbehavior.Validation
yarn testpassed on the repository-pinned Node 22.14.0, including React 19/compiler and React 18 suites, plus core, layout, routing, sanitizer and mock-SVG suites.devpassed.On macOS the test browser was launched with process-local classic-scrollbar flags to satisfy the existing viewport test's scrollbar assumption. Test assertions and repository browser configuration were not changed. The host's Node 24 run encountered a worker crash; the final complete run passed on Node 22.14.0.