From c805bba0c73e80b9d1083ed0b4a05eaabf264d88 Mon Sep 17 00:00:00 2001 From: Rainke Date: Wed, 12 Jul 2023 16:22:08 +0800 Subject: [PATCH 01/25] fix: keep `this` in parse expression function 1. Wrong work when function has `__self` 2. All `this` will replaced anyway --- packages/renderer-core/src/utils/common.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 29381b547..262231eef 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -251,23 +251,21 @@ function parseExpression(a: any, b?: any, c = false) { thisRequired = c; } try { - const contextArr = ['"use strict";', 'var __self = arguments[0];']; - contextArr.push('return '); let tarStr: string; tarStr = (str.value || '').trim(); - // NOTE: use __self replace 'this' in the original function str - // may be wrong in extreme case which contains '__self' already - tarStr = tarStr.replace(/this(\W|$)/g, (_a: any, b: any) => `__self${b}`); - tarStr = contextArr.join('\n') + tarStr; + let code = `"use strict"; function __wrapper(){ return ${tarStr}} return __wrapper.call(arguments[0])`; // 默认调用顶层窗口的parseObj, 保障new Function的window对象是顶层的window对象 if (inSameDomain() && (window.parent as any).__newFunc) { - return (window.parent as any).__newFunc(tarStr)(self); + return (window.parent as any).__newFunc(code)(self); } - const code = `with(${thisRequired ? '{}' : '$scope || {}'}) { ${tarStr} }`; - return new Function('$scope', code)(self); + if (!thisRequired) { + code = `with($scope){${code}}`; + } + const result = new Function('$scope', code)(self); + return typeof result === "function" ? result.bind(self): result; } catch (err) { logger.error(`${logScope || ''} parseExpression.error`, err, str, self?.__self ?? self); return undefined; From fc947d2feb0411223430ab154398cfcd83c11dcb Mon Sep 17 00:00:00 2001 From: Rainke Date: Tue, 18 Jul 2023 10:37:46 +0800 Subject: [PATCH 02/25] fix: remove function bind If the returned function is bound to a context, there is no way to call it with `call` and `apply`. --- packages/renderer-core/src/utils/common.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 262231eef..3439bf297 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -264,8 +264,7 @@ function parseExpression(a: any, b?: any, c = false) { if (!thisRequired) { code = `with($scope){${code}}`; } - const result = new Function('$scope', code)(self); - return typeof result === "function" ? result.bind(self): result; + return new Function('$scope', code)(self); } catch (err) { logger.error(`${logScope || ''} parseExpression.error`, err, str, self?.__self ?? self); return undefined; From 699abd69fb30aff1f8506f3db4ab53965350e897 Mon Sep 17 00:00:00 2001 From: webstar <814566123@qq.com> Date: Fri, 23 Feb 2024 17:48:16 +0800 Subject: [PATCH 03/25] docs: add star history to README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add star history to README。 --- packages/engine/README-zh_CN.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index 5442aa58b..f534bef0a 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -169,6 +169,12 @@ lowcode-engine 启动后,提供了几个 umd 文件,可以结合 [lowcode-de 关于提交 PR: 请将目标合并分支设置为 **develop**,不要指定 **main** 分支,在发布正式版本后,develop 分支将会合入 main 分支。 +## ⭐️ Star 历史 + + + Star History Chart + + ## ❤️ 致谢 感谢所有为引擎项目贡献力量的同学们~ From d66f712174304b637822f6888912cd7a15cac403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=8F=8A=E8=90=8D=28=E7=B5=AE=E9=BB=8E=29?= Date: Thu, 29 Feb 2024 15:18:14 +0800 Subject: [PATCH 04/25] Update commonUI.md --- docs/docs/api/commonUI.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/docs/api/commonUI.md b/docs/docs/api/commonUI.md index 45640051f..e997ac003 100644 --- a/docs/docs/api/commonUI.md +++ b/docs/docs/api/commonUI.md @@ -3,6 +3,8 @@ title: commonUI - UI 组件库 sidebar_position: 10 --- +> **@since** v1.3.0 + ## 简介 CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开发的插件,可以保证在不同项目和主题切换中能够保持一致性和兼容性。 From 4465866433280577bd775b14eba6488244d2b98e Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 29 Feb 2024 08:48:58 +0000 Subject: [PATCH 05/25] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 574ff2878..1e203302b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.32", + "version": "1.2.33", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 40eb152a4e2e07e16d12ed6d5441ce4937f07241 Mon Sep 17 00:00:00 2001 From: DiscoverForever <595740536@qq.com> Date: Wed, 28 Feb 2024 14:57:51 +0800 Subject: [PATCH 06/25] =?UTF-8?q?docs:=20fix=20incorrect=20word,=20change?= =?UTF-8?q?=20"=E6=90=9C=E6=90=9C"=20to=20"=E6=90=9C=E7=B4=A2"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复readme中的错别字,"搜搜"修改为"搜索"。 --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 85da75163..78ca20006 100644 --- a/docs/README.md +++ b/docs/README.md @@ -36,7 +36,7 @@ $ yarn build ## 功能 -- [x] 支持本地离线搜搜 +- [x] 支持本地离线搜索 - [x] 版本化文档管理 - [x] 离线静态部署 - [x] 主题(fork 宜搭开发者中心) From 814d046a43bb5772d679a6b17f4273b174c6aac5 Mon Sep 17 00:00:00 2001 From: zzzhrookie Date: Tue, 27 Feb 2024 23:21:17 +0800 Subject: [PATCH 07/25] docs(chore): fix incorrect link redirects within lowcode-spec.md --- docs/docs/specs/lowcode-spec.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs/specs/lowcode-spec.md b/docs/docs/specs/lowcode-spec.md index c27721410..409883aa9 100644 --- a/docs/docs/specs/lowcode-spec.md +++ b/docs/docs/specs/lowcode-spec.md @@ -20,7 +20,7 @@ sidebar_position: 0 ### 1.2 协议草案起草人 - 撰写:月飞、康为、林熠 -- 审阅:大果、潕量、九神、元彦、戊子、屹凡、金禅、前道、天晟、戊子、游鹿、光弘、力皓 +- 审阅:大果、潕量、九神、元彦、戊子、屹凡、金禅、前道、天晟、游鹿、光弘、力皓 ### 1.3 版本号 @@ -430,7 +430,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input'; | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | ----------- | ---------------------- | -------------------------------------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------- | | list[] | 数据源列表 | **ComponentDataSourceItem**[] | - | - | 成为为单个请求配置, 内容定义详见 [ComponentDataSourceItem 对象描述](#2314-componentdatasourceitem-对象描述) | -| dataHandler | 所有请求数据的处理函数 | Function | - | - | 详见 [dataHandler Function 描述](#2317-datahandler-function 描述) | +| dataHandler | 所有请求数据的处理函数 | Function | - | - | 详见 [dataHandler Function 描述](#2317-datahandler-function-描述) | ##### 2.3.1.4 ComponentDataSourceItem 对象描述 @@ -447,7 +447,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input'; | errorHandler | request 失败后的回调函数 | Function | - | - | 参数:请求出错 promise 的 error 内容 | | options {} | 请求参数 | **ComponentDataSourceItemOptions**| - | - | 每种请求类型对应不同参数,详见 | 每种请求类型对应不同参数,详见 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) | -**关于 dataHandler 于 errorHandler 的细节说明:** +**关于 dataHandler 与 errorHandler 的细节说明:** request 返回的是一个 promise,dataHandler 和 errorHandler 遵循 Promise 对象的 then 方法,实际使用方式如下: @@ -560,7 +560,7 @@ try { | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | ------------- | ---------------------- | ---------------- | -------- | ----------------- | ---------------------------------------------------------------------------------------------------------- | | id | 组件唯一标识 | String | - | | 可选,组件 id 由引擎随机生成(UUID),并保证唯一性,消费方为上层应用平台,在组件发生移动等场景需保持 id 不变 | -| componentName | 组件名称 | String | - | Div | 必填,首字母大写,同 [componentsMap](#22-组件映射关系 a) 中的要求 | +| componentName | 组件名称 | String | - | Div | 必填,首字母大写,同 [componentsMap](#22-组件映射关系a) 中的要求 | | props {} | 组件属性对象 | **Props**| - | {} | 必填,详见 | 必填,详见 [Props 结构描述](#2311-props-结构描述) | | condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 | | loop | 循环数据 | Array | ✅ | - | 选填,默认不进行循环渲染;支持变量表达式 | @@ -797,7 +797,7 @@ try { | 参数 | 说明 | 值类型 | 默认值 | 备注 | | ------ | ---------- | --------------------- | -------- | -------------------------------------------------------------- | | type | 值类型描述 | String | 'JSSlot' | 固定值 | -| value | 具体的值 | NodeSchema \| NodeSchema[] | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述 a) | +| value | 具体的值 | NodeSchema \| NodeSchema[] | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述(A)) | | params | 函数的参数 | String[] | null | 函数的入参,其子节点可以通过 `this[参数名]` 来获取对应的参数。 | @@ -1124,7 +1124,7 @@ this.setState((prevState) => ({ count: prevState.count + 1 })); | utils[] | 工具类扩展映射关系 | **UtilItem**[] | - | | | *UtilItem*.name | 工具类扩展项名称 | String | - | | | *UtilItem*.type | 工具类扩展项类型 | 枚举, `'npm'` (代表公网 npm 类型) / `'tnpm'` (代表阿里巴巴内部 npm 类型) / `'function'` (代表 Javascript 函数类型) | - | | -| *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系 a) 或 [JSFunction](#2432事件函数类型 a) | - | | +| *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系a) 或 [JSFunction](#2342事件函数类型a) | - | | 描述示例: From 98e9179f23d9898fbb8820f0bc2639ba184119a2 Mon Sep 17 00:00:00 2001 From: zzzhrookie Date: Tue, 27 Feb 2024 23:21:32 +0800 Subject: [PATCH 08/25] docs(chore): update command for developing docs --- docs/docs/participate/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/participate/index.md b/docs/docs/participate/index.md index e09f2ddad..7f6452fb1 100644 --- a/docs/docs/participate/index.md +++ b/docs/docs/participate/index.md @@ -70,7 +70,7 @@ npm start 在 lowcode-engine 目录下执行下面命令 ``` cd docs - +npm install npm start ``` From 72a5a279c36b2b85c7797d5904a5652d6abda90c Mon Sep 17 00:00:00 2001 From: zzzhrookie Date: Wed, 28 Feb 2024 10:05:40 +0800 Subject: [PATCH 09/25] docs(chore): replace English parentheses with Chinese ones --- docs/docs/specs/lowcode-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/specs/lowcode-spec.md b/docs/docs/specs/lowcode-spec.md index 409883aa9..480698354 100644 --- a/docs/docs/specs/lowcode-spec.md +++ b/docs/docs/specs/lowcode-spec.md @@ -94,7 +94,7 @@ sidebar_position: 0 ### 1.9 使用范围 -本协议描述的是低代码搭建平台产物(应用、页面、区块、组件)的 schema 结构,以及实现其数据状态更新(内置 api)、能力扩展、国际化等方面完整,只在低代码搭建场景下可用; +本协议描述的是低代码搭建平台产物(应用、页面、区块、组件)的 schema 结构,以及实现其数据状态更新(内置 api)、能力扩展、国际化等方面完整,只在低代码搭建场景下可用; ### 1.10 协议目标 From d986beedbcf57f87e7f22bf3ec4e391680054c7b Mon Sep 17 00:00:00 2001 From: zzzhrookie Date: Wed, 28 Feb 2024 17:19:36 +0800 Subject: [PATCH 10/25] docs(chore): fix incorrect module name --- docs/docs/guide/create/useRenderer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guide/create/useRenderer.md b/docs/docs/guide/create/useRenderer.md index a9fc79909..9a577bac6 100644 --- a/docs/docs/guide/create/useRenderer.md +++ b/docs/docs/guide/create/useRenderer.md @@ -20,7 +20,7 @@ sidebar_position: 1 [在 Demo 中](https://lowcode-engine.cn/demo/demo-general/index.html),右上角有渲染模块的示例使用方式: ![Mar-13-2022 16-52-49.gif](https://img.alicdn.com/imgextra/i2/O1CN01PRsEl61o7Zct5fJML_!!6000000005178-1-tps-1534-514.gif) -基于官方提供的渲染模块 [@alifd/lowcode-react-renderer](https://github.com/alibaba/lowcode-engine/tree/main/packages/react-renderer),你可以在 React 上下文渲染低代码编辑器产出的页面。 +基于官方提供的渲染模块 [@alilc/lowcode-react-renderer](https://github.com/alibaba/lowcode-engine/tree/main/packages/react-renderer),你可以在 React 上下文渲染低代码编辑器产出的页面。 ### 构造渲染模块所需数据 From cc45087225f1aa7bd2e9260e782b83abdc2bfce0 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 1 Mar 2024 00:27:33 +0000 Subject: [PATCH 11/25] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 1e203302b..dfe270bac 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.33", + "version": "1.2.34", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 7cecf91a2528a23713e7649df096ee4394bb4204 Mon Sep 17 00:00:00 2001 From: liujuping Date: Thu, 29 Feb 2024 18:02:29 +0800 Subject: [PATCH 12/25] feat(hotkey): Add mount method to Hotkey class --- docs/docs/api/hotkey.md | 13 +++++++++++++ packages/designer/src/project/project.ts | 2 +- packages/editor-core/src/command.ts | 10 ++-------- packages/editor-core/src/hotkey.ts | 11 ++++++----- packages/shell/src/api/hotkey.ts | 8 ++++++++ packages/types/src/shell/api/hotkey.ts | 6 ++++++ 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/docs/docs/api/hotkey.md b/docs/docs/api/hotkey.md index be6a3033d..b391e367b 100644 --- a/docs/docs/api/hotkey.md +++ b/docs/docs/api/hotkey.md @@ -32,6 +32,19 @@ bind( - [IPublicTypeHotkeyCallback](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/hotkey-callback.ts) - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) +### mount + +给指定窗口绑定快捷键 + +```typescript +/** + * 给指定窗口绑定快捷键 + * @param window 窗口的 window 对象 + */ +mount(window: Window): IPublicTypeDisposable; + +``` + ## 使用示例 ### 基础示例 diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index 94913d9fa..88978e467 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -68,7 +68,7 @@ export interface IProject extends Omit void): () => void; - onSimulatorReady(fn: (args: any) => void): () => void; + onSimulatorReady(fn: (simulator: ISimulatorHost) => void): () => void; onRendererReady(fn: () => void): () => void; diff --git a/packages/editor-core/src/command.ts b/packages/editor-core/src/command.ts index 7facc33d9..04bd5ba5a 100644 --- a/packages/editor-core/src/command.ts +++ b/packages/editor-core/src/command.ts @@ -1,18 +1,12 @@ import { IPublicApiCommand, IPublicEnumTransitionType, IPublicModelPluginContext, IPublicTypeCommand, IPublicTypeCommandHandlerArgs, IPublicTypeListCommand } from '@alilc/lowcode-types'; import { checkPropTypes } from '@alilc/lowcode-utils'; -export interface ICommand extends Omit { - registerCommand(command: IPublicTypeCommand, options?: { - commandScope?: string; - }): void; - - batchExecuteCommand(commands: { name: string; args: IPublicTypeCommandHandlerArgs }[], pluginContext?: IPublicModelPluginContext): void; -} +export interface ICommand extends Command {} export interface ICommandOptions { commandScope?: string; } -export class Command implements ICommand { +export class Command implements Omit { private commands: Map = new Map(); private commandErrors: Function[] = []; diff --git a/packages/editor-core/src/hotkey.ts b/packages/editor-core/src/hotkey.ts index d0dd40cc2..496cec251 100644 --- a/packages/editor-core/src/hotkey.ts +++ b/packages/editor-core/src/hotkey.ts @@ -1,6 +1,6 @@ import { isEqual } from 'lodash'; import { globalContext } from './di'; -import { IPublicTypeHotkeyCallback, IPublicTypeHotkeyCallbackConfig, IPublicTypeHotkeyCallbacks, IPublicApiHotkey } from '@alilc/lowcode-types'; +import { IPublicTypeHotkeyCallback, IPublicTypeHotkeyCallbackConfig, IPublicTypeHotkeyCallbacks, IPublicApiHotkey, IPublicTypeDisposable } from '@alilc/lowcode-types'; interface KeyMap { [key: number]: string; @@ -339,11 +339,10 @@ function fireCallback(callback: IPublicTypeHotkeyCallback, e: KeyboardEvent, com } } -export interface IHotKey extends Omit { - activate(activate: boolean): void; +export interface IHotKey extends Hotkey { } -export class Hotkey implements IHotKey { +export class Hotkey implements Omit { callBacks: IPublicTypeHotkeyCallbacks = {}; private directMap: HotkeyDirectMap = {}; @@ -368,7 +367,7 @@ export class Hotkey implements IHotKey { this.isActivate = activate; } - mount(window: Window) { + mount(window: Window): IPublicTypeDisposable { const { document } = window; const handleKeyEvent = this.handleKeyEvent.bind(this); document.addEventListener('keypress', handleKeyEvent, false); @@ -542,6 +541,8 @@ export class Hotkey implements IHotKey { } private handleKeyEvent(e: KeyboardEvent): void { + console.log(e); + // debugger; if (!this.isActivate) { return; } diff --git a/packages/shell/src/api/hotkey.ts b/packages/shell/src/api/hotkey.ts index 4e65844ce..78a782994 100644 --- a/packages/shell/src/api/hotkey.ts +++ b/packages/shell/src/api/hotkey.ts @@ -50,4 +50,12 @@ export class Hotkey implements IPublicApiHotkey { this[hotkeySymbol].unbind(combos, callback, action); }; } + + /** + * 给指定窗口绑定快捷键 + * @param window 窗口的 window 对象 + */ + mount(window: Window) { + return this[hotkeySymbol].mount(window); + } } \ No newline at end of file diff --git a/packages/types/src/shell/api/hotkey.ts b/packages/types/src/shell/api/hotkey.ts index 894eb0e2f..55bde5d01 100644 --- a/packages/types/src/shell/api/hotkey.ts +++ b/packages/types/src/shell/api/hotkey.ts @@ -22,4 +22,10 @@ export interface IPublicApiHotkey { callback: IPublicTypeHotkeyCallback, action?: string, ): IPublicTypeDisposable; + + /** + * 给指定窗口绑定快捷键 + * @param window 窗口的 window 对象 + */ + mount(window: Window): IPublicTypeDisposable; } From d7dfde5452b2dd3e9e4fcd934708ecd03b0f60ba Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 1 Mar 2024 01:35:48 +0000 Subject: [PATCH 13/25] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index dfe270bac..7c644de33 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.34", + "version": "1.2.35", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 71f9e08cb25cf2bde709a644034e49340b8356fd Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 6 Mar 2024 16:38:19 +0800 Subject: [PATCH 14/25] fix: remove console.log statements, update test, and purge children in NodeChildren class --- packages/designer/jest.config.js | 1 + .../src/designer/setting/setting-field.ts | 54 +----------------- .../src/designer/setting/setting-top-entry.ts | 56 ++++++++----------- .../src/document/node/node-children.ts | 5 ++ packages/designer/src/document/node/node.ts | 2 +- .../setting/setting-top-entry.test.ts | 23 +++++++- packages/editor-core/src/hotkey.ts | 2 - .../src/components/settings/main.ts | 20 ++++--- .../settings/settings-primary-pane.tsx | 19 +++---- 9 files changed, 77 insertions(+), 105 deletions(-) diff --git a/packages/designer/jest.config.js b/packages/designer/jest.config.js index 3684a48ac..0d0f7f8f8 100644 --- a/packages/designer/jest.config.js +++ b/packages/designer/jest.config.js @@ -22,6 +22,7 @@ const jestConfig = { // testMatch: ['**/selection.test.ts'], // testMatch: ['**/plugin/sequencify.test.ts'], // testMatch: ['**/builtin-simulator/utils/parse-metadata.test.ts'], + // testMatch: ['**/setting/setting-top-entry.test.ts'], transformIgnorePatterns: [ `/node_modules/(?!${esModules})/`, ], diff --git a/packages/designer/src/designer/setting/setting-field.ts b/packages/designer/src/designer/setting/setting-field.ts index 1a63fb7a4..39b0b1e30 100644 --- a/packages/designer/src/designer/setting/setting-field.ts +++ b/packages/designer/src/designer/setting/setting-field.ts @@ -1,4 +1,3 @@ -import { ReactNode } from 'react'; import { IPublicTypeTitleContent, IPublicTypeSetterType, @@ -7,18 +6,15 @@ import { IPublicTypeFieldConfig, IPublicTypeCustomView, IPublicTypeDisposable, - IPublicModelSettingField, - IBaseModelSettingField, } from '@alilc/lowcode-types'; import type { IPublicTypeSetValueOptions, } from '@alilc/lowcode-types'; import { Transducer } from './utils'; -import { ISettingPropEntry, SettingPropEntry } from './setting-prop-entry'; +import { SettingPropEntry } from './setting-prop-entry'; import { computed, obx, makeObservable, action, untracked, intl } from '@alilc/lowcode-editor-core'; import { cloneDeep, isCustomView, isDynamicSetter, isJSExpression } from '@alilc/lowcode-utils'; import { ISettingTopEntry } from './setting-top-entry'; -import { IComponentMeta, INode } from '@alilc/lowcode-designer'; function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, config: IPublicTypeFieldConfig) { let cur = parent; @@ -32,53 +28,9 @@ function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, c return path.join('.'); } -export interface ISettingField extends ISettingPropEntry, Omit, 'setValue' | 'key' | 'node'> { - readonly isSettingField: true; +export interface ISettingField extends SettingField {} - readonly isRequired: boolean; - - readonly isGroup: boolean; - - extraProps: IPublicTypeFieldExtraProps; - - get items(): Array; - - get title(): string | ReactNode | undefined; - - get setter(): IPublicTypeSetterType | null; - - get expanded(): boolean; - - get valueState(): number; - - setExpanded(value: boolean): void; - - purge(): void; - - setValue( - val: any, - isHotValue?: boolean, - force?: boolean, - extraOptions?: IPublicTypeSetValueOptions, - ): void; - - clearValue(): void; - - valueChange(options: IPublicTypeSetValueOptions): void; - - createField(config: IPublicTypeFieldConfig): ISettingField; - - onEffect(action: () => void): IPublicTypeDisposable; - - internalToShellField(): IPublicModelSettingField; -} - -export class SettingField extends SettingPropEntry implements ISettingField { +export class SettingField extends SettingPropEntry { readonly isSettingField = true; readonly isRequired: boolean; diff --git a/packages/designer/src/designer/setting/setting-top-entry.ts b/packages/designer/src/designer/setting/setting-top-entry.ts index 85be74b7f..850cd165e 100644 --- a/packages/designer/src/designer/setting/setting-top-entry.ts +++ b/packages/designer/src/designer/setting/setting-top-entry.ts @@ -1,6 +1,6 @@ import { IPublicTypeCustomView, IPublicModelEditor, IPublicModelSettingTopEntry, IPublicApiSetters } from '@alilc/lowcode-types'; import { isCustomView } from '@alilc/lowcode-utils'; -import { computed, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; +import { computed, IEventBus, createModuleEventBus, obx, makeObservable } from '@alilc/lowcode-editor-core'; import { ISettingEntry } from './setting-entry-type'; import { ISettingField, SettingField } from './setting-field'; import { INode } from '../../document'; @@ -14,33 +14,17 @@ function generateSessionId(nodes: INode[]) { .join(','); } -export interface ISettingTopEntry extends ISettingEntry, IPublicModelSettingTopEntry< +export interface ISettingTopEntry extends SettingTopEntry {} + +export class SettingTopEntry implements ISettingEntry, IPublicModelSettingTopEntry< INode, ISettingField > { - readonly top: ISettingTopEntry; - - readonly parent: ISettingTopEntry; - - readonly path: never[]; - - items: Array; - - componentMeta: IComponentMeta | null; - - purge(): void; - - getExtraPropValue(propName: string): void; - - setExtraPropValue(propName: string, value: any): void; -} - -export class SettingTopEntry implements ISettingTopEntry { private emitter: IEventBus = createModuleEventBus('SettingTopEntry'); - private _items: Array = []; + private _items: Array = []; - private _componentMeta: IComponentMeta | null = null; + private _componentMeta: IComponentMeta | null | undefined = null; private _isSame = true; @@ -75,7 +59,7 @@ export class SettingTopEntry implements ISettingTopEntry { } get isLocked(): boolean { - return this.first.isLocked; + return this.first?.isLocked ?? false; } /** @@ -87,7 +71,11 @@ export class SettingTopEntry implements ISettingTopEntry { readonly id: string; - readonly first: INode; + @computed get first(): INode | null { + return this._first; + } + + @obx.ref _first: INode | null; readonly designer: IDesigner | undefined; @@ -96,12 +84,14 @@ export class SettingTopEntry implements ISettingTopEntry { disposeFunctions: any[] = []; constructor(readonly editor: IPublicModelEditor, readonly nodes: INode[]) { + makeObservable(this); + if (!Array.isArray(nodes) || nodes.length < 1) { throw new ReferenceError('nodes should not be empty'); } this.id = generateSessionId(nodes); - this.first = nodes[0]; - this.designer = this.first.document?.designer; + this._first = nodes[0]; + this.designer = this._first.document?.designer; this.setters = editor.get('setters') as IPublicApiSetters; // setups @@ -116,7 +106,7 @@ export class SettingTopEntry implements ISettingTopEntry { private setupComponentMeta() { // todo: enhance compile a temp configure.compiled const { first } = this; - const meta = first.componentMeta; + const meta = first?.componentMeta; const l = this.nodes.length; let theSame = true; for (let i = 1; i < l; i++) { @@ -160,7 +150,7 @@ export class SettingTopEntry implements ISettingTopEntry { /** * 获取当前属性值 */ - @computed getValue(): any { + getValue(): any { return this.first?.propsData; } @@ -202,14 +192,14 @@ export class SettingTopEntry implements ISettingTopEntry { * 获取子级属性值 */ getPropValue(propName: string | number): any { - return this.first.getProp(propName.toString(), true)?.getValue(); + return this.first?.getProp(propName.toString(), true)?.getValue(); } /** * 获取顶层附属属性值 */ getExtraPropValue(propName: string) { - return this.first.getExtraProp(propName, false)?.getValue(); + return this.first?.getExtraProp(propName, false)?.getValue(); } /** @@ -244,8 +234,9 @@ export class SettingTopEntry implements ISettingTopEntry { this.disposeItems(); this._settingFieldMap = {}; this.emitter.removeAllListeners(); - this.disposeFunctions.forEach(f => f()); + this.disposeFunctions.forEach(f => f?.()); this.disposeFunctions = []; + this._first = null; } getProp(propName: string | number) { @@ -274,7 +265,7 @@ export class SettingTopEntry implements ISettingTopEntry { } getPage() { - return this.first.document; + return this.first?.document; } /** @@ -292,6 +283,7 @@ export class SettingTopEntry implements ISettingTopEntry { interface Purgeable { purge(): void; } + function isPurgeable(obj: any): obj is Purgeable { return obj && obj.purge; } diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index b7f03d9fe..d374daa8e 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -91,6 +91,7 @@ export class NodeChildren implements Omit, node.import(item); } else { node = this.owner.document?.createNode(item); + child?.purge(); } if (node) { @@ -98,6 +99,10 @@ export class NodeChildren implements Omit, } } + for (let i = data.length; i < originChildren.length; i++) { + originChildren[i].purge(); + } + this.children = children; this.internalInitParent(); if (!shallowEqual(children, originChildren)) { diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 0b698831e..04c72a8fd 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -987,7 +987,7 @@ export class Node this.autoruns?.forEach((dispose) => dispose()); this.props.purge(); this.settingEntry?.purge(); - // this.document.destroyNode(this); + this.children?.purge(); } internalPurgeStart() { diff --git a/packages/designer/tests/designer/setting/setting-top-entry.test.ts b/packages/designer/tests/designer/setting/setting-top-entry.test.ts index 23a42c2af..e5234690c 100644 --- a/packages/designer/tests/designer/setting/setting-top-entry.test.ts +++ b/packages/designer/tests/designer/setting/setting-top-entry.test.ts @@ -1,8 +1,9 @@ import '../../fixtures/window'; -import { Editor, Setters } from '@alilc/lowcode-editor-core'; +import { Editor, Setters, reaction } from '@alilc/lowcode-editor-core'; import { Node } from '../../../src/document/node/node'; import { Designer } from '../../../src/designer/designer'; import settingSchema from '../../fixtures/schema/setting'; +import { SettingTopEntry } from '../../../src/designer/setting/setting-top-entry'; import divMeta from '../../fixtures/component-metadata/div'; import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; @@ -109,6 +110,26 @@ describe('setting-top-entry 测试', () => { expect(settingEntry.items).toHaveLength(0); }); + it('should notify when _first is set to null', (done) => { + // 创建一个简单的INode数组用于初始化SettingTopEntry实例 + const nodes = [{ id: '1', propsData: {} }, { id: '2', propsData: {} }]; + const entry = new SettingTopEntry(editor as any, nodes as any); + + // 使用MobX的reaction来观察_first属性的变化 + const dispose = reaction( + () => entry.first, + (first) => { + if (first === null) { + dispose(); // 清理reaction监听 + done(); // 结束测试 + } + } + ); + + // 执行purge方法,期望_first被设置为null,触发reaction回调 + entry.purge(); + }); + it('vision 兼容测试', () => { designer.createComponentMeta(divMeta); designer.project.open(settingSchema); diff --git a/packages/editor-core/src/hotkey.ts b/packages/editor-core/src/hotkey.ts index 496cec251..e3482ab4d 100644 --- a/packages/editor-core/src/hotkey.ts +++ b/packages/editor-core/src/hotkey.ts @@ -541,8 +541,6 @@ export class Hotkey implements Omit { } private handleKeyEvent(e: KeyboardEvent): void { - console.log(e); - // debugger; if (!this.isActivate) { return; } diff --git a/packages/editor-skeleton/src/components/settings/main.ts b/packages/editor-skeleton/src/components/settings/main.ts index 6cc672c90..3cca2c861 100644 --- a/packages/editor-skeleton/src/components/settings/main.ts +++ b/packages/editor-skeleton/src/components/settings/main.ts @@ -1,7 +1,7 @@ -import { Node, Designer, Selection, SettingTopEntry } from '@alilc/lowcode-designer'; +import { INode, IDesigner, Selection, SettingTopEntry } from '@alilc/lowcode-designer'; import { Editor, obx, computed, makeObservable, action, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; -function generateSessionId(nodes: Node[]) { +function generateSessionId(nodes: INode[]) { return nodes .map((node) => node.id) .sort() @@ -29,7 +29,11 @@ export class SettingsMain { private disposeListener: () => void; - private designer?: Designer; + private _designer?: IDesigner; + + get designer(): IDesigner | undefined { + return this._designer; + } constructor(readonly editor: Editor) { makeObservable(this); @@ -49,12 +53,12 @@ export class SettingsMain { this.editor.removeListener('designer.selection.change', setupSelection); }; const designer = await this.editor.onceGot('designer'); - this.designer = designer; + this._designer = designer; setupSelection(designer.currentSelection); } @action - private setup(nodes: Node[]) { + private setup(nodes: INode[]) { // check nodes change const sessionId = generateSessionId(nodes); if (sessionId === this._sessionId) { @@ -66,15 +70,15 @@ export class SettingsMain { return; } - if (!this.designer) { - this.designer = nodes[0].document.designer; + if (!this._designer) { + this._designer = nodes[0].document.designer; } // 当节点只有一个时,复用 node 上挂载的 settingEntry,不会产生平行的两个实例,这样在整个系统中对 // 某个节点操作的 SettingTopEntry 只有一个实例,后续的 getProp() 也会拿到相同的 SettingField 实例 if (nodes.length === 1) { this._settings = nodes[0].settingEntry; } else { - this._settings = this.designer.createSettingEntry(nodes); + this._settings = this._designer.createSettingEntry(nodes); } } diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index 747a2ea1d..b2eb8c7a8 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -1,14 +1,14 @@ import React, { Component } from 'react'; import { Tab, Breadcrumb } from '@alifd/next'; import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@alilc/lowcode-editor-core'; -import { Node, SettingField, isSettingField, INode } from '@alilc/lowcode-designer'; +import { ISettingField, INode } from '@alilc/lowcode-designer'; import classNames from 'classnames'; import { SettingsMain } from './main'; import { SettingsPane } from './settings-pane'; import { StageBox } from '../stage-box'; import { SkeletonContext } from '../../context'; import { intl } from '../../locale'; -import { createIcon } from '@alilc/lowcode-utils'; +import { createIcon, isSettingField } from '@alilc/lowcode-utils'; interface ISettingsPrimaryPaneProps { engineEditor: Editor; @@ -53,8 +53,7 @@ export class SettingsPrimaryPane extends Component { + const tabs = (items as ISettingField[]).map((field) => { if (this._activeKey === field.name) { matched = true; } @@ -235,7 +233,7 @@ export class SettingsPrimaryPane extends Component ); }); - const activeKey = matched ? this._activeKey : (items[0] as SettingField).name; + const activeKey = matched ? this._activeKey : (items[0] as ISettingField).name; const className = classNames('lc-settings-main', { 'lc-settings-hide-tabs': @@ -261,9 +259,10 @@ export class SettingsPrimaryPane extends Component Date: Wed, 6 Mar 2024 16:50:20 +0800 Subject: [PATCH 15/25] fix: refactor splice method to remove and purge nodes*** --- packages/designer/src/document/node/node-children.ts | 10 ++++++++-- packages/shell/src/model/node-children.ts | 5 +++-- packages/types/src/shell/model/node-children.ts | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index d374daa8e..2ce2d07de 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -307,10 +307,16 @@ export class NodeChildren implements Omit, * */ splice(start: number, deleteCount: number, node?: INode): INode[] { + let removedNode; if (node) { - return this.children.splice(start, deleteCount, node); + removedNode = this.children.splice(start, deleteCount, node); + } else { + removedNode = this.children.splice(start, deleteCount); } - return this.children.splice(start, deleteCount); + + removedNode.forEach(d => d?.purge()); + + return removedNode; } /** diff --git a/packages/shell/src/model/node-children.ts b/packages/shell/src/model/node-children.ts index b6d52e86f..c4e336aa0 100644 --- a/packages/shell/src/model/node-children.ts +++ b/packages/shell/src/model/node-children.ts @@ -97,8 +97,9 @@ export class NodeChildren implements IPublicModelNodeChildren { * @param deleteCount * @param node */ - splice(start: number, deleteCount: number, node?: IPublicModelNode): any { - this[nodeChildrenSymbol].splice(start, deleteCount, (node as any)?.[nodeSymbol]); + splice(start: number, deleteCount: number, node?: IPublicModelNode): IPublicModelNode[] { + const removedNode = this[nodeChildrenSymbol].splice(start, deleteCount, (node as any)?.[nodeSymbol]); + return removedNode.map((item: InnerNode) => ShellNode.create(item)!); } /** diff --git a/packages/types/src/shell/model/node-children.ts b/packages/types/src/shell/model/node-children.ts index f2be13250..207db5672 100644 --- a/packages/types/src/shell/model/node-children.ts +++ b/packages/types/src/shell/model/node-children.ts @@ -78,7 +78,7 @@ export interface IPublicModelNodeChildren< * @param deleteCount * @param node */ - splice(start: number, deleteCount: number, node?: Node): any; + splice(start: number, deleteCount: number, node?: Node): Node[]; /** * 返回指定下标的节点 From d2138d7edb4469eba2daf612dbca426f94370d66 Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 6 Mar 2024 17:20:51 +0800 Subject: [PATCH 16/25] fix: fix node parent assignment and update settings check --- packages/designer/src/document/node/node-children.ts | 1 + packages/designer/src/document/node/node.ts | 3 ++- .../designer/tests/document/node/node-children.test.ts | 10 ++++++++++ .../src/components/settings/settings-primary-pane.tsx | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 2ce2d07de..48503ba6c 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -310,6 +310,7 @@ export class NodeChildren implements Omit, let removedNode; if (node) { removedNode = this.children.splice(start, deleteCount, node); + node.internalSetParent(this.owner); } else { removedNode = this.children.splice(start, deleteCount); } diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 04c72a8fd..4155dedb7 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -197,7 +197,7 @@ export class Node isInited = false; - _settingEntry: ISettingTopEntry; + _settingEntry?: ISettingTopEntry; get settingEntry(): ISettingTopEntry { if (this._settingEntry) return this._settingEntry; @@ -988,6 +988,7 @@ export class Node this.props.purge(); this.settingEntry?.purge(); this.children?.purge(); + this._settingEntry = undefined; } internalPurgeStart() { diff --git a/packages/designer/tests/document/node/node-children.test.ts b/packages/designer/tests/document/node/node-children.test.ts index 1aa7e3ccb..b5b2744ff 100644 --- a/packages/designer/tests/document/node/node-children.test.ts +++ b/packages/designer/tests/document/node/node-children.test.ts @@ -111,6 +111,16 @@ describe('NodeChildren 方法测试', () => { expect(children.length).toBe(2); }); + it('split add node and update node parent', () => { + const firstBtn = doc.getNode('node_k1ow3cbn')!; + const { children } = firstBtn.parent!; + const node = doc.createNode({ componentName: 'Button' }); + + children.splice(0, 0, node); + + expect(node.parent).toBe(firstBtn.parent); + }) + it('map', () => { const firstBtn = doc.getNode('node_k1ow3cbn')!; const { children } = firstBtn.parent!; diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index b2eb8c7a8..3aaa9435a 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -134,7 +134,7 @@ export class SettingsPrimaryPane extends Component From dc98670c378d36d6671ccd9c2b97fd03dcdc758f Mon Sep 17 00:00:00 2001 From: liujuping Date: Thu, 7 Mar 2024 11:09:11 +0800 Subject: [PATCH 17/25] fix: update import statements to use type imports --- packages/designer/src/designer/dragon.ts | 2 +- .../src/designer/setting/setting-entry-type.ts | 8 ++++---- .../designer/src/designer/setting/setting-field.ts | 6 +++--- .../src/designer/setting/setting-prop-entry.ts | 12 ++++++------ .../src/designer/setting/setting-top-entry.ts | 9 +++++---- packages/designer/src/document/document-model.ts | 6 +++--- packages/designer/src/document/document-view.tsx | 2 +- packages/designer/src/document/history.ts | 2 +- packages/designer/src/document/node/node-children.ts | 10 +++++----- packages/designer/src/document/node/node.ts | 6 +++--- .../src/components/settings/settings-pane.tsx | 4 ++-- .../components/settings/settings-primary-pane.tsx | 2 +- 12 files changed, 35 insertions(+), 34 deletions(-) diff --git a/packages/designer/src/designer/dragon.ts b/packages/designer/src/designer/dragon.ts index 5c4d0648d..f96b667b1 100644 --- a/packages/designer/src/designer/dragon.ts +++ b/packages/designer/src/designer/dragon.ts @@ -13,7 +13,7 @@ import { import { setNativeSelection, cursor } from '@alilc/lowcode-utils'; import { INode, Node } from '../document'; import { ISimulatorHost, isSimulatorHost } from '../simulator'; -import { IDesigner } from './designer'; +import type { IDesigner } from './designer'; import { makeEventsHandler } from '../utils/misc'; export interface ILocateEvent extends IPublicModelLocateEvent { diff --git a/packages/designer/src/designer/setting/setting-entry-type.ts b/packages/designer/src/designer/setting/setting-entry-type.ts index 1aee9016e..5cbe232ab 100644 --- a/packages/designer/src/designer/setting/setting-entry-type.ts +++ b/packages/designer/src/designer/setting/setting-entry-type.ts @@ -1,7 +1,7 @@ -import { IPublicApiSetters, IPublicModelEditor } from '@alilc/lowcode-types'; -import { IDesigner } from '../designer'; -import { INode } from '../../document'; -import { ISettingField } from './setting-field'; +import type { IPublicApiSetters, IPublicModelEditor } from '@alilc/lowcode-types'; +import type { IDesigner } from '../designer'; +import type { INode } from '../../document'; +import type { ISettingField } from './setting-field'; export interface ISettingEntry { readonly designer: IDesigner | undefined; diff --git a/packages/designer/src/designer/setting/setting-field.ts b/packages/designer/src/designer/setting/setting-field.ts index 39b0b1e30..87415dd98 100644 --- a/packages/designer/src/designer/setting/setting-field.ts +++ b/packages/designer/src/designer/setting/setting-field.ts @@ -14,7 +14,7 @@ import { Transducer } from './utils'; import { SettingPropEntry } from './setting-prop-entry'; import { computed, obx, makeObservable, action, untracked, intl } from '@alilc/lowcode-editor-core'; import { cloneDeep, isCustomView, isDynamicSetter, isJSExpression } from '@alilc/lowcode-utils'; -import { ISettingTopEntry } from './setting-top-entry'; +import type { ISettingTopEntry } from './setting-top-entry'; function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, config: IPublicTypeFieldConfig) { let cur = parent; @@ -28,8 +28,6 @@ function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, c return path.join('.'); } -export interface ISettingField extends SettingField {} - export class SettingField extends SettingPropEntry { readonly isSettingField = true; @@ -273,3 +271,5 @@ export class SettingField extends SettingPropEntry { export function isSettingField(obj: any): obj is ISettingField { return obj && obj.isSettingField; } + +export type ISettingField = typeof SettingField; diff --git a/packages/designer/src/designer/setting/setting-prop-entry.ts b/packages/designer/src/designer/setting/setting-prop-entry.ts index d6904f0c8..6cce4cddc 100644 --- a/packages/designer/src/designer/setting/setting-prop-entry.ts +++ b/packages/designer/src/designer/setting/setting-prop-entry.ts @@ -1,12 +1,12 @@ import { obx, computed, makeObservable, runInAction, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { GlobalEvent, IPublicApiSetters, IPublicModelEditor, IPublicModelSettingField, IPublicTypeFieldExtraProps, IPublicTypeSetValueOptions } from '@alilc/lowcode-types'; -import { uniqueId, isJSExpression } from '@alilc/lowcode-utils'; -import { ISettingEntry } from './setting-entry-type'; -import { INode } from '../../document'; +import { uniqueId, isJSExpression, isSettingField } from '@alilc/lowcode-utils'; +import type { ISettingEntry } from './setting-entry-type'; +import type { INode } from '../../document'; import type { IComponentMeta } from '../../component-meta'; -import { IDesigner } from '../designer'; -import { ISettingTopEntry } from './setting-top-entry'; -import { ISettingField, isSettingField } from './setting-field'; +import type { IDesigner } from '../designer'; +import type { ISettingTopEntry } from './setting-top-entry'; +import type { ISettingField } from './setting-field'; export interface ISettingPropEntry extends ISettingEntry { readonly isGroup: boolean; diff --git a/packages/designer/src/designer/setting/setting-top-entry.ts b/packages/designer/src/designer/setting/setting-top-entry.ts index 850cd165e..3a1739788 100644 --- a/packages/designer/src/designer/setting/setting-top-entry.ts +++ b/packages/designer/src/designer/setting/setting-top-entry.ts @@ -1,11 +1,12 @@ import { IPublicTypeCustomView, IPublicModelEditor, IPublicModelSettingTopEntry, IPublicApiSetters } from '@alilc/lowcode-types'; import { isCustomView } from '@alilc/lowcode-utils'; import { computed, IEventBus, createModuleEventBus, obx, makeObservable } from '@alilc/lowcode-editor-core'; -import { ISettingEntry } from './setting-entry-type'; -import { ISettingField, SettingField } from './setting-field'; -import { INode } from '../../document'; +import { SettingField } from './setting-field'; +import type { ISettingEntry } from './setting-entry-type'; +import type { ISettingField } from './setting-field'; +import type { INode } from '../../document'; import type { IComponentMeta } from '../../component-meta'; -import { IDesigner } from '../designer'; +import type { IDesigner } from '../designer'; function generateSessionId(nodes: INode[]) { return nodes diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 2938395a9..dd9258fc1 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -37,10 +37,10 @@ import { isDragNodeDataObject, isNode, } from '@alilc/lowcode-utils'; -import { IProject } from '../project'; -import { ISimulatorHost } from '../simulator'; +import type { IProject } from '../project'; +import type { ISimulatorHost } from '../simulator'; import type { IComponentMeta } from '../component-meta'; -import { IDesigner, IHistory } from '../designer'; +import type { IDesigner, IHistory } from '../designer'; import { insertChildren, insertChild, IRootNode } from './node/node'; import type { INode } from './node/node'; import { Selection, ISelection } from './selection'; diff --git a/packages/designer/src/document/document-view.tsx b/packages/designer/src/document/document-view.tsx index c6dbe76a8..ec588e223 100644 --- a/packages/designer/src/document/document-view.tsx +++ b/packages/designer/src/document/document-view.tsx @@ -1,7 +1,7 @@ import { Component } from 'react'; import classNames from 'classnames'; import { observer } from '@alilc/lowcode-editor-core'; -import { DocumentModel, IDocumentModel } from './document-model'; +import type { IDocumentModel } from './document-model'; import { BuiltinSimulatorHostView } from '../builtin-simulator'; @observer diff --git a/packages/designer/src/document/history.ts b/packages/designer/src/document/history.ts index ca288c03a..10695e235 100644 --- a/packages/designer/src/document/history.ts +++ b/packages/designer/src/document/history.ts @@ -1,7 +1,7 @@ import { reaction, untracked, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { IPublicTypeNodeSchema, IPublicModelHistory, IPublicTypeDisposable } from '@alilc/lowcode-types'; import { Logger } from '@alilc/lowcode-utils'; -import { IDocumentModel } from '../designer'; +import type { IDocumentModel } from '../designer'; const logger = new Logger({ level: 'warn', bizName: 'history' }); diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 48503ba6c..0f0c4a459 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -1,5 +1,5 @@ import { obx, computed, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; -import { Node, INode } from './node'; +import type { INode } from './node'; import { IPublicTypeNodeData, IPublicModelNodeChildren, IPublicEnumTransformStage, IPublicTypeDisposable } from '@alilc/lowcode-types'; import { shallowEqual, compatStage, isNodeSchema } from '@alilc/lowcode-utils'; import { foreachReverse } from '../../utils/tree'; @@ -7,7 +7,7 @@ import { NodeRemoveOptions } from '../../types'; export interface IOnChangeOptions { type: string; - node: Node; + node: INode; } export class NodeChildren implements Omit, @@ -80,7 +80,7 @@ export class NodeChildren implements Omit, const originChildren = this.children.slice(); this.children.forEach((child) => child.internalSetParent(null)); - const children = new Array(data.length); + const children = new Array(data.length); for (let i = 0, l = data.length; i < l; i++) { const child = originChildren[i]; const item = data[i]; @@ -169,14 +169,14 @@ export class NodeChildren implements Omit, if (node.isParentalNode) { foreachReverse( node.children!, - (subNode: Node) => { + (subNode: INode) => { subNode.remove(useMutator, purge, options); }, (iterable, idx) => (iterable as NodeChildren).get(idx), ); foreachReverse( node.slots, - (slotNode: Node) => { + (slotNode: INode) => { slotNode.remove(useMutator, purge); }, (iterable, idx) => (iterable as [])[idx], diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 4155dedb7..5a43fc15c 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -18,11 +18,11 @@ import { IBaseModelNode, } from '@alilc/lowcode-types'; import { compatStage, isDOMText, isJSExpression, isNode, isNodeSchema } from '@alilc/lowcode-utils'; -import { ISettingTopEntry } from '@alilc/lowcode-designer'; +import type { ISettingTopEntry } from '@alilc/lowcode-designer'; import { Props, getConvertedExtraKey, IProps } from './props/props'; import type { IDocumentModel } from '../document-model'; import { NodeChildren, INodeChildren } from './node-children'; -import { IProp, Prop } from './props/prop'; +import type { IProp } from './props/prop'; import type { IComponentMeta } from '../../component-meta'; import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group'; import type { IExclusiveGroup } from './exclusive-group'; @@ -495,7 +495,7 @@ export class Node } } - internalSetSlotFor(slotFor: Prop | null | undefined) { + internalSetSlotFor(slotFor: IProp | null | undefined) { this._slotFor = slotFor; } diff --git a/packages/editor-skeleton/src/components/settings/settings-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-pane.tsx index 1561bf8bb..4bb23d292 100644 --- a/packages/editor-skeleton/src/components/settings/settings-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-pane.tsx @@ -1,9 +1,9 @@ import { Component, MouseEvent, Fragment, ReactNode } from 'react'; import { shallowIntl, observer, obx, engineConfig, runInAction } from '@alilc/lowcode-editor-core'; -import { createContent, isJSSlot, isSetterConfig, shouldUseVariableSetter } from '@alilc/lowcode-utils'; +import { createContent, isJSSlot, isSetterConfig, shouldUseVariableSetter, isSettingField } from '@alilc/lowcode-utils'; import { Skeleton, Stage } from '@alilc/lowcode-editor-skeleton'; import { IPublicApiSetters, IPublicTypeCustomView, IPublicTypeDynamicProps } from '@alilc/lowcode-types'; -import { ISettingEntry, IComponentMeta, ISettingField, isSettingField, ISettingTopEntry } from '@alilc/lowcode-designer'; +import type { ISettingEntry, IComponentMeta, ISettingField, ISettingTopEntry } from '@alilc/lowcode-designer'; import { createField } from '../field'; import PopupService, { PopupPipe } from '../popup'; import { SkeletonContext } from '../../context'; diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index 3aaa9435a..5231d9f20 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { Tab, Breadcrumb } from '@alifd/next'; import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@alilc/lowcode-editor-core'; -import { ISettingField, INode } from '@alilc/lowcode-designer'; +import type { ISettingField, INode } from '@alilc/lowcode-designer'; import classNames from 'classnames'; import { SettingsMain } from './main'; import { SettingsPane } from './settings-pane'; From db2f2d6aa201d5d3548f76bbc7c5bbcce681a531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=8F=8A=E8=90=8D=28=E7=B5=AE=E9=BB=8E=29?= Date: Thu, 28 Mar 2024 11:13:08 +0800 Subject: [PATCH 18/25] Update skeleton.md --- docs/docs/api/skeleton.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index 396fad9e9..3ae0e3524 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -11,8 +11,9 @@ sidebar_position: 10 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01eVA0U41xYRP3e5zo0_!!6000000006455-2-tps-1780-996.png) -页面上可以扩展的区域共 5 个,具体如下: -![image.png](https://img.alicdn.com/imgextra/i3/O1CN014d2AcS1D5c9TshEiQ_!!6000000000165-2-tps-1892-974.png) +页面上可以扩展的区域共 6 个,具体如下: +![image](https://github.com/alibaba/lowcode-engine/assets/11935995/ba4641dd-d346-4ef7-8b71-8ca211e6eaf4) + ### 基本概念 #### 扩展区域位置 (area) ##### topArea @@ -41,6 +42,11 @@ sidebar_position: 10 ##### rightArea 右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。 + +##### bottomArea + +底部扩展区域。 + ##### toolbar 跟 topArea 类似,按需放置面板插件~ From 816b58c8d0412ce436e93d5e483e3e6be58c1696 Mon Sep 17 00:00:00 2001 From: AndyJin Date: Mon, 25 Mar 2024 14:35:13 +0800 Subject: [PATCH 19/25] docs(readme): update participation url --- packages/engine/README-zh_CN.md | 3 +-- packages/engine/README.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index 5442aa58b..e6717d689 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -160,9 +160,8 @@ lowcode-engine 启动后,提供了几个 umd 文件,可以结合 [lowcode-de ## 🤝 参与共建 请先阅读: -1. [如何配置引擎调试环境?](https://lowcode-engine.cn/site/docs/participate/prepare) +1. [如何配置引擎调试环境?](https://lowcode-engine.cn/site/docs/participate) 2. [关于引擎的研发协作流程](https://lowcode-engine.cn/site/docs/participate/flow) -3. [引擎的工程化配置](https://lowcode-engine.cn/site/docs/participate/config) > 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。(此段参考 [antd](https://github.com/ant-design/ant-design)) diff --git a/packages/engine/README.md b/packages/engine/README.md index ae4e7fd43..82d855236 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -160,9 +160,8 @@ After lowcode-engine is started, several umd files are provided, which can be de ## 🤝 Participation Please read first: -1. [How to configure the engine debugging environment? ](https://lowcode-engine.cn/site/docs/participate/prepare) +1. [How to configure the engine debugging environment? ](https://lowcode-engine.cn/site/docs/participate) 2. [About the R&D collaboration process of the engine](https://lowcode-engine.cn/site/docs/participate/flow) -3. [Engineering Configuration of Engine](https://lowcode-engine.cn/site/docs/participate/config) > Strongly recommend reading ["The Wisdom of Asking Questions"](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way), ["How to Ask Questions to the Open Source Community"](https: //github.com/seajs/seajs/issues/545) and [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html), [ "How to Submit Unanswerable Questions to Open Source Projects"](https://zhuanlan.zhihu.com/p/25795393), better questions are easier to get help. (This paragraph refers to [antd](https://github.com/ant-design/ant-design)) From c1dce149794462599de7d54ebf686da815dcb259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=8F=8A=E8=90=8D=28=E7=B5=AE=E9=BB=8E=29?= Date: Thu, 28 Mar 2024 15:01:36 +0800 Subject: [PATCH 20/25] Update npms.md --- docs/docs/guide/appendix/npms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guide/appendix/npms.md b/docs/docs/guide/appendix/npms.md index b0292c273..257e6b126 100644 --- a/docs/docs/guide/appendix/npms.md +++ b/docs/docs/guide/appendix/npms.md @@ -43,5 +43,5 @@ sidebar_position: 3 | @alilc/lowcode-materials | [https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) | packages/fusion-lowcode-materials | | @alilc/antd-lowcode-materials | [https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) | packages/antd-lowcode-materials | | @alifd/layout(原 @alifd/pro-layout 升级后的版本) | [https://github.com/alibaba-fusion/layout](https://github.com/alibaba-fusion/layout) | | -| | | | +| @alilc/lowcode-engine-docs | [https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | docs | | | | | From 3a9ebd39838adf00ab83dda7a356b104a01a97b3 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 28 Mar 2024 07:02:42 +0000 Subject: [PATCH 21/25] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 7c644de33..f6b649506 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.35", + "version": "1.2.36", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 395e60079a7800b2d39343e1e016de52b57f3be2 Mon Sep 17 00:00:00 2001 From: woshilaoge <785431601@qq.com> Date: Wed, 15 May 2024 17:01:52 +0800 Subject: [PATCH 22/25] =?UTF-8?q?fix:=20next=20=E7=BB=84=E4=BB=B6=E6=9C=80?= =?UTF-8?q?=E6=96=B0=E7=89=88=E6=9C=AC=20TS=20=E5=A3=B0=E6=98=8E=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=AF=BC=E5=87=BA=E9=83=A8=E5=88=86=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=EF=BC=8C=E6=9A=82=E6=97=B6=E8=B0=83=E6=95=B4=E5=A3=B0=E6=98=8E?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=BF=9B=E8=A1=8C=E6=AD=A3=E5=B8=B8=E7=BC=96?= =?UTF-8?q?=E8=AF=91=EF=BC=8C=E5=90=8E=E7=BB=AD=E7=BB=84=E4=BB=B6=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=E5=90=8E=E5=8F=AF=E5=86=8D=E9=85=8D=E5=90=88=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/shell/src/api/commonUI.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/shell/src/api/commonUI.tsx b/packages/shell/src/api/commonUI.tsx index 69dd104b2..753c24cbe 100644 --- a/packages/shell/src/api/commonUI.tsx +++ b/packages/shell/src/api/commonUI.tsx @@ -19,7 +19,7 @@ export class CommonUI implements IPublicApiCommonUI { Card = Card; Checkbox = Checkbox; DatePicker = DatePicker; - Dialog = Dialog; + Dialog = Dialog as any; Dropdown = Dropdown; Form = Form; Icon = Icon; @@ -31,15 +31,15 @@ export class CommonUI implements IPublicApiCommonUI { Radio = Radio; Search = Search; Select = Select; - SplitButton = SplitButton; + SplitButton = SplitButton as any; Step = Step; - Switch = Switch; + Switch = Switch as any; Tab = Tab; Table = Table; Tree = Tree; TreeSelect = TreeSelect; Upload = Upload; - Divider = Divider; + Divider = Divider as any; ContextMenu: ((props: { menus: IPublicTypeContextMenuAction[]; From 418a0bdaa231f0e8ad805554a5f2fd9641950155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=BE=9C?= <1ncounter.100@gmail.com> Date: Thu, 16 May 2024 15:25:19 +0800 Subject: [PATCH 23/25] Revert "fix: keep `this` in parse expression function" --- packages/renderer-core/src/utils/common.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index a9c5ffb8f..0462d358a 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -221,19 +221,22 @@ function parseExpression(a: any, b?: any, c = false) { thisRequired = c; } try { + const contextArr = ['"use strict";', 'var __self = arguments[0];']; + contextArr.push('return '); let tarStr: string; tarStr = (str.value || '').trim(); - let code = `"use strict"; function __wrapper(){ return ${tarStr}} return __wrapper.call(arguments[0])`; + // NOTE: use __self replace 'this' in the original function str + // may be wrong in extreme case which contains '__self' already + tarStr = tarStr.replace(/this(\W|$)/g, (_a: any, b: any) => `__self${b}`); + tarStr = contextArr.join('\n') + tarStr; // 默认调用顶层窗口的parseObj, 保障new Function的window对象是顶层的window对象 if (inSameDomain() && (window.parent as any).__newFunc) { - return (window.parent as any).__newFunc(code)(self); - } - if (!thisRequired) { - code = `with($scope){${code}}`; + return (window.parent as any).__newFunc(tarStr)(self); } + const code = `with(${thisRequired ? '{}' : '$scope || {}'}) { ${tarStr} }`; return new Function('$scope', code)(self); } catch (err) { logger.error(`${logScope || ''} parseExpression.error`, err, str, self?.__self ?? self); From 8d44c588454f5d691da55b476c13896b3c306db6 Mon Sep 17 00:00:00 2001 From: liukairui Date: Fri, 14 Jun 2024 03:21:37 +0800 Subject: [PATCH 24/25] fix: update outline tree when node loop property changes --- .../src/controllers/tree-node.ts | 18 ++++++++++++++++++ .../src/controllers/tree.ts | 5 +++-- .../src/views/tree-title.tsx | 9 ++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/plugin-outline-pane/src/controllers/tree-node.ts b/packages/plugin-outline-pane/src/controllers/tree-node.ts index 34d06fee0..1526e2a59 100644 --- a/packages/plugin-outline-pane/src/controllers/tree-node.ts +++ b/packages/plugin-outline-pane/src/controllers/tree-node.ts @@ -37,6 +37,8 @@ enum EVENT_NAMES { expandableChanged = 'expandableChanged', conditionChanged = 'conditionChanged', + + loopChanged = 'loopChanged', } export default class TreeNode { @@ -160,6 +162,10 @@ export default class TreeNode { return this.node.hasCondition() && !this.node.conditionGroup; } + get loop(): boolean { + return this.node.hasLoop(); + } + get children(): TreeNode[] | null { return this.node.children?.map((node) => this.tree.getTreeNode(node)) || null; } @@ -222,6 +228,14 @@ export default class TreeNode { }; } + onLoopChanged(fn: (treeNode: TreeNode) => void): IPublicTypeDisposable { + this.event.on(EVENT_NAMES.loopChanged, fn); + + return () => { + this.event.off(EVENT_NAMES.loopChanged, fn); + }; + } + onExpandableChanged(fn: (expandable: boolean) => void): IPublicTypeDisposable { this.event.on(EVENT_NAMES.expandableChanged, fn); return () => { @@ -244,6 +258,10 @@ export default class TreeNode { this.event.emit(EVENT_NAMES.conditionChanged, this.condition); } + notifyLoopChanged(): void { + this.event.emit(EVENT_NAMES.loopChanged, this.loop); + } + setHidden(flag: boolean) { if (this.node.conditionGroup) { return; diff --git a/packages/plugin-outline-pane/src/controllers/tree.ts b/packages/plugin-outline-pane/src/controllers/tree.ts index ca5a43c55..7e75307a0 100644 --- a/packages/plugin-outline-pane/src/controllers/tree.ts +++ b/packages/plugin-outline-pane/src/controllers/tree.ts @@ -36,12 +36,13 @@ export class Tree { doc?.onChangeNodeProp((info: IPublicTypePropChangeOptions) => { const { node, key } = info; + const treeNode = this.getTreeNodeById(node.id); if (key === '___title___') { - const treeNode = this.getTreeNodeById(node.id); treeNode?.notifyTitleLabelChanged(); } else if (key === '___condition___') { - const treeNode = this.getTreeNodeById(node.id); treeNode?.notifyConditionChanged(); + } else if (key === '___loop___') { + treeNode?.notifyLoopChanged(); } }); diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index f822bd644..d7e29dbe8 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -28,6 +28,7 @@ export default class TreeTitle extends PureComponent<{ editing: boolean; title: string; condition?: boolean; + loop?: boolean; visible?: boolean; filterWorking: boolean; keywords: string; @@ -89,6 +90,7 @@ export default class TreeTitle extends PureComponent<{ editing: false, title: treeNode.titleLabel, condition: treeNode.condition, + loop: treeNode.loop, visible: !treeNode.hidden, }); treeNode.onTitleLabelChanged(() => { @@ -101,6 +103,11 @@ export default class TreeTitle extends PureComponent<{ condition: treeNode.condition, }); }); + treeNode.onLoopChanged(() => { + this.setState({ + loop: treeNode.loop, + }); + }); treeNode.onHiddenChanged((hidden: boolean) => { this.setState({ visible: !hidden, @@ -207,7 +214,7 @@ export default class TreeTitle extends PureComponent<{ {intlNode('Slot for {prop}', { prop: node.slotFor.key })} )} - {node.hasLoop() && ( + {this.state.loop && ( {/* todo: click todo something */} From a8c50ef9cd2a24349641ef71b0b0528d1df1406a Mon Sep 17 00:00:00 2001 From: liukairui Date: Fri, 14 Jun 2024 03:31:19 +0800 Subject: [PATCH 25/25] test: update renderer-core snapshots --- .../renderer/__snapshots__/renderer.test.tsx.snap | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap index 79c5f0f08..4a55c6cd4 100644 --- a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap +++ b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap @@ -259,10 +259,11 @@ exports[`Base Render renderComp 1`] = ` "hidden": undefined, } } + aria-expanded="false" + aria-label="select" autoComplete="off" disabled={false} height="100%" - maxLength={null} onBlur={[Function]} onChange={[Function]} onCompositionEnd={[Function]} @@ -378,10 +379,11 @@ exports[`Base Render renderComp 1`] = ` "hidden": undefined, } } + aria-expanded="false" + aria-label="select" autoComplete="off" disabled={false} height="100%" - maxLength={null} onBlur={[Function]} onChange={[Function]} onCompositionEnd={[Function]} @@ -485,7 +487,6 @@ exports[`Base Render renderComp 1`] = ` autoComplete="off" disabled={false} height="100%" - maxLength={null} onBlur={[Function]} onChange={[Function]} onCompositionEnd={[Function]} @@ -988,7 +989,6 @@ exports[`Base Render renderComp 1`] = ` autoComplete="off" disabled={false} height="100%" - maxLength={null} onBlur={[Function]} onChange={[Function]} onCompositionEnd={[Function]} @@ -1048,10 +1048,11 @@ exports[`Base Render renderComp 1`] = ` "hidden": undefined, } } + aria-expanded="false" + aria-label="select" autoComplete="off" disabled={false} height="100%" - maxLength={null} name="error" onBlur={[Function]} onChange={[Function]}