From 66c2bf315156b623bb37a22a1be0afc44d61e4e7 Mon Sep 17 00:00:00 2001 From: L-Sun Date: Thu, 14 Aug 2025 11:10:32 +0800 Subject: [PATCH] fix(editor): incorrect z-index in dom renderer (#13465) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### PR Dependency Tree * **PR #13464** * **PR #13465** 👈 * **PR #13471** * **PR #13472** * **PR #13473** This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) ## Summary by CodeRabbit * **Bug Fixes** * Improved stacking order across canvas elements (shapes, connectors, brush, highlighter), reducing unexpected overlap. * Corrected z-index application for placeholders and fully rendered elements to ensure consistent layering during edits. * **Refactor** * Centralized z-index handling for canvas elements to provide predictable, uniform layering behavior across the app. --- .../affine/blocks/surface/src/renderer/dom-renderer.ts | 10 ++++++++-- blocksuite/affine/gfx/brush/src/renderer/dom/brush.ts | 3 --- .../affine/gfx/brush/src/renderer/dom/highlighter.ts | 3 --- .../src/element-renderer/connector-dom/index.ts | 3 --- .../gfx/shape/src/element-renderer/shape-dom/index.ts | 2 -- blocksuite/framework/std/src/gfx/layer.ts | 5 ++--- blocksuite/framework/std/src/utils/layer.ts | 8 ++------ .../src/__tests__/edgeless/layer.spec.ts | 2 +- 8 files changed, 13 insertions(+), 23 deletions(-) diff --git a/blocksuite/affine/blocks/surface/src/renderer/dom-renderer.ts b/blocksuite/affine/blocks/surface/src/renderer/dom-renderer.ts index b711d64a78..73c9c10096 100644 --- a/blocksuite/affine/blocks/surface/src/renderer/dom-renderer.ts +++ b/blocksuite/affine/blocks/surface/src/renderer/dom-renderer.ts @@ -298,7 +298,10 @@ export class DomRenderer { viewportBounds, zoom ); - Object.assign(domElement.style, geometricStyles); + const zIndexStyle = { + 'z-index': this.layerManager.getZIndex(elementModel), + }; + Object.assign(domElement.style, geometricStyles, zIndexStyle); Object.assign(domElement.style, PLACEHOLDER_RESET_STYLES); // Clear classes specific to shapes, if applicable @@ -335,7 +338,10 @@ export class DomRenderer { zoom ); const opacityStyle = getOpacity(elementModel); - Object.assign(domElement.style, geometricStyles, opacityStyle); + const zIndexStyle = { + 'z-index': this.layerManager.getZIndex(elementModel), + }; + Object.assign(domElement.style, geometricStyles, opacityStyle, zIndexStyle); this._renderElement(elementModel, domElement); } diff --git a/blocksuite/affine/gfx/brush/src/renderer/dom/brush.ts b/blocksuite/affine/gfx/brush/src/renderer/dom/brush.ts index 88b15ae80f..5f5dea340a 100644 --- a/blocksuite/affine/gfx/brush/src/renderer/dom/brush.ts +++ b/blocksuite/affine/gfx/brush/src/renderer/dom/brush.ts @@ -65,8 +65,5 @@ export const BrushDomRendererExtension = DomElementRendererExtension( domElement.style.height = `${h * zoom}px`; domElement.style.overflow = 'visible'; domElement.style.pointerEvents = 'none'; - - // Set z-index for layering - domElement.style.zIndex = renderer.layerManager.getZIndex(model).toString(); } ); diff --git a/blocksuite/affine/gfx/brush/src/renderer/dom/highlighter.ts b/blocksuite/affine/gfx/brush/src/renderer/dom/highlighter.ts index aa9583b037..e15f2a300e 100644 --- a/blocksuite/affine/gfx/brush/src/renderer/dom/highlighter.ts +++ b/blocksuite/affine/gfx/brush/src/renderer/dom/highlighter.ts @@ -69,8 +69,5 @@ export const HighlighterDomRendererExtension = DomElementRendererExtension( domElement.style.height = `${h * zoom}px`; domElement.style.overflow = 'visible'; domElement.style.pointerEvents = 'none'; - - // Set z-index for layering - domElement.style.zIndex = renderer.layerManager.getZIndex(model).toString(); } ); diff --git a/blocksuite/affine/gfx/connector/src/element-renderer/connector-dom/index.ts b/blocksuite/affine/gfx/connector/src/element-renderer/connector-dom/index.ts index 44c44fb280..f8de1d12d8 100644 --- a/blocksuite/affine/gfx/connector/src/element-renderer/connector-dom/index.ts +++ b/blocksuite/affine/gfx/connector/src/element-renderer/connector-dom/index.ts @@ -359,9 +359,6 @@ export const connectorDomRenderer = ( element.style.overflow = 'visible'; element.style.pointerEvents = 'none'; - // Set z-index for layering - element.style.zIndex = renderer.layerManager.getZIndex(model).toString(); - // Render label if present renderConnectorLabel(model, element, renderer, zoom); }; diff --git a/blocksuite/affine/gfx/shape/src/element-renderer/shape-dom/index.ts b/blocksuite/affine/gfx/shape/src/element-renderer/shape-dom/index.ts index 2308a42d9e..bdcc807cc4 100644 --- a/blocksuite/affine/gfx/shape/src/element-renderer/shape-dom/index.ts +++ b/blocksuite/affine/gfx/shape/src/element-renderer/shape-dom/index.ts @@ -181,8 +181,6 @@ export const shapeDomRenderer = ( applyTransformStyles(model, element); - element.style.zIndex = renderer.layerManager.getZIndex(model).toString(); - manageClassNames(model, element); applyShadowStyles(model, element, renderer); }; diff --git a/blocksuite/framework/std/src/gfx/layer.ts b/blocksuite/framework/std/src/gfx/layer.ts index fe3259f0ab..e26a2134cc 100644 --- a/blocksuite/framework/std/src/gfx/layer.ts +++ b/blocksuite/framework/std/src/gfx/layer.ts @@ -57,7 +57,7 @@ export type CanvasLayer = BaseLayer & { type: 'canvas'; /** - * The z-index of canvas layer. + * The z-index of the first element in this canvas layer. * * A canvas layer renders all the elements in a single canvas, * this property is used to render the canvas with correct z-index. @@ -165,8 +165,7 @@ export class LayerManager extends GfxExtension { ]; curLayer.zIndex = currentCSSZindex; layers.push(curLayer as LayerManager['layers'][number]); - currentCSSZindex += - curLayer.type === 'block' ? curLayer.elements.length : 1; + currentCSSZindex += curLayer.elements.length; } }; const addLayer = (type: 'canvas' | 'block') => { diff --git a/blocksuite/framework/std/src/utils/layer.ts b/blocksuite/framework/std/src/utils/layer.ts index 7ca5b44337..f078518488 100644 --- a/blocksuite/framework/std/src/utils/layer.ts +++ b/blocksuite/framework/std/src/utils/layer.ts @@ -12,11 +12,7 @@ import type { SurfaceBlockModel } from '../gfx/model/surface/surface-model.js'; export function getLayerEndZIndex(layers: Layer[], layerIndex: number) { const layer = layers[layerIndex]; - return layer - ? layer.type === 'block' - ? layer.zIndex + layer.elements.length - 1 - : layer.zIndex - : 0; + return layer ? layer.zIndex + layer.elements.length - 1 : 0; } export function updateLayersZIndex(layers: Layer[], startIdx: number) { @@ -27,7 +23,7 @@ export function updateLayersZIndex(layers: Layer[], startIdx: number) { const curLayer = layers[i]; curLayer.zIndex = curIndex; - curIndex += curLayer.type === 'block' ? curLayer.elements.length : 1; + curIndex += curLayer.elements.length; } } diff --git a/blocksuite/integration-test/src/__tests__/edgeless/layer.spec.ts b/blocksuite/integration-test/src/__tests__/edgeless/layer.spec.ts index 984db465b5..1cbb9ec907 100644 --- a/blocksuite/integration-test/src/__tests__/edgeless/layer.spec.ts +++ b/blocksuite/integration-test/src/__tests__/edgeless/layer.spec.ts @@ -200,7 +200,7 @@ test('layer zindex should update correctly when elements changed', async () => { expect(service.layer.layers[1].zIndex).toBe(3); expect(service.layer.layers[2].type).toBe('block'); - expect(service.layer.layers[2].zIndex).toBe(4); + expect(service.layer.layers[2].zIndex).toBe(5); }; assert2StepState();