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.
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
Measuring was spread over
graph-store.ts,graph-changes.ts,graph-projection.tsandcreate-elements-size-observer.ts, and the only way to react to it wasuseOnElementsMeasured. This PR moves all of it into one module and exposes the measured state as selectors, so it is consumed with the hooks that already exist (useCells) plus one new effect-like hook (useOnCellsChange). Nothing is removed from the public API;useOnElementsMeasuredstays and is marked@deprecated.src/store/measurement.ts(new, replacescreate-elements-size-observer.ts)createMeasurement({ graph, autoSizeOrigin, paperStores }), exposed asgraphStore.measurement. It owns its ownmvc.Listeneron the graph (add/remove/reset/change:size), the node registry and theResizeObserver.ResizeObserveris created by the firstobserve(): a diagram that never measures does not have one.graph-store.ts,graph-changes.ts,graph-projection.tsandstate-container.tsno longer contain measurement code.use-are-elements-measured.tsand two dead helpers inclear-view.tsare deleted.src/selectors/(reorganised)measurement-selectors.ts:selectMeasuredState(0while unmeasured, otherwise a value that changes once per settled change and is never reused),selectIsMeasured,selectElementsSizes(ReadonlyMap<CellId, dia.Size>, same reference until a size / add / remove / reset).source-selector.ts:createSourceSelector. These selectors read a store source, not the cells, souseCells/useOnCellsChangesubscribe to that source only: no work on other commits (a drag frame builds no cells array - asserted by a test). They must be used in the all-cells form; with an id, ids or a collection the hook throws.store-selectors.ts(internal snapshot selectors) andselector-utils.ts(equality helpers, moved fromsrc/utils).cell-selectors.tsis unchanged.src/hooksuseOnCellsChange(selector, onChange, isEqual?)and the id / ids / collection forms:useCellsas an effect. The callback runs once on mount and then synchronously with each store change that changes the selected value, without re-rendering.useCellsis now a thin wrapper over the internaluseCellsSource, shared withuseOnCellsChange.isEqualis read through a ref, so an inlineisEqualno longer re-subscribes on every render.useOnElementsMeasured:@deprecated, same contract, now readsmeasurement.stateSource.useMeasureElement: unchanged API; usesmeasurement.observeand clears the view cache of its own element when its size changes (replaces the global sweep).Store callbacks (
src/utils/scheduler.ts,src/store/graph-projection.ts)Three bugs that already exist on
devand that a general change hook makes easy to hit:Stories
flowchart,element-controls,collapsible-subtrees,dynamic-status-icons,introduction,automatic-layoutandautomatic-layout-storageuse the new API.Tests
src/store/__tests__/measurement.test.ts: the observer and graph-changes tests, ported one to one, plus the settled-state cases.src/hooks/__tests__/measurement-events.test.tsx: the 16 spec cases from test(joint-react): specify how many events useOnElementsMeasured delivers #3520, driven throughuseOnCellsChange(selectMeasuredState, ...);measurement-settling.test.tsx;use-on-cells-change.test.tsx;use-on-elements-measured.test.tsx(deprecated hook, same assertions as before).src/selectors/__tests__/source-selector.test.ts,src/utils/__tests__/scheduler.test.ts.yarn testinpackages/joint-react(typecheck + knip + duplicity-detect + jest): 1140 tests on React 19, 1136 on React 18, all passing.yarn lint: 0 errors.yarn benchA/B is within noise.Changesets:
@joint/reactminor -useOnCellsChange- add the hook, with theselectMeasuredState,selectIsMeasuredandselectElementsSizesselectors;useOnElementsMeasuredis deprecated in favor of it.@joint/reactpatch -<GraphProvider />- fix a store callback that throws or changes the graph breaking later updates.Motivation and Context
Follow-up of #3518 (spec in #3520). The measuring feature touched the core store files although most diagrams never use it, and
useOnElementsMeasuredwas a one-purpose hook. With the measured state as a selector, the same need is covered byuseCellsand one general hook, and the store core no longer knows about measuring.Migration (optional, the old hook still works):
Notes
devget no CI; the full suite was run locally.useOnCellsChangeunder StrictMode (development only).yarn test-coverageis below its floor ondevalready; not changed here.Screenshots (if appropriate):