From 4055dcad3f286d993c107d11cda3554c6f2df803 Mon Sep 17 00:00:00 2001 From: Rick Butterfield Date: Wed, 17 Jun 2026 09:19:04 +0100 Subject: [PATCH 1/2] fix: Prevent Block Grid area previews rendering before layoutAreas are available (#293) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a timing regression introduced in 5.4.0 where blocks with Areas could render an incomplete preview (empty Areas) if UMB_BLOCK_GRID_MANAGER_CONTEXT fired before layoutAreas arrived from UMB_BLOCK_GRID_ENTRY_CONTEXT. Two-part fix: - #observeBlockPropertyValue: defer the initial render when areas are configured but layoutAreas have not arrived yet, instead of rendering with empty area items. - observeBlockValue: trigger a re-render when layoutAreas first become available (prevLayoutAreas undefined → real value) so blocks that did receive an incomplete early render are refreshed with full area content. Also applies the contentUdi guard (only subscribe to manager context once contentUdi is non-empty) to prevent a parallel issue where an empty contentUdi on the first entry-context emission could lock the manager subscription into returning an empty blockGridValue. Co-Authored-By: Claude Sonnet 4.6 --- .../block-grid-preview.custom-view.element.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Community.BlockPreview.UI/src/blockEditor/block-grid-preview.custom-view.element.ts b/src/Umbraco.Community.BlockPreview.UI/src/blockEditor/block-grid-preview.custom-view.element.ts index 4da9534..1c01efb 100644 --- a/src/Umbraco.Community.BlockPreview.UI/src/blockEditor/block-grid-preview.custom-view.element.ts +++ b/src/Umbraco.Community.BlockPreview.UI/src/blockEditor/block-grid-preview.custom-view.element.ts @@ -103,6 +103,7 @@ export class BlockGridPreviewCustomView extends BlockPreviewBaseElement { const prevColumnSpan = this._blockContext.layout?.columnSpan; const prevRowSpan = this._blockContext.layout?.rowSpan; + const prevLayoutAreas = this._blockContext.layoutAreas; this._blockContext.contentUdi = contentUdi ?? ''; this._blockContext.settingsUdi = settingsUdi ?? ''; @@ -113,11 +114,16 @@ export class BlockGridPreviewCustomView extends BlockPreviewBaseElement 0) { + this.renderBlockPreview(); + } + // Re-render when layout dimensions change (resize) if (this._htmlMarkup && layout && ( layout.columnSpan !== prevColumnSpan || @@ -161,6 +167,11 @@ export class BlockGridPreviewCustomView extends BlockPreviewBaseElement x.key === this._blockContext.contentUdi); if (!this._htmlMarkup && !this._isLoading) { + // Defer render if areas are expected but layoutAreas haven't arrived yet; + // observeBlockValue will trigger the render once layoutAreas are available. + if ((this._blockContext.areas?.length ?? 0) > 0 && !this._blockContext.layoutAreas) { + return; + } this.renderBlockPreview(); } } From 78979ae7fd356ed458aec49d0f4b9ba29506eb0f Mon Sep 17 00:00:00 2001 From: Rick Butterfield Date: Wed, 17 Jun 2026 09:32:23 +0100 Subject: [PATCH 2/2] fix: Address PR review feedback on layoutAreas re-render and null safety - Rebuild blockGridValue.layout before re-rendering on layoutAreas arrival so callPreviewApi() sends updated area data, not the stale empty layout - Remove _htmlMarkup requirement from the layoutAreas re-render condition so the deferred case (initial render skipped) is also handled - Guard the re-render on #managerObserved so it only fires once contentData is available from the manager context - Fix contents.findIndex() to use (contents ?? []).findIndex() for null safety Co-Authored-By: Claude Sonnet 4.6 --- .../block-grid-preview.custom-view.element.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Community.BlockPreview.UI/src/blockEditor/block-grid-preview.custom-view.element.ts b/src/Umbraco.Community.BlockPreview.UI/src/blockEditor/block-grid-preview.custom-view.element.ts index 1c01efb..ddc4fd8 100644 --- a/src/Umbraco.Community.BlockPreview.UI/src/blockEditor/block-grid-preview.custom-view.element.ts +++ b/src/Umbraco.Community.BlockPreview.UI/src/blockEditor/block-grid-preview.custom-view.element.ts @@ -119,8 +119,15 @@ export class BlockGridPreviewCustomView extends BlockPreviewBaseElement 0) { + // Re-render when layoutAreas first arrive for a block with areas. + // Covers both the deferred case (_htmlMarkup empty) and the early-render + // case (_htmlMarkup set from an incomplete render). blockGridValue.layout + // must be rebuilt here so callPreviewApi() sends the updated area data. + if (!prevLayoutAreas && layoutAreas && (areas?.length ?? 0) > 0 && this.#managerObserved && !this._isLoading) { + this.blockGridValue = { + ...this._blockGridValue, + layout: { ['Umbraco.BlockGrid']: this.#filterLayouts() } + }; this.renderBlockPreview(); } @@ -165,7 +172,7 @@ export class BlockGridPreviewCustomView extends BlockPreviewBaseElement x.key === this._blockContext.contentUdi); + this._blockContext.blockIndex = (contents ?? []).findIndex(x => x.key === this._blockContext.contentUdi); if (!this._htmlMarkup && !this._isLoading) { // Defer render if areas are expected but layoutAreas haven't arrived yet; // observeBlockValue will trigger the render once layoutAreas are available.