diff --git a/docs/config/navbar.js b/docs/config/navbar.js index 20d5e5f90c..24f8a39376 100644 --- a/docs/config/navbar.js +++ b/docs/config/navbar.js @@ -39,6 +39,12 @@ module.exports = { position: 'left', label: '文章', }, + { + type: 'doc', + docId: 'video/index', + position: 'left', + label: '视频', + }, { type: 'doc', docId: 'demoUsage/intro', diff --git a/docs/docs/api/configOptions.md b/docs/docs/api/configOptions.md index 4127576569..467655f68c 100644 --- a/docs/docs/api/configOptions.md +++ b/docs/docs/api/configOptions.md @@ -254,6 +254,16 @@ JSExpression 是否只支持使用 this 来访问上下文变量,假如需要 自定义 loading 组件 +### 插件 + +#### defaultSettingPanelProps + +内置设置面板插件的 panelProps + +#### defaultOutlinePaneProps + +内置大纲树面板插件的 panelProps + ### 其他 #### enableStrictPluginMode @@ -282,4 +292,3 @@ customPluginTransducer: async (originPlugin: IPublicTypePlugin, ctx: IPublicMode 大纲树插件面板默认 props - diff --git a/docs/docs/api/model/node.md b/docs/docs/api/model/node.md index c10af34660..697eefd088 100644 --- a/docs/docs/api/model/node.md +++ b/docs/docs/api/model/node.md @@ -657,4 +657,22 @@ setConditionalVisible(): void; */ getDOMNode(): HTMLElement; +``` + +### getRGL + +获取磁贴相关信息 + +```typescript +/** + * 获取磁贴相关信息 + */ +getRGL(): { + isContainerNode: boolean; + isEmptyNode: boolean; + isRGLContainerNode: boolean; + isRGLNode: boolean; + isRGL: boolean; + rglNode: Node | null; +} ``` \ No newline at end of file diff --git a/docs/docs/api/model/simulatorRender.md b/docs/docs/api/model/simulatorRender.md new file mode 100644 index 0000000000..f5bacec493 --- /dev/null +++ b/docs/docs/api/model/simulatorRender.md @@ -0,0 +1,38 @@ +--- +title: SimulatorRender +sidebar_position: 6 +--- +> **@types** [IPublicModelSimulatorRender](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/simulator-render.ts)
+> **@since** v1.0.0 + +## 基本介绍 + +画布节点选中模型 + +## 属性 +### components + +画布组件列表 + +```typescript +/** + * 画布组件列表 + */ +components: { + [key: string]: any; +} +``` + +## 方法 + +### rerender + +触发画布重新渲染 + +```typescript +/** + * 触发画布重新渲染 + */ +rerender: () => void; +``` + diff --git a/docs/docs/api/simulatorHost.md b/docs/docs/api/simulatorHost.md index b30a614992..ee8f038fc3 100644 --- a/docs/docs/api/simulatorHost.md +++ b/docs/docs/api/simulatorHost.md @@ -50,11 +50,11 @@ get(key: string): any; ``` ### rerender -刷新渲染画布 +触发组件构建,并刷新渲染画布 ```typescript /** - * 刷新渲染画布 + * 触发组件构建,并刷新渲染画布 * make simulator render again */ rerender(): void; diff --git a/docs/docs/api/workspace.md b/docs/docs/api/workspace.md index 3c13b00aa0..9911dc93ad 100644 --- a/docs/docs/api/workspace.md +++ b/docs/docs/api/workspace.md @@ -37,6 +37,16 @@ get plugins(): IPublicApiPlugins 关联模型 [IPublicApiPlugins](./plugins) +### skeleton + +应用级别的面板管理 + +```typescript +get skeleton(): IPublicApiSkeleton +``` + +关联模型 [IPublicApiSkeleton](./skeleton) + ### windows 当前设计器的编辑窗口 diff --git a/docs/docs/article/index.md b/docs/docs/article/index.md index 8ff76ff476..2f6f2cee3f 100644 --- a/docs/docs/article/index.md +++ b/docs/docs/article/index.md @@ -1,8 +1,4 @@ ---- -title: 低代码引擎相关文章资料 ---- - -## 官方文章 +# 官方文章 - [2023/04/04 什么?低代码引擎可以开发应用了](https://mp.weixin.qq.com/s/dwi40gJjGBHW9MVpag5Oxg) - [2023/03/23 低代码引擎 LowCodeEngine 茁壮成长的一年](https://mp.weixin.qq.com/s/DDt4LQLFUBQ2-F5ehZGBKg) - [2023/02/21 基于 LowCodeEngine 的低代码组件体系的建设和实践](https://mp.weixin.qq.com/s/rnvbGHImGt6oJuX2wCtaqw) @@ -14,28 +10,4 @@ title: 低代码引擎相关文章资料 - [2022/04/07 磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw) - [2022/03/23 阿里低代码引擎 LowCodeEngine 正式开源!](https://mp.weixin.qq.com/s/T66LghtWLz2Oh048XqaniA) - [2022/01/10 阿里低代码引擎和生态建设实战及思考](https://mp.weixin.qq.com/s/MI6MrUKKydtnSdO4xq6jwA) -- [2021/04/14 2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw) - -## Portal 设计项目实战 -#### 直播回放 -[https://www.bilibili.com/video/BV1AS4y1K7DP/](https://www.bilibili.com/video/BV1AS4y1K7DP/) - -#### 示例项目 -- 前端: [https://github.com/mark-ck/lowcode-portal](https://github.com/mark-ck/lowcode-portal) -- 后端: [https://github.com/mark-ck/document-solution-site](https://github.com/mark-ck/document-solution-site) -- 组件库:[https://github.com/mark-ck/portal-components](https://github.com/mark-ck/portal-components) - -**注意** -1. 前端项目要把代码里请求接口的域名改成本地或者自己的域名; -2. 后端项目要把 config.default.js 里的 yuque 和 oss 配置补全; - -#### 视频链接 -- [阿里低代码引擎项目实战 (1)-引擎 demo 部署到 faas 服务](https://www.bilibili.com/video/BV1B44y1P7GM/) -- [【有翻车】阿里低代码引擎项目实战 (2)-保存页面到远端存储](https://www.bilibili.com/video/BV1AS4y1K7DP/) -- [阿里巴巴低代码引擎项目实战 (3)-自定义组件接入](https://www.bilibili.com/video/BV1dZ4y1m76S/) -- [阿里低代码引擎项目实战 (4)-自定义插件 - 页面管理](https://www.bilibili.com/video/BV17a411i73f/) -- [阿里低代码引擎项目实战 (4)-用户登录](https://www.bilibili.com/video/BV1Wu411e7EQ/) -- [【有翻车】阿里低代码引擎项目实战 (5)-表单回显](https://www.bilibili.com/video/BV1UY4y1v7D7/) -- [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/) -- [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 前端](https://www.bilibili.com/video/BV1Yq4y1a74P/) -- [阿里低代码引擎项目实战 (7)-自定义插件 - 页面管理 (完结)](https://www.bilibili.com/video/BV13Y4y1e7EV/) +- [2021/04/14 2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw) \ No newline at end of file diff --git a/docs/docs/demoUsage/appendix/loop.md b/docs/docs/demoUsage/appendix/loop.md index 8b364ecf4f..46f39398af 100644 --- a/docs/docs/demoUsage/appendix/loop.md +++ b/docs/docs/demoUsage/appendix/loop.md @@ -15,3 +15,14 @@ sidebar_position: 0 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01XQfnYL1P4wxn01oXv_!!6000000001788-2-tps-3840-1896.png) this.index 是当前循环的索引值。 + +3.在事件绑定函数中使用 + +在事件绑定函数中使用扩展参数设置 +![image](https://github.com/alibaba/lowcode-engine/assets/11935995/7274506e-decd-497a-b07f-c95941a706b4) + +绑定之后在函数中使用 +![image](https://github.com/alibaba/lowcode-engine/assets/11935995/9d52ee5c-9959-4991-91be-9391e639bb7e) + +按钮点击效果 +![image](https://github.com/alibaba/lowcode-engine/assets/11935995/6ca590c9-1f5f-4d48-94a5-439130a22e92) diff --git a/docs/docs/guide/design/specs.md b/docs/docs/guide/design/specs.md index 0d97f5cc08..2e8e4c195c 100644 --- a/docs/docs/guide/design/specs.md +++ b/docs/docs/guide/design/specs.md @@ -58,7 +58,7 @@ sidebar_position: 1 ## 协议的作用 -基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,各类中后台研发系统生产的物料可借助物料中心进行跨系统流通,通过丰富物料生态的共享提升各平台研发系统的效率。同时完成低代码引擎的标准统一以及低代码搭建中台能力的输出,帮助业务方快速孵化本业务域中后台研发系统。 +基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,各类中后台研发系统生产的物料可借助物料中心进行跨系统流通,通过丰富物料生态的共享提升各平台研发系统的效率。同时完成低代码引擎的标准统一以及低代码搭建中台能力的输出,帮助业务方快速孵化本业务域中后台研发系统。 ### 打破物料孤岛 diff --git a/docs/docs/guide/design/summary.md b/docs/docs/guide/design/summary.md index cd5edfd886..38d523cac9 100644 --- a/docs/docs/guide/design/summary.md +++ b/docs/docs/guide/design/summary.md @@ -20,7 +20,7 @@ sidebar_position: 0 低代码引擎分为 4 大模块,入料 - 编排 - 渲染 - 出码: -- 入料模块就是将外部的物料,比如海量的 npm 组件,按照《物料描述协议》进行描述。将描述后的数据通过引擎 API 注册后,在编辑器中使用。 +- 入料模块就是将外部的物料,比如海量的 npm 组件,按照[《低代码引擎物料协议规范》](/site/docs/specs/material-spec)进行描述。将描述后的数据通过引擎 API 注册后,在编辑器中使用。 > **注意,这里仅是增加描述,而非重写一套,这样我们能最大程度复用 ProCode 体系已沉淀的组件。** - 编排,本质上来讲,就是**不断在生成符合[《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec)的页面描述,将编辑器中的所有物料,进行布局设置、组件 CRUD 操作、以及 JS / CSS 编写/ 逻辑编排 **等,最终转换成页面描述,技术细节后文会展开。 - 渲染,顾名思义,就是**将编排生成的页面描述结构渲染成视图的过程**,视图是面向用户的,所以必须处理好内部数据流、生命周期、事件绑定、国际化等。 diff --git a/docs/docs/guide/expand/editor/cli.md b/docs/docs/guide/expand/editor/cli.md index 60f44ce875..0577a181db 100644 --- a/docs/docs/guide/expand/editor/cli.md +++ b/docs/docs/guide/expand/editor/cli.md @@ -1,6 +1,6 @@ --- title: 低代码生态脚手架 & 调试机制 -sidebar_position: 8 +sidebar_position: 10 --- ## 脚手架简述 diff --git a/docs/docs/guide/expand/editor/graph.md b/docs/docs/guide/expand/editor/graph.md index 2d5127054e..a45f34baf0 100644 --- a/docs/docs/guide/expand/editor/graph.md +++ b/docs/docs/guide/expand/editor/graph.md @@ -1,6 +1,6 @@ --- title: 图编排扩展 -sidebar_position: 9 +sidebar_position: 8 --- ## 项目运行 ### 前置准备 diff --git a/docs/docs/guide/expand/editor/setter.md b/docs/docs/guide/expand/editor/setter.md index 01fd949bbd..4f0e0219fc 100644 --- a/docs/docs/guide/expand/editor/setter.md +++ b/docs/docs/guide/expand/editor/setter.md @@ -1,6 +1,6 @@ --- title: 设置器扩展 -sidebar_position: 5 +sidebar_position: 7 --- ## 设置器简述 diff --git a/docs/docs/guide/expand/editor/theme.md b/docs/docs/guide/expand/editor/theme.md new file mode 100644 index 0000000000..b62fb4f28c --- /dev/null +++ b/docs/docs/guide/expand/editor/theme.md @@ -0,0 +1,91 @@ +--- +title: 主题色扩展 +sidebar_position: 9 +--- + +## 主题色扩展简述 + +通过主题色扩展,可以定制多种设计器主题。 + +## 主题色扩展说明 + +### 主题色变量 + +- `--color-brand`: 品牌色 +- `--color-brand-light`: 品牌色(light) +- `--color-brand-dark`: 品牌色(dark) +- `--color-icon-normal`: 正常 icon 颜色 +- `--color-icon-hover`: icon hover 态颜色 +- `--color-icon-active`: icon active 态颜色 +- `--color-icon-reverse`: icon 反色 +- `--color-icon-disabled`: icon 禁用态颜色 +- `--color-icon-pane`: icon 面板颜色 +- `--color-line-normal`: 线条颜色 +- `--color-line-darken`: 线条颜色(darken) +- `--color-title`: 标题颜色 +- `--color-text`: 文字颜色 +- `--color-text-dark`: 文字颜色(dark) +- `--color-text-light`: 文字颜色(light) +- `--color-text-reverse`: 反色情况下,文字颜色 +- `--color-text-regular`: 文字颜色(regular) +- `--color-text-disabled`: 禁用态文字颜色 +- `--color-field-label`: field 标签颜色 +- `--color-field-text`: field 文本颜色 +- `--color-field-placeholder`: field placeholder 颜色 +- `--color-field-border`: field 边框颜色 +- `--color-field-border-hover`: hover 态下,field 边框颜色 +- `--color-field-border-active`: active 态下,field 边框颜色 +- `--color-field-background`: field 背景色 +- `--color-success`: success 颜色 +- `--colo-success-dark`: success 颜色(dark) +- `--color-success-light`: success 颜色(light) +- `--color-warning`: warning 颜色 +- `--color-warning-dark`: warning 颜色(dark) +- `--color-warning-light`: warning 颜色(light) +- `--color-information`: information 颜色 +- `--color-information-dark`: information 颜色(dark) +- `--color-information-light`: information 颜色(light) +- `--color-error`: error 颜色 +- `--color-error-dark`: error 颜色(dark) +- `--color-error-light`: error 颜色(light) +- `--color-purple`: purple 颜色 +- `--color-brown`: brown 颜色 +- `--color-pane-background`: 面板背景色 +- `--color-block-background-normal`: 区块背景色 +- `--color-block-background-light`: 区块背景色(light), 作用于画布组件 hover 时遮罩背景色。 +- `--color-block-background-shallow`: 区块背景色 shallow +- `--color-block-background-dark`: 区块背景色(dark) +- `--color-block-background-disabled`: 区块背景色(disabled) +- `--color-block-background-active`: 区块背景色(active) +- `--color-block-background-warning`: 区块背景色(warning) +- `--color-block-background-error`: 区块背景色(error) +- `--color-block-background-success`: 区块背景色(success) +- `--color-block-background-deep-dark`: 区块背景色(deep-dark),作用于多个组件同时拖拽的背景色。 +- `--color-layer-mask-background`: 拖拽元素时,元素原来位置的遮罩背景色 +- `--color-layer-tooltip-background`: tooltip 背景色 +- `--color-background`: 设计器主要背景色 +- `--color-top-area-background`: topArea 背景色,优先级大于 `--color-pane-background` +- `--color-left-area-background`: leftArea 背景色,优先级大于 `--color-pane-background` +- `--color-workspace-left-area-background`: 应用级 leftArea 背景色,优先级大于 `--color-pane-background` +- `--color-workspace-top-area-background`: 应用级 topArea 背景色,优先级大于 `--color-pane-background` +- `--color-workspace-sub-top-area-background`: 应用级二级 topArea 背景色,优先级大于 `--color-pane-background` +- `--workspace-sub-top-area-height`: 应用级二级 topArea 高度 +- `--workspace-sub-top-area-margin`: 应用级二级 topArea margin +- `--workspace-sub-top-area-padding`: 应用级二级 topArea padding + +### 生态使用主题色变量 + +插件、物料、设置器等生态为了支持主题色需要对样式进行改造,需要对生态中的样式升级为 css 变量。例如: + +```css +/* before */ +background: #006cff; + +/* after */ +background: var(--color-brand, #006cff); + +``` + +### fusion 物料进行主题色扩展 + +如果使用了 fusion 组件,可以通过 https://fusion.alibaba-inc.com/ 平台进行主题色定制。 \ No newline at end of file diff --git a/docs/docs/video/index.md b/docs/docs/video/index.md new file mode 100644 index 0000000000..9f348e4e65 --- /dev/null +++ b/docs/docs/video/index.md @@ -0,0 +1,13 @@ +# 官方视频 +- [2023/08/03 初识低代码引擎](https://www.bilibili.com/video/BV1gu411p7TC) + +# 社区视频 +- [阿里低代码引擎项目实战 (1)-引擎 demo 部署到 faas 服务](https://www.bilibili.com/video/BV1B44y1P7GM/) +- [【有翻车】阿里低代码引擎项目实战 (2)-保存页面到远端存储](https://www.bilibili.com/video/BV1AS4y1K7DP/) +- [阿里巴巴低代码引擎项目实战 (3)-自定义组件接入](https://www.bilibili.com/video/BV1dZ4y1m76S/) +- [阿里低代码引擎项目实战 (4)-自定义插件 - 页面管理](https://www.bilibili.com/video/BV17a411i73f/) +- [阿里低代码引擎项目实战 (4)-用户登录](https://www.bilibili.com/video/BV1Wu411e7EQ/) +- [【有翻车】阿里低代码引擎项目实战 (5)-表单回显](https://www.bilibili.com/video/BV1UY4y1v7D7/) +- [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/) +- [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 前端](https://www.bilibili.com/video/BV1Yq4y1a74P/) +- [阿里低代码引擎项目实战 (7)-自定义插件 - 页面管理 (完结)](https://www.bilibili.com/video/BV13Y4y1e7EV/) diff --git a/docs/package.json b/docs/package.json index 012ef49d04..177226a287 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.7", + "version": "1.1.12", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ diff --git a/lerna.json b/lerna.json index 0bb34d1aee..b76ff2ae85 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.1.10", + "version": "1.2.0", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/package.json b/package.json index 6a650c49b6..aded2a3015 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,8 @@ "lockfile": "enable" }, "resolutions": { - "typescript": "4.6.2" + "typescript": "4.6.2", + "react-error-overlay": "6.0.9" }, "repository": "git@github.com:alibaba/lowcode-engine.git" } diff --git a/packages/designer/package.json b/packages/designer/package.json index 274d266fc0..c32b54a778 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.1.10", + "version": "1.2.0", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,10 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/build-plugin-lce": "^0.0.4-beta.2", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/designer/src/builtin-simulator/bem-tools/borders.less b/packages/designer/src/builtin-simulator/bem-tools/borders.less index 2cdc9fb403..43fba6a2b8 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/borders.less +++ b/packages/designer/src/builtin-simulator/bem-tools/borders.less @@ -17,7 +17,7 @@ } & > &-status { margin-left: 5px; - color: #3c3c3c; + color: var(--color-text, #3c3c3c); transform: translateY(-100%); font-weight: lighter; } @@ -46,7 +46,7 @@ opacity: 1; max-height: 100%; overflow: hidden; - color: white; + color: var(--color-icon-reverse, white); &:hover { background: var(--color-brand-light, #006cff); } @@ -56,8 +56,8 @@ display: inline-block; width: 8px; height: 8px; - border: 1px solid #197aff; - background: #fff; + border: 1px solid var(--color-brand, #197aff); + background: var(--color-block-background-normal, #fff); pointer-events: auto; z-index: 2; } @@ -73,11 +73,9 @@ &:after { content: ""; display: block; - border: 1px solid #197aff; - background: #fff; - // background: #738397; + border: 1px solid var(--color-brand, #197aff); + background: var(--color-block-background-normal, #fff); border-radius: 2px; - // animation: flashing 1.5s infinite linear; } &.e, @@ -85,7 +83,6 @@ cursor: ew-resize; &:after { width: 4px; - // height: calc(100% - 20px); min-height: 50%; } } @@ -94,62 +91,24 @@ &.s { cursor: ns-resize; &:after { - // width: calc(100% - 20px); min-width: 50%; height: 4px; } } } - // &&-hovering { &&-detecting { z-index: 1; border-style: dashed; - background: rgba(0,121,242,.04); - - &.x-loop { - border-color: rgba(138, 93, 226, 0.8); - background: rgba(138, 93, 226, 0.04); - - >.@{scope}-title { - color: rgba(138, 93, 226, 1.0); - } - } - - &.x-condition { - border-color: rgba(255, 99, 8, 0.8); - background: rgba(255, 99, 8, 0.04); - >.@{scope}-title { - color: rgb(255, 99, 8); - } - } + background: var(--color-block-background-light, rgba(0,121,242,.04)); } &&-selecting { z-index: 2; border-width: 2px; - &.x-loop { - border-color: rgba(147, 112, 219, 1.0); - background: rgba(147, 112, 219, 0.04); - - >@{scope}-title { - color: rgba(147, 112, 219, 1.0); - } - &.highlight { - background: transparent; - } - } - - &.x-condition { - border-color: rgb(255, 99, 8); - >@{scope}-title { - color: rgb(255, 99, 8); - } - } - &.dragging { - background: rgba(182, 178, 178, 0.8); + background: var(--color-layer-mask-background, rgba(182, 178, 178, 0.8)); border: none; } } diff --git a/packages/designer/src/builtin-simulator/bem-tools/insertion.less b/packages/designer/src/builtin-simulator/bem-tools/insertion.less index 770d3893ca..fff045631a 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/insertion.less +++ b/packages/designer/src/builtin-simulator/bem-tools/insertion.less @@ -23,6 +23,6 @@ } &.invalid { - background-color: red; + background-color: var(--color-error, var(--color-function-error, red)); } } diff --git a/packages/designer/src/builtin-simulator/create-simulator.ts b/packages/designer/src/builtin-simulator/create-simulator.ts index 15ab3507b5..57369efd89 100644 --- a/packages/designer/src/builtin-simulator/create-simulator.ts +++ b/packages/designer/src/builtin-simulator/create-simulator.ts @@ -56,12 +56,13 @@ export function createSimulator( } const id = asset.id ? ` data-id="${asset.id}"` : ''; const lv = asset.level || level || AssetLevel.Environment; + const scriptType = asset.scriptType ? ` type="${asset.scriptType}"` : ''; if (asset.type === AssetType.JSUrl) { scripts[lv].push( - ``, + ``, ); } else if (asset.type === AssetType.JSText) { - scripts[lv].push(`${asset.content}`); + scripts[lv].push(`${asset.content}`); } else if (asset.type === AssetType.CSSUrl) { styles[lv].push( ``, diff --git a/packages/designer/src/builtin-simulator/host.less b/packages/designer/src/builtin-simulator/host.less index 5e230c4007..7130c42972 100644 --- a/packages/designer/src/builtin-simulator/host.less +++ b/packages/designer/src/builtin-simulator/host.less @@ -31,7 +31,7 @@ max-height: calc(100% - 32px); max-width: calc(100% - 32px); transform: translateX(-50%); - box-shadow: 0 2px 10px 0 rgba(31,56,88,.15); + box-shadow: 0 2px 10px 0 var(--color-block-background-shallow, rgba(31,56,88,.15)); } &-device-iphonex { // 增加默认的小程序的壳 @@ -44,7 +44,7 @@ background: url(https://img.alicdn.com/tfs/TB1b4DHilFR4u4jSZFPXXanzFXa-750-1574.png) no-repeat top; background-size: 375px 812px; border-radius: 44px; - box-shadow: rgba(0, 0, 0, 0.1) 0 36px 42px; + box-shadow: var(--color-block-background-shallow, rgba(0, 0, 0, 0.1)) 0 36px 42px; .@{scope}-canvas-viewport { width: auto; top: 50px; @@ -78,7 +78,7 @@ bottom: 16px; left: 16px; width: auto; - box-shadow: 0 1px 4px 0 rgba(31, 50, 88, 0.125); + box-shadow: 0 1px 4px 0 var(--color-block-background-shallow, rgba(31, 50, 88, 0.125)); } &-content { diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index 5e6fc06a62..eb855e4498 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -1069,15 +1069,15 @@ export class BuiltinSimulatorHost implements ISimulatorHost { - return node.componentMeta.isModal; + condition: (node: IPublicModelNode) => { + return node.componentMeta?.isModal; }, important: true, }, @@ -47,25 +56,26 @@ export class ComponentActions { icon: IconClone, title: intlNode('copy'), /* istanbul ignore next */ - action(node: Node) { + action(node: IPublicModelNode) { // node.remove(); const { document: doc, parent, index } = node; if (parent) { - const newNode = doc.insertNode(parent, node, index + 1, true); - newNode.select(); - const { isRGL, rglNode } = node.getRGL(); + const newNode = doc?.insertNode(parent, node, (index ?? 0) + 1, true); + deduplicateRef(newNode); + newNode?.select(); + const { isRGL, rglNode } = node?.getRGL(); if (isRGL) { // 复制 layout 信息 - const layout = rglNode.getPropValue('layout') || []; - const curLayout = layout.filter((item) => item.i === node.getPropValue('fieldId')); + const layout: any = rglNode?.getPropValue('layout') || []; + const curLayout = layout.filter((item: any) => item.i === node.getPropValue('fieldId')); if (curLayout && curLayout[0]) { layout.push({ ...curLayout[0], - i: newNode.getPropValue('fieldId'), + i: newNode?.getPropValue('fieldId'), }); - rglNode.setPropValue('layout', layout); + rglNode?.setPropValue('layout', layout); // 如果是磁贴块复制,则需要滚动到影响位置 - setTimeout(() => newNode.document.simulator?.scrollToNode(newNode), 10); + setTimeout(() => newNode?.document?.project?.simulatorHost?.scrollToNode(newNode), 10); } } } @@ -79,13 +89,13 @@ export class ComponentActions { icon: IconLock, // 锁定 icon title: intlNode('lock'), /* istanbul ignore next */ - action(node: Node) { + action(node: IPublicModelNode) { node.lock(); }, }, /* istanbul ignore next */ - condition: (node: Node) => { - return engineConfig.get('enableCanvasLock', false) && node.isContainer() && !node.isLocked; + condition: (node: IPublicModelNode) => { + return engineConfig.get('enableCanvasLock', false) && node.isContainerNode && !node.isLocked; }, important: true, }, @@ -95,13 +105,13 @@ export class ComponentActions { icon: IconUnlock, // 解锁 icon title: intlNode('unlock'), /* istanbul ignore next */ - action(node: Node) { + action(node: IPublicModelNode) { node.lock(false); }, }, /* istanbul ignore next */ - condition: (node: Node) => { - return engineConfig.get('enableCanvasLock', false) && node.isContainer() && node.isLocked; + condition: (node: IPublicModelNode) => { + return engineConfig.get('enableCanvasLock', false) && node.isContainerNode && node.isLocked; }, important: true, }, @@ -132,8 +142,6 @@ export class ComponentActions { } } - private metadataTransducers: IPublicTypeMetadataTransducer[] = []; - registerMetadataTransducer( transducer: IPublicTypeMetadataTransducer, level = 100, diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index 784ebf57bc..d7e17e84ca 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -18,7 +18,7 @@ import { IPublicEnumTransformStage, IPublicModelLocateEvent, } from '@alilc/lowcode-types'; -import { megreAssets, 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 { Node, DocumentModel, insertChildren, INode } from '../document'; import { ComponentMeta, IComponentMeta } from '../component-meta'; @@ -458,7 +458,7 @@ export class Designer implements IDesigner { if (components) { // 合并 assets let assets = this.editor.get('assets') || {}; - let newAssets = megreAssets(assets, incrementalAssets); + let newAssets = mergeAssets(assets, incrementalAssets); // 对于 assets 存在需要二次网络下载的过程,必须 await 等待结束之后,再进行事件触发 await this.editor.set('assets', newAssets); } diff --git a/packages/designer/src/designer/drag-ghost/ghost.less b/packages/designer/src/designer/drag-ghost/ghost.less index 7ab61b41d6..1d9c03552f 100644 --- a/packages/designer/src/designer/drag-ghost/ghost.less +++ b/packages/designer/src/designer/drag-ghost/ghost.less @@ -7,8 +7,8 @@ flex-direction: column; align-items: center; pointer-events: none; - background-color: rgba(0, 0, 0, 0.4); - box-shadow: 0 0 6px grey; + background-color: var(--color-block-background-deep-dark, rgba(0, 0, 0, 0.4)); + box-shadow: 0 0 6px var(--color-block-background-shallow, grey); transform: translate(-10%, -50%); .lc-ghost { .lc-ghost-title { diff --git a/packages/designer/src/designer/scroller.ts b/packages/designer/src/designer/scroller.ts index 67efe7f444..7391c39fab 100644 --- a/packages/designer/src/designer/scroller.ts +++ b/packages/designer/src/designer/scroller.ts @@ -46,7 +46,7 @@ function easing(n: number) { return Math.sin((n * Math.PI) / 2); } -const SCROLL_ACCURCY = 30; +const SCROLL_ACCURACY = 30; export interface IScroller extends IPublicModelScroller { @@ -142,15 +142,15 @@ export class Scroller implements IScroller { let sy = scrollTarget.top; let ax = 0; let ay = 0; - if (y < bounds.top + SCROLL_ACCURCY) { - ay = -Math.min(Math.max(bounds.top + SCROLL_ACCURCY - y, 10), 50) / scale; - } else if (y > bounds.bottom - SCROLL_ACCURCY) { - ay = Math.min(Math.max(y + SCROLL_ACCURCY - bounds.bottom, 10), 50) / scale; + if (y < bounds.top + SCROLL_ACCURACY) { + ay = -Math.min(Math.max(bounds.top + SCROLL_ACCURACY - y, 10), 50) / scale; + } else if (y > bounds.bottom - SCROLL_ACCURACY) { + ay = Math.min(Math.max(y + SCROLL_ACCURACY - bounds.bottom, 10), 50) / scale; } - if (x < bounds.left + SCROLL_ACCURCY) { - ax = -Math.min(Math.max(bounds.top + SCROLL_ACCURCY - y, 10), 50) / scale; - } else if (x > bounds.right - SCROLL_ACCURCY) { - ax = Math.min(Math.max(x + SCROLL_ACCURCY - bounds.right, 10), 50) / scale; + if (x < bounds.left + SCROLL_ACCURACY) { + ax = -Math.min(Math.max(bounds.top + SCROLL_ACCURACY - y, 10), 50) / scale; + } else if (x > bounds.right - SCROLL_ACCURACY) { + ax = Math.min(Math.max(x + SCROLL_ACCURACY - bounds.right, 10), 50) / scale; } if (!ax && !ay) { diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index b0e509bce8..9effc341dd 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -1225,7 +1225,7 @@ export class Node const isRGLContainerNode = this.isRGLContainer; const isRGLNode = this.getParent()?.isRGLContainer; const isRGL = isRGLContainerNode || (isRGLNode && (!isContainerNode || !isEmptyNode)); - let rglNode = isRGLContainerNode ? this : isRGL ? this?.getParent() : {}; + let rglNode = isRGLContainerNode ? this : isRGL ? this?.getParent() : null; return { isContainerNode, isEmptyNode, isRGLContainerNode, isRGLNode, isRGL, rglNode }; } diff --git a/packages/designer/src/less-variables.less b/packages/designer/src/less-variables.less index c44fc196e2..017e432ce6 100644 --- a/packages/designer/src/less-variables.less +++ b/packages/designer/src/less-variables.less @@ -99,19 +99,19 @@ @brand-link-hover: #2e76a6; // F1-1-7 A10 -@brand-danger-alpha-7: rgba(240, 70, 49, 0.9); +@brand-danger-alpha-7: rgba(240, 70, 49, 0.1); // F1-1-8 A6 @brand-danger-alpha-8: rgba(240, 70, 49, 0.8); // F2-1-2 A80 @brand-warning-alpha-2: rgba(250, 189, 14, 0.8); // F2-1-7 A10 -@brand-warning-alpha-7: rgba(250, 189, 14, 0.9); +@brand-warning-alpha-7: rgba(250, 189, 14, 0.1); // F3-1-2 A80 @brand-success-alpha-2: rgba(102, 188, 92, 0.8); // F3-1-7 A10 -@brand-success-alpha-7: rgba(102, 188, 92, 0.9); +@brand-success-alpha-7: rgba(102, 188, 92, 0.1); // F4-1-7 A10 -@brand-link-alpha-7: rgba(102, 188, 92, 0.9); +@brand-link-alpha-7: rgba(102, 188, 92, 0.1); // 文本色 @text-primary-color: @dark-alpha-3; diff --git a/packages/designer/src/project/project.less b/packages/designer/src/project/project.less index 9d37c73fb4..38f1f74428 100644 --- a/packages/designer/src/project/project.less +++ b/packages/designer/src/project/project.less @@ -14,7 +14,7 @@ } .lc-simulator { - background: rgb(237, 239, 243); + background-color: var(--color-background, rgb(237, 239, 243)); } .lc-simulator-shell { diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index e05002469e..bd4899c9a5 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.1.10", + "version": "1.2.0", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index 10aa0bea1c..f31a2a2dda 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -153,11 +153,7 @@ export class Editor extends EventEmitter implements IEditor { return; } if (!AssetsCache[exportName] || !npm?.version || AssetsCache[exportName].npm?.version !== npm?.version) { - try { - await (new AssetLoader()).load(url); - } catch (error) { - console.error(`${url} load error: `, error); - } + await (new AssetLoader()).load(url); } AssetsCache[exportName] = component; function setAssetsComponent(component: any, extraNpmInfo: any = {}) { diff --git a/packages/editor-core/src/widgets/tip/style.less b/packages/editor-core/src/widgets/tip/style.less index 3c02e5313e..602886d060 100644 --- a/packages/editor-core/src/widgets/tip/style.less +++ b/packages/editor-core/src/widgets/tip/style.less @@ -147,7 +147,7 @@ z-index: 2; position: fixed; box-sizing: border-box; - background: rgba(0, 0, 0, 0.7); + background: var(--color-layer-tooltip-background); max-height: 400px; color: var(--color-text-reverse, rgba(255, 255, 255, 0.8)); left: 0; @@ -156,7 +156,7 @@ opacity: 0; border-radius: 3px; padding: 6px 8px; - text-shadow: 0 -1px rgba(0, 0, 0, 0.3); + text-shadow: 0 -1px var(--color-field-label, rgba(0, 0, 0, 0.3)); font-size: var(--font-size-text); line-height: 14px; max-width: 200px; @@ -178,19 +178,19 @@ height: 8px; &:after { border: 6px solid transparent; - border-top-color: rgba(0, 0, 0, 0.7); + border-top-color: var(--color-layer-tooltip-background, rgba(0, 0, 0, 0.7)); } } &.lc-theme-black { - background: rgba(0, 0, 0, 0.7); + background: var(--color-icon-pane, rgba(0, 0, 0, 0.7)); .lc-arrow:after { - border-top-color: rgba(0, 0, 0, 0.7); + border-top-color: var(--color-layer-tooltip-background, rgba(0, 0, 0, 0.7)); } } &.lc-theme-green { - background: #57a672; + background: var(--color-success-dark, var(--color-function-success-dark, #57a672)); .lc-arrow:after { - border-top-color: #57a672; + border-top-color: var(--color-success-dark, var(--color-function-success-dark, #57a672)); } } &.lc-visible { diff --git a/packages/editor-core/src/widgets/title/title.less b/packages/editor-core/src/widgets/title/title.less index e9d0765522..f6747ef474 100644 --- a/packages/editor-core/src/widgets/title/title.less +++ b/packages/editor-core/src/widgets/title/title.less @@ -21,7 +21,7 @@ cursor: help; text-decoration-line: underline; text-decoration-style: dashed; - text-decoration-color: rgba(31, 56, 88, .3); + text-decoration-color: var(--color-text-light, rgba(31, 56, 88, .3)); } line-height: initial !important; word-break: break-all; diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 2c8efccebf..0b23435f91 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.1.10", + "version": "1.2.0", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/editor-skeleton/src/components/field/fields.tsx b/packages/editor-skeleton/src/components/field/fields.tsx index b773995e3a..21ae93eb25 100644 --- a/packages/editor-skeleton/src/components/field/fields.tsx +++ b/packages/editor-skeleton/src/components/field/fields.tsx @@ -203,40 +203,6 @@ export class Field extends Component { */ function createValueState(/* valueState?: number, onClear?: (e: React.MouseEvent) => void */) { return null; - - /* - let tip: any = null; - let className = 'lc-valuestate'; - let icon: any = null; - if (valueState) { - if (valueState < 0) { - // multiple value 橘黄色点: tip:多种值,点击清除 - tip = intlNode('Multiple Value, Click to Clear'); - className += ' valuestate-multiple'; - icon = ; - } else if (valueState === 10) { - // isset orangered tip: 必填项 - tip = intlNode('Required'); - className += ' valuestate-required'; - onClear = undefined; - } else if (valueState > 0) { - // isset 蓝点 tip: 已设置值,点击清除 - tip = intlNode('Setted Value, Click to Clear'); - className += ' valuestate-isset'; - icon = ; - } - } else { - onClear = undefined; - // unset 占位空间 - } - - return ( - - {icon} - {tip && {tip}} - - ); - */ } export interface PopupFieldProps extends FieldProps { diff --git a/packages/editor-skeleton/src/components/field/index.less b/packages/editor-skeleton/src/components/field/index.less index 249abef570..8c1facfbaf 100644 --- a/packages/editor-skeleton/src/components/field/index.less +++ b/packages/editor-skeleton/src/components/field/index.less @@ -14,54 +14,6 @@ .lc-field-title { display: flex; align-items: center; - .lc-valuestate { - height: 6px; - width: 6px; - min-width: 6px; - border-radius: 100%; - margin-right: 2px; - pointer-events: none; - display: inline-flex; - align-items: center; - justify-content: center; - color: white; - > svg { - display: none; - } - &.valuestate-multiple { - background-color: rgb(232, 145, 83); - pointer-events: auto; - &:hover { - background-color: rgb(223, 139, 30); - cursor: pointer; - transform: scale(2); - transform-origin: center; - > svg { - display: block; - } - } - } - &.valuestate-isset { - background-color: rgba(124, 177, 238, 0.6); - pointer-events: auto; - &:hover { - background-color: rgb(45, 126, 219); - cursor: pointer; - transform: scale(2); - transform-origin: center; - > svg { - display: block; - } - } - } - &.valuestate-required { - background-color: rgb(250, 82, 76); - pointer-events: auto; - &:hover { - background-color: rgb(224, 46, 40); - } - } - } } .lc-field-icon { transform-origin: center; @@ -92,11 +44,7 @@ &.lc-block-field, &.lc-accordion-field, &.lc-entry-field { display: block; - &:first-child { - > .lc-field-head { - // border-top: none; - } - } + > .lc-field-head { height: 32px; display: flex; @@ -110,7 +58,7 @@ user-select: none; > .lc-field-icon { - color: #8f9bb3; + color: var(--color-icon-normal, #8f9bb3); } } @@ -128,10 +76,6 @@ } } } - - // + .lc-inline-field { - // border-top: 1px solid var(--color-line-normal); - // } } &.lc-entry-field { @@ -163,15 +107,11 @@ > .lc-field-head { cursor: pointer; } - + &.lc-field-is-collapsed { margin-bottom: 6px; } - // collapsed - // &:last-child.lc-field-is-collapsed{ - // border-bottom: 1px solid var(--color-line-normal); - // } &.lc-field-is-collapsed { > .lc-field-head .lc-field-icon { transform: rotate(180deg); @@ -180,56 +120,5 @@ display: none; } } - - // 邻近的保持上下距离 - + .lc-field { - // margin-top: @y-gap; - } - } - - // 2rd level reset - .lc-field-body { - // .lc-inline-field { - // &:first-child { - // padding-top: 0; - // } - // + .lc-accordion-field, +.lc-block-field { - // margin-top: @y-gap; - // } - // } - - // .lc-field { - // border-top: none !important; - // } - - // .lc-accordion-field, .lc-block-field { - // > .lc-field-head { - // padding-left: @x-gap; - // background: var(--color-block-background-light); - // border-bottom: none; - // border-top: none; - // > .lc-field-icon { - // // margin-right: @x-gap/2; - // margin-right: 0; - // } - // } - - // > .lc-field-body { - // padding: 8px; - // } - // } - - // 3rd level field title width should short - // .lc-field-body .lc-inline-field { - // > .lc-field-head { - // width: 50px; - // .lc-title-label { - // width: 50px; - // } - // } - // } - // >.lc-block-setter { - // flex: 1; - // } } } diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index 800719588f..a68647ed0d 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -64,7 +64,6 @@ export class SettingsPrimaryPane extends Component {createIcon(settings.componentMeta?.icon, { className: 'lc-settings-navigator-icon', - class: 'lc-settings-navigator-icon', })} <span> x {settings.nodes.length}</span> diff --git a/packages/editor-skeleton/src/components/settings/style.less b/packages/editor-skeleton/src/components/settings/style.less index 23b707afd8..4599ed55c2 100644 --- a/packages/editor-skeleton/src/components/settings/style.less +++ b/packages/editor-skeleton/src/components/settings/style.less @@ -33,14 +33,6 @@ position: relative; margin-bottom: 4px; position: absolute; - - .lc-setting-stage-back-icon { - position: absolute; - left: 8px; - top: 8px; - color: #8f9bb3; - cursor: pointer; - } } .lc-settings-notice { @@ -143,7 +135,6 @@ .lc-outline-pane { position: absolute; z-index: 100; - background-color: white; top: 0; bottom: 0; display: none; diff --git a/packages/editor-skeleton/src/index.ts b/packages/editor-skeleton/src/index.ts index d4851ff5b0..a39b445d1f 100644 --- a/packages/editor-skeleton/src/index.ts +++ b/packages/editor-skeleton/src/index.ts @@ -8,3 +8,4 @@ export * from './components/popup'; export * from './context'; export * from './register-defaults'; export * from './widget'; +export * from './layouts'; diff --git a/packages/editor-skeleton/src/layouts/index.ts b/packages/editor-skeleton/src/layouts/index.ts new file mode 100644 index 0000000000..b3c7a10580 --- /dev/null +++ b/packages/editor-skeleton/src/layouts/index.ts @@ -0,0 +1,7 @@ +export { default as LeftArea } from './left-area'; +export { default as LeftFloatPane } from './left-float-pane'; +export { default as LeftFixedPane } from './left-fixed-pane'; +export { default as MainArea } from './main-area'; +export { default as BottomArea } from './bottom-area'; +export { default as TopArea } from './top-area'; +export { default as SubTopArea } from './sub-top-area'; \ No newline at end of file diff --git a/packages/editor-skeleton/src/layouts/left-area.tsx b/packages/editor-skeleton/src/layouts/left-area.tsx index cbeba5a5c8..d30dcfa863 100644 --- a/packages/editor-skeleton/src/layouts/left-area.tsx +++ b/packages/editor-skeleton/src/layouts/left-area.tsx @@ -4,14 +4,14 @@ import { observer } from '@alilc/lowcode-editor-core'; import { Area } from '../area'; @observer -export default class LeftArea extends Component<{ area: Area }> { +export default class LeftArea extends Component<{ area: Area; className?: string }> { render() { - const { area } = this.props; + const { area, className = 'lc-left-area' } = this.props; if (area.isEmpty()) { return null; } return ( - <div className={classNames('lc-left-area', { + <div className={classNames(className, { 'lc-area-visible': area.visible, })} > @@ -21,7 +21,6 @@ export default class LeftArea extends Component<{ area: Area }> { } } - @observer class Contents extends Component<{ area: Area }> { render() { diff --git a/packages/editor-skeleton/src/layouts/right-area.tsx b/packages/editor-skeleton/src/layouts/right-area.tsx index 4393eef55f..f00ae1461a 100644 --- a/packages/editor-skeleton/src/layouts/right-area.tsx +++ b/packages/editor-skeleton/src/layouts/right-area.tsx @@ -22,14 +22,23 @@ export default class RightArea extends Component<{ area: Area<any, Panel> }> { } } - @observer class Contents extends Component<{ area: Area<any, Panel> }> { render() { const { area } = this.props; + return ( <Fragment> - {area.container.items.map((item) => item.content)} + { + area.container.items + .slice() + .sort((a, b) => { + const index1 = a.config?.index || 0; + const index2 = b.config?.index || 0; + return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1); + }) + .map((item) => item.content) + } </Fragment> ); } diff --git a/packages/workspace/src/layouts/sub-top-area.tsx b/packages/editor-skeleton/src/layouts/sub-top-area.tsx similarity index 79% rename from packages/workspace/src/layouts/sub-top-area.tsx rename to packages/editor-skeleton/src/layouts/sub-top-area.tsx index e6bf61871a..cef6aa5b02 100644 --- a/packages/workspace/src/layouts/sub-top-area.tsx +++ b/packages/editor-skeleton/src/layouts/sub-top-area.tsx @@ -13,7 +13,7 @@ export default class SubTopArea extends Component<{ area: Area; itemClassName?: } return ( - <div className={classNames('lc-sub-top-area engine-actionpane', { + <div className={classNames('lc-workspace-sub-top-area lc-sub-top-area engine-actionpane', { 'lc-area-visible': area.visible, })} > @@ -50,13 +50,13 @@ class Contents extends Component<{ area: Area; itemClassName?: string }> { }); let children = []; if (left && left.length) { - children.push(<div className="lc-sub-top-area-left">{left}</div>); + children.push(<div className="lc-workspace-sub-top-area-left lc-sub-top-area-left">{left}</div>); } if (center && center.length) { - children.push(<div className="lc-sub-top-area-center">{center}</div>); + children.push(<div className="lc-workspace-sub-top-area-center lc-sub-top-area-center">{center}</div>); } if (right && right.length) { - children.push(<div className="lc-sub-top-area-right">{right}</div>); + children.push(<div className="lc-workspace-sub-top-area-right lc-sub-top-area-right">{right}</div>); } return ( <Fragment> diff --git a/packages/editor-skeleton/src/layouts/theme.less b/packages/editor-skeleton/src/layouts/theme.less index b0da053db1..716ab3a99e 100644 --- a/packages/editor-skeleton/src/layouts/theme.less +++ b/packages/editor-skeleton/src/layouts/theme.less @@ -16,6 +16,8 @@ --color-icon-hover: @normal-alpha-3; --color-icon-active: @brand-color-1; --color-icon-reverse: @white-alpha-1; + --color-icon-disabled: @normal-alpha-6; + --color-icon-pane: @dark-alpha-3; --color-line-normal: @normal-alpha-7; --color-line-darken: darken(@normal-alpha-7, 10%); @@ -26,6 +28,7 @@ --color-text-light: lighten(@dark-alpha-3, 10%); --color-text-reverse: @white-alpha-2; --color-text-regular: @normal-alpha-2; + --color-text-disabled: @gray-light; --color-field-label: @dark-alpha-4; --color-field-text: @dark-alpha-3; @@ -35,18 +38,20 @@ --color-field-border-active: @normal-alpha-3; --color-field-background: @white-alpha-1; - --color-function-success: @brand-success; - --color-function-success-dark: darken(@brand-success, 10%); - --color-function-success-light: lighten(@brand-success, 10%); - --color-function-warning: @brand-warning; - --color-function-warning-dark: darken(@brand-warning, 10%); - --color-function-warning-light: lighten(@brand-warning, 10%); - --color-function-information: @brand-link-hover; - --color-function-information-dark: darken(@brand-link-hover, 10%); - --color-function-information-light: lighten(@brand-link-hover, 10%); - --color-function-error: @brand-danger; - --color-function-error-dark: darken(@brand-danger, 10%); - --color-function-error-light: lighten(@brand-danger, 10%); + --color-success: @brand-success; + --colo-success-dark: darken(@brand-success, 10%); + --color-success-light: lighten(@brand-success, 10%); + --color-warning: @brand-warning; + --color-warning-dark: darken(@brand-warning, 10%); + --color-warning-light: lighten(@brand-warning, 10%); + --color-information: @brand-link-hover; + --color-information-dark: darken(@brand-link-hover, 10%); + --color-information-light: lighten(@brand-link-hover, 10%); + --color-error: @brand-danger; + --color-error-dark: darken(@brand-danger, 10%); + --color-error-light: lighten(@brand-danger, 10%); + --color-purple: rgb(144, 94, 190); + --color-brown: #7b605b; --color-pane-background: @white-alpha-1; --color-block-background-normal: @white-alpha-1; @@ -54,9 +59,32 @@ --color-block-background-shallow: @normal-alpha-8; --color-block-background-dark: @normal-alpha-7; --color-block-background-disabled: @normal-alpha-6; + --color-block-background-active: @brand-color-1-7; + --color-block-background-warning: @brand-warning-alpha-7; + --color-block-background-error: @brand-danger-alpha-7; + --color-block-background-success: @brand-success-alpha-7; --color-block-background-deep-dark: @normal-5; --color-layer-mask-background: @dark-alpha-7; --color-layer-tooltip-background: rgba(44,47,51,0.8); + --color-background: #edeff3; --pane-title-bg-color: rgba(31,56,88,.04); } + +// @deprecated 变量 +:root { + --color-function-success: @brand-success; + --color-function-success-dark: darken(@brand-success, 10%); + --color-function-success-light: lighten(@brand-success, 10%); + --color-function-warning: @brand-warning; + --color-function-warning-dark: darken(@brand-warning, 10%); + --color-function-warning-light: lighten(@brand-warning, 10%); + --color-function-information: @brand-link-hover; + --color-function-information-dark: darken(@brand-link-hover, 10%); + --color-function-information-light: lighten(@brand-link-hover, 10%); + --color-function-error: @brand-danger; + --color-function-error-dark: darken(@brand-danger, 10%); + --color-function-error-light: lighten(@brand-danger, 10%); + --color-function-purple: rgb(144, 94, 190); + --color-function-brown: #7b605b; +} diff --git a/packages/editor-skeleton/src/layouts/top-area.tsx b/packages/editor-skeleton/src/layouts/top-area.tsx index 56949cbb7f..f6b84b3e6f 100644 --- a/packages/editor-skeleton/src/layouts/top-area.tsx +++ b/packages/editor-skeleton/src/layouts/top-area.tsx @@ -4,14 +4,14 @@ import { observer } from '@alilc/lowcode-editor-core'; import { Area } from '../area'; @observer -export default class TopArea extends Component<{ area: Area; itemClassName?: string }> { +export default class TopArea extends Component<{ area: Area; itemClassName?: string; className?: string }> { render() { - const { area, itemClassName } = this.props; + const { area, itemClassName, className } = this.props; if (area.isEmpty()) { return null; } return ( - <div className={classNames('lc-top-area engine-actionpane', { + <div className={classNames(className, 'lc-top-area engine-actionpane', { 'lc-area-visible': area.visible, })} > diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index fccdad4c2d..6d0604a1f1 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -38,7 +38,7 @@ body { font-family: var(--font-family); font-size: var(--font-size-text); color: var(--color-text); - background-color: #edeff3; + background-color: var(--color-background); } * { @@ -49,13 +49,10 @@ body { width: 100%; height: 100%; position: relative; - background-color: #fff; - background-color: var(--color-pane-background); &.hidden { display: none; } .lc-panel-title { - // background-color: var(--pane-title-bg-color,rgba(31,56,88,.04)); display: flex; align-items: center; justify-content: flex-start; @@ -63,7 +60,7 @@ body { .lc-help-tip { margin-left: 4px; - color: rgba(0, 0, 0, 0.4); + color: var(--color-icon-normal, rgba(0, 0, 0, 0.4)); cursor: pointer; } } @@ -71,8 +68,7 @@ body { height: 48px; font-size: 16px; padding: 0 15px; - // border-bottom: 1px solid var(--color-line-normal,rgba(31,56,88,.1)); - color: #0f1726; + color: var(--color-title, #0f1726); font-weight: bold; } @@ -83,39 +79,6 @@ body { left: 0; right: 0; overflow: visible; - /* - .my-tabs { - width: 100%; - height: 100%; - position: relative; - .tabs-title { - display: flex; - height: var(--pane-title-height); - > .tab-title { - cursor: pointer; - padding: 0; - flex: 1; - min-width: 0; - justify-content: center; - border-bottom: 2px solid transparent; - &.actived { - cursor: default; - color: var(--color-text-avtived); - border-bottom-color: #3896ee; - } - } - } - .tabs-content { - position: absolute; - top: var(--pane-title-height); - bottom: 0; - left: 0; - right: 0; - height: calc(100% - var(--pane-title-height)); - overflow: hidden; - } - } - */ } .lc-outline-tree-container { border-top: 1px solid var(--color-line-normal, rgba(31, 56, 88, 0.1)); @@ -125,9 +88,6 @@ body { height: 100%; width: 100%; position: relative; - background-color: #fff; - background-color: var(--color-pane-background); - // overflow: auto; &.hidden { display: none; } @@ -137,7 +97,7 @@ body { height: 100%; display: flex; flex-direction: column; - background-color: #edeff3; + background-color: var(--color-background); position: absolute; left: 0; top: 0; @@ -164,47 +124,62 @@ body { &.active { z-index: 999; - background: #edeff3; + background: var(--color-background); } } } -.lc-workbench { +.lc-workbench, .lc-workspace-workbench { height: 100%; display: flex; flex-direction: column; - background-color: #edeff3; + background-color: var(--color-background); &.engine-main { height: 100%; display: flex; flex-direction: column; - background-color: #edeff3; + background-color: var(--color-background); } - .lc-top-area { - height: var(--top-area-height); - background-color: var(--color-pane-background); + .lc-top-area, .lc-workspace-sub-top-area { width: 100%; display: none; margin-bottom: 2px; padding: 8px 12px 8px 16px; + &.lc-top-area { + background-color: var(--color-top-area-background, var(--color-pane-background)); + height: var(--top-area-height); + } + + &.lc-workspace-top-area { + background-color: var(--color-workspace-top-area-background, var(--color-pane-background)); + } + + &.lc-workspace-sub-top-area { + background-color: var(--color-workspace-sub-top-area-background, var(--color-pane-background)); + height: var(--workspace-sub-top-area-height, var(--top-area-height)); + margin: var(--workspace-sub-top-area-margin, 0px 0px 2px 0px); + padding: var(--workspace-sub-top-area-padding, 8px 12px 8px 16px); + } + &.lc-area-visible { display: flex; } - .lc-top-area-left { + .lc-top-area-left, .lc-workspace-sub-top-area-left { display: flex; align-items: center; + max-width: 100%; } - .lc-top-area-center { + .lc-top-area-center, .lc-workspace-sub-top-area-center { flex: 1; display: flex; justify-content: center; margin: 0 8px; } - .lc-top-area-right { + .lc-top-area-right, .lc-workspace-sub-top-area-right { display: flex; align-items: center; > * { @@ -216,7 +191,7 @@ body { } } } - .lc-workbench-body { + .lc-workbench-body, .lc-workspace-workbench-body { flex: 1; display: flex; min-height: 0; @@ -230,8 +205,7 @@ body { display: flex; justify-content: center; align-items: center; - // background: rgba(31,56,88,0.04); - border-bottom: 1px solid #edeff3; + border-bottom: 1px solid var(--color-line-normal, #edeff3); .lc-tab-title { flex: 1; height: 32px; @@ -242,8 +216,8 @@ body { cursor: pointer; font-size: 12px; &.actived { - color: #0079f2; - border-bottom-color: #0079f2; + color: var(--color-brand, #0079f2); + border-bottom-color: var(--color-brand, #0079f2); } } } @@ -264,7 +238,7 @@ body { z-index: 2; .next-icon { line-height: 1; - color: rgba(0, 0, 0, 0.6); + color: var(--color-icon-pane); } } @@ -277,7 +251,7 @@ body { z-index: 2; svg { vertical-align: middle; - color: rgba(0, 0, 0, 0.6); + color: var(--color-icon-pane); } } @@ -288,8 +262,8 @@ body { width: var(--dock-pane-width); // min-width: var(--dock-fixed-pane-width); left: calc(var(--left-area-width) + 1px); - background-color: var(--color-pane-background); - box-shadow: 4px 6px 6px 0 rgba(31, 50, 88, 0.08); + background-color: var(--color-left-float-pane-background, var(--color-pane-background)); + box-shadow: 4px 6px 6px 0 var(--color-block-background-shallow, rgba(31, 50, 88, 0.08)); z-index: 820; display: none; // padding-top: 36px; @@ -297,15 +271,19 @@ body { display: block; } } - .lc-left-area { + .lc-left-area, .lc-workspace-left-area { height: 100%; width: var(--left-area-width); - background-color: var(--color-pane-background); display: none; flex-shrink: 0; flex-direction: column; justify-content: space-between; overflow: hidden; + background-color: var(--color-left-area-background, var(--color-pane-background)); + + &.lc-workspace-left-area { + background-color: var(--color-workspace-left-area-background, var(--color-pane-background)); + } &.lc-area-visible { display: flex; } @@ -316,6 +294,8 @@ body { flex-direction: column; justify-content: flex-start; align-items: center; + color: var(--color-text); + .lc-title { flex-direction: column; width: calc(var(--left-area-width) - 2px); @@ -325,8 +305,11 @@ body { justify-content: center; cursor: pointer; + &.has-tip { + cursor: pointer; + } &.actived { - color: #0079f2; + color: var(--color-brand, #0079f2); } &.disabled { opacity: 0.4; @@ -366,6 +349,9 @@ body { .lc-left-area.lc-area-visible ~ .lc-workbench-center { margin-left: 2px; } + .lc-workspace-left-area.lc-area-visible ~ .lc-workspace-workbench-center { + margin-left: 2px; + } .lc-outline-pane { .lc-outline-tree .tree-node .tree-node-title { border-bottom: none; @@ -390,7 +376,7 @@ body { } .lc-main-area { flex: 1; - background-color: #edeff3; + background-color: var(--color-background); } .lc-bottom-area { height: var(--bottom-area-height); @@ -404,15 +390,17 @@ body { .lc-right-area { height: 100%; width: var(--right-area-width); - background-color: var(--color-pane-background); + background-color: var(--color-right-area-background, var(--color-pane-background)); display: none; flex-shrink: 0; margin-left: 2px; position: relative; > .lc-panel { position: absolute; + background-color: var(--color-right-area-background, var(--color-pane-background, #fff)); left: 0; top: 0; + z-index: 1; } &.lc-area-visible { display: block; @@ -437,4 +425,68 @@ body { } } } + .engine-actionitem { + max-width: 100%; + color: var(--color-text); + } +} + +.lc-workspace-workbench { + height: 100%; + display: flex; + flex-direction: column; + background-color: var(--color-background); + .lc-workspace-workbench-body { + flex: 1; + display: flex; + min-height: 0; + position: relative; + + .lc-workspace-workbench-center { + flex: 1; + display: flex; + flex-direction: column; + z-index: 10; + position: relative; + .lc-toolbar { + display: flex; + height: var(--toolbar-height); + background-color: var(--color-pane-background); + padding: 8px 16px; + .lc-toolbar-center { + display: flex; + justify-content: center; + align-items: center; + flex: 1; + } + } + .lc-main-area { + flex: 1; + } + .lc-bottom-area { + height: var(--bottom-area-height); + background-color: var(--color-pane-background); + display: none; + &.lc-area-visible { + display: block; + } + } + } + + .lc-workspace-workbench-center-content { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + flex-direction: column; + display: flex; + align-content: stretch; + } + + .lc-workspace-workbench-window { + position: relative; + height: 100%; + } + } } diff --git a/packages/editor-skeleton/src/less-variables.less b/packages/editor-skeleton/src/less-variables.less index c44fc196e2..017e432ce6 100644 --- a/packages/editor-skeleton/src/less-variables.less +++ b/packages/editor-skeleton/src/less-variables.less @@ -99,19 +99,19 @@ @brand-link-hover: #2e76a6; // F1-1-7 A10 -@brand-danger-alpha-7: rgba(240, 70, 49, 0.9); +@brand-danger-alpha-7: rgba(240, 70, 49, 0.1); // F1-1-8 A6 @brand-danger-alpha-8: rgba(240, 70, 49, 0.8); // F2-1-2 A80 @brand-warning-alpha-2: rgba(250, 189, 14, 0.8); // F2-1-7 A10 -@brand-warning-alpha-7: rgba(250, 189, 14, 0.9); +@brand-warning-alpha-7: rgba(250, 189, 14, 0.1); // F3-1-2 A80 @brand-success-alpha-2: rgba(102, 188, 92, 0.8); // F3-1-7 A10 -@brand-success-alpha-7: rgba(102, 188, 92, 0.9); +@brand-success-alpha-7: rgba(102, 188, 92, 0.1); // F4-1-7 A10 -@brand-link-alpha-7: rgba(102, 188, 92, 0.9); +@brand-link-alpha-7: rgba(102, 188, 92, 0.1); // 文本色 @text-primary-color: @dark-alpha-3; diff --git a/packages/editor-skeleton/src/skeleton.ts b/packages/editor-skeleton/src/skeleton.ts index 8836434049..89bffc4cfe 100644 --- a/packages/editor-skeleton/src/skeleton.ts +++ b/packages/editor-skeleton/src/skeleton.ts @@ -108,7 +108,7 @@ export interface ISkeleton extends Omit<IPublicApiSkeleton, add(config: IPublicTypeSkeletonConfig, extraConfig?: Record<string, any>): IWidget | Widget | Panel | Stage | Dock | PanelDock | undefined; } -export class Skeleton { +export class Skeleton implements ISkeleton { private panels = new Map<string, Panel>(); private containers = new Map<string, WidgetContainer<any>>(); diff --git a/packages/engine/package.json b/packages/engine/package.json index a9521d486b..59ecb02610 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.1.10", + "version": "1.2.0", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-editor-skeleton": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-editor-skeleton": "1.2.0", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.1.10", - "@alilc/lowcode-plugin-outline-pane": "1.1.10", - "@alilc/lowcode-shell": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", - "@alilc/lowcode-workspace": "1.1.10", + "@alilc/lowcode-plugin-designer": "1.2.0", + "@alilc/lowcode-plugin-outline-pane": "1.2.0", + "@alilc/lowcode-shell": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-workspace": "1.2.0", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/engine/src/inner-plugins/builtin-hotkey.ts b/packages/engine/src/inner-plugins/builtin-hotkey.ts index 692773a756..1a1f3a9c44 100644 --- a/packages/engine/src/inner-plugins/builtin-hotkey.ts +++ b/packages/engine/src/inner-plugins/builtin-hotkey.ts @@ -277,6 +277,10 @@ export const builtinHotkey = (ctx: IPublicModelPluginContext) => { if (isFormEvent(e) || !doc) { return; } + const anchorValue = document.getSelection()?.anchorNode?.nodeValue; + if (anchorValue && typeof anchorValue === 'string') { + return; + } e.preventDefault(); let selected = doc.selection.getTopNodes(true); diff --git a/packages/engine/src/inner-plugins/default-panel-registry.tsx b/packages/engine/src/inner-plugins/default-panel-registry.tsx index d7549d764b..b5f538d44c 100644 --- a/packages/engine/src/inner-plugins/default-panel-registry.tsx +++ b/packages/engine/src/inner-plugins/default-panel-registry.tsx @@ -28,6 +28,9 @@ export const defaultPanelRegistry = (editor: any) => { props: { ignoreRoot: true, }, + panelProps: { + ...(config.get('defaultSettingPanelProps') || {}), + }, }); } }, @@ -39,5 +42,4 @@ export const defaultPanelRegistry = (editor: any) => { return fun; }; - export default defaultPanelRegistry; diff --git a/packages/engine/src/modules/symbols.ts b/packages/engine/src/modules/symbols.ts index a0371abf98..55c70e5dcb 100644 --- a/packages/engine/src/modules/symbols.ts +++ b/packages/engine/src/modules/symbols.ts @@ -12,6 +12,9 @@ import { propSymbol, simulatorHostSymbol, skeletonItemSymbol, + editorCabinSymbol, + skeletonCabinSymbol, + simulatorRenderSymbol, } from '@alilc/lowcode-shell'; export default { @@ -25,7 +28,10 @@ export default { settingPropEntrySymbol: settingFieldSymbol, settingTopEntrySymbol, designerCabinSymbol, + editorCabinSymbol, + skeletonCabinSymbol, propSymbol, simulatorHostSymbol, skeletonItemSymbol, + simulatorRenderSymbol, }; diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 116f98e5d5..f524eba845 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.1.10", + "version": "1.2.0", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 760d57a133..65c931ef37 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.1.10", + "version": "1.2.0", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 4a71eb26b8..e933128018 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.1.10", + "version": "1.2.0", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/plugin-outline-pane/src/index.tsx b/packages/plugin-outline-pane/src/index.tsx index addebbb402..822c503f27 100644 --- a/packages/plugin-outline-pane/src/index.tsx +++ b/packages/plugin-outline-pane/src/index.tsx @@ -92,6 +92,7 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => { paneName: BackupPaneName, treeMaster, }, + index: 1, }); // 处理 master pane 和 backup pane 切换 diff --git a/packages/plugin-outline-pane/src/locale/en-US.json b/packages/plugin-outline-pane/src/locale/en-US.json index 9ade9e66f4..b86a7859bb 100644 --- a/packages/plugin-outline-pane/src/locale/en-US.json +++ b/packages/plugin-outline-pane/src/locale/en-US.json @@ -10,7 +10,7 @@ "Loop": "Loop", "Slots": "Slots", "Slot for {prop}": "Slot for {prop}", - "Outline Tree": "Outline Tree", + "Outline Tree": "Component Tree", "Filter Node": "Filter Node", "Check All": "Check All", "Conditional rendering": "Conditional rendering", diff --git a/packages/plugin-outline-pane/src/views/style.less b/packages/plugin-outline-pane/src/views/style.less index 254b639d62..15f115ea6b 100644 --- a/packages/plugin-outline-pane/src/views/style.less +++ b/packages/plugin-outline-pane/src/views/style.less @@ -3,7 +3,6 @@ width: 100%; position: relative; z-index: 200; - background-color: white; > .lc-outline-tree-container { top: 52px; @@ -29,8 +28,8 @@ } .lc-outline-filter-icon { - background: #ebecf0; - border: 1px solid #c4c6cf; + background: var(--color-block-background-shallow, #ebecf0); + border: 1px solid var(--color-field-border, #c4c6cf); display: flex; align-items: center; border-radius: 0 2px 2px 0; @@ -55,17 +54,17 @@ .tree-node-modal { margin: 5px; - border: 1px solid rgba(31, 56, 88, 0.2); + border: 1px solid var(--color-field-border, rgba(31, 56, 88, 0.2)); border-radius: 3px; - box-shadow: 0 1px 4px 0 rgba(31, 56, 88, 0.15); + box-shadow: 0 1px 4px 0 var(--color-block-background-shallow, rgba(31, 56, 88, 0.15)); .tree-node-modal-title { position: relative; - background: rgba(31, 56, 88, 0.04); + background: var(--color-block-background-light, rgba(31, 56, 88, 0.04)); padding: 0 10px; height: 32px; line-height: 32px; - border-bottom: 1px solid rgba(31, 56, 88, 0.2); + border-bottom: 1px solid var(--color-field-border, rgba(31, 56, 88, 0.2)); .tree-node-modal-title-visible-icon { position: absolute; @@ -90,7 +89,7 @@ left: 6px; } .tree-node-modal-radio-active { - color: #006cff; + color: var(--color-brand, #006cff); } } @@ -109,7 +108,7 @@ &:hover { .tree-node-branches::before { - border-left-color: #ddd; + border-left-color: var(--color-line-darken, #ddd); } } @@ -121,20 +120,20 @@ transform: translateZ(0); transition: all 0.2s ease-in-out; &.invalid { - border-color: red; - background-color: rgba(240, 154, 154, 0.719); + border-color: var(--color-error, var(--color-function-error, red)); + background-color: var(--color-block-background-error, rgba(240, 154, 154, 0.719)); } } .condition-group-container { - border-bottom: 1px solid #7b605b; + border-bottom: 1px solid var(--color-brown, var(--color-function-brown, #7b605b)); position: relative; &:before { position: absolute; display: block; width: 0; - border-left: 0.5px solid #7b605b; + border-left: 0.5px solid var(--color-brown, var(--color-function-brown, #7b605b)); height: 100%; top: 0; left: 0; @@ -143,26 +142,26 @@ } > .condition-group-title { text-align: center; - background-color: #7b605b; + background-color: var(--color-brown, var(--color-function-brown, #7b605b)); height: 14px; > .lc-title { font-size: 12px; transform: scale(0.8); transform-origin: top; - color: white; - text-shadow: 0 0 2px black; + color: var(--color-text-reverse, white); + text-shadow: 0 0 2px var(--color-block-background-shallow, black); display: block; } } } .tree-node-slots { - border-bottom: 1px solid rgb(144, 94, 190); + border-bottom: 1px solid var(--color-purple, var(--color-function-purple, rgb(144, 94, 190))); position: relative; &::before { position: absolute; display: block; width: 0; - border-left: 0.5px solid rgb(144, 94, 190); + border-left: 0.5px solid var(--color-purple, var(--color-function-purple, rgb(144, 94, 190))); height: 100%; top: 0; left: 0; @@ -171,25 +170,25 @@ } > .tree-node-slots-title { text-align: center; - background-color: rgb(144, 94, 190); + background-color: var(--color-purple, var(--color-function-purple, rgb(144, 94, 190))); height: 14px; > .lc-title { font-size: 12px; transform: scale(0.8); transform-origin: top; - color: white; + color: var(--color-text-reverse, white); text-shadow: 0 0 2px black; display: block; } } &.insertion-at-slots { padding-bottom: @treeNodeHeight; - border-bottom-color: rgb(182, 55, 55); + border-bottom-color: var(--color-error-dark, var(--color-function-error-dark, rgb(182, 55, 55))); > .tree-node-slots-title { - background-color: rgb(182, 55, 55); + background-color: var(--color-error-dark, var(--color-function-error-dark, rgb(182, 55, 55))); } &::before { - border-left-color: rgb(182, 55, 55); + border-left-color: var(--color-error-dark, var(--color-function-error-dark, rgb(182, 55, 55))); } } } @@ -245,7 +244,6 @@ .tree-node-title { font-size: var(--font-size-text); cursor: pointer; - background: var(--color-pane-background); border-bottom: 1px solid var(--color-line-normal, rgba(31, 56, 88, 0.1)); display: flex; align-items: center; @@ -328,13 +326,13 @@ align-items: center; line-height: 0; &.cond { - color: rgb(179, 52, 6); + color: var(--color-error, var(--color-function-error, rgb(179, 52, 6))); } &.loop { - color: rgb(103, 187, 187); + color: var(--color-success, var(--color-function-success, rgb(103, 187, 187))); } &.slot { - color: rgb(211, 90, 211); + color: var(--color-purple, var(--color-function-purple, rgb(211, 90, 211))); } } } @@ -368,7 +366,7 @@ &.hidden { .tree-node-title-label { - color: #9b9b9b; + color: var(--color-text-disabled, #9b9b9b); } & > .tree-node-title > .tree-node-hide-btn { opacity: 0.8; diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index 02ac94ae69..c8c0e75b09 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -83,6 +83,7 @@ export default class TreeTitle extends PureComponent<{ editing: false, title: treeNode.titleLabel, condition: treeNode.condition, + visible: !treeNode.hidden, }); treeNode.onTitleLabelChanged(() => { this.setState({ diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 90a9b7e08e..7d55b5ae6c 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.1.10", + "version": "1.2.0", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-renderer-core": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 8ff7f1f0a4..69a029578c 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.1.10", + "version": "1.2.0", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-rax-renderer": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-rax-renderer": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 1535cb2088..f1d8b5ea54 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.1.10", + "version": "1.2.0", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.1.10" + "@alilc/lowcode-renderer-core": "1.2.0" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index ffb8228dfd..a265c3e88f 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.1.10", + "version": "1.2.0", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-react-renderer": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-react-renderer": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/react-simulator-renderer/src/locale/index.ts b/packages/react-simulator-renderer/src/locale/index.ts index e4b39a347c..5f4ef01505 100644 --- a/packages/react-simulator-renderer/src/locale/index.ts +++ b/packages/react-simulator-renderer/src/locale/index.ts @@ -9,10 +9,10 @@ const instance: Record<string, Record<string, string>> = { export function createIntl(locale: string = 'zh-CN') { const intl = (id: string) => { - return instance[locale][id]; + return instance[locale]?.[id] || id; }; - const intlNode = (id: string) => createElement('span', instance[locale][id]); + const intlNode = (id: string) => createElement('span', instance[locale]?.[id] || id); return { intl, diff --git a/packages/react-simulator-renderer/test/src/renderer/__snapshots__/demo.test.tsx.snap b/packages/react-simulator-renderer/test/src/renderer/__snapshots__/demo.test.tsx.snap index 0ebb606dac..2f2d19f269 100644 --- a/packages/react-simulator-renderer/test/src/renderer/__snapshots__/demo.test.tsx.snap +++ b/packages/react-simulator-renderer/test/src/renderer/__snapshots__/demo.test.tsx.snap @@ -31,6 +31,7 @@ exports[`Base should be render Text 1`] = ` behavior="NORMAL" componentId="node_ockvuu8u916" fieldId="text_kvuu9gl2" + forwardRef={[Function]} maxLine={0} showTitle={false} > diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 52b13b86c6..ecfd233809 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.1.10", + "version": "1.2.0", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/renderer-core/src/hoc/index.tsx b/packages/renderer-core/src/hoc/index.tsx index a9314060f3..3e7f5ec6a1 100644 --- a/packages/renderer-core/src/hoc/index.tsx +++ b/packages/renderer-core/src/hoc/index.tsx @@ -1,20 +1,88 @@ import { cloneEnumerableProperty } from '@alilc/lowcode-utils'; import adapter from '../adapter'; +import { IBaseRendererInstance, IRendererProps } from '../types'; -export function compWrapper(Comp: any) { +interface Options { + baseRenderer: IBaseRendererInstance; + schema: any; +} + +function patchDidCatch(Comp: any, { baseRenderer }: Options) { + if (Comp.patchedCatch) { + return; + } + Comp.patchedCatch = true; + const { PureComponent } = adapter.getRuntime(); + // Rax 的 getDerivedStateFromError 有 BUG,这里先用 componentDidCatch 来替代 + // @see https://github.com/alibaba/rax/issues/2211 + const originalDidCatch = Comp.prototype.componentDidCatch; + Comp.prototype.componentDidCatch = function didCatch(this: any, error: Error, errorInfo: any) { + this.setState({ engineRenderError: true, error }); + if (originalDidCatch && typeof originalDidCatch === 'function') { + originalDidCatch.call(this, error, errorInfo); + } + }; + + const { engine } = baseRenderer.context; + const originRender = Comp.prototype.render; + Comp.prototype.render = function () { + if (this.state && this.state.engineRenderError) { + this.state.engineRenderError = false; + return engine.createElement(engine.getFaultComponent(), { + ...this.props, + error: this.state.error, + componentName: this.props._componentName, + }); + } + return originRender.call(this); + }; + if (!(Comp.prototype instanceof PureComponent)) { + const originShouldComponentUpdate = Comp.prototype.shouldComponentUpdate; + Comp.prototype.shouldComponentUpdate = function (nextProps: IRendererProps, nextState: any) { + if (nextState && nextState.engineRenderError) { + return true; + } + return originShouldComponentUpdate + ? originShouldComponentUpdate.call(this, nextProps, nextState) + : true; + }; + } +} + +const cache = new Map(); + +export function compWrapper(Comp: any, options: Options) { const { createElement, Component, forwardRef } = adapter.getRuntime(); - class Wrapper extends Component { - // constructor(props: any, context: any) { - // super(props, context); - // } + if ( + Comp?.prototype?.isReactComponent || // react + Comp?.prototype?.setState || // rax + Comp?.prototype instanceof Component + ) { + patchDidCatch(Comp, options); + return Comp; + } + + if (cache.has(options.schema.id)) { + return cache.get(options.schema.id); + } + class Wrapper extends Component { render() { - return createElement(Comp, this.props); + return createElement(Comp, { ...this.props, ref: this.props.forwardRef }); } } (Wrapper as any).displayName = Comp.displayName; - return cloneEnumerableProperty(forwardRef((props: any, ref: any) => { - return createElement(Wrapper, { ...props, forwardRef: ref }); - }), Comp); + patchDidCatch(Wrapper, options); + + const WrapperComponent = cloneEnumerableProperty( + forwardRef((props: any, ref: any) => { + return createElement(Wrapper, { ...props, forwardRef: ref }); + }), + Comp, + ); + + cache.set(options.schema.id, WrapperComponent); + + return WrapperComponent; } diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 99a9a40cfa..7b9562fcc6 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -23,7 +23,6 @@ import { transformStringToFunction, checkPropTypes, getI18n, - canAcceptsRef, getFileCssName, capitalizeFirstLetter, DataHelper, @@ -131,7 +130,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { static contextType = AppContext; - appHelper?: IRendererAppHelper; i18n: any; getLocale: any; setLocale: any; @@ -174,7 +172,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { __beforeInit(_props: IBaseRendererProps) { } __init(props: IBaseRendererProps) { - this.appHelper = props.__appHelper; this.__compScopes = {}; this.__instanceMap = {}; this.__bindCustomMethods(props); @@ -455,7 +452,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { * @param idx 为循环渲染的循环Index */ __createVirtualDom = (originalSchema: IPublicTypeNodeData | IPublicTypeNodeData[] | undefined, originalScope: any, parentInfo: INodeInfo, idx: string | number = ''): any => { - if (!originalSchema) { + if (originalSchema === null || originalSchema === undefined) { return null; } let scope = originalScope; @@ -547,6 +544,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (schema.loop != null) { const loop = this.__parseData(schema.loop, scope); + if (Array.isArray(loop) && loop.length === 0) return null; const useLoop = isUseLoop(loop, this.__designModeIsDesign); if (useLoop) { return this.__createLoopVirtualDom( @@ -617,11 +615,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { }); }); - // 对于不可以接收到 ref 的组件需要做特殊处理 - if (!canAcceptsRef(Comp)) { - Comp = compWrapper(Comp); - components[schema.componentName] = Comp; - } + Comp = compWrapper(Comp, { baseRenderer: this, schema }); + components[schema.componentName] = Comp; otherProps.ref = (ref: any) => { this.$(props.fieldId || props.ref, ref); // 收集ref @@ -651,7 +646,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { props.key = props.__id; } - let child = this.__getSchemaChildrenVirtualDom(schema, scope, Comp); + let child = this.__getSchemaChildrenVirtualDom(schema, scope, Comp, condition); const renderComp = (innerProps: any) => engine.createElement(Comp, innerProps, child); // 设计模式下的特殊处理 if (engine && [DESIGN_MODE.EXTEND, DESIGN_MODE.BORDER].includes(engine.props.designMode)) { @@ -711,8 +706,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { return []; } - __getSchemaChildrenVirtualDom = (schema: IPublicTypeNodeSchema | undefined, scope: any, Comp: any) => { - let children = getSchemaChildren(schema); + __getSchemaChildrenVirtualDom = (schema: IPublicTypeNodeSchema | undefined, scope: any, Comp: any, condition = true) => { + let children = condition ? getSchemaChildren(schema) : null; // @todo 补完这里的 Element 定义 @承虎 let result: any = []; @@ -1019,6 +1014,10 @@ export default function baseRendererFactory(): IBaseRenderComponent { return !isSchema(schema) || !componentNames.includes(schema?.componentName ?? ''); }; + get appHelper(): IRendererAppHelper { + return this.props.__appHelper; + } + get requestHandlersMap() { return this.appHelper?.requestHandlersMap; } diff --git a/packages/renderer-core/src/renderer/renderer.tsx b/packages/renderer-core/src/renderer/renderer.tsx index 09559b6f89..300b1cd164 100644 --- a/packages/renderer-core/src/renderer/renderer.tsx +++ b/packages/renderer-core/src/renderer/renderer.tsx @@ -105,55 +105,7 @@ export default function rendererFactory(): IRenderComponent { return SetComponent; } - patchDidCatch(SetComponent: any) { - if (!this.isValidComponent(SetComponent)) { - return; - } - if (SetComponent.patchedCatch) { - return; - } - if (!SetComponent.prototype) { - return; - } - SetComponent.patchedCatch = true; - - // Rax 的 getDerivedStateFromError 有 BUG,这里先用 componentDidCatch 来替代 - // @see https://github.com/alibaba/rax/issues/2211 - const originalDidCatch = SetComponent.prototype.componentDidCatch; - SetComponent.prototype.componentDidCatch = function didCatch(this: any, error: Error, errorInfo: any) { - this.setState({ engineRenderError: true, error }); - if (originalDidCatch && typeof originalDidCatch === 'function') { - originalDidCatch.call(this, error, errorInfo); - } - }; - - const engine = this; - const originRender = SetComponent.prototype.render; - SetComponent.prototype.render = function () { - if (this.state && this.state.engineRenderError) { - this.state.engineRenderError = false; - return engine.createElement(engine.getFaultComponent(), { - ...this.props, - error: this.state.error, - componentName: this.props._componentName - }); - } - return originRender.call(this); - }; - if(!(SetComponent.prototype instanceof PureComponent)) { - const originShouldComponentUpdate = SetComponent.prototype.shouldComponentUpdate; - SetComponent.prototype.shouldComponentUpdate = function (nextProps: IRendererProps, nextState: any) { - if (nextState && nextState.engineRenderError) { - return true; - } - return originShouldComponentUpdate ? originShouldComponentUpdate.call(this, nextProps, nextState) : true; - }; - } - } - createElement(SetComponent: any, props: any, children?: any) { - // TODO: enable in runtime mode? - this.patchDidCatch(SetComponent); return (this.props.customCreateElement || createElement)(SetComponent, props, children); } diff --git a/packages/renderer-core/src/types/index.ts b/packages/renderer-core/src/types/index.ts index a49fe89920..afbec272ab 100644 --- a/packages/renderer-core/src/types/index.ts +++ b/packages/renderer-core/src/types/index.ts @@ -335,7 +335,6 @@ export interface IRenderComponent { componentDidCatch(e: any): Promise<void> | void; shouldComponentUpdate(nextProps: IRendererProps): boolean; isValidComponent(SetComponent: any): any; - patchDidCatch(SetComponent: any): void; createElement(SetComponent: any, props: any, children?: any): any; getNotFoundComponent(): any; getFaultComponent(): any; diff --git a/packages/shell/package.json b/packages/shell/package.json index 09768a06a7..884915877c 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.1.10", + "version": "1.2.0", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-editor-skeleton": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", - "@alilc/lowcode-workspace": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-editor-skeleton": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-workspace": "1.2.0", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/shell/src/api/common.tsx b/packages/shell/src/api/common.tsx index 9f38cf1091..a2e4d8c4fa 100644 --- a/packages/shell/src/api/common.tsx +++ b/packages/shell/src/api/common.tsx @@ -1,4 +1,4 @@ -import { editorSymbol, skeletonSymbol, designerCabinSymbol, designerSymbol, settingFieldSymbol } from '../symbols'; +import { editorSymbol, skeletonSymbol, designerCabinSymbol, designerSymbol, settingFieldSymbol, editorCabinSymbol, skeletonCabinSymbol } from '../symbols'; import { isFormEvent as innerIsFormEvent, compatibleLegaoSchema as innerCompatibleLegaoSchema, @@ -36,6 +36,11 @@ import { getConvertedExtraKey as innerGetConvertedExtraKey, getOriginalExtraKey as innerGetOriginalExtraKey, IDesigner, + DropLocation as InnerDropLocation, + Designer as InnerDesigner, + Node as InnerNode, + LowCodePluginManager as InnerLowCodePluginManager, + DesignerView as InnerDesignerView, } from '@alilc/lowcode-designer'; import { Skeleton as InnerSkeleton, @@ -43,6 +48,8 @@ import { PopupContext as InnerPopupContext, PopupPipe as InnerPopupPipe, Workbench as InnerWorkbench, + SettingsPrimaryPane as InnerSettingsPrimaryPane, + registerDefaults as InnerRegisterDefaults, } from '@alilc/lowcode-editor-skeleton'; import { Editor, @@ -61,6 +68,7 @@ import { action as innerAction, runInAction as innerRunInAction, engineConfig as innerEngineConfig, + globalContext, } from '@alilc/lowcode-editor-core'; import { Dragon as ShellDragon } from '../model'; import { ReactNode } from 'react'; @@ -94,6 +102,11 @@ class DesignerCabin implements IPublicApiCommonDesignerCabin { DragObjectType: InnerDragObjectType, isDragNodeDataObject: innerIsDragNodeDataObject, isNode: innerIsNode, + DropLocation: InnerDropLocation, + Designer: InnerDesigner, + Node: InnerNode, + LowCodePluginManager: InnerLowCodePluginManager, + DesignerView: InnerDesignerView, }; } @@ -160,8 +173,19 @@ class DesignerCabin implements IPublicApiCommonDesignerCabin { class SkeletonCabin implements IPublicApiCommonSkeletonCabin { private readonly [skeletonSymbol]: InnerSkeleton; + readonly [skeletonCabinSymbol]: any; + constructor(skeleton: InnerSkeleton) { this[skeletonSymbol] = skeleton; + this[skeletonCabinSymbol] = { + Workbench: InnerWorkbench, + createSettingFieldView: this.createSettingFieldView, + PopupContext: InnerPopupContext, + PopupPipe: InnerPopupPipe, + SettingsPrimaryPane: InnerSettingsPrimaryPane, + registerDefaults: InnerRegisterDefaults, + Skeleton: InnerSkeleton, + }; } get Workbench(): any { @@ -242,8 +266,33 @@ class Utils implements IPublicApiCommonUtils { class EditorCabin implements IPublicApiCommonEditorCabin { private readonly [editorSymbol]: Editor; + /** + * @deprecated + */ + readonly [editorCabinSymbol]: any; + constructor(editor: Editor) { this[editorSymbol] = editor; + this[editorCabinSymbol] = { + Editor, + globalContext, + runInAction: innerRunInAction, + Title: InnerTitle, + Tip: InnerTip, + shallowIntl: innerShallowIntl, + createIntl: innerCreateIntl, + intl: innerIntl, + createSetterContent: this.createSetterContent.bind(this), + globalLocale: innerGlobalLocale, + obx: innerObx, + action: innerAction, + engineConfig: innerEngineConfig, + observable: innerObservable, + makeObservable: innerMakeObservable, + untracked: innerUntracked, + computed: innerComputed, + observer: innerObserver, + }; } /** diff --git a/packages/shell/src/api/simulator-host.ts b/packages/shell/src/api/simulator-host.ts index 3ed7448905..663ba0c668 100644 --- a/packages/shell/src/api/simulator-host.ts +++ b/packages/shell/src/api/simulator-host.ts @@ -2,7 +2,8 @@ import { BuiltinSimulatorHost, } from '@alilc/lowcode-designer'; import { simulatorHostSymbol, nodeSymbol } from '../symbols'; -import { IPublicApiSimulatorHost, IPublicModelNode } from '@alilc/lowcode-types'; +import { IPublicApiSimulatorHost, IPublicModelNode, IPublicModelSimulatorRender } from '@alilc/lowcode-types'; +import { SimulatorRender } from '../model/simulator-render'; export class SimulatorHost implements IPublicApiSimulatorHost { private readonly [simulatorHostSymbol]: BuiltinSimulatorHost; @@ -30,8 +31,12 @@ export class SimulatorHost implements IPublicApiSimulatorHost { return this[simulatorHostSymbol].contentDocument; } - get renderer(): any { - return this[simulatorHostSymbol].renderer; + get renderer(): IPublicModelSimulatorRender | undefined { + if (this[simulatorHostSymbol].renderer) { + return SimulatorRender.create(this[simulatorHostSymbol].renderer); + } + + return undefined; } /** @@ -61,7 +66,7 @@ export class SimulatorHost implements IPublicApiSimulatorHost { } /** - * 刷新渲染画布 + * 触发组件构建,并刷新渲染画布 */ rerender(): void { this[simulatorHostSymbol].rerender(); diff --git a/packages/shell/src/api/workspace.ts b/packages/shell/src/api/workspace.ts index 8737e37bd7..fd3e82fa90 100644 --- a/packages/shell/src/api/workspace.ts +++ b/packages/shell/src/api/workspace.ts @@ -3,6 +3,7 @@ import { IWorkspace } from '@alilc/lowcode-workspace'; import { resourceSymbol, workspaceSymbol } from '../symbols'; import { Resource as ShellResource, Window as ShellWindow } from '../model'; import { Plugins } from './plugins'; +import { Skeleton } from './skeleton'; export class Workspace implements IPublicApiWorkspace { readonly [workspaceSymbol]: IWorkspace; @@ -92,6 +93,10 @@ export class Workspace implements IPublicApiWorkspace { return new Plugins(this[workspaceSymbol].plugins, true); } + get skeleton() { + return new Skeleton(this[workspaceSymbol].skeleton, 'workspace', true); + } + get windows() { return this[workspaceSymbol].windows.map((d) => new ShellWindow(d)); } diff --git a/packages/shell/src/model/node.ts b/packages/shell/src/model/node.ts index f2cddd1ab8..29d24232eb 100644 --- a/packages/shell/src/model/node.ts +++ b/packages/shell/src/model/node.ts @@ -655,4 +655,24 @@ export class Node implements IPublicModelNode { setConditionalVisible(): void { this[nodeSymbol].setConditionalVisible(); } + + getRGL() { + const { + isContainerNode, + isEmptyNode, + isRGLContainerNode, + isRGLNode, + isRGL, + rglNode, + } = this[nodeSymbol].getRGL(); + + return { + isContainerNode, + isEmptyNode, + isRGLContainerNode, + isRGLNode, + isRGL, + rglNode: Node.create(rglNode), + }; + } } diff --git a/packages/shell/src/model/simulator-render.ts b/packages/shell/src/model/simulator-render.ts new file mode 100644 index 0000000000..f6ae47996c --- /dev/null +++ b/packages/shell/src/model/simulator-render.ts @@ -0,0 +1,23 @@ +import { IPublicModelSimulatorRender } from '@alilc/lowcode-types'; +import { simulatorRenderSymbol } from '../symbols'; +import { BuiltinSimulatorRenderer } from '@alilc/lowcode-designer'; + +export class SimulatorRender implements IPublicModelSimulatorRender { + private readonly [simulatorRenderSymbol]: BuiltinSimulatorRenderer; + + constructor(simulatorRender: BuiltinSimulatorRenderer) { + this[simulatorRenderSymbol] = simulatorRender; + } + + static create(simulatorRender: BuiltinSimulatorRenderer): IPublicModelSimulatorRender { + return new SimulatorRender(simulatorRender); + } + + get components() { + return this[simulatorRenderSymbol].components; + } + + rerender() { + return this[simulatorRenderSymbol].rerender(); + } +} \ No newline at end of file diff --git a/packages/shell/src/symbols.ts b/packages/shell/src/symbols.ts index b4ec01c7ec..8e2962a24f 100644 --- a/packages/shell/src/symbols.ts +++ b/packages/shell/src/symbols.ts @@ -21,9 +21,12 @@ export const dragonSymbol = Symbol('dragon'); export const componentMetaSymbol = Symbol('componentMeta'); export const dropLocationSymbol = Symbol('dropLocation'); export const simulatorHostSymbol = Symbol('simulatorHost'); +export const simulatorRenderSymbol = Symbol('simulatorRender'); export const dragObjectSymbol = Symbol('dragObject'); export const locateEventSymbol = Symbol('locateEvent'); export const designerCabinSymbol = Symbol('designerCabin'); +export const editorCabinSymbol = Symbol('editorCabin'); +export const skeletonCabinSymbol = Symbol('skeletonCabin'); export const hotkeySymbol = Symbol('hotkey'); export const pluginsSymbol = Symbol('plugins'); export const workspaceSymbol = Symbol('workspace'); diff --git a/packages/types/package.json b/packages/types/package.json index fe9cd51235..155242712a 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.1.10", + "version": "1.2.0", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/types/src/assets.ts b/packages/types/src/assets.ts index 852ed00380..f0e6d35396 100644 --- a/packages/types/src/assets.ts +++ b/packages/types/src/assets.ts @@ -38,6 +38,7 @@ export interface AssetItem { device?: string; level?: AssetLevel; id?: string; + scriptType?: string; } export type AssetList = Array<Asset | undefined | null>; diff --git a/packages/types/src/shell/api/simulator-host.ts b/packages/types/src/shell/api/simulator-host.ts index 1c0f5dec35..9137067951 100644 --- a/packages/types/src/shell/api/simulator-host.ts +++ b/packages/types/src/shell/api/simulator-host.ts @@ -1,7 +1,7 @@ -import { IPublicModelNode } from '../model'; - +import { IPublicModelNode, IPublicModelSimulatorRender } from '../model'; export interface IPublicApiSimulatorHost { + /** * 获取 contentWindow * @experimental unstable api, pay extra caution when trying to use it @@ -17,7 +17,7 @@ export interface IPublicApiSimulatorHost { /** * @experimental unstable api, pay extra caution when trying to use it */ - get renderer(): any; + get renderer(): IPublicModelSimulatorRender | undefined; /** * 设置若干用于画布渲染的变量,比如画布大小、locale 等。 diff --git a/packages/types/src/shell/model/index.ts b/packages/types/src/shell/model/index.ts index 1924f11215..ffe6347ac2 100644 --- a/packages/types/src/shell/model/index.ts +++ b/packages/types/src/shell/model/index.ts @@ -32,3 +32,4 @@ export * from './clipboard'; export * from './setting-field'; export * from './editor-view'; export * from './skeleton-item'; +export * from './simulator-render'; diff --git a/packages/types/src/shell/model/node.ts b/packages/types/src/shell/model/node.ts index 0255376aec..9d8cec3647 100644 --- a/packages/types/src/shell/model/node.ts +++ b/packages/types/src/shell/model/node.ts @@ -490,6 +490,18 @@ export interface IBaseModelNode< * 获取节点实例对应的 dom 节点 */ getDOMNode(): HTMLElement; + + /** + * 获取磁贴相关信息 + */ + getRGL(): { + isContainerNode: boolean; + isEmptyNode: boolean; + isRGLContainerNode: boolean; + isRGLNode: boolean; + isRGL: boolean; + rglNode: Node | null; + }; } export interface IPublicModelNode extends IBaseModelNode<IPublicModelDocumentModel, IPublicModelNode> {} \ No newline at end of file diff --git a/packages/types/src/shell/model/simulator-render.ts b/packages/types/src/shell/model/simulator-render.ts new file mode 100644 index 0000000000..8cf3a03c55 --- /dev/null +++ b/packages/types/src/shell/model/simulator-render.ts @@ -0,0 +1,14 @@ +export interface IPublicModelSimulatorRender { + + /** + * 画布组件列表 + */ + components: { + [key: string]: any; + }; + + /** + * 触发画布重新渲染 + */ + rerender: () => void; +} diff --git a/packages/utils/package.json b/packages/utils/package.json index ecf6bff3c0..f9c0005b4d 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.1.10", + "version": "1.2.0", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-types": "1.2.0", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/utils/src/app-helper.ts b/packages/utils/src/app-helper.ts index d5eb2072b3..86b535c592 100644 --- a/packages/utils/src/app-helper.ts +++ b/packages/utils/src/app-helper.ts @@ -34,18 +34,18 @@ export class AppHelper extends EventEmitter { } } - batchOn(events: Array<string | symbol>, lisenter: (...args: any[]) => void) { + batchOn(events: Array<string | symbol>, listener: (...args: any[]) => void) { if (!Array.isArray(events)) return; - events.forEach((event) => this.on(event, lisenter)); + events.forEach((event) => this.on(event, listener)); } - batchOnce(events: Array<string | symbol>, lisenter: (...args: any[]) => void) { + batchOnce(events: Array<string | symbol>, listener: (...args: any[]) => void) { if (!Array.isArray(events)) return; - events.forEach((event) => this.once(event, lisenter)); + events.forEach((event) => this.once(event, listener)); } - batchOff(events: Array<string | symbol>, lisenter: (...args: any[]) => void) { + batchOff(events: Array<string | symbol>, listener: (...args: any[]) => void) { if (!Array.isArray(events)) return; - events.forEach((event) => this.off(event, lisenter)); + events.forEach((event) => this.off(event, listener)); } } diff --git a/packages/utils/src/asset.ts b/packages/utils/src/asset.ts index 4e5a360b86..ad05221248 100644 --- a/packages/utils/src/asset.ts +++ b/packages/utils/src/asset.ts @@ -50,7 +50,7 @@ export function assetItem(type: AssetType, content?: string | null, level?: Asse }; } -export function megreAssets(assets: IPublicTypeAssetsJson, incrementalAssets: IPublicTypeAssetsJson): IPublicTypeAssetsJson { +export function mergeAssets(assets: IPublicTypeAssetsJson, incrementalAssets: IPublicTypeAssetsJson): IPublicTypeAssetsJson { if (incrementalAssets.packages) { assets.packages = [...(assets.packages || []), ...incrementalAssets.packages]; } @@ -59,13 +59,13 @@ export function megreAssets(assets: IPublicTypeAssetsJson, incrementalAssets: IP assets.components = [...(assets.components || []), ...incrementalAssets.components]; } - megreAssetsComponentList(assets, incrementalAssets, 'componentList'); - megreAssetsComponentList(assets, incrementalAssets, 'bizComponentList'); + mergeAssetsComponentList(assets, incrementalAssets, 'componentList'); + mergeAssetsComponentList(assets, incrementalAssets, 'bizComponentList'); return assets; } -function megreAssetsComponentList(assets: IPublicTypeAssetsJson, incrementalAssets: IPublicTypeAssetsJson, listName: keyof IPublicTypeAssetsJson): void { +function mergeAssetsComponentList(assets: IPublicTypeAssetsJson, incrementalAssets: IPublicTypeAssetsJson, listName: keyof IPublicTypeAssetsJson): void { if (incrementalAssets[listName]) { if (assets[listName]) { // 根据title进行合并 diff --git a/packages/utils/src/create-icon.tsx b/packages/utils/src/create-icon.tsx index 0f25005298..0a5d6c1ff7 100644 --- a/packages/utils/src/create-icon.tsx +++ b/packages/utils/src/create-icon.tsx @@ -18,7 +18,11 @@ export function createIcon( } if (typeof icon === 'string') { if (URL_RE.test(icon)) { - return <img src={icon} {...props} />; + return createElement('img', { + src: icon, + class: props?.className, + ...props, + }); } return <Icon type={icon} {...props} />; } diff --git a/packages/utils/src/is-react.ts b/packages/utils/src/is-react.ts index 07568db981..b19f043f14 100644 --- a/packages/utils/src/is-react.ts +++ b/packages/utils/src/is-react.ts @@ -10,10 +10,10 @@ export function isReactClass(obj: any): obj is ComponentClass<any> { } export function acceptsRef(obj: any): boolean { - return obj?.prototype?.isReactComponent || (obj.$$typeof && obj.$$typeof === REACT_FORWARD_REF_TYPE); + return obj?.prototype?.isReactComponent || isForwardOrMemoForward(obj); } -function isForwardRefType(obj: any): boolean { +export function isForwardRefType(obj: any): boolean { return obj?.$$typeof && obj?.$$typeof === REACT_FORWARD_REF_TYPE; } @@ -21,6 +21,15 @@ function isMemoType(obj: any): boolean { return obj?.$$typeof && obj.$$typeof === REACT_MEMO_TYPE; } +export function isForwardOrMemoForward(obj: any): boolean { + return obj?.$$typeof && ( + // React.forwardRef(..) + isForwardRefType(obj) || + // React.memo(React.forwardRef(..)) + (isMemoType(obj) && isForwardRefType(obj.type)) + ); +} + export function isReactComponent(obj: any): obj is ComponentType<any> { if (!obj) { return false; diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts index 032b54bdc4..4c8f375ecd 100644 --- a/packages/utils/src/logger.ts +++ b/packages/utils/src/logger.ts @@ -52,11 +52,11 @@ const bizNameColors = [ '#2e8b57', ]; const bodyColors: Record<string, string> = { - debug: '#666666', - log: '#bbbbbb', - info: '#ffffff', - warn: '#bbbbbb', - error: '#bbbbbb', + debug: '#fadb14', + log: '#8c8c8c', + info: '#52c41a', + warn: '#fa8c16', + error: '#ff4d4f', }; const levelMarks: Record<string, string> = { debug: 'debug', @@ -65,7 +65,7 @@ const levelMarks: Record<string, string> = { warn: 'warn', error: 'error', }; -const outputFuntion: Record<string, any> = { +const outputFunction: Record<string, any> = { debug: console.log, log: console.log, info: console.log, @@ -88,7 +88,7 @@ const shouldOutput = ( const output = (logLevel: string, bizName: string) => { return (...args: any[]) => { - return outputFuntion[logLevel].apply(console, getLogArgs(args, bizName, logLevel)); + return outputFunction[logLevel].apply(console, getLogArgs(args, bizName, logLevel)); }; }; diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 8802691d60..7e662af378 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.1.10", + "version": "1.2.0", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-editor-skeleton": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-editor-skeleton": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/workspace/src/layouts/bottom-area.tsx b/packages/workspace/src/layouts/bottom-area.tsx deleted file mode 100644 index 5fc4d815bc..0000000000 --- a/packages/workspace/src/layouts/bottom-area.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@alilc/lowcode-editor-core'; -import { Area, Panel } from '@alilc/lowcode-editor-skeleton'; - -@observer -export default class BottomArea extends Component<{ area: Area<any, Panel> }> { - render() { - const { area } = this.props; - if (area.isEmpty()) { - return null; - } - return ( - <div className={classNames('lc-bottom-area', { - 'lc-area-visible': area.visible, - })} - > - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area<any, Panel> }> { - render() { - const { area } = this.props; - return ( - <Fragment> - {area.container.items.map((item) => item.content)} - </Fragment> - ); - } -} diff --git a/packages/workspace/src/layouts/left-area.tsx b/packages/workspace/src/layouts/left-area.tsx deleted file mode 100644 index 3057386eda..0000000000 --- a/packages/workspace/src/layouts/left-area.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@alilc/lowcode-editor-core'; -import { Area } from '@alilc/lowcode-editor-skeleton'; - -@observer -export default class LeftArea extends Component<{ area: Area }> { - render() { - const { area } = this.props; - if (area.isEmpty()) { - return null; - } - return ( - <div className={classNames('lc-left-area', { - 'lc-area-visible': area.visible, - })} - > - <Contents area={area} /> - </div> - ); - } -} - - -@observer -class Contents extends Component<{ area: Area }> { - render() { - const { area } = this.props; - const top: any[] = []; - const bottom: any[] = []; - area.container.items.slice().sort((a, b) => { - const index1 = a.config?.index || 0; - const index2 = b.config?.index || 0; - return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1); - }).forEach((item) => { - const content = <div key={`left-area-${item.name}`}>{item.content}</div>; - if (item.align === 'bottom') { - bottom.push(content); - } else { - top.push(content); - } - }); - return ( - <Fragment> - <div className="lc-left-area-top">{top}</div> - <div className="lc-left-area-bottom">{bottom}</div> - </Fragment> - ); - } -} diff --git a/packages/workspace/src/layouts/left-fixed-pane.tsx b/packages/workspace/src/layouts/left-fixed-pane.tsx deleted file mode 100644 index e0c01c5109..0000000000 --- a/packages/workspace/src/layouts/left-fixed-pane.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@alilc/lowcode-editor-core'; -import { Area, Panel, PanelConfig } from '@alilc/lowcode-editor-skeleton'; - -@observer -export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, Panel> }> { - componentDidUpdate() { - // FIXME: dirty fix, need deep think - this.props.area.skeleton.editor.get('designer')?.touchOffsetObserver(); - } - - - render() { - const { area } = this.props; - const width = area.current?.config.props?.width; - const style = width - ? { - width, - } - : undefined; - - return ( - <div - className={classNames('lc-left-fixed-pane', { - 'lc-area-visible': area.visible, - })} - style={style} - > - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area<PanelConfig, Panel> }> { - render() { - const { area } = this.props; - return <Fragment>{area.container.items.map((panel) => panel.content)}</Fragment>; - } -} diff --git a/packages/workspace/src/layouts/left-float-pane.tsx b/packages/workspace/src/layouts/left-float-pane.tsx deleted file mode 100644 index 3df3e197c2..0000000000 --- a/packages/workspace/src/layouts/left-float-pane.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer, Focusable } from '@alilc/lowcode-editor-core'; -import { Area, Panel } from '@alilc/lowcode-editor-skeleton'; -import { IPublicApiProject } from '@alilc/lowcode-types'; - -@observer -export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> { - private dispose?: () => void; - - private focusing?: Focusable; - - private shell: HTMLElement | null = null; - - componentDidMount() { - const { area } = this.props; - const triggerClose = (e: any) => { - if (!area.visible) return; - // 当 MouseEvent 的 target 为「插入占位符」时,不关闭当前 panel - if (e.originalEvent?.target?.classList.contains('insertion')) return; - // 假如当前操作 target 祖先节点中有属性 data-keep-visible-while-dragging="true" 代表该 target 所属 panel - // 不希望 target 在 panel 范围内拖拽时关闭 panel - const panelElem = e.originalEvent?.target.closest('div[data-keep-visible-while-dragging="true"]'); - if (panelElem) return; - area.setVisible(false); - }; - area.skeleton.editor.eventBus.on('designer.drag', triggerClose); - - this.dispose = () => { - area.skeleton.editor.removeListener('designer.drag', triggerClose); - }; - - const project: IPublicApiProject | undefined = area.skeleton.editor.get('project'); - - this.focusing = area.skeleton.focusTracker.create({ - range: (e) => { - const target = e.target as HTMLElement; - if (!target) { - return false; - } - if (this.shell?.contains(target)) { - return true; - } - // 点击了 iframe 内容,算失焦 - if ((document.querySelector('.lc-simulator-content-frame') as HTMLIFrameElement)?.contentWindow?.document.documentElement.contains(target)) { - return false; - } - if (project?.simulatorHost?.contentWindow?.document.documentElement.contains(target)) { - return false; - } - // 点击设置区 - if (document.querySelector('.lc-right-area')?.contains(target)) { - return false; - } - // 点击非编辑区域的popup/dialog,插件栏左侧等不触发失焦 - if (!document.querySelector('.lc-workbench')?.contains(target)) { - return true; - } - // 排除设置区,iframe 之后,都不算失焦 - if (document.querySelector('.lc-workbench-body')?.contains(target)) { - return true; - } - const docks = area.current?.getAssocDocks(); - if (docks && docks?.length) { - return docks.some(dock => dock.getDOMNode()?.contains(target)); - } - return false; - }, - onEsc: () => { - this.props.area.setVisible(false); - }, - onBlur: () => { - this.props.area.setVisible(false); - }, - }); - - this.onEffect(); - } - - onEffect() { - const { area } = this.props; - if (area.visible) { - this.focusing?.active(); - // 关闭当前fixed区域的面板 - // TODO: 看看有没有更合适的地方 - const fixedContainer = area?.skeleton?.leftFixedArea?.container; - const currentFixed = fixedContainer?.current; - if (currentFixed) { - fixedContainer.unactive(currentFixed); - } - } else { - this.focusing?.suspense(); - } - } - - componentDidUpdate() { - this.onEffect(); - } - - componentWillUnmount() { - this.focusing?.purge(); - this.dispose?.(); - } - - render() { - const { area } = this.props; - const width = area.current?.config.props?.width; - - const style = width ? { - width, - } : undefined; - return ( - <div - ref={(ref) => { this.shell = ref; }} - className={classNames('lc-left-float-pane', { - 'lc-area-visible': area.visible, - })} - style={style} - > - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area<any, Panel> }> { - render() { - const { area } = this.props; - return ( - <Fragment> - {area.container.items.map((panel) => panel.content)} - </Fragment> - ); - } -} diff --git a/packages/workspace/src/layouts/main-area.tsx b/packages/workspace/src/layouts/main-area.tsx deleted file mode 100644 index 5313d7007e..0000000000 --- a/packages/workspace/src/layouts/main-area.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Component } from 'react'; -import classNames from 'classnames'; -import { observer } from '@alilc/lowcode-editor-core'; -import { Area, Panel, Widget } from '@alilc/lowcode-editor-skeleton'; - -@observer -export default class MainArea extends Component<{ area: Area<any, Panel | Widget> }> { - render() { - const { area } = this.props; - return ( - <div className={classNames('lc-main-area engine-workspacepane')}> - {area.container.items.map((item) => item.content)} - </div> - ); - } -} diff --git a/packages/workspace/src/layouts/theme.less b/packages/workspace/src/layouts/theme.less deleted file mode 100644 index b0da053db1..0000000000 --- a/packages/workspace/src/layouts/theme.less +++ /dev/null @@ -1,62 +0,0 @@ -@import '../less-variables.less'; - -/* - * Theme Colors - * - * 乐高设计器的主要主题色变量 - */ -:root { - --color-brand: @brand-color-1; - --color-brand-light: @brand-color-2; - --color-brand-dark: @brand-color-3; - - --color-canvas-background: @normal-alpha-8; - - --color-icon-normal: @normal-alpha-4; - --color-icon-hover: @normal-alpha-3; - --color-icon-active: @brand-color-1; - --color-icon-reverse: @white-alpha-1; - - --color-line-normal: @normal-alpha-7; - --color-line-darken: darken(@normal-alpha-7, 10%); - - --color-title: @dark-alpha-2; - --color-text: @dark-alpha-3; - --color-text-dark: darken(@dark-alpha-3, 10%); - --color-text-light: lighten(@dark-alpha-3, 10%); - --color-text-reverse: @white-alpha-2; - --color-text-regular: @normal-alpha-2; - - --color-field-label: @dark-alpha-4; - --color-field-text: @dark-alpha-3; - --color-field-placeholder: @normal-alpha-5; - --color-field-border: @normal-alpha-5; - --color-field-border-hover: @normal-alpha-4; - --color-field-border-active: @normal-alpha-3; - --color-field-background: @white-alpha-1; - - --color-function-success: @brand-success; - --color-function-success-dark: darken(@brand-success, 10%); - --color-function-success-light: lighten(@brand-success, 10%); - --color-function-warning: @brand-warning; - --color-function-warning-dark: darken(@brand-warning, 10%); - --color-function-warning-light: lighten(@brand-warning, 10%); - --color-function-information: @brand-link-hover; - --color-function-information-dark: darken(@brand-link-hover, 10%); - --color-function-information-light: lighten(@brand-link-hover, 10%); - --color-function-error: @brand-danger; - --color-function-error-dark: darken(@brand-danger, 10%); - --color-function-error-light: lighten(@brand-danger, 10%); - - --color-pane-background: @white-alpha-1; - --color-block-background-normal: @white-alpha-1; - --color-block-background-light: @normal-alpha-9; - --color-block-background-shallow: @normal-alpha-8; - --color-block-background-dark: @normal-alpha-7; - --color-block-background-disabled: @normal-alpha-6; - --color-block-background-deep-dark: @normal-5; - --color-layer-mask-background: @dark-alpha-7; - --color-layer-tooltip-background: rgba(44,47,51,0.8); - - --pane-title-bg-color: rgba(31,56,88,.04); -} diff --git a/packages/workspace/src/layouts/top-area.tsx b/packages/workspace/src/layouts/top-area.tsx deleted file mode 100644 index cecaee2a71..0000000000 --- a/packages/workspace/src/layouts/top-area.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@alilc/lowcode-editor-core'; -import { Area } from '@alilc/lowcode-editor-skeleton'; - -@observer -export default class TopArea extends Component<{ area: Area; itemClassName?: string }> { - render() { - const { area, itemClassName } = this.props; - - if (area.isEmpty()) { - return null; - } - - return ( - <div className={classNames('lc-top-area engine-actionpane', { - 'lc-area-visible': area.visible, - })} - > - <Contents area={area} itemClassName={itemClassName} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area; itemClassName?: string }> { - render() { - const { area, itemClassName } = this.props; - const left: any[] = []; - const center: any[] = []; - const right: any[] = []; - area.container.items.slice().sort((a, b) => { - const index1 = a.config?.index || 0; - const index2 = b.config?.index || 0; - return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1); - }).forEach(item => { - const content = ( - <div className={itemClassName || ''} key={`top-area-${item.name}`}> - {item.content} - </div> - ); - if (item.align === 'center') { - center.push(content); - } else if (item.align === 'left') { - left.push(content); - } else { - right.push(content); - } - }); - - return ( - <Fragment> - <div className="lc-top-area-left">{left}</div> - <div className="lc-top-area-center">{center}</div> - <div className="lc-top-area-right">{right}</div> - </Fragment> - ); - } -} diff --git a/packages/workspace/src/layouts/workbench.less b/packages/workspace/src/layouts/workbench.less deleted file mode 100644 index 05eb5f513b..0000000000 --- a/packages/workspace/src/layouts/workbench.less +++ /dev/null @@ -1,421 +0,0 @@ -@import './theme.less'; - -:root { - --font-family: @font-family; - --font-size-label: @fontSize-4; - --font-size-text: @fontSize-5; - --font-size-btn-large: @fontSize-3; - --font-size-btn-medium: @fontSize-4; - --font-size-btn-small: @fontSize-5; - - --global-border-radius: @global-border-radius; - --input-border-radius: @input-border-radius; - --popup-border-radius: @popup-border-radius; - - --left-area-width: 48px; - --right-area-width: 300px; - --top-area-height: 48px; - --toolbar-height: 36px; - --dock-pane-width: 300px; - --dock-fixed-pane-width: 300px; -} - -@media (min-width: 1860px) { - :root { - --right-area-width: 400px; - --dock-pane-width: 452px; - --dock-fixed-pane-width: 350px; - } -} - -html, -body { - height: 100%; - overflow: hidden; - padding: 0; - margin: 0; - position: relative; - font-family: var(--font-family); - font-size: var(--font-size-text); - color: var(--color-text); - background-color: #edeff3; -} - -* { - box-sizing: border-box; -} - -.lc-titled-panel { - width: 100%; - height: 100%; - position: relative; - background-color: #fff; - background-color: var(--color-pane-background); - &.hidden { - display: none; - } - .lc-panel-title { - // background-color: var(--pane-title-bg-color,rgba(31,56,88,.04)); - display: flex; - align-items: center; - justify-content: flex-start; - padding: 0 15px; - - .lc-help-tip { - margin-left: 4px; - color: rgba(0, 0, 0, 0.4); - cursor: pointer; - } - } - > .lc-panel-title { - height: 48px; - font-size: 16px; - padding: 0 15px; - // border-bottom: 1px solid var(--color-line-normal,rgba(31,56,88,.1)); - color: #0f1726; - font-weight: bold; - } - - .lc-panel-body { - position: absolute; - top: 48px; - bottom: 0; - left: 0; - right: 0; - overflow: visible; - /* - .my-tabs { - width: 100%; - height: 100%; - position: relative; - .tabs-title { - display: flex; - height: var(--pane-title-height); - > .tab-title { - cursor: pointer; - padding: 0; - flex: 1; - min-width: 0; - justify-content: center; - border-bottom: 2px solid transparent; - &.actived { - cursor: default; - color: var(--color-text-avtived); - border-bottom-color: #3896ee; - } - } - } - .tabs-content { - position: absolute; - top: var(--pane-title-height); - bottom: 0; - left: 0; - right: 0; - height: calc(100% - var(--pane-title-height)); - overflow: hidden; - } - } - */ - } - .lc-outline-tree-container { - border-top: 1px solid var(--color-line-normal, rgba(31, 56, 88, 0.1)); - } -} -.lc-panel { - height: 100%; - width: 100%; - position: relative; - background-color: #fff; - background-color: var(--color-pane-background); - // overflow: auto; - &.hidden { - display: none; - } -} - -.lc-workspace-workbench { - height: 100%; - display: flex; - flex-direction: column; - background-color: #edeff3; - .lc-top-area, .lc-sub-top-area { - height: var(--top-area-height); - background-color: var(--color-pane-background); - width: 100%; - display: none; - margin-bottom: 2px; - padding: 8px 12px 8px 16px; - - &.lc-area-visible { - display: flex; - } - - .lc-top-area-left, .lc-sub-top-area-left { - display: flex; - align-items: center; - max-width: 100%; - } - - .lc-top-area-center, .lc-sub-top-area-center { - flex: 1; - display: flex; - justify-content: center; - margin: 0 8px; - } - .lc-top-area-right, .lc-sub-top-area-right { - display: flex; - align-items: center; - > * { - margin-left: 4px; - margin-right: 4px; - } - .ve-quick-search-trigger { - display: flex; - } - } - } - .lc-workspace-workbench-body { - flex: 1; - display: flex; - min-height: 0; - position: relative; - - .lc-tabs-title { - width: 100%; - height: 32px; - position: relative; - display: center; - display: flex; - justify-content: center; - align-items: center; - // background: rgba(31,56,88,0.04); - border-bottom: 1px solid #edeff3; - .lc-tab-title { - flex: 1; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - border-bottom: 2px solid transparent; - cursor: pointer; - font-size: 12px; - &.actived { - color: #0079f2; - border-bottom-color: #0079f2; - } - } - } - - .lc-tabs-content { - position: absolute; - top: 32px; - bottom: 0; - left: 0; - right: 0; - } - - .lc-pane-icon-close { - position: absolute; - right: 16px; - top: 14px; - height: auto; - z-index: 2; - .next-icon { - line-height: 1; - color: rgba(0, 0, 0, 0.6); - } - } - - .lc-pane-icon-fix, - .lc-pane-icon-float { - position: absolute; - right: 38px; - top: 14px; - height: auto; - z-index: 2; - svg { - vertical-align: middle; - color: rgba(0, 0, 0, 0.6); - } - } - - .lc-left-float-pane { - position: absolute; - top: 0; - bottom: 0; - width: var(--dock-pane-width); - // min-width: var(--dock-fixed-pane-width); - left: calc(var(--left-area-width) + 1px); - background-color: var(--color-pane-background); - box-shadow: 4px 6px 6px 0 rgba(31, 50, 88, 0.08); - z-index: 820; - display: none; - // padding-top: 36px; - &.lc-area-visible { - display: block; - } - } - .lc-left-area { - height: 100%; - width: var(--left-area-width); - background-color: var(--color-pane-background); - display: none; - flex-shrink: 0; - flex-direction: column; - justify-content: space-between; - overflow: hidden; - &.lc-area-visible { - display: flex; - } - .lc-left-area-top, - .lc-left-area-bottom { - width: 100%; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - .lc-title { - flex-direction: column; - width: calc(var(--left-area-width) - 2px); - height: 46px; - display: flex; - align-items: center; - justify-content: center; - - &.has-tip { - cursor: pointer; - } - &.actived { - color: #0079f2; - } - &.disabled { - opacity: 0.4; - } - .lc-title-icon { - height: 20px; - width: 20px; - margin: 0; - .next-icon:before { - line-height: 1 !important; - } - } - } - } - .lc-left-area-top { - padding-top: 12px; - } - .lc-left-area-bottom { - padding-bottom: 12px; - } - } - .lc-left-fixed-pane { - width: var(--dock-fixed-pane-width); - background-color: var(--color-pane-background); - height: 100%; - display: none; - flex-shrink: 0; - position: relative; - z-index: 820; - &.lc-area-visible { - display: block; - } - } - .lc-left-area.lc-area-visible ~ .lc-left-fixed-pane { - margin-left: 1px; - } - .lc-left-area.lc-area-visible ~ .lc-workspace-workbench-center { - margin-left: 2px; - } - .lc-outline-pane { - .lc-outline-tree .tree-node .tree-node-title { - border-bottom: none; - } - } - .lc-workspace-workbench-center { - flex: 1; - display: flex; - flex-direction: column; - z-index: 10; - position: relative; - .lc-toolbar { - display: flex; - height: var(--toolbar-height); - background-color: var(--color-pane-background); - padding: 8px 16px; - .lc-toolbar-center { - display: flex; - justify-content: center; - align-items: center; - flex: 1; - } - } - .lc-main-area { - flex: 1; - } - .lc-bottom-area { - height: var(--bottom-area-height); - background-color: var(--color-pane-background); - display: none; - &.lc-area-visible { - display: block; - } - } - } - - .lc-workspace-workbench-center-content { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - flex-direction: column; - display: flex; - align-content: stretch; - } - - .engine-actionitem { - max-width: 100%; - } - - .lc-workspace-workbench-window { - position: relative; - height: 100%; - } - - .lc-right-area { - height: 100%; - width: var(--right-area-width); - background-color: var(--color-pane-background); - display: none; - flex-shrink: 0; - margin-left: 2px; - position: relative; - > .lc-panel { - position: absolute; - left: 0; - top: 0; - } - &.lc-area-visible { - display: block; - } - .lc-settings-tabs { - > .next-tabs-nav-extra { - top: 36px !important; - } - .lc-settings-tab-item { - .next-tabs-tab-inner { - font-size: 12px; - line-height: 12px; - } - } - .lc-title { - color: inherit; - line-height: inherit !important; - } - } - .lc-settings-tabs-content { - top: 66px; - } - } - } -} diff --git a/packages/workspace/src/layouts/workbench.tsx b/packages/workspace/src/layouts/workbench.tsx index 08d6dc1a93..2913576e1c 100644 --- a/packages/workspace/src/layouts/workbench.tsx +++ b/packages/workspace/src/layouts/workbench.tsx @@ -2,17 +2,10 @@ import { Component } from 'react'; import { TipContainer, engineConfig, observer } from '@alilc/lowcode-editor-core'; import { WindowView } from '../view/window-view'; import classNames from 'classnames'; -import TopArea from './top-area'; -import LeftArea from './left-area'; -import LeftFixedPane from './left-fixed-pane'; -import LeftFloatPane from './left-float-pane'; -import MainArea from './main-area'; -import BottomArea from './bottom-area'; -import './workbench.less'; import { SkeletonContext } from '../skeleton-context'; import { EditorConfig, PluginClassSet } from '@alilc/lowcode-types'; import { Workspace } from '../workspace'; -import SubTopArea from './sub-top-area'; +import { BottomArea, LeftArea, LeftFixedPane, LeftFloatPane, MainArea, SubTopArea, TopArea } from '@alilc/lowcode-editor-skeleton'; @observer export class Workbench extends Component<{ @@ -23,12 +16,18 @@ export class Workbench extends Component<{ topAreaItemClassName?: string; }, { workspaceEmptyComponent: any; + theme?: string; }> { constructor(props: any) { super(props); const { config, components, workspace } = this.props; const { skeleton } = workspace; skeleton.buildFromConfig(config, components); + engineConfig.onGot('theme', (theme) => { + this.setState({ + theme, + }); + }); engineConfig.onGot('workspaceEmptyComponent', (workspaceEmptyComponent) => { this.setState({ workspaceEmptyComponent, @@ -36,20 +35,21 @@ export class Workbench extends Component<{ }); this.state = { workspaceEmptyComponent: engineConfig.get('workspaceEmptyComponent'), + theme: engineConfig.get('theme'), }; } render() { const { workspace, className, topAreaItemClassName } = this.props; const { skeleton } = workspace; - const WorkspaceEmptyComponent = this.state.workspaceEmptyComponent; + const { workspaceEmptyComponent: WorkspaceEmptyComponent, theme } = this.state; return ( - <div className={classNames('lc-workspace-workbench', className)}> + <div className={classNames('lc-workspace-workbench', className, theme)}> <SkeletonContext.Provider value={skeleton}> - <TopArea area={skeleton.topArea} itemClassName={topAreaItemClassName} /> + <TopArea className="lc-workspace-top-area" area={skeleton.topArea} itemClassName={topAreaItemClassName} /> <div className="lc-workspace-workbench-body"> - <LeftArea area={skeleton.leftArea} /> + <LeftArea className="lc-workspace-left-area lc-left-area" area={skeleton.leftArea} /> <LeftFloatPane area={skeleton.leftFloatArea} /> <LeftFixedPane area={skeleton.leftFixedArea} /> <div className="lc-workspace-workbench-center"> diff --git a/packages/workspace/src/less-variables.less b/packages/workspace/src/less-variables.less index c44fc196e2..017e432ce6 100644 --- a/packages/workspace/src/less-variables.less +++ b/packages/workspace/src/less-variables.less @@ -99,19 +99,19 @@ @brand-link-hover: #2e76a6; // F1-1-7 A10 -@brand-danger-alpha-7: rgba(240, 70, 49, 0.9); +@brand-danger-alpha-7: rgba(240, 70, 49, 0.1); // F1-1-8 A6 @brand-danger-alpha-8: rgba(240, 70, 49, 0.8); // F2-1-2 A80 @brand-warning-alpha-2: rgba(250, 189, 14, 0.8); // F2-1-7 A10 -@brand-warning-alpha-7: rgba(250, 189, 14, 0.9); +@brand-warning-alpha-7: rgba(250, 189, 14, 0.1); // F3-1-2 A80 @brand-success-alpha-2: rgba(102, 188, 92, 0.8); // F3-1-7 A10 -@brand-success-alpha-7: rgba(102, 188, 92, 0.9); +@brand-success-alpha-7: rgba(102, 188, 92, 0.1); // F4-1-7 A10 -@brand-link-alpha-7: rgba(102, 188, 92, 0.9); +@brand-link-alpha-7: rgba(102, 188, 92, 0.1); // 文本色 @text-primary-color: @dark-alpha-3; diff --git a/packages/workspace/src/view/resource-view.tsx b/packages/workspace/src/view/resource-view.tsx index 9ef30af092..e2204dd505 100644 --- a/packages/workspace/src/view/resource-view.tsx +++ b/packages/workspace/src/view/resource-view.tsx @@ -1,10 +1,10 @@ import { PureComponent } from 'react'; import { EditorView } from './editor-view'; import { observer } from '@alilc/lowcode-editor-core'; -import TopArea from '../layouts/top-area'; import { IResource } from '../resource'; import { IEditorWindow } from '../window'; import './resource-view.less'; +import { TopArea } from '@alilc/lowcode-editor-skeleton'; @observer export class ResourceView extends PureComponent<{ diff --git a/packages/workspace/src/window.ts b/packages/workspace/src/window.ts index 2c670346fb..ce5aab4142 100644 --- a/packages/workspace/src/window.ts +++ b/packages/workspace/src/window.ts @@ -126,9 +126,10 @@ export class EditorWindow implements IEditorWindow { async init() { await this.initViewTypes(); await this.execViewTypesInit(); - Promise.all(Array.from(this.editorViews.values()).map((d) => d.onSimulatorRendererReady)).then(() => { - this.workspace.emitWindowRendererReady(); - }); + Promise.all(Array.from(this.editorViews.values()).map((d) => d.onSimulatorRendererReady())) + .then(() => { + this.workspace.emitWindowRendererReady(); + }); this.url = await this.resource.url(); this.setDefaultViewName(); this.initReady = true; diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index 22eb9ede2b..9f1abaa0fb 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -6,6 +6,7 @@ import { EditorWindow, WINDOW_STATE } from './window'; import type { IEditorWindow } from './window'; import { IResource, Resource } from './resource'; import { IResourceType, ResourceType } from './resource-type'; +import { ISkeleton } from '@alilc/lowcode-editor-skeleton'; enum EVENT { CHANGE_WINDOW = 'change_window', @@ -33,6 +34,8 @@ export interface IWorkspace extends Omit<IPublicApiWorkspace< plugins: ILowCodePluginManager; + skeleton: ISkeleton; + resourceTypeMap: Map<string, ResourceType>; getResourceList(): IResource[]; @@ -127,7 +130,9 @@ export class Workspace implements IWorkspace { } const windowInfo = this.windowQueue.shift(); - if (windowInfo) { + if (windowInfo instanceof Resource) { + this.openEditorWindowByResource(windowInfo); + } else if (windowInfo) { this.openEditorWindow(windowInfo.name, windowInfo.title, windowInfo.options, windowInfo.viewName); } } @@ -248,7 +253,7 @@ export class Workspace implements IWorkspace { } async openEditorWindowByResource(resource: IResource, sleep: boolean = false): Promise<void> { - if (this.window && !this.window?.initReady && !sleep) { + if (this.window && !this.window.sleep && !this.window?.initReady && !sleep) { this.windowQueue.push(resource); return; } @@ -289,7 +294,7 @@ export class Workspace implements IWorkspace { } async openEditorWindow(name: string, title: string, options: Object, viewName?: string, sleep?: boolean) { - if (this.window && !this.window?.initReady && !sleep) { + if (this.window && !this.window.sleep && !this.window?.initReady && !sleep) { this.windowQueue.push({ name, title, options, viewName, }); @@ -301,7 +306,7 @@ export class Workspace implements IWorkspace { return; } this.window?.updateState(WINDOW_STATE.inactive); - const filterWindows = this.windows.filter(d => (d.resource?.name === name && d.resource.title == title)); + const filterWindows = this.windows.filter(d => (d.resource?.name === name && d.resource.title == title) || (d.resource.id == title)); if (filterWindows && filterWindows.length) { this.window = filterWindows[0]; if (!sleep && this.window.sleep) { @@ -317,6 +322,7 @@ export class Workspace implements IWorkspace { resourceName: name, title, options, + id: title?.toString(), }, resourceType, this); const window = new EditorWindow(resource, this, { title,