mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-10-14 17:33:01 +08:00
Compare commits
57 Commits
v1.6.0-bet
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
5387a18024 | ||
|
2b80ba3efd | ||
|
6c3916c580 | ||
|
4dfdc836f6 | ||
|
fef1e2c2b4 | ||
|
51f95aef6f | ||
|
81aa8f151d | ||
|
cae11dce12 | ||
|
83bf36d980 | ||
|
2888004c17 | ||
|
abab44ad24 | ||
|
849b561933 | ||
|
1031595a97 | ||
|
f5cb19dfa4 | ||
|
e400175ffe | ||
|
958c78d968 | ||
|
9f81597596 | ||
|
001f2b6c9e | ||
|
a56bb562d8 | ||
|
7695f005f6 | ||
|
a10f9d230d | ||
|
9f350541bf | ||
|
0643699fac | ||
|
9f63dff49b | ||
|
7d3a2df793 | ||
|
0967c3449e | ||
|
f267643c42 | ||
|
f3387ed5e9 | ||
|
71d1aab69e | ||
|
4c6118f50f | ||
|
77da3f9762 | ||
|
8b3cb63f77 | ||
|
fc1c9feafd | ||
|
371be8aa27 | ||
|
7bb14e6c25 | ||
|
cdb07dfaea | ||
|
c2830fca6b | ||
|
bba67b5533 | ||
|
eda9924327 | ||
|
07b8f5fe83 | ||
|
d31a544a23 | ||
|
01b7b58065 | ||
|
870dd99e2c | ||
|
01b88dba25 | ||
|
2605011df4 | ||
|
00cf312a91 | ||
|
e3ed80b121 | ||
|
0752abc312 | ||
|
ded24c8b4f | ||
|
7799a5da61 | ||
|
6cb08cf458 | ||
|
305ea4619f | ||
|
291de2005d | ||
|
34bc223f02 | ||
|
bf9fad18b6 | ||
|
cebf3506d4 | ||
|
a43825caa2 |
99
CHANGELOG.md
99
CHANGELOG.md
@ -1,3 +1,102 @@
|
|||||||
|
## [1.6.1](https://github.com/Tencent/tmagic-editor/compare/v1.6.0...v1.6.1) (2025-10-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **core:** 异步加载数据源时,数据源事件配置失效 ([1031595](https://github.com/Tencent/tmagic-editor/commit/1031595a976b33f8e5e3a71d8c00944d4777beb1))
|
||||||
|
* **form:** text与同行元素不对齐问题 ([cae11dc](https://github.com/Tencent/tmagic-editor/commit/cae11dce1290b9ea314c07daee30f1eb6f400681))
|
||||||
|
* 组件声明周期函数配置中配置数据源自有方法生效 ([e400175](https://github.com/Tencent/tmagic-editor/commit/e400175ffe89ab3105e50d2ffcd702d9d2a12970))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **data-source, editor, schema, react-runtime-help, vue-components:** 新增条件成立时隐藏的配置功能 ([51f95ae](https://github.com/Tencent/tmagic-editor/commit/51f95aef6f649851222e09e7234648f4985d1ad8))
|
||||||
|
* **data-source:** 数据源数据变化事件监听响应支持立即执行 ([849b561](https://github.com/Tencent/tmagic-editor/commit/849b561933d74bcc68f75f15d67e0d252c5a8468))
|
||||||
|
* **editor:** 属性配置中的样式面板样式优化 ([81aa8f1](https://github.com/Tencent/tmagic-editor/commit/81aa8f151d765bf08d2f88c334ff7c58b38aab56))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.6.0](https://github.com/Tencent/tmagic-editor/compare/v1.6.0-beta.6...v1.6.0) (2025-08-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **cli:** 在pnpm工作空间中的项目,保持package.json不受配置中的packages影响 ([a10f9d2](https://github.com/Tencent/tmagic-editor/commit/a10f9d230d93064c28ff82f2c3aba2679f8fe495))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **cli:** 支持tmagic.config.local配置文件,会与tmagic.config配置合并,可用于本地开发时的临时配置 ([9f35054](https://github.com/Tencent/tmagic-editor/commit/9f350541bf84a634499a9af53449015f34da26b5))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.6.0-beta.6](https://github.com/Tencent/tmagic-editor/compare/v1.6.0-beta.5...v1.6.0-beta.6) (2025-08-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **core:** 事件支持关联数据源自身方法 ([4c6118f](https://github.com/Tencent/tmagic-editor/commit/4c6118f50f8e78e8db157f9b32c49f5f068e3e9a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.6.0-beta.5](https://github.com/Tencent/tmagic-editor/compare/v1.6.0-beta.4...v1.6.0-beta.5) (2025-08-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **core:** 事件行为应该为串行执行 ([fc1c9fe](https://github.com/Tencent/tmagic-editor/commit/fc1c9feafd337ad8fa8a9b5b3501278779d32410))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.6.0-beta.4](https://github.com/Tencent/tmagic-editor/compare/v1.6.0-beta.3...v1.6.0-beta.4) (2025-07-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **editor:** runtime url更新后恢复当前选中状态 ([c2830fc](https://github.com/Tencent/tmagic-editor/commit/c2830fca6b21648b51a486650caba3f9eb753c91))
|
||||||
|
* **editor:** 避免services plugin重复添加 ([cdb07df](https://github.com/Tencent/tmagic-editor/commit/cdb07dfaea13a1813caddd59ba7e8efbdb374b3c))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.6.0-beta.3](https://github.com/Tencent/tmagic-editor/compare/v1.6.0-beta.2...v1.6.0-beta.3) (2025-07-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **editor:** runtimeUrl更新后需要重新设置runtime的dsl ([d31a544](https://github.com/Tencent/tmagic-editor/commit/d31a544a2312b4d78ae74eb600760df450946db8))
|
||||||
|
* **editor:** 修复代码块编辑器的更新内容后按下ctrl+s光标会偏移的问题 ([07b8f5f](https://github.com/Tencent/tmagic-editor/commit/07b8f5fe8303bad57490c7dd0eba00e435fbfad5))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.6.0-beta.2](https://github.com/Tencent/tmagic-editor/compare/v1.6.0-beta.1...v1.6.0-beta.2) (2025-07-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **core:** 异步加载dsl片段下,事件触发时node可能不存在 ([01b88db](https://github.com/Tencent/tmagic-editor/commit/01b88dba251a1f7cc29947c2a80e15839e50fcca))
|
||||||
|
* **utile:** replaceChildNode找不多目标不报错 ([2605011](https://github.com/Tencent/tmagic-editor/commit/2605011df481d9edba5503d2ee3b3c9d4b76d0a3))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.6.0-beta.1](https://github.com/Tencent/tmagic-editor/compare/v1.6.0-beta.0...v1.6.0-beta.1) (2025-07-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **data-source:** 页面未初始化好之前,数据源数据变化后需要修改page.data ([305ea46](https://github.com/Tencent/tmagic-editor/commit/305ea4619fe15efbae069ef3f289c8742e8d51ee))
|
||||||
|
* **vue-components:** iterator-container 传递 page-fragment-contianer-id 参数 ([7799a5d](https://github.com/Tencent/tmagic-editor/commit/7799a5da618b0136f4b3c12315c69d21b27a5965))
|
||||||
|
* **vue-components:** page-fragment-container不标记为不是node节点 ([bf9fad1](https://github.com/Tencent/tmagic-editor/commit/bf9fad18b64521a9075a60f7e6e662b01d37f66f))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **core:** Node中的instance初始为null,用于判断是否与组件产生关联 ([291de20](https://github.com/Tencent/tmagic-editor/commit/291de2005de54b8eeba818de67ab3506885f5057))
|
||||||
|
* **editor:** 页面片容器内的组件不允许选中 ([ded24c8](https://github.com/Tencent/tmagic-editor/commit/ded24c8b4ff2c203260ec7633fc85325c98a565c))
|
||||||
|
* **vue-components:** page-fragment-container编辑器中不去除内部组件id,不然会导致无法从app中获取dsl ([34bc223](https://github.com/Tencent/tmagic-editor/commit/34bc223f0241d9eef39450ebcef8a92b23c63f37))
|
||||||
|
* **vue-components:** 添加页面片容器id prop ([a43825c](https://github.com/Tencent/tmagic-editor/commit/a43825caa27695fcd85cc4b5351a00080fefcec0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [1.6.0-beta.0](https://github.com/Tencent/tmagic-editor/compare/v1.5.24...v1.6.0-beta.0) (2025-07-15)
|
# [1.6.0-beta.0](https://github.com/Tencent/tmagic-editor/compare/v1.5.24...v1.6.0-beta.0) (2025-07-15)
|
||||||
|
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ const stageContentMenu = ref([
|
|||||||
```html
|
```html
|
||||||
<template>
|
<template>
|
||||||
<m-editor
|
<m-editor
|
||||||
runtime-url="https://tencent.github.io/tmagic-editor/playground/runtime/vue3/playground/index.html"
|
runtime-url="https://tencent.github.io/tmagic-editor/playground/runtime/vue/playground/index.html"
|
||||||
></m-editor>
|
></m-editor>
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
@ -60,6 +60,5 @@ export default defineComponent({
|
|||||||
|
|
||||||
## 渲染器示例
|
## 渲染器示例
|
||||||
在tmagic-editor的示例项目中,我们提供了三个版本的 @tmagic/ui。可以参考对应前端框架的渲染器实现。
|
在tmagic-editor的示例项目中,我们提供了三个版本的 @tmagic/ui。可以参考对应前端框架的渲染器实现。
|
||||||
- [vue3 渲染器](https://github.com/Tencent/tmagic-editor/blob/master/packages/ui/src/container/src/Container.vue)
|
- [vue 渲染器](https://github.com/Tencent/tmagic-editor/blob/master/vue-components/container/src/Container.vue)
|
||||||
- [vue2 渲染器](https://github.com/Tencent/tmagic-editor/blob/master/packages/ui-vue2/src/container/Container.vue)
|
- [react 渲染器](https://github.com/Tencent/tmagic-editor/blob/master/react-components/container/src/Container.tsx)
|
||||||
- [react 渲染器](https://github.com/Tencent/tmagic-editor/blob/master/packages/ui-react/src/container/Container.tsx)
|
|
@ -5,15 +5,13 @@ tmagic-editor的设计是希望发布的页面支持多个前端框架,即各
|
|||||||
|
|
||||||
所以tmagic-editor的设计中,针对每个前端框架,都需要有一个对应的 @tmagic/ui 来承担渲染器职责。同时,也需要一个使用和 @tmagic/ui 相同前端框架的 runtime 来 @tmagic/ui 和业务组件的,具体 runtime 概念,可以参考[页面发布](../publish)。
|
所以tmagic-editor的设计中,针对每个前端框架,都需要有一个对应的 @tmagic/ui 来承担渲染器职责。同时,也需要一个使用和 @tmagic/ui 相同前端框架的 runtime 来 @tmagic/ui 和业务组件的,具体 runtime 概念,可以参考[页面发布](../publish)。
|
||||||
|
|
||||||
@tmagic/ui 在tmagic-editor设计中,承担的是业务逻辑无关的,基础组件渲染的功能。一切和业务相关的逻辑,都应该在 [runtime](../runtime.html) 中实现。这样 @tmagic/ui 就能保持其通用性。
|
我们以项目代码中提供的 vue 版本的 [vue-components](https://tencent.github.io/tmagic-editor/vue-components) 作为示例介绍其中包含的内容。
|
||||||
|
|
||||||
我们以项目代码中提供的 vue3 版本的 @tmagic/ui 作为示例介绍其中包含的内容。
|
|
||||||
|
|
||||||
## 渲染器
|
## 渲染器
|
||||||
在 vue3 中,实现渲染器的具体形式参考[页面渲染](../advanced/page)中描述的[容器渲染](../advanced/page.html#容器渲染)和[组件渲染](../advanced/page.html#容器渲染)。
|
在 vue 中,实现渲染器的具体形式参考[页面渲染](../advanced/page)中描述的[容器渲染](../advanced/page.html#容器渲染)和[组件渲染](../advanced/page.html#容器渲染)。
|
||||||
|
|
||||||
## 基础组件
|
## 基础组件
|
||||||
在 @tmagic/ui vue3 中,我们提供了几个基础组件,可以在项目源码中找到对应内容。
|
在 [vue-components](https://tencent.github.io/tmagic-editor/vue-components) 中,我们提供了几个基础组件,可以在项目源码中找到对应内容。
|
||||||
|
|
||||||
- page tmagic-editor的页面基础
|
- page tmagic-editor的页面基础
|
||||||
- container tmagic-editor的容器渲染器
|
- container tmagic-editor的容器渲染器
|
||||||
@ -23,8 +21,3 @@ tmagic-editor的设计是希望发布的页面支持多个前端框架,即各
|
|||||||
其中 page/container/Component 是 UI 的基础,是每个框架的 UI 都应该实现的。
|
其中 page/container/Component 是 UI 的基础,是每个框架的 UI 都应该实现的。
|
||||||
|
|
||||||
button/text 其实就是一个组件开发的示例,具体组件开发相关规范可以参考[组件开发](../component)。
|
button/text 其实就是一个组件开发的示例,具体组件开发相关规范可以参考[组件开发](../component)。
|
||||||
|
|
||||||
## @tmagic/ui 示例
|
|
||||||
- [vue3 渲染器](https://github.com/Tencent/tmagic-editor/blob/master/packages/ui)
|
|
||||||
- [vue2 渲染器](https://github.com/Tencent/tmagic-editor/blob/master/packages/ui-vue2)
|
|
||||||
- [react 渲染器](https://github.com/Tencent/tmagic-editor/blob/master/packages/ui-react)
|
|
@ -2,14 +2,14 @@
|
|||||||
tmagic-editor支持业务方进行自定义组件开发。在tmagic-editor中,组件是以 npm 包形式存在的,组件和插件只要按照规范开发,就可以在tmagic-editor的 runtime 中被加入并正确渲染组件。
|
tmagic-editor支持业务方进行自定义组件开发。在tmagic-editor中,组件是以 npm 包形式存在的,组件和插件只要按照规范开发,就可以在tmagic-editor的 runtime 中被加入并正确渲染组件。
|
||||||
|
|
||||||
## 组件开发
|
## 组件开发
|
||||||
以 vue3 的组件开发为例。运行项目中的 playground 示例,会自动加载 vue3 的 runtime。runtime会加载[@tmagic/ui](https://github.com/Tencent/tmagic-editor/tree/master/packages/ui)
|
以 vue 的组件开发为例。运行项目中的 playground 示例,会自动加载 vue 的 runtime。runtime会加载[@tmagic/ui](https://github.com/Tencent/tmagic-editor/tree/master/packages/ui)
|
||||||
|
|
||||||
## 组件注册
|
## 组件注册
|
||||||
在 [playground](https://tencent.github.io/tmagic-editor/playground/index.html#/) 中,我们可以尝试点击添加一个组件,在模拟器区域里,就会出现这个组件。其中就涉及到组件注册。
|
在 [playground](https://tencent.github.io/tmagic-editor/playground/index.html#/) 中,我们可以尝试点击添加一个组件,在模拟器区域里,就会出现这个组件。其中就涉及到组件注册。
|
||||||
|
|
||||||
这一步需要开发者基于tmagic-editor搭建了平台后,实现组件列表的注册、获取机制,tmagic-editor组件注册其实就是保存好组件 `type` 的映射关系。`type` 可以参考[组件介绍](../guide/conception.html#组件)。
|
这一步需要开发者基于tmagic-editor搭建了平台后,实现组件列表的注册、获取机制,tmagic-editor组件注册其实就是保存好组件 `type` 的映射关系。`type` 可以参考[组件介绍](../guide/conception.html#组件)。
|
||||||
|
|
||||||
可以参考 vue3 版本的 @tmagic/ui 中,[组件渲染](../guide/advanced/page.html#组件渲染)逻辑里,type 会作为组件名进入渲染。所以在 vue3 的组件开发中,我们也需要在为 vue 组件声明 name 字段时,和 type 值对应起来,才能正确渲染组件。
|
可以参考 vue 版本的 @tmagic/ui 中,[组件渲染](../guide/advanced/page.html#组件渲染)逻辑里,type 会作为组件名进入渲染。所以在 vue 的组件开发中,我们也需要在为 vue 组件声明 name 字段时,和 type 值对应起来,才能正确渲染组件。
|
||||||
|
|
||||||
### 组件规范
|
### 组件规范
|
||||||
组件的基础形式,需要有四个文件
|
组件的基础形式,需要有四个文件
|
||||||
@ -22,7 +22,7 @@ tmagic-editor支持业务方进行自定义组件开发。在tmagic-editor中,
|
|||||||
@tmagic/ui 中的 button/text 就是基础的组件示例。我们要求声明 index 入口,因为我们希望在后续的配套打包工具实现上,可以有一个统一规范入口。
|
@tmagic/ui 中的 button/text 就是基础的组件示例。我们要求声明 index 入口,因为我们希望在后续的配套打包工具实现上,可以有一个统一规范入口。
|
||||||
|
|
||||||
### 1. 创建组件
|
### 1. 创建组件
|
||||||
在项目中,如 runtime vue3 目录中,创建一个名为 test-component 的组件目录,其中包含上面四个规范文件。
|
在项目中,如 runtime 目录中,创建一个名为 test-component 的组件目录,其中包含上面四个规范文件。
|
||||||
```javascript
|
```javascript
|
||||||
// index.js
|
// index.js
|
||||||
// vue
|
// vue
|
||||||
@ -69,7 +69,7 @@ export default {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
vue3 版本的组件代码示例
|
版本的组件代码示例
|
||||||
```vue
|
```vue
|
||||||
<!-- Test.vue -->
|
<!-- Test.vue -->
|
||||||
<template>
|
<template>
|
||||||
@ -119,7 +119,7 @@ export default Test;
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 2. 使用tmagic-cli
|
### 2. 使用tmagic-cli
|
||||||
在 runtime vue3 中,我们已经提供好一份示例。在 tmagic.config.ts 文件中。只需要在 packages 加入你创建的组件的路径(如果是个 npm 包,则将路径替换为包名即可),打包工具就会自动识别到你的组件。
|
在 runtime vue 中,我们已经提供好一份示例。在 tmagic.config.ts 文件中。只需要在 packages 加入你创建的组件的路径(如果是个 npm 包,则将路径替换为包名即可),打包工具就会自动识别到你的组件。
|
||||||
|
|
||||||
### 3. 启动 playground
|
### 3. 启动 playground
|
||||||
在上面的步骤完成后,在 playground/src/configs/componentGroupList 中。找到组件栏的基础组件列表,在其中加入你的开发组件
|
在上面的步骤完成后,在 playground/src/configs/componentGroupList 中。找到组件栏的基础组件列表,在其中加入你的开发组件
|
||||||
@ -155,7 +155,7 @@ npm run playground
|
|||||||
<img src="https://image.video.qpic.cn/oa_fd3c9c-3_548108267_1636719045199471">
|
<img src="https://image.video.qpic.cn/oa_fd3c9c-3_548108267_1636719045199471">
|
||||||
|
|
||||||
### 4. 启动 runtime
|
### 4. 启动 runtime
|
||||||
在完成开发中组件在编辑器中的实现后,我们将编辑器中的 DSL 源码📄 打开,复制 DSL。并在 runtime/vue3/src/page 下。创建一个 page-config.js 文件。将 DSL 作为配置导出。
|
在完成开发中组件在编辑器中的实现后,我们将编辑器中的 DSL 源码📄 打开,复制 DSL。并在 runtime/vue/src/page 下。创建一个 page-config.js 文件。将 DSL 作为配置导出。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
window.magicDSL = [
|
window.magicDSL = [
|
||||||
@ -168,7 +168,7 @@ window.magicDSL = [
|
|||||||
import './page-config.js';
|
import './page-config.js';
|
||||||
```
|
```
|
||||||
|
|
||||||
然后执行在 runtime/vue3 目录下执行
|
然后执行在 runtime/ 目录下执行
|
||||||
```
|
```
|
||||||
npm run build:libs
|
npm run build:libs
|
||||||
npm run dev
|
npm run dev
|
||||||
|
@ -60,11 +60,6 @@ DSL 是编辑器搭建页面的最终产物(描述文件),其中包含了
|
|||||||
### runtime
|
### runtime
|
||||||
我们把页面统一称为 runtime,更具体的 runtime 概念可以查看[页面发布](./publish.html#runtime)。**runtime 是承载tmagic-editor项目页面的运行环境**。编辑器的工作区是 runtime 的一个具体实例,另一个就是我们发布上线后,用户访问的真实项目页面。
|
我们把页面统一称为 runtime,更具体的 runtime 概念可以查看[页面发布](./publish.html#runtime)。**runtime 是承载tmagic-editor项目页面的运行环境**。编辑器的工作区是 runtime 的一个具体实例,另一个就是我们发布上线后,用户访问的真实项目页面。
|
||||||
|
|
||||||
### @tmagic/ui
|
|
||||||
@tmagic/ui 包含了tmagic-editor的基础组件库,提供了容器、文本、按钮这样的基础组件。我们提供了不同语言框架的 @tmagic/ui,如 vue2 和 vue3。
|
|
||||||
|
|
||||||
@tmagic/ui 和 runtime 是配套出现的,runtime 必须基于 @tmagic/ui 才可以实现渲染。因为 @tmagic/ui 需要提供 runtime 所需要的渲染器。
|
|
||||||
|
|
||||||
## 联动
|
## 联动
|
||||||
页面搭建过程中,会涉及到两种联动形式
|
页面搭建过程中,会涉及到两种联动形式
|
||||||
- 在编辑器中,组件的表单配置项之间需要联动。
|
- 在编辑器中,组件的表单配置项之间需要联动。
|
||||||
|
@ -125,7 +125,7 @@ app.mount('#app');
|
|||||||
// 初始化页面数据
|
// 初始化页面数据
|
||||||
}),
|
}),
|
||||||
|
|
||||||
runtimeUrl: "/runtime/vue3/playground/index.html",
|
runtimeUrl: "/runtime/vue/playground/index.html",
|
||||||
|
|
||||||
propsConfigs: [
|
propsConfigs: [
|
||||||
// 组件属性列表
|
// 组件属性列表
|
||||||
@ -208,10 +208,10 @@ npm install sass -D
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
setup() {
|
setup() {
|
||||||
asyncLoadJs(`/runtime/vue3/assets/config.js`).then(() => {
|
asyncLoadJs(`/runtime/vue/assets/config.js`).then(() => {
|
||||||
propsConfigs.value = window.magicPresetConfigs;
|
propsConfigs.value = window.magicPresetConfigs;
|
||||||
});
|
});
|
||||||
asyncLoadJs(`/runtime/vue3/assets/value.js`).then(() => {
|
asyncLoadJs(`/runtime/vue/assets/value.js`).then(() => {
|
||||||
propsValues.value = window.magicPresetValues;
|
propsValues.value = window.magicPresetValues;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,6 @@ tmagic-editor可视化开源项目是从魔方平台演化而来的开源项目
|
|||||||
- **@tmagic/core** 实现对组件进行跨框架管理与一些通用复杂逻辑的实现。
|
- **@tmagic/core** 实现对组件进行跨框架管理与一些通用复杂逻辑的实现。
|
||||||
- **@tmagic/data-source** 实现数据源的管理与编译。
|
- **@tmagic/data-source** 实现数据源的管理与编译。
|
||||||
- **@tmagic/stage** 实现在编辑器中对组件的位置拖动与大小拖拉。
|
- **@tmagic/stage** 实现在编辑器中对组件的位置拖动与大小拖拉。
|
||||||
- **@tmagic/ui** 提供一些vue3基础组件。
|
|
||||||
- **@tmagic/ui-vue2** 提供一些vue2基础组件。
|
|
||||||
- **@tmagic/ui-react** 提供一些react基础组件。
|
|
||||||
- **runtime** 实现在编辑器中对使用不同框架的组件的渲染。
|
- **runtime** 实现在编辑器中对使用不同框架的组件的渲染。
|
||||||
|
|
||||||
可以查阅 tmagic 的[源代码](https://github.com/Tencent/tmagic-editor),与文档描述内容可以逐一对应上,希望文档内容可以为开发者带来比较好的开发体验。
|
可以查阅 tmagic 的[源代码](https://github.com/Tencent/tmagic-editor),与文档描述内容可以逐一对应上,希望文档内容可以为开发者带来比较好的开发体验。
|
||||||
|
@ -13,7 +13,7 @@ runtime 的概念,是理解tmagic-editor项目页运行的重要概念,runti
|
|||||||
|
|
||||||
所以更深入描述,runtime 是tmagic-editor页面的渲染环境,提供不同场景下的能力封装。如果理解了tmagic-editor的设计,阅读了tmagic-editor的源码,可以发现,runtime 只是对tmagic-editor的渲染器做了一层包装,在不同 runtime 中,tmagic-editor的渲染逻辑和组件代码都是相同的。
|
所以更深入描述,runtime 是tmagic-editor页面的渲染环境,提供不同场景下的能力封装。如果理解了tmagic-editor的设计,阅读了tmagic-editor的源码,可以发现,runtime 只是对tmagic-editor的渲染器做了一层包装,在不同 runtime 中,tmagic-editor的渲染逻辑和组件代码都是相同的。
|
||||||
|
|
||||||
并且,由于tmagic-editor在编辑器中的模拟器是通过 iframe 渲染的,和tmagic-editor平台本身可以做到框架解耦,所以 runtime 也可以用不同框架开发。目前tmagic-editor提供了 vue2/vue3 和 react 的 runtime 示例。
|
并且,由于tmagic-editor在编辑器中的模拟器是通过 iframe 渲染的,和tmagic-editor平台本身可以做到框架解耦,所以 runtime 也可以用不同框架开发。目前tmagic-editor提供了 vue 和 react 的 runtime 示例。
|
||||||
|
|
||||||
各个 runtime 的作用除了作为不同场景下的渲染环境,同时也是不同环境的打包构建载体。tmagic-editor示例代码中的打包就是基于 runtime 进行的。
|
各个 runtime 的作用除了作为不同场景下的渲染环境,同时也是不同环境的打包构建载体。tmagic-editor示例代码中的打包就是基于 runtime 进行的。
|
||||||
|
|
||||||
@ -21,8 +21,7 @@ runtime 的概念,是理解tmagic-editor项目页运行的重要概念,runti
|
|||||||
由于 runtime 是页面渲染的承载环境,其中会加载 @tmagic/ui 以及各个业务组件,业务发布项目页也是基于 runtime,所以在 runtime 中实现业务方的自定义逻辑是最合适的。runtime 可以提供一些全局 API,供业务组件调用。我们可以把下面的模拟器中的 runtime 视为一个业务方runtime。
|
由于 runtime 是页面渲染的承载环境,其中会加载 @tmagic/ui 以及各个业务组件,业务发布项目页也是基于 runtime,所以在 runtime 中实现业务方的自定义逻辑是最合适的。runtime 可以提供一些全局 API,供业务组件调用。我们可以把下面的模拟器中的 runtime 视为一个业务方runtime。
|
||||||
|
|
||||||
tmagic-editor提供了三个版本的 runtime 示例,可以参考:
|
tmagic-editor提供了三个版本的 runtime 示例,可以参考:
|
||||||
- [vue3 runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue3)
|
- [vue runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue)
|
||||||
- [vue2 runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue2)
|
|
||||||
- [react runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/react)
|
- [react runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/react)
|
||||||
|
|
||||||
### 真实页面渲染(Page)
|
### 真实页面渲染(Page)
|
||||||
|
@ -14,8 +14,7 @@ runtime 的 `page` 部分,就是真实项目页面的渲染环境。发布出
|
|||||||
- 加载第三方全局组件/插件等
|
- 加载第三方全局组件/插件等
|
||||||
|
|
||||||
具体的 page 实现示例,可以参考
|
具体的 page 实现示例,可以参考
|
||||||
- [vue3 runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue3/page)
|
- [vue runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue/page)
|
||||||
- [vue2 runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue2/page)
|
|
||||||
- [react runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/react/page)
|
- [react runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/react/page)
|
||||||
|
|
||||||
### playground
|
### playground
|
||||||
@ -45,8 +44,7 @@ window.magic.onPageElUpdate(document.querySelector('.magic-ui-page'));
|
|||||||
|sortNode| 组件在容器间排序 |{ `src` , `dist`, `root` }: `SortEventData` |
|
|sortNode| 组件在容器间排序 |{ `src` , `dist`, `root` }: `SortEventData` |
|
||||||
|
|
||||||
runtime 的实现示例,可以参考tmagic-editor提供的:
|
runtime 的实现示例,可以参考tmagic-editor提供的:
|
||||||
- [vue3 runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue3)
|
- [vue runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue)
|
||||||
- [vue2 runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue2)
|
|
||||||
- [react runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/react)
|
- [react runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/react)
|
||||||
|
|
||||||
### 页面发布
|
### 页面发布
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# 3.[DSL](../conception.md#dsl) 解析渲染
|
# 3.[DSL](../conception.md#dsl) 解析渲染
|
||||||
|
|
||||||
tmagic 提供了 vue3/vue2/react 三个版本的解析渲染组件,可以直接使用
|
tmagic 提供了 vue/react 两个个版本的解析渲染组件,可以直接使用
|
||||||
|
|
||||||
[@tmagic/ui](https://www.npmjs.com/package/@tmagic/ui)
|
[@tmagic/ui](https://www.npmjs.com/package/@tmagic/ui)
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import js from '@eslint/js';
|
import js from '@eslint/js';
|
||||||
import stylistic from '@stylistic/eslint-plugin';
|
import stylistic from '@stylistic/eslint-plugin';
|
||||||
import stylisticTs from '@stylistic/eslint-plugin-ts';
|
|
||||||
import parserTs from '@typescript-eslint/parser';
|
import parserTs from '@typescript-eslint/parser';
|
||||||
import { defineConfig } from 'eslint/config';
|
import { defineConfig } from 'eslint/config';
|
||||||
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
||||||
@ -21,7 +20,6 @@ export default (tsconfigRootDir) =>
|
|||||||
...tseslint.config(tencentEslintBaseConfig, tencentEslintImportexport, tseslint.configs.base, {
|
...tseslint.config(tencentEslintBaseConfig, tencentEslintImportexport, tseslint.configs.base, {
|
||||||
plugins: {
|
plugins: {
|
||||||
'@stylistic': stylistic,
|
'@stylistic': stylistic,
|
||||||
'@stylistic/ts': stylisticTs,
|
|
||||||
},
|
},
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
parser: parserTs,
|
parser: parserTs,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@tmagic/eslint-config",
|
"name": "@tmagic/eslint-config",
|
||||||
"version": "0.0.2",
|
"version": "0.0.3",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"repository": {
|
"repository": {
|
||||||
@ -9,18 +9,17 @@
|
|||||||
"url": "https://github.com/Tencent/tmagic-editor.git"
|
"url": "https://github.com/Tencent/tmagic-editor.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/js": "^9.24.0",
|
"@eslint/js": "^9.34.0",
|
||||||
"@typescript-eslint/parser": "^8.30.1",
|
"@typescript-eslint/parser": "^8.41.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.30.1",
|
"@typescript-eslint/eslint-plugin": "^8.41.0 ",
|
||||||
"@stylistic/eslint-plugin": "^4.2.0",
|
"@stylistic/eslint-plugin": "^5.2.3",
|
||||||
"@stylistic/eslint-plugin-ts": "^4.2.0",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-config-prettier": "^10.1.2",
|
"eslint-plugin-import": "^2.32.0",
|
||||||
"eslint-plugin-import": "^2.31.0",
|
|
||||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||||
"eslint-plugin-vue": "^10.0.0",
|
"eslint-plugin-vue": "^10.4.0",
|
||||||
"eslint-plugin-prettier": "^5.2.6",
|
"eslint-plugin-prettier": "^5.5.4 ",
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.3.0",
|
||||||
"typescript-eslint": "^8.30.1"
|
"typescript-eslint": "^8.41.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": ">=9.24.0",
|
"eslint": ">=9.24.0",
|
||||||
|
28
package.json
28
package.json
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "tmagic",
|
"name": "tmagic",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"packageManager": "pnpm@10.11.1",
|
"packageManager": "pnpm@10.18.2",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"bootstrap": "pnpm i && pnpm build",
|
"bootstrap": "pnpm i && pnpm build",
|
||||||
"clean:top": "rimraf */**/dist */**/types */dist coverage dwt* temp packages/cli/lib",
|
"clean:top": "rimraf */**/dist */**/types */dist coverage dwt* temp packages/cli/lib",
|
||||||
@ -11,16 +11,14 @@
|
|||||||
"clean:all": "pnpm clean:top && pnpm clean:modules",
|
"clean:all": "pnpm clean:top && pnpm clean:modules",
|
||||||
"lint": "eslint --cache .",
|
"lint": "eslint --cache .",
|
||||||
"lint-fix": "eslint --fix --cache .",
|
"lint-fix": "eslint --fix --cache .",
|
||||||
"playground": "pnpm --filter \"runtime-vue3\" build:libs && pnpm --filter \"runtime-vue3\" --filter \"tmagic-playground\" dev",
|
"playground": "pnpm --filter \"runtime-vue\" build:libs && pnpm --filter \"runtime-vue\" --filter \"tmagic-playground\" dev",
|
||||||
"pg": "pnpm playground",
|
"pg": "pnpm playground",
|
||||||
"playground:vue2": "pnpm --filter \"runtime-vue2\" build:libs && pnpm --filter \"runtime-vue2\" --filter \"tmagic-playground\" dev:vue2",
|
|
||||||
"pg:vue2": "pnpm playground:vue2",
|
|
||||||
"playground:react": "pnpm --filter \"runtime-react\" build:libs && pnpm --filter \"runtime-react\" --filter \"tmagic-playground\" dev:react",
|
"playground:react": "pnpm --filter \"runtime-react\" build:libs && pnpm --filter \"runtime-react\" --filter \"tmagic-playground\" dev:react",
|
||||||
"pg:react": "pnpm playground:react",
|
"pg:react": "pnpm playground:react",
|
||||||
"build": "pnpm build:dts && node scripts/build.mjs",
|
"build": "pnpm build:dts && node scripts/build.mjs",
|
||||||
"build:dts": "pnpm --filter \"@tmagic/cli\" build && tsc -p tsconfig.build-browser.json && vue-tsc --declaration --emitDeclarationOnly --project tsconfig.build-vue.json && rollup -c rollup.dts.config.js && rimraf temp",
|
"build:dts": "pnpm --filter \"@tmagic/cli\" build && tsc -p tsconfig.build-browser.json && vue-tsc --declaration --emitDeclarationOnly --project tsconfig.build-vue.json && rollup -c rollup.dts.config.js && rimraf temp",
|
||||||
"check:type": "tsc --incremental --noEmit -p tsconfig.check.json && vue-tsc --noEmit -p tsconfig.check-vue.json",
|
"check:type": "tsc --incremental --noEmit -p tsconfig.check.json && vue-tsc --noEmit -p tsconfig.check-vue.json",
|
||||||
"build:playground": "pnpm --filter \"runtime-vue3\" build && pnpm --filter \"tmagic-playground\" build",
|
"build:playground": "pnpm --filter \"runtime-vue\" build && pnpm --filter \"tmagic-playground\" build",
|
||||||
"docs:dev": "vitepress dev docs",
|
"docs:dev": "vitepress dev docs",
|
||||||
"docs:serve": "vitepress serve docs",
|
"docs:serve": "vitepress serve docs",
|
||||||
"docs:build": "vitepress build docs",
|
"docs:build": "vitepress build docs",
|
||||||
@ -32,7 +30,7 @@
|
|||||||
"release": "node scripts/release.mjs"
|
"release": "node scripts/release.mjs"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
},
|
},
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
@ -49,15 +47,15 @@
|
|||||||
"@types/node": "24.0.10",
|
"@types/node": "24.0.10",
|
||||||
"@vitejs/plugin-vue": "^5.2.3",
|
"@vitejs/plugin-vue": "^5.2.3",
|
||||||
"@vitest/coverage-v8": "^2.1.9",
|
"@vitest/coverage-v8": "^2.1.9",
|
||||||
"@vue/compiler-sfc": "^3.5.13",
|
"@vue/compiler-sfc": "catalog:",
|
||||||
"c8": "^7.14.0",
|
"c8": "^7.14.0",
|
||||||
"commitizen": "^4.3.1",
|
"commitizen": "^4.3.1",
|
||||||
"conventional-changelog-cli": "^5.0.0",
|
"conventional-changelog-cli": "^5.0.0",
|
||||||
"cosmiconfig": "^8.3.6",
|
"cosmiconfig": "^8.3.6",
|
||||||
"cz-conventional-changelog": "^3.3.0",
|
"cz-conventional-changelog": "^3.3.0",
|
||||||
"element-plus": "^2.9.11",
|
"element-plus": "^2.11.4",
|
||||||
"enquirer": "^2.4.1",
|
"enquirer": "^2.4.1",
|
||||||
"eslint": "^9.28.0",
|
"eslint": "^9.37.0",
|
||||||
"execa": "^4.1.0",
|
"execa": "^4.1.0",
|
||||||
"highlight.js": "^11.11.1",
|
"highlight.js": "^11.11.1",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
@ -65,20 +63,20 @@
|
|||||||
"lint-staged": "^16.1.0",
|
"lint-staged": "^16.1.0",
|
||||||
"minimist": "^1.2.8",
|
"minimist": "^1.2.8",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.6.2",
|
||||||
"recast": "^0.23.11",
|
"recast": "^0.23.11",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rollup": "^4.44.1",
|
"rollup": "4.44.1",
|
||||||
"rollup-plugin-dts": "^6.2.1",
|
"rollup-plugin-dts": "^6.2.1",
|
||||||
"semver": "^7.7.1",
|
"semver": "^7.7.1",
|
||||||
"serialize-javascript": "^6.0.2",
|
"serialize-javascript": "^6.0.2",
|
||||||
"shx": "^0.3.4",
|
"shx": "^0.3.4",
|
||||||
"typescript": "catalog:",
|
"typescript": "catalog:",
|
||||||
"vite": "catalog:",
|
"vite": "catalog:",
|
||||||
"vitepress": "^1.6.3",
|
"vitepress": "^1.6.4",
|
||||||
"vitest": "^3.2.1",
|
"vitest": "^3.2.4",
|
||||||
"vue": "catalog:",
|
"vue": "catalog:",
|
||||||
"vue-tsc": "^3.0.0"
|
"vue-tsc": "^3.1.1"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"commitizen": {
|
"commitizen": {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/cli",
|
"name": "@tmagic/cli",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
@ -30,6 +30,7 @@
|
|||||||
"chokidar": "^3.6.0",
|
"chokidar": "^3.6.0",
|
||||||
"esbuild": "^0.21.5",
|
"esbuild": "^0.21.5",
|
||||||
"fs-extra": "^11.2.0",
|
"fs-extra": "^11.2.0",
|
||||||
|
"merge-options": "^3.0.4",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"recast": "^0.23.11",
|
"recast": "^0.23.11",
|
||||||
"tslib": "^2.8.0"
|
"tslib": "^2.8.0"
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
|
// @ts-ignore
|
||||||
|
import mergeOptions from 'merge-options';
|
||||||
|
|
||||||
import App from '../Core';
|
import App from '../Core';
|
||||||
import { UserConfig } from '../types';
|
import { UserConfig } from '../types';
|
||||||
@ -22,18 +24,29 @@ export const scripts = (defaultAppConfig: UserConfig) => {
|
|||||||
path.resolve(defaultAppConfig.temp, 'config.cjs'),
|
path.resolve(defaultAppConfig.temp, 'config.cjs'),
|
||||||
].find((item) => fs.pathExistsSync(item));
|
].find((item) => fs.pathExistsSync(item));
|
||||||
|
|
||||||
const { npmConfig = {}, ...userConfig } = await loadUserConfig(userConfigPath);
|
const localUserConfigPath = [
|
||||||
|
path.resolve(defaultAppConfig.source, 'tmagic.config.local.ts'),
|
||||||
|
path.resolve(defaultAppConfig.source, 'tmagic.config.local.js'),
|
||||||
|
path.resolve(defaultAppConfig.source, 'tmagic.config.local.cjs'),
|
||||||
|
path.resolve(defaultAppConfig.temp, 'config.local.ts'),
|
||||||
|
path.resolve(defaultAppConfig.temp, 'config.local.js'),
|
||||||
|
path.resolve(defaultAppConfig.temp, 'config.local.cjs'),
|
||||||
|
].find((item) => fs.pathExistsSync(item));
|
||||||
|
|
||||||
|
let userConfig = await loadUserConfig(userConfigPath);
|
||||||
|
|
||||||
|
if (localUserConfigPath) {
|
||||||
|
const localUserConfig = await loadUserConfig(localUserConfigPath);
|
||||||
|
|
||||||
|
if (localUserConfig.packages?.length) {
|
||||||
|
localUserConfig.packages = [...(userConfig.packages || []), ...localUserConfig.packages];
|
||||||
|
}
|
||||||
|
|
||||||
|
userConfig = mergeOptions(userConfig, localUserConfig);
|
||||||
|
}
|
||||||
|
|
||||||
// resolve the final app config to use
|
// resolve the final app config to use
|
||||||
const appConfig = {
|
const appConfig = mergeOptions(defaultAppConfig, userConfig);
|
||||||
...defaultAppConfig,
|
|
||||||
...userConfig,
|
|
||||||
npmConfig: {
|
|
||||||
...(defaultAppConfig.npmConfig || {}),
|
|
||||||
...npmConfig,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const app = new App(appConfig);
|
const app = new App(appConfig);
|
||||||
|
|
||||||
// clean temp and cache
|
// clean temp and cache
|
||||||
|
@ -1,11 +1,35 @@
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
import process from 'node:process';
|
||||||
|
|
||||||
|
const windowsPathRegex = /^(?:[a-zA-Z]:|[\\/]{2}[^\\/]+[\\/]+[^\\/]+)?[\\/]$/;
|
||||||
|
|
||||||
|
export const isRootPath = (path: string) => {
|
||||||
|
if (typeof path !== 'string') {
|
||||||
|
throw new TypeError('Expected a string');
|
||||||
|
}
|
||||||
|
|
||||||
|
path = path.trim();
|
||||||
|
|
||||||
|
// While it's unclear how long a root path can be on Windows, it definitely cannot be longer than 100 characters.
|
||||||
|
if (path === '' || path.length > 100) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return process.platform === 'win32' ? windowsPathRegex.test(path) : path === '/';
|
||||||
|
};
|
||||||
|
|
||||||
export const backupFile = (runtimeSource: string, file: string) => {
|
export const backupFile = (runtimeSource: string, file: string) => {
|
||||||
|
if (isRootPath(runtimeSource)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const filePath = path.join(runtimeSource, file);
|
const filePath = path.join(runtimeSource, file);
|
||||||
|
|
||||||
if (fs.existsSync(filePath)) {
|
if (fs.existsSync(filePath)) {
|
||||||
fs.copyFileSync(filePath, `${filePath}.bak`);
|
fs.copyFileSync(filePath, `${filePath}.bak`);
|
||||||
|
} else {
|
||||||
|
backupFile(path.resolve(runtimeSource, '..'), file);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -26,11 +50,17 @@ export const backupLock = (runtimeSource: string, npmType: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const restoreFile = (runtimeSource: string, file: string) => {
|
export const restoreFile = (runtimeSource: string, file: string) => {
|
||||||
|
if (isRootPath(runtimeSource)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const filePath = path.join(runtimeSource, file);
|
const filePath = path.join(runtimeSource, file);
|
||||||
|
|
||||||
if (fs.existsSync(filePath)) {
|
if (fs.existsSync(filePath)) {
|
||||||
fs.unlinkSync(filePath);
|
fs.unlinkSync(filePath);
|
||||||
fs.renameSync(`${filePath}.bak`, filePath);
|
fs.renameSync(`${filePath}.bak`, filePath);
|
||||||
|
} else {
|
||||||
|
restoreFile(path.resolve(runtimeSource, '..'), file);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -601,10 +601,20 @@ const flattenPackagesConfig = (packages: (string | Record<string, string>)[]) =>
|
|||||||
const packagesConfig: ([string] | [string, string])[] = [];
|
const packagesConfig: ([string] | [string, string])[] = [];
|
||||||
packages.forEach((item) => {
|
packages.forEach((item) => {
|
||||||
if (typeof item === 'object') {
|
if (typeof item === 'object') {
|
||||||
Object.entries(item).forEach(([key, packagePath]) => {
|
for (const [key, packagePath] of Object.entries(item)) {
|
||||||
packagesConfig.push([packagePath, key]);
|
const index = packagesConfig.findIndex(([, k]) => {
|
||||||
|
return k === key;
|
||||||
});
|
});
|
||||||
|
if (index > -1) {
|
||||||
|
packagesConfig[index] = [packagePath, key];
|
||||||
|
} else {
|
||||||
|
packagesConfig.push([packagePath, key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (typeof item === 'string') {
|
} else if (typeof item === 'string') {
|
||||||
|
if (packagesConfig.find(([k]) => k === item)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
packagesConfig.push([item]);
|
packagesConfig.push([item]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/core",
|
"name": "@tmagic/core",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/tmagic-core.umd.cjs",
|
"main": "dist/tmagic-core.umd.cjs",
|
||||||
|
@ -167,8 +167,13 @@ class App extends EventEmitter {
|
|||||||
this.setPage(pageId);
|
this.setPage(pageId);
|
||||||
|
|
||||||
if (this.dataSourceManager) {
|
if (this.dataSourceManager) {
|
||||||
const dataSourceList = Array.from(this.dataSourceManager.dataSourceMap.values());
|
if (this.dataSourceManager.isAllDataSourceRegistered()) {
|
||||||
this.eventHelper?.bindDataSourceEvents(dataSourceList);
|
this.eventHelper?.bindDataSourceEvents();
|
||||||
|
} else {
|
||||||
|
this.dataSourceManager.once('registered-all', () => {
|
||||||
|
this.eventHelper?.bindDataSourceEvents();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,15 +264,15 @@ class App extends EventEmitter {
|
|||||||
* @param eventConfig 代码动作的配置
|
* @param eventConfig 代码动作的配置
|
||||||
* @returns void
|
* @returns void
|
||||||
*/
|
*/
|
||||||
public async runCode(codeId: Id, params: Record<string, any>, args: any[], flowState?: FlowState) {
|
public async runCode(codeId: Id, params: Record<string, any>, args: any[], flowState?: FlowState, node?: Node) {
|
||||||
if (!codeId || isEmpty(this.codeDsl)) return;
|
if (!codeId || isEmpty(this.codeDsl)) return;
|
||||||
const content = this.codeDsl?.[codeId]?.content;
|
const content = this.codeDsl?.[codeId]?.content;
|
||||||
if (typeof content === 'function') {
|
if (typeof content === 'function') {
|
||||||
try {
|
try {
|
||||||
await content({ app: this, params, eventParams: args, flowState });
|
await content({ app: this, params, eventParams: args, flowState, node });
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (this.errorHandler) {
|
if (this.errorHandler) {
|
||||||
this.errorHandler(e, undefined, { type: 'run-code', codeId, params, eventParams: args, flowState });
|
this.errorHandler(e, undefined, { type: 'run-code', codeId, params, eventParams: args, flowState, node });
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -281,6 +286,7 @@ class App extends EventEmitter {
|
|||||||
params: Record<string, any>,
|
params: Record<string, any>,
|
||||||
args: any[],
|
args: any[],
|
||||||
flowState?: FlowState,
|
flowState?: FlowState,
|
||||||
|
node?: Node,
|
||||||
) {
|
) {
|
||||||
if (!dsId || !methodName) return;
|
if (!dsId || !methodName) return;
|
||||||
|
|
||||||
@ -288,24 +294,23 @@ class App extends EventEmitter {
|
|||||||
|
|
||||||
if (!dataSource) return;
|
if (!dataSource) return;
|
||||||
|
|
||||||
|
try {
|
||||||
const methods = dataSource.methods || [];
|
const methods = dataSource.methods || [];
|
||||||
|
|
||||||
const method = methods.find((item) => item.name === methodName);
|
const method = methods.find((item) => item.name === methodName);
|
||||||
|
if (method && typeof method.content === 'function') {
|
||||||
if (!method) return;
|
await method.content({ app: this, params, dataSource, eventParams: args, flowState, node });
|
||||||
|
} else if (typeof dataSource[methodName] === 'function') {
|
||||||
if (typeof method.content === 'function') {
|
await dataSource[methodName]();
|
||||||
try {
|
}
|
||||||
await method.content({ app: this, params, dataSource, eventParams: args, flowState });
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (this.errorHandler) {
|
if (this.errorHandler) {
|
||||||
this.errorHandler(e, dataSource, { type: 'data-source-method', params, eventParams: args, flowState });
|
this.errorHandler(e, dataSource, { type: 'data-source-method', params, eventParams: args, flowState, node });
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
this.removeAllListeners();
|
this.removeAllListeners();
|
||||||
|
@ -31,6 +31,7 @@ import {
|
|||||||
type DataSourceItemConfig,
|
type DataSourceItemConfig,
|
||||||
type EventActionItem,
|
type EventActionItem,
|
||||||
type EventConfig,
|
type EventConfig,
|
||||||
|
Id,
|
||||||
NODE_DISABLE_CODE_BLOCK_KEY,
|
NODE_DISABLE_CODE_BLOCK_KEY,
|
||||||
NODE_DISABLE_DATA_SOURCE_KEY,
|
NODE_DISABLE_DATA_SOURCE_KEY,
|
||||||
} from '@tmagic/schema';
|
} from '@tmagic/schema';
|
||||||
@ -41,8 +42,17 @@ import FlowState from './FlowState';
|
|||||||
import type { default as TMagicNode } from './Node';
|
import type { default as TMagicNode } from './Node';
|
||||||
import { AfterEventHandler, BeforeEventHandler } from './type';
|
import { AfterEventHandler, BeforeEventHandler } from './type';
|
||||||
|
|
||||||
|
interface EventCache {
|
||||||
|
toId: Id;
|
||||||
|
method: string;
|
||||||
|
fromCpt: any;
|
||||||
|
args: any[];
|
||||||
|
handled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export default class EventHelper extends EventEmitter {
|
export default class EventHelper extends EventEmitter {
|
||||||
public app: TMagicApp;
|
public app: TMagicApp;
|
||||||
|
public eventQueue: EventCache[] = [];
|
||||||
|
|
||||||
private nodeEventList = new Map<(fromCpt: TMagicNode, ...args: any[]) => void, symbol>();
|
private nodeEventList = new Map<(fromCpt: TMagicNode, ...args: any[]) => void, symbol>();
|
||||||
private dataSourceEventList = new Map<string, Map<string, (...args: any[]) => void>>();
|
private dataSourceEventList = new Map<string, Map<string, (...args: any[]) => void>>();
|
||||||
@ -103,21 +113,23 @@ export default class EventHelper extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public removeNodeEvents() {
|
public removeNodeEvents() {
|
||||||
Array.from(this.nodeEventList.keys()).forEach((handler) => {
|
for (const handler of Array.from(this.nodeEventList.keys())) {
|
||||||
const name = this.nodeEventList.get(handler);
|
const name = this.nodeEventList.get(handler);
|
||||||
name && this.off(name, handler);
|
name && this.off(name, handler);
|
||||||
});
|
}
|
||||||
|
|
||||||
this.nodeEventList.clear();
|
this.nodeEventList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bindDataSourceEvents(dataSourceList: DataSource[]) {
|
public bindDataSourceEvents() {
|
||||||
|
const dataSourceList = Array.from(this.app.dataSourceManager?.dataSourceMap.values() || []);
|
||||||
|
|
||||||
this.removeDataSourceEvents(dataSourceList);
|
this.removeDataSourceEvents(dataSourceList);
|
||||||
|
|
||||||
dataSourceList.forEach((dataSource) => {
|
for (const dataSource of dataSourceList) {
|
||||||
const dataSourceEvent = this.dataSourceEventList.get(dataSource.id) ?? new Map<string, (args: any) => void>();
|
const dataSourceEvent = this.dataSourceEventList.get(dataSource.id) ?? new Map<string, (args: any) => void>();
|
||||||
|
|
||||||
(dataSource.schema.events || []).forEach((event) => {
|
for (const event of dataSource.schema.events || []) {
|
||||||
const [prefix, ...path] = event.name?.split('.') || [];
|
const [prefix, ...path] = event.name?.split('.') || [];
|
||||||
if (!prefix) return;
|
if (!prefix) return;
|
||||||
const handler = (...args: any[]) => {
|
const handler = (...args: any[]) => {
|
||||||
@ -131,9 +143,9 @@ export default class EventHelper extends EventEmitter {
|
|||||||
// 数据源自定义事件
|
// 数据源自定义事件
|
||||||
dataSource.on(prefix, handler);
|
dataSource.on(prefix, handler);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
this.dataSourceEventList.set(dataSource.id, dataSourceEvent);
|
this.dataSourceEventList.set(dataSource.id, dataSourceEvent);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeDataSourceEvents(dataSourceList: DataSource[]) {
|
public removeDataSourceEvents(dataSourceList: DataSource[]) {
|
||||||
@ -142,24 +154,32 @@ export default class EventHelper extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 先清掉之前注册的事件,重新注册
|
// 先清掉之前注册的事件,重新注册
|
||||||
dataSourceList.forEach((dataSource) => {
|
for (const dataSource of dataSourceList) {
|
||||||
const dataSourceEvent = this.dataSourceEventList.get(dataSource.id)!;
|
const dataSourceEvent = this.dataSourceEventList.get(dataSource.id)!;
|
||||||
|
|
||||||
if (!dataSourceEvent) return;
|
if (!dataSourceEvent) return;
|
||||||
|
|
||||||
Array.from(dataSourceEvent.keys()).forEach((eventName) => {
|
for (const eventName of Array.from(dataSourceEvent.keys())) {
|
||||||
const [prefix, ...path] = eventName.split('.');
|
const [prefix, ...path] = eventName.split('.');
|
||||||
if (prefix === DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX) {
|
if (prefix === DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX) {
|
||||||
dataSource.offDataChange(path.join('.'), dataSourceEvent.get(eventName)!);
|
dataSource.offDataChange(path.join('.'), dataSourceEvent.get(eventName)!);
|
||||||
} else {
|
} else {
|
||||||
dataSource.off(prefix, dataSourceEvent.get(eventName)!);
|
dataSource.off(prefix, dataSourceEvent.get(eventName)!);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
this.dataSourceEventList.clear();
|
this.dataSourceEventList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getEventQueue() {
|
||||||
|
return this.eventQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addEventToQueue(event: EventCache) {
|
||||||
|
this.eventQueue.push(event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 事件联动处理函数
|
* 事件联动处理函数
|
||||||
* @param eventsConfigIndex 事件配置索引,可以通过此索引从node.event中获取最新事件配置
|
* @param eventsConfigIndex 事件配置索引,可以通过此索引从node.event中获取最新事件配置
|
||||||
@ -182,9 +202,9 @@ export default class EventHelper extends EventEmitter {
|
|||||||
if (typeof config === 'number') {
|
if (typeof config === 'number') {
|
||||||
// 事件响应中可能会有修改数据源数据的,会更新dsl,所以这里需要重新获取
|
// 事件响应中可能会有修改数据源数据的,会更新dsl,所以这里需要重新获取
|
||||||
const actionItem = ((fromCpt as TMagicNode).events[config] as EventConfig).actions[i];
|
const actionItem = ((fromCpt as TMagicNode).events[config] as EventConfig).actions[i];
|
||||||
this.actionHandler(actionItem, fromCpt as TMagicNode, args, flowState);
|
await this.actionHandler(actionItem, fromCpt as TMagicNode, args, flowState);
|
||||||
} else {
|
} else {
|
||||||
this.actionHandler(actions[i], fromCpt as DataSource, args, flowState);
|
await this.actionHandler(actions[i], fromCpt as DataSource, args, flowState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flowState.reset();
|
flowState.reset();
|
||||||
@ -271,6 +291,16 @@ export default class EventHelper extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (toNodes.length === 0) {
|
||||||
|
this.addEventToQueue({
|
||||||
|
toId: to,
|
||||||
|
method: methodName,
|
||||||
|
fromCpt,
|
||||||
|
args,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const instanceMethodPropmise = [];
|
const instanceMethodPropmise = [];
|
||||||
for (const node of toNodes) {
|
for (const node of toNodes) {
|
||||||
if (node.instance) {
|
if (node.instance) {
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
|
||||||
import { DataSource } from '@tmagic/data-source';
|
|
||||||
import type { EventConfig, MNode } from '@tmagic/schema';
|
import type { EventConfig, MNode } from '@tmagic/schema';
|
||||||
import { HookCodeType, HookType, NODE_DISABLE_CODE_BLOCK_KEY } from '@tmagic/schema';
|
import { HookCodeType, HookType, NODE_DISABLE_CODE_BLOCK_KEY } from '@tmagic/schema';
|
||||||
|
|
||||||
@ -49,7 +48,7 @@ class Node extends EventEmitter {
|
|||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
public events: EventConfig[] = [];
|
public events: EventConfig[] = [];
|
||||||
public instance?: any = {};
|
public instance?: any = null;
|
||||||
public page?: Page;
|
public page?: Page;
|
||||||
public parent?: Node;
|
public parent?: Node;
|
||||||
public app: TMagicApp;
|
public app: TMagicApp;
|
||||||
@ -78,7 +77,8 @@ class Node extends EventEmitter {
|
|||||||
if (
|
if (
|
||||||
this.instance &&
|
this.instance &&
|
||||||
!Object.isFrozen(this.instance) &&
|
!Object.isFrozen(this.instance) &&
|
||||||
Object.getOwnPropertyDescriptor(this.instance, 'config')?.writable !== false
|
Object.getOwnPropertyDescriptor(this.instance, 'config')?.writable !== false &&
|
||||||
|
!this.instance.__isVue
|
||||||
) {
|
) {
|
||||||
this.instance.config = data;
|
this.instance.config = data;
|
||||||
}
|
}
|
||||||
@ -140,23 +140,10 @@ class Node extends EventEmitter {
|
|||||||
for (const item of hookData.hookData) {
|
for (const item of hookData.hookData) {
|
||||||
const { codeType = HookCodeType.CODE, codeId, params: itemParams = {} } = item;
|
const { codeType = HookCodeType.CODE, codeId, params: itemParams = {} } = item;
|
||||||
|
|
||||||
let functionContent: ((...args: any[]) => any) | string | undefined;
|
if (codeType === HookCodeType.CODE && typeof codeId === 'string') {
|
||||||
const functionParams: { app: TMagicApp; node: Node; params: Record<string, any>; dataSource?: DataSource } = {
|
await this.app.runCode(codeId, params || itemParams, [], undefined, this);
|
||||||
app: this.app,
|
|
||||||
node: this,
|
|
||||||
params: params || itemParams,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (codeType === HookCodeType.CODE && typeof codeId === 'string' && this.app.codeDsl?.[codeId]) {
|
|
||||||
functionContent = this.app.codeDsl[codeId].content;
|
|
||||||
} else if (codeType === HookCodeType.DATA_SOURCE_METHOD && Array.isArray(codeId) && codeId.length > 1) {
|
} else if (codeType === HookCodeType.DATA_SOURCE_METHOD && Array.isArray(codeId) && codeId.length > 1) {
|
||||||
const dataSource = this.app.dataSourceManager?.get(codeId[0]);
|
await this.app.runDataSourceMethod(codeId[0], codeId[1], params || itemParams, [], undefined, this);
|
||||||
functionContent = dataSource?.methods.find((method) => method.name === codeId[1])?.content;
|
|
||||||
functionParams.dataSource = dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (functionContent && typeof functionContent === 'function') {
|
|
||||||
await functionContent(functionParams);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,6 +188,25 @@ class Node extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.app.eventHelper) {
|
||||||
|
for (const eventConfig of this.app.eventHelper.getEventQueue()) {
|
||||||
|
for (const [, page] of this.app.pageFragments) {
|
||||||
|
const node = page.getNode(eventConfig.toId);
|
||||||
|
if (node && node === this) {
|
||||||
|
if (typeof instance[eventConfig.method] === 'function') {
|
||||||
|
await instance[eventConfig.method](eventConfig.fromCpt, ...eventConfig.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
eventConfig.handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.app.eventHelper.eventQueue = this.app.eventHelper
|
||||||
|
.getEventQueue()
|
||||||
|
.filter((eventConfig) => !eventConfig.handled);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.data[NODE_DISABLE_CODE_BLOCK_KEY] !== true) {
|
if (this.data[NODE_DISABLE_CODE_BLOCK_KEY] !== true) {
|
||||||
this.runHookCode('mounted');
|
this.runHookCode('mounted');
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/data-source",
|
"name": "@tmagic/data-source",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/tmagic-data-source.umd.cjs",
|
"main": "dist/tmagic-data-source.umd.cjs",
|
||||||
|
@ -22,7 +22,13 @@ import EventEmitter from 'events';
|
|||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
import type { DataSourceSchema, default as TMagicApp, DisplayCond, Id, MNode } from '@tmagic/core';
|
import type { DataSourceSchema, default as TMagicApp, DisplayCond, Id, MNode } from '@tmagic/core';
|
||||||
import { compiledNode, getDefaultValueFromFields, NODE_CONDS_KEY, NODE_DISABLE_DATA_SOURCE_KEY } from '@tmagic/core';
|
import {
|
||||||
|
compiledNode,
|
||||||
|
getDefaultValueFromFields,
|
||||||
|
NODE_CONDS_KEY,
|
||||||
|
NODE_CONDS_RESULT_KEY,
|
||||||
|
NODE_DISABLE_DATA_SOURCE_KEY,
|
||||||
|
} from '@tmagic/core';
|
||||||
|
|
||||||
import { SimpleObservedData } from './observed-data/SimpleObservedData';
|
import { SimpleObservedData } from './observed-data/SimpleObservedData';
|
||||||
import { DataSource, HttpDataSource } from './data-sources';
|
import { DataSource, HttpDataSource } from './data-sources';
|
||||||
@ -238,8 +244,9 @@ class DataSourceManager extends EventEmitter {
|
|||||||
Array.isArray(items) && deep ? items.map((item) => this.compiledNode(item, sourceId, deep)) : items;
|
Array.isArray(items) && deep ? items.map((item) => this.compiledNode(item, sourceId, deep)) : items;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.condResult === false) return newNode;
|
if (node.condResult === false || (typeof node.condResult === 'undefined' && node[NODE_CONDS_RESULT_KEY])) {
|
||||||
if (node.visible === false) return newNode;
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
// 编译函数这里作为参数,方便后续支持自定义编译
|
// 编译函数这里作为参数,方便后续支持自定义编译
|
||||||
return compiledNode(
|
return compiledNode(
|
||||||
@ -255,11 +262,24 @@ class DataSourceManager extends EventEmitter {
|
|||||||
* @param {{ [NODE_CONDS_KEY]?: DisplayCond[] }} node 显示条件组配置
|
* @param {{ [NODE_CONDS_KEY]?: DisplayCond[] }} node 显示条件组配置
|
||||||
* @returns {boolean} 是否显示
|
* @returns {boolean} 是否显示
|
||||||
*/
|
*/
|
||||||
public compliedConds(node: { [NODE_CONDS_KEY]?: DisplayCond[]; [NODE_DISABLE_DATA_SOURCE_KEY]?: boolean }) {
|
public compliedConds(
|
||||||
|
node: {
|
||||||
|
[NODE_CONDS_KEY]?: DisplayCond[];
|
||||||
|
[NODE_CONDS_RESULT_KEY]?: boolean;
|
||||||
|
[NODE_DISABLE_DATA_SOURCE_KEY]?: boolean;
|
||||||
|
},
|
||||||
|
data = this.data,
|
||||||
|
) {
|
||||||
if (node[NODE_DISABLE_DATA_SOURCE_KEY]) {
|
if (node[NODE_DISABLE_DATA_SOURCE_KEY]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return compliedConditions(node, this.data);
|
|
||||||
|
const result = compliedConditions(node, data);
|
||||||
|
|
||||||
|
if (!node[NODE_CONDS_RESULT_KEY]) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return !result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -271,7 +291,11 @@ class DataSourceManager extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
public compliedIteratorItemConds(
|
public compliedIteratorItemConds(
|
||||||
itemData: any,
|
itemData: any,
|
||||||
node: { [NODE_CONDS_KEY]?: DisplayCond[] },
|
node: {
|
||||||
|
[NODE_CONDS_KEY]?: DisplayCond[];
|
||||||
|
[NODE_CONDS_RESULT_KEY]?: boolean;
|
||||||
|
[NODE_DISABLE_DATA_SOURCE_KEY]?: boolean;
|
||||||
|
},
|
||||||
dataSourceField: string[] = [],
|
dataSourceField: string[] = [],
|
||||||
) {
|
) {
|
||||||
const [dsId, ...keys] = dataSourceField;
|
const [dsId, ...keys] = dataSourceField;
|
||||||
@ -279,7 +303,7 @@ class DataSourceManager extends EventEmitter {
|
|||||||
if (!ds) return true;
|
if (!ds) return true;
|
||||||
|
|
||||||
const ctxData = createIteratorContentData(itemData, ds.id, keys, this.data);
|
const ctxData = createIteratorContentData(itemData, ds.id, keys, this.data);
|
||||||
return compliedConditions(node, ctxData);
|
return this.compliedConds(node, ctxData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public compliedIteratorItems(itemData: any, nodes: MNode[], dataSourceField: string[] = []): MNode[] {
|
public compliedIteratorItems(itemData: any, nodes: MNode[], dataSourceField: string[] = []): MNode[] {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
import { union } from 'lodash-es';
|
import { union } from 'lodash-es';
|
||||||
|
|
||||||
import type { default as TMagicApp } from '@tmagic/core';
|
import type { default as TMagicApp } from '@tmagic/core';
|
||||||
import { getDepNodeIds, getNodes, isPage, isPageFragment } from '@tmagic/core';
|
import { getDepNodeIds, getNodes, isPage, isPageFragment, replaceChildNode } from '@tmagic/core';
|
||||||
|
|
||||||
import DataSourceManager from './DataSourceManager';
|
import DataSourceManager from './DataSourceManager';
|
||||||
import type { ChangeEvent, DataSourceManagerData } from './types';
|
import type { ChangeEvent, DataSourceManagerData } from './types';
|
||||||
@ -74,14 +74,21 @@ export const createDataSourceManager = (app: TMagicApp, useMock?: boolean, initi
|
|||||||
if (typeof app.page?.setData === 'function') {
|
if (typeof app.page?.setData === 'function') {
|
||||||
if (isPage(newNode)) {
|
if (isPage(newNode)) {
|
||||||
app.page.setData(newNode);
|
app.page.setData(newNode);
|
||||||
} else if (isPageFragment(newNode)) {
|
} else if (page.id === app.page.data.id && !app.page.instance) {
|
||||||
for (const [, page] of app.pageFragments) {
|
replaceChildNode(newNode, [app.page.data]);
|
||||||
if (page.data.id === node.id) {
|
|
||||||
page.setData(newNode);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
|
||||||
app.getNode(node.id)?.setData(newNode);
|
app.getNode(node.id)?.setData(newNode);
|
||||||
|
|
||||||
|
for (const [, pageFragment] of app.pageFragments) {
|
||||||
|
if (pageFragment.data.id === newNode.id) {
|
||||||
|
pageFragment.setData(newNode);
|
||||||
|
} else if (pageFragment.data.id === page.id) {
|
||||||
|
pageFragment.getNode(newNode.id)?.setData(newNode);
|
||||||
|
if (!pageFragment.instance) {
|
||||||
|
replaceChildNode(newNode, [pageFragment.data]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@ export class DeepObservedData extends ObservedData {
|
|||||||
update = (data: any, path?: string) => {
|
update = (data: any, path?: string) => {
|
||||||
this.state?.update(path ?? '', data);
|
this.state?.update(path ?? '', data);
|
||||||
};
|
};
|
||||||
on = (path: string, callback: (newVal: any) => void) => {
|
on = (path: string, callback: (newVal: any) => void, options?: { immediate?: boolean }) => {
|
||||||
// subscribe 会立即执行一次,ignoreFirstCall 会忽略第一次执行
|
// subscribe 会立即执行一次,ignoreFirstCall 会忽略第一次执行
|
||||||
const unsubscribe = this.state!.subscribe(path, ignoreFirstCall(callback));
|
const unsubscribe = this.state!.subscribe(path, options?.immediate ? callback : ignoreFirstCall(callback));
|
||||||
|
|
||||||
// 把取消监听的函数保存下来,供 off 时调用
|
// 把取消监听的函数保存下来,供 off 时调用
|
||||||
const pathSubscribers = this.subscribers.get(path) ?? new Map<Function, () => void>();
|
const pathSubscribers = this.subscribers.get(path) ?? new Map<Function, () => void>();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export abstract class ObservedData {
|
export abstract class ObservedData {
|
||||||
abstract update(data: any, path?: string): void;
|
abstract update(data: any, path?: string): void;
|
||||||
|
|
||||||
abstract on(path: string, callback: (newVal: any) => void): void;
|
abstract on(path: string, callback: (newVal: any) => void, options?: { immediate?: boolean }): void;
|
||||||
|
|
||||||
abstract off(path: string, callback: (newVal: any) => void): void;
|
abstract off(path: string, callback: (newVal: any) => void): void;
|
||||||
|
|
||||||
|
@ -32,7 +32,10 @@ export class SimpleObservedData extends ObservedData {
|
|||||||
this.event.emit('', changeEvent);
|
this.event.emit('', changeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
on(path: string, callback: (newVal: any) => void): void {
|
on(path: string, callback: (newVal: any) => void, options?: { immediate?: boolean }): void {
|
||||||
|
if (options?.immediate) {
|
||||||
|
callback(this.getData(path));
|
||||||
|
}
|
||||||
this.event.on(path, callback);
|
this.event.on(path, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/dep",
|
"name": "@tmagic/dep",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/tmagic-dep.umd.cjs",
|
"main": "dist/tmagic-dep.umd.cjs",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/design",
|
"name": "@tmagic/design",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"sideEffects": [
|
"sideEffects": [
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/editor",
|
"name": "@tmagic/editor",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"sideEffects": [
|
"sideEffects": [
|
||||||
|
@ -129,7 +129,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
|
||||||
import { provide, watch } from 'vue';
|
import { provide } from 'vue';
|
||||||
|
|
||||||
import type { MApp } from '@tmagic/core';
|
import type { MApp } from '@tmagic/core';
|
||||||
|
|
||||||
@ -211,22 +211,6 @@ const stageOptions: StageOptions = {
|
|||||||
|
|
||||||
stageOverlayService.set('stageOptions', stageOptions);
|
stageOverlayService.set('stageOptions', stageOptions);
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.runtimeUrl,
|
|
||||||
(url) => {
|
|
||||||
if (!url) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stage = editorService.get('stage');
|
|
||||||
if (!stage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
stage.reloadIframe(url);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
provide('services', services);
|
provide('services', services);
|
||||||
|
|
||||||
provide('codeOptions', props.codeOptions);
|
provide('codeOptions', props.codeOptions);
|
||||||
|
@ -126,7 +126,7 @@ export const defaultEditorProps = {
|
|||||||
eventMethodList: () => ({}),
|
eventMethodList: () => ({}),
|
||||||
datasourceValues: () => ({}),
|
datasourceValues: () => ({}),
|
||||||
datasourceConfigs: () => ({}),
|
datasourceConfigs: () => ({}),
|
||||||
canSelect: (el: HTMLElement) => Boolean(getIdFromEl()(el)),
|
canSelect: (el: HTMLElement) => Boolean(getIdFromEl()(el) && !el.dataset.tmagicPageFragmentContainerId),
|
||||||
isContainer: (el: HTMLElement) => el.classList.contains('magic-ui-container'),
|
isContainer: (el: HTMLElement) => el.classList.contains('magic-ui-container'),
|
||||||
codeOptions: () => ({}),
|
codeOptions: () => ({}),
|
||||||
customContentMenu: (menus: (MenuButton | MenuComponent)[]) => menus,
|
customContentMenu: (menus: (MenuButton | MenuComponent)[]) => menus,
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
content="选择数据源"
|
content="选择数据源"
|
||||||
>
|
>
|
||||||
<TMagicButton
|
<TMagicButton
|
||||||
style="margin-left: 5px"
|
|
||||||
:type="showDataSourceFieldSelect ? 'primary' : 'default'"
|
:type="showDataSourceFieldSelect ? 'primary' : 'default'"
|
||||||
:size="size"
|
:size="size"
|
||||||
@click="showDataSourceFieldSelect = !showDataSourceFieldSelect"
|
@click="showDataSourceFieldSelect = !showDataSourceFieldSelect"
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="m-fields-style-setter">
|
<TMagicCollapse class="m-fields-style-setter" :model-value="collapseValue">
|
||||||
<TMagicCollapse :model-value="collapseValue">
|
|
||||||
<template v-for="(item, index) in list" :key="index">
|
<template v-for="(item, index) in list" :key="index">
|
||||||
<TMagicCollapseItem :name="`${index}`">
|
<TMagicCollapseItem :name="`${index}`">
|
||||||
<template #title><MIcon :icon="Grid"></MIcon>{{ item.title }}</template>
|
<template #title><MIcon :icon="Grid"></MIcon>{{ item.title }}</template>
|
||||||
<component v-if="item.component" :is="item.component" :values="model[name]" @change="change"></component>
|
<component
|
||||||
|
v-if="item.component"
|
||||||
|
:is="item.component"
|
||||||
|
:values="model[name]"
|
||||||
|
:size="size"
|
||||||
|
:disabled="disabled"
|
||||||
|
@change="change"
|
||||||
|
></component>
|
||||||
</TMagicCollapseItem>
|
</TMagicCollapseItem>
|
||||||
</template>
|
</template>
|
||||||
</TMagicCollapse>
|
</TMagicCollapse>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@ -6,13 +6,21 @@
|
|||||||
:key="index"
|
:key="index"
|
||||||
link
|
link
|
||||||
:class="model[name] === item.value && 'btn-active'"
|
:class="model[name] === item.value && 'btn-active'"
|
||||||
|
:disabled="disabled"
|
||||||
@click="changeHandler(item.value)"
|
@click="changeHandler(item.value)"
|
||||||
>
|
>
|
||||||
<div :class="['position-icon', item.class, model[name] === item.value && 'active']"></div>
|
<div :class="['position-icon', item.class, model[name] === item.value && 'active']"></div>
|
||||||
</TMagicButton>
|
</TMagicButton>
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-value">
|
<div class="custom-value">
|
||||||
<TMagicInput v-model="model[name]" size="small" placeholder="自定义背景位置" clearable @change="changeHandler">
|
<TMagicInput
|
||||||
|
v-model="model[name]"
|
||||||
|
placeholder="自定义背景位置"
|
||||||
|
clearable
|
||||||
|
:size="size"
|
||||||
|
:disabled="disabled"
|
||||||
|
@change="changeHandler"
|
||||||
|
>
|
||||||
</TMagicInput>
|
</TMagicInput>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-value-container">
|
<div class="border-value-container">
|
||||||
<MContainer :config="config" :model="model" @change="change"></MContainer>
|
<MContainer :config="config" :model="model" :size="size" :disabled="disabled" @change="change"></MContainer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -67,7 +67,6 @@ const config = computed(() => ({
|
|||||||
{
|
{
|
||||||
name: `border${direction.value}Style`,
|
name: `border${direction.value}Style`,
|
||||||
text: '边框样式',
|
text: '边框样式',
|
||||||
|
|
||||||
labelWidth: '68px',
|
labelWidth: '68px',
|
||||||
type: 'data-source-field-select',
|
type: 'data-source-field-select',
|
||||||
fieldConfig: {
|
fieldConfig: {
|
||||||
@ -90,6 +89,8 @@ const emit = defineEmits<{
|
|||||||
withDefaults(
|
withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
model: FormValue;
|
model: FormValue;
|
||||||
|
disabled?: boolean;
|
||||||
|
size?: 'large' | 'default' | 'small';
|
||||||
}>(),
|
}>(),
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
@ -5,9 +5,10 @@
|
|||||||
<span class="next-input">
|
<span class="next-input">
|
||||||
<input
|
<input
|
||||||
v-model="model[item.name]"
|
v-model="model[item.name]"
|
||||||
:title="model[item.name]"
|
|
||||||
@change="change($event, item.name)"
|
|
||||||
placeholder="0"
|
placeholder="0"
|
||||||
|
:title="model[item.name]"
|
||||||
|
:disabled="disabled"
|
||||||
|
@change="change($event, item.name)"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -60,6 +61,8 @@ const emit = defineEmits<{
|
|||||||
|
|
||||||
withDefaults(
|
withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
disabled?: boolean;
|
||||||
|
size?: 'large' | 'default' | 'small';
|
||||||
model: FormValue;
|
model: FormValue;
|
||||||
}>(),
|
}>(),
|
||||||
{},
|
{},
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
<span class="next-input">
|
<span class="next-input">
|
||||||
<input
|
<input
|
||||||
v-model="model[item.name]"
|
v-model="model[item.name]"
|
||||||
:title="model[item.name]"
|
|
||||||
@change="change($event, item.name)"
|
|
||||||
placeholder="0"
|
placeholder="0"
|
||||||
|
:title="model[item.name]"
|
||||||
|
:disabled="disabled"
|
||||||
|
@change="change($event, item.name)"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -42,6 +43,8 @@ const emit = defineEmits<{
|
|||||||
withDefaults(
|
withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
model: FormValue;
|
model: FormValue;
|
||||||
|
disabled?: boolean;
|
||||||
|
size?: 'large' | 'default' | 'small';
|
||||||
}>(),
|
}>(),
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<MContainer :config="config" :model="values" @change="change"></MContainer>
|
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -11,7 +11,11 @@ import type { StyleSchema } from '@tmagic/schema';
|
|||||||
import BackgroundPosition from '../components/BackgroundPosition.vue';
|
import BackgroundPosition from '../components/BackgroundPosition.vue';
|
||||||
import { BackgroundNoRepeat, BackgroundRepeat, BackgroundRepeatX, BackgroundRepeatY } from '../icons/background-repeat';
|
import { BackgroundNoRepeat, BackgroundRepeat, BackgroundRepeatX, BackgroundRepeatY } from '../icons/background-repeat';
|
||||||
|
|
||||||
defineProps<{ values: Partial<StyleSchema> }>();
|
defineProps<{
|
||||||
|
values: Partial<StyleSchema>;
|
||||||
|
disabled?: boolean;
|
||||||
|
size?: 'large' | 'default' | 'small';
|
||||||
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
change: [v: StyleSchema, eventData: ContainerChangeEventData];
|
change: [v: StyleSchema, eventData: ContainerChangeEventData];
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<MContainer :config="config" :model="values" @change="change"></MContainer>
|
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
|
||||||
<Border :model="values" @change="change"></Border>
|
<Border :model="values" :size="size" :disabled="disabled" @change="change"></Border>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -9,7 +9,11 @@ import type { StyleSchema } from '@tmagic/schema';
|
|||||||
|
|
||||||
import Border from '../components/Border.vue';
|
import Border from '../components/Border.vue';
|
||||||
|
|
||||||
defineProps<{ values: Partial<StyleSchema> }>();
|
defineProps<{
|
||||||
|
values: Partial<StyleSchema>;
|
||||||
|
disabled?: boolean;
|
||||||
|
size?: 'large' | 'default' | 'small';
|
||||||
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
change: [v: StyleSchema, eventData: ContainerChangeEventData];
|
change: [v: StyleSchema, eventData: ContainerChangeEventData];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<MContainer :config="config" :model="values" @change="change"></MContainer>
|
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -10,7 +10,11 @@ import type { StyleSchema } from '@tmagic/schema';
|
|||||||
|
|
||||||
import { AlignCenter, AlignLeft, AlignRight } from '../icons/text-align';
|
import { AlignCenter, AlignLeft, AlignRight } from '../icons/text-align';
|
||||||
|
|
||||||
defineProps<{ values: Partial<StyleSchema> }>();
|
defineProps<{
|
||||||
|
values: Partial<StyleSchema>;
|
||||||
|
disabled?: boolean;
|
||||||
|
size?: 'large' | 'default' | 'small';
|
||||||
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
change: [v: StyleSchema, eventData: ContainerChangeEventData];
|
change: [v: StyleSchema, eventData: ContainerChangeEventData];
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<MContainer :config="config" :model="values" @change="change"></MContainer>
|
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
|
||||||
<Box v-show="!['fixed', 'absolute'].includes(values.position)" :model="values" @change="change"></Box>
|
<Box
|
||||||
|
v-show="!['fixed', 'absolute'].includes(values.position)"
|
||||||
|
:model="values"
|
||||||
|
:size="size"
|
||||||
|
:disabled="disabled"
|
||||||
|
@change="change"
|
||||||
|
></Box>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -28,6 +34,8 @@ import {
|
|||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
values: Partial<StyleSchema>;
|
values: Partial<StyleSchema>;
|
||||||
|
disabled?: boolean;
|
||||||
|
size?: 'large' | 'default' | 'small';
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<MContainer :config="config" :model="values" @change="change"></MContainer>
|
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ContainerChangeEventData, MContainer } from '@tmagic/form';
|
import { ContainerChangeEventData, MContainer } from '@tmagic/form';
|
||||||
import type { StyleSchema } from '@tmagic/schema';
|
import type { StyleSchema } from '@tmagic/schema';
|
||||||
|
|
||||||
const props = defineProps<{ values: Partial<StyleSchema> }>();
|
const props = defineProps<{
|
||||||
|
values: Partial<StyleSchema>;
|
||||||
|
disabled?: boolean;
|
||||||
|
size?: 'large' | 'default' | 'small';
|
||||||
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
|
change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
|
||||||
|
@ -347,6 +347,32 @@ export const initServiceEvents = (
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.runtimeUrl,
|
||||||
|
(url) => {
|
||||||
|
if (!url) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stage = editorService.get('stage');
|
||||||
|
if (!stage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stage.reloadIframe(url);
|
||||||
|
|
||||||
|
stage.renderer?.once('runtime-ready', (runtime) => {
|
||||||
|
runtime.updateRootConfig?.(cloneDeep(toRaw(editorService.get('root')))!);
|
||||||
|
const page = editorService.get('page');
|
||||||
|
const node = editorService.get('node');
|
||||||
|
page?.id && runtime?.updatePageId?.(page.id);
|
||||||
|
setTimeout(() => {
|
||||||
|
node && stage?.select(toRaw(node.id));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const getStage = (): Promise<StageCore> => {
|
const getStage = (): Promise<StageCore> => {
|
||||||
const stage = editorService.get('stage');
|
const stage = editorService.get('stage');
|
||||||
if (stage) {
|
if (stage) {
|
||||||
@ -434,7 +460,7 @@ export const initServiceEvents = (
|
|||||||
delete value.dataSourceCondDeps;
|
delete value.dataSourceCondDeps;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = async () => {
|
(async () => {
|
||||||
const nodeId = editorService.get('node')?.id || props.defaultSelected;
|
const nodeId = editorService.get('node')?.id || props.defaultSelected;
|
||||||
let node;
|
let node;
|
||||||
if (nodeId) {
|
if (nodeId) {
|
||||||
@ -453,9 +479,7 @@ export const initServiceEvents = (
|
|||||||
if (toRaw(value) !== toRaw(preValue)) {
|
if (toRaw(value) !== toRaw(preValue)) {
|
||||||
emit('update:modelValue', value);
|
emit('update:modelValue', value);
|
||||||
}
|
}
|
||||||
};
|
})();
|
||||||
|
|
||||||
handler();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 新增节点,收集依赖
|
// 新增节点,收集依赖
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { nextTick, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue';
|
import { nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, useTemplateRef, watch } from 'vue';
|
||||||
import { FullScreen } from '@element-plus/icons-vue';
|
import { FullScreen } from '@element-plus/icons-vue';
|
||||||
import { throttle } from 'lodash-es';
|
import { throttle } from 'lodash-es';
|
||||||
import serialize from 'serialize-javascript';
|
import serialize from 'serialize-javascript';
|
||||||
@ -62,7 +62,7 @@ const props = withDefaults(
|
|||||||
const emit = defineEmits(['initd', 'save']);
|
const emit = defineEmits(['initd', 'save']);
|
||||||
|
|
||||||
const toString = (v: string | any, language: string): string => {
|
const toString = (v: string | any, language: string): string => {
|
||||||
let value = '';
|
let value: string;
|
||||||
if (typeof v !== 'string') {
|
if (typeof v !== 'string') {
|
||||||
if (language === 'json') {
|
if (language === 'json') {
|
||||||
value = JSON.stringify(v, null, 2);
|
value = JSON.stringify(v, null, 2);
|
||||||
@ -113,19 +113,40 @@ const setEditorValue = (v: string | any, m: string | any) => {
|
|||||||
if (props.type === 'diff') {
|
if (props.type === 'diff') {
|
||||||
const originalModel = monaco.editor.createModel(values.value, 'text/javascript');
|
const originalModel = monaco.editor.createModel(values.value, 'text/javascript');
|
||||||
const modifiedModel = monaco.editor.createModel(toString(m, props.language), 'text/javascript');
|
const modifiedModel = monaco.editor.createModel(toString(m, props.language), 'text/javascript');
|
||||||
|
const position = vsDiffEditor?.getPosition();
|
||||||
return vsDiffEditor?.setModel({
|
const result = vsDiffEditor?.setModel({
|
||||||
original: originalModel,
|
original: originalModel,
|
||||||
modified: modifiedModel,
|
modified: modifiedModel,
|
||||||
});
|
});
|
||||||
|
if (position) {
|
||||||
|
vsDiffEditor?.setPosition(position);
|
||||||
|
vsDiffEditor?.focus();
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
return vsEditor?.setValue(values.value);
|
}
|
||||||
|
// 保存当前光标位置
|
||||||
|
const position = vsEditor?.getPosition();
|
||||||
|
const result = vsEditor?.setValue(values.value);
|
||||||
|
// 恢复光标位置
|
||||||
|
if (position) {
|
||||||
|
vsEditor?.setPosition(position);
|
||||||
|
vsEditor?.focus();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getEditorValue = () =>
|
const getEditorValue = () =>
|
||||||
(props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue()) || '';
|
(props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue()) || '';
|
||||||
|
|
||||||
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
|
if (e.keyCode === 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
const newValue = getEditorValue();
|
||||||
|
values.value = newValue;
|
||||||
|
emit('save', props.parse ? parseCode(newValue, props.language) : newValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
if (!codeEditorEl.value) return;
|
if (!codeEditorEl.value) return;
|
||||||
|
|
||||||
@ -149,16 +170,7 @@ const init = async () => {
|
|||||||
setEditorValue(props.initValues, props.modifiedValues);
|
setEditorValue(props.initValues, props.modifiedValues);
|
||||||
|
|
||||||
emit('initd', vsEditor);
|
emit('initd', vsEditor);
|
||||||
|
codeEditorEl.value.addEventListener('keydown', handleKeyDown);
|
||||||
codeEditorEl.value.addEventListener('keydown', (e) => {
|
|
||||||
if (e.keyCode === 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
const newValue = getEditorValue();
|
|
||||||
values.value = newValue;
|
|
||||||
emit('save', props.parse ? parseCode(newValue, props.language) : newValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (props.type !== 'diff' && props.autoSave) {
|
if (props.type !== 'diff' && props.autoSave) {
|
||||||
vsEditor?.onDidBlurEditorWidget(() => {
|
vsEditor?.onDidBlurEditorWidget(() => {
|
||||||
@ -214,7 +226,9 @@ onBeforeUnmount(() => {
|
|||||||
vsEditor = null;
|
vsEditor = null;
|
||||||
vsDiffEditor = null;
|
vsDiffEditor = null;
|
||||||
});
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
codeEditorEl.value?.removeEventListener('keydown', handleKeyDown);
|
||||||
|
});
|
||||||
const fullScreen = ref(false);
|
const fullScreen = ref(false);
|
||||||
const fullScreenHandler = () => {
|
const fullScreenHandler = () => {
|
||||||
fullScreen.value = !fullScreen.value;
|
fullScreen.value = !fullScreen.value;
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
:width="160"
|
:width="160"
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
>
|
>
|
||||||
<div>
|
<div class="page-bar-popover-wrapper">
|
||||||
|
<div class="page-bar-popover-inner">
|
||||||
<slot name="page-list-popover" :list="list">
|
<slot name="page-list-popover" :list="list">
|
||||||
<ToolButton
|
<ToolButton
|
||||||
v-for="(item, index) in list"
|
v-for="(item, index) in list"
|
||||||
@ -25,6 +26,7 @@
|
|||||||
></ToolButton>
|
></ToolButton>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<TMagicIcon class="m-editor-page-list-menu-icon">
|
<TMagicIcon class="m-editor-page-list-menu-icon">
|
||||||
<Files></Files>
|
<Files></Files>
|
||||||
|
@ -206,7 +206,9 @@ export default class extends EventEmitter {
|
|||||||
|
|
||||||
public usePlugin(options: Record<string, Function>) {
|
public usePlugin(options: Record<string, Function>) {
|
||||||
for (const [methodName, method] of Object.entries(options)) {
|
for (const [methodName, method] of Object.entries(options)) {
|
||||||
if (typeof method === 'function') this.pluginOptionsList[methodName].push(method);
|
if (typeof method === 'function' && !this.pluginOptionsList[methodName].includes(method)) {
|
||||||
|
this.pluginOptionsList[methodName].push(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,17 @@
|
|||||||
border-bottom: 1px solid $border-color;
|
border-bottom: 1px solid $border-color;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .el-collapse-item__header {
|
||||||
|
padding: 0 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-collapse-item__title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-collapse-item__header,
|
.el-collapse-item__header,
|
||||||
|
@ -13,4 +13,8 @@
|
|||||||
flex: 2;
|
flex: 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.tmagic-design-button {
|
||||||
|
margin-left: 5px;
|
||||||
|
padding: 5px 8px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,11 @@
|
|||||||
padding: 4px 0;
|
padding: 4px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-bar-popover-wrapper {
|
||||||
|
max-height: calc(100vh - $page-bar-height - 20px);
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-item {
|
.menu-item {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease 0s;
|
transition: all 0.2s ease 0s;
|
||||||
|
@ -72,11 +72,6 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
border-bottom: 2px solid $border-color;
|
border-bottom: 2px solid $border-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tmagic-design-form {
|
|
||||||
padding-right: 10px;
|
|
||||||
padding-left: 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.m-editor-props-panel-src-icon {
|
.m-editor-props-panel-src-icon {
|
||||||
|
@ -8,12 +8,25 @@
|
|||||||
.tmagic-design-collapse-item {
|
.tmagic-design-collapse-item {
|
||||||
> .el-collapse-item__header {
|
> .el-collapse-item__header {
|
||||||
background-color: #f2f3f7;
|
background-color: #f2f3f7;
|
||||||
height: 36px;
|
height: 26px;
|
||||||
padding: 10px;
|
min-height: 26px;
|
||||||
|
line-height: 26px;
|
||||||
|
padding: 0 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-collapse-item__wrap {
|
.el-collapse-item__wrap {
|
||||||
padding: 0 10px;
|
padding: 10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-collapse-item__title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-collapse-item__content {
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
|
||||||
/*
|
/*
|
||||||
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
||||||
*
|
*
|
||||||
@ -17,7 +16,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { NODE_CONDS_KEY, NODE_DISABLE_CODE_BLOCK_KEY, NODE_DISABLE_DATA_SOURCE_KEY } from '@tmagic/core';
|
import {
|
||||||
|
NODE_CONDS_KEY,
|
||||||
|
NODE_CONDS_RESULT_KEY,
|
||||||
|
NODE_DISABLE_CODE_BLOCK_KEY,
|
||||||
|
NODE_DISABLE_DATA_SOURCE_KEY,
|
||||||
|
} from '@tmagic/core';
|
||||||
import { tMagicMessage } from '@tmagic/design';
|
import { tMagicMessage } from '@tmagic/design';
|
||||||
import type { FormConfig, FormState, TabConfig, TabPaneConfig } from '@tmagic/form';
|
import type { FormConfig, FormState, TabConfig, TabPaneConfig } from '@tmagic/form';
|
||||||
|
|
||||||
@ -163,8 +167,20 @@ export const advancedTabConfig: TabPaneConfig = {
|
|||||||
|
|
||||||
export const displayTabConfig: TabPaneConfig = {
|
export const displayTabConfig: TabPaneConfig = {
|
||||||
title: '显示条件',
|
title: '显示条件',
|
||||||
display: (_vm: FormState, { model }: any) => model.type !== 'page',
|
display: (_state: FormState, { model }: any) => model.type !== 'page',
|
||||||
items: [
|
items: [
|
||||||
|
{
|
||||||
|
name: NODE_CONDS_RESULT_KEY,
|
||||||
|
type: 'select',
|
||||||
|
text: '条件成立时',
|
||||||
|
defaultValue: false,
|
||||||
|
options: [
|
||||||
|
{ text: '显示', value: false },
|
||||||
|
{ text: '隐藏', value: true },
|
||||||
|
],
|
||||||
|
extra: (_state, { model }) =>
|
||||||
|
`条件成立时${model[NODE_CONDS_RESULT_KEY] ? '隐藏' : '显示'},不成立时${model[NODE_CONDS_RESULT_KEY] ? '显示' : '隐藏'};<br />同一条件组内的所有条件配置同时成立时表示该条件组成立,任意一个条件组成立时表示条件成立(条件组内为且的关系,条件组间为或的关系);<br />条件为空时表示成立;`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'display-conds',
|
type: 'display-conds',
|
||||||
name: NODE_CONDS_KEY,
|
name: NODE_CONDS_KEY,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/element-plus-adapter",
|
"name": "@tmagic/element-plus-adapter",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/tmagic-element-plus-adapter.umd.cjs",
|
"main": "dist/tmagic-element-plus-adapter.umd.cjs",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/form-schema",
|
"name": "@tmagic/form-schema",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/tmagic-form-schema.umd.cjs",
|
"main": "dist/tmagic-form-schema.umd.cjs",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/form",
|
"name": "@tmagic/form",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"sideEffects": [
|
"sideEffects": [
|
||||||
|
@ -9,12 +9,12 @@
|
|||||||
>
|
>
|
||||||
<TMagicTooltip v-if="option.tooltip" placement="top-start" :content="option.tooltip">
|
<TMagicTooltip v-if="option.tooltip" placement="top-start" :content="option.tooltip">
|
||||||
<div>
|
<div>
|
||||||
<TMagicIcon v-if="option.icon" :size="'16'"><component :is="option.icon"></component></TMagicIcon>
|
<TMagicIcon v-if="option.icon" :size="iconSize"><component :is="option.icon"></component></TMagicIcon>
|
||||||
<span>{{ option.text }}</span>
|
<span>{{ option.text }}</span>
|
||||||
</div>
|
</div>
|
||||||
</TMagicTooltip>
|
</TMagicTooltip>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<TMagicIcon v-if="option.icon" :size="'16'"><component :is="option.icon"></component></TMagicIcon>
|
<TMagicIcon v-if="option.icon" :size="iconSize"><component :is="option.icon"></component></TMagicIcon>
|
||||||
<span>{{ option.text }}</span>
|
<span>{{ option.text }}</span>
|
||||||
</div>
|
</div>
|
||||||
</component>
|
</component>
|
||||||
@ -49,4 +49,14 @@ const clickHandler = (item: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useAddField(props.prop);
|
useAddField(props.prop);
|
||||||
|
|
||||||
|
const iconSize = computed(() => {
|
||||||
|
if (props.size === 'small') {
|
||||||
|
return '12';
|
||||||
|
}
|
||||||
|
if (props.size === 'large') {
|
||||||
|
return '16';
|
||||||
|
}
|
||||||
|
return '14';
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="width: 100%">
|
<div class="m-fields-text">
|
||||||
<TMagicInput
|
<TMagicInput
|
||||||
v-model="model[name]"
|
v-model="model[name]"
|
||||||
ref="input"
|
ref="input"
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
.m-fields-text {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.m-form-validate__warning {
|
.m-form-validate__warning {
|
||||||
color: var(--el-color-warning);
|
color: var(--el-color-warning);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/schema",
|
"name": "@tmagic/schema",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/tmagic-schema.umd.cjs",
|
"main": "dist/tmagic-schema.umd.cjs",
|
||||||
|
@ -47,6 +47,8 @@ export enum NodeType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const NODE_CONDS_KEY = 'displayConds';
|
export const NODE_CONDS_KEY = 'displayConds';
|
||||||
|
export const NODE_CONDS_RESULT_KEY = 'displayCondsResultReverse';
|
||||||
|
|
||||||
export const NODE_DISABLE_DATA_SOURCE_KEY = '_tmagic_node_disabled_data_source';
|
export const NODE_DISABLE_DATA_SOURCE_KEY = '_tmagic_node_disabled_data_source';
|
||||||
export const NODE_DISABLE_CODE_BLOCK_KEY = '_tmagic_node_disabled_code_block';
|
export const NODE_DISABLE_CODE_BLOCK_KEY = '_tmagic_node_disabled_code_block';
|
||||||
|
|
||||||
@ -130,6 +132,7 @@ export interface MComponent {
|
|||||||
/** 组件根Dom的style */
|
/** 组件根Dom的style */
|
||||||
style?: StyleSchema;
|
style?: StyleSchema;
|
||||||
[NODE_CONDS_KEY]?: DisplayCond[];
|
[NODE_CONDS_KEY]?: DisplayCond[];
|
||||||
|
[NODE_CONDS_RESULT_KEY]?: boolean;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/stage",
|
"name": "@tmagic/stage",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/tmagic-stage.umd.cjs",
|
"main": "dist/tmagic-stage.umd.cjs",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/table",
|
"name": "@tmagic/table",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"sideEffects": [
|
"sideEffects": [
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/tdesign-vue-next-adapter",
|
"name": "@tmagic/tdesign-vue-next-adapter",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/tmagic-tdesign-vue-next-adapter.umd.cjs",
|
"main": "dist/tmagic-tdesign-vue-next-adapter.umd.cjs",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"name": "@tmagic/utils",
|
"name": "@tmagic/utils",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/tmagic-utils.umd.cjs",
|
"main": "dist/tmagic-utils.umd.cjs",
|
||||||
|
@ -380,8 +380,15 @@ export const replaceChildNode = (newNode: MNode, data?: MNode[], parentId?: Id):
|
|||||||
parent = getNodePath(parentId, data).pop();
|
parent = getNodePath(parentId, data).pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node) throw new Error('未找到目标节点');
|
if (!node) {
|
||||||
if (!parent) throw new Error('未找到父节点');
|
console.warn(`未找到目标节点(${newNode.id})`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parent) {
|
||||||
|
console.warn(`未找到父节点(${newNode.id})`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const index = parent.items?.findIndex((child: MNode) => child.id === node.id);
|
const index = parent.items?.findIndex((child: MNode) => child.id === node.id);
|
||||||
parent.items.splice(index, 1, newNode);
|
parent.items.splice(index, 1, newNode);
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
VITE_RUNTIME_PATH=/tmagic-editor/playground/runtime/vue2
|
|
||||||
VITE_ENTRY_PATH=./entry/vue2
|
|
@ -1,2 +1,2 @@
|
|||||||
VITE_RUNTIME_PATH=/tmagic-editor/playground/runtime/vue3
|
VITE_RUNTIME_PATH=/tmagic-editor/playground/runtime/vue
|
||||||
VITE_ENTRY_PATH=./entry/vue3
|
VITE_ENTRY_PATH=./entry/vue
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
# Vue 3 + Typescript + Vite
|
|
||||||
|
|
||||||
This template should help get you started developing with Vue 3 and Typescript in Vite.
|
|
||||||
|
|
||||||
## Recommended IDE Setup
|
|
||||||
|
|
||||||
[VSCode](https://code.visualstudio.com/) + [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur). Make sure to enable `vetur.experimental.templateInterpolationService` in settings!
|
|
||||||
|
|
||||||
### If Using `<script setup>`
|
|
||||||
|
|
||||||
[`<script setup>`](https://github.com/vuejs/rfcs/pull/227) is a feature that is currently in RFC stage. To get proper IDE support for the syntax, use [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) instead of Vetur (and disable Vetur).
|
|
||||||
|
|
||||||
## Type Support For `.vue` Imports in TS
|
|
||||||
|
|
||||||
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can use the following:
|
|
||||||
|
|
||||||
### If Using Volar
|
|
||||||
|
|
||||||
Run `Volar: Switch TS Plugin on/off` from VSCode command palette.
|
|
||||||
|
|
||||||
### If Using Vetur
|
|
||||||
|
|
||||||
1. Install and add `@vuedx/typescript-plugin-vue` to the [plugins section](https://www.typescriptlang.org/tsconfig#plugins) in `tsconfig.json`
|
|
||||||
2. Delete `src/shims-vue.d.ts` as it is no longer needed to provide module info to Typescript
|
|
||||||
3. Open `src/main.ts` in VSCode
|
|
||||||
4. Open the VSCode command palette
|
|
||||||
5. Search and run "Select TypeScript version" -> "Use workspace version"
|
|
@ -1,23 +1,22 @@
|
|||||||
{
|
{
|
||||||
"name": "tmagic-playground",
|
"name": "tmagic-playground",
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean:top": "rimraf dist",
|
"clean:top": "rimraf dist",
|
||||||
"dev": "vite --mode vue3",
|
"dev": "vite --mode vue3",
|
||||||
"dev:vue2": "vite --mode vue2",
|
|
||||||
"dev:react": "vite --mode react",
|
"dev:react": "vite --mode react",
|
||||||
"build": "npm run clean:top && node --max_old_space_size=8192 node_modules/vite/bin/vite.js build --mode vue3",
|
"build": "npm run clean:top && node --max_old_space_size=8192 node_modules/vite/bin/vite.js build --mode vue3",
|
||||||
"serve": "vite preview"
|
"serve": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.3.1",
|
"@element-plus/icons-vue": "^2.3.2",
|
||||||
"@tmagic/core": "1.6.0-beta.0",
|
"@tmagic/core": "1.6.1",
|
||||||
"@tmagic/editor": "1.6.0-beta.0",
|
"@tmagic/editor": "1.6.1",
|
||||||
"@tmagic/element-plus-adapter": "1.6.0-beta.0",
|
"@tmagic/element-plus-adapter": "1.6.1",
|
||||||
"@tmagic/tmagic-form-runtime": "1.1.3",
|
"@tmagic/tmagic-form-runtime": "1.1.3",
|
||||||
"element-plus": "^2.9.11",
|
"element-plus": "^2.11.4",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"monaco-editor": "^0.52.2",
|
"monaco-editor": "^0.52.2",
|
||||||
"serialize-javascript": "^6.0.2",
|
"serialize-javascript": "^6.0.2",
|
||||||
@ -28,15 +27,15 @@
|
|||||||
"@types/lodash-es": "^4.17.4",
|
"@types/lodash-es": "^4.17.4",
|
||||||
"@types/node": "^24.0.10",
|
"@types/node": "^24.0.10",
|
||||||
"@types/serialize-javascript": "^5.0.4",
|
"@types/serialize-javascript": "^5.0.4",
|
||||||
"@vitejs/plugin-legacy": "^7.0.0",
|
"@vitejs/plugin-legacy": "^7.2.1",
|
||||||
"@vitejs/plugin-vue": "^6.0.0",
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
"@vitejs/plugin-vue-jsx": "^5.0.1",
|
"@vitejs/plugin-vue-jsx": "^5.1.0",
|
||||||
"@vue/compiler-sfc": "catalog:",
|
"@vue/compiler-sfc": "catalog:",
|
||||||
"sass": "^1.89.2",
|
"lightningcss": "^1.30.2",
|
||||||
"terser": "^5.43.1",
|
"terser": "^5.43.1",
|
||||||
"typescript": "catalog:",
|
"typescript": "catalog:",
|
||||||
"unplugin-auto-import": "^19.3.0",
|
"unplugin-auto-import": "^20.0.0",
|
||||||
"unplugin-vue-components": "^28.8.0",
|
"unplugin-vue-components": "^29.0.0",
|
||||||
"vite": "catalog:"
|
"vite": "catalog:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ export default defineConfig({
|
|||||||
base: '/tmagic-editor/playground/',
|
base: '/tmagic-editor/playground/',
|
||||||
|
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: [
|
alias: process.env.NODE_ENV === 'development' ? [
|
||||||
{
|
{
|
||||||
find: /^@tmagic\/editor\/dist\/style.css/,
|
find: /^@tmagic\/editor\/dist\/style.css/,
|
||||||
replacement: path.join(__dirname, '../packages/editor/src/theme/index.scss'),
|
replacement: path.join(__dirname, '../packages/editor/src/theme/index.scss'),
|
||||||
@ -85,7 +85,7 @@ export default defineConfig({
|
|||||||
find: /^@tmagic\/element-plus-adapter/,
|
find: /^@tmagic\/element-plus-adapter/,
|
||||||
replacement: path.join(__dirname, '../packages/element-plus-adapter/src/index.ts'),
|
replacement: path.join(__dirname, '../packages/element-plus-adapter/src/index.ts'),
|
||||||
},
|
},
|
||||||
],
|
] : [],
|
||||||
},
|
},
|
||||||
|
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
@ -116,5 +116,6 @@ export default defineConfig({
|
|||||||
|
|
||||||
build: {
|
build: {
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
|
cssMinify: 'lightningcss'
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
3760
pnpm-lock.yaml
generated
3760
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -7,8 +7,8 @@ packages:
|
|||||||
- 'eslint-config'
|
- 'eslint-config'
|
||||||
|
|
||||||
catalog:
|
catalog:
|
||||||
vue: ^3.5.17
|
vue: ^3.5.22
|
||||||
'@vue/compiler-sfc': ^3.5.17
|
'@vue/compiler-sfc': ^3.5.22
|
||||||
vite: ^7.0.0
|
vite: ^7.1.9
|
||||||
typescript: "^5.8.3"
|
typescript: "^5.9.3"
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"name": "@tmagic/react-iterator-container",
|
"name": "@tmagic/react-iterator-container",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
|
@ -56,11 +56,10 @@ const IteratorContainer: React.FC<IteratorContainerProps> = ({
|
|||||||
|
|
||||||
const MagicUiComp = app?.resolveComponent('container');
|
const MagicUiComp = app?.resolveComponent('container');
|
||||||
|
|
||||||
const iteratorContainerNode = app?.getNode<TMagicIteratorContainer>(
|
const iteratorContainerNode = app?.getNode<TMagicIteratorContainer>(id || config.id || '', {
|
||||||
id || config.id || '',
|
|
||||||
iteratorContainerId,
|
iteratorContainerId,
|
||||||
iteratorIndex,
|
iteratorIndex,
|
||||||
);
|
});
|
||||||
|
|
||||||
iteratorContainerNode?.resetNodes();
|
iteratorContainerNode?.resetNodes();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.1",
|
"version": "0.2.1",
|
||||||
"name": "@tmagic/react-runtime-help",
|
"name": "@tmagic/react-runtime-help",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
@ -31,8 +31,8 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"@tmagic/core": ">=1.5.0",
|
"@tmagic/core": ">=1.6.0-beta.0",
|
||||||
"@tmagic/stage": ">=1.5.0",
|
"@tmagic/stage": ">=1.6.0-beta.0",
|
||||||
"react": ">=18.3.1",
|
"react": ">=18.3.1",
|
||||||
"typescript": "catalog:"
|
"typescript": "catalog:"
|
||||||
},
|
},
|
||||||
|
@ -20,7 +20,7 @@ import { useContext, useEffect, useState } from 'react';
|
|||||||
|
|
||||||
import type TMagicApp from '@tmagic/core';
|
import type TMagicApp from '@tmagic/core';
|
||||||
import type { Id, MNodeInstance, Node as TMagicNode } from '@tmagic/core';
|
import type { Id, MNodeInstance, Node as TMagicNode } from '@tmagic/core';
|
||||||
import { isDslNode } from '@tmagic/core';
|
import { isDslNode, NODE_CONDS_RESULT_KEY } from '@tmagic/core';
|
||||||
|
|
||||||
import AppContent from '../AppContent';
|
import AppContent from '../AppContent';
|
||||||
|
|
||||||
@ -96,8 +96,13 @@ export const useApp = ({ methods = {}, config, iteratorContainerId, iteratorInde
|
|||||||
}
|
}
|
||||||
|
|
||||||
const display = <T extends MNodeInstance>(config: T) => {
|
const display = <T extends MNodeInstance>(config: T) => {
|
||||||
if (config.visible === false) return false;
|
if (
|
||||||
if (config.condResult === false) return false;
|
config.visible === false ||
|
||||||
|
config.condResult === false ||
|
||||||
|
(typeof config.condResult === 'undefined' && config[NODE_CONDS_RESULT_KEY])
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const displayCfg = config.display;
|
const displayCfg = config.display;
|
||||||
|
|
||||||
|
4
runtime/react/.gitignore
vendored
4
runtime/react/.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
.tmagic
|
.tmagic
|
||||||
entry-dist
|
dist
|
||||||
|
*.local
|
||||||
|
*.local.*
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 Tencent. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
import { defineConfig } from 'vite';
|
|
||||||
import legacy from '@vitejs/plugin-legacy';
|
|
||||||
import reactRefresh from '@vitejs/plugin-react-refresh';
|
|
||||||
|
|
||||||
export default defineConfig(({ mode }) => {
|
|
||||||
if (['value', 'config', 'event', 'ds:value', 'ds:config', 'ds:event'].includes(mode)) {
|
|
||||||
const capitalToken = mode
|
|
||||||
.split(':')
|
|
||||||
.map((word) => word[0].toUpperCase() + word.slice(1))
|
|
||||||
.join('');
|
|
||||||
|
|
||||||
const fileName = mode.replace(':', '-');
|
|
||||||
|
|
||||||
return {
|
|
||||||
publicDir: './.tmagic/public',
|
|
||||||
build: {
|
|
||||||
cssCodeSplit: false,
|
|
||||||
sourcemap: true,
|
|
||||||
minify: false,
|
|
||||||
target: 'esnext',
|
|
||||||
outDir: `../../playground/public/entry/react/${fileName}`,
|
|
||||||
|
|
||||||
lib: {
|
|
||||||
entry: `.tmagic/${fileName}-entry.ts`,
|
|
||||||
name: `magicPreset${capitalToken}s`,
|
|
||||||
fileName: 'index',
|
|
||||||
formats: ['umd'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (['page', 'playground'].includes(mode)) {
|
|
||||||
return {
|
|
||||||
plugins: [
|
|
||||||
reactRefresh(),
|
|
||||||
legacy({
|
|
||||||
targets: ['defaults', 'not IE 11'],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
|
|
||||||
root: `./${mode}/`,
|
|
||||||
|
|
||||||
publicDir: '../public',
|
|
||||||
|
|
||||||
base: `/tmagic-editor/playground/runtime/react/${mode}`,
|
|
||||||
|
|
||||||
build: {
|
|
||||||
emptyOutDir: true,
|
|
||||||
sourcemap: true,
|
|
||||||
outDir: path.resolve(process.cwd(), `../../playground/public/runtime/react/${mode}`),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
});
|
|
@ -1,39 +1,40 @@
|
|||||||
{
|
{
|
||||||
"name": "runtime-react",
|
"name": "runtime-react",
|
||||||
"version": "1.6.0-beta.0",
|
"version": "1.6.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:react": "vite --config dev.vite.config.ts",
|
"tmagic": "tmagic entry",
|
||||||
"dev:playground": "vite --config dev.vite.config.ts",
|
"dev:react": "vite --force",
|
||||||
"build": "npm run build:libs && npm run build:page && npm run build:playground",
|
"serve": "vite preview",
|
||||||
"build:page": "vite build --config build.vite.config.ts --mode page",
|
"build": "rimraf ./dist && node scripts/build.mjs --type=all",
|
||||||
"build:playground": "vite build --config build.vite.config.ts --mode playground",
|
"build:libs": "node scripts/build.mjs --type=res",
|
||||||
"build:libs": "tmagic entry && npm run build:config && npm run build:value && npm run build:event && npm run build:ds:libs",
|
"build:page": "node scripts/build.mjs --type=page",
|
||||||
"build:ds:libs": "npm run build:ds:config && npm run build:ds:value && npm run build:ds:event",
|
"build:playground": "node scripts/build.mjs --type=playground"
|
||||||
"build:config": "vite build --config build.vite.config.ts --mode config",
|
|
||||||
"build:value": "vite build --config build.vite.config.ts --mode value",
|
|
||||||
"build:event": "vite build --config build.vite.config.ts --mode event",
|
|
||||||
"build:ds:config": "vite build --config build.vite.config.ts --mode ds:config",
|
|
||||||
"build:ds:value": "vite build --config build.vite.config.ts --mode ds:value",
|
|
||||||
"build:ds:event": "vite build --config build.vite.config.ts --mode ds:event"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tmagic/core": "1.6.0-beta.0",
|
"@tmagic/core": "1.6.1",
|
||||||
"@tmagic/react-runtime-help": "0.1.1",
|
"@tmagic/react-runtime-help": "0.2.0",
|
||||||
"@tmagic/stage": "1.6.0-beta.0",
|
"@tmagic/stage": "1.6.1",
|
||||||
"axios": "^1.10.0",
|
"axios": "^1.11.0",
|
||||||
|
"qrcode": "^1.5.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1"
|
"react-dom": "^18.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tmagic/cli": "1.6.0-beta.0",
|
"@tmagic/cli": "1.6.1",
|
||||||
|
"@types/fs-extra": "^11.0.4",
|
||||||
"@types/react": "^18.3.3",
|
"@types/react": "^18.3.3",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@vitejs/plugin-legacy": "^7.0.0",
|
"@vitejs/plugin-legacy": "^7.2.1",
|
||||||
"@vitejs/plugin-react-refresh": "^1.3.6",
|
"@vitejs/plugin-react-refresh": "^1.3.6",
|
||||||
|
"fs-extra": "^11.3.1",
|
||||||
"typescript": "catalog:",
|
"typescript": "catalog:",
|
||||||
"terser": "^5.43.1",
|
"terser": "^5.43.1",
|
||||||
"vite": "catalog:"
|
"vite": "catalog:",
|
||||||
|
"vite-plugin-commonjs": "^0.10.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
runtime/react/page/vite.config.ts
Normal file
32
runtime/react/page/vite.config.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
|
import baseConfig from '../vite.config';
|
||||||
|
|
||||||
|
const INVALID_CHAR_REGEX = /[\x00-\x1F\x7F<>*#"{}|^[\]`;?:&=+$,]/g;
|
||||||
|
const DRIVE_LETTER_REGEX = /^[a-z]:/i;
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
...baseConfig,
|
||||||
|
|
||||||
|
root: './page',
|
||||||
|
|
||||||
|
publicDir: '../public',
|
||||||
|
|
||||||
|
base: `${baseConfig.base}/page`,
|
||||||
|
|
||||||
|
build: {
|
||||||
|
emptyOutDir: false,
|
||||||
|
sourcemap: true,
|
||||||
|
outDir: '../dist/page',
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
// https://github.com/rollup/rollup/blob/master/src/utils/sanitizeFileName.ts
|
||||||
|
sanitizeFileName(name) {
|
||||||
|
const match = DRIVE_LETTER_REGEX.exec(name);
|
||||||
|
const driveLetter = match ? match[0] : '';
|
||||||
|
return driveLetter + name.slice(driveLetter.length).replace(INVALID_CHAR_REGEX, '');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
32
runtime/react/playground/vite.config.ts
Normal file
32
runtime/react/playground/vite.config.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
|
import baseConfig from '../vite.config';
|
||||||
|
|
||||||
|
const INVALID_CHAR_REGEX = /[\x00-\x1F\x7F<>*#"{}|^[\]`;?:&=+$,]/g;
|
||||||
|
const DRIVE_LETTER_REGEX = /^[a-z]:/i;
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
...baseConfig,
|
||||||
|
|
||||||
|
root: './playground',
|
||||||
|
|
||||||
|
publicDir: '../public',
|
||||||
|
|
||||||
|
base: `${baseConfig.base}/playground`,
|
||||||
|
|
||||||
|
build: {
|
||||||
|
emptyOutDir: false,
|
||||||
|
sourcemap: true,
|
||||||
|
outDir: '../dist/playground',
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
// https://github.com/rollup/rollup/blob/master/src/utils/sanitizeFileName.ts
|
||||||
|
sanitizeFileName(name) {
|
||||||
|
const match = DRIVE_LETTER_REGEX.exec(name);
|
||||||
|
const driveLetter = match ? match[0] : '';
|
||||||
|
return driveLetter + name.slice(driveLetter.length).replace(INVALID_CHAR_REGEX, '');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
60
runtime/react/scripts/build.mjs
Normal file
60
runtime/react/scripts/build.mjs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { execSync } from 'node:child_process';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
import { build as buildVite } from 'vite';
|
||||||
|
import fse from 'fs-extra';
|
||||||
|
import minimist from 'minimist';
|
||||||
|
|
||||||
|
import resViteConfig from './vite.res.config.mjs';
|
||||||
|
|
||||||
|
const args = minimist(process.argv.slice(2));
|
||||||
|
|
||||||
|
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
fse.removeSync(path.resolve(dirname, '../.tmagic'));
|
||||||
|
|
||||||
|
execSync('tmagic entry', {
|
||||||
|
stdio: 'inherit',
|
||||||
|
cwd: path.resolve(dirname, '../'),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (args.type === 'res' || args.type === 'all') {
|
||||||
|
fse.removeSync(path.resolve(dirname, '../dist/entry'));
|
||||||
|
for (const mode of ['value', 'config', 'event', 'ds:value', 'ds:config', 'ds:event']) {
|
||||||
|
const fileName = mode.replace(':', '-');
|
||||||
|
|
||||||
|
buildVite({
|
||||||
|
root: path.resolve(dirname, '../'),
|
||||||
|
clearScreen: false,
|
||||||
|
configFile: false,
|
||||||
|
...resViteConfig(mode),
|
||||||
|
}).then(() => {
|
||||||
|
fse.copySync(
|
||||||
|
path.resolve(dirname, '../dist/entry', fileName),
|
||||||
|
path.resolve(dirname, '../../../playground/public/entry/vue/', fileName),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildRuntime = (type) => {
|
||||||
|
fse.removeSync(path.resolve(dirname, '../dist', type));
|
||||||
|
|
||||||
|
buildVite({
|
||||||
|
root: path.resolve(dirname, '../', type),
|
||||||
|
clearScreen: false,
|
||||||
|
configFile: path.resolve(dirname, '../', type, 'vite.config.ts'),
|
||||||
|
}).then(() => {
|
||||||
|
const clientFile = path.resolve(dirname, '../dist', type);
|
||||||
|
fse.copySync(clientFile, path.resolve(dirname, '../../../playground/public/runtime/react', type));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (args.type === 'page' || args.type === 'all') {
|
||||||
|
buildRuntime('page');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.type === 'playground' || args.type === 'all') {
|
||||||
|
buildRuntime('playground');
|
||||||
|
}
|
28
runtime/react/scripts/vite.res.config.mjs
Normal file
28
runtime/react/scripts/vite.res.config.mjs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
|
export default defineConfig((mode) => {
|
||||||
|
const capitalToken = mode
|
||||||
|
.split(':')
|
||||||
|
.map((word) => word[0].toUpperCase() + word.slice(1))
|
||||||
|
.join('');
|
||||||
|
|
||||||
|
const fileName = mode.replace(':', '-');
|
||||||
|
|
||||||
|
return {
|
||||||
|
publicDir: './.tmagic/public',
|
||||||
|
build: {
|
||||||
|
cssCodeSplit: false,
|
||||||
|
sourcemap: true,
|
||||||
|
minify: false,
|
||||||
|
target: 'esnext',
|
||||||
|
outDir: `./dist/entry/${fileName}`,
|
||||||
|
|
||||||
|
lib: {
|
||||||
|
entry: `./.tmagic/${fileName}-entry.ts`,
|
||||||
|
name: `magicPreset${capitalToken}s`,
|
||||||
|
fileName: 'index',
|
||||||
|
formats: ['umd'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
@ -1,8 +1,23 @@
|
|||||||
import path from 'path';
|
|
||||||
|
|
||||||
import { defineConfig } from '@tmagic/cli';
|
import { defineConfig } from '@tmagic/cli';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
packages: [path.join(__dirname, '../ui-react')],
|
|
||||||
componentFileAffix: '.tsx',
|
componentFileAffix: '.tsx',
|
||||||
|
npmConfig: {
|
||||||
|
client: 'pnpm',
|
||||||
|
keepPackageJsonClean: true,
|
||||||
|
},
|
||||||
|
packages: [
|
||||||
|
{
|
||||||
|
button: '@tmagic/react-button',
|
||||||
|
container: '@tmagic/react-container',
|
||||||
|
img: '@tmagic/react-img',
|
||||||
|
'iterator-container': '@tmagic/react-iterator-container',
|
||||||
|
overlay: '@tmagic/react-overlay',
|
||||||
|
page: '@tmagic/react-page',
|
||||||
|
'page-fragment': '@tmagic/react-page-fragment',
|
||||||
|
'page-fragment-container': '@tmagic/react-page-fragment-container',
|
||||||
|
'qrcode': '@tmagic/react-qrcode',
|
||||||
|
'text': '@tmagic/react-text',
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
@ -16,13 +16,28 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import path from 'path';
|
import path from 'node:path';
|
||||||
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
|
import legacy from '@vitejs/plugin-legacy';
|
||||||
import reactRefresh from '@vitejs/plugin-react-refresh';
|
import reactRefresh from '@vitejs/plugin-react-refresh';
|
||||||
|
import commonjs from 'vite-plugin-commonjs';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [reactRefresh()],
|
plugins: [
|
||||||
|
commonjs({
|
||||||
|
filter: (id) => {
|
||||||
|
if (id.includes('qrcode')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
reactRefresh(),
|
||||||
|
legacy({
|
||||||
|
targets: ['defaults', 'not IE 11'],
|
||||||
|
})
|
||||||
|
],
|
||||||
|
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: [
|
alias: [
|
||||||
@ -34,17 +49,18 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
{ find: /^@tmagic\/utils/, replacement: path.join(__dirname, '../../packages/utils/src/index.ts') },
|
{ find: /^@tmagic\/utils/, replacement: path.join(__dirname, '../../packages/utils/src/index.ts') },
|
||||||
{ find: /^@tmagic\/core/, replacement: path.join(__dirname, '../../packages/core/src/index.ts') },
|
{ find: /^@tmagic\/core/, replacement: path.join(__dirname, '../../packages/core/src/index.ts') },
|
||||||
{ find: /^@tmagic\/schema/, replacement: path.join(__dirname, '../../packages/schema/src/index.ts') },
|
|
||||||
{ find: /^@data-source/, replacement: path.join(__dirname, '../../packages/data-source/src') },
|
|
||||||
{ find: /^@tmagic\/data-source/, replacement: path.join(__dirname, '../../packages/data-source/src/index.ts') },
|
{ find: /^@tmagic\/data-source/, replacement: path.join(__dirname, '../../packages/data-source/src/index.ts') },
|
||||||
{ find: /^@tmagic\/dep/, replacement: path.join(__dirname, '../../packages/dep/src/index.ts') },
|
{ find: /^@tmagic\/dep/, replacement: path.join(__dirname, '../../packages/dep/src/index.ts') },
|
||||||
{ find: /^@tmagic\/react-runtime-help/, replacement: path.join(__dirname, '../react-runtime-help/src/index.ts') },
|
{ find: /^@data-source/, replacement: path.join(__dirname, '../../packages/data-source/src') },
|
||||||
|
{ find: /^@tmagic\/schema/, replacement: path.join(__dirname, '../../packages/schema/src/index.ts') },
|
||||||
|
{ find: /^@tmagic\/vue-runtime-help/, replacement: path.join(__dirname, '../vue-runtime-help/src/index.ts') },
|
||||||
|
{ find: /^qrcode/, replacement: path.join(__dirname, './node_modules/qrcode') },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
root: './',
|
root: './',
|
||||||
|
|
||||||
base: '/tmagic-editor/playground/runtime/react/',
|
base: '/tmagic-editor/playground/runtime/react',
|
||||||
|
|
||||||
publicDir: 'public',
|
publicDir: 'public',
|
||||||
|
|
||||||
@ -55,17 +71,10 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
|
|
||||||
build: {
|
build: {
|
||||||
sourcemap: true,
|
|
||||||
|
|
||||||
cssCodeSplit: false,
|
|
||||||
|
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
input: {
|
input: {
|
||||||
page: './page/index.html',
|
page: path.resolve(__dirname, './page/index.html'),
|
||||||
playground: './playground/index.html',
|
playground: path.resolve(__dirname, './playground/index.html'),
|
||||||
},
|
|
||||||
output: {
|
|
||||||
entryFileNames: 'assets/[name].js',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
@ -1 +0,0 @@
|
|||||||
# [文档](https://tencent.github.io/tmagic-editor/docs/)
|
|
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@tmagic/ui-react",
|
|
||||||
"version": "1.5.18",
|
|
||||||
"type": "module",
|
|
||||||
"main": "dist/tmagic-ui-react.js",
|
|
||||||
"types": "types/index.d.ts",
|
|
||||||
"files": [
|
|
||||||
"src"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"directory": "runtime/ui-react",
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/Tencent/tmagic-editor.git"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@tmagic/react-button": "workspace:*",
|
|
||||||
"@tmagic/react-container": "workspace:*",
|
|
||||||
"@tmagic/react-img": "workspace:*",
|
|
||||||
"@tmagic/react-iterator-container": "workspace:*",
|
|
||||||
"@tmagic/react-overlay": "workspace:*",
|
|
||||||
"@tmagic/react-page": "workspace:*",
|
|
||||||
"@tmagic/react-page-fragment": "workspace:*",
|
|
||||||
"@tmagic/react-page-fragment-container": "workspace:*",
|
|
||||||
"@tmagic/react-qrcode": "workspace:*",
|
|
||||||
"@tmagic/react-text": "workspace:*"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"typescript": "catalog:"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"typescript": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 Tencent. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Button from '@tmagic/react-button';
|
|
||||||
import Container from '@tmagic/react-container';
|
|
||||||
import Img from '@tmagic/react-img';
|
|
||||||
import IteratorContainer from '@tmagic/react-iterator-container';
|
|
||||||
import Overlay from '@tmagic/react-overlay';
|
|
||||||
import Page from '@tmagic/react-page';
|
|
||||||
import PageFragment from '@tmagic/react-page-fragment';
|
|
||||||
import PageFragmentContainer from '@tmagic/react-page-fragment-container';
|
|
||||||
import QRcode from '@tmagic/react-qrcode';
|
|
||||||
import Text from '@tmagic/react-text';
|
|
||||||
|
|
||||||
export { default as TMagicUiButton } from '@tmagic/react-button';
|
|
||||||
export { default as TMagicUiContainer } from '@tmagic/react-container';
|
|
||||||
export { default as TMagicUiImg } from '@tmagic/react-img';
|
|
||||||
export { default as TMagicUiIteratorContainer } from '@tmagic/react-iterator-container';
|
|
||||||
export { default as TMagicUiOverlay } from '@tmagic/react-overlay';
|
|
||||||
export { default as TMagicUiPage } from '@tmagic/react-page';
|
|
||||||
export { default as TMagicUiPageFragment } from '@tmagic/react-page-fragment';
|
|
||||||
export { default as TMagicUiPageFragmentContainer } from '@tmagic/react-page-fragment-container';
|
|
||||||
export { default as TMagicUiQRcode } from '@tmagic/react-qrcode';
|
|
||||||
export { default as TMagicUiText } from '@tmagic/react-text';
|
|
||||||
|
|
||||||
const ui: Record<string, any> = {
|
|
||||||
page: Page,
|
|
||||||
container: Container,
|
|
||||||
button: Button,
|
|
||||||
text: Text,
|
|
||||||
img: Img,
|
|
||||||
qrcode: QRcode,
|
|
||||||
overlay: Overlay,
|
|
||||||
'page-fragment-container': PageFragmentContainer,
|
|
||||||
'page-fragment': PageFragment,
|
|
||||||
'iterator-container': IteratorContainer,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ui;
|
|
@ -1 +0,0 @@
|
|||||||
# [文档](https://tencent.github.io/tmagic-editor/docs/)
|
|
@ -1,41 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "1.5.18",
|
|
||||||
"name": "@tmagic/ui",
|
|
||||||
"type": "module",
|
|
||||||
"main": "dist/tmagic-ui.js",
|
|
||||||
"types": "types/index.d.ts",
|
|
||||||
"files": [
|
|
||||||
"src",
|
|
||||||
"dist",
|
|
||||||
"types"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"repository": {
|
|
||||||
"directory": "runtime/ui",
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/Tencent/tmagic-editor.git"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@tmagic/vue-button": "workspace:*",
|
|
||||||
"@tmagic/vue-container": "workspace:*",
|
|
||||||
"@tmagic/vue-img": "workspace:*",
|
|
||||||
"@tmagic/vue-iterator-container": "workspace:*",
|
|
||||||
"@tmagic/vue-overlay": "workspace:*",
|
|
||||||
"@tmagic/vue-page": "workspace:*",
|
|
||||||
"@tmagic/vue-page-fragment": "workspace:*",
|
|
||||||
"@tmagic/vue-page-fragment-container": "workspace:*",
|
|
||||||
"@tmagic/vue-qrcode": "workspace:*",
|
|
||||||
"@tmagic/vue-text": "workspace:*"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"typescript": "catalog:"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"typescript": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 Tencent. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Button from '@tmagic/vue-button';
|
|
||||||
import Container from '@tmagic/vue-container';
|
|
||||||
import Img from '@tmagic/vue-img';
|
|
||||||
import IteratorContainer from '@tmagic/vue-iterator-container';
|
|
||||||
import Overlay from '@tmagic/vue-overlay';
|
|
||||||
import Page from '@tmagic/vue-page';
|
|
||||||
import PageFragment from '@tmagic/vue-page-fragment';
|
|
||||||
import PageFragmentContainer from '@tmagic/vue-page-fragment-container';
|
|
||||||
import QRcode from '@tmagic/vue-qrcode';
|
|
||||||
import Text from '@tmagic/vue-text';
|
|
||||||
|
|
||||||
export { default as TMagicUiButton } from '@tmagic/vue-button';
|
|
||||||
export { default as TMagicUiContainer } from '@tmagic/vue-container';
|
|
||||||
export { default as TMagicUiImg } from '@tmagic/vue-img';
|
|
||||||
export { default as TMagicUiIteratorContainer } from '@tmagic/vue-iterator-container';
|
|
||||||
export { default as TMagicUiOverlay } from '@tmagic/vue-overlay';
|
|
||||||
export { default as TMagicUiPage } from '@tmagic/vue-page';
|
|
||||||
export { default as TMagicUiPageFragment } from '@tmagic/vue-page-fragment';
|
|
||||||
export { default as TMagicUiPageFragmentContainer } from '@tmagic/vue-page-fragment-container';
|
|
||||||
export { default as TMagicUiQRcode } from '@tmagic/vue-qrcode';
|
|
||||||
export { default as TMagicUiText } from '@tmagic/vue-text';
|
|
||||||
|
|
||||||
const ui: Record<string, any> = {
|
|
||||||
page: Page,
|
|
||||||
container: Container,
|
|
||||||
button: Button,
|
|
||||||
text: Text,
|
|
||||||
img: Img,
|
|
||||||
qrcode: QRcode,
|
|
||||||
overlay: Overlay,
|
|
||||||
'page-fragment-container': PageFragmentContainer,
|
|
||||||
'page-fragment': PageFragment,
|
|
||||||
'iterator-container': IteratorContainer,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ui;
|
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.1.5",
|
"version": "1.2.2",
|
||||||
"name": "@tmagic/vue-runtime-help",
|
"name": "@tmagic/vue-runtime-help",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
@ -30,8 +30,8 @@
|
|||||||
"vue-demi": "^0.14.10"
|
"vue-demi": "^0.14.10"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@tmagic/core": ">=1.5.0",
|
"@tmagic/core": ">=1.6.0-beta.0",
|
||||||
"@tmagic/stage": ">=1.5.0",
|
"@tmagic/stage": ">=1.6.0-beta.0",
|
||||||
"@vue/composition-api": ">=1.7.2",
|
"@vue/composition-api": ">=1.7.2",
|
||||||
"typescript": "catalog:",
|
"typescript": "catalog:",
|
||||||
"vue": ">=2.6.0 || >=3.5.0"
|
"vue": ">=2.6.0 || >=3.5.0"
|
||||||
|
@ -4,7 +4,7 @@ import type TMagicApp from '@tmagic/core';
|
|||||||
import type { ChangeEvent, Id, MNode } from '@tmagic/core';
|
import type { ChangeEvent, Id, MNode } from '@tmagic/core';
|
||||||
import { isPage, isPageFragment, replaceChildNode } from '@tmagic/core';
|
import { isPage, isPageFragment, replaceChildNode } from '@tmagic/core';
|
||||||
|
|
||||||
export const useDsl = (app = inject<TMagicApp>('app'), pageFragmentConstainerId: Id) => {
|
export const useDsl = (app = inject<TMagicApp>('app'), pageFragmentConstainerId?: Id) => {
|
||||||
if (!app) {
|
if (!app) {
|
||||||
throw new Error('useDsl must be used after MagicApp is created');
|
throw new Error('useDsl must be used after MagicApp is created');
|
||||||
}
|
}
|
||||||
|
4
runtime/vue/.gitignore
vendored
Normal file
4
runtime/vue/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.tmagic
|
||||||
|
dist
|
||||||
|
*.local
|
||||||
|
*.local.*
|
43
runtime/vue/package.json
Normal file
43
runtime/vue/package.json
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"name": "runtime-vue",
|
||||||
|
"version": "1.6.1",
|
||||||
|
"type": "module",
|
||||||
|
"private": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"tmagic": "tmagic entry",
|
||||||
|
"dev": "vite --force",
|
||||||
|
"serve": "vite preview",
|
||||||
|
"build": "rimraf ./dist && node scripts/build.mjs --type=all",
|
||||||
|
"build:libs": "node scripts/build.mjs --type=res",
|
||||||
|
"build:page": "node scripts/build.mjs --type=page",
|
||||||
|
"build:playground": "node scripts/build.mjs --type=playground"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@tmagic/core": "1.6.1",
|
||||||
|
"@tmagic/stage": "1.6.1",
|
||||||
|
"@tmagic/vue-runtime-help": "^1.2.0",
|
||||||
|
"axios": "^1.11.0",
|
||||||
|
"vue": "catalog:"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tmagic/cli": "1.6.1",
|
||||||
|
"@types/fs-extra": "^11.0.4",
|
||||||
|
"@types/node": "^24.0.10",
|
||||||
|
"@vitejs/plugin-legacy": "^7.2.1",
|
||||||
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^5.1.0",
|
||||||
|
"@vue/compiler-sfc": "catalog:",
|
||||||
|
"fs-extra": "^11.3.1",
|
||||||
|
"minimist": "^1.2.8",
|
||||||
|
"lightningcss": "^1.30.2",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"rollup": "4.44.1",
|
||||||
|
"rollup-plugin-external-globals": "^0.13.0",
|
||||||
|
"terser": "^5.43.1",
|
||||||
|
"typescript": "catalog:",
|
||||||
|
"vite": "catalog:"
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="icon" href="/favicon.png" type="image/png">
|
<link rel="icon" href="/favicon.png" type="image/png">
|
||||||
<title>Vue2 Page</title>
|
<title>Vue Page</title>
|
||||||
<style>
|
<style>
|
||||||
html,
|
html,
|
||||||
body,
|
body,
|
||||||
@ -12,7 +12,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
@ -25,9 +25,6 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/vue-demi"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body style="font-size: 14px">
|
<body style="font-size: 14px">
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
@ -16,9 +16,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createApp, defineAsyncComponent } from 'vue';
|
import { createApp, defineAsyncComponent, resolveDirective, withDirectives } from 'vue';
|
||||||
|
|
||||||
import TMagicApp, { DataSourceManager, DeepObservedData, getUrlParam, registerDataSourceOnDemand } from '@tmagic/core';
|
import TMagicApp, { DataSourceManager, DeepObservedData, getUrlParam, registerDataSourceOnDemand } from '@tmagic/core';
|
||||||
|
import { UserRenderFunctionOptions } from '@tmagic/vue-runtime-help';
|
||||||
|
|
||||||
import components from '../.tmagic/async-comp-entry';
|
import components from '../.tmagic/async-comp-entry';
|
||||||
import asyncDataSources from '../.tmagic/async-datasource-entry';
|
import asyncDataSources from '../.tmagic/async-datasource-entry';
|
||||||
@ -56,6 +57,32 @@ Object.values(plugins).forEach((plugin: any) => {
|
|||||||
vueApp.use(plugin, { app });
|
vueApp.use(plugin, { app });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
vueApp.provide(
|
||||||
|
'userRender',
|
||||||
|
({ h, type, props = {}, attrs = {}, style, className, on, directives = [] }: UserRenderFunctionOptions) => {
|
||||||
|
const options: Record<string, any> = {
|
||||||
|
...props,
|
||||||
|
...attrs,
|
||||||
|
style,
|
||||||
|
class: className,
|
||||||
|
};
|
||||||
|
if (on) {
|
||||||
|
for (const [key, handler] of Object.entries(on)) {
|
||||||
|
options[`on${key[0].toLocaleUpperCase()}${key.substring(1)}`] = handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (directives.length) {
|
||||||
|
return withDirectives(
|
||||||
|
h(type, options),
|
||||||
|
directives.map((directive) => [resolveDirective(directive.name), directive.value, directive.modifiers]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return h(type, options);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
registerDataSourceOnDemand(dsl, asyncDataSources).then((dataSources) => {
|
registerDataSourceOnDemand(dsl, asyncDataSources).then((dataSources) => {
|
||||||
Object.entries(dataSources).forEach(([type, ds]: [string, any]) => {
|
Object.entries(dataSources).forEach(([type, ds]: [string, any]) => {
|
||||||
DataSourceManager.register(type, ds);
|
DataSourceManager.register(type, ds);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user