Compare commits

..

54 Commits

Author SHA1 Message Date
GitHub Action
0aaab6c56b chore(release): publish 1.3.3-beta.3 2024-06-18 01:56:57 +00:00
1ncounter
6f69efcab0 Merge branch 'develop' into release/1.3.3-beta 2024-06-18 09:47:25 +08:00
唐澜
deb50d1122
Merge pull request #3049 from liukairui/develop
fix: update outline tree when node loop property changes
2024-06-18 09:20:18 +08:00
liukairui
a8c50ef9cd test: update renderer-core snapshots 2024-06-14 03:31:19 +08:00
liukairui
8d44c58845 fix: update outline tree when node loop property changes 2024-06-14 03:21:37 +08:00
暁仙
09707ce6b1
Merge pull request #3026 from alibaba/fix/ts-error
fix: next 组件最新版本 TS 声明文件导出部分异常,暂时调整声明文件进行正常编译,后续组件升级后可再配合调整
2024-05-16 15:53:50 +08:00
唐澜
bc6eb4a03a Merge branch 'develop' into fix/ts-error 2024-05-16 15:34:51 +08:00
唐澜
6cd7dfb3d5
Merge pull request #3027 from alibaba/revert-2271-patch-3
Revert "fix: keep `this` in parse expression function"
2024-05-16 15:26:26 +08:00
唐澜
418a0bdaa2
Revert "fix: keep this in parse expression function" 2024-05-16 15:25:19 +08:00
woshilaoge
395e60079a fix: next 组件最新版本 TS 声明文件导出部分异常,暂时调整声明文件进行正常编译,后续组件升级后可再配合调整 2024-05-15 17:01:52 +08:00
唐澜
5d220ce9cf
Merge pull request #2271 from rainke/patch-3
fix: keep `this` in parse expression function
2024-04-26 11:38:33 +08:00
唐澜
a4ecdd0040
Merge pull request #2938 from Osub/patch-3
docs: add star history to README
2024-04-15 10:37:35 +08:00
GitHub Action
3a9ebd3983 chore(docs): publish documentation 2024-03-28 07:02:42 +00:00
刘菊萍(絮黎)
c1dce14979 Update npms.md 2024-03-28 15:01:48 +08:00
AndyJin
816b58c8d0 docs(readme): update participation url 2024-03-28 11:21:04 +08:00
刘菊萍(絮黎)
db2f2d6aa2 Update skeleton.md 2024-03-28 11:20:39 +08:00
GitHub Action
2471bf3d31 chore(release): publish 1.3.3-beta.2 2024-03-07 06:56:15 +00:00
liujuping
a74ce5c229 fix: update import statements to use type imports 2024-03-07 14:50:06 +08:00
liujuping
20ddbed4fd fix: fix node parent assignment and update settings check 2024-03-07 14:50:06 +08:00
liujuping
4c83b945a7 fix: refactor splice method to remove and purge nodes*** 2024-03-07 14:50:06 +08:00
liujuping
a423a7dab5 fix: remove console.log statements, update test, and purge children in NodeChildren class 2024-03-07 14:50:05 +08:00
GitHub Action
2918abffb5 chore(docs): publish documentation 2024-03-07 14:50:05 +08:00
liujuping
dc98670c37 fix: update import statements to use type imports 2024-03-07 14:49:46 +08:00
liujuping
d2138d7edb fix: fix node parent assignment and update settings check 2024-03-07 14:49:46 +08:00
liujuping
0d7ae43b79 fix: refactor splice method to remove and purge nodes*** 2024-03-07 14:49:46 +08:00
liujuping
71f9e08cb2 fix: remove console.log statements, update test, and purge children in NodeChildren class 2024-03-07 14:49:46 +08:00
GitHub Action
c8350a4095 chore(release): publish 1.3.3-beta.1 2024-03-01 01:41:54 +00:00
GitHub Action
d7dfde5452 chore(docs): publish documentation 2024-03-01 01:35:48 +00:00
liujuping
33902e0109 feat(hotkey): Add mount method to Hotkey class 2024-03-01 09:35:33 +08:00
GitHub Action
202159cfd0 chore(docs): publish documentation 2024-03-01 09:35:33 +08:00
zzzhrookie
a5e1106160 docs(chore): fix incorrect module name 2024-03-01 09:35:33 +08:00
zzzhrookie
42480f4d68 docs(chore): replace English parentheses with Chinese ones 2024-03-01 09:35:32 +08:00
zzzhrookie
f84d4e7901 docs(chore): update command for developing docs 2024-03-01 09:35:32 +08:00
zzzhrookie
cc36ba152d docs(chore): fix incorrect link redirects within lowcode-spec.md 2024-03-01 09:35:32 +08:00
DiscoverForever
abb0ce001c docs: fix incorrect word, change "搜搜" to "搜索"
修复readme中的错别字,"搜搜"修改为"搜索"。
2024-03-01 09:35:32 +08:00
GitHub Action
3ab64227d5 chore(docs): publish documentation 2024-03-01 09:35:31 +08:00
刘菊萍(絮黎)
f8651ce0d5 Update commonUI.md 2024-03-01 09:35:31 +08:00
liujuping
7cecf91a25 feat(hotkey): Add mount method to Hotkey class 2024-03-01 09:34:52 +08:00
GitHub Action
cc45087225 chore(docs): publish documentation 2024-03-01 00:27:33 +00:00
zzzhrookie
d986beedbc docs(chore): fix incorrect module name 2024-03-01 08:26:40 +08:00
zzzhrookie
72a5a279c3 docs(chore): replace English parentheses with Chinese ones 2024-03-01 08:26:40 +08:00
zzzhrookie
98e9179f23 docs(chore): update command for developing docs 2024-03-01 08:26:40 +08:00
zzzhrookie
814d046a43 docs(chore): fix incorrect link redirects within lowcode-spec.md 2024-03-01 08:26:40 +08:00
DiscoverForever
40eb152a4e docs: fix incorrect word, change "搜搜" to "搜索"
修复readme中的错别字,"搜搜"修改为"搜索"。
2024-03-01 08:25:33 +08:00
GitHub Action
4465866433 chore(docs): publish documentation 2024-02-29 08:48:58 +00:00
刘菊萍(絮黎)
d66f712174 Update commonUI.md 2024-02-29 16:48:03 +08:00
GitHub Action
bd4b735f3b chore(release): publish 1.3.3-beta.0 2024-02-27 05:59:07 +00:00
liujuping
0d92011863 chore: update ts defined 2024-02-27 11:05:03 +08:00
GitHub Action
dbd9382117 chore(docs): publish documentation 2024-02-26 07:02:35 +00:00
刘菊萍(絮黎)
1e72c43459 Update command.md 2024-02-26 15:01:45 +08:00
webstar
699abd69fb
docs: add star history to README
add star history to README。
2024-02-23 17:48:16 +08:00
Rainke
fc947d2feb
fix: remove function bind
If the returned function is bound to a context, there is no way to call it with `call` and `apply`.
2023-07-18 10:37:46 +08:00
林熠
ce7e766b86
Merge branch 'develop' into patch-3 2023-07-13 09:20:55 +08:00
Rainke
c805bba0c7
fix: keep this in parse expression function
1. Wrong work when function has `__self`
2. All `this` will replaced anyway
2023-07-12 16:22:08 +08:00
129 changed files with 534 additions and 944 deletions

2
.github/CODEOWNERS vendored
View File

@ -2,7 +2,7 @@
# These owners will be the default owners for everything in # These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence # the repo. Unless a later match takes precedence
* @liujuping @1ncounter * @liujuping @JackLian
/modules/material-parser @akirakai /modules/material-parser @akirakai
/modules/code-generator @qingniaotonghua /modules/code-generator @qingniaotonghua

View File

@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: >- if: >-
contains(github.ref, 'refs/heads/release/') && contains(github.ref, 'refs/heads/release/') &&
(github.actor == '1ncounter' || github.actor == 'liujuping') (github.actor == 'JackLian' || github.actor == 'liujuping')
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Setup Node.js - name: Setup Node.js

View File

@ -36,7 +36,7 @@ $ yarn build
## 功能 ## 功能
- [x] 支持本地离线搜 - [x] 支持本地离线搜
- [x] 版本化文档管理 - [x] 版本化文档管理
- [x] 离线静态部署 - [x] 离线静态部署
- [x] 主题fork 宜搭开发者中心) - [x] 主题fork 宜搭开发者中心)

View File

@ -25,8 +25,7 @@ sidebar_position: 10
注册一个新命令及其处理函数。 注册一个新命令及其处理函数。
``` ```typescript
typescriptCopy code
/** /**
* 注册一个新的命令及其处理程序。 * 注册一个新的命令及其处理程序。
* @param command {IPublicTypeCommand} - 要注册的命令。 * @param command {IPublicTypeCommand} - 要注册的命令。
@ -38,8 +37,7 @@ registerCommand(command: IPublicTypeCommand): void;
注销一个已存在的命令。 注销一个已存在的命令。
``` ```typescript
typescriptCopy code
/** /**
* 注销一个已存在的命令。 * 注销一个已存在的命令。
* @param name {string} - 要注销的命令的名称。 * @param name {string} - 要注销的命令的名称。
@ -51,8 +49,7 @@ unregisterCommand(name: string): void;
根据名称和提供的参数执行命令,确保参数符合命令的定义。 根据名称和提供的参数执行命令,确保参数符合命令的定义。
``` ```typescript
typescriptCopy code
/** /**
* 根据名称和提供的参数执行命令。 * 根据名称和提供的参数执行命令。
* @param name {string} - 要执行的命令的名称。 * @param name {string} - 要执行的命令的名称。
@ -65,8 +62,7 @@ executeCommand(name: string, args?: IPublicTypeCommandHandlerArgs): void;
批量执行命令,在所有命令执行后进行重绘,历史记录中只记录一次。 批量执行命令,在所有命令执行后进行重绘,历史记录中只记录一次。
``` ```typescript
typescriptCopy code
/** /**
* 批量执行命令,随后进行重绘,历史记录中只记录一次。 * 批量执行命令,随后进行重绘,历史记录中只记录一次。
* @param commands {Array} - 命令对象的数组,包含名称和可选参数。 * @param commands {Array} - 命令对象的数组,包含名称和可选参数。
@ -78,8 +74,7 @@ batchExecuteCommand(commands: { name: string; args?: IPublicTypeCommandHandlerAr
列出所有已注册的命令。 列出所有已注册的命令。
``` ```typescript
typescriptCopy code
/** /**
* 列出所有已注册的命令。 * 列出所有已注册的命令。
* @returns {IPublicTypeListCommand[]} - 已注册命令的数组。 * @returns {IPublicTypeListCommand[]} - 已注册命令的数组。
@ -91,8 +86,7 @@ listCommands(): IPublicTypeListCommand[];
为命令执行过程中的错误注册错误处理回调函数。 为命令执行过程中的错误注册错误处理回调函数。
``` ```typescript
typescriptCopy code
/** /**
* 为命令执行过程中的错误注册一个回调函数。 * 为命令执行过程中的错误注册一个回调函数。
* @param callback {(name: string, error: Error) => void} - 错误处理的回调函数。 * @param callback {(name: string, error: Error) => void} - 错误处理的回调函数。

View File

@ -3,6 +3,8 @@ title: commonUI - UI 组件库
sidebar_position: 10 sidebar_position: 10
--- ---
> **@since** v1.3.0
## 简介 ## 简介
CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开发的插件,可以保证在不同项目和主题切换中能够保持一致性和兼容性。 CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开发的插件,可以保证在不同项目和主题切换中能够保持一致性和兼容性。

View File

@ -32,6 +32,19 @@ bind(
- [IPublicTypeHotkeyCallback](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/hotkey-callback.ts) - [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) - [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;
```
## 使用示例 ## 使用示例
### 基础示例 ### 基础示例

View File

@ -11,8 +11,9 @@ sidebar_position: 10
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01eVA0U41xYRP3e5zo0_!!6000000006455-2-tps-1780-996.png) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01eVA0U41xYRP3e5zo0_!!6000000006455-2-tps-1780-996.png)
页面上可以扩展的区域共 5 个,具体如下: 页面上可以扩展的区域共 6 个,具体如下:
![image.png](https://img.alicdn.com/imgextra/i3/O1CN014d2AcS1D5c9TshEiQ_!!6000000000165-2-tps-1892-974.png) ![image](https://github.com/alibaba/lowcode-engine/assets/11935995/ba4641dd-d346-4ef7-8b71-8ca211e6eaf4)
### 基本概念 ### 基本概念
#### 扩展区域位置 (area) #### 扩展区域位置 (area)
##### topArea ##### topArea
@ -41,6 +42,11 @@ sidebar_position: 10
##### rightArea ##### rightArea
右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。 右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。
##### bottomArea
底部扩展区域。
##### toolbar ##### toolbar
跟 topArea 类似,按需放置面板插件~ 跟 topArea 类似,按需放置面板插件~

View File

@ -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/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 | | @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) | | | @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 |
| | | | | | | |

View File

@ -20,7 +20,7 @@ sidebar_position: 1
[在 Demo 中](https://lowcode-engine.cn/demo/demo-general/index.html),右上角有渲染模块的示例使用方式: [在 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) ![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 上下文渲染低代码编辑器产出的页面。
### 构造渲染模块所需数据 ### 构造渲染模块所需数据

View File

@ -70,7 +70,7 @@ npm start
在 lowcode-engine 目录下执行下面命令 在 lowcode-engine 目录下执行下面命令
``` ```
cd docs cd docs
npm install
npm start npm start
``` ```

View File

@ -20,7 +20,7 @@ sidebar_position: 0
### 1.2 协议草案起草人 ### 1.2 协议草案起草人
- 撰写:月飞、康为、林熠 - 撰写:月飞、康为、林熠
- 审阅:大果、潕量、九神、元彦、戊子、屹凡、金禅、前道、天晟、戊子、游鹿、光弘、力皓 - 审阅:大果、潕量、九神、元彦、戊子、屹凡、金禅、前道、天晟、游鹿、光弘、力皓
### 1.3 版本号 ### 1.3 版本号
@ -94,7 +94,7 @@ sidebar_position: 0
### 1.9 使用范围 ### 1.9 使用范围
本协议描述的是低代码搭建平台产物(应用、页面、区块、组件)的 schema 结构,以及实现其数据状态更新(内置 api)、能力扩展、国际化等方面完整,只在低代码搭建场景下可用; 本协议描述的是低代码搭建平台产物(应用、页面、区块、组件)的 schema 结构,以及实现其数据状态更新(内置 api、能力扩展、国际化等方面完整,只在低代码搭建场景下可用;
### 1.10 协议目标 ### 1.10 协议目标
@ -430,7 +430,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input';
| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 |
| ----------- | ---------------------- | -------------------------------------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------- | | ----------- | ---------------------- | -------------------------------------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------- |
| list[] | 数据源列表 | **ComponentDataSourceItem**[] | - | - | 成为为单个请求配置, 内容定义详见 [ComponentDataSourceItem 对象描述](#2314-componentdatasourceitem-对象描述) | | list[] | 数据源列表 | **ComponentDataSourceItem**[] | - | - | 成为为单个请求配置, 内容定义详见 [ComponentDataSourceItem 对象描述](#2314-componentdatasourceitem-对象描述) |
| dataHandler | 所有请求数据的处理函数 | Function | - | - | 详见 [dataHandler Function 描述](#2317-datahandler-function 描述) | | dataHandler | 所有请求数据的处理函数 | Function | - | - | 详见 [dataHandler Function 描述](#2317-datahandler-function-描述) |
##### 2.3.1.4 ComponentDataSourceItem 对象描述 ##### 2.3.1.4 ComponentDataSourceItem 对象描述
@ -447,7 +447,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input';
| errorHandler | request 失败后的回调函数 | Function | - | - | 参数:请求出错 promise 的 error 内容 | | errorHandler | request 失败后的回调函数 | Function | - | - | 参数:请求出错 promise 的 error 内容 |
| options {} | 请求参数 | **ComponentDataSourceItemOptions**| - | - | 每种请求类型对应不同参数,详见 | 每种请求类型对应不同参数,详见 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) | | options {} | 请求参数 | **ComponentDataSourceItemOptions**| - | - | 每种请求类型对应不同参数,详见 | 每种请求类型对应不同参数,详见 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) |
**关于 dataHandler errorHandler 的细节说明:** **关于 dataHandler errorHandler 的细节说明:**
request 返回的是一个 promisedataHandler 和 errorHandler 遵循 Promise 对象的 then 方法,实际使用方式如下: request 返回的是一个 promisedataHandler 和 errorHandler 遵循 Promise 对象的 then 方法,实际使用方式如下:
@ -560,7 +560,7 @@ try {
| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 |
| ------------- | ---------------------- | ---------------- | -------- | ----------------- | ---------------------------------------------------------------------------------------------------------- | | ------------- | ---------------------- | ---------------- | -------- | ----------------- | ---------------------------------------------------------------------------------------------------------- |
| id | 组件唯一标识 | String | - | | 可选,组件 id 由引擎随机生成UUID并保证唯一性消费方为上层应用平台在组件发生移动等场景需保持 id 不变 | | id | 组件唯一标识 | String | - | | 可选,组件 id 由引擎随机生成UUID并保证唯一性消费方为上层应用平台在组件发生移动等场景需保持 id 不变 |
| componentName | 组件名称 | String | - | Div | 必填,首字母大写,同 [componentsMap](#22-组件映射关系 a) 中的要求 | | componentName | 组件名称 | String | - | Div | 必填,首字母大写,同 [componentsMap](#22-组件映射关系a) 中的要求 |
| props {} | 组件属性对象 | **Props**| - | {} | 必填,详见 | 必填,详见 [Props 结构描述](#2311-props-结构描述) | | props {} | 组件属性对象 | **Props**| - | {} | 必填,详见 | 必填,详见 [Props 结构描述](#2311-props-结构描述) |
| condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 | | condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 |
| loop | 循环数据 | Array | ✅ | - | 选填,默认不进行循环渲染;支持变量表达式 | | loop | 循环数据 | Array | ✅ | - | 选填,默认不进行循环渲染;支持变量表达式 |
@ -797,7 +797,7 @@ try {
| 参数 | 说明 | 值类型 | 默认值 | 备注 | | 参数 | 说明 | 值类型 | 默认值 | 备注 |
| ------ | ---------- | --------------------- | -------- | -------------------------------------------------------------- | | ------ | ---------- | --------------------- | -------- | -------------------------------------------------------------- |
| type | 值类型描述 | String | 'JSSlot' | 固定值 | | type | 值类型描述 | String | 'JSSlot' | 固定值 |
| value | 具体的值 | NodeSchema \| NodeSchema[] | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述 a) | | value | 具体的值 | NodeSchema \| NodeSchema[] | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述A) |
| params | 函数的参数 | String[] | null | 函数的入参,其子节点可以通过 `this[参数名]` 来获取对应的参数。 | | params | 函数的参数 | String[] | null | 函数的入参,其子节点可以通过 `this[参数名]` 来获取对应的参数。 |
@ -1124,7 +1124,7 @@ this.setState((prevState) => ({ count: prevState.count + 1 }));
| utils[] | 工具类扩展映射关系 | **UtilItem**[] | - | | | utils[] | 工具类扩展映射关系 | **UtilItem**[] | - | |
| *UtilItem*.name | 工具类扩展项名称 | String | - | | | *UtilItem*.name | 工具类扩展项名称 | String | - | |
| *UtilItem*.type | 工具类扩展项类型 | 枚举, `'npm'` (代表公网 npm 类型) / `'tnpm'` (代表阿里巴巴内部 npm 类型) / `'function'` (代表 Javascript 函数类型) | - | | | *UtilItem*.type | 工具类扩展项类型 | 枚举, `'npm'` (代表公网 npm 类型) / `'tnpm'` (代表阿里巴巴内部 npm 类型) / `'function'` (代表 Javascript 函数类型) | - | |
| *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系 a) 或 [JSFunction](#2432事件函数类型 a) | - | | | *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系a) 或 [JSFunction](#2342事件函数类型a) | - | |
描述示例: 描述示例:

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-engine-docs", "name": "@alilc/lowcode-engine-docs",
"version": "1.2.31", "version": "1.2.36",
"description": "低代码引擎版本化文档", "description": "低代码引擎版本化文档",
"license": "MIT", "license": "MIT",
"files": [ "files": [

View File

@ -1,6 +1,6 @@
{ {
"lerna": "4.0.0", "lerna": "4.0.0",
"version": "1.3.2", "version": "1.3.3-beta.3",
"npmClient": "yarn", "npmClient": "yarn",
"useWorkspaces": true, "useWorkspaces": true,
"packages": [ "packages": [

View File

@ -22,6 +22,7 @@ const jestConfig = {
// testMatch: ['**/selection.test.ts'], // testMatch: ['**/selection.test.ts'],
// testMatch: ['**/plugin/sequencify.test.ts'], // testMatch: ['**/plugin/sequencify.test.ts'],
// testMatch: ['**/builtin-simulator/utils/parse-metadata.test.ts'], // testMatch: ['**/builtin-simulator/utils/parse-metadata.test.ts'],
// testMatch: ['**/setting/setting-top-entry.test.ts'],
transformIgnorePatterns: [ transformIgnorePatterns: [
`/node_modules/(?!${esModules})/`, `/node_modules/(?!${esModules})/`,
], ],

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-designer", "name": "@alilc/lowcode-designer",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "Designer for Ali LowCode Engine", "description": "Designer for Ali LowCode Engine",
"main": "lib/index.js", "main": "lib/index.js",
"module": "es/index.js", "module": "es/index.js",
@ -15,9 +15,9 @@
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@alilc/lowcode-editor-core": "1.3.2", "@alilc/lowcode-editor-core": "1.3.3-beta.3",
"@alilc/lowcode-types": "1.3.2", "@alilc/lowcode-types": "1.3.3-beta.3",
"@alilc/lowcode-utils": "1.3.2", "@alilc/lowcode-utils": "1.3.3-beta.3",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"react": "^16", "react": "^16",
"react-dom": "^16.7.0", "react-dom": "^16.7.0",

View File

@ -5,18 +5,6 @@ import { Menu } from '@alifd/next';
import { engineConfig } from '@alilc/lowcode-editor-core'; import { engineConfig } from '@alilc/lowcode-editor-core';
import './context-menu-actions.scss'; import './context-menu-actions.scss';
export interface IContextMenuActions {
actions: IPublicTypeContextMenuAction[];
adjustMenuLayoutFn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[];
addMenuAction: IPublicApiMaterial['addContextMenuOption'];
removeMenuAction: IPublicApiMaterial['removeContextMenuOption'];
adjustMenuLayout: IPublicApiMaterial['adjustContextMenuLayout'];
}
let adjustMenuLayoutFn: Function = (actions: IPublicTypeContextMenuAction[]) => actions; let adjustMenuLayoutFn: Function = (actions: IPublicTypeContextMenuAction[]) => actions;
export class GlobalContextMenuActions { export class GlobalContextMenuActions {
@ -116,7 +104,7 @@ export class GlobalContextMenuActions {
const globalContextMenuActions = new GlobalContextMenuActions(); const globalContextMenuActions = new GlobalContextMenuActions();
export class ContextMenuActions implements IContextMenuActions { export class ContextMenuActions {
actions: IPublicTypeContextMenuAction[] = []; actions: IPublicTypeContextMenuAction[] = [];
designer: IDesigner; designer: IDesigner;
@ -204,30 +192,32 @@ export class ContextMenuActions implements IContextMenuActions {
originalEvent.stopPropagation(); originalEvent.stopPropagation();
originalEvent.preventDefault(); originalEvent.preventDefault();
// 如果右键的节点不在 当前选中的节点中,选中该节点 // 如果右键的节点不在 当前选中的节点中,选中该节点
if (!designer.currentSelection.has(node.id)) { if (!designer.currentSelection?.has(node.id)) {
designer.currentSelection.select(node.id); designer.currentSelection?.select(node.id);
} }
const nodes = designer.currentSelection.getNodes(); const nodes = designer.currentSelection?.getNodes();
this.handleContextMenu(nodes, originalEvent); this.handleContextMenu(nodes, originalEvent);
}), }),
); );
} }
addMenuAction(action: IPublicTypeContextMenuAction) { addMenuAction: IPublicApiMaterial['addContextMenuOption'] = (action: IPublicTypeContextMenuAction) => {
this.actions.push({ this.actions.push({
type: IPublicEnumContextMenuType.MENU_ITEM, type: IPublicEnumContextMenuType.MENU_ITEM,
...action, ...action,
}); });
} };
removeMenuAction(name: string) { removeMenuAction: IPublicApiMaterial['removeContextMenuOption'] = (name: string) => {
const i = this.actions.findIndex((action) => action.name === name); const i = this.actions.findIndex((action) => action.name === name);
if (i > -1) { if (i > -1) {
this.actions.splice(i, 1); this.actions.splice(i, 1);
} }
} };
adjustMenuLayout(fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]) { adjustMenuLayout: IPublicApiMaterial['adjustContextMenuLayout'] = (fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]) => {
adjustMenuLayoutFn = fn; adjustMenuLayoutFn = fn;
} };
} }
export interface IContextMenuActions extends ContextMenuActions {}

View File

@ -1,16 +1,16 @@
import { Component } from 'react'; import { Component } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import BuiltinDragGhostComponent from './drag-ghost'; import BuiltinDragGhostComponent from './drag-ghost';
import { Designer, DesignerProps } from './designer'; import { Designer, DesignerProps, IDesigner } from './designer';
import { ProjectView } from '../project'; import { ProjectView } from '../project';
import './designer.less'; import './designer.less';
type IProps = DesignerProps & { type IProps = DesignerProps & {
designer?: Designer; designer?: IDesigner;
}; };
export class DesignerView extends Component<IProps> { export class DesignerView extends Component<IProps> {
readonly designer: Designer; readonly designer: IDesigner;
readonly viewName: string | undefined; readonly viewName: string | undefined;
constructor(props: IProps) { constructor(props: IProps) {

View File

@ -6,7 +6,6 @@ import {
IPublicTypeComponentAction, IPublicTypeComponentAction,
IPublicTypeNpmInfo, IPublicTypeNpmInfo,
IPublicModelEditor, IPublicModelEditor,
IPublicTypeCompositeObject,
IPublicTypePropsList, IPublicTypePropsList,
IPublicTypeNodeSchema, IPublicTypeNodeSchema,
IPublicTypePropsTransducer, IPublicTypePropsTransducer,
@ -17,15 +16,16 @@ import {
IPublicTypeLocationData, IPublicTypeLocationData,
IPublicEnumTransformStage, IPublicEnumTransformStage,
IPublicModelLocateEvent, IPublicModelLocateEvent,
IPublicTypePropsMap,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { mergeAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils'; import { mergeAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils';
import { IProject, Project } from '../project'; import { IProject, Project } from '../project';
import { Node, DocumentModel, insertChildren, INode, ISelection } from '../document'; import { Node, DocumentModel, insertChildren, INode } from '../document';
import { ComponentMeta, IComponentMeta } from '../component-meta'; import { ComponentMeta, IComponentMeta } from '../component-meta';
import { INodeSelector, Component } from '../simulator'; import { INodeSelector, Component } from '../simulator';
import { Scroller } from './scroller'; import { Scroller } from './scroller';
import { Dragon, IDragon } from './dragon'; import { Dragon, IDragon } from './dragon';
import { ActiveTracker, IActiveTracker } from './active-tracker'; import { ActiveTracker } from './active-tracker';
import { Detecting } from './detecting'; import { Detecting } from './detecting';
import { DropLocation } from './location'; import { DropLocation } from './location';
import { OffsetObserver, createOffsetObserver } from './offset-observer'; import { OffsetObserver, createOffsetObserver } from './offset-observer';
@ -47,7 +47,7 @@ export interface DesignerProps {
viewName?: string; viewName?: string;
simulatorProps?: Record<string, any> | ((document: DocumentModel) => object); simulatorProps?: Record<string, any> | ((document: DocumentModel) => object);
simulatorComponent?: ComponentType<any>; simulatorComponent?: ComponentType<any>;
dragGhostComponent?: ComponentType<any>; dragGhostComponent?: ComponentType<{ designer: IDesigner }>;
suspensed?: boolean; suspensed?: boolean;
componentMetadatas?: IPublicTypeComponentMetadata[]; componentMetadatas?: IPublicTypeComponentMetadata[];
globalComponentActions?: IPublicTypeComponentAction[]; globalComponentActions?: IPublicTypeComponentAction[];
@ -60,70 +60,10 @@ export interface DesignerProps {
) => void; ) => void;
} }
export interface IDesigner { export class Designer {
readonly shellModelFactory: IShellModelFactory;
viewName: string | undefined;
readonly project: IProject;
get dragon(): IDragon;
get activeTracker(): IActiveTracker;
get componentActions(): ComponentActions;
get contextMenuActions(): ContextMenuActions;
get editor(): IPublicModelEditor;
get detecting(): Detecting;
get simulatorComponent(): ComponentType<any> | undefined;
get currentSelection(): ISelection;
createScroller(scrollable: IPublicTypeScrollable): IPublicModelScroller;
refreshComponentMetasMap(): void;
createOffsetObserver(nodeInstance: INodeSelector): OffsetObserver | null;
/**
* dragon
*/
createLocation(locationData: IPublicTypeLocationData<INode>): DropLocation;
get componentsMap(): { [key: string]: IPublicTypeNpmInfo | Component };
loadIncrementalAssets(incrementalAssets: IPublicTypeAssetsJson): Promise<void>;
getComponentMeta(
componentName: string,
generateMetadata?: () => IPublicTypeComponentMetadata | null,
): IComponentMeta;
clearLocation(): void;
createComponentMeta(data: IPublicTypeComponentMetadata): IComponentMeta | null;
getComponentMetasMap(): Map<string, IComponentMeta>;
addPropsReducer(reducer: IPublicTypePropsTransducer, stage: IPublicEnumTransformStage): void;
postEvent(event: string, ...args: any[]): void;
transformProps(props: IPublicTypeCompositeObject | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage): IPublicTypeCompositeObject | IPublicTypePropsList;
createSettingEntry(nodes: INode[]): ISettingTopEntry;
autorun(effect: (reaction: IReactionPublic) => void, options?: IReactionOptions<any, any>): IReactionDisposer;
}
export class Designer implements IDesigner {
dragon: IDragon; dragon: IDragon;
viewName: string | undefined; readonly viewName: string | undefined;
readonly componentActions = new ComponentActions(); readonly componentActions = new ComponentActions();
@ -423,7 +363,7 @@ export class Designer implements IDesigner {
if (props.simulatorProps !== this.props.simulatorProps) { if (props.simulatorProps !== this.props.simulatorProps) {
this._simulatorProps = props.simulatorProps; this._simulatorProps = props.simulatorProps;
// 重新 setupSelection // 重新 setupSelection
if (props.simulatorProps?.designMode !== this.props.simulatorProps?.designMode) { if ((props.simulatorProps as any)?.designMode !== (this.props.simulatorProps as any)?.designMode) {
this.setupSelection(); this.setupSelection();
} }
} }
@ -612,7 +552,7 @@ export class Designer implements IDesigner {
return maps; return maps;
} }
transformProps(props: IPublicTypeCompositeObject | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage) { transformProps(props: IPublicTypePropsMap | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage): IPublicTypePropsMap | IPublicTypePropsList {
if (Array.isArray(props)) { if (Array.isArray(props)) {
// current not support, make this future // current not support, make this future
return props; return props;
@ -623,7 +563,7 @@ export class Designer implements IDesigner {
return props; return props;
} }
return reducers.reduce((xprops, reducer) => { return reducers.reduce((xprops, reducer: IPublicTypePropsTransducer) => {
try { try {
return reducer(xprops, node.internalToShellNode() as any, { stage }); return reducer(xprops, node.internalToShellNode() as any, { stage });
} catch (e) { } catch (e) {
@ -655,3 +595,5 @@ export class Designer implements IDesigner {
// TODO: // TODO:
} }
} }
export interface IDesigner extends Designer {}

View File

@ -13,7 +13,7 @@ import {
import { setNativeSelection, cursor } from '@alilc/lowcode-utils'; import { setNativeSelection, cursor } from '@alilc/lowcode-utils';
import { INode, Node } from '../document'; import { INode, Node } from '../document';
import { ISimulatorHost, isSimulatorHost } from '../simulator'; import { ISimulatorHost, isSimulatorHost } from '../simulator';
import { IDesigner } from './designer'; import type { IDesigner } from './designer';
import { makeEventsHandler } from '../utils/misc'; import { makeEventsHandler } from '../utils/misc';
export interface ILocateEvent extends IPublicModelLocateEvent { export interface ILocateEvent extends IPublicModelLocateEvent {
@ -95,17 +95,13 @@ function isDragEvent(e: any): e is DragEvent {
return e?.type?.startsWith('drag'); return e?.type?.startsWith('drag');
} }
export interface IDragon extends IPublicModelDragon<
INode,
ILocateEvent
> {
emitter: IEventBus;
}
/** /**
* Drag-on * Drag-on
*/ */
export class Dragon implements IDragon { export class Dragon implements IPublicModelDragon<
INode,
ILocateEvent
> {
private sensors: IPublicModelSensor[] = []; private sensors: IPublicModelSensor[] = [];
private nodeInstPointerEvents: boolean; private nodeInstPointerEvents: boolean;
@ -637,3 +633,5 @@ export class Dragon implements IDragon {
}; };
} }
} }
export interface IDragon extends Dragon { }

View File

@ -28,11 +28,11 @@ export class OffsetObserver {
@obx private _bottom = 0; @obx private _bottom = 0;
@computed get height() { @computed get height() {
return this.isRoot ? this.viewport.height : this._height * this.scale; return this.isRoot ? this.viewport?.height : this._height * this.scale;
} }
@computed get width() { @computed get width() {
return this.isRoot ? this.viewport.width : this._width * this.scale; return this.isRoot ? this.viewport?.width : this._width * this.scale;
} }
@computed get top() { @computed get top() {
@ -44,51 +44,51 @@ export class OffsetObserver {
} }
@computed get bottom() { @computed get bottom() {
return this.isRoot ? this.viewport.height : this._bottom * this.scale; return this.isRoot ? this.viewport?.height : this._bottom * this.scale;
} }
@computed get right() { @computed get right() {
return this.isRoot ? this.viewport.width : this._right * this.scale; return this.isRoot ? this.viewport?.width : this._right * this.scale;
} }
@obx hasOffset = false; @obx hasOffset = false;
@computed get offsetLeft() { @computed get offsetLeft() {
if (this.isRoot) { if (this.isRoot) {
return this.viewport.scrollX * this.scale; return (this.viewport?.scrollX || 0) * this.scale;
} }
if (!this.viewport.scrolling || this.lastOffsetLeft == null) { if (!this.viewport?.scrolling || this.lastOffsetLeft == null) {
this.lastOffsetLeft = this.left + this.viewport.scrollX * this.scale; this.lastOffsetLeft = this.left + (this.viewport?.scrollX || 0) * this.scale;
} }
return this.lastOffsetLeft; return this.lastOffsetLeft;
} }
@computed get offsetTop() { @computed get offsetTop() {
if (this.isRoot) { if (this.isRoot) {
return this.viewport.scrollY * this.scale; return (this.viewport?.scrollY || 0) * this.scale;
} }
if (!this.viewport.scrolling || this.lastOffsetTop == null) { if (!this.viewport?.scrolling || this.lastOffsetTop == null) {
this.lastOffsetTop = this.top + this.viewport.scrollY * this.scale; this.lastOffsetTop = this.top + (this.viewport?.scrollY || 0) * this.scale;
} }
return this.lastOffsetTop; return this.lastOffsetTop;
} }
@computed get offsetHeight() { @computed get offsetHeight() {
if (!this.viewport.scrolling || this.lastOffsetHeight == null) { if (!this.viewport?.scrolling || this.lastOffsetHeight == null) {
this.lastOffsetHeight = this.isRoot ? this.viewport.height : this.height; this.lastOffsetHeight = this.isRoot ? (this.viewport?.height || 0) : this.height;
} }
return this.lastOffsetHeight; return this.lastOffsetHeight;
} }
@computed get offsetWidth() { @computed get offsetWidth() {
if (!this.viewport.scrolling || this.lastOffsetWidth == null) { if (!(this.viewport?.scrolling || 0) || this.lastOffsetWidth == null) {
this.lastOffsetWidth = this.isRoot ? this.viewport.width : this.width; this.lastOffsetWidth = this.isRoot ? (this.viewport?.width || 0) : this.width;
} }
return this.lastOffsetWidth; return this.lastOffsetWidth;
} }
@computed get scale() { @computed get scale() {
return this.viewport.scale; return this.viewport?.scale || 0;
} }
private pid: number | undefined; private pid: number | undefined;
@ -124,11 +124,11 @@ export class OffsetObserver {
return; return;
} }
const rect = host.computeComponentInstanceRect(instance!, node.componentMeta.rootSelector); const rect = host?.computeComponentInstanceRect(instance!, node.componentMeta.rootSelector);
if (!rect) { if (!rect) {
this.hasOffset = false; this.hasOffset = false;
} else if (!this.viewport.scrolling || !this.hasOffset) { } else if (!this.viewport?.scrolling || !this.hasOffset) {
this._height = rect.height; this._height = rect.height;
this._width = rect.width; this._width = rect.width;
this._left = rect.left; this._left = rect.left;

View File

@ -1,7 +1,7 @@
import { IPublicApiSetters, IPublicModelEditor } from '@alilc/lowcode-types'; import type { IPublicApiSetters, IPublicModelEditor } from '@alilc/lowcode-types';
import { IDesigner } from '../designer'; import type { IDesigner } from '../designer';
import { INode } from '../../document'; import type { INode } from '../../document';
import { ISettingField } from './setting-field'; import type { ISettingField } from './setting-field';
export interface ISettingEntry { export interface ISettingEntry {
readonly designer: IDesigner | undefined; readonly designer: IDesigner | undefined;

View File

@ -1,4 +1,3 @@
import { ReactNode } from 'react';
import { import {
IPublicTypeTitleContent, IPublicTypeTitleContent,
IPublicTypeSetterType, IPublicTypeSetterType,
@ -7,18 +6,15 @@ import {
IPublicTypeFieldConfig, IPublicTypeFieldConfig,
IPublicTypeCustomView, IPublicTypeCustomView,
IPublicTypeDisposable, IPublicTypeDisposable,
IPublicModelSettingField,
IBaseModelSettingField,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import type { import type {
IPublicTypeSetValueOptions, IPublicTypeSetValueOptions,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { Transducer } from './utils'; 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 { computed, obx, makeObservable, action, untracked, intl } from '@alilc/lowcode-editor-core';
import { cloneDeep, isCustomView, isDynamicSetter, isJSExpression } from '@alilc/lowcode-utils'; import { cloneDeep, isCustomView, isDynamicSetter, isJSExpression } from '@alilc/lowcode-utils';
import { ISettingTopEntry } from './setting-top-entry'; import type { ISettingTopEntry } from './setting-top-entry';
import { IComponentMeta, INode } from '@alilc/lowcode-designer';
function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, config: IPublicTypeFieldConfig) { function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, config: IPublicTypeFieldConfig) {
let cur = parent; let cur = parent;
@ -32,53 +28,7 @@ function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, c
return path.join('.'); return path.join('.');
} }
export interface ISettingField extends ISettingPropEntry, Omit<IBaseModelSettingField< export class SettingField extends SettingPropEntry {
ISettingTopEntry,
ISettingField,
IComponentMeta,
INode
>, 'setValue' | 'key' | 'node'> {
readonly isSettingField: true;
readonly isRequired: boolean;
readonly isGroup: boolean;
extraProps: IPublicTypeFieldExtraProps;
get items(): Array<ISettingField | IPublicTypeCustomView>;
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 {
readonly isSettingField = true; readonly isSettingField = true;
readonly isRequired: boolean; readonly isRequired: boolean;
@ -321,3 +271,5 @@ export class SettingField extends SettingPropEntry implements ISettingField {
export function isSettingField(obj: any): obj is ISettingField { export function isSettingField(obj: any): obj is ISettingField {
return obj && obj.isSettingField; return obj && obj.isSettingField;
} }
export type ISettingField = typeof SettingField;

View File

@ -1,12 +1,12 @@
import { obx, computed, makeObservable, runInAction, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { obx, computed, makeObservable, runInAction, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
import { GlobalEvent, IPublicApiSetters, IPublicModelEditor, IPublicModelSettingField, IPublicTypeFieldExtraProps, IPublicTypeSetValueOptions } from '@alilc/lowcode-types'; import { GlobalEvent, IPublicApiSetters, IPublicModelEditor, IPublicModelSettingField, IPublicTypeFieldExtraProps, IPublicTypeSetValueOptions } from '@alilc/lowcode-types';
import { uniqueId, isJSExpression } from '@alilc/lowcode-utils'; import { uniqueId, isJSExpression, isSettingField } from '@alilc/lowcode-utils';
import { ISettingEntry } from './setting-entry-type'; import type { ISettingEntry } from './setting-entry-type';
import { INode } from '../../document'; import type { INode } from '../../document';
import type { IComponentMeta } from '../../component-meta'; import type { IComponentMeta } from '../../component-meta';
import { IDesigner } from '../designer'; import type { IDesigner } from '../designer';
import { ISettingTopEntry } from './setting-top-entry'; import type { ISettingTopEntry } from './setting-top-entry';
import { ISettingField, isSettingField } from './setting-field'; import type { ISettingField } from './setting-field';
export interface ISettingPropEntry extends ISettingEntry { export interface ISettingPropEntry extends ISettingEntry {
readonly isGroup: boolean; readonly isGroup: boolean;

View File

@ -1,11 +1,12 @@
import { IPublicTypeCustomView, IPublicModelEditor, IPublicModelSettingTopEntry, IPublicApiSetters } from '@alilc/lowcode-types'; import { IPublicTypeCustomView, IPublicModelEditor, IPublicModelSettingTopEntry, IPublicApiSetters } from '@alilc/lowcode-types';
import { isCustomView } from '@alilc/lowcode-utils'; 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 { SettingField } from './setting-field';
import { ISettingField, SettingField } from './setting-field'; import type { ISettingEntry } from './setting-entry-type';
import { INode } from '../../document'; import type { ISettingField } from './setting-field';
import type { INode } from '../../document';
import type { IComponentMeta } from '../../component-meta'; import type { IComponentMeta } from '../../component-meta';
import { IDesigner } from '../designer'; import type { IDesigner } from '../designer';
function generateSessionId(nodes: INode[]) { function generateSessionId(nodes: INode[]) {
return nodes return nodes
@ -14,33 +15,17 @@ function generateSessionId(nodes: INode[]) {
.join(','); .join(',');
} }
export interface ISettingTopEntry extends ISettingEntry, IPublicModelSettingTopEntry< export interface ISettingTopEntry extends SettingTopEntry {}
export class SettingTopEntry implements ISettingEntry, IPublicModelSettingTopEntry<
INode, INode,
ISettingField ISettingField
> { > {
readonly top: ISettingTopEntry;
readonly parent: ISettingTopEntry;
readonly path: never[];
items: Array<ISettingField | IPublicTypeCustomView>;
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 emitter: IEventBus = createModuleEventBus('SettingTopEntry');
private _items: Array<SettingField | IPublicTypeCustomView> = []; private _items: Array<ISettingField | IPublicTypeCustomView> = [];
private _componentMeta: IComponentMeta | null = null; private _componentMeta: IComponentMeta | null | undefined = null;
private _isSame = true; private _isSame = true;
@ -75,7 +60,7 @@ export class SettingTopEntry implements ISettingTopEntry {
} }
get isLocked(): boolean { get isLocked(): boolean {
return this.first.isLocked; return this.first?.isLocked ?? false;
} }
/** /**
@ -87,7 +72,11 @@ export class SettingTopEntry implements ISettingTopEntry {
readonly id: string; readonly id: string;
readonly first: INode; @computed get first(): INode | null {
return this._first;
}
@obx.ref _first: INode | null;
readonly designer: IDesigner | undefined; readonly designer: IDesigner | undefined;
@ -96,12 +85,14 @@ export class SettingTopEntry implements ISettingTopEntry {
disposeFunctions: any[] = []; disposeFunctions: any[] = [];
constructor(readonly editor: IPublicModelEditor, readonly nodes: INode[]) { constructor(readonly editor: IPublicModelEditor, readonly nodes: INode[]) {
makeObservable(this);
if (!Array.isArray(nodes) || nodes.length < 1) { if (!Array.isArray(nodes) || nodes.length < 1) {
throw new ReferenceError('nodes should not be empty'); throw new ReferenceError('nodes should not be empty');
} }
this.id = generateSessionId(nodes); this.id = generateSessionId(nodes);
this.first = nodes[0]; this._first = nodes[0];
this.designer = this.first.document?.designer; this.designer = this._first.document?.designer;
this.setters = editor.get('setters') as IPublicApiSetters; this.setters = editor.get('setters') as IPublicApiSetters;
// setups // setups
@ -116,7 +107,7 @@ export class SettingTopEntry implements ISettingTopEntry {
private setupComponentMeta() { private setupComponentMeta() {
// todo: enhance compile a temp configure.compiled // todo: enhance compile a temp configure.compiled
const { first } = this; const { first } = this;
const meta = first.componentMeta; const meta = first?.componentMeta;
const l = this.nodes.length; const l = this.nodes.length;
let theSame = true; let theSame = true;
for (let i = 1; i < l; i++) { for (let i = 1; i < l; i++) {
@ -160,7 +151,7 @@ export class SettingTopEntry implements ISettingTopEntry {
/** /**
* *
*/ */
@computed getValue(): any { getValue(): any {
return this.first?.propsData; return this.first?.propsData;
} }
@ -202,14 +193,14 @@ export class SettingTopEntry implements ISettingTopEntry {
* *
*/ */
getPropValue(propName: string | number): any { getPropValue(propName: string | number): any {
return this.first.getProp(propName.toString(), true)?.getValue(); return this.first?.getProp(propName.toString(), true)?.getValue();
} }
/** /**
* *
*/ */
getExtraPropValue(propName: string) { getExtraPropValue(propName: string) {
return this.first.getExtraProp(propName, false)?.getValue(); return this.first?.getExtraProp(propName, false)?.getValue();
} }
/** /**
@ -244,8 +235,9 @@ export class SettingTopEntry implements ISettingTopEntry {
this.disposeItems(); this.disposeItems();
this._settingFieldMap = {}; this._settingFieldMap = {};
this.emitter.removeAllListeners(); this.emitter.removeAllListeners();
this.disposeFunctions.forEach(f => f()); this.disposeFunctions.forEach(f => f?.());
this.disposeFunctions = []; this.disposeFunctions = [];
this._first = null;
} }
getProp(propName: string | number) { getProp(propName: string | number) {
@ -274,7 +266,7 @@ export class SettingTopEntry implements ISettingTopEntry {
} }
getPage() { getPage() {
return this.first.document; return this.first?.document;
} }
/** /**
@ -292,6 +284,7 @@ export class SettingTopEntry implements ISettingTopEntry {
interface Purgeable { interface Purgeable {
purge(): void; purge(): void;
} }
function isPurgeable(obj: any): obj is Purgeable { function isPurgeable(obj: any): obj is Purgeable {
return obj && obj.purge; return obj && obj.purge;
} }

View File

@ -37,10 +37,10 @@ import {
isDragNodeDataObject, isDragNodeDataObject,
isNode, isNode,
} from '@alilc/lowcode-utils'; } from '@alilc/lowcode-utils';
import { IProject } from '../project'; import type { IProject } from '../project';
import { ISimulatorHost } from '../simulator'; import type { ISimulatorHost } from '../simulator';
import type { IComponentMeta } from '../component-meta'; 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 { insertChildren, insertChild, IRootNode } from './node/node';
import type { INode } from './node/node'; import type { INode } from './node/node';
import { Selection, ISelection } from './selection'; import { Selection, ISelection } from './selection';
@ -56,104 +56,30 @@ export type GetDataType<T, NodeType> = T extends undefined
: any : any
: T; : T;
export interface IDocumentModel extends Omit<IPublicModelDocumentModel< export class DocumentModel implements Omit<IPublicModelDocumentModel<
ISelection, ISelection,
IHistory, IHistory,
INode, INode,
IDropLocation, IDropLocation,
IModalNodesManager, IModalNodesManager,
IProject IProject
>, >,
'detecting' | 'detecting' |
'checkNesting' | 'checkNesting' |
'getNodeById' | 'getNodeById' |
// 以下属性在内部的 document 中不存在 // 以下属性在内部的 document 中不存在
'exportSchema' | 'exportSchema' |
'importSchema' | 'importSchema' |
'onAddNode' | 'onAddNode' |
'onRemoveNode' | 'onRemoveNode' |
'onChangeDetecting' | 'onChangeDetecting' |
'onChangeSelection' | 'onChangeSelection' |
'onChangeNodeProp' | 'onChangeNodeProp' |
'onImportSchema' | 'onImportSchema' |
'isDetectingNode' | 'isDetectingNode' |
'onFocusNodeChanged' | 'onFocusNodeChanged' |
'onDropLocationChanged' 'onDropLocationChanged'
> { > {
readonly designer: IDesigner;
selection: ISelection;
get rootNode(): INode | null;
get simulator(): ISimulatorHost | null;
get active(): boolean;
get nodesMap(): Map<string, INode>;
/**
*
*/
get suspensed(): boolean;
get fileName(): string;
get currentRoot(): INode | null;
isBlank(): boolean;
/**
* id
*/
getNode(id: string): INode | null;
getRoot(): INode | null;
getHistory(): IHistory;
checkNesting(
dropTarget: INode,
dragObject: IPublicTypeDragNodeObject | IPublicTypeNodeSchema | INode | IPublicTypeDragNodeDataObject,
): boolean;
getNodeCount(): number;
nextId(possibleId: string | undefined): string;
import(schema: IPublicTypeRootSchema, checkId?: boolean): void;
export(stage: IPublicEnumTransformStage): IPublicTypeRootSchema | undefined;
onNodeCreate(func: (node: INode) => void): IPublicTypeDisposable;
onNodeDestroy(func: (node: INode) => void): IPublicTypeDisposable;
onChangeNodeVisible(fn: (node: INode, visible: boolean) => void): IPublicTypeDisposable;
addWillPurge(node: INode): void;
removeWillPurge(node: INode): void;
getComponentMeta(componentName: string): IComponentMeta;
insertNodes(parent: INode, thing: INode[] | IPublicTypeNodeData[], at?: number | null, copy?: boolean): INode[];
open(): IDocumentModel;
remove(): void;
suspense(): void;
close(): void;
unlinkNode(node: INode): void;
destroyNode(node: INode): void;
}
export class DocumentModel implements IDocumentModel {
/** /**
* Page/Component/Block * Page/Component/Block
*/ */
@ -322,7 +248,7 @@ export class DocumentModel implements IDocumentModel {
// 兼容 vision // 兼容 vision
this.id = project.getSchema()?.id || this.id; this.id = project.getSchema()?.id || this.id;
this.rootNode = this.createNode( this.rootNode = this.createNode<IRootNode, IPublicTypeRootSchema>(
schema || { schema || {
componentName: 'Page', componentName: 'Page',
id: 'root', id: 'root',
@ -425,7 +351,7 @@ export class DocumentModel implements IDocumentModel {
* schema * schema
*/ */
@action @action
createNode<T extends INode = INode, C = undefined>(data: GetDataType<C, T>): T { createNode<T = INode, S = IPublicTypeNodeSchema>(data: S): T {
let schema: any; let schema: any;
if (isDOMText(data) || isJSExpression(data)) { if (isDOMText(data) || isJSExpression(data)) {
schema = { schema = {
@ -529,7 +455,7 @@ export class DocumentModel implements IDocumentModel {
return null; return null;
} }
const wrapper = this.createNode(schema); const wrapper = this.createNode(schema);
if (wrapper.isParental()) { if (wrapper?.isParental()) {
const first = nodes[0]; const first = nodes[0];
// TODO: check nesting rules x 2 // TODO: check nesting rules x 2
insertChild(first.parent!, wrapper, first.index); insertChild(first.parent!, wrapper, first.index);
@ -538,7 +464,7 @@ export class DocumentModel implements IDocumentModel {
return wrapper; return wrapper;
} }
this.removeNode(wrapper); wrapper && this.removeNode(wrapper);
return null; return null;
} }
@ -928,3 +854,5 @@ export function isDocumentModel(obj: any): obj is IDocumentModel {
export function isPageSchema(obj: any): obj is IPublicTypePageSchema { export function isPageSchema(obj: any): obj is IPublicTypePageSchema {
return obj?.componentName === 'Page'; return obj?.componentName === 'Page';
} }
export interface IDocumentModel extends DocumentModel {}

View File

@ -1,7 +1,7 @@
import { Component } from 'react'; import { Component } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { observer } from '@alilc/lowcode-editor-core'; import { observer } from '@alilc/lowcode-editor-core';
import { DocumentModel, IDocumentModel } from './document-model'; import type { IDocumentModel } from './document-model';
import { BuiltinSimulatorHostView } from '../builtin-simulator'; import { BuiltinSimulatorHostView } from '../builtin-simulator';
@observer @observer

View File

@ -1,7 +1,7 @@
import { reaction, untracked, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { reaction, untracked, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
import { IPublicTypeNodeSchema, IPublicModelHistory, IPublicTypeDisposable } from '@alilc/lowcode-types'; import { IPublicTypeNodeSchema, IPublicModelHistory, IPublicTypeDisposable } from '@alilc/lowcode-types';
import { Logger } from '@alilc/lowcode-utils'; import { Logger } from '@alilc/lowcode-utils';
import { IDocumentModel } from '../designer'; import type { IDocumentModel } from '../designer';
const logger = new Logger({ level: 'warn', bizName: 'history' }); const logger = new Logger({ level: 'warn', bizName: 'history' });

View File

@ -1,5 +1,5 @@
import { obx, computed, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; 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 { IPublicTypeNodeData, IPublicModelNodeChildren, IPublicEnumTransformStage, IPublicTypeDisposable } from '@alilc/lowcode-types';
import { shallowEqual, compatStage, isNodeSchema } from '@alilc/lowcode-utils'; import { shallowEqual, compatStage, isNodeSchema } from '@alilc/lowcode-utils';
import { foreachReverse } from '../../utils/tree'; import { foreachReverse } from '../../utils/tree';
@ -7,66 +7,15 @@ import { NodeRemoveOptions } from '../../types';
export interface IOnChangeOptions { export interface IOnChangeOptions {
type: string; type: string;
node: Node; node: INode;
} }
export interface INodeChildren extends Omit<IPublicModelNodeChildren<INode>, export class NodeChildren implements Omit<IPublicModelNodeChildren<INode>,
'importSchema' | 'importSchema' |
'exportSchema' | 'exportSchema' |
'isEmpty' | 'isEmpty' |
'notEmpty' 'notEmpty'
> { > {
children: INode[];
get owner(): INode;
get length(): number;
unlinkChild(node: INode): void;
/**
*
*/
internalDelete(
node: INode,
purge: boolean,
useMutator: boolean,
options: NodeRemoveOptions
): boolean;
/**
*
*/
internalInsert(node: INode, at?: number | null, useMutator?: boolean): void;
import(data?: IPublicTypeNodeData | IPublicTypeNodeData[], checkId?: boolean): void;
/**
* schema
*/
export(stage: IPublicEnumTransformStage): IPublicTypeNodeData[];
/** following methods are overriding super interface, using different param types */
/** overriding methods start */
forEach(fn: (item: INode, index: number) => void): void;
/**
*
*/
get(index: number): INode | null;
isEmpty(): boolean;
notEmpty(): boolean;
internalInitParent(): void;
onChange(fn: (info?: IOnChangeOptions) => void): IPublicTypeDisposable;
/** overriding methods end */
}
export class NodeChildren implements INodeChildren {
@obx.shallow children: INode[]; @obx.shallow children: INode[];
private emitter: IEventBus = createModuleEventBus('NodeChildren'); private emitter: IEventBus = createModuleEventBus('NodeChildren');
@ -99,11 +48,10 @@ export class NodeChildren implements INodeChildren {
constructor( constructor(
readonly owner: INode, readonly owner: INode,
data: IPublicTypeNodeData | IPublicTypeNodeData[], data: IPublicTypeNodeData | IPublicTypeNodeData[],
options: any = {},
) { ) {
makeObservable(this); makeObservable(this);
this.children = (Array.isArray(data) ? data : [data]).filter(child => !!child).map((child) => { this.children = (Array.isArray(data) ? data : [data]).filter(child => !!child).map((child) => {
return this.owner.document?.createNode(child, options.checkId); return this.owner.document?.createNode(child);
}); });
} }
@ -132,7 +80,7 @@ export class NodeChildren implements INodeChildren {
const originChildren = this.children.slice(); const originChildren = this.children.slice();
this.children.forEach((child) => child.internalSetParent(null)); this.children.forEach((child) => child.internalSetParent(null));
const children = new Array<Node>(data.length); const children = new Array<INode>(data.length);
for (let i = 0, l = data.length; i < l; i++) { for (let i = 0, l = data.length; i < l; i++) {
const child = originChildren[i]; const child = originChildren[i];
const item = data[i]; const item = data[i];
@ -142,9 +90,17 @@ export class NodeChildren implements INodeChildren {
node = child; node = child;
node.import(item); node.import(item);
} else { } else {
node = this.owner.document?.createNode(item, checkId); node = this.owner.document?.createNode(item);
child?.purge();
} }
children[i] = node;
if (node) {
children[i] = node;
}
}
for (let i = data.length; i < originChildren.length; i++) {
originChildren[i].purge();
} }
this.children = children; this.children = children;
@ -176,13 +132,13 @@ export class NodeChildren implements INodeChildren {
/** /**
* *
*/ */
purge(useMutator = true) { purge() {
if (this.purged) { if (this.purged) {
return; return;
} }
this.purged = true; this.purged = true;
this.children.forEach((child) => { this.children.forEach((child) => {
child.purge(useMutator); child.purge();
}); });
} }
@ -212,15 +168,15 @@ export class NodeChildren implements INodeChildren {
node.internalPurgeStart(); node.internalPurgeStart();
if (node.isParentalNode) { if (node.isParentalNode) {
foreachReverse( foreachReverse(
node.children, node.children!,
(subNode: Node) => { (subNode: INode) => {
subNode.remove(useMutator, purge, options); subNode.remove(useMutator, purge, options);
}, },
(iterable, idx) => (iterable as NodeChildren).get(idx), (iterable, idx) => (iterable as NodeChildren).get(idx),
); );
foreachReverse( foreachReverse(
node.slots, node.slots,
(slotNode: Node) => { (slotNode: INode) => {
slotNode.remove(useMutator, purge); slotNode.remove(useMutator, purge);
}, },
(iterable, idx) => (iterable as [])[idx], (iterable, idx) => (iterable as [])[idx],
@ -351,10 +307,17 @@ export class NodeChildren implements INodeChildren {
* *
*/ */
splice(start: number, deleteCount: number, node?: INode): INode[] { splice(start: number, deleteCount: number, node?: INode): INode[] {
let removedNode;
if (node) { if (node) {
return this.children.splice(start, deleteCount, node); removedNode = this.children.splice(start, deleteCount, node);
node.internalSetParent(this.owner);
} else {
removedNode = this.children.splice(start, deleteCount);
} }
return this.children.splice(start, deleteCount);
removedNode.forEach(d => d?.purge());
return removedNode;
} }
/** /**
@ -459,11 +422,11 @@ export class NodeChildren implements INodeChildren {
const items = adder(this.children); const items = adder(this.children);
if (items && items.length > 0) { if (items && items.length > 0) {
items.forEach((child: IPublicTypeNodeData) => { items.forEach((child: IPublicTypeNodeData) => {
const node: INode = this.owner.document?.createNode(child); const node: INode | null = this.owner.document?.createNode(child);
this.children.push(node); node && this.children.push(node);
node.internalSetParent(this.owner); node?.internalSetParent(this.owner);
/* istanbul ignore next */ /* istanbul ignore next */
const editor = node.document?.designer.editor; const editor = node?.document?.designer.editor;
editor?.eventBus.emit('node.add', { node }); editor?.eventBus.emit('node.add', { node });
}); });
changed = true; changed = true;
@ -504,7 +467,7 @@ export class NodeChildren implements INodeChildren {
try { try {
callbacks?.onSubtreeModified.call( callbacks?.onSubtreeModified.call(
node.internalToShellNode(), node.internalToShellNode(),
owner.internalToShellNode(), owner.internalToShellNode()!,
options, options,
); );
} catch (e) { } catch (e) {
@ -517,3 +480,5 @@ export class NodeChildren implements INodeChildren {
} }
} }
} }
export interface INodeChildren extends NodeChildren {}

View File

@ -13,17 +13,16 @@ import {
GlobalEvent, GlobalEvent,
IPublicTypeComponentAction, IPublicTypeComponentAction,
IPublicModelNode, IPublicModelNode,
IPublicModelExclusiveGroup,
IPublicEnumTransformStage, IPublicEnumTransformStage,
IPublicTypeDisposable, IPublicTypeDisposable,
IBaseModelNode, IBaseModelNode,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { compatStage, isDOMText, isJSExpression, isNode, isNodeSchema } from '@alilc/lowcode-utils'; 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 { Props, getConvertedExtraKey, IProps } from './props/props';
import type { IDocumentModel } from '../document-model'; import type { IDocumentModel } from '../document-model';
import { NodeChildren, INodeChildren } from './node-children'; 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 type { IComponentMeta } from '../../component-meta';
import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group'; import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group';
import type { IExclusiveGroup } from './exclusive-group'; import type { IExclusiveGroup } from './exclusive-group';
@ -37,132 +36,7 @@ export interface NodeStatus {
inPlaceEditing: boolean; inPlaceEditing: boolean;
} }
export interface IBaseNode<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> extends Omit<IBaseModelNode< export interface IBaseNode extends Node {}
IDocumentModel,
IBaseNode,
INodeChildren,
IComponentMeta,
ISettingTopEntry,
IProps,
IProp,
IExclusiveGroup
>,
'isRoot' |
'isPage' |
'isComponent' |
'isModal' |
'isSlot' |
'isParental' |
'isLeaf' |
'settingEntry' |
// 在内部的 node 模型中不存在
'getExtraPropValue' |
'setExtraPropValue' |
'exportSchema' |
'visible' |
'importSchema' |
// 内外实现有差异
'isContainer' |
'isEmpty'
> {
isNode: boolean;
get componentMeta(): IComponentMeta;
get settingEntry(): ISettingTopEntry;
get isPurged(): boolean;
get index(): number | undefined;
get isPurging(): boolean;
getId(): string;
getParent(): INode | null;
/**
* 使
* @param useMutator
*/
internalSetParent(parent: INode | null, useMutator?: boolean): void;
setConditionGroup(grp: IPublicModelExclusiveGroup | string | null): void;
internalToShellNode(): IPublicModelNode | null;
internalPurgeStart(): void;
unlinkSlot(slotNode: INode): void;
/**
* schema
*/
export<T = Schema>(stage: IPublicEnumTransformStage, options?: any): T;
emitPropChange(val: IPublicTypePropChangeOptions): void;
import(data: Schema, checkId?: boolean): void;
internalSetSlotFor(slotFor: Prop | null | undefined): void;
addSlot(slotNode: INode): void;
onVisibleChange(func: (flag: boolean) => any): () => void;
getSuitablePlace(node: INode, ref: any): any;
onChildrenChange(fn: (param?: { type: string; node: INode }) => void): IPublicTypeDisposable | undefined;
onPropChange(func: (info: IPublicTypePropChangeOptions) => void): IPublicTypeDisposable;
isModal(): boolean;
isRoot(): boolean;
isPage(): boolean;
isComponent(): boolean;
isSlot(): boolean;
isParental(): boolean;
isLeaf(): boolean;
isContainer(): boolean;
isEmpty(): boolean;
remove(
useMutator?: boolean,
purge?: boolean,
options?: NodeRemoveOptions,
): void;
didDropIn(dragment: INode): void;
didDropOut(dragment: INode): void;
purge(): void;
removeSlot(slotNode: INode): boolean;
setVisible(flag: boolean): void;
getVisible(): boolean;
getChildren(): INodeChildren | null;
clearPropValue(path: string | number): void;
setProps(props?: IPublicTypePropsMap | IPublicTypePropsList | Props | null): void;
mergeProps(props: IPublicTypePropsMap): void;
/** 是否可以选中 */
canSelect(): boolean;
}
/** /**
* *
@ -212,7 +86,34 @@ export interface IBaseNode<Schema extends IPublicTypeNodeSchema = IPublicTypeNod
* isLocked * isLocked
* hidden * hidden
*/ */
export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> implements IBaseNode { export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> implements Omit<IBaseModelNode<
IDocumentModel,
IBaseNode,
INodeChildren,
IComponentMeta,
ISettingTopEntry,
IProps,
IProp,
IExclusiveGroup
>,
'isRoot' |
'isPage' |
'isComponent' |
'isModal' |
'isSlot' |
'isParental' |
'isLeaf' |
'settingEntry' |
// 在内部的 node 模型中不存在
'getExtraPropValue' |
'setExtraPropValue' |
'exportSchema' |
'visible' |
'importSchema' |
// 内外实现有差异
'isContainer' |
'isEmpty'
> {
private emitter: IEventBus; private emitter: IEventBus;
/** /**
@ -296,7 +197,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
isInited = false; isInited = false;
_settingEntry: ISettingTopEntry; _settingEntry?: ISettingTopEntry;
get settingEntry(): ISettingTopEntry { get settingEntry(): ISettingTopEntry {
if (this._settingEntry) return this._settingEntry; if (this._settingEntry) return this._settingEntry;
@ -594,7 +495,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
} }
} }
internalSetSlotFor(slotFor: Prop | null | undefined) { internalSetSlotFor(slotFor: IProp | null | undefined) {
this._slotFor = slotFor; this._slotFor = slotFor;
} }
@ -690,7 +591,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
} }
/* istanbul ignore next */ /* istanbul ignore next */
setConditionGroup(grp: IPublicModelExclusiveGroup | string | null) { setConditionGroup(grp: IExclusiveGroup | string | null) {
let _grp: IExclusiveGroup | null = null; let _grp: IExclusiveGroup | null = null;
if (!grp) { if (!grp) {
this.getExtraProp('conditionGroup', false)?.remove(); this.getExtraProp('conditionGroup', false)?.remove();
@ -1086,7 +987,8 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
this.autoruns?.forEach((dispose) => dispose()); this.autoruns?.forEach((dispose) => dispose());
this.props.purge(); this.props.purge();
this.settingEntry?.purge(); this.settingEntry?.purge();
// this.document.destroyNode(this); this.children?.purge();
this._settingEntry = undefined;
} }
internalPurgeStart() { internalPurgeStart() {
@ -1389,11 +1291,11 @@ export interface LeafNode extends Node {
export type IPublicTypePropChangeOptions = Omit<GlobalEvent.Node.Prop.ChangeOptions, 'node'>; export type IPublicTypePropChangeOptions = Omit<GlobalEvent.Node.Prop.ChangeOptions, 'node'>;
export type ISlotNode = IBaseNode<IPublicTypeSlotSchema>; export interface ISlotNode extends Node<IPublicTypeSlotSchema> {}
export type IPageNode = IBaseNode<IPublicTypePageSchema>; export interface IPageNode extends Node<IPublicTypePageSchema> {}
export type IComponentNode = IBaseNode<IPublicTypeComponentSchema>; export interface IComponentNode extends Node<IPublicTypeComponentSchema> {}
export type IRootNode = IPageNode | IComponentNode; export interface IRootNode extends Node<IPublicTypePageSchema | IPublicTypeComponentSchema> {}
export type INode = IPageNode | ISlotNode | IComponentNode | IRootNode; export interface INode extends Node<IPublicTypePageSchema | IPublicTypeSlotSchema | IPublicTypeComponentSchema | IPublicTypeNodeSchema> {}
export function isRootNode(node: INode): node is IRootNode { export function isRootNode(node: INode): node is IRootNode {
return node && node.isRootNode; return node && node.isRootNode;
@ -1505,7 +1407,7 @@ export function insertChild(
export function insertChildren( export function insertChildren(
container: INode, container: INode,
nodes: INode[] | IPublicTypeNodeData[], nodes: INode[] | IPublicTypeNodeData[] | IPublicModelNode[],
at?: number | null, at?: number | null,
copy?: boolean, copy?: boolean,
): INode[] { ): INode[] {

View File

@ -1,6 +1,6 @@
import { untracked, computed, obx, engineConfig, action, makeObservable, mobx, runInAction } from '@alilc/lowcode-editor-core'; import { untracked, computed, obx, engineConfig, action, makeObservable, mobx, runInAction } from '@alilc/lowcode-editor-core';
import { GlobalEvent, IPublicEnumTransformStage } from '@alilc/lowcode-types'; import { GlobalEvent, IPublicEnumTransformStage } from '@alilc/lowcode-types';
import type { IPublicTypeCompositeValue, IPublicTypeJSSlot, IPublicTypeSlotSchema, IPublicModelProp } from '@alilc/lowcode-types'; import type { IPublicTypeCompositeValue, IPublicTypeJSSlot, IPublicTypeSlotSchema, IPublicModelProp, IPublicTypeNodeData } from '@alilc/lowcode-types';
import { uniqueId, isPlainObject, hasOwnProperty, compatStage, isJSExpression, isJSSlot, isNodeSchema } from '@alilc/lowcode-utils'; import { uniqueId, isPlainObject, hasOwnProperty, compatStage, isJSExpression, isJSSlot, isNodeSchema } from '@alilc/lowcode-utils';
import { valueToSource } from './value-to-source'; import { valueToSource } from './value-to-source';
import { IPropParent } from './props'; import { IPropParent } from './props';
@ -227,7 +227,7 @@ export class Prop implements IProp, IPropParent {
constructor( constructor(
public parent: IPropParent, public parent: IPropParent,
value: IPublicTypeCompositeValue | UNSET = UNSET, value: IPublicTypeCompositeValue | IPublicTypeNodeData | IPublicTypeNodeData[] | UNSET = UNSET,
key?: string | number, key?: string | number,
spread = false, spread = false,
options = {}, options = {},
@ -351,7 +351,7 @@ export class Prop implements IProp, IPropParent {
* set value, val should be JSON Object * set value, val should be JSON Object
*/ */
@action @action
setValue(val: IPublicTypeCompositeValue) { setValue(val: IPublicTypeCompositeValue | IPublicTypeNodeData | IPublicTypeNodeData[]) {
if (val === this._value) return; if (val === this._value) return;
const oldValue = this._value; const oldValue = this._value;
this._value = val; this._value = val;

View File

@ -37,30 +37,9 @@ export interface IPropParent {
delete(prop: IProp): void; delete(prop: IProp): void;
} }
export interface IProps extends Omit<IBaseModelProps<IProp>, | 'getExtraProp' | 'getExtraPropValue' | 'setExtraPropValue' | 'node'>, IPropParent { export interface IProps extends Props {}
/** export class Props implements Omit<IBaseModelProps<IProp>, | 'getExtraProp' | 'getExtraPropValue' | 'setExtraPropValue' | 'node'>, IPropParent {
* props node
*/
getNode(): INode;
get(path: string, createIfNone?: boolean): IProp | null;
export(stage?: IPublicEnumTransformStage): {
props?: IPublicTypePropsMap | IPublicTypePropsList;
extras?: ExtrasObject;
};
merge(value: IPublicTypePropsMap, extras?: IPublicTypePropsMap): void;
purge(): void;
query(path: string, createIfNone: boolean): IProp | null;
import(value?: IPublicTypePropsMap | IPublicTypePropsList | null, extras?: ExtrasObject): void;
}
export class Props implements IProps, IPropParent {
readonly id = uniqueId('props'); readonly id = uniqueId('props');
@obx.shallow private items: IProp[] = []; @obx.shallow private items: IProp[] = [];

View File

@ -20,6 +20,7 @@ import {
IPublicEnumPluginRegisterLevel, IPublicEnumPluginRegisterLevel,
IPublicModelWindow, IPublicModelWindow,
IPublicApiCommonUI, IPublicApiCommonUI,
IPublicApiCommand,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { import {
IPluginContextOptions, IPluginContextOptions,
@ -48,6 +49,7 @@ export default class PluginContext implements
editorWindow: IPublicModelWindow; editorWindow: IPublicModelWindow;
commonUI: IPublicApiCommonUI; commonUI: IPublicApiCommonUI;
isPluginRegisteredInWorkspace: false; isPluginRegisteredInWorkspace: false;
command: IPublicApiCommand;
constructor( constructor(
options: IPluginContextOptions, options: IPluginContextOptions,

View File

@ -68,7 +68,7 @@ export interface IProject extends Omit<IBaseApiProject<
onCurrentDocumentChange(fn: (doc: IDocumentModel) => void): () => void; onCurrentDocumentChange(fn: (doc: IDocumentModel) => void): () => void;
onSimulatorReady(fn: (args: any) => void): () => void; onSimulatorReady(fn: (simulator: ISimulatorHost) => void): () => void;
onRendererReady(fn: () => void): () => void; onRendererReady(fn: () => void): () => void;

View File

@ -1,8 +1,9 @@
import '../../fixtures/window'; 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 { Node } from '../../../src/document/node/node';
import { Designer } from '../../../src/designer/designer'; import { Designer } from '../../../src/designer/designer';
import settingSchema from '../../fixtures/schema/setting'; import settingSchema from '../../fixtures/schema/setting';
import { SettingTopEntry } from '../../../src/designer/setting/setting-top-entry';
import divMeta from '../../fixtures/component-metadata/div'; import divMeta from '../../fixtures/component-metadata/div';
import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory';
@ -109,6 +110,26 @@ describe('setting-top-entry 测试', () => {
expect(settingEntry.items).toHaveLength(0); 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 兼容测试', () => { it('vision 兼容测试', () => {
designer.createComponentMeta(divMeta); designer.createComponentMeta(divMeta);
designer.project.open(settingSchema); designer.project.open(settingSchema);

View File

@ -111,6 +111,16 @@ describe('NodeChildren 方法测试', () => {
expect(children.length).toBe(2); 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', () => { it('map', () => {
const firstBtn = doc.getNode('node_k1ow3cbn')!; const firstBtn = doc.getNode('node_k1ow3cbn')!;
const { children } = firstBtn.parent!; const { children } = firstBtn.parent!;

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-editor-core", "name": "@alilc/lowcode-editor-core",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "Core Api for Ali lowCode engine", "description": "Core Api for Ali lowCode engine",
"license": "MIT", "license": "MIT",
"main": "lib/index.js", "main": "lib/index.js",
@ -16,8 +16,8 @@
}, },
"dependencies": { "dependencies": {
"@alifd/next": "^1.19.16", "@alifd/next": "^1.19.16",
"@alilc/lowcode-types": "1.3.2", "@alilc/lowcode-types": "1.3.3-beta.3",
"@alilc/lowcode-utils": "1.3.2", "@alilc/lowcode-utils": "1.3.3-beta.3",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"debug": "^4.1.1", "debug": "^4.1.1",
"intl-messageformat": "^9.3.1", "intl-messageformat": "^9.3.1",

View File

@ -1,18 +1,12 @@
import { IPublicApiCommand, IPublicEnumTransitionType, IPublicModelPluginContext, IPublicTypeCommand, IPublicTypeCommandHandlerArgs, IPublicTypeListCommand } from '@alilc/lowcode-types'; import { IPublicApiCommand, IPublicEnumTransitionType, IPublicModelPluginContext, IPublicTypeCommand, IPublicTypeCommandHandlerArgs, IPublicTypeListCommand } from '@alilc/lowcode-types';
import { checkPropTypes } from '@alilc/lowcode-utils'; import { checkPropTypes } from '@alilc/lowcode-utils';
export interface ICommand extends Omit<IPublicApiCommand, 'registerCommand' | 'batchExecuteCommand'> { export interface ICommand extends Command {}
registerCommand(command: IPublicTypeCommand, options?: {
commandScope?: string;
}): void;
batchExecuteCommand(commands: { name: string; args: IPublicTypeCommandHandlerArgs }[], pluginContext?: IPublicModelPluginContext): void;
}
export interface ICommandOptions { export interface ICommandOptions {
commandScope?: string; commandScope?: string;
} }
export class Command implements ICommand { export class Command implements Omit<IPublicApiCommand, 'registerCommand' | 'batchExecuteCommand'> {
private commands: Map<string, IPublicTypeCommand> = new Map(); private commands: Map<string, IPublicTypeCommand> = new Map();
private commandErrors: Function[] = []; private commandErrors: Function[] = [];

View File

@ -1,6 +1,6 @@
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { globalContext } from './di'; 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 { interface KeyMap {
[key: number]: string; [key: number]: string;
@ -339,11 +339,10 @@ function fireCallback(callback: IPublicTypeHotkeyCallback, e: KeyboardEvent, com
} }
} }
export interface IHotKey extends Omit<IPublicApiHotkey, 'bind' | 'callbacks'> { export interface IHotKey extends Hotkey {
activate(activate: boolean): void;
} }
export class Hotkey implements IHotKey { export class Hotkey implements Omit<IPublicApiHotkey, 'bind' | 'callbacks'> {
callBacks: IPublicTypeHotkeyCallbacks = {}; callBacks: IPublicTypeHotkeyCallbacks = {};
private directMap: HotkeyDirectMap = {}; private directMap: HotkeyDirectMap = {};
@ -368,7 +367,7 @@ export class Hotkey implements IHotKey {
this.isActivate = activate; this.isActivate = activate;
} }
mount(window: Window) { mount(window: Window): IPublicTypeDisposable {
const { document } = window; const { document } = window;
const handleKeyEvent = this.handleKeyEvent.bind(this); const handleKeyEvent = this.handleKeyEvent.bind(this);
document.addEventListener('keypress', handleKeyEvent, false); document.addEventListener('keypress', handleKeyEvent, false);

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-editor-skeleton", "name": "@alilc/lowcode-editor-skeleton",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "alibaba lowcode editor skeleton", "description": "alibaba lowcode editor skeleton",
"main": "lib/index.js", "main": "lib/index.js",
"module": "es/index.js", "module": "es/index.js",
@ -19,10 +19,10 @@
], ],
"dependencies": { "dependencies": {
"@alifd/next": "^1.20.12", "@alifd/next": "^1.20.12",
"@alilc/lowcode-designer": "1.3.2", "@alilc/lowcode-designer": "1.3.3-beta.3",
"@alilc/lowcode-editor-core": "1.3.2", "@alilc/lowcode-editor-core": "1.3.3-beta.3",
"@alilc/lowcode-types": "1.3.2", "@alilc/lowcode-types": "1.3.3-beta.3",
"@alilc/lowcode-utils": "1.3.2", "@alilc/lowcode-utils": "1.3.3-beta.3",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"react": "^16.8.1", "react": "^16.8.1",
"react-dom": "^16.8.1" "react-dom": "^16.8.1"

View File

@ -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'; import { Editor, obx, computed, makeObservable, action, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
function generateSessionId(nodes: Node[]) { function generateSessionId(nodes: INode[]) {
return nodes return nodes
.map((node) => node.id) .map((node) => node.id)
.sort() .sort()
@ -29,7 +29,11 @@ export class SettingsMain {
private disposeListener: () => void; private disposeListener: () => void;
private designer?: Designer; private _designer?: IDesigner;
get designer(): IDesigner | undefined {
return this._designer;
}
constructor(readonly editor: Editor) { constructor(readonly editor: Editor) {
makeObservable(this); makeObservable(this);
@ -49,12 +53,12 @@ export class SettingsMain {
this.editor.removeListener('designer.selection.change', setupSelection); this.editor.removeListener('designer.selection.change', setupSelection);
}; };
const designer = await this.editor.onceGot('designer'); const designer = await this.editor.onceGot('designer');
this.designer = designer; this._designer = designer;
setupSelection(designer.currentSelection); setupSelection(designer.currentSelection);
} }
@action @action
private setup(nodes: Node[]) { private setup(nodes: INode[]) {
// check nodes change // check nodes change
const sessionId = generateSessionId(nodes); const sessionId = generateSessionId(nodes);
if (sessionId === this._sessionId) { if (sessionId === this._sessionId) {
@ -66,15 +70,15 @@ export class SettingsMain {
return; return;
} }
if (!this.designer) { if (!this._designer) {
this.designer = nodes[0].document.designer; this._designer = nodes[0].document.designer;
} }
// 当节点只有一个时,复用 node 上挂载的 settingEntry不会产生平行的两个实例这样在整个系统中对 // 当节点只有一个时,复用 node 上挂载的 settingEntry不会产生平行的两个实例这样在整个系统中对
// 某个节点操作的 SettingTopEntry 只有一个实例,后续的 getProp() 也会拿到相同的 SettingField 实例 // 某个节点操作的 SettingTopEntry 只有一个实例,后续的 getProp() 也会拿到相同的 SettingField 实例
if (nodes.length === 1) { if (nodes.length === 1) {
this._settings = nodes[0].settingEntry; this._settings = nodes[0].settingEntry;
} else { } else {
this._settings = this.designer.createSettingEntry(nodes); this._settings = this._designer.createSettingEntry(nodes);
} }
} }

View File

@ -1,9 +1,9 @@
import { Component, MouseEvent, Fragment, ReactNode } from 'react'; import { Component, MouseEvent, Fragment, ReactNode } from 'react';
import { shallowIntl, observer, obx, engineConfig, runInAction } from '@alilc/lowcode-editor-core'; 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 { Skeleton, Stage } from '@alilc/lowcode-editor-skeleton';
import { IPublicApiSetters, IPublicTypeCustomView, IPublicTypeDynamicProps } from '@alilc/lowcode-types'; 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 { createField } from '../field';
import PopupService, { PopupPipe } from '../popup'; import PopupService, { PopupPipe } from '../popup';
import { SkeletonContext } from '../../context'; import { SkeletonContext } from '../../context';

View File

@ -1,14 +1,14 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Tab, Breadcrumb } from '@alifd/next'; import { Tab, Breadcrumb } from '@alifd/next';
import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@alilc/lowcode-editor-core'; import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@alilc/lowcode-editor-core';
import { Node, SettingField, isSettingField, INode } from '@alilc/lowcode-designer'; import type { ISettingField, INode } from '@alilc/lowcode-designer';
import classNames from 'classnames'; import classNames from 'classnames';
import { SettingsMain } from './main'; import { SettingsMain } from './main';
import { SettingsPane } from './settings-pane'; import { SettingsPane } from './settings-pane';
import { StageBox } from '../stage-box'; import { StageBox } from '../stage-box';
import { SkeletonContext } from '../../context'; import { SkeletonContext } from '../../context';
import { intl } from '../../locale'; import { intl } from '../../locale';
import { createIcon } from '@alilc/lowcode-utils'; import { createIcon, isSettingField } from '@alilc/lowcode-utils';
interface ISettingsPrimaryPaneProps { interface ISettingsPrimaryPaneProps {
engineEditor: Editor; engineEditor: Editor;
@ -53,8 +53,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
} }
renderBreadcrumb() { renderBreadcrumb() {
const { settings, editor } = this.main; const { settings, editor, designer } = this.main;
// const shouldIgnoreRoot = config.props?.ignoreRoot;
const { shouldIgnoreRoot } = this.state; const { shouldIgnoreRoot } = this.state;
if (!settings) { if (!settings) {
return null; return null;
@ -73,10 +72,9 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
); );
} }
const designer = editor.get('designer');
const current = designer?.currentSelection?.getNodes()?.[0]; const current = designer?.currentSelection?.getNodes()?.[0];
let node: INode | null = settings.first; let node: INode | null = settings.first;
const focusNode = node.document?.focusNode; const focusNode = node?.document?.focusNode;
const items = []; const items = [];
let l = 3; let l = 3;
@ -136,7 +134,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
render() { render() {
const { settings } = this.main; const { settings } = this.main;
const editor = this.props.engineEditor; const editor = this.props.engineEditor;
if (!settings) { if (!settings || !settings.first) {
// 未选中节点,提示选中 或者 显示根节点设置 // 未选中节点,提示选中 或者 显示根节点设置
return ( return (
<div className="lc-settings-main"> <div className="lc-settings-main">
@ -202,7 +200,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
} }
let matched = false; let matched = false;
const tabs = (items as SettingField[]).map((field) => { const tabs = (items as ISettingField[]).map((field) => {
if (this._activeKey === field.name) { if (this._activeKey === field.name) {
matched = true; matched = true;
} }
@ -235,7 +233,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
</Tab.Item> </Tab.Item>
); );
}); });
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', { const className = classNames('lc-settings-main', {
'lc-settings-hide-tabs': 'lc-settings-hide-tabs':
@ -261,9 +259,10 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
} }
} }
function hoverNode(node: Node, flag: boolean) { function hoverNode(node: INode, flag: boolean) {
node.hover(flag); node.hover(flag);
} }
function selectNode(node: Node) {
function selectNode(node: INode) {
node?.select(); node?.select();
} }

View File

@ -44,72 +44,27 @@ export enum SkeletonEvents {
WIDGET_ENABLE = 'skeleton.widget.enable', WIDGET_ENABLE = 'skeleton.widget.enable',
} }
export interface ISkeleton extends Omit<IPublicApiSkeleton, export interface ISkeleton extends Skeleton {}
'showPanel' |
'hidePanel' | export class Skeleton implements Omit<IPublicApiSkeleton,
'showWidget' | 'showPanel' |
'enableWidget' | 'hidePanel' |
'hideWidget' | 'showWidget' |
'disableWidget' | 'enableWidget' |
'showArea' | 'hideWidget' |
'onShowPanel' | 'disableWidget' |
'onHidePanel' | 'showArea' |
'onShowWidget' | 'onShowPanel' |
'onHideWidget' | 'onHidePanel' |
'remove' | 'onShowWidget' |
'hideArea' | 'onHideWidget' |
'add' 'remove' |
'hideArea' |
'add' |
'getAreaItems' |
'onDisableWidget' |
'onEnableWidget'
> { > {
editor: IEditor;
readonly leftArea: Area<DockConfig | PanelDockConfig | DialogDockConfig>;
readonly topArea: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>;
readonly subTopArea: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>;
readonly toolbar: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>;
readonly leftFixedArea: Area<IPublicTypePanelConfig, Panel>;
readonly leftFloatArea: Area<IPublicTypePanelConfig, Panel>;
readonly rightArea: Area<IPublicTypePanelConfig, Panel>;
readonly mainArea: Area<WidgetConfig | IPublicTypePanelConfig, Widget | Panel>;
readonly bottomArea: Area<IPublicTypePanelConfig, Panel>;
readonly stages: Area<StageConfig, Stage>;
readonly widgets: IWidget[];
readonly focusTracker: FocusTracker;
getPanel(name: string): Panel | undefined;
getWidget(name: string): IWidget | undefined;
buildFromConfig(config?: EditorConfig, components?: PluginClassSet): void;
createStage(config: any): string | undefined;
getStage(name: string): Stage | null;
createContainer(
name: string,
handle: (item: any) => any,
exclusive?: boolean,
checkVisible?: () => boolean,
defaultSetCurrent?: boolean,
): WidgetContainer;
createPanel(config: IPublicTypePanelConfig): Panel;
add(config: IPublicTypeSkeletonConfig, extraConfig?: Record<string, any>): IWidget | Widget | Panel | Stage | Dock | PanelDock | undefined;
}
export class Skeleton implements ISkeleton {
private panels = new Map<string, Panel>(); private panels = new Map<string, Panel>();
private configTransducers: IPublicTypeConfigTransducer[] = []; private configTransducers: IPublicTypeConfigTransducer[] = [];
@ -431,7 +386,7 @@ export class Skeleton implements ISkeleton {
} }
const { content, ...restConfig } = config; const { content, ...restConfig } = config;
if (content) { if (content) {
if (isPlainObject(content) && !isValidElement(content)) { if (isPlainObject<IPublicTypePanelConfig>(content) && !isValidElement(content)) {
Object.keys(content).forEach((key) => { Object.keys(content).forEach((key) => {
if (/props$/i.test(key) && restConfig[key]) { if (/props$/i.test(key) && restConfig[key]) {
restConfig[key] = { restConfig[key] = {

View File

@ -160,15 +160,20 @@ 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) 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) > 强烈推荐阅读 [《提问的智慧》](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)
关于提交 PR 关于提交 PR
请将目标合并分支设置为 **develop**,不要指定 **main** 分支在发布正式版本后develop 分支将会合入 main 分支。 请将目标合并分支设置为 **develop**,不要指定 **main** 分支在发布正式版本后develop 分支将会合入 main 分支。
## ⭐️ Star 历史
<a href="https://star-history.com/#alibaba/lowcode-engine">
<img src="https://api.star-history.com/svg?repos=alibaba/lowcode-engine&type=Date" alt="Star History Chart" width="100%" />
</a>
## ❤️ 致谢 ## ❤️ 致谢
感谢所有为引擎项目贡献力量的同学们~ 感谢所有为引擎项目贡献力量的同学们~

View File

@ -160,9 +160,8 @@ After lowcode-engine is started, several umd files are provided, which can be de
## 🤝 Participation ## 🤝 Participation
Please read first: 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) 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)) > 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))

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-engine", "name": "@alilc/lowcode-engine",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系",
"main": "lib/engine-core.js", "main": "lib/engine-core.js",
"module": "es/engine-core.js", "module": "es/engine-core.js",
@ -19,16 +19,16 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@alifd/next": "^1.19.12", "@alifd/next": "^1.19.12",
"@alilc/lowcode-designer": "1.3.2", "@alilc/lowcode-designer": "1.3.3-beta.3",
"@alilc/lowcode-editor-core": "1.3.2", "@alilc/lowcode-editor-core": "1.3.3-beta.3",
"@alilc/lowcode-editor-skeleton": "1.3.2", "@alilc/lowcode-editor-skeleton": "1.3.3-beta.3",
"@alilc/lowcode-engine-ext": "^1.0.0", "@alilc/lowcode-engine-ext": "^1.0.0",
"@alilc/lowcode-plugin-command": "1.3.2", "@alilc/lowcode-plugin-command": "1.3.3-beta.3",
"@alilc/lowcode-plugin-designer": "1.3.2", "@alilc/lowcode-plugin-designer": "1.3.3-beta.3",
"@alilc/lowcode-plugin-outline-pane": "1.3.2", "@alilc/lowcode-plugin-outline-pane": "1.3.3-beta.3",
"@alilc/lowcode-shell": "1.3.2", "@alilc/lowcode-shell": "1.3.3-beta.3",
"@alilc/lowcode-utils": "1.3.2", "@alilc/lowcode-utils": "1.3.3-beta.3",
"@alilc/lowcode-workspace": "1.3.2", "@alilc/lowcode-workspace": "1.3.3-beta.3",
"react": "^16.8.1", "react": "^16.8.1",
"react-dom": "^16.8.1" "react-dom": "^16.8.1"
}, },

View File

@ -229,7 +229,7 @@ export async function init(
document.body.appendChild(engineContainer); document.body.appendChild(engineContainer);
} else { } else {
engineOptions = options; engineOptions = options;
engineContainer = container; engineContainer = container!;
if (!container) { if (!container) {
engineContainer = document.createElement('div'); engineContainer = document.createElement('div');
engineContainer.id = 'engine'; engineContainer.id = 'engine';

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-ignitor", "name": "@alilc/lowcode-ignitor",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "点火器bootstrap lce project", "description": "点火器bootstrap lce project",
"main": "lib/index.js", "main": "lib/index.js",
"private": true, "private": true,

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-plugin-command", "name": "@alilc/lowcode-plugin-command",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "> TODO: description", "description": "> TODO: description",
"author": "liujuping <liujup@foxmail.com>", "author": "liujuping <liujup@foxmail.com>",
"homepage": "https://github.com/alibaba/lowcode-engine#readme", "homepage": "https://github.com/alibaba/lowcode-engine#readme",
@ -30,8 +30,8 @@
"url": "https://github.com/alibaba/lowcode-engine/issues" "url": "https://github.com/alibaba/lowcode-engine/issues"
}, },
"dependencies": { "dependencies": {
"@alilc/lowcode-types": "1.3.2", "@alilc/lowcode-types": "1.3.3-beta.3",
"@alilc/lowcode-utils": "1.3.2" "@alilc/lowcode-utils": "1.3.3-beta.3"
}, },
"devDependencies": { "devDependencies": {
"@alib/build-scripts": "^0.1.18" "@alib/build-scripts": "^0.1.18"

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-plugin-designer", "name": "@alilc/lowcode-plugin-designer",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "alibaba lowcode editor designer plugin", "description": "alibaba lowcode editor designer plugin",
"files": [ "files": [
"es", "es",
@ -18,9 +18,9 @@
], ],
"author": "xiayang.xy", "author": "xiayang.xy",
"dependencies": { "dependencies": {
"@alilc/lowcode-designer": "1.3.2", "@alilc/lowcode-designer": "1.3.3-beta.3",
"@alilc/lowcode-editor-core": "1.3.2", "@alilc/lowcode-editor-core": "1.3.3-beta.3",
"@alilc/lowcode-utils": "1.3.2", "@alilc/lowcode-utils": "1.3.3-beta.3",
"react": "^16.8.1", "react": "^16.8.1",
"react-dom": "^16.8.1" "react-dom": "^16.8.1"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-plugin-outline-pane", "name": "@alilc/lowcode-plugin-outline-pane",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "Outline pane for Ali lowCode engine", "description": "Outline pane for Ali lowCode engine",
"files": [ "files": [
"es", "es",
@ -13,8 +13,8 @@
}, },
"dependencies": { "dependencies": {
"@alifd/next": "^1.19.16", "@alifd/next": "^1.19.16",
"@alilc/lowcode-types": "1.3.2", "@alilc/lowcode-types": "1.3.3-beta.3",
"@alilc/lowcode-utils": "1.3.2", "@alilc/lowcode-utils": "1.3.3-beta.3",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"react": "^16", "react": "^16",
"react-dom": "^16.7.0", "react-dom": "^16.7.0",

View File

@ -37,6 +37,8 @@ enum EVENT_NAMES {
expandableChanged = 'expandableChanged', expandableChanged = 'expandableChanged',
conditionChanged = 'conditionChanged', conditionChanged = 'conditionChanged',
loopChanged = 'loopChanged',
} }
export default class TreeNode { export default class TreeNode {
@ -160,6 +162,10 @@ export default class TreeNode {
return this.node.hasCondition() && !this.node.conditionGroup; return this.node.hasCondition() && !this.node.conditionGroup;
} }
get loop(): boolean {
return this.node.hasLoop();
}
get children(): TreeNode[] | null { get children(): TreeNode[] | null {
return this.node.children?.map((node) => this.tree.getTreeNode(node)) || 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 { onExpandableChanged(fn: (expandable: boolean) => void): IPublicTypeDisposable {
this.event.on(EVENT_NAMES.expandableChanged, fn); this.event.on(EVENT_NAMES.expandableChanged, fn);
return () => { return () => {
@ -244,6 +258,10 @@ export default class TreeNode {
this.event.emit(EVENT_NAMES.conditionChanged, this.condition); this.event.emit(EVENT_NAMES.conditionChanged, this.condition);
} }
notifyLoopChanged(): void {
this.event.emit(EVENT_NAMES.loopChanged, this.loop);
}
setHidden(flag: boolean) { setHidden(flag: boolean) {
if (this.node.conditionGroup) { if (this.node.conditionGroup) {
return; return;

View File

@ -36,12 +36,13 @@ export class Tree {
doc?.onChangeNodeProp((info: IPublicTypePropChangeOptions) => { doc?.onChangeNodeProp((info: IPublicTypePropChangeOptions) => {
const { node, key } = info; const { node, key } = info;
const treeNode = this.getTreeNodeById(node.id);
if (key === '___title___') { if (key === '___title___') {
const treeNode = this.getTreeNodeById(node.id);
treeNode?.notifyTitleLabelChanged(); treeNode?.notifyTitleLabelChanged();
} else if (key === '___condition___') { } else if (key === '___condition___') {
const treeNode = this.getTreeNodeById(node.id);
treeNode?.notifyConditionChanged(); treeNode?.notifyConditionChanged();
} else if (key === '___loop___') {
treeNode?.notifyLoopChanged();
} }
}); });

View File

@ -28,6 +28,7 @@ export default class TreeTitle extends PureComponent<{
editing: boolean; editing: boolean;
title: string; title: string;
condition?: boolean; condition?: boolean;
loop?: boolean;
visible?: boolean; visible?: boolean;
filterWorking: boolean; filterWorking: boolean;
keywords: string; keywords: string;
@ -89,6 +90,7 @@ export default class TreeTitle extends PureComponent<{
editing: false, editing: false,
title: treeNode.titleLabel, title: treeNode.titleLabel,
condition: treeNode.condition, condition: treeNode.condition,
loop: treeNode.loop,
visible: !treeNode.hidden, visible: !treeNode.hidden,
}); });
treeNode.onTitleLabelChanged(() => { treeNode.onTitleLabelChanged(() => {
@ -101,6 +103,11 @@ export default class TreeTitle extends PureComponent<{
condition: treeNode.condition, condition: treeNode.condition,
}); });
}); });
treeNode.onLoopChanged(() => {
this.setState({
loop: treeNode.loop,
});
});
treeNode.onHiddenChanged((hidden: boolean) => { treeNode.onHiddenChanged((hidden: boolean) => {
this.setState({ this.setState({
visible: !hidden, visible: !hidden,
@ -207,7 +214,7 @@ export default class TreeTitle extends PureComponent<{
<Tip>{intlNode('Slot for {prop}', { prop: node.slotFor.key })}</Tip> <Tip>{intlNode('Slot for {prop}', { prop: node.slotFor.key })}</Tip>
</a> </a>
)} )}
{node.hasLoop() && ( {this.state.loop && (
<a className="tree-node-tag loop"> <a className="tree-node-tag loop">
{/* todo: click todo something */} {/* todo: click todo something */}
<IconLoop /> <IconLoop />

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-react-renderer", "name": "@alilc/lowcode-react-renderer",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "react renderer for ali lowcode engine", "description": "react renderer for ali lowcode engine",
"main": "lib/index.js", "main": "lib/index.js",
"module": "es/index.js", "module": "es/index.js",
@ -22,7 +22,7 @@
], ],
"dependencies": { "dependencies": {
"@alifd/next": "^1.21.16", "@alifd/next": "^1.21.16",
"@alilc/lowcode-renderer-core": "1.3.2" "@alilc/lowcode-renderer-core": "1.3.3-beta.3"
}, },
"devDependencies": { "devDependencies": {
"@alib/build-scripts": "^0.1.18", "@alib/build-scripts": "^0.1.18",

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-react-simulator-renderer", "name": "@alilc/lowcode-react-simulator-renderer",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "react simulator renderer for alibaba lowcode designer", "description": "react simulator renderer for alibaba lowcode designer",
"main": "lib/index.js", "main": "lib/index.js",
"module": "es/index.js", "module": "es/index.js",
@ -17,10 +17,10 @@
"test:cov": "build-scripts test --config build.test.json --jest-coverage" "test:cov": "build-scripts test --config build.test.json --jest-coverage"
}, },
"dependencies": { "dependencies": {
"@alilc/lowcode-designer": "1.3.2", "@alilc/lowcode-designer": "1.3.3-beta.3",
"@alilc/lowcode-react-renderer": "1.3.2", "@alilc/lowcode-react-renderer": "1.3.3-beta.3",
"@alilc/lowcode-types": "1.3.2", "@alilc/lowcode-types": "1.3.3-beta.3",
"@alilc/lowcode-utils": "1.3.2", "@alilc/lowcode-utils": "1.3.3-beta.3",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"mobx": "^6.3.0", "mobx": "^6.3.0",
"mobx-react": "^7.2.0", "mobx-react": "^7.2.0",

View File

@ -1,29 +1,32 @@
interface UtilsMetadata { // interface UtilsMetadata {
name: string; // name: string;
npm: { // npm: {
package: string; // package: string;
version?: string; // version?: string;
exportName: string; // exportName: string;
subName?: string; // subName?: string;
destructuring?: boolean; // destructuring?: boolean;
main?: string; // main?: string;
}; // };
} // }
interface LibrayMap { // invalid code
[key: string]: string;
}
export function getProjectUtils(librayMap: LibrayMap, utilsMetadata: UtilsMetadata[]) { // interface LibrayMap {
const projectUtils: { [packageName: string]: any } = {}; // [key: string]: string;
if (utilsMetadata) { // }
utilsMetadata.forEach(meta => {
if (librayMap[meta?.npm.package]) { // export function getProjectUtils(librayMap: LibrayMap, utilsMetadata: UtilsMetadata[]) {
const lib = window[librayMap[meta?.npm.package]];
} // const projectUtils: { [packageName: string]: any } = {};
}); // if (utilsMetadata) {
} // utilsMetadata.forEach(meta => {
} // if (librayMap[meta?.npm.package]) {
// const lib = window[librayMap[meta?.npm.package] as any];
// }
// });
// }
// }
/** /**
* judges if current simulator renderer deteched or not * judges if current simulator renderer deteched or not

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-renderer-core", "name": "@alilc/lowcode-renderer-core",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "renderer core", "description": "renderer core",
"license": "MIT", "license": "MIT",
"main": "lib/index.js", "main": "lib/index.js",
@ -16,8 +16,8 @@
}, },
"dependencies": { "dependencies": {
"@alilc/lowcode-datasource-engine": "^1.0.0", "@alilc/lowcode-datasource-engine": "^1.0.0",
"@alilc/lowcode-types": "1.3.2", "@alilc/lowcode-types": "1.3.3-beta.3",
"@alilc/lowcode-utils": "1.3.2", "@alilc/lowcode-utils": "1.3.3-beta.3",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"debug": "^4.1.1", "debug": "^4.1.1",
"fetch-jsonp": "^1.1.3", "fetch-jsonp": "^1.1.3",
@ -32,7 +32,7 @@
"devDependencies": { "devDependencies": {
"@alib/build-scripts": "^0.1.18", "@alib/build-scripts": "^0.1.18",
"@alifd/next": "^1.26.0", "@alifd/next": "^1.26.0",
"@alilc/lowcode-designer": "1.3.2", "@alilc/lowcode-designer": "1.3.3-beta.3",
"@babel/plugin-transform-typescript": "^7.16.8", "@babel/plugin-transform-typescript": "^7.16.8",
"@testing-library/react": "^11.2.2", "@testing-library/react": "^11.2.2",
"@types/classnames": "^2.2.11", "@types/classnames": "^2.2.11",

View File

@ -259,10 +259,11 @@ exports[`Base Render renderComp 1`] = `
"hidden": undefined, "hidden": undefined,
} }
} }
aria-expanded="false"
aria-label="select"
autoComplete="off" autoComplete="off"
disabled={false} disabled={false}
height="100%" height="100%"
maxLength={null}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
onCompositionEnd={[Function]} onCompositionEnd={[Function]}
@ -378,10 +379,11 @@ exports[`Base Render renderComp 1`] = `
"hidden": undefined, "hidden": undefined,
} }
} }
aria-expanded="false"
aria-label="select"
autoComplete="off" autoComplete="off"
disabled={false} disabled={false}
height="100%" height="100%"
maxLength={null}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
onCompositionEnd={[Function]} onCompositionEnd={[Function]}
@ -485,7 +487,6 @@ exports[`Base Render renderComp 1`] = `
autoComplete="off" autoComplete="off"
disabled={false} disabled={false}
height="100%" height="100%"
maxLength={null}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
onCompositionEnd={[Function]} onCompositionEnd={[Function]}
@ -988,7 +989,6 @@ exports[`Base Render renderComp 1`] = `
autoComplete="off" autoComplete="off"
disabled={false} disabled={false}
height="100%" height="100%"
maxLength={null}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
onCompositionEnd={[Function]} onCompositionEnd={[Function]}
@ -1048,10 +1048,11 @@ exports[`Base Render renderComp 1`] = `
"hidden": undefined, "hidden": undefined,
} }
} }
aria-expanded="false"
aria-label="select"
autoComplete="off" autoComplete="off"
disabled={false} disabled={false}
height="100%" height="100%"
maxLength={null}
name="error" name="error"
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-shell", "name": "@alilc/lowcode-shell",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "Shell Layer for AliLowCodeEngine", "description": "Shell Layer for AliLowCodeEngine",
"main": "lib/index.js", "main": "lib/index.js",
"module": "es/index.js", "module": "es/index.js",
@ -13,12 +13,12 @@
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@alilc/lowcode-designer": "1.3.2", "@alilc/lowcode-designer": "1.3.3-beta.3",
"@alilc/lowcode-editor-core": "1.3.2", "@alilc/lowcode-editor-core": "1.3.3-beta.3",
"@alilc/lowcode-editor-skeleton": "1.3.2", "@alilc/lowcode-editor-skeleton": "1.3.3-beta.3",
"@alilc/lowcode-types": "1.3.2", "@alilc/lowcode-types": "1.3.3-beta.3",
"@alilc/lowcode-utils": "1.3.2", "@alilc/lowcode-utils": "1.3.3-beta.3",
"@alilc/lowcode-workspace": "1.3.2", "@alilc/lowcode-workspace": "1.3.3-beta.3",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"enzyme": "^3.11.0", "enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5", "enzyme-adapter-react-16": "^1.15.5",

View File

@ -19,7 +19,7 @@ export class CommonUI implements IPublicApiCommonUI {
Card = Card; Card = Card;
Checkbox = Checkbox; Checkbox = Checkbox;
DatePicker = DatePicker; DatePicker = DatePicker;
Dialog = Dialog; Dialog = Dialog as any;
Dropdown = Dropdown; Dropdown = Dropdown;
Form = Form; Form = Form;
Icon = Icon; Icon = Icon;
@ -31,15 +31,15 @@ export class CommonUI implements IPublicApiCommonUI {
Radio = Radio; Radio = Radio;
Search = Search; Search = Search;
Select = Select; Select = Select;
SplitButton = SplitButton; SplitButton = SplitButton as any;
Step = Step; Step = Step;
Switch = Switch; Switch = Switch as any;
Tab = Tab; Tab = Tab;
Table = Table; Table = Table;
Tree = Tree; Tree = Tree;
TreeSelect = TreeSelect; TreeSelect = TreeSelect;
Upload = Upload; Upload = Upload;
Divider = Divider; Divider = Divider as any;
ContextMenu: ((props: { ContextMenu: ((props: {
menus: IPublicTypeContextMenuAction[]; menus: IPublicTypeContextMenuAction[];

View File

@ -50,4 +50,12 @@ export class Hotkey implements IPublicApiHotkey {
this[hotkeySymbol].unbind(combos, callback, action); this[hotkeySymbol].unbind(combos, callback, action);
}; };
} }
/**
*
* @param window window
*/
mount(window: Window) {
return this[hotkeySymbol].mount(window);
}
} }

View File

@ -1,4 +1,4 @@
import { IPublicApiWorkspace, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType } from '@alilc/lowcode-types'; import { IPublicApiWorkspace, IPublicModelResource, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType } from '@alilc/lowcode-types';
import { IWorkspace } from '@alilc/lowcode-workspace'; import { IWorkspace } from '@alilc/lowcode-workspace';
import { resourceSymbol, workspaceSymbol } from '../symbols'; import { resourceSymbol, workspaceSymbol } from '../symbols';
import { Resource as ShellResource, Window as ShellWindow } from '../model'; import { Resource as ShellResource, Window as ShellWindow } from '../model';
@ -13,7 +13,7 @@ export class Workspace implements IPublicApiWorkspace {
} }
get resourceList() { get resourceList() {
return this[workspaceSymbol].getResourceList().map((d) => new ShellResource(d)); return this[workspaceSymbol].getResourceList().map((d) => new ShellResource(d) as IPublicModelResource);
} }
setResourceList(resourceList: IPublicResourceList) { setResourceList(resourceList: IPublicResourceList) {

View File

@ -97,8 +97,9 @@ export class NodeChildren implements IPublicModelNodeChildren {
* @param deleteCount * @param deleteCount
* @param node * @param node
*/ */
splice(start: number, deleteCount: number, node?: IPublicModelNode): any { splice(start: number, deleteCount: number, node?: IPublicModelNode): IPublicModelNode[] {
this[nodeChildrenSymbol].splice(start, deleteCount, (node as any)?.[nodeSymbol]); const removedNode = this[nodeChildrenSymbol].splice(start, deleteCount, (node as any)?.[nodeSymbol]);
return removedNode.map((item: InnerNode) => ShellNode.create(item)!);
} }
/** /**

View File

@ -46,7 +46,7 @@ export class Resource implements IPublicModelResource {
} }
get children() { get children() {
return this[resourceSymbol].children.map((child) => new Resource(child)); return this[resourceSymbol].children.map((child) => new Resource(child) as IPublicModelResource);
} }
get viewName() { get viewName() {

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-types", "name": "@alilc/lowcode-types",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "Types for Ali lowCode engine", "description": "Types for Ali lowCode engine",
"files": [ "files": [
"es", "es",

View File

@ -1,5 +1,5 @@
import { Component, ReactNode } from 'react'; import { Component, ReactElement, ReactNode } from 'react';
import { IPublicTypeI18nData, IPublicTypeNodeSchema, IPublicTypeTitleContent } from '../type'; import { IPublicTypeI18nData, IPublicTypeNodeSchema, IPublicTypeTitleContent } from '../type';
import { IPublicEnumTransitionType } from '../enum'; import { IPublicEnumTransitionType } from '../enum';
@ -73,7 +73,7 @@ export interface IPublicApiCommonUtils {
/** /**
* i18n * i18n
*/ */
intl(data: IPublicTypeI18nData | string, params?: object): string; intl(data: IPublicTypeI18nData | string | undefined | ReactElement, params?: object): string;
} }
export interface IPublicApiCommonSkeletonCabin { export interface IPublicApiCommonSkeletonCabin {

View File

@ -22,4 +22,10 @@ export interface IPublicApiHotkey {
callback: IPublicTypeHotkeyCallback, callback: IPublicTypeHotkeyCallback,
action?: string, action?: string,
): IPublicTypeDisposable; ): IPublicTypeDisposable;
/**
*
* @param window window
*/
mount(window: Window): IPublicTypeDisposable;
} }

View File

@ -108,7 +108,7 @@ export interface IPublicModelDocumentModel<
* @param data * @param data
* @returns * @returns
*/ */
createNode<T = Node>(data: IPublicTypeNodeSchema): T | null; createNode<T = Node, S = IPublicTypeNodeSchema>(data: S): T | null;
/** /**
* /id * /id

View File

@ -78,7 +78,7 @@ export interface IPublicModelNodeChildren<
* @param deleteCount * @param deleteCount
* @param node * @param node
*/ */
splice(start: number, deleteCount: number, node?: Node): any; splice(start: number, deleteCount: number, node?: Node): Node[];
/** /**
* *

View File

@ -1,5 +1,5 @@
import { IPublicEnumTransformStage } from '../enum'; import { IPublicEnumTransformStage } from '../enum';
import { IPublicTypeCompositeValue } from '../type'; import { IPublicTypeCompositeValue, IPublicTypeNodeData } from '../type';
import { IPublicModelNode } from './'; import { IPublicModelNode } from './';
export interface IPublicModelProp< export interface IPublicModelProp<
@ -48,7 +48,7 @@ export interface IPublicModelProp<
* set value for this prop * set value for this prop
* @param val * @param val
*/ */
setValue(val: IPublicTypeCompositeValue): void; setValue(val: IPublicTypeCompositeValue | IPublicTypeNodeData | IPublicTypeNodeData[]): void;
/** /**
* *

View File

@ -1,4 +1,4 @@
import { ReactElement } from 'react'; import { ComponentType, ReactElement } from 'react';
export interface IBaseModelResource< export interface IBaseModelResource<
Resource Resource
@ -7,7 +7,7 @@ export interface IBaseModelResource<
get id(): string | undefined; get id(): string | undefined;
get icon(): ReactElement | undefined; get icon(): ReactElement | undefined | ComponentType;
get options(): Record<string, any>; get options(): Record<string, any>;

View File

@ -102,7 +102,7 @@ export interface IPublicTypeFilterItem {
} }
export interface IPublicTypeAutorunItem { export interface IPublicTypeAutorunItem {
name: string; name: string;
autorun: (target: IPublicModelSettingField | null) => any; autorun: (target: IPublicModelSettingField | null | undefined) => any;
} }
// thinkof Array // thinkof Array

View File

@ -1,11 +1,11 @@
import { IPublicEnumTransformStage } from '../enum'; import { IPublicEnumTransformStage } from '../enum';
import { IPublicModelNode } from '../model'; import { IPublicModelNode } from '../model';
import { IPublicTypeCompositeObject } from './'; import { IPublicTypePropsMap } from './';
export type IPublicTypePropsTransducer = ( export type IPublicTypePropsTransducer = (
props: IPublicTypeCompositeObject, props: IPublicTypePropsMap,
node: IPublicModelNode, node: IPublicModelNode,
ctx?: { ctx?: {
stage: IPublicEnumTransformStage; stage: IPublicEnumTransformStage;
}, },
) => IPublicTypeCompositeObject; ) => IPublicTypePropsMap;

View File

@ -36,7 +36,7 @@ export interface IPublicTypeWidgetBaseConfig {
*/ */
area?: IPublicTypeWidgetConfigArea; area?: IPublicTypeWidgetConfigArea;
props?: Record<string, any>; props?: Record<string, any>;
content?: string | ReactElement | ComponentType<any> | IPublicTypePanelConfig[]; content?: string | ReactElement | ComponentType<any> | IPublicTypePanelConfig[] | IPublicTypePanelConfig;
contentProps?: Record<string, any>; contentProps?: Record<string, any>;
/** /**

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-utils", "name": "@alilc/lowcode-utils",
"version": "1.3.2", "version": "1.3.3-beta.3",
"description": "Utils for Ali lowCode engine", "description": "Utils for Ali lowCode engine",
"files": [ "files": [
"lib", "lib",
@ -14,7 +14,7 @@
}, },
"dependencies": { "dependencies": {
"@alifd/next": "^1.19.16", "@alifd/next": "^1.19.16",
"@alilc/lowcode-types": "1.3.2", "@alilc/lowcode-types": "1.3.3-beta.3",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mobx": "^6.3.0", "mobx": "^6.3.0",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",

View File

@ -1,6 +1,6 @@
import { isObject } from './is-object'; import { isObject } from './is-object';
export function isPlainObject(value: any): value is any { export function isPlainObject<T extends object = object>(value: any): value is T {
if (!isObject(value)) { if (!isObject(value)) {
return false; return false;
} }

Some files were not shown because too many files have changed in this diff Show More