From 360d95cc487a11489e139e4ff04f6d38374199d7 Mon Sep 17 00:00:00 2001 From: weareoutman Date: Mon, 11 Nov 2024 09:53:01 +0800 Subject: [PATCH] fix(): allow transform in useBrick + slots --- etc/runtime.api.md | 2 + packages/runtime/src/internal/Renderer.ts | 24 ++++++- packages/runtime/src/internal/interfaces.ts | 1 + .../src/internal/secret_internals.spec.ts | 63 +++++++++++++++++-- .../runtime/src/internal/secret_internals.ts | 17 +---- 5 files changed, 85 insertions(+), 22 deletions(-) diff --git a/etc/runtime.api.md b/etc/runtime.api.md index b15862036b..5921e3c947 100644 --- a/etc/runtime.api.md +++ b/etc/runtime.api.md @@ -416,6 +416,8 @@ interface RuntimeContext extends LegacyCompatibleRuntimeContext { // (undocumented) formStateStoreScope?: DataStore<"FORM_STATE">[]; // (undocumented) + inUseBrick?: boolean; + // (undocumented) pendingPermissionsPreCheck: (Promise | undefined)[]; // (undocumented) tplStateStoreId?: string; diff --git a/packages/runtime/src/internal/Renderer.ts b/packages/runtime/src/internal/Renderer.ts index fb91429b2e..ec0aa649a4 100644 --- a/packages/runtime/src/internal/Renderer.ts +++ b/packages/runtime/src/internal/Renderer.ts @@ -391,10 +391,10 @@ async function legacyRenderBrick( runtimeContext.forEachSize = brickConf[symbolForTPlExternalForEachSize]; } + const strict = isStrictMode(runtimeContext); const { context } = brickConf as { context?: ContextConf[] }; // istanbul ignore next if (Array.isArray(context) && context.length > 0) { - const strict = isStrictMode(runtimeContext); warnAboutStrictMode( strict, "Defining context on bricks", @@ -720,7 +720,27 @@ async function legacyRenderBrick( formData = await asyncComputeRealValue(formData, runtimeContext); } } else { - confProps = brickConf.properties; + if (runtimeContext.inUseBrick) { + // Keep v2 behavior for `useBrick`: treat `transform` as `properties`. + const transform = (brickConf as { transform?: Record }) + .transform; + if (transform) { + warnAboutStrictMode( + strict, + "`useBrick.transform`", + 'please use "properties" instead, check your useBrick:', + brickConf + ); + + if (!strict) { + confProps = { + ...brickConf.properties, + ...transform, + }; + } + } + } + confProps ??= brickConf.properties; } const trackingContextList: TrackingContextItem[] = []; diff --git a/packages/runtime/src/internal/interfaces.ts b/packages/runtime/src/internal/interfaces.ts index f62e451766..fdd593bfca 100644 --- a/packages/runtime/src/internal/interfaces.ts +++ b/packages/runtime/src/internal/interfaces.ts @@ -34,6 +34,7 @@ export interface RuntimeContext extends LegacyCompatibleRuntimeContext { formStateStoreMap: Map>; formStateStoreId?: string; formStateStoreScope?: DataStore<"FORM_STATE">[]; + inUseBrick?: boolean; } export type AsyncPropertyEntry = [ diff --git a/packages/runtime/src/internal/secret_internals.spec.ts b/packages/runtime/src/internal/secret_internals.spec.ts index a9e02db319..12047b1f67 100644 --- a/packages/runtime/src/internal/secret_internals.spec.ts +++ b/packages/runtime/src/internal/secret_internals.spec.ts @@ -200,7 +200,7 @@ describe("useBrick", () => { }); test("strict mode with transform", async () => { - mockIsStrictMode.mockReturnValueOnce(true); + mockIsStrictMode.mockReturnValue(true); const useBrick: any = { brick: "div", properties: { @@ -209,14 +209,34 @@ describe("useBrick", () => { transform: { title: "<% `byTransform:${DATA}` %>", }, + children: [ + { + brick: "span", + properties: { + title: "<% `byProperties:${DATA}` %>", + textContent: "<% `byProperties[text]:${DATA}` %>", + }, + transform: { + textContent: "<% `byTransform[text]:${DATA}` %>", + }, + }, + ], }; const renderResult = await renderUseBrick(useBrick, "ok"); - expect(warnAboutStrictMode).toBeCalledWith( + expect(warnAboutStrictMode).toHaveBeenNthCalledWith( + 1, true, "`useBrick.transform`", 'please use "properties" instead, check your useBrick:', useBrick ); + expect(warnAboutStrictMode).toHaveBeenNthCalledWith( + 2, + true, + "`useBrick.transform`", + 'please use "properties" instead, check your useBrick:', + useBrick.children[0] + ); expect(mockIsStrictMode).toBeCalled(); const root = document.createElement("div"); @@ -224,9 +244,16 @@ describe("useBrick", () => { expect(root).toMatchInlineSnapshot(`
+ > + + byProperties[text]:ok + +
`); unmountUseBrick(renderResult, mountResult); + mockIsStrictMode.mockReturnValue(false); }); test("non-strict mode with transform", async () => { @@ -238,21 +265,47 @@ describe("useBrick", () => { transform: { title: "<% `byTransform:${DATA}` %>", }, + children: [ + { + brick: "span", + properties: { + title: "<% `byProperties:${DATA}` %>", + textContent: "<% `byProperties[text]:${DATA}` %>", + }, + transform: { + textContent: "<% `byTransform[text]:${DATA}` %>", + }, + }, + ], }; const renderResult = await renderUseBrick(useBrick, "ok"); - expect(warnAboutStrictMode).toBeCalledWith( + expect(warnAboutStrictMode).toHaveBeenNthCalledWith( + 1, false, "`useBrick.transform`", 'please use "properties" instead, check your useBrick:', useBrick ); + expect(warnAboutStrictMode).toHaveBeenNthCalledWith( + 2, + false, + "`useBrick.transform`", + 'please use "properties" instead, check your useBrick:', + useBrick.children[0] + ); const root = document.createElement("div"); const mountResult = mountUseBrick(renderResult, root); expect(root).toMatchInlineSnapshot(`
+ > + + byTransform[text]:ok + +
`); unmountUseBrick(renderResult, mountResult); }); diff --git a/packages/runtime/src/internal/secret_internals.ts b/packages/runtime/src/internal/secret_internals.ts index 0913519c66..cbd304ff81 100644 --- a/packages/runtime/src/internal/secret_internals.ts +++ b/packages/runtime/src/internal/secret_internals.ts @@ -38,7 +38,7 @@ import type { import { mountTree, unmountTree } from "./mount.js"; import { RenderTag } from "./enums.js"; import { computeRealValue } from "./compute/computeRealValue.js"; -import { isStrictMode, warnAboutStrictMode } from "../isStrictMode.js"; +import { isStrictMode } from "../isStrictMode.js"; import { customTemplates } from "../CustomTemplates.js"; import { registerAppI18n } from "./registerAppI18n.js"; import { getTplStateStore } from "./CustomTemplates/utils.js"; @@ -76,6 +76,7 @@ export async function renderUseBrick( pendingPermissionsPreCheck: [], }); + scopedRuntimeContext.inUseBrick = true; scopedRuntimeContext.tplStateStoreMap ??= new Map(); scopedRuntimeContext.formStateStoreMap ??= new Map(); @@ -87,17 +88,7 @@ export async function renderUseBrick( createPortal: null!, }; - const transform = (useBrick as { transform?: Record }) - .transform; const strict = isStrictMode(); - if (transform) { - warnAboutStrictMode( - strict, - "`useBrick.transform`", - 'please use "properties" instead, check your useBrick:', - useBrick - ); - } const output = await renderBrick( renderRoot, @@ -106,10 +97,6 @@ export async function renderUseBrick( : { errorBoundary, ...useBrick, - properties: { - ...useBrick.properties, - ...transform, - }, }, scopedRuntimeContext, rendererContext,