From 9eea90924d11add83ead869ad9a3914d91f3b18e Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Fri, 22 May 2026 13:50:07 +0200 Subject: [PATCH 1/6] gridPatterns override --- packages/joint-core/src/dia/Paper.mjs | 42 +++++++++++++++-------- packages/joint-core/types/dia.d.ts | 2 ++ packages/joint-react/src/presets/paper.ts | 25 +++++++------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/packages/joint-core/src/dia/Paper.mjs b/packages/joint-core/src/dia/Paper.mjs index aca2dbe331..c2ee4cb5ee 100644 --- a/packages/joint-core/src/dia/Paper.mjs +++ b/packages/joint-core/src/dia/Paper.mjs @@ -300,20 +300,6 @@ const backgroundPatterns = { } }; -const implicitLayers = [{ - id: paperLayers.GRID, - type: 'GridLayerView', - patterns: gridPatterns -}, { - id: paperLayers.BACK, -}, { - id: paperLayers.LABELS, -}, { - id: paperLayers.FRONT -}, { - id: paperLayers.TOOLS -}]; - const CELL_VIEW_PLACEHOLDER_MARKER = Symbol('joint.cellViewPlaceholderMarker'); export const Paper = View.extend({ @@ -627,7 +613,21 @@ export const Paper = View.extend({ FLAG_INIT: 1<<28, // Layers that are always present on the paper (e.g. grid, back, front, tools) - implicitLayers, + implicitLayers: [{ + id: paperLayers.GRID, + type: 'GridLayerView', + // @deprecated, `getGridPatterns` method overrides this property when creating the GridLayerView instance, + // so this is kept for backward compatibility only. + patterns: gridPatterns + }, { + id: paperLayers.BACK, + }, { + id: paperLayers.LABELS, + }, { + id: paperLayers.FRONT + }, { + id: paperLayers.TOOLS + }], // Reference layer for inserting new graph layers. graphLayerRefId: paperLayers.LABELS, @@ -843,12 +843,24 @@ export const Paper = View.extend({ }); }, + /** + * @protected + * @description Returns grid patterns for the paper grid layer. + */ + getGridPatterns: function() { + return cloneDeep(this.constructor.gridPatterns); + }, + /** * @protected * @description Renders all implicit layer views. */ renderImplicitLayerViews: function() { this.implicitLayers.forEach(layerInit => { + if (layerInit.type === 'GridLayerView') { + layerInit.patterns = this.getGridPatterns(); + } + const layerView = this.createLayerView(layerInit); this.addLayerView(layerView); }); diff --git a/packages/joint-core/types/dia.d.ts b/packages/joint-core/types/dia.d.ts index e1fec5f798..b054b65baa 100644 --- a/packages/joint-core/types/dia.d.ts +++ b/packages/joint-core/types/dia.d.ts @@ -2384,6 +2384,8 @@ export class Paper extends mvc.View { protected addStylesheet(stylesheet: string): void; + protected getGridPatterns(): Record; + /** * @deprecated use `getLayerView(id).el` instead * **/ diff --git a/packages/joint-react/src/presets/paper.ts b/packages/joint-react/src/presets/paper.ts index 52c1a20127..13272e5ec3 100644 --- a/packages/joint-react/src/presets/paper.ts +++ b/packages/joint-react/src/presets/paper.ts @@ -18,6 +18,7 @@ const POINTER_DOCUMENT_EVENTS: Record = { }; type ProtectedPaperPrototype = { + readonly getGridPatterns: () => Record; readonly pointermove: (event: dia.Event) => void; readonly pointerup: (event: dia.Event) => void; readonly startListening: () => void; @@ -39,18 +40,6 @@ function getPointerId(event: dia.Event): number | null { return typeof fromOriginal === 'number' ? fromOriginal : null; } -// Inject CSS custom property into all built-in grid pattern colors -// so they respond to --jj-paper-grid-color. -// @ts-expect-error Accessing protected member to set default grid pattern colors -// eslint-disable-next-line unicorn/no-array-for-each -Object.values(dia.Paper.gridPatterns).forEach((pattern) => { - const patterns = Array.isArray(pattern) ? pattern : [pattern]; - for (const subPattern of patterns) { - if (!subPattern.color) continue; - subPattern.color = 'var(--jj-paper-grid-color)'; - } -}); - const DEFAULT_CLICK_THRESHOLD = 5; const DEFAULT_GRID_SIZE = 10; const DEFAULT_SNAP_RADIUS = 15; @@ -118,6 +107,18 @@ export const Paper = dia.Paper.extend({ classNamePrefix: '', documentEvents: POINTER_DOCUMENT_EVENTS, + getGridPatterns() { + const patterns = protectedProto.getGridPatterns.call(this); + // Change default color to CSS variable + for (const pattern of Object.values(patterns)) { + for (const subPattern of pattern) { + if (!subPattern.color) continue; + subPattern.color = 'var(--jj-paper-grid-color)'; + } + } + return patterns; + }, + /** * Add listeners that record the original pointerdown target into the * drag's `evt.data`, so `pointermove` can use it as a `setPointerCapture` From 70148420f2de5bf6404eb05679a762065d96b14c Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Fri, 22 May 2026 14:15:09 +0200 Subject: [PATCH 2/6] refactor --- packages/joint-core/src/dia/GridLayerView.mjs | 2 ++ packages/joint-core/src/dia/Paper.mjs | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/joint-core/src/dia/GridLayerView.mjs b/packages/joint-core/src/dia/GridLayerView.mjs index 843fed8e62..14da7ae42f 100644 --- a/packages/joint-core/src/dia/GridLayerView.mjs +++ b/packages/joint-core/src/dia/GridLayerView.mjs @@ -26,6 +26,8 @@ export const GridLayerView = LayerView.extend({ }, afterPaperReferenceSet(paper) { + // override deprecated property with method call to get grid patterns + this.options.patterns = paper.getGridPatterns(); this.listenTo(paper, 'transform resize', this.updateGrid); }, diff --git a/packages/joint-core/src/dia/Paper.mjs b/packages/joint-core/src/dia/Paper.mjs index c2ee4cb5ee..48b896f883 100644 --- a/packages/joint-core/src/dia/Paper.mjs +++ b/packages/joint-core/src/dia/Paper.mjs @@ -857,10 +857,6 @@ export const Paper = View.extend({ */ renderImplicitLayerViews: function() { this.implicitLayers.forEach(layerInit => { - if (layerInit.type === 'GridLayerView') { - layerInit.patterns = this.getGridPatterns(); - } - const layerView = this.createLayerView(layerInit); this.addLayerView(layerView); }); From 0b97ae3e5f7a2e7f07e6c0357960c8a4c818ca5c Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Fri, 22 May 2026 14:47:08 +0200 Subject: [PATCH 3/6] updates --- packages/joint-core/src/dia/GridLayerView.mjs | 1 - packages/joint-core/src/dia/Paper.mjs | 5 +---- packages/joint-core/types/dia.d.ts | 4 ++-- packages/joint-react/src/presets/paper.ts | 3 +-- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/joint-core/src/dia/GridLayerView.mjs b/packages/joint-core/src/dia/GridLayerView.mjs index 14da7ae42f..2bb67b90f5 100644 --- a/packages/joint-core/src/dia/GridLayerView.mjs +++ b/packages/joint-core/src/dia/GridLayerView.mjs @@ -26,7 +26,6 @@ export const GridLayerView = LayerView.extend({ }, afterPaperReferenceSet(paper) { - // override deprecated property with method call to get grid patterns this.options.patterns = paper.getGridPatterns(); this.listenTo(paper, 'transform resize', this.updateGrid); }, diff --git a/packages/joint-core/src/dia/Paper.mjs b/packages/joint-core/src/dia/Paper.mjs index 48b896f883..3a572a9c98 100644 --- a/packages/joint-core/src/dia/Paper.mjs +++ b/packages/joint-core/src/dia/Paper.mjs @@ -615,10 +615,7 @@ export const Paper = View.extend({ // Layers that are always present on the paper (e.g. grid, back, front, tools) implicitLayers: [{ id: paperLayers.GRID, - type: 'GridLayerView', - // @deprecated, `getGridPatterns` method overrides this property when creating the GridLayerView instance, - // so this is kept for backward compatibility only. - patterns: gridPatterns + type: 'GridLayerView' }, { id: paperLayers.BACK, }, { diff --git a/packages/joint-core/types/dia.d.ts b/packages/joint-core/types/dia.d.ts index b054b65baa..da25e87f82 100644 --- a/packages/joint-core/types/dia.d.ts +++ b/packages/joint-core/types/dia.d.ts @@ -2149,6 +2149,8 @@ export class Paper extends mvc.View { setGridSize(gridSize: number): this; + getGridPatterns(): Record; + // tools removeTools(): this; @@ -2384,8 +2386,6 @@ export class Paper extends mvc.View { protected addStylesheet(stylesheet: string): void; - protected getGridPatterns(): Record; - /** * @deprecated use `getLayerView(id).el` instead * **/ diff --git a/packages/joint-react/src/presets/paper.ts b/packages/joint-react/src/presets/paper.ts index 13272e5ec3..208c3201b4 100644 --- a/packages/joint-react/src/presets/paper.ts +++ b/packages/joint-react/src/presets/paper.ts @@ -18,7 +18,6 @@ const POINTER_DOCUMENT_EVENTS: Record = { }; type ProtectedPaperPrototype = { - readonly getGridPatterns: () => Record; readonly pointermove: (event: dia.Event) => void; readonly pointerup: (event: dia.Event) => void; readonly startListening: () => void; @@ -108,7 +107,7 @@ export const Paper = dia.Paper.extend({ documentEvents: POINTER_DOCUMENT_EVENTS, getGridPatterns() { - const patterns = protectedProto.getGridPatterns.call(this); + const patterns = dia.Paper.prototype.getGridPatterns.call(this); // Change default color to CSS variable for (const pattern of Object.values(patterns)) { for (const subPattern of pattern) { From 7705940c4792f3d3f8b4a05fe6f25230b0cdaa1a Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Fri, 22 May 2026 15:00:19 +0200 Subject: [PATCH 4/6] up --- packages/joint-core/src/dia/GridLayerView.mjs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/joint-core/src/dia/GridLayerView.mjs b/packages/joint-core/src/dia/GridLayerView.mjs index 2bb67b90f5..d5021f786a 100644 --- a/packages/joint-core/src/dia/GridLayerView.mjs +++ b/packages/joint-core/src/dia/GridLayerView.mjs @@ -20,13 +20,12 @@ export const GridLayerView = LayerView.extend({ init() { LayerView.prototype.init.apply(this, arguments); - this.paper = this.options.paper; this._gridCache = null; this._gridSettings = []; }, afterPaperReferenceSet(paper) { - this.options.patterns = paper.getGridPatterns(); + this.patterns = paper.getGridPatterns(); this.listenTo(paper, 'transform resize', this.updateGrid); }, @@ -151,7 +150,7 @@ export const GridLayerView = LayerView.extend({ _resolveDrawGridOption(opt) { - const namespace = this.options.patterns; + const namespace = this.patterns; if (isString(opt) && Array.isArray(namespace[opt])) { return namespace[opt].map(function(item) { return assign({}, item); From eb3b0202e09ee2ccfb038d7f787c884c168da05c Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Fri, 22 May 2026 16:25:47 +0200 Subject: [PATCH 5/6] updates --- packages/joint-core/src/dia/GridLayerView.mjs | 2 +- packages/joint-core/src/dia/Paper.mjs | 8 -------- packages/joint-core/types/dia.d.ts | 2 -- packages/joint-react/src/presets/paper.ts | 20 ++++++++++++++++--- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/joint-core/src/dia/GridLayerView.mjs b/packages/joint-core/src/dia/GridLayerView.mjs index d5021f786a..81a5243575 100644 --- a/packages/joint-core/src/dia/GridLayerView.mjs +++ b/packages/joint-core/src/dia/GridLayerView.mjs @@ -25,7 +25,7 @@ export const GridLayerView = LayerView.extend({ }, afterPaperReferenceSet(paper) { - this.patterns = paper.getGridPatterns(); + this.patterns = paper.constructor.gridPatterns; this.listenTo(paper, 'transform resize', this.updateGrid); }, diff --git a/packages/joint-core/src/dia/Paper.mjs b/packages/joint-core/src/dia/Paper.mjs index 3a572a9c98..c2861b1431 100644 --- a/packages/joint-core/src/dia/Paper.mjs +++ b/packages/joint-core/src/dia/Paper.mjs @@ -840,14 +840,6 @@ export const Paper = View.extend({ }); }, - /** - * @protected - * @description Returns grid patterns for the paper grid layer. - */ - getGridPatterns: function() { - return cloneDeep(this.constructor.gridPatterns); - }, - /** * @protected * @description Renders all implicit layer views. diff --git a/packages/joint-core/types/dia.d.ts b/packages/joint-core/types/dia.d.ts index da25e87f82..e1fec5f798 100644 --- a/packages/joint-core/types/dia.d.ts +++ b/packages/joint-core/types/dia.d.ts @@ -2149,8 +2149,6 @@ export class Paper extends mvc.View { setGridSize(gridSize: number): this; - getGridPatterns(): Record; - // tools removeTools(): this; diff --git a/packages/joint-react/src/presets/paper.ts b/packages/joint-react/src/presets/paper.ts index 208c3201b4..19e5db51e9 100644 --- a/packages/joint-react/src/presets/paper.ts +++ b/packages/joint-react/src/presets/paper.ts @@ -1,4 +1,4 @@ -import { dia } from '@joint/core'; +import { dia, util } from '@joint/core'; import { measureNode } from './measure-node'; import { linkRoutingStraight } from './link-routing'; import { LinkView } from './link-view'; @@ -101,12 +101,24 @@ const linkView = ( return NSViewCtor ?? LinkView; }; +function getGridPatterns(): Record { + // @ts-expect-error Accessing protected member to set default grid pattern colors + const patterns = util.cloneDeep(dia.Paper.gridPatterns as Record); + for (const pattern of Object.values(patterns)) { + for (const subPattern of pattern) { + if (!subPattern.color) continue; + subPattern.color = 'var(--jj-paper-grid-color)'; + } + } + return patterns; +} + export const Paper = dia.Paper.extend({ className: 'jj-paper joint-paper', classNamePrefix: '', documentEvents: POINTER_DOCUMENT_EVENTS, - getGridPatterns() { + /*getGridPatterns() { const patterns = dia.Paper.prototype.getGridPatterns.call(this); // Change default color to CSS variable for (const pattern of Object.values(patterns)) { @@ -116,7 +128,7 @@ export const Paper = dia.Paper.extend({ } } return patterns; - }, + },*/ /** * Add listeners that record the original pointerdown target into the @@ -210,4 +222,6 @@ export const Paper = dia.Paper.extend({ measureNode, linkView, }, +}, { + gridPatterns: getGridPatterns(), }) as typeof dia.Paper; From 5e311ae6021e90a9c99d6a730828051f6aa29a4e Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Fri, 22 May 2026 16:29:29 +0200 Subject: [PATCH 6/6] up --- packages/joint-react/src/presets/paper.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/packages/joint-react/src/presets/paper.ts b/packages/joint-react/src/presets/paper.ts index 19e5db51e9..8256d23dd1 100644 --- a/packages/joint-react/src/presets/paper.ts +++ b/packages/joint-react/src/presets/paper.ts @@ -118,18 +118,6 @@ export const Paper = dia.Paper.extend({ classNamePrefix: '', documentEvents: POINTER_DOCUMENT_EVENTS, - /*getGridPatterns() { - const patterns = dia.Paper.prototype.getGridPatterns.call(this); - // Change default color to CSS variable - for (const pattern of Object.values(patterns)) { - for (const subPattern of pattern) { - if (!subPattern.color) continue; - subPattern.color = 'var(--jj-paper-grid-color)'; - } - } - return patterns; - },*/ - /** * Add listeners that record the original pointerdown target into the * drag's `evt.data`, so `pointermove` can use it as a `setPointerCapture`