Skip to content

feat(joint-react): add declarative layers with initialLayers, controlled layers, useLayers and useLayer - #3499

Open
samuelgja wants to merge 12 commits into
clientIO:devfrom
samuelgja:feat/layers-support-for-react
Open

samuelgja wants to merge 12 commits into
clientIO:devfrom
samuelgja:feat/layers-support-for-react

Conversation

@samuelgja

@samuelgja samuelgja commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Description

Add declarative graph layers to @joint/react: initialLayers, controlled layers with onLayersChange, useLayers, useLayer, and useGraph().setLayers() / setLayer(). LayerModel, LayerView, and layerNamespace support custom layer types and visibility without unmounting cells.

Sync the latest dev into this branch, preserving its store, measurement lifecycle, and core layer fixes. Layer resets and JSON imports retain cells across every layer; validation rejects invalid declarations before writes, and failed constructors close the React-origin batch. Provider subscriptions catch child layout-effect changes and stop queued reverts after teardown. HTML overlays, detached link labels, and the implicit default SVG layer follow layer visibility while retaining measurable content. Explicit default-layer attributes survive JSON round trips. Pending removals retry after cells leave and respect newer declarations, default-layer changes, and teardown.

Motivation and Context

React diagrams can declare layer order, attributes, and visibility, and subscribe to individual layers without reacting to cell drags. Controlled cells and layers reconcile together so newly declared layers exist before cells use them, and empty layers are removed after their cells leave.

Verification

  • Root yarn test with Node 22.14.0, including React 18, React 19, compiler tests, coverage, type checks, and all workspace tests.
  • Root yarn lint and yarn dist.
  • yarn workspace @joint/react bench --runInBand.
  • yarn workspace @joint/react build-storybook.
  • Regression tests failed before the corresponding fixes for named-layer resets, constructor validation and batch cleanup, derived default-layer status, provider notification ownership, and HTML overlay visibility.

- Added support for layer visibility and management in the PaperView class.
- Implemented layer reconciliation and removal of empty layers in the graph store.
- Created utility functions for reading and updating layer records.
- Enhanced the GraphProvider to accept initial layers and manage layer updates.
- Introduced hooks for layer visibility control and layer management in the React components.
- Updated example stories to demonstrate the new layer functionality.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Layer re-addition retains a stale model binding, and reconciliation mishandles empty declarations and writable isDefault metadata.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds declarative layer management to @joint/react, including controlled state, hooks, setters, rendering behavior, documentation, and tests.

Changes:

  • Adds layer records, reconciliation, subscriptions, and controlled provider support.
  • Adds useLayers, useLayer, setLayers, and setLayer.
  • Implements layer visibility and updates the example and test coverage.
File summaries
File Description
packages/joint-react/stories/examples/layers/story.tsx Updates story metadata.
packages/joint-react/stories/examples/layers/code.tsx Demonstrates declarative layers.
packages/joint-react/src/utils/dev-warnings.ts Adds non-empty-layer warnings.
packages/joint-react/src/types/layer.types.ts Defines layer record and patch types.
packages/joint-react/src/store/layers.ts Implements layer projection and reconciliation.
packages/joint-react/src/store/graph-store.ts Exposes layer mutation operations.
packages/joint-react/src/store/graph-projection.ts Adds reactive layer snapshots.
packages/joint-react/src/store/graph-changes.ts Integrates layer events and synchronized updates.
packages/joint-react/src/store/__tests__/layers.test.ts Tests layer reconciliation.
packages/joint-react/src/mvc/paper.ts Implements visibility and re-add handling.
packages/joint-react/src/mvc/__tests__/paper-layer-visibility.test.tsx Tests layer rendering behavior.
packages/joint-react/src/index.ts Exports the public layer API.
packages/joint-react/src/hooks/use-layers.ts Adds the ordered-layers hook.
packages/joint-react/src/hooks/use-layer.ts Adds the selected-layer hook.
packages/joint-react/src/hooks/use-graph.ts Adds layer setters.
packages/joint-react/src/hooks/index.ts Exports layer hooks internally.
packages/joint-react/src/hooks/__tests__/use-layers.test.tsx Tests hooks and controlled behavior.
packages/joint-react/src/hooks/__tests__/use-layer.type.test.ts Tests layer API typings.
packages/joint-react/src/components/graph/graph-provider.tsx Adds declarative provider props.
.changeset/layers-use-layers.md Records the useLayers API.
.changeset/layers-use-layer.md Records the useLayer API.
.changeset/layers-setters.md Records layer setters.
.changeset/layers-record.md Records layer types and visibility.
.changeset/layers-graph-provider.md Records provider layer props.
Review details
  • Files reviewed: 24/24 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/joint-react/src/mvc/paper.ts Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Layer defaults are not restored when overrides are removed, and failed synchronization can leave graph batches open.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

packages/joint-react/src/store/layers.ts:158

  • When a controlled record drops an overridden attribute that is also present in the layer subclass's defaults, this branch leaves the old override in place. For example, a layer with default opacity: 1 remains at 0.5 after changing { opacity: 0.5 } to an omitted opacity, so the graph no longer matches the declared record. Reset such keys to their class-default value; only non-default keys should be unset.
  • Files reviewed: 27/27 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Reset ordering, exception-safe batching, and public layer input validation have unresolved correctness issues.

Get a fresh assessment by requesting another Copilot review.

Review details
  • Files reviewed: 28/28 changed files
  • Comments generated: 5
  • Review effort level: Balanced

Comment thread packages/joint-react/src/mvc/paper.ts Resolved
@kumilingus kumilingus added this to the v4.4 milestone Sep 28, 2026
Preserve the current store and measurement lifecycle while integrating declarative layers. Cover named-layer resets, input validation, subscription ownership, and HTML overlay visibility with regression tests.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread packages/joint-react/src/mvc/paper.ts Resolved
@kumilingus

Copy link
Copy Markdown
Contributor

Changesets: please consolidate the 9 changesets into a single one for the feature, e.g.:

---
"@joint/react": minor
---

<GraphProvider /> - add layers support (`initialLayers`, controlled `layers` with `onLayersChange`, `useLayers()`, `useLayer()`, `useGraph().setLayers()` / `setLayer()`)

Layer visibility: please remove the layer visibility feature from this PR (visible on layers, LayerView, the createLayerView override, detached-label and HTML-overlay mirroring). It needs to be thought through first.

Hiding a layer with CSS visibility leaves the cells mounted: tools and highlighters of hidden cells stay visible, findViewsInArea/snapping/magnets still hit them, and every element outside the layer group (labels layer, HTML portals) needs its own patch. Layer visibility should go through the paper's view management - cellVisibility - so hidden cells are unmounted consistently. Most likely it belongs in core (dia.Paper checks the layer's visibility when it evaluates cell visibility), and we'll handle it in a separate PR.

The createLayerView override is only there because core ignores layerViewNamespace while the graph is in legacyMode. That should be fixed in core as well rather than worked around here.

@kumilingus kumilingus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branch has not been deployed

No deployments
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.

4 participants