chore: merge from develop

This commit is contained in:
JackLian 2023-01-10 21:58:24 +08:00
commit 38915d615a
104 changed files with 1791 additions and 1008 deletions

View File

@ -41,5 +41,16 @@ module.exports = {
'@typescript-eslint/dot-notation': 0, // for lint performance '@typescript-eslint/dot-notation': 0, // for lint performance
'@typescript-eslint/restrict-plus-operands': 0, // for lint performance '@typescript-eslint/restrict-plus-operands': 0, // for lint performance
'no-unexpected-multiline': 1, 'no-unexpected-multiline': 1,
'no-multiple-empty-lines': ['error', { "max": 1 }],
'lines-around-comment': ['error', {
"beforeBlockComment": true,
"afterBlockComment": false,
"afterLineComment": false,
"allowBlockStart": true,
}],
"@typescript-eslint/member-ordering": [
"error",
{ "default": ["signature", "field", "constructor", "method"] }
],
} }
}; };

View File

@ -44,3 +44,7 @@ sidebar_position: 0
2. 事件events的命名格式为on[Will|Did]VerbNoun?,参考 [https://code.visualstudio.com/api/references/vscode-api#events](https://code.visualstudio.com/api/references/vscode-api#events) 2. 事件events的命名格式为on[Will|Did]VerbNoun?,参考 [https://code.visualstudio.com/api/references/vscode-api#events](https://code.visualstudio.com/api/references/vscode-api#events)
3. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数 3. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数
4. 对于属性的导出,统一用 .xxx 的 getter 模式,(尽量)不使用 .getXxx() 4. 对于属性的导出,统一用 .xxx 的 getter 模式,(尽量)不使用 .getXxx()
## experimental
说明此模块处于公测阶段, API 可能会发生改变.

View File

@ -9,30 +9,65 @@ sidebar_position: 6
画布节点悬停模型 画布节点悬停模型
## 方法签名 ## 变量
### capture
capture(id: string)
hover 指定节点
### release
release(id: string)
hover 离开指定节点
### leave
leave()
清空 hover 态
### current ### current
当前 hover 的节点 当前 hover 的节点
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
**@since v1.0.16** **@since v1.0.16**
### enable
是否启用
`@type {boolean}`
## 方法签名
### capture
hover 指定节点
```typescript
/**
* hover 指定节点
* capture node with nodeId
* @param id 节点 id
*/
capture(id: string): void;
```
### release
hover 离开指定节点
```typescript
/**
* hover 离开指定节点
* release node with nodeId
* @param id 节点 id
*/
release(id: string): void;
```
### leave
清空 hover 态
```typescript
/**
* 清空 hover 态
* clear all hover state
*/
leave(): void;
```
## 事件
### onDetectingChange ### onDetectingChange
hover 节点变化事件 hover 节点变化事件
@ -42,6 +77,11 @@ hover 节点变化事件
* set callback which will be called when hovering object changed. * set callback which will be called when hovering object changed.
* @since v1.1.0 * @since v1.1.0
*/ */
onDetectingChange(fn: (node: IPublicModelNode) => void): () => void; onDetectingChange(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable;
``` ```
相关类型:
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
**@since v1.1.0** **@since v1.1.0**

View File

@ -334,7 +334,7 @@ onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): voi
### onChangeNodeChildren ### onChangeNodeChildren
onChangeNodeChildren(fn: (info?: IPublicOnChangeOptions) => void) onChangeNodeChildren(fn: (info?: IPublicTypeOnChangeOptions) => void)
当前 document 的节点 children 变更事件 当前 document 的节点 children 变更事件

View File

@ -12,47 +12,113 @@ sidebar_position: 5
## 方法签名 ## 方法签名
### go ### go
go(cursor: number)
历史记录跳转到指定位置 历史记录跳转到指定位置
```typescript
/**
* 历史记录跳转到指定位置
* go to a specific history
* @param cursor
*/
go(cursor: number): void;
```
### back ### back
back()
历史记录后退 历史记录后退
```typescript
/**
* 历史记录后退
* go backward in history
*/
back(): void;
```
### forward ### forward
forward() forward()
历史记录前进 历史记录前进
```typescript
/**
* 历史记录前进
* go forward in history
*/
forward(): void;
```
### savePoint ### savePoint
savePoint()
保存当前状态 保存当前状态
### isSavePoint
isSavePoint() ```typescript
/**
* 保存当前状态
* do save current change as a record in history
*/
savePoint(): void;
```
### isSavePoint
当前是否是「保存点」,即是否有状态变更但未保存 当前是否是「保存点」,即是否有状态变更但未保存
```typescript
/**
* 当前是否是「保存点」,即是否有状态变更但未保存
* check if there is unsaved change for history
*/
isSavePoint(): boolean;
```
### getState ### getState
getState()
获取 state判断当前是否为「可回退」、「可前进」的状态 获取 state判断当前是否为「可回退」、「可前进」的状态
```typescript
/**
* 获取 state判断当前是否为「可回退」、「可前进」的状态
* get flags in number which indicat current change state
*
* | 1 | 1 | 1 |
* | -------- | -------- | -------- |
* | modified | redoable | undoable |
* eg:
* 7 means : modified && redoable && undoable
* 5 means : modified && undoable
*/
getState(): number;
```
## 事件 ## 事件
### onChangeState ### onChangeState
onChangeState(func: () => any)
监听 state 变更事件 监听 state 变更事件
```typescript
/**
* 监听 state 变更事件
* monitor on stateChange event
* @param func
*/
onChangeState(func: () => any): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onChangeCursor ### onChangeCursor
onChangeCursor(func: () => any)
监听历史记录游标位置变更事件 监听历史记录游标位置变更事件
```typescript
/**
* 监听历史记录游标位置变更事件
* monitor on cursorChange event
* @param func
*/
onChangeCursor(func: () => any): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)

View File

@ -1,5 +1,5 @@
--- ---
title: plugin-instance title: PluginInstance
sidebar_position: 12 sidebar_position: 12
--- ---

View File

@ -15,39 +15,94 @@ sidebar_position: 3
id id
`@type {string}`
### key ### key
key 值 key 值
`@type {string | number | undefined}`
### path ### path
返回当前 prop 的路径 返回当前 prop 的路径
`@type {string[]}`
### node ### node
返回所属的节点实例 返回所属的节点实例
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### slotNode
当本 prop 代表一个 Slot 时,返回对应的 slotNode
`@type {IPublicModelNode | undefined | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
## 方法签名 ## 方法签名
### setValue ### setValue
setValue(val: CompositeValue)
设置值 设置值
```typescript
/**
* 设置值
* set value for this prop
* @param val
*/
setValue(val: IPublicTypeCompositeValue): void;
```
相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
### getValue ### getValue
getValue()
获取值 获取值
```typescript
/**
* 获取值
* get value of this prop
*/
getValue(): any;
```
### remove ### remove
移除值 移除值
```typescript
/**
* 移除值
* remove value of this prop
* @since v1.0.16
*/
remove(): void;
```
**@since v1.0.16** **@since v1.0.16**
### exportSchema ### exportSchema
exportSchema(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Render)
导出值 导出值
```typescript
/**
* 导出值
* export schema
* @param stage
*/
exportSchema(stage: IPublicEnumTransformStage): IPublicTypeCompositeValue;
```
相关类型:
- [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts)
- [IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)

View File

@ -13,46 +13,148 @@ sidebar_position: 4
### id ### id
id id
`@type {string}`
### path ### path
返回当前 props 的路径 返回当前 props 的路径
`@type {string[]}`
### node ### node
返回当前属性集所属的节点实例 返回当前属性集所属的节点实例
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
## 方法签名 ## 方法签名
### getProp ### getProp
getProp(path: string): Prop | null
获取指定 path 的属性模型实例 获取指定 path 的属性模型实例
```typescript
/**
* 获取指定 path 的属性模型实例
* get prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
*/
getProp(path: string): IPublicModelProp | null;
```
相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts)
### getPropValue ### getPropValue
getPropValue(path: string)
获取指定 path 的属性模型实例值 获取指定 path 的属性模型实例值
```typescript
/**
* 获取指定 path 的属性模型实例值
* get value of prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
*/
getPropValue(path: string): any;
```
### getExtraProp ### getExtraProp
getExtraProp(path: string): Prop | null
获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
```typescript
/**
* 获取指定 path 的属性模型实例,
* 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
* get extra prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
*/
getExtraProp(path: string): IPublicModelProp | null;
```
相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts)
### getExtraPropValue ### getExtraPropValue
getExtraPropValue(path: string)
获取指定 path 的属性模型实例值,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 获取指定 path 的属性模型实例值,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
```typescript
/**
* 获取指定 path 的属性模型实例值
* 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
* get value of extra prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
*/
getExtraPropValue(path: string): any;
```
### setPropValue ### setPropValue
setPropValue(path: string, value: CompositeValue)
设置指定 path 的属性模型实例值 设置指定 path 的属性模型实例值
```typescript
/**
* 设置指定 path 的属性模型实例值
* set value of prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
* @param value 值
*/
setPropValue(path: string, value: IPublicTypeCompositeValue): void;
```
相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
### setExtraPropValue ### setExtraPropValue
setExtraPropValue(path: string, value: CompositeValue)
设置指定 path 的属性模型实例值 设置指定 path 的属性模型实例值
```typescript
/**
* 设置指定 path 的属性模型实例值
* set value of extra prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
* @param value 值
*/
setExtraPropValue(path: string, value: IPublicTypeCompositeValue): void;
```
相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
### has
当前 props 是否包含某 prop
```typescript
/**
* 当前 props 是否包含某 prop
* check if the specified key is existing or not.
* @param key
* @since v1.1.0
*/
has(key: string): boolean;
```
**@since v1.1.0**
### add
添加一个 prop
```typescript
/**
* 添加一个 prop
* add a key with given value
* @param value
* @param key
* @since v1.1.0
*/
add(value: IPublicTypeCompositeValue, key?: string | number | undefined): any;
```
相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
**@since v1.1.0**

View File

@ -0,0 +1,46 @@
---
title: Resource
sidebar_position: 12
---
> **[@experimental](./#experimental)**<br/>
> **@types** [IPublicModelWindow](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/resource.ts)<br/>
> **@since** v1.1.0
## 变量
### title
资源标题
`@type {string}`
### name
资源名字
`@type {string}`
### type
资源类型
`@type {string}`
### category
资源分类
`@type {string}`
### icon
资源 icon
`@type {ReactElement}`
### options
资源配置信息
`@type {Object}`

View File

@ -14,49 +14,110 @@ sidebar_position: 6
返回选中的节点 id 返回选中的节点 id
`@type {string[]}`
### node
返回选中的节点(如多个节点只返回第一个)
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
**@since v1.1.0**
## 方法签名 ## 方法签名
### select ### select
select(id: string)
选中指定节点(覆盖方式) 选中指定节点(覆盖方式)
```typescript
/**
* 选中指定节点(覆盖方式)
* select node with id, this will override current selection
* @param id
*/
select(id: string): void;
```
### selectAll ### selectAll
selectAll(ids: string[])
批量选中指定节点们 批量选中指定节点们
```typescript
/**
* 批量选中指定节点们
* select node with ids, this will override current selection
*
* @param ids
*/
selectAll(ids: string[]): void;
```
### remove ### remove
remove(id: string)
**取消选中**选中的指定节点,不会删除组件 **取消选中**选中的指定节点,不会删除组件
```typescript
/**
* 移除选中的指定节点
* remove node from selection with node id
* @param id
*/
remove(id: string): void;
```
### clear ### clear
clear()
**取消选中**所有选中节点,不会删除组件 **取消选中**所有选中节点,不会删除组件
```typescript
/**
* 清除所有选中节点
* clear current selection
*/
clear(): void;
```
### has ### has
has(id: string)
判断是否选中了指定节点 判断是否选中了指定节点
```typescript
/**
* 判断是否选中了指定节点
* check if node with specific id is selected
* @param id
*/
has(id: string): boolean;
```
### add ### add
add(id: string)
选中指定节点(增量方式) 选中指定节点(增量方式)
```typescript
/**
* 选中指定节点(增量方式)
* add node with specific id to selection
* @param id
*/
add(id: string): void;
```
### getNodes ### getNodes
getNodes()
获取选中的节点实例 获取选中的节点实例
```typescript
/**
* 获取选中的节点实例
* get selected nodes
*/
getNodes(): IPublicModelNode[];
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### getTopNodes ### getTopNodes
获取选区的顶层节点 获取选区的顶层节点
例如选中的节点为: 例如选中的节点为:
@ -67,19 +128,34 @@ getNodes()
getNodes 返回的是 [DivA、ChildrenA、DivB]getTopNodes 返回的是 [DivA、DivB],其中 ChildrenA 由于是二层节点getTopNodes 不会返回 getNodes 返回的是 [DivA、ChildrenA、DivB]getTopNodes 返回的是 [DivA、DivB],其中 ChildrenA 由于是二层节点getTopNodes 不会返回
```typescript
/**
* 获取选区的顶层节点
* get seleted top nodes
* for example:
* getNodes() returns [A, subA, B], then
* getTopNodes() will return [A, B], subA will be removed
* @since v1.0.16
*/
getTopNodes(includeRoot?: boolean): IPublicModelNode[];
```
**@since v1.0.16** **@since v1.0.16**
## 事件
### onSelectionChange ### onSelectionChange
注册 selection 变化事件回调 注册 selection 变化事件回调
```typescript ```typescript
/** /**
* 注册 selection 变化事件回调 * 注册 selection 变化事件回调
* set callback which will be called when selection is changed * set callback which will be called when selection is changed
* @since v1.1.0 * @since v1.1.0
*/ */
onSelectionChange(fn: (ids: string[]) => void): () => void; onSelectionChange(fn: (ids: string[]) => void): IPublicTypeDisposable;
``` ```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
**@since v1.1.0** **@since v1.1.0**

View File

@ -3,6 +3,7 @@ title: Window
sidebar_position: 12 sidebar_position: 12
--- ---
> **[@experimental](./#experimental)**<br/>
> **@types** [IPublicModelWindow](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/window.ts)<br/> > **@types** [IPublicModelWindow](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/window.ts)<br/>
> **@since** v1.1.0 > **@since** v1.1.0
@ -17,13 +18,25 @@ sidebar_position: 12
窗口唯一 id 窗口唯一 id
`@type {string}`
### title ### title
窗口标题 窗口标题
### resourceName `@type {string}`
窗口资源名字 ### icon
`@type {ReactElement}`
### resource
窗口对应资源
`@type {IPublicModelResource}`
关联模型 [IPublicModelResource](./resource)
## 方法签名 ## 方法签名

View File

@ -222,7 +222,7 @@ your-plugin/package.json
} }
``` ```
转换后的结构: 转换后的结构:
```json ```typescript
const debug = (ctx: IPublicModelPluginContext, options: any) => { const debug = (ctx: IPublicModelPluginContext, options: any) => {
return {}; return {};
} }

View File

@ -3,10 +3,10 @@ title: workspace - 应用级 API
sidebar_position: 12 sidebar_position: 12
--- ---
> **[@experimental](./#experimental)**<br/>
> **@types** [IPublicApiWorkspace](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/workspace.ts)<br/> > **@types** [IPublicApiWorkspace](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/workspace.ts)<br/>
> **@since** v1.1.0 > **@since** v1.1.0
## 模块简介 ## 模块简介
通过该模块可以开发应用级低代码设计器。 通过该模块可以开发应用级低代码设计器。
@ -47,6 +47,16 @@ get window(): IPublicModelWindow[]
关联模型 [IPublicModelWindow](./model/window) 关联模型 [IPublicModelWindow](./model/window)
### resourceList
当前设计器的资源列表数据
```
get resourceList(): IPublicModelResource;
```
关联模型 [IPublicModelResource](./model/resource)
## 方法签名 ## 方法签名
### registerResourceType ### registerResourceType
@ -54,10 +64,10 @@ get window(): IPublicModelWindow[]
```typescript ```typescript
/** 注册资源 */ /** 注册资源 */
registerResourceType(resourceName: string, resourceType: 'editor', options: IPublicResourceOptions): void; registerResourceType(resourceTypeModel: IPublicTypeResourceType): void;
``` ```
相关类型:[IPublicResourceOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-options.ts) 相关类型:[IPublicTypeResourceType](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-type.ts)
### onChangeWindows ### onChangeWindows
@ -74,3 +84,55 @@ active 窗口变更事件
```typescript ```typescript
function onChangeActiveWindow(fn: () => void): void; function onChangeActiveWindow(fn: () => void): void;
``` ```
### setResourceList
设置设计器资源列表数据
```typescript
setResourceList(resourceList: IPublicResourceList) {}
```
相关类型:[IPublicResourceOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-options.ts)
### onResourceListChange
设计器资源列表数据变更事件
```typescript
onResourceListChange(fn: (resourceList: IPublicResourceList): void): (): void;
```
相关类型:[IPublicResourceOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-options.ts)
### openEditorWindow
打开视图窗口
```typescript
openEditorWindow(resourceName: string, title: string, options: Object, viewName?: string): void;
```
### openEditorWindowById
通过视图 id 打开窗口
```typescript
openEditorWindowById(id: string): void;
```
### removeEditorWindow
移除视图窗口
```typescript
removeEditorWindow(resourceName: string, title: string): void;
```
### removeEditorWindowById
通过视图 id 移除窗口
```typescript
removeEditorWindowById(id: string): void;
```

View File

@ -313,7 +313,7 @@ simulator-renderer 通过调用 host 的方法,将 schema、components 等参
- 被拖拽对象 - `DragObject` - 被拖拽对象 - `DragObject`
- 拖拽到的目标位置 - `DropLocation` - 拖拽到的目标位置 - `DropLocation`
- 拖拽感应区 - `ISensor` - 拖拽感应区 - `IPublicModelSensor`
- 定位事件 - `LocateEvent` - 定位事件 - `LocateEvent`
##### Sensor ##### Sensor

View File

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

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-code-generator", "name": "@alilc/lowcode-code-generator",
"version": "1.0.7-beta.5", "version": "1.0.7",
"description": "出码引擎 for LowCode Engine", "description": "出码引擎 for LowCode Engine",
"license": "MIT", "license": "MIT",
"main": "lib/index.js", "main": "lib/index.js",

View File

@ -40,6 +40,11 @@ export interface ProjectBuilderInitOptions {
inStrictMode?: boolean; inStrictMode?: boolean;
/** 一些额外的上下文数据 */ /** 一些额外的上下文数据 */
extraContextData?: Record<string, unknown>; extraContextData?: Record<string, unknown>;
/**
* Hook which is used to customize original options, we can reorder/add/remove plugins/processors
* of the existing solution.
*/
customizeBuilderOptions?(originalOptions: ProjectBuilderInitOptions): ProjectBuilderInitOptions;
} }
export class ProjectBuilder implements IProjectBuilder { export class ProjectBuilder implements IProjectBuilder {
@ -67,16 +72,21 @@ export class ProjectBuilder implements IProjectBuilder {
/** 一些额外的上下文数据 */ /** 一些额外的上下文数据 */
readonly extraContextData: IContextData; readonly extraContextData: IContextData;
constructor({ constructor(builderOptions: ProjectBuilderInitOptions) {
template, let customBuilderOptions = builderOptions;
plugins, if (typeof builderOptions.customizeBuilderOptions === 'function') {
postProcessors, customBuilderOptions = builderOptions.customizeBuilderOptions(builderOptions);
schemaParser = new SchemaParser(), }
projectPreProcessors = [], const {
projectPostProcessors = [], template,
inStrictMode = false, plugins,
extraContextData = {}, postProcessors,
}: ProjectBuilderInitOptions) { schemaParser = new SchemaParser(),
projectPreProcessors = [],
projectPostProcessors = [],
inStrictMode = false,
extraContextData = {},
} = customBuilderOptions;
this.template = template; this.template = template;
this.plugins = plugins; this.plugins = plugins;
this.postProcessors = postProcessors; this.postProcessors = postProcessors;

View File

@ -5,7 +5,7 @@
import changeCase from 'change-case'; import changeCase from 'change-case';
import { import {
IPublicTypeUtilItem, IPublicTypeUtilItem,
NodeDataType, IPublicTypeNodeDataType,
IPublicTypeNodeSchema, IPublicTypeNodeSchema,
IPublicTypeContainerSchema, IPublicTypeContainerSchema,
IPublicTypeProjectSchema, IPublicTypeProjectSchema,
@ -81,7 +81,7 @@ function processChildren(schema: IPublicTypeNodeSchema): void {
if (nodeProps.children) { if (nodeProps.children) {
if (!schema.children) { if (!schema.children) {
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
schema.children = nodeProps.children as NodeDataType; schema.children = nodeProps.children as IPublicTypeNodeDataType;
} else { } else {
let _children: IPublicTypeNodeData[] = []; let _children: IPublicTypeNodeData[] = [];
@ -331,7 +331,7 @@ export class SchemaParser implements ISchemaParser {
}; };
} }
getComponentNames(children: NodeDataType): string[] { getComponentNames(children: IPublicTypeNodeDataType): string[] {
return handleSubNodes<string>( return handleSubNodes<string>(
children, children,
{ {

View File

@ -91,6 +91,7 @@ export default function createIceJsProjectBuilder(
packageJSON: [icejs.plugins.packageJSON()], packageJSON: [icejs.plugins.packageJSON()],
}, },
postProcessors: [prettier()], postProcessors: [prettier()],
customizeBuilderOptions: options?.customizeBuilderOptions,
}); });
} }

View File

@ -71,6 +71,7 @@ export default function createRaxProjectBuilder(
packageJSON: [raxApp.plugins.packageJSON(options)], packageJSON: [raxApp.plugins.packageJSON(options)],
}, },
postProcessors: [prettier()], postProcessors: [prettier()],
customizeBuilderOptions: options?.customizeBuilderOptions,
}); });
} }

View File

@ -5,7 +5,7 @@ import {
IPublicTypeCompositeObject, IPublicTypeCompositeObject,
ResultDir, ResultDir,
ResultFile, ResultFile,
NodeDataType, IPublicTypeNodeDataType,
IPublicTypeProjectSchema, IPublicTypeProjectSchema,
IPublicTypeJSExpression, IPublicTypeJSExpression,
IPublicTypeJSFunction, IPublicTypeJSFunction,
@ -14,6 +14,7 @@ import {
import { IParseResult } from './intermediate'; import { IParseResult } from './intermediate';
import { IScopeBindings } from '../utils/ScopeBindings'; import { IScopeBindings } from '../utils/ScopeBindings';
import type { ProjectBuilderInitOptions } from '../generator/ProjectBuilder';
export enum FileType { export enum FileType {
CSS = 'css', CSS = 'css',
@ -65,7 +66,10 @@ export interface ICodeStruct extends IBaseCodeStruct {
/** 上下文数据,用来在插件之间共享一些数据 */ /** 上下文数据,用来在插件之间共享一些数据 */
export interface IContextData extends IProjectBuilderOptions { export interface IContextData extends IProjectBuilderOptions {
/** 是否使用了 Ref 的 API (this.$/this.$$) */
/**
* 使 Ref API (this.$/this.$$)
* */
useRefApi?: boolean; useRefApi?: boolean;
/** /**
@ -108,6 +112,7 @@ export interface IModuleBuilder {
* @interface ICodeGenerator * @interface ICodeGenerator
*/ */
export interface ICodeGenerator { export interface ICodeGenerator {
/** /**
* Schema * Schema
* *
@ -138,30 +143,36 @@ export interface IProjectPlugins {
} }
export interface IProjectBuilderOptions { export interface IProjectBuilderOptions {
/** 是否处于严格模式(默认: 否) */
/** 是否处于严格模式 (默认:否) */
inStrictMode?: boolean; inStrictMode?: boolean;
/** /**
* JSExpression * JSExpression
* true * true
* : 如果容忍异 try-catch * try-catch
* catch CustomEvent * catch CustomEvent
*/ */
tolerateEvalErrors?: boolean; tolerateEvalErrors?: boolean;
/** /**
* *
* 默认: *
* *
* window.dispatchEvent(new CustomEvent('lowcode-eval-error', { error, expr })) * window.dispatchEvent(new CustomEvent('lowcode-eval-error', { error, expr }))
* *
* *
* *
* : *
* - error: 异常信息 * - error: 异常信息
* - expr: 求值的表达式 * - expr: 求值的表达式
*/ */
evalErrorsHandler?: string; evalErrorsHandler?: string;
/**
* Hook which is used to customize original options, we can reorder/add/remove plugins/processors
* of the existing solution.
*/
customizeBuilderOptions?(originalOptions: ProjectBuilderInitOptions): ProjectBuilderInitOptions;
} }
export interface IProjectBuilder { export interface IProjectBuilder {
@ -205,7 +216,7 @@ type CompositeTypeGenerator<I, T> =
| BaseGenerator<I, T, CompositeValueGeneratorOptions> | BaseGenerator<I, T, CompositeValueGeneratorOptions>
| Array<BaseGenerator<I, T, CompositeValueGeneratorOptions>>; | Array<BaseGenerator<I, T, CompositeValueGeneratorOptions>>;
export type NodeGenerator<T> = (nodeItem: NodeDataType, scope: IScope) => T; export type NodeGenerator<T> = (nodeItem: IPublicTypeNodeDataType, scope: IScope) => T;
// FIXME: 在新的实现中,添加了第一参数 this: CustomHandlerSet 作为上下文。究其本质 // FIXME: 在新的实现中,添加了第一参数 this: CustomHandlerSet 作为上下文。究其本质
// scopeBindings?: IScopeBindings; // scopeBindings?: IScopeBindings;

View File

@ -1,6 +1,6 @@
import _ from 'lodash'; import _ from 'lodash';
import { pipe } from 'fp-ts/function'; import { pipe } from 'fp-ts/function';
import { IPublicTypeNodeSchema, isNodeSchema, NodeDataType, IPublicTypeCompositeValue } from '@alilc/lowcode-types'; import { IPublicTypeNodeSchema, isNodeSchema, IPublicTypeNodeDataType, IPublicTypeCompositeValue } from '@alilc/lowcode-types';
import { import {
IScope, IScope,
@ -365,7 +365,7 @@ export function generateReactExprInJS(
const handleChildren = (v: string[]) => v.join(''); const handleChildren = (v: string[]) => v.join('');
export function createNodeGenerator(cfg: NodeGeneratorConfig = {}): NodeGenerator<string> { export function createNodeGenerator(cfg: NodeGeneratorConfig = {}): NodeGenerator<string> {
const generateNode = (nodeItem: NodeDataType, scope: IScope): string => { const generateNode = (nodeItem: IPublicTypeNodeDataType, scope: IScope): string => {
if (_.isArray(nodeItem)) { if (_.isArray(nodeItem)) {
const resList = nodeItem.map((n) => generateNode(n, scope)); const resList = nodeItem.map((n) => generateNode(n, scope));
return handleChildren(resList); return handleChildren(resList);
@ -390,7 +390,7 @@ export function createNodeGenerator(cfg: NodeGeneratorConfig = {}): NodeGenerato
return `{${valueStr}}`; return `{${valueStr}}`;
}; };
return (nodeItem: NodeDataType, scope: IScope) => unwrapJsExprQuoteInJsx(generateNode(nodeItem, scope)); return (nodeItem: IPublicTypeNodeDataType, scope: IScope) => unwrapJsExprQuoteInJsx(generateNode(nodeItem, scope));
} }
const defaultReactGeneratorConfig: NodeGeneratorConfig = { const defaultReactGeneratorConfig: NodeGeneratorConfig = {

View File

@ -6,7 +6,6 @@ import { getClosestNode } from '@alilc/lowcode-utils';
import { intl } from '../../locale'; import { intl } from '../../locale';
import { BuiltinSimulatorHost } from '../host'; import { BuiltinSimulatorHost } from '../host';
export class BorderDetectingInstance extends PureComponent<{ export class BorderDetectingInstance extends PureComponent<{
title: IPublicTypeTitleContent; title: IPublicTypeTitleContent;
rect: DOMRect | null; rect: DOMRect | null;
@ -77,11 +76,9 @@ export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> {
const { host } = this.props; const { host } = this.props;
const { current } = this; const { current } = this;
const canHoverHook = current?.componentMeta.getMetadata()?.configure.advanced?.callbacks?.onHoverHook; const canHoverHook = current?.componentMeta.getMetadata()?.configure.advanced?.callbacks?.onHoverHook;
const canHover = (canHoverHook && typeof canHoverHook === 'function') ? canHoverHook(current.internalToShellNode()) : true; const canHover = (canHoverHook && typeof canHoverHook === 'function') ? canHoverHook(current.internalToShellNode()) : true;
if (!canHover || !current || host.viewport.scrolling || host.liveEditing.editing) { if (!canHover || !current || host.viewport.scrolling || host.liveEditing.editing) {
return null; return null;
} }

View File

@ -57,7 +57,7 @@ import {
IPublicEnumTransitionType, IPublicEnumTransitionType,
IPublicEnumDragObjectType, IPublicEnumDragObjectType,
IPublicTypeDragNodeObject, IPublicTypeDragNodeObject,
NodeInstance, IPublicTypeNodeInstance,
IPublicTypeComponentInstance, IPublicTypeComponentInstance,
IPublicTypeLocationChildrenDetail, IPublicTypeLocationChildrenDetail,
IPublicTypeLocationDetailType, IPublicTypeLocationDetailType,
@ -173,7 +173,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
readonly emitter: IEventBus = createModuleEventBus('BuiltinSimulatorHost'); readonly emitter: IEventBus = createModuleEventBus('BuiltinSimulatorHost');
readonly componentsConsumer: ResourceConsumer; readonly componentsConsumer: ResourceConsumer;
readonly injectionConsumer: ResourceConsumer; readonly injectionConsumer: ResourceConsumer;
@ -898,7 +897,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
/** /**
* @see ISimulator * @see ISimulator
*/ */
getComponentInstances(node: Node, context?: NodeInstance): IPublicTypeComponentInstance[] | null { getComponentInstances(node: Node, context?: IPublicTypeNodeInstance): IPublicTypeComponentInstance[] | null {
const docId = node.document.id; const docId = node.document.id;
const instances = this.instancesMap[docId]?.get(node.id) || null; const instances = this.instancesMap[docId]?.get(node.id) || null;
@ -925,7 +924,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
getClosestNodeInstance( getClosestNodeInstance(
from: IPublicTypeComponentInstance, from: IPublicTypeComponentInstance,
specId?: string, specId?: string,
): NodeInstance<IPublicTypeComponentInstance> | null { ): IPublicTypeNodeInstance<IPublicTypeComponentInstance> | null {
return this.renderer?.getClosestNodeInstance(from, specId) || null; return this.renderer?.getClosestNodeInstance(from, specId) || null;
} }
@ -1028,7 +1027,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
/** /**
* DOM simulator * DOM simulator
*/ */
getNodeInstanceFromElement(target: Element | null): NodeInstance<IPublicTypeComponentInstance> | null { getNodeInstanceFromElement(target: Element | null): IPublicTypeNodeInstance<IPublicTypeComponentInstance> | null {
if (!target) { if (!target) {
return null; return null;
} }
@ -1111,14 +1110,14 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
private _sensorAvailable = true; private _sensorAvailable = true;
/** /**
* @see ISensor * @see IPublicModelSensor
*/ */
get sensorAvailable(): boolean { get sensorAvailable(): boolean {
return this._sensorAvailable; return this._sensorAvailable;
} }
/** /**
* @see ISensor * @see IPublicModelSensor
*/ */
fixEvent(e: ILocateEvent): ILocateEvent { fixEvent(e: ILocateEvent): ILocateEvent {
if (e.fixed) { if (e.fixed) {
@ -1149,7 +1148,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
} }
/** /**
* @see ISensor * @see IPublicModelSensor
*/ */
isEnter(e: ILocateEvent): boolean { isEnter(e: ILocateEvent): boolean {
const rect = this.viewport.bounds; const rect = this.viewport.bounds;
@ -1164,7 +1163,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
private sensing = false; private sensing = false;
/** /**
* @see ISensor * @see IPublicModelSensor
*/ */
deactiveSensor() { deactiveSensor() {
this.sensing = false; this.sensing = false;
@ -1174,7 +1173,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
// ========= drag location logic: helper for locate ========== // ========= drag location logic: helper for locate ==========
/** /**
* @see ISensor * @see IPublicModelSensor
*/ */
locate(e: ILocateEvent): any { locate(e: ILocateEvent): any {
const { dragObject } = e; const { dragObject } = e;
@ -1372,7 +1371,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
const document = this.project.currentDocument!; const document = this.project.currentDocument!;
const { currentRoot } = document; const { currentRoot } = document;
let container: INode; let container: INode;
let nodeInstance: NodeInstance<IPublicTypeComponentInstance> | undefined; let nodeInstance: IPublicTypeNodeInstance<IPublicTypeComponentInstance> | undefined;
if (target) { if (target) {
const ref = this.getNodeInstanceFromElement(target); const ref = this.getNodeInstanceFromElement(target);

View File

@ -214,7 +214,6 @@ function selectRange(doc: Document, range: Range) {
} }
} }
function queryPropElement(rootElement: HTMLElement, targetElement: HTMLElement, selector?: string) { function queryPropElement(rootElement: HTMLElement, targetElement: HTMLElement, selector?: string) {
if (!selector) { if (!selector) {
return null; return null;

View File

@ -1,5 +1,5 @@
import { Component } from '../simulator'; import { Component } from '../simulator';
import { IPublicTypeNodeSchema, IPublicTypeComponentInstance, NodeInstance } from '@alilc/lowcode-types'; import { IPublicTypeNodeSchema, IPublicTypeComponentInstance, IPublicTypeNodeInstance } from '@alilc/lowcode-types';
export interface BuiltinSimulatorRenderer { export interface BuiltinSimulatorRenderer {
readonly isSimulatorRenderer: true; readonly isSimulatorRenderer: true;
@ -8,7 +8,7 @@ export interface BuiltinSimulatorRenderer {
getClosestNodeInstance( getClosestNodeInstance(
from: IPublicTypeComponentInstance, from: IPublicTypeComponentInstance,
nodeId?: string, nodeId?: string,
): NodeInstance<IPublicTypeComponentInstance> | null; ): IPublicTypeNodeInstance<IPublicTypeComponentInstance> | null;
findDOMNodes(instance: IPublicTypeComponentInstance): Array<Element | Text> | null; findDOMNodes(instance: IPublicTypeComponentInstance): Array<Element | Text> | null;
getClientRects(element: Element | Text): DOMRect[]; getClientRects(element: Element | Text): DOMRect[];
setNativeSelection(enableFlag: boolean): void; setNativeSelection(enableFlag: boolean): void;

View File

@ -18,23 +18,8 @@ function getDataFromPasteEvent(event: ClipboardEvent) {
}; };
} }
} catch (error) { } catch (error) {
/*
const html = clipboardData.getData('text/html');
if (html !== '') {
// TODO: clear the html
return {
code: '<div dangerouslySetInnerHTML={ __html: html } />',
maps: {},
};
}
*/
// TODO: open the parser implement // TODO: open the parser implement
return { }; return { };
/*
return {
code: clipboardData.getData('text/plain'),
maps: {},
}; */
} }
} }

View File

@ -13,10 +13,12 @@ import {
IShellModelFactory, IShellModelFactory,
IPublicModelDragObject, IPublicModelDragObject,
IPublicModelScrollable, IPublicModelScrollable,
IDesigner,
IPublicModelScroller, IPublicModelScroller,
IPublicTypeLocationData, IPublicTypeLocationData,
IPublicEnumTransformStage, IPublicEnumTransformStage,
IPublicModelDragon,
IPublicModelActiveTracker,
IPublicModelDropLocation,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { megreAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils'; import { megreAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils';
import { Project } from '../project'; import { Project } from '../project';
@ -37,12 +39,14 @@ import { ComponentActions } from '../component-actions';
const logger = new Logger({ level: 'warn', bizName: 'designer' }); const logger = new Logger({ level: 'warn', bizName: 'designer' });
export interface DesignerProps { export interface DesignerProps {
[key: string]: any;
editor: IPublicModelEditor; editor: IPublicModelEditor;
shellModelFactory: IShellModelFactory; shellModelFactory: IShellModelFactory;
className?: string; className?: string;
style?: object; style?: object;
defaultSchema?: IPublicTypeProjectSchema; defaultSchema?: IPublicTypeProjectSchema;
hotkeys?: object; hotkeys?: object;
viewName?: string;
simulatorProps?: object | ((document: DocumentModel) => object); simulatorProps?: object | ((document: DocumentModel) => object);
simulatorComponent?: ComponentType<any>; simulatorComponent?: ComponentType<any>;
dragGhostComponent?: ComponentType<any>; dragGhostComponent?: ComponentType<any>;
@ -53,13 +57,23 @@ export interface DesignerProps {
onDragstart?: (e: ILocateEvent) => void; onDragstart?: (e: ILocateEvent) => void;
onDrag?: (e: ILocateEvent) => void; onDrag?: (e: ILocateEvent) => void;
onDragend?: (e: { dragObject: IPublicModelDragObject; copy: boolean }, loc?: DropLocation) => void; onDragend?: (e: { dragObject: IPublicModelDragObject; copy: boolean }, loc?: DropLocation) => void;
viewName?: string;
[key: string]: any;
} }
export interface IDesigner {
get dragon(): IPublicModelDragon;
get activeTracker(): IPublicModelActiveTracker;
createScroller(scrollable: IPublicModelScrollable): IPublicModelScroller;
/**
* dragon
*/
createLocation(locationData: IPublicTypeLocationData): IPublicModelDropLocation;
}
export class Designer implements IDesigner { export class Designer implements IDesigner {
dragon: Dragon; public dragon: Dragon;
public viewName: string | undefined;
readonly componentActions = new ComponentActions(); readonly componentActions = new ComponentActions();
@ -75,6 +89,24 @@ export class Designer implements IDesigner {
readonly shellModelFactory: IShellModelFactory; readonly shellModelFactory: IShellModelFactory;
private _dropLocation?: DropLocation;
private propsReducers = new Map<IPublicEnumTransformStage, IPublicTypePropsTransducer[]>();
private _lostComponentMetasMap = new Map<string, ComponentMeta>();
private props?: DesignerProps;
private oobxList: OffsetObserver[] = [];
@obx.ref private _componentMetasMap = new Map<string, ComponentMeta>();
@obx.ref private _simulatorComponent?: ComponentType<any>;
@obx.ref private _simulatorProps?: object | ((project: Project) => object);
@obx.ref private _suspensed = false;
get currentDocument() { get currentDocument() {
return this.project.currentDocument; return this.project.currentDocument;
} }
@ -87,8 +119,6 @@ export class Designer implements IDesigner {
return this.currentDocument?.selection; return this.currentDocument?.selection;
} }
viewName: string | undefined;
constructor(props: DesignerProps) { constructor(props: DesignerProps) {
makeObservable(this); makeObservable(this);
const { editor, viewName, shellModelFactory } = props; const { editor, viewName, shellModelFactory } = props;
@ -222,8 +252,6 @@ export class Designer implements IDesigner {
this.editor.eventBus.emit(`designer.${event}`, ...args); this.editor.eventBus.emit(`designer.${event}`, ...args);
} }
private _dropLocation?: DropLocation;
get dropLocation() { get dropLocation() {
return this._dropLocation; return this._dropLocation;
} }
@ -258,8 +286,6 @@ export class Designer implements IDesigner {
return new Scroller(scrollable); return new Scroller(scrollable);
} }
private oobxList: OffsetObserver[] = [];
createOffsetObserver(nodeInstance: INodeSelector): OffsetObserver | null { createOffsetObserver(nodeInstance: INodeSelector): OffsetObserver | null {
const oobx = createOffsetObserver(nodeInstance); const oobx = createOffsetObserver(nodeInstance);
this.clearOobxList(); this.clearOobxList();
@ -330,8 +356,6 @@ export class Designer implements IDesigner {
return { target, index }; return { target, index };
} }
private props?: DesignerProps;
setProps(nextProps: DesignerProps) { setProps(nextProps: DesignerProps) {
const props = this.props ? { ...this.props, ...nextProps } : nextProps; const props = this.props ? { ...this.props, ...nextProps } : nextProps;
if (this.props) { if (this.props) {
@ -409,14 +433,10 @@ export class Designer implements IDesigner {
return this.props?.[key]; return this.props?.[key];
} }
@obx.ref private _simulatorComponent?: ComponentType<any>;
@computed get simulatorComponent(): ComponentType<any> | undefined { @computed get simulatorComponent(): ComponentType<any> | undefined {
return this._simulatorComponent; return this._simulatorComponent;
} }
@obx.ref private _simulatorProps?: object | ((project: Project) => object);
@computed get simulatorProps(): object { @computed get simulatorProps(): object {
if (typeof this._simulatorProps === 'function') { if (typeof this._simulatorProps === 'function') {
return this._simulatorProps(this.project); return this._simulatorProps(this.project);
@ -439,8 +459,6 @@ export class Designer implements IDesigner {
}; };
} }
@obx.ref private _suspensed = false;
get suspensed(): boolean { get suspensed(): boolean {
return this._suspensed; return this._suspensed;
} }
@ -461,16 +479,15 @@ export class Designer implements IDesigner {
this.project.load(schema); this.project.load(schema);
} }
@obx.ref private _componentMetasMap = new Map<string, ComponentMeta>();
private _lostComponentMetasMap = new Map<string, ComponentMeta>();
buildComponentMetasMap(metas: IPublicTypeComponentMetadata[]) { buildComponentMetasMap(metas: IPublicTypeComponentMetadata[]) {
metas.forEach((data) => this.createComponentMeta(data)); metas.forEach((data) => this.createComponentMeta(data));
} }
createComponentMeta(data: IPublicTypeComponentMetadata): ComponentMeta { createComponentMeta(data: IPublicTypeComponentMetadata): ComponentMeta | null {
const key = data.componentName; const key = data.componentName;
if (!key) {
return null;
}
let meta = this._componentMetasMap.get(key); let meta = this._componentMetasMap.get(key);
if (meta) { if (meta) {
meta.setMetadata(data); meta.setMetadata(data);
@ -540,8 +557,6 @@ export class Designer implements IDesigner {
return maps; return maps;
} }
private propsReducers = new Map<IPublicEnumTransformStage, IPublicTypePropsTransducer[]>();
transformProps(props: IPublicTypeCompositeObject | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage) { transformProps(props: IPublicTypeCompositeObject | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage) {
if (Array.isArray(props)) { if (Array.isArray(props)) {
// current not support, make this future // current not support, make this future

View File

@ -2,8 +2,13 @@ import { makeObservable, obx, IEventBus, createModuleEventBus } from '@alilc/low
import { IPublicModelDetecting, IPublicModelNode, IPublicModelDocumentModel } from '@alilc/lowcode-types'; import { IPublicModelDetecting, IPublicModelNode, IPublicModelDocumentModel } from '@alilc/lowcode-types';
const DETECTING_CHANGE_EVENT = 'detectingChange'; const DETECTING_CHANGE_EVENT = 'detectingChange';
export interface IDetecting extends IPublicModelDetecting { export interface IDetecting extends Omit< IPublicModelDetecting, 'capture' | 'release' | 'leave' > {
capture(node: IPublicModelNode | null): void;
release(node: IPublicModelNode | null): void;
leave(document: IPublicModelDocumentModel | undefined): void;
} }
export class Detecting implements IDetecting { export class Detecting implements IDetecting {

View File

@ -8,7 +8,7 @@ import {
IPublicModelNode, IPublicModelNode,
IPublicModelDragon, IPublicModelDragon,
IPublicModelLocateEvent, IPublicModelLocateEvent,
ISensor, IPublicModelSensor,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { setNativeSelection, cursor } from '@alilc/lowcode-utils'; import { setNativeSelection, cursor } from '@alilc/lowcode-utils';
import { Node } from '../document'; import { Node } from '../document';
@ -22,7 +22,7 @@ export interface ILocateEvent extends IPublicModelLocateEvent {
/** /**
* *
*/ */
sensor?: ISensor; sensor?: IPublicModelSensor;
} }
@ -52,6 +52,7 @@ export function isLocateEvent(e: any): e is ILocateEvent {
} }
const SHAKE_DISTANCE = 4; const SHAKE_DISTANCE = 4;
/** /**
* mouse shake check * mouse shake check
*/ */
@ -103,16 +104,16 @@ export interface IDragon extends IPublicModelDragon {
* Drag-on * Drag-on
*/ */
export class Dragon implements IDragon { export class Dragon implements IDragon {
private sensors: ISensor[] = []; private sensors: IPublicModelSensor[] = [];
key = Math.random(); key = Math.random();
/** /**
* current active sensor, * current active sensor,
*/ */
@obx.ref private _activeSensor: ISensor | undefined; @obx.ref private _activeSensor: IPublicModelSensor | undefined;
get activeSensor(): ISensor | undefined { get activeSensor(): IPublicModelSensor | undefined {
return this._activeSensor; return this._activeSensor;
} }
@ -173,7 +174,7 @@ export class Dragon implements IDragon {
const forceCopyState = const forceCopyState =
isDragNodeObject(dragObject) && dragObject.nodes.some((node: Node | IPublicModelNode) => (typeof node.isSlot === 'function' ? node.isSlot() : node.isSlot)); isDragNodeObject(dragObject) && dragObject.nodes.some((node: Node | IPublicModelNode) => (typeof node.isSlot === 'function' ? node.isSlot() : node.isSlot));
const isBoostFromDragAPI = isDragEvent(boostEvent); const isBoostFromDragAPI = isDragEvent(boostEvent);
let lastSensor: ISensor | undefined; let lastSensor: IPublicModelSensor | undefined;
this._dragging = false; this._dragging = false;
@ -462,7 +463,7 @@ export class Dragon implements IDragon {
/* istanbul ignore next */ /* istanbul ignore next */
const chooseSensor = (e: ILocateEvent) => { const chooseSensor = (e: ILocateEvent) => {
// this.sensors will change on dragstart // this.sensors will change on dragstart
const sensors: ISensor[] = this.sensors.concat(masterSensors as ISensor[]); const sensors: IPublicModelSensor[] = this.sensors.concat(masterSensors as IPublicModelSensor[]);
let sensor = let sensor =
e.sensor && e.sensor.isEnter(e) e.sensor && e.sensor.isEnter(e)
? e.sensor ? e.sensor

View File

@ -8,25 +8,24 @@ import {
IPublicTypeDragNodeObject, IPublicTypeDragNodeObject,
IPublicTypeDragNodeDataObject, IPublicTypeDragNodeDataObject,
IPublicModelDocumentModel, IPublicModelDocumentModel,
IPublicModelSelection,
IPublicModelHistory, IPublicModelHistory,
IPublicModelModalNodesManager, IPublicModelModalNodesManager,
IPublicModelNode, IPublicModelNode,
IPublicApiProject, IPublicApiProject,
IPublicModelDropLocation, IPublicModelDropLocation,
IPublicEnumTransformStage, IPublicEnumTransformStage,
IPublicOnChangeOptions, IPublicTypeOnChangeOptions,
EDITOR_EVENT,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { Project } from '../project'; import { Project } from '../project';
import { ISimulatorHost } from '../simulator'; import { ISimulatorHost } from '../simulator';
import { ComponentMeta } from '../component-meta'; import { ComponentMeta } from '../component-meta';
import { IDropLocation, Designer } from '../designer'; import { IDropLocation, Designer } from '../designer';
import { Node, insertChildren, insertChild, isNode, RootNode, INode } from './node/node'; import { Node, insertChildren, insertChild, isNode, RootNode, INode } from './node/node';
import { Selection } from './selection'; import { Selection, ISelection } from './selection';
import { History } from './history'; import { History } from './history';
import { ModalNodesManager } from './node'; import { ModalNodesManager } from './node';
import { uniqueId, isPlainObject, compatStage, isJSExpression, isDOMText, isNodeSchema, isDragNodeObject, isDragNodeDataObject } from '@alilc/lowcode-utils'; import { uniqueId, isPlainObject, compatStage, isJSExpression, isDOMText, isNodeSchema, isDragNodeObject, isDragNodeDataObject } from '@alilc/lowcode-utils';
import { EDITOR_EVENT } from '../types';
export type GetDataType<T, NodeType> = T extends undefined export type GetDataType<T, NodeType> = T extends undefined
? NodeType extends { ? NodeType extends {
@ -35,8 +34,20 @@ export type GetDataType<T, NodeType> = T extends undefined
? R ? R
: any : any
: T; : T;
export interface IDocumentModel extends IPublicModelDocumentModel {
export interface IDocumentModel extends Omit< IPublicModelDocumentModel, 'selection' > {
readonly designer: Designer;
/**
*
*/
readonly selection: ISelection;
/**
* id
*/
getNode(id: string): INode | null;
} }
export class DocumentModel implements IDocumentModel { export class DocumentModel implements IDocumentModel {
@ -53,7 +64,7 @@ export class DocumentModel implements IDocumentModel {
/** /**
* *
*/ */
readonly selection: IPublicModelSelection = new Selection(this); readonly selection: ISelection = new Selection(this);
/** /**
* *
@ -116,16 +127,85 @@ export class DocumentModel implements IDocumentModel {
@obx.ref private _drillDownNode: Node | null = null; @obx.ref private _drillDownNode: Node | null = null;
drillDown(node: Node | null) {
this._drillDownNode = node;
}
private _modalNode?: INode; private _modalNode?: INode;
private _blank?: boolean; private _blank?: boolean;
private inited = false; private inited = false;
@obx.shallow private willPurgeSpace: Node[] = [];
get modalNode() {
return this._modalNode;
}
get currentRoot() {
return this.modalNode || this.focusNode;
}
@obx.shallow private activeNodes?: Node[];
@obx.ref private _dropLocation: IDropLocation | null = null;
set dropLocation(loc: IPublicModelDropLocation | null) {
this._dropLocation = loc;
// pub event
this.designer.editor.eventBus.emit(
'document.dropLocation.changed',
{ document: this, location: loc },
);
}
/**
*
*/
get dropLocation() {
return this._dropLocation;
}
/**
* schema
*/
get schema(): IPublicTypeRootSchema {
return this.rootNode?.schema as any;
}
@obx.ref private _opened = false;
@obx.ref private _suspensed = false;
/**
*
*/
get suspensed(): boolean {
return this._suspensed || !this._opened;
}
/**
* suspensed
*/
get active(): boolean {
return !this._suspensed;
}
/**
* @deprecated
*/
get actived(): boolean {
return this.active;
}
/**
*
*/
get opened() {
return this._opened;
}
get root() {
return this.rootNode;
}
constructor(project: Project, schema?: IPublicTypeRootSchema) { constructor(project: Project, schema?: IPublicTypeRootSchema) {
makeObservable(this); makeObservable(this);
this.project = project; this.project = project;
@ -160,6 +240,10 @@ export class DocumentModel implements IDocumentModel {
this.inited = true; this.inited = true;
} }
drillDown(node: Node | null) {
this._drillDownNode = node;
}
onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): () => void { onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): () => void {
this.designer.editor?.eventBus.on(EDITOR_EVENT.NODE_CHILDREN_CHANGE, fn); this.designer.editor?.eventBus.on(EDITOR_EVENT.NODE_CHILDREN_CHANGE, fn);
@ -168,7 +252,7 @@ export class DocumentModel implements IDocumentModel {
}; };
} }
onChangeNodeChildren(fn: (info: IPublicOnChangeOptions) => void): () => void { onChangeNodeChildren(fn: (info: IPublicTypeOnChangeOptions) => void): () => void {
this.designer.editor?.eventBus.on(EDITOR_EVENT.NODE_VISIBLE_CHANGE, fn); this.designer.editor?.eventBus.on(EDITOR_EVENT.NODE_VISIBLE_CHANGE, fn);
return () => { return () => {
@ -176,16 +260,6 @@ export class DocumentModel implements IDocumentModel {
}; };
} }
@obx.shallow private willPurgeSpace: Node[] = [];
get modalNode() {
return this._modalNode;
}
get currentRoot() {
return this.modalNode || this.focusNode;
}
addWillPurge(node: Node) { addWillPurge(node: Node) {
this.willPurgeSpace.push(node); this.willPurgeSpace.push(node);
} }
@ -202,7 +276,7 @@ export class DocumentModel implements IDocumentModel {
} }
/** /**
* id * id
*/ */
nextId(possibleId: string | undefined) { nextId(possibleId: string | undefined) {
let id = possibleId; let id = possibleId;
@ -216,7 +290,7 @@ export class DocumentModel implements IDocumentModel {
/** /**
* id * id
*/ */
getNode(id: string): Node | null { getNode(id: string): INode | null {
return this._nodesMap.get(id) || null; return this._nodesMap.get(id) || null;
} }
@ -235,8 +309,6 @@ export class DocumentModel implements IDocumentModel {
return node ? !node.isPurged : false; return node ? !node.isPurged : false;
} }
@obx.shallow private activeNodes?: Node[];
/** /**
* schema * schema
*/ */
@ -336,25 +408,6 @@ export class DocumentModel implements IDocumentModel {
this._nodesMap.delete(node.id); this._nodesMap.delete(node.id);
} }
@obx.ref private _dropLocation: IDropLocation | null = null;
set dropLocation(loc: IPublicModelDropLocation | null) {
this._dropLocation = loc;
// pub event
this.designer.editor.eventBus.emit(
'document.dropLocation.changed',
{ document: this, location: loc },
);
}
/**
*
*/
get dropLocation() {
return this._dropLocation;
}
/** /**
* *
*/ */
@ -377,13 +430,6 @@ export class DocumentModel implements IDocumentModel {
return null; return null;
} }
/**
* schema
*/
get schema(): IPublicTypeRootSchema {
return this.rootNode?.schema as any;
}
@action @action
import(schema: IPublicTypeRootSchema, checkId = false) { import(schema: IPublicTypeRootSchema, checkId = false) {
const drillDownNodeId = this._drillDownNode?.id; const drillDownNodeId = this._drillDownNode?.id;
@ -448,38 +494,6 @@ export class DocumentModel implements IDocumentModel {
); );
} }
@obx.ref private _opened = false;
@obx.ref private _suspensed = false;
/**
*
*/
get suspensed(): boolean {
return this._suspensed || !this._opened;
}
/**
* suspensed
*/
get active(): boolean {
return !this._suspensed;
}
/**
* @deprecated
*/
get actived(): boolean {
return this.active;
}
/**
*
*/
get opened() {
return this._opened;
}
/** /**
* *
* tab * tab
@ -616,10 +630,6 @@ export class DocumentModel implements IDocumentModel {
return this.history; return this.history;
} }
get root() {
return this.rootNode;
}
/** /**
* @deprecated * @deprecated
*/ */

View File

@ -1,5 +1,8 @@
import { reaction, untracked, globalContext, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { reaction, untracked, globalContext, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
import { IPublicTypeNodeSchema, IPublicModelHistory } from '@alilc/lowcode-types'; import { IPublicTypeNodeSchema, IPublicModelHistory } from '@alilc/lowcode-types';
import { Logger } from '@alilc/lowcode-utils';
const logger = new Logger({ level: 'warn', bizName: 'history' });
export interface Serialization<K = IPublicTypeNodeSchema, T = string> { export interface Serialization<K = IPublicTypeNodeSchema, T = string> {
serialize(data: K): T; serialize(data: K): T;
@ -30,11 +33,15 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
}, },
}; };
setSerialization(serialization: Serialization<T, string>) { get hotData() {
this.currentSerialization = serialization; return this.session.data;
} }
constructor(dataFn: () => T | null, private redoer: (data: T) => void, private timeGap: number = 1000) { constructor(
dataFn: () => T | null,
private redoer: (data: T) => void,
private timeGap: number = 1000,
) {
this.session = new Session(0, null, this.timeGap); this.session = new Session(0, null, this.timeGap);
this.records = [this.session]; this.records = [this.session];
@ -68,8 +75,8 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
}, { fireImmediately: true }); }, { fireImmediately: true });
} }
get hotData() { setSerialization(serialization: Serialization<T, string>) {
return this.session.data; this.currentSerialization = serialization;
} }
isSavePoint(): boolean { isSavePoint(): boolean {
@ -84,16 +91,18 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
this.asleep = false; this.asleep = false;
} }
go(cursor: number) { go(originalCursor: number) {
this.session.end(); this.session.end();
const currentCursor = this.session.cursor; let cursor = originalCursor;
cursor = +cursor; cursor = +cursor;
if (cursor < 0) { if (cursor < 0) {
cursor = 0; cursor = 0;
} else if (cursor >= this.records.length) { } else if (cursor >= this.records.length) {
cursor = this.records.length - 1; cursor = this.records.length - 1;
} }
const currentCursor = this.session.cursor;
if (cursor === currentCursor) { if (cursor === currentCursor) {
return; return;
} }
@ -106,7 +115,7 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
this.redoer(this.currentSerialization.unserialize(hotData)); this.redoer(this.currentSerialization.unserialize(hotData));
this.emitter.emit('cursor', hotData); this.emitter.emit('cursor', hotData);
} catch (e) /* istanbul ignore next */ { } catch (e) /* istanbul ignore next */ {
console.error(e); logger.error(e);
} }
this.wakeup(); this.wakeup();
@ -174,6 +183,7 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
} }
return state; return state;
} }
/** /**
* state * state
* @param func * @param func
@ -209,6 +219,7 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
this.emitter.removeAllListeners(); this.emitter.removeAllListeners();
this.records = []; this.records = [];
} }
/** /**
* *
* @deprecated * @deprecated

View File

@ -6,30 +6,33 @@ import {
IPublicTypePropsList, IPublicTypePropsList,
IPublicTypeNodeData, IPublicTypeNodeData,
IPublicTypeI18nData, IPublicTypeI18nData,
SlotSchema, IPublicTypeSlotSchema,
IPublicTypePageSchema, IPublicTypePageSchema,
IPublicTypeComponentSchema, IPublicTypeComponentSchema,
NodeStatus,
IPublicTypeCompositeValue, IPublicTypeCompositeValue,
GlobalEvent, GlobalEvent,
IPublicTypeComponentAction, IPublicTypeComponentAction,
IPublicModelNode, IPublicModelNode,
IPublicModelExclusiveGroup, IPublicModelExclusiveGroup,
IPublicEnumTransformStage, IPublicEnumTransformStage,
EDITOR_EVENT,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { compatStage, isDOMText, isJSExpression } from '@alilc/lowcode-utils'; import { compatStage, isDOMText, isJSExpression } from '@alilc/lowcode-utils';
import { SettingTopEntry } from '@alilc/lowcode-designer'; import { SettingTopEntry } from '@alilc/lowcode-designer';
import { Props, getConvertedExtraKey } from './props/props'; import { Props, getConvertedExtraKey } from './props/props';
import { DocumentModel } from '../document-model'; import { DocumentModel, IDocumentModel } from '../document-model';
import { NodeChildren, INodeChildren } from './node-children'; import { NodeChildren, INodeChildren } from './node-children';
import { Prop } from './props/prop'; import { Prop } from './props/prop';
import { ComponentMeta } from '../../component-meta'; import { ComponentMeta } from '../../component-meta';
import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group'; import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group';
import { includeSlot, removeSlot } from '../../utils/slot'; import { includeSlot, removeSlot } from '../../utils/slot';
import { foreachReverse } from '../../utils/tree'; import { foreachReverse } from '../../utils/tree';
import { NodeRemoveOptions } from '../../types'; import { NodeRemoveOptions, EDITOR_EVENT } from '../../types';
export interface NodeStatus {
locking: boolean;
pseudo: boolean;
inPlaceEditing: boolean;
}
export interface INode extends IPublicModelNode { export interface INode extends IPublicModelNode {
@ -52,6 +55,21 @@ export interface INode extends IPublicModelNode {
unlinkSlot(slotNode: Node): void; unlinkSlot(slotNode: Node): void;
didDropOut(dragment: Node): void; didDropOut(dragment: Node): void;
/**
* schema
*/
export(stage: IPublicEnumTransformStage, options?: any): IPublicTypeNodeSchema;
get document(): IDocumentModel;
emitPropChange(val: IPublicTypePropChangeOptions): void;
import(data: IPublicTypeNodeSchema, checkId?: boolean): void;
internalSetSlotFor(slotFor: Prop | null | undefined): void;
addSlot(slotNode: INode): void;
} }
/** /**
@ -186,7 +204,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
isInited = false; isInited = false;
constructor(readonly document: DocumentModel, nodeSchema: Schema, options: any = {}) { constructor(readonly document: IDocumentModel, nodeSchema: Schema, options: any = {}) {
makeObservable(this); makeObservable(this);
const { componentName, id, children, props, ...extras } = nodeSchema; const { componentName, id, children, props, ...extras } = nodeSchema;
this.id = document.nextId(id); this.id = document.nextId(id);
@ -518,7 +536,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
return this.props.export(IPublicEnumTransformStage.Serilize).props || null; return this.props.export(IPublicEnumTransformStage.Serilize).props || null;
} }
@obx.shallow _slots: Node[] = []; @obx.shallow _slots: INode[] = [];
hasSlots() { hasSlots() {
return this._slots.length > 0; return this._slots.length > 0;
@ -882,7 +900,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
return false; return false;
} }
addSlot(slotNode: Node) { addSlot(slotNode: INode) {
const slotName = slotNode?.getExtraProp('name')?.getAsString(); const slotName = slotNode?.getExtraProp('name')?.getAsString();
// 一个组件下的所有 slot相同 slotName 的 slot 应该是唯一的 // 一个组件下的所有 slot相同 slotName 的 slot 应该是唯一的
if (includeSlot(this, slotName)) { if (includeSlot(this, slotName)) {
@ -1235,14 +1253,13 @@ function ensureNode(node: any, document: DocumentModel): Node {
return nodeInstance; return nodeInstance;
} }
export interface LeafNode extends Node { export interface LeafNode extends Node {
readonly children: null; readonly children: null;
} }
export type IPublicTypePropChangeOptions = Omit<GlobalEvent.Node.Prop.ChangeOptions, 'node'>; export type IPublicTypePropChangeOptions = Omit<GlobalEvent.Node.Prop.ChangeOptions, 'node'>;
export type SlotNode = Node<SlotSchema>; export type SlotNode = Node<IPublicTypeSlotSchema>;
export type PageNode = Node<IPublicTypePageSchema>; export type PageNode = Node<IPublicTypePageSchema>;
export type ComponentNode = Node<IPublicTypeComponentSchema>; export type ComponentNode = Node<IPublicTypeComponentSchema>;
export type RootNode = PageNode | ComponentNode; export type RootNode = PageNode | ComponentNode;

View File

@ -1,9 +1,9 @@
import { untracked, computed, obx, engineConfig, action, makeObservable, mobx, runInAction } from '@alilc/lowcode-editor-core'; import { untracked, computed, obx, engineConfig, action, makeObservable, mobx, runInAction } from '@alilc/lowcode-editor-core';
import { IPublicTypeCompositeValue, GlobalEvent, IPublicTypeJSSlot, SlotSchema, IPublicEnumTransformStage } from '@alilc/lowcode-types'; import { IPublicTypeCompositeValue, GlobalEvent, IPublicTypeJSSlot, IPublicTypeSlotSchema, IPublicEnumTransformStage, IPublicModelProp } from '@alilc/lowcode-types';
import { uniqueId, isPlainObject, hasOwnProperty, compatStage, isJSExpression, isJSSlot } from '@alilc/lowcode-utils'; import { uniqueId, isPlainObject, hasOwnProperty, compatStage, isJSExpression, isJSSlot } from '@alilc/lowcode-utils';
import { valueToSource } from './value-to-source'; import { valueToSource } from './value-to-source';
import { Props } from './props'; import { Props, IProps, IPropParent } from './props';
import { SlotNode, Node } from '../node'; import { SlotNode, INode } from '../node';
// import { TransformStage } from '../transform-stage'; // import { TransformStage } from '../transform-stage';
const { set: mobxSet, isObservableArray } = mobx; const { set: mobxSet, isObservableArray } = mobx;
@ -11,19 +11,25 @@ export const UNSET = Symbol.for('unset');
// eslint-disable-next-line no-redeclare // eslint-disable-next-line no-redeclare
export type UNSET = typeof UNSET; export type UNSET = typeof UNSET;
export interface IPropParent { export interface IProp extends Omit<IPublicModelProp, 'exportSchema' | 'node'> {
delete(prop: Prop): void;
readonly props: Props; readonly props: Props;
readonly owner: Node;
readonly path: string[]; readonly owner: INode;
delete(prop: Prop): void;
export(stage: IPublicEnumTransformStage): IPublicTypeCompositeValue;
getNode(): INode;
} }
export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot'; export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot';
export class Prop implements IPropParent { export class Prop implements IProp, IPropParent {
readonly isProp = true; readonly isProp = true;
readonly owner: Node; readonly owner: INode;
/** /**
* *
@ -39,6 +45,150 @@ export class Prop implements IPropParent {
readonly options: any; readonly options: any;
readonly id = uniqueId('prop$');
@obx.ref private _type: ValueTypes = 'unset';
/**
*
*/
get type(): ValueTypes {
return this._type;
}
@obx private _value: any = UNSET;
/**
*
*/
@computed get value(): IPublicTypeCompositeValue | UNSET {
return this.export(IPublicEnumTransformStage.Serilize);
}
private _code: string | null = null;
/**
*
*/
@computed get code() {
if (isJSExpression(this.value)) {
return this.value.value;
}
// todo: JSFunction ...
if (this.type === 'slot') {
return JSON.stringify(this._slotNode!.export(IPublicEnumTransformStage.Save));
}
return this._code != null ? this._code : JSON.stringify(this.value);
}
/**
*
*/
set code(code: string) {
if (isJSExpression(this._value)) {
this.setValue({
...this._value,
value: code,
});
this._code = code;
return;
}
try {
const v = JSON.parse(code);
this.setValue(v);
this._code = code;
return;
} catch (e) {
// ignore
}
this.setValue({
type: 'JSExpression',
value: code,
mock: this._value,
});
this._code = code;
}
private _slotNode?: INode;
get slotNode(): INode | undefined | null {
return this._slotNode;
}
@obx.shallow private _items: Prop[] | null = null;
@obx.shallow private _maps: Map<string | number, Prop> | null = null;
/**
* _maps Prop
* Prop#_value { a: 1 } setValue({ a: 2 }) Prop
* mobx reaction observer
* reaction Prop(a) _value Prop(a) _value
*/
private _prevMaps: Map<string | number, Prop> | null = null;
/**
* items maps
*/
private get items(): Prop[] | null {
if (this._items) return this._items;
return runInAction(() => {
let items: Prop[] | null = null;
if (this._type === 'list') {
const data = this._value;
data.forEach((item: any, idx: number) => {
items = items || [];
items.push(new Prop(this, item, idx));
});
this._maps = null;
} else if (this._type === 'map') {
const data = this._value;
const maps = new Map<string, Prop>();
const keys = Object.keys(data);
for (const key of keys) {
let prop: Prop;
if (this._prevMaps?.has(key)) {
prop = this._prevMaps.get(key)!;
prop.setValue(data[key]);
} else {
prop = new Prop(this, data[key], key);
}
items = items || [];
items.push(prop);
maps.set(key, prop);
}
this._maps = maps;
} else {
items = null;
this._maps = null;
}
this._items = items;
return this._items;
});
}
@computed private get maps(): Map<string | number, Prop> | null {
if (!this.items) {
return null;
}
return this._maps;
}
get path(): string[] {
return (this.parent.path || []).concat(this.key as string);
}
/**
*
*/
get size(): number {
return this.items?.length || 0;
}
private purged = false;
constructor( constructor(
public parent: IPropParent, public parent: IPropParent,
value: IPublicTypeCompositeValue | UNSET = UNSET, value: IPublicTypeCompositeValue | UNSET = UNSET,
@ -88,26 +238,6 @@ export class Prop implements IPropParent {
this.get(propName, false)?.unset(); this.get(propName, false)?.unset();
} }
readonly id = uniqueId('prop$');
@obx.ref private _type: ValueTypes = 'unset';
/**
*
*/
get type(): ValueTypes {
return this._type;
}
@obx private _value: any = UNSET;
/**
*
*/
@computed get value(): IPublicTypeCompositeValue | UNSET {
return this.export(IPublicEnumTransformStage.Serilize);
}
export(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Save): IPublicTypeCompositeValue { export(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Save): IPublicTypeCompositeValue {
stage = compatStage(stage); stage = compatStage(stage);
const type = this._type; const type = this._type;
@ -180,52 +310,6 @@ export class Prop implements IPropParent {
} }
} }
private _code: string | null = null;
/**
*
*/
@computed get code() {
if (isJSExpression(this.value)) {
return this.value.value;
}
// todo: JSFunction ...
if (this.type === 'slot') {
return JSON.stringify(this._slotNode!.export(IPublicEnumTransformStage.Save));
}
return this._code != null ? this._code : JSON.stringify(this.value);
}
/**
*
*/
set code(code: string) {
if (isJSExpression(this._value)) {
this.setValue({
...this._value,
value: code,
});
this._code = code;
return;
}
try {
const v = JSON.parse(code);
this.setValue(v);
this._code = code;
return;
} catch (e) {
// ignore
}
this.setValue({
type: 'JSExpression',
value: code,
mock: this._value,
});
this._code = code;
}
getAsString(): string { getAsString(): string {
if (this.type === 'literal') { if (this.type === 'literal') {
return this._value ? String(this._value) : ''; return this._value ? String(this._value) : '';
@ -305,19 +389,13 @@ export class Prop implements IPropParent {
} }
} }
private _slotNode?: SlotNode;
get slotNode() {
return this._slotNode;
}
@action @action
setAsSlot(data: IPublicTypeJSSlot) { setAsSlot(data: IPublicTypeJSSlot) {
this._type = 'slot'; this._type = 'slot';
let slotSchema: SlotSchema; let slotSchema: IPublicTypeSlotSchema;
// 当 data.value 的结构为 { componentName: 'Slot' } 时,复用部分 slotSchema 数据 // 当 data.value 的结构为 { componentName: 'Slot' } 时,复用部分 slotSchema 数据
if ((isPlainObject(data.value) && data.value?.componentName === 'Slot')) { if ((isPlainObject(data.value) && data.value?.componentName === 'Slot')) {
const value = data.value as SlotSchema; const value = data.value as IPublicTypeSlotSchema;
slotSchema = { slotSchema = {
componentName: 'Slot', componentName: 'Slot',
title: value.title || value.props?.slotTitle, title: value.title || value.props?.slotTitle,
@ -325,7 +403,7 @@ export class Prop implements IPropParent {
name: value.name || value.props?.slotName, name: value.name || value.props?.slotName,
params: value.params || value.props?.slotParams, params: value.params || value.props?.slotParams,
children: data.value, children: data.value,
} as SlotSchema; } as IPublicTypeSlotSchema;
} else { } else {
slotSchema = { slotSchema = {
componentName: 'Slot', componentName: 'Slot',
@ -342,8 +420,10 @@ export class Prop implements IPropParent {
} else { } else {
const { owner } = this.props; const { owner } = this.props;
this._slotNode = owner.document.createNode<SlotNode>(slotSchema); this._slotNode = owner.document.createNode<SlotNode>(slotSchema);
owner.addSlot(this._slotNode); if (this._slotNode) {
this._slotNode.internalSetSlotFor(this); owner.addSlot(this._slotNode);
this._slotNode.internalSetSlotFor(this);
}
} }
} }
@ -389,69 +469,6 @@ export class Prop implements IPropParent {
return this.code === other.code ? 0 : 2; return this.code === other.code ? 0 : 2;
} }
@obx.shallow private _items: Prop[] | null = null;
@obx.shallow private _maps: Map<string | number, Prop> | null = null;
/**
* _maps Prop
* Prop#_value { a: 1 } setValue({ a: 2 }) Prop
* mobx reaction observer
* reaction Prop(a) _value Prop(a) _value
*/
private _prevMaps: Map<string | number, Prop> | null = null;
get path(): string[] {
return (this.parent.path || []).concat(this.key as string);
}
/**
* items maps
*/
private get items(): Prop[] | null {
if (this._items) return this._items;
return runInAction(() => {
let items: Prop[] | null = null;
if (this._type === 'list') {
const data = this._value;
data.forEach((item: any, idx: number) => {
items = items || [];
items.push(new Prop(this, item, idx));
});
this._maps = null;
} else if (this._type === 'map') {
const data = this._value;
const maps = new Map<string, Prop>();
const keys = Object.keys(data);
for (const key of keys) {
let prop: Prop;
if (this._prevMaps?.has(key)) {
prop = this._prevMaps.get(key)!;
prop.setValue(data[key]);
} else {
prop = new Prop(this, data[key], key);
}
items = items || [];
items.push(prop);
maps.set(key, prop);
}
this._maps = maps;
} else {
items = null;
this._maps = null;
}
this._items = items;
return this._items;
});
}
@computed private get maps(): Map<string | number, Prop> | null {
if (!this.items) {
return null;
}
return this._maps;
}
/** /**
* *
* @param createIfNone * @param createIfNone
@ -544,13 +561,6 @@ export class Prop implements IPropParent {
} }
} }
/**
*
*/
get size(): number {
return this.items?.length || 0;
}
/** /**
* *
* *
@ -640,8 +650,6 @@ export class Prop implements IPropParent {
return hasOwnProperty(this._value, key); return hasOwnProperty(this._value, key);
} }
private purged = false;
/** /**
* *
*/ */

View File

@ -1,8 +1,8 @@
import { computed, makeObservable, obx, action } from '@alilc/lowcode-editor-core'; import { computed, makeObservable, obx, action } from '@alilc/lowcode-editor-core';
import { IPublicTypePropsMap, IPublicTypePropsList, IPublicTypeCompositeValue, IPublicEnumTransformStage } from '@alilc/lowcode-types'; import { IPublicTypePropsMap, IPublicTypePropsList, IPublicTypeCompositeValue, IPublicEnumTransformStage, IPublicModelProps } from '@alilc/lowcode-types';
import { uniqueId, compatStage } from '@alilc/lowcode-utils'; import { uniqueId, compatStage } from '@alilc/lowcode-utils';
import { Prop, IPropParent, UNSET } from './prop'; import { Prop, IProp, UNSET } from './prop';
import { Node } from '../node'; import { INode, Node } from '../node';
// import { TransformStage } from '../transform-stage'; // import { TransformStage } from '../transform-stage';
interface ExtrasObject { interface ExtrasObject {
@ -23,7 +23,30 @@ export function getConvertedExtraKey(key: string): string {
export function getOriginalExtraKey(key: string): string { export function getOriginalExtraKey(key: string): string {
return key.replace(new RegExp(`${EXTRA_KEY_PREFIX}`, 'g'), ''); return key.replace(new RegExp(`${EXTRA_KEY_PREFIX}`, 'g'), '');
} }
export class Props implements IPropParent {
export interface IPropParent {
readonly props: Props;
readonly owner: INode;
get path(): string[];
delete(prop: Prop): void;
}
export interface IProps extends Omit<IPublicModelProps, 'getProp' | 'getExtraProp' | 'getExtraPropValue' | 'setExtraPropValue' | 'node'> {
/**
* props node
*/
getNode(): INode;
getProp(path: string): IProp | null;
}
export class Props implements IProps, IPropParent {
readonly id = uniqueId('props'); readonly id = uniqueId('props');
@obx.shallow private items: Prop[] = []; @obx.shallow private items: Prop[] = [];
@ -46,7 +69,7 @@ export class Props implements IPropParent {
return this; return this;
} }
readonly owner: Node; readonly owner: INode;
/** /**
* *
@ -57,7 +80,9 @@ export class Props implements IPropParent {
@obx type: 'map' | 'list' = 'map'; @obx type: 'map' | 'list' = 'map';
constructor(owner: Node, value?: IPublicTypePropsMap | IPublicTypePropsList | null, extras?: ExtrasObject) { private purged = false;
constructor(owner: INode, value?: IPublicTypePropsMap | IPublicTypePropsList | null, extras?: ExtrasObject) {
makeObservable(this); makeObservable(this);
this.owner = owner; this.owner = owner;
if (Array.isArray(value)) { if (Array.isArray(value)) {
@ -196,7 +221,7 @@ export class Props implements IPropParent {
} }
/** /**
* , *
* @param createIfNone * @param createIfNone
*/ */
@action @action
@ -323,8 +348,6 @@ export class Props implements IPropParent {
}); });
} }
private purged = false;
/** /**
* *
*/ */

View File

@ -1,10 +1,20 @@
import { obx, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { obx, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
import { Node, comparePosition, PositionNO } from './node/node'; import { Node, INode, comparePosition, PositionNO } from './node/node';
import { DocumentModel } from './document-model'; import { DocumentModel } from './document-model';
import { IPublicModelSelection } from '@alilc/lowcode-types'; import { IPublicModelSelection } from '@alilc/lowcode-types';
export interface ISelection extends IPublicModelSelection { export interface ISelection extends Omit< IPublicModelSelection, 'getNodes' | 'getTopNodes' > {
/**
*
* @returns
*/
getNodes(): INode[];
/**
*
*/
getTopNodes(includeRoot?: boolean): INode[];
} }
export class Selection implements ISelection { export class Selection implements ISelection {

View File

@ -1,5 +1,5 @@
import { ComponentType } from 'react'; import { ComponentType } from 'react';
import { IPublicTypeComponentMetadata, IPublicTypeNodeSchema, IPublicModelScrollable, IPublicTypeComponentInstance, ISensor, NodeInstance } from '@alilc/lowcode-types'; import { IPublicTypeComponentMetadata, IPublicTypeNodeSchema, IPublicModelScrollable, IPublicTypeComponentInstance, IPublicModelSensor, IPublicTypeNodeInstance } from '@alilc/lowcode-types';
import { Point, ScrollTarget, ILocateEvent } from './designer'; import { Point, ScrollTarget, ILocateEvent } from './designer';
import { BuiltinSimulatorRenderer } from './builtin-simulator/renderer'; import { BuiltinSimulatorRenderer } from './builtin-simulator/renderer';
import { Node, INode } from './document'; import { Node, INode } from './document';
@ -11,6 +11,7 @@ export const AutoFit = '100%';
export interface IScrollable extends IPublicModelScrollable { export interface IScrollable extends IPublicModelScrollable {
} }
export interface IViewport extends IScrollable { export interface IViewport extends IScrollable {
/** /**
* *
*/ */
@ -32,22 +33,27 @@ export interface IViewport extends IScrollable {
* *
*/ */
readonly bounds: DOMRect; readonly bounds: DOMRect;
/** /**
* *
*/ */
readonly contentBounds: DOMRect; readonly contentBounds: DOMRect;
/** /**
* *
*/ */
readonly scrollTarget?: ScrollTarget; readonly scrollTarget?: ScrollTarget;
/** /**
* *
*/ */
readonly scrolling: boolean; readonly scrolling: boolean;
/** /**
* X * X
*/ */
readonly scrollX: number; readonly scrollX: number;
/** /**
* Y * Y
*/ */
@ -72,8 +78,9 @@ export interface DropContainer {
/** /**
* *
*/ */
export interface ISimulatorHost<P = object> extends ISensor { export interface ISimulatorHost<P = object> extends IPublicModelSensor {
readonly isSimulator: true; readonly isSimulator: true;
/** /**
* *
*/ */
@ -104,14 +111,17 @@ export interface ISimulatorHost<P = object> extends ISensor {
* *
*/ */
setNativeSelection(enableFlag: boolean): void; setNativeSelection(enableFlag: boolean): void;
/** /**
* *
*/ */
setDraggingState(state: boolean): void; setDraggingState(state: boolean): void;
/** /**
* *
*/ */
setCopyState(state: boolean): void; setCopyState(state: boolean): void;
/** /**
* *
*/ */
@ -128,24 +138,28 @@ export interface ISimulatorHost<P = object> extends ISensor {
* *
*/ */
generateComponentMetadata(componentName: string): IPublicTypeComponentMetadata; generateComponentMetadata(componentName: string): IPublicTypeComponentMetadata;
/** /**
* *
*/ */
getComponent(componentName: string): Component | any; getComponent(componentName: string): Component | any;
/** /**
* *
*/ */
getComponentInstances(node: Node): IPublicTypeComponentInstance[] | null; getComponentInstances(node: Node): IPublicTypeComponentInstance[] | null;
/** /**
* schema * schema
*/ */
createComponent(schema: IPublicTypeNodeSchema): Component | null; createComponent(schema: IPublicTypeNodeSchema): Component | null;
/** /**
* *
*/ */
getComponentContext(node: Node): object | null; getComponentContext(node: Node): object | null;
getClosestNodeInstance(from: IPublicTypeComponentInstance, specId?: string): NodeInstance | null; getClosestNodeInstance(from: IPublicTypeComponentInstance, specId?: string): IPublicTypeNodeInstance | null;
computeRect(node: Node): DOMRect | null; computeRect(node: Node): DOMRect | null;
@ -158,6 +172,7 @@ export interface ISimulatorHost<P = object> extends ISensor {
postEvent(evtName: string, evtData: any): void; postEvent(evtName: string, evtData: any): void;
rerender(): void; rerender(): void;
/** /**
* *
*/ */

View File

@ -11,4 +11,10 @@ export const utils = {
getNodeSchemaById, getNodeSchemaById,
}; };
export enum EDITOR_EVENT {
NODE_CHILDREN_CHANGE = 'node.children.change',
NODE_VISIBLE_CHANGE = 'node.visible.change',
}
export type Utils = typeof utils; export type Utils = typeof utils;

View File

@ -7,8 +7,8 @@ import {
IPublicModelEditor, IPublicModelEditor,
EditorConfig, EditorConfig,
PluginClassSet, PluginClassSet,
KeyType, IPublicTypeEditorValueKey,
GetReturnType, IPublicTypeEditorGetResult,
HookConfig, HookConfig,
IPublicTypeComponentDescription, IPublicTypeComponentDescription,
IPublicTypeRemoteComponentDescription, IPublicTypeRemoteComponentDescription,
@ -61,10 +61,11 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
this.setMaxListeners(200); this.setMaxListeners(200);
this.eventBus = new EventBus(this); this.eventBus = new EventBus(this);
} }
/** /**
* Ioc Container * Ioc Container
*/ */
@obx.shallow private context = new Map<KeyType, any>(); @obx.shallow private context = new Map<IPublicTypeEditorValueKey, any>();
get locale() { get locale() {
return globalLocale.getLocale(); return globalLocale.getLocale();
@ -76,15 +77,15 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
get<T = undefined, KeyOrType = any>( get<T = undefined, KeyOrType = any>(
keyOrType: KeyOrType, keyOrType: KeyOrType,
): GetReturnType<T, KeyOrType> | undefined { ): IPublicTypeEditorGetResult<T, KeyOrType> | undefined {
return this.context.get(keyOrType as any); return this.context.get(keyOrType as any);
} }
has(keyOrType: KeyType): boolean { has(keyOrType: IPublicTypeEditorValueKey): boolean {
return this.context.has(keyOrType); return this.context.has(keyOrType);
} }
set(key: KeyType, data: any): void | Promise<void> { set(key: IPublicTypeEditorValueKey, data: any): void | Promise<void> {
if (key === 'assets') { if (key === 'assets') {
return this.setAssets(data); return this.setAssets(data);
} }
@ -172,7 +173,7 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
this.notifyGot('assets'); this.notifyGot('assets');
} }
onceGot<T = undefined, KeyOrType extends KeyType = any>(keyOrType: KeyOrType): Promise<GetReturnType<T, KeyOrType>> { onceGot<T = undefined, KeyOrType extends IPublicTypeEditorValueKey = any>(keyOrType: KeyOrType): Promise<IPublicTypeEditorGetResult<T, KeyOrType>> {
const x = this.context.get(keyOrType); const x = this.context.get(keyOrType);
if (x !== undefined) { if (x !== undefined) {
return Promise.resolve(x); return Promise.resolve(x);
@ -182,9 +183,9 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
}); });
} }
onGot<T = undefined, KeyOrType extends KeyType = any>( onGot<T = undefined, KeyOrType extends IPublicTypeEditorValueKey = any>(
keyOrType: KeyOrType, keyOrType: KeyOrType,
fn: (data: GetReturnType<T, KeyOrType>) => void, fn: (data: IPublicTypeEditorGetResult<T, KeyOrType>) => void,
): () => void { ): () => void {
const x = this.context.get(keyOrType); const x = this.context.get(keyOrType);
if (x !== undefined) { if (x !== undefined) {
@ -198,7 +199,7 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
} }
} }
register(data: any, key?: KeyType): void { register(data: any, key?: IPublicTypeEditorValueKey): void {
this.context.set(key || data, data); this.context.set(key || data, data);
this.notifyGot(key || data); this.notifyGot(key || data);
} }
@ -273,7 +274,7 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
/* eslint-disable */ /* eslint-disable */
private waits = new Map< private waits = new Map<
KeyType, IPublicTypeEditorValueKey,
Array<{ Array<{
once?: boolean; once?: boolean;
resolve: (data: any) => void; resolve: (data: any) => void;
@ -281,7 +282,7 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
>(); >();
/* eslint-enable */ /* eslint-enable */
private notifyGot(key: KeyType) { private notifyGot(key: IPublicTypeEditorValueKey) {
let waits = this.waits.get(key); let waits = this.waits.get(key);
if (!waits) { if (!waits) {
return; return;
@ -301,7 +302,7 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
} }
} }
private setWait(key: KeyType, resolve: (data: any) => void, once?: boolean) { private setWait(key: IPublicTypeEditorValueKey, resolve: (data: any) => void, once?: boolean) {
const waits = this.waits.get(key); const waits = this.waits.get(key);
if (waits) { if (waits) {
waits.push({ resolve, once }); waits.push({ resolve, once });
@ -310,7 +311,7 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
} }
} }
private delWait(key: KeyType, fn: any) { private delWait(key: IPublicTypeEditorValueKey, fn: any) {
const waits = this.waits.get(key); const waits = this.waits.get(key);
if (!waits) { if (!waits) {
return; return;

View File

@ -2,15 +2,12 @@ import store from 'store';
import { getLogger } from './logger'; import { getLogger } from './logger';
import { IPublicModelPreference } from '@alilc/lowcode-types'; import { IPublicModelPreference } from '@alilc/lowcode-types';
const logger = getLogger({ level: 'log', bizName: 'Preference' }); const logger = getLogger({ level: 'warn', bizName: 'Preference' });
const STORAGE_KEY_PREFIX = 'ale'; const STORAGE_KEY_PREFIX = 'ale';
/** /**
* used to store user preferences, such as pinned status of a pannel. * used to store user preferences, such as pinned status of a pannel.
* save to local storage. * save to local storage.
*
* @class PreferenceStore
*/ */
export default class Preference implements IPublicModelPreference { export default class Preference implements IPublicModelPreference {
getStorageKey(key: string, module?: string): string { getStorageKey(key: string, module?: string): string {
@ -24,7 +21,7 @@ export default class Preference implements IPublicModelPreference {
return; return;
} }
const storageKey = this.getStorageKey(key, module); const storageKey = this.getStorageKey(key, module);
logger.log('storageKey:', storageKey, 'set with value:', value); logger.debug('storageKey:', storageKey, 'set with value:', value);
store.set(storageKey, value); store.set(storageKey, value);
} }
@ -35,16 +32,15 @@ export default class Preference implements IPublicModelPreference {
} }
const storageKey = this.getStorageKey(key, module); const storageKey = this.getStorageKey(key, module);
const result = store.get(storageKey); const result = store.get(storageKey);
logger.log('storageKey:', storageKey, 'get with result:', result); logger.debug('storageKey:', storageKey, 'get with result:', result);
return result; return result;
} }
/** /**
* check if local storage contain certain key * check if local storage contain certain key
* *
* @param {string} key * @param {string} key
* @param {string} module * @param {string} module
* @returns {boolean}
* @memberof Preference
*/ */
contains(key: string, module: string): boolean { contains(key: string, module: string): boolean {
if (!key || typeof key !== 'string' || key.length === 0) { if (!key || typeof key !== 'string' || key.length === 0) {

View File

@ -1,12 +1,20 @@
/* eslint-disable max-len */ /* eslint-disable max-len */
import { obx, computed, makeObservable } from '@alilc/lowcode-editor-core'; import { obx, computed, makeObservable } from '@alilc/lowcode-editor-core';
import { Logger } from '@alilc/lowcode-utils'; import { Logger } from '@alilc/lowcode-utils';
import { IPublicTypeWidgetBaseConfig, IArea } from '@alilc/lowcode-types'; import { IPublicTypeWidgetBaseConfig } from '@alilc/lowcode-types';
import { WidgetContainer } from './widget/widget-container'; import { WidgetContainer } from './widget/widget-container';
import { Skeleton } from './skeleton'; import { Skeleton } from './skeleton';
import { IWidget } from './widget/widget'; import { IWidget } from './widget/widget';
const logger = new Logger({ level: 'warn', bizName: 'skeleton:area' }); const logger = new Logger({ level: 'warn', bizName: 'skeleton:area' });
export interface IArea<C, T> {
isEmpty(): boolean;
add(config: T | C): T;
remove(config: T | string): number;
setVisible(flag: boolean): void;
hide(): void;
show(): void;
}
export class Area<C extends IPublicTypeWidgetBaseConfig = any, T extends IWidget = IWidget> implements IArea<C, T> { export class Area<C extends IPublicTypeWidgetBaseConfig = any, T extends IWidget = IWidget> implements IArea<C, T> {
@obx private _visible = true; @obx private _visible = true;

View File

@ -9,7 +9,7 @@ import {
import { import {
IPublicModelDragObject, IPublicModelDragObject,
IPublicModelScrollable, IPublicModelScrollable,
ISensor, IPublicModelSensor,
IPublicTypeLocationChildrenDetail, IPublicTypeLocationChildrenDetail,
IPublicTypeLocationDetailType, IPublicTypeLocationDetailType,
IPublicModelNode, IPublicModelNode,
@ -24,7 +24,7 @@ import { IndentTrack } from '../helper/indent-track';
import DwellTimer from '../helper/dwell-timer'; import DwellTimer from '../helper/dwell-timer';
import { ITreeBoard, TreeMaster } from './tree-master'; import { ITreeBoard, TreeMaster } from './tree-master';
export class PaneController implements ISensor, ITreeBoard, IPublicModelScrollable { export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicModelScrollable {
private pluginContext: IPublicModelPluginContext; private pluginContext: IPublicModelPluginContext;
private treeMaster?: TreeMaster; private treeMaster?: TreeMaster;
@ -50,12 +50,12 @@ export class PaneController implements ISensor, ITreeBoard, IPublicModelScrollab
setup(); setup();
} }
/** -------------------- ISensor begin -------------------- */ /** -------------------- IPublicModelSensor begin -------------------- */
private indentTrack = new IndentTrack(); private indentTrack = new IndentTrack();
/** /**
* @see ISensor * @see IPublicModelSensor
*/ */
fixEvent(e: IPublicModelLocateEvent): IPublicModelLocateEvent { fixEvent(e: IPublicModelLocateEvent): IPublicModelLocateEvent {
if (e.fixed) { if (e.fixed) {
@ -77,7 +77,7 @@ export class PaneController implements ISensor, ITreeBoard, IPublicModelScrollab
} }
/** /**
* @see ISensor * @see IPublicModelSensor
*/ */
locate(e: IPublicModelLocateEvent): IPublicModelDropLocation | undefined | null { locate(e: IPublicModelLocateEvent): IPublicModelDropLocation | undefined | null {
this.sensing = true; this.sensing = true;
@ -213,7 +213,7 @@ export class PaneController implements ISensor, ITreeBoard, IPublicModelScrollab
} }
/** /**
* @see ISensor * @see IPublicModelSensor
*/ */
isEnter(e: IPublicModelLocateEvent): boolean { isEnter(e: IPublicModelLocateEvent): boolean {
if (!this._shell) { if (!this._shell) {
@ -224,7 +224,7 @@ export class PaneController implements ISensor, ITreeBoard, IPublicModelScrollab
} }
/** /**
* @see ISensor * @see IPublicModelSensor
*/ */
deactiveSensor() { deactiveSensor() {
this.sensing = false; this.sensing = false;
@ -234,15 +234,15 @@ export class PaneController implements ISensor, ITreeBoard, IPublicModelScrollab
} }
private _sensorAvailable = false; private _sensorAvailable = false;
/** /**
* @see ISensor * @see IPublicModelSensor
*/ */
get sensorAvailable() { get sensorAvailable() {
return this._sensorAvailable; return this._sensorAvailable;
} }
/** -------------------- ISensor end -------------------- */ /** -------------------- IPublicModelSensor end -------------------- */
/** -------------------- ITreeBoard begin -------------------- */ /** -------------------- ITreeBoard begin -------------------- */
@ -564,7 +564,6 @@ export class PaneController implements ISensor, ITreeBoard, IPublicModelScrollab
return this._scrollTarget; return this._scrollTarget;
} }
private scroller?: IPublicModelScroller; private scroller?: IPublicModelScroller;
purge() { purge() {
@ -573,7 +572,6 @@ export class PaneController implements ISensor, ITreeBoard, IPublicModelScrollab
this.treeMaster?.removeBoard(this); this.treeMaster?.removeBoard(this);
} }
private _shell: HTMLDivElement | null = null; private _shell: HTMLDivElement | null = null;
mount(shell: HTMLDivElement | null) { mount(shell: HTMLDivElement | null) {

View File

@ -1,5 +1,5 @@
import { BuiltinSimulatorRenderer, Component, DocumentModel, Node } from '@alilc/lowcode-designer'; import { BuiltinSimulatorRenderer, Component, DocumentModel, Node } from '@alilc/lowcode-designer';
import { IPublicTypeComponentSchema, IPublicTypeNodeSchema, IPublicTypeNpmInfo, IPublicEnumTransformStage, NodeInstance } from '@alilc/lowcode-types'; import { IPublicTypeComponentSchema, IPublicTypeNodeSchema, IPublicTypeNpmInfo, IPublicEnumTransformStage, IPublicTypeNodeInstance } from '@alilc/lowcode-types';
import { Asset, compatibleLegaoSchema, cursor, isElement, isESModule, isPlainObject, isReactComponent, setNativeSelection } from '@alilc/lowcode-utils'; import { Asset, compatibleLegaoSchema, cursor, isElement, isESModule, isPlainObject, isReactComponent, setNativeSelection } from '@alilc/lowcode-utils';
import LowCodeRenderer from '@alilc/lowcode-rax-renderer'; import LowCodeRenderer from '@alilc/lowcode-rax-renderer';
import { computed, observable as obx, makeObservable, configure } from 'mobx'; import { computed, observable as obx, makeObservable, configure } from 'mobx';
@ -94,7 +94,7 @@ function isValidDesignModeRaxComponentInstance(
raxComponentInst: any, raxComponentInst: any,
): raxComponentInst is { ): raxComponentInst is {
props: { props: {
_leaf: Exclude<NodeInstance<any>['node'], null | undefined>; _leaf: Exclude<IPublicTypeNodeInstance<any>['node'], null | undefined>;
}; };
} { } {
const leaf = raxComponentInst?.props?._leaf; const leaf = raxComponentInst?.props?._leaf;
@ -370,6 +370,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
@computed get componentsMap(): any { @computed get componentsMap(): any {
return this._componentsMap; return this._componentsMap;
} }
/** /**
* *
*/ */
@ -396,7 +397,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
} }
} }
getNodeInstance(dom: HTMLElement): NodeInstance<any> | null { getNodeInstance(dom: HTMLElement): IPublicTypeNodeInstance<any> | null {
const INTERNAL = '_internal'; const INTERNAL = '_internal';
let instance: any = dom; let instance: any = dom;
if (!isElement(instance)) { if (!isElement(instance)) {
@ -429,7 +430,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
return null; return null;
} }
getClosestNodeInstance(from: any, nodeId?: string): NodeInstance<any> | null { getClosestNodeInstance(from: any, nodeId?: string): IPublicTypeNodeInstance<any> | null {
const el: any = from; const el: any = from;
if (el) { if (el) {
// if (isElement(el)) { // if (isElement(el)) {
@ -510,7 +511,6 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
doc.getElementsByTagName('head')[0].appendChild(s); doc.getElementsByTagName('head')[0].appendChild(s);
} }
const renderer = this; const renderer = this;
const { componentsMap: components } = renderer; const { componentsMap: components } = renderer;

View File

@ -17,7 +17,7 @@ import {
AssetLoader, AssetLoader,
getProjectUtils, getProjectUtils,
} from '@alilc/lowcode-utils'; } from '@alilc/lowcode-utils';
import { IPublicTypeComponentSchema, IPublicEnumTransformStage, IPublicTypeNodeSchema, NodeInstance } from '@alilc/lowcode-types'; import { IPublicTypeComponentSchema, IPublicEnumTransformStage, IPublicTypeNodeSchema, IPublicTypeNodeInstance } from '@alilc/lowcode-types';
// just use types // just use types
import { BuiltinSimulatorRenderer, Component, DocumentModel, Node } from '@alilc/lowcode-designer'; import { BuiltinSimulatorRenderer, Component, DocumentModel, Node } from '@alilc/lowcode-designer';
import LowCodeRenderer from '@alilc/lowcode-react-renderer'; import LowCodeRenderer from '@alilc/lowcode-react-renderer';
@ -368,6 +368,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
* *
*/ */
autoRepaintNode = true; autoRepaintNode = true;
/** /**
* *
*/ */
@ -399,7 +400,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
} }
} }
getClosestNodeInstance(from: ReactInstance, nodeId?: string): NodeInstance<ReactInstance> | null { getClosestNodeInstance(from: ReactInstance, nodeId?: string): IPublicTypeNodeInstance<ReactInstance> | null {
return getClosestNodeInstance(from, nodeId); return getClosestNodeInstance(from, nodeId);
} }
@ -557,7 +558,7 @@ const SYMBOL_VDID = Symbol('_LCDocId');
function getClosestNodeInstance( function getClosestNodeInstance(
from: ReactInstance, from: ReactInstance,
specId?: string, specId?: string,
): NodeInstance<ReactInstance> | null { ): IPublicTypeNodeInstance<ReactInstance> | null {
let el: any = from; let el: any = from;
if (el) { if (el) {
if (isElement(el)) { if (isElement(el)) {
@ -587,7 +588,7 @@ function getClosestNodeInstance(
return null; return null;
} }
function getNodeInstance(fiberNode: any, specId?: string): NodeInstance<ReactInstance> | null { function getNodeInstance(fiberNode: any, specId?: string): IPublicTypeNodeInstance<ReactInstance> | null {
const instance = fiberNode?.stateNode; const instance = fiberNode?.stateNode;
if (instance && SYMBOL_VNID in instance) { if (instance && SYMBOL_VNID in instance) {
const nodeId = instance[SYMBOL_VNID]; const nodeId = instance[SYMBOL_VNID];

View File

@ -4,7 +4,6 @@ import {
IPublicModelScrollTarget, IPublicModelScrollTarget,
IPublicModelScrollable, IPublicModelScrollable,
IPublicModelScroller, IPublicModelScroller,
IDesigner,
IPublicTypeLocationData, IPublicTypeLocationData,
IPublicModelEditor, IPublicModelEditor,
IPublicModelDragon, IPublicModelDragon,
@ -12,13 +11,13 @@ import {
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { import {
ScrollTarget as InnerScrollTarget, ScrollTarget as InnerScrollTarget,
IDesigner,
} from '@alilc/lowcode-designer'; } from '@alilc/lowcode-designer';
import { editorSymbol, designerSymbol, nodeSymbol } from '../symbols'; import { editorSymbol, designerSymbol, nodeSymbol } from '../symbols';
import { Dragon } from '../model'; import { Dragon } from '../model';
import { DropLocation } from '../model/drop-location'; import { DropLocation } from '../model/drop-location';
import { ActiveTracker } from '../model/active-tracker'; import { ActiveTracker } from '../model/active-tracker';
export class Canvas implements IPublicApiCanvas { export class Canvas implements IPublicApiCanvas {
private readonly [editorSymbol]: IPublicModelEditor; private readonly [editorSymbol]: IPublicModelEditor;

View File

@ -25,7 +25,6 @@ import {
IPublicTypeLocationDetailType as InnerLocationDetailType, IPublicTypeLocationDetailType as InnerLocationDetailType,
IPublicApiCommonEditorCabin, IPublicApiCommonEditorCabin,
IPublicModelDragon, IPublicModelDragon,
IDesigner,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { import {
SettingField as InnerSettingField, SettingField as InnerSettingField,
@ -35,6 +34,7 @@ import {
ScrollTarget as InnerScrollTarget, ScrollTarget as InnerScrollTarget,
getConvertedExtraKey as innerGetConvertedExtraKey, getConvertedExtraKey as innerGetConvertedExtraKey,
getOriginalExtraKey as innerGetOriginalExtraKey, getOriginalExtraKey as innerGetOriginalExtraKey,
IDesigner,
} from '@alilc/lowcode-designer'; } from '@alilc/lowcode-designer';
import { import {
Skeleton as InnerSkeleton, Skeleton as InnerSkeleton,
@ -63,6 +63,7 @@ import { ReactNode, Component } from 'react';
class DesignerCabin implements IPublicApiCommonDesignerCabin { class DesignerCabin implements IPublicApiCommonDesignerCabin {
private readonly [editorSymbol]: Editor; private readonly [editorSymbol]: Editor;
/** /**
* @deprecated * @deprecated
*/ */
@ -240,6 +241,7 @@ class EditorCabin implements IPublicApiCommonEditorCabin {
constructor(editor: Editor) { constructor(editor: Editor) {
this[editorSymbol] = editor; this[editorSymbol] = editor;
} }
/** /**
* Title * Title
* @experimental unstable API, pay extra caution when trying to use this * @experimental unstable API, pay extra caution when trying to use this
@ -335,7 +337,6 @@ class EditorCabin implements IPublicApiCommonEditorCabin {
} }
} }
export class Common implements IPublicApiCommon { export class Common implements IPublicApiCommon {
private readonly __designerCabin: any; private readonly __designerCabin: any;
private readonly __skeletonCabin: any; private readonly __skeletonCabin: any;

View File

@ -1,8 +1,9 @@
import { IPublicApiWorkspace } from '@alilc/lowcode-types'; import { IPublicApiWorkspace, IPublicResourceList, IPublicTypeResourceType } from '@alilc/lowcode-types';
import { Workspace as InnerWorkSpace } from '@alilc/lowcode-workspace'; import { Workspace as InnerWorkSpace } from '@alilc/lowcode-workspace';
import { Plugins } from '@alilc/lowcode-shell'; import { Plugins } from '@alilc/lowcode-shell';
import { Window } from '../model/window'; import { Window } from '../model/window';
import { workspaceSymbol } from '../symbols'; import { workspaceSymbol } from '../symbols';
import { Resource } from '../model';
export class Workspace implements IPublicApiWorkspace { export class Workspace implements IPublicApiWorkspace {
readonly [workspaceSymbol]: InnerWorkSpace; readonly [workspaceSymbol]: InnerWorkSpace;
@ -11,6 +12,18 @@ export class Workspace implements IPublicApiWorkspace {
this[workspaceSymbol] = innerWorkspace; this[workspaceSymbol] = innerWorkspace;
} }
get resourceList() {
return this[workspaceSymbol].getResourceList().map(d => new Resource(d));
}
setResourceList(resourceList: IPublicResourceList) {
this[workspaceSymbol].setResourceList(resourceList);
}
onResourceListChange(fn: (resourceList: IPublicResourceList) => void): () => void {
return this[workspaceSymbol].onResourceListChange(fn);
}
get isActive() { get isActive() {
return this[workspaceSymbol].isActive; return this[workspaceSymbol].isActive;
} }
@ -19,12 +32,12 @@ export class Workspace implements IPublicApiWorkspace {
return new Window(this[workspaceSymbol].window); return new Window(this[workspaceSymbol].window);
} }
registerResourceType(resourceName: string, resourceType: 'editor', options: any): void { registerResourceType(resourceTypeModel: IPublicTypeResourceType): void {
this[workspaceSymbol].registerResourceType(resourceName, resourceType, options); this[workspaceSymbol].registerResourceType(resourceTypeModel);
} }
openEditorWindow(resourceName: string, title: string, viewType?: string) { openEditorWindow(resourceName: string, title: string, extra: Object, viewName?: string) {
this[workspaceSymbol].openEditorWindow(resourceName, title, viewType); this[workspaceSymbol].openEditorWindow(resourceName, title, extra, viewName);
} }
openEditorWindowById(id: string) { openEditorWindowById(id: string) {

View File

@ -1,10 +1,10 @@
import { Node } from './node'; import { Node as ShellNode } from './node';
import { import {
Detecting as InnerDetecting, Detecting as InnerDetecting,
DocumentModel as InnerDocumentModel, IDocumentModel as InnerDocumentModel,
} from '@alilc/lowcode-designer'; } from '@alilc/lowcode-designer';
import { documentSymbol, detectingSymbol } from '../symbols'; import { documentSymbol, detectingSymbol } from '../symbols';
import { IPublicModelDetecting, IPublicModelNode } from '@alilc/lowcode-types'; import { IPublicModelDetecting, IPublicModelNode, IPublicTypeDisposable } from '@alilc/lowcode-types';
export class Detecting implements IPublicModelDetecting { export class Detecting implements IPublicModelDetecting {
private readonly [documentSymbol]: InnerDocumentModel; private readonly [documentSymbol]: InnerDocumentModel;
@ -26,7 +26,7 @@ export class Detecting implements IPublicModelDetecting {
* hover * hover
*/ */
get current() { get current() {
return Node.create(this[detectingSymbol].current); return ShellNode.create(this[detectingSymbol].current);
} }
/** /**
@ -52,7 +52,7 @@ export class Detecting implements IPublicModelDetecting {
this[detectingSymbol].leave(this[documentSymbol]); this[detectingSymbol].leave(this[documentSymbol]);
} }
onDetectingChange(fn: (node: IPublicModelNode) => void): () => void { onDetectingChange(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable {
return this[detectingSymbol].onDetectingChange(fn); return this[detectingSymbol].onDetectingChange(fn);
} }
} }

View File

@ -3,14 +3,13 @@ import {
DocumentModel as InnerDocumentModel, DocumentModel as InnerDocumentModel,
Node as InnerNode, Node as InnerNode,
isDragNodeObject, isDragNodeObject,
IOnChangeOptions as InnerOnChangeOptions,
} from '@alilc/lowcode-designer'; } from '@alilc/lowcode-designer';
import { import {
IPublicEnumTransformStage, IPublicEnumTransformStage,
IPublicTypeRootSchema, IPublicTypeRootSchema,
GlobalEvent, GlobalEvent,
IPublicModelDocumentModel, IPublicModelDocumentModel,
IPublicOnChangeOptions, IPublicTypeOnChangeOptions,
IPublicModelDragObject, IPublicModelDragObject,
IPublicTypeDragNodeObject, IPublicTypeDragNodeObject,
IPublicTypeDragNodeDataObject, IPublicTypeDragNodeDataObject,
@ -45,6 +44,7 @@ export class DocumentModel implements IPublicModelDocumentModel {
selection: IPublicModelSelection; selection: IPublicModelSelection;
detecting: IPublicModelDetecting; detecting: IPublicModelDetecting;
history: IPublicModelHistory; history: IPublicModelHistory;
/** /**
* @deprecated use canvas API instead * @deprecated use canvas API instead
*/ */
@ -141,6 +141,7 @@ export class DocumentModel implements IPublicModelDocumentModel {
set dropLocation(loc: IPublicModelDropLocation | null) { set dropLocation(loc: IPublicModelDropLocation | null) {
this[documentSymbol].dropLocation = loc; this[documentSymbol].dropLocation = loc;
} }
/** /**
* nodeId Node * nodeId Node
* get node instance by nodeId * get node instance by nodeId
@ -297,8 +298,8 @@ export class DocumentModel implements IPublicModelDocumentModel {
* document children * document children
* @param fn * @param fn
*/ */
onChangeNodeChildren(fn: (info: IPublicOnChangeOptions) => void): void { onChangeNodeChildren(fn: (info: IPublicTypeOnChangeOptions) => void): void {
this[documentSymbol].onChangeNodeChildren((info?: IPublicOnChangeOptions) => { this[documentSymbol].onChangeNodeChildren((info?: IPublicTypeOnChangeOptions) => {
if (!info) { if (!info) {
return; return;
} }

View File

@ -1,6 +1,6 @@
import { DocumentModel as InnerDocumentModel } from '@alilc/lowcode-designer'; import { DocumentModel as InnerDocumentModel } from '@alilc/lowcode-designer';
import { historySymbol, documentSymbol } from '../symbols'; import { historySymbol, documentSymbol } from '../symbols';
import { IPublicModelHistory } from '@alilc/lowcode-types'; import { IPublicModelHistory, IPublicTypeDisposable } from '@alilc/lowcode-types';
export class History implements IPublicModelHistory { export class History implements IPublicModelHistory {
private readonly [documentSymbol]: InnerDocumentModel; private readonly [documentSymbol]: InnerDocumentModel;
@ -54,7 +54,7 @@ export class History implements IPublicModelHistory {
* state退 * state退
* @returns * @returns
*/ */
getState(): any { getState(): number {
return this[historySymbol].getState(); return this[historySymbol].getState();
} }
@ -63,7 +63,7 @@ export class History implements IPublicModelHistory {
* @param func * @param func
* @returns * @returns
*/ */
onChangeState(func: () => any): () => void { onChangeState(func: () => any): IPublicTypeDisposable {
return this[historySymbol].onStateChange(func); return this[historySymbol].onStateChange(func);
} }
@ -72,7 +72,7 @@ export class History implements IPublicModelHistory {
* @param func * @param func
* @returns * @returns
*/ */
onChangeCursor(func: () => any): () => void { onChangeCursor(func: () => any): IPublicTypeDisposable {
return this[historySymbol].onCursor(func); return this[historySymbol].onCursor(func);
} }
} }

View File

@ -14,3 +14,4 @@ export * from './props';
export * from './selection'; export * from './selection';
export * from './setting-prop-entry'; export * from './setting-prop-entry';
export * from './setting-top-entry'; export * from './setting-top-entry';
export * from './resource';

View File

@ -19,12 +19,12 @@ import {
IPublicModelSettingTopEntry, IPublicModelSettingTopEntry,
IPublicModelExclusiveGroup, IPublicModelExclusiveGroup,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { Prop } from './prop'; import { Prop as ShellProp } from './prop';
import { Props } from './props'; import { Props as ShellProps } from './props';
import { DocumentModel } from './document-model'; import { DocumentModel as ShellDocumentModel } from './document-model';
import { NodeChildren } from './node-children'; import { NodeChildren as ShellNodeChildren } from './node-children';
import { ComponentMeta } from './component-meta'; import { ComponentMeta as ShellComponentMeta } from './component-meta';
import { SettingTopEntry } from './setting-top-entry'; import { SettingTopEntry as ShellSettingTopEntry } from './setting-top-entry';
import { documentSymbol, nodeSymbol } from '../symbols'; import { documentSymbol, nodeSymbol } from '../symbols';
import { ReactElement } from 'react'; import { ReactElement } from 'react';
@ -36,27 +36,6 @@ export class Node implements IPublicModelNode {
private _id: string; private _id: string;
constructor(node: IPublicModelNode) {
this[nodeSymbol] = node;
this[documentSymbol] = node.document;
this._id = this[nodeSymbol].id;
}
static create(node: IPublicModelNode | null | undefined): IPublicModelNode | null {
if (!node) {
return null;
}
// @ts-ignore 直接返回已挂载的 shell node 实例
if (node[shellNodeSymbol]) {
return (node as any)[shellNodeSymbol];
}
const shellNode = new Node(node);
// @ts-ignore 挂载 shell node 实例
node[shellNodeSymbol] = shellNode;
return shellNode;
}
/** /**
* id * id
*/ */
@ -257,7 +236,7 @@ export class Node implements IPublicModelNode {
* *
*/ */
get componentMeta(): IPublicModelComponentMeta | null { get componentMeta(): IPublicModelComponentMeta | null {
return ComponentMeta.create(this[nodeSymbol].componentMeta); return ShellComponentMeta.create(this[nodeSymbol].componentMeta);
} }
/** /**
@ -265,7 +244,7 @@ export class Node implements IPublicModelNode {
* @returns * @returns
*/ */
get document(): IPublicModelDocumentModel | null { get document(): IPublicModelDocumentModel | null {
return DocumentModel.create(this[documentSymbol]); return ShellDocumentModel.create(this[documentSymbol]);
} }
/** /**
@ -297,7 +276,7 @@ export class Node implements IPublicModelNode {
* @returns * @returns
*/ */
get children(): IPublicModelNodeChildren | null { get children(): IPublicModelNodeChildren | null {
return NodeChildren.create(this[nodeSymbol].children); return ShellNodeChildren.create(this[nodeSymbol].children);
} }
/** /**
@ -311,14 +290,14 @@ export class Node implements IPublicModelNode {
* *
*/ */
get slotFor(): IPublicModelProp | null { get slotFor(): IPublicModelProp | null {
return Prop.create(this[nodeSymbol].slotFor); return ShellProp.create(this[nodeSymbol].slotFor);
} }
/** /**
* *
*/ */
get props(): IPublicModelProps | null { get props(): IPublicModelProps | null {
return Props.create(this[nodeSymbol].props); return ShellProps.create(this[nodeSymbol].props);
} }
/** /**
@ -336,7 +315,28 @@ export class Node implements IPublicModelNode {
} }
get settingEntry(): IPublicModelSettingTopEntry { get settingEntry(): IPublicModelSettingTopEntry {
return SettingTopEntry.create(this[nodeSymbol].settingEntry as any); return ShellSettingTopEntry.create(this[nodeSymbol].settingEntry as any);
}
constructor(node: IPublicModelNode) {
this[nodeSymbol] = node;
this[documentSymbol] = node.document;
this._id = this[nodeSymbol].id;
}
static create(node: InnerNode | null | undefined): IPublicModelNode | null {
if (!node) {
return null;
}
// @ts-ignore 直接返回已挂载的 shell node 实例
if (node[shellNodeSymbol]) {
return (node as any)[shellNodeSymbol];
}
const shellNode = new Node(node);
// @ts-ignore 挂载 shell node 实例
node[shellNodeSymbol] = shellNode;
return shellNode;
} }
/** /**
@ -445,7 +445,7 @@ export class Node implements IPublicModelNode {
* @returns * @returns
*/ */
getProp(path: string, createIfNone = true): IPublicModelProp | null { getProp(path: string, createIfNone = true): IPublicModelProp | null {
return Prop.create(this[nodeSymbol].getProp(path, createIfNone)); return ShellProp.create(this[nodeSymbol].getProp(path, createIfNone));
} }
/** /**
@ -465,7 +465,7 @@ export class Node implements IPublicModelNode {
* @returns * @returns
*/ */
getExtraProp(path: string, createIfNone?: boolean): IPublicModelProp | null { getExtraProp(path: string, createIfNone?: boolean): IPublicModelProp | null {
return Prop.create(this[nodeSymbol].getExtraProp(path, createIfNone)); return ShellProp.create(this[nodeSymbol].getExtraProp(path, createIfNone));
} }
/** /**
@ -591,12 +591,13 @@ export class Node implements IPublicModelNode {
remove(): void { remove(): void {
this[nodeSymbol].remove(); this[nodeSymbol].remove();
} }
/** /**
* @deprecated * @deprecated
* *
*/ */
set isRGLContainer(flag: boolean) { set isRGLContainer(flag: boolean) {
this[nodeSymbol].isRGLContainer = flag; this[nodeSymbol].isRGLContainerNode = flag;
} }
/** /**
@ -605,14 +606,14 @@ export class Node implements IPublicModelNode {
* @returns Boolean * @returns Boolean
*/ */
get isRGLContainer() { get isRGLContainer() {
return this[nodeSymbol].isRGLContainer; return this[nodeSymbol].isRGLContainerNode;
} }
/** /**
* *
*/ */
set isRGLContainerNode(flag: boolean) { set isRGLContainerNode(flag: boolean) {
this[nodeSymbol].isRGLContainer = flag; this[nodeSymbol].isRGLContainerNode = flag;
} }
/** /**
@ -620,7 +621,7 @@ export class Node implements IPublicModelNode {
* @returns Boolean * @returns Boolean
*/ */
get isRGLContainerNode() { get isRGLContainerNode() {
return this[nodeSymbol].isRGLContainer; return this[nodeSymbol].isRGLContainerNode;
} }
internalToShellNode() { internalToShellNode() {

View File

@ -1,7 +1,7 @@
import { IPropParent as InnerProp } from '@alilc/lowcode-designer'; import { IProp as InnerProp } from '@alilc/lowcode-designer';
import { IPublicTypeCompositeValue, IPublicEnumTransformStage, IPublicModelProp, IPublicModelNode } from '@alilc/lowcode-types'; import { IPublicTypeCompositeValue, IPublicEnumTransformStage, IPublicModelProp, IPublicModelNode } from '@alilc/lowcode-types';
import { propSymbol } from '../symbols'; import { propSymbol } from '../symbols';
import { Node } from './node'; import { Node as ShellNode } from './node';
export class Prop implements IPublicModelProp { export class Prop implements IPublicModelProp {
private readonly [propSymbol]: InnerProp; private readonly [propSymbol]: InnerProp;
@ -26,6 +26,7 @@ export class Prop implements IPublicModelProp {
/** /**
* key * key
* get key of prop
*/ */
get key(): string | number | undefined { get key(): string | number | undefined {
return this[propSymbol].key; return this[propSymbol].key;
@ -34,7 +35,7 @@ export class Prop implements IPublicModelProp {
/** /**
* prop * prop
*/ */
get path(): any[] { get path(): string[] {
return this[propSymbol].path; return this[propSymbol].path;
} }
@ -42,14 +43,14 @@ export class Prop implements IPublicModelProp {
* *
*/ */
get node(): IPublicModelNode | null { get node(): IPublicModelNode | null {
return Node.create(this[propSymbol].getNode()); return ShellNode.create(this[propSymbol].getNode());
} }
/** /**
* return the slot node (only if the current prop represents a slot) * return the slot node (only if the current prop represents a slot)
*/ */
get slotNode(): IPublicModelNode | null { get slotNode(): IPublicModelNode | null {
return Node.create(this[propSymbol].slotNode); return ShellNode.create(this[propSymbol].slotNode);
} }
/** /**

View File

@ -1,8 +1,8 @@
import { IPropParent as InnerProps, getConvertedExtraKey } from '@alilc/lowcode-designer'; import { IProps as InnerProps, getConvertedExtraKey } from '@alilc/lowcode-designer';
import { IPublicTypeCompositeValue, IPublicModelProps, IPublicModelNode, IPublicModelProp } from '@alilc/lowcode-types'; import { IPublicTypeCompositeValue, IPublicModelProps, IPublicModelNode, IPublicModelProp } from '@alilc/lowcode-types';
import { propsSymbol } from '../symbols'; import { propsSymbol } from '../symbols';
import { Node } from './node'; import { Node as ShellNode } from './node';
import { Prop } from './prop'; import { Prop as ShellProp } from './prop';
export class Props implements IPublicModelProps { export class Props implements IPublicModelProps {
private readonly [propsSymbol]: InnerProps; private readonly [propsSymbol]: InnerProps;
@ -36,7 +36,7 @@ export class Props implements IPublicModelProps {
* node * node
*/ */
get node(): IPublicModelNode | null { get node(): IPublicModelNode | null {
return Node.create(this[propsSymbol].getNode()); return ShellNode.create(this[propsSymbol].getNode());
} }
/** /**
@ -45,7 +45,7 @@ export class Props implements IPublicModelProps {
* @returns * @returns
*/ */
getProp(path: string): IPublicModelProp | null { getProp(path: string): IPublicModelProp | null {
return Prop.create(this[propsSymbol].getProp(path)); return ShellProp.create(this[propsSymbol].getProp(path));
} }
/** /**
@ -64,7 +64,7 @@ export class Props implements IPublicModelProps {
* @returns * @returns
*/ */
getExtraProp(path: string): IPublicModelProp | null { getExtraProp(path: string): IPublicModelProp | null {
return Prop.create(this[propsSymbol].getProp(getConvertedExtraKey(path))); return ShellProp.create(this[propsSymbol].getProp(getConvertedExtraKey(path)));
} }
/** /**

View File

@ -0,0 +1,36 @@
import { IPublicModelResource } from '@alilc/lowcode-types';
import { Resource as InnerResource } from '@alilc/lowcode-workspace';
import { resourceSymbol } from '../symbols';
import { ResourceType } from './resource-type';
export class Resource implements IPublicModelResource {
readonly [resourceSymbol]: InnerResource;
constructor(resource: InnerResource) {
this[resourceSymbol] = resource;
}
get title() {
return this[resourceSymbol].title;
}
get icon() {
return this[resourceSymbol].icon;
}
get options() {
return this[resourceSymbol].options;
}
get name() {
return this[resourceSymbol].resourceType.name;
}
get type() {
return this[resourceSymbol].resourceType.type;
}
get category() {
return this[resourceSymbol].category;
}
}

View File

@ -1,19 +1,17 @@
import { import {
DocumentModel as InnerDocumentModel, IDocumentModel as InnerDocumentModel,
Node as InnerNode, INode as InnerNode,
Selection as InnerSelection, ISelection as InnerSelection,
} from '@alilc/lowcode-designer'; } from '@alilc/lowcode-designer';
import { Node } from './node'; import { Node as ShellNode } from './node';
import { selectionSymbol, documentSymbol } from '../symbols'; import { selectionSymbol } from '../symbols';
import { IPublicModelSelection, IPublicModelNode } from '@alilc/lowcode-types'; import { IPublicModelSelection, IPublicModelNode, IPublicTypeDisposable } from '@alilc/lowcode-types';
export class Selection implements IPublicModelSelection { export class Selection implements IPublicModelSelection {
private readonly [selectionSymbol]: InnerSelection; private readonly [selectionSymbol]: InnerSelection;
private readonly [documentSymbol]: InnerDocumentModel;
constructor(document: InnerDocumentModel) { constructor(document: InnerDocumentModel) {
this[selectionSymbol] = document.selection; this[selectionSymbol] = document.selection;
this[documentSymbol] = document;
} }
/** /**
@ -83,8 +81,16 @@ export class Selection implements IPublicModelSelection {
* *
* @returns * @returns
*/ */
getNodes(): Array<IPublicModelNode | null> { getNodes(): IPublicModelNode[] {
return this[selectionSymbol].getNodes().map((node: InnerNode) => Node.create(node)); const innerNodes = this[selectionSymbol].getNodes();
const nodes: IPublicModelNode[] = [];
innerNodes.forEach((node: InnerNode) => {
const shellNode = ShellNode.create(node);
if (shellNode) {
nodes.push(shellNode);
}
});
return nodes;
} }
/** /**
@ -94,12 +100,19 @@ export class Selection implements IPublicModelSelection {
* getTopNodes() will return [A, B], subA will be removed * getTopNodes() will return [A, B], subA will be removed
* @returns * @returns
*/ */
getTopNodes(includeRoot: boolean = false): Array<IPublicModelNode | null> { getTopNodes(includeRoot: boolean = false): IPublicModelNode[] {
return this[selectionSymbol].getTopNodes(includeRoot).map((node: InnerNode) => Node.create(node)); const innerNodes = this[selectionSymbol].getTopNodes(includeRoot);
const nodes: IPublicModelNode[] = [];
innerNodes.forEach((node: InnerNode) => {
const shellNode = ShellNode.create(node);
if (shellNode) {
nodes.push(shellNode);
}
});
return nodes;
} }
onSelectionChange(fn: (ids: string[]) => void): IPublicTypeDisposable {
onSelectionChange(fn: (ids: string[]) => void): () => void {
return this[selectionSymbol].onSelectionChange(fn); return this[selectionSymbol].onSelectionChange(fn);
} }
} }

View File

@ -1,12 +1,13 @@
import { windowSymbol } from '../symbols'; import { windowSymbol } from '../symbols';
import { IPublicModelWindow } from '@alilc/lowcode-types'; import { IPublicModelResource, IPublicModelWindow } from '@alilc/lowcode-types';
import { EditorWindow } from '@alilc/lowcode-workspace'; import { EditorWindow } from '@alilc/lowcode-workspace';
import { Resource } from './resource';
export class Window implements IPublicModelWindow { export class Window implements IPublicModelWindow {
private readonly [windowSymbol]: EditorWindow; private readonly [windowSymbol]: EditorWindow;
get id() { get id() {
return this[windowSymbol].id; return this[windowSymbol]?.id;
} }
get title() { get title() {
@ -17,8 +18,8 @@ export class Window implements IPublicModelWindow {
return this[windowSymbol].icon; return this[windowSymbol].icon;
} }
get resourceName() { get resource(): IPublicModelResource {
return this[windowSymbol].resourceName; return new Resource(this[windowSymbol].resource);
} }
constructor(editorWindow: EditorWindow) { constructor(editorWindow: EditorWindow) {

View File

@ -29,3 +29,5 @@ export const pluginsSymbol = Symbol('plugins');
export const workspaceSymbol = Symbol('workspace'); export const workspaceSymbol = Symbol('workspace');
export const windowSymbol = Symbol('window'); export const windowSymbol = Symbol('window');
export const pluginInstanceSymbol = Symbol('plugin-instance'); export const pluginInstanceSymbol = Symbol('plugin-instance');
export const resourceTypeSymbol = Symbol('resourceType');
export const resourceSymbol = Symbol('resource');

View File

@ -7,7 +7,7 @@ export enum ActivityType {
'COMPOSITE' = 'composite', 'COMPOSITE' = 'composite',
} }
export interface IActivityPayload { interface IActivityPayload {
schema: IPublicTypeNodeSchema; schema: IPublicTypeNodeSchema;
location?: { location?: {
parent: { parent: {
@ -20,6 +20,10 @@ export interface IActivityPayload {
newValue: any; newValue: any;
} }
/**
* TODO: not sure if this is used anywhere
* @deprecated
*/
export type ActivityData = { export type ActivityData = {
type: ActivityType; type: ActivityType;
payload: IActivityPayload; payload: IActivityPayload;

View File

@ -1,12 +1,3 @@
export interface AssetItem {
type: AssetType;
content?: string | null;
device?: string;
level?: AssetLevel;
id?: string;
}
export enum AssetLevel { export enum AssetLevel {
// 环境依赖库 比如 react, react-dom // 环境依赖库 比如 react, react-dom
Environment = 1, Environment = 1,
@ -41,12 +32,20 @@ export enum AssetType {
Bundle = 'bundle', Bundle = 'bundle',
} }
export interface AssetItem {
type: AssetType;
content?: string | null;
device?: string;
level?: AssetLevel;
id?: string;
}
export type AssetList = Array<Asset | undefined | null>;
export type Asset = AssetList | AssetBundle | AssetItem | URL;
export interface AssetBundle { export interface AssetBundle {
type: AssetType.Bundle; type: AssetType.Bundle;
level?: AssetLevel; level?: AssetLevel;
assets?: Asset | AssetList | null; assets?: Asset | AssetList | null;
} }
export type Asset = AssetList | AssetBundle | AssetItem | URL;
export type AssetList = Array<Asset | undefined | null>;

View File

@ -1,25 +0,0 @@
import { IPublicModelNode, IPublicModelDragon, IPublicModelDropLocation, IPublicModelScroller, IPublicModelScrollable, IPublicTypeComponentInstance, IPublicTypeLocationData, IPublicModelActiveTracker } from './shell';
export interface IPublicOnChangeOptions {
type: string;
node: IPublicModelNode;
}
export interface NodeInstance<T = IPublicTypeComponentInstance> {
docId: string;
nodeId: string;
instance: T;
node?: Node | null;
}
export interface IDesigner {
get dragon(): IPublicModelDragon;
get activeTracker(): IPublicModelActiveTracker;
createScroller(scrollable: IPublicModelScrollable): IPublicModelScroller;
/**
* dragon
*/
createLocation(locationData: IPublicTypeLocationData): IPublicModelDropLocation;
}

View File

@ -1,82 +0,0 @@
import { NodeInstance } from './designer';
import {
IPublicModelDocumentModel,
IPublicModelLocateEvent,
IPublicModelDropLocation,
IPublicTypeComponentInstance,
} from './shell';
import { IPublicTypeDragObject } from './shell/type/drag-object';
export interface LocateEvent {
readonly type: 'LocateEvent';
/**
*
*/
readonly globalX: number;
readonly globalY: number;
/**
*
*/
readonly originalEvent: MouseEvent | DragEvent;
/**
*
*/
readonly dragObject: IPublicTypeDragObject;
/**
*
*/
sensor?: ISensor;
// ======= 以下是 激活的 sensor 将填充的值 ========
/**
*
*/
target?: Element | null;
/**
*
*/
canvasX?: number;
canvasY?: number;
/**
*
*/
documentModel?: IPublicModelDocumentModel;
/**
* canvasX,canvasY,
*/
fixed?: true;
}
/**
*
*/
export interface ISensor {
/**
* false
*/
readonly sensorAvailable: boolean;
/**
*
*/
fixEvent(e: IPublicModelLocateEvent): IPublicModelLocateEvent;
/**
*
*/
locate(e: IPublicModelLocateEvent): IPublicModelDropLocation | undefined | null;
/**
*
*/
isEnter(e: IPublicModelLocateEvent): boolean;
/**
*
*/
deactiveSensor(): void;
/**
*
*/
getNodeInstanceFromElement?: (e: Element | null) => NodeInstance<IPublicTypeComponentInstance> | null;
}

View File

@ -1,8 +0,0 @@
export interface IArea<C, T> {
isEmpty(): boolean;
add(config: T | C): T;
remove(config: T | string): number;
setVisible(flag: boolean): void;
hide(): void;
show(): void;
}

View File

@ -1,34 +1,6 @@
import { ReactNode, ComponentType } from 'react'; import { ReactNode, ComponentType } from 'react';
import { IPublicTypeNpmInfo, IPublicModelEditor } from './shell'; import { IPublicTypeNpmInfo, IPublicModelEditor } from './shell';
export type KeyType = (new (...args: any[]) => any) | symbol | string;
export type ClassType = new (...args: any[]) => any;
export interface GetOptions {
forceNew?: boolean;
sourceCls?: ClassType;
}
export type GetReturnType<T, ClsType> = T extends undefined
? ClsType extends {
prototype: infer R;
}
? R
: any
: T;
/**
* duck-typed power-di
*
* @see https://www.npmjs.com/package/power-di
*/
export interface PowerDIRegisterOptions {
/** default: true */
singleton?: boolean;
/** if data a class, auto new a instance.
* if data a function, auto run(lazy).
* default: true */
autoNew?: boolean;
}
export interface EditorConfig { export interface EditorConfig {
skeleton?: SkeletonConfig; skeleton?: SkeletonConfig;
theme?: ThemeConfig; theme?: ThemeConfig;
@ -173,9 +145,3 @@ export interface PluginStatus {
export interface PluginStatusSet { export interface PluginStatusSet {
[key: string]: PluginStatus; [key: string]: PluginStatus;
} }
export enum EDITOR_EVENT {
NODE_CHILDREN_CHANGE = 'node.children.change',
NODE_VISIBLE_CHANGE = 'node.visible.change',
}

View File

@ -1,29 +1,10 @@
export * from '@alilc/lowcode-datasource-types'; export * from '@alilc/lowcode-datasource-types';
export * from './editor'; export * from './editor';
export * from './shell/type/field-extra-props';
export * from './shell/type/i18n-map';
export * from './shell/type/icon-config';
export * from './shell/type/metadata';
export * from './shell/type/npm';
export * from './shell/type/prop-types';
export * from './schema';
export * from './activity'; export * from './activity';
export * from './shell/type/tip-config';
export * from './shell/type/title-content';
export * from './utils';
export * from './shell/type/value-type';
export * from './shell/type/setter-config';
export * from './shell/model/setting-target';
export * from './node';
export * from './shell/enum/transform-stage';
export * from './code-intermediate'; export * from './code-intermediate';
export * from './code-result'; export * from './code-result';
export * from './assets'; export * from './assets';
export * as GlobalEvent from './event'; export * as GlobalEvent from './event';
export * from './shell/type/props-transducer';
export * from './editor-skeleton';
export * from './designer';
export * from './dragon';
export * from './shell'; export * from './shell';
export * from './shell-model-factory'; export * from './shell-model-factory';
// TODO: remove this in future versions // TODO: remove this in future versions

View File

@ -1,10 +0,0 @@
export interface NodeStatus {
locking: boolean;
pseudo: boolean;
inPlaceEditing: boolean;
}
export interface LeafNode extends Node {
readonly children: null;
}

View File

@ -1,19 +0,0 @@
import { IPublicTypeNodeSchema } from './shell/type/node-schema';
import { IPublicTypeNodeData } from './shell/type/node-data';
export type NodeDataType = IPublicTypeNodeData | IPublicTypeNodeData[];
/**
* Slot schema
*/
export interface SlotSchema extends IPublicTypeNodeSchema {
componentName: 'Slot';
name?: string;
title?: string;
params?: string[];
props?: {
slotTitle?: string;
slotName?: string;
slotParams?: string[];
};
children?: IPublicTypeNodeSchema[];
}

View File

@ -1,31 +1,46 @@
import { IPublicModelWindow } from '../model'; import { IPublicModelWindow } from '../model';
import { IPublicResourceOptions } from '../type'; import { IPublicApiPlugins, IPublicModelResource, IPublicResourceList, IPublicTypeResourceType } from '@alilc/lowcode-types';
import { IPublicApiPlugins } from '@alilc/lowcode-types';
export interface IPublicApiWorkspace { export interface IPublicApiWorkspace {
/** 是否启用 workspace 模式 */ /** 是否启用 workspace 模式 */
isActive: boolean; isActive: boolean;
/** 当前设计器窗口 */ /** 当前设计器窗口 */
window: IPublicModelWindow; window: IPublicModelWindow;
/** 注册资源 */
registerResourceType(resourceName: string, resourceType: 'editor', options: IPublicResourceOptions): void;
/** 打开视图窗口 */
openEditorWindow(resourceName: string, title: string, viewType?: string): void;
/** 移除窗口 */
removeEditorWindow(resourceName: string, title: string): void;
plugins: IPublicApiPlugins; plugins: IPublicApiPlugins;
/** 当前设计器的编辑窗口 */ /** 当前设计器的编辑窗口 */
windows: IPublicModelWindow[]; windows: IPublicModelWindow[];
/** 获取资源树列表 */
get resourceList(): IPublicModelResource[];
/** 设置资源树列表 */
setResourceList(resourceList: IPublicResourceList): void;
/** 资源树列表更新事件 */
onResourceListChange(fn: (resourceList: IPublicResourceList) => void): () => void;
/** 注册资源 */
registerResourceType(resourceTypeModel: IPublicTypeResourceType): void;
/** 打开视图窗口 */
openEditorWindow(resourceName: string, title: string, extra: Object, viewName?: string): void;
/** 通过视图 id 打开窗口 */
openEditorWindowById(id: string): void;
/** 移除视图窗口 */
removeEditorWindow(resourceName: string, title: string): void;
/** 通过视图 id 移除窗口 */
removeEditorWindowById(id: string): void;
/** 窗口新增/删除的事件 */ /** 窗口新增/删除的事件 */
onChangeWindows: (fn: () => void) => void; onChangeWindows(fn: () => void): void;
/** active 窗口变更事件 */ /** active 窗口变更事件 */
onChangeActiveWindow: (fn: () => void) => void; onChangeActiveWindow(fn: () => void): void;
} }

View File

@ -1,39 +1,46 @@
import { IPublicModelNode } from './'; import { IPublicModelNode } from './';
import { IPublicTypeDisposable } from '../type';
export interface IPublicModelDetecting { export interface IPublicModelDetecting {
/** /**
* hover *
* check if current detecting is enabled
* @since v1.1.0
*/ */
get enable(): boolean; get enable(): boolean;
/** /**
* hover * hover
* get current hovering node
* @since v1.0.16 * @since v1.0.16
*/ */
get current(): any; get current(): IPublicModelNode | null;
/** /**
* hover * hover
* capture node with nodeId
* @param id id * @param id id
*/ */
capture(id: string): any; capture(id: string): void;
/** /**
* hover * hover
* release node with nodeId
* @param id id * @param id id
*/ */
release(id: string): any; release(id: string): void;
/** /**
* hover * hover
* clear all hover state
*/ */
leave(): any; leave(): void;
/** /**
* hover * hover
* set callback which will be called when hovering object changed. * set callback which will be called when hovering object changed.
* @since v1.1.0 * @since v1.1.0
*/ */
onDetectingChange(fn: (node: IPublicModelNode) => void): () => void; onDetectingChange(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable;
} }

View File

@ -2,7 +2,7 @@ import { IPublicTypeRootSchema, IPublicTypeDragNodeDataObject, IPublicTypeDragNo
import { IPublicEnumTransformStage } from '../enum'; import { IPublicEnumTransformStage } from '../enum';
import { IPublicApiProject } from '../api'; import { IPublicApiProject } from '../api';
import { IPublicModelDropLocation, IPublicModelDetecting, IPublicModelNode, IPublicModelSelection, IPublicModelHistory, IPublicModelModalNodesManager } from './'; import { IPublicModelDropLocation, IPublicModelDetecting, IPublicModelNode, IPublicModelSelection, IPublicModelHistory, IPublicModelModalNodesManager } from './';
import { IPublicOnChangeOptions } from '@alilc/lowcode-types'; import { IPublicTypeOnChangeOptions } from '@alilc/lowcode-types';
export interface IPublicModelDocumentModel { export interface IPublicModelDocumentModel {
@ -168,12 +168,11 @@ export interface IPublicModelDocumentModel {
*/ */
onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): void; onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): void;
/** /**
* document children * document children
* @param fn * @param fn
*/ */
onChangeNodeChildren(fn: (info: IPublicOnChangeOptions) => void): void; onChangeNodeChildren(fn: (info: IPublicTypeOnChangeOptions) => void): void;
/** /**
* document * document
@ -210,7 +209,6 @@ export interface IPublicModelDocumentModel {
*/ */
set dropLocation(loc: IPublicModelDropLocation | null); set dropLocation(loc: IPublicModelDropLocation | null);
/** /**
* *
* triggered focused node is set mannually from plugin * triggered focused node is set mannually from plugin

View File

@ -3,27 +3,26 @@ import { EventEmitter } from 'events';
import StrictEventEmitter from 'strict-event-emitter-types'; import StrictEventEmitter from 'strict-event-emitter-types';
import * as GlobalEvent from '../../event'; import * as GlobalEvent from '../../event';
import { IPublicApiEvent } from '../api'; import { IPublicApiEvent } from '../api';
import { GetOptions, GetReturnType, KeyType, PowerDIRegisterOptions } from '../../editor'; import { IPublicTypeEditorValueKey, IPublicTypeEditorGetOptions, IPublicTypeEditorGetResult, IPublicTypeEditorRegisterOptions } from '../type';
export interface IPublicModelEditor extends StrictEventEmitter<EventEmitter, GlobalEvent.EventConfig> { export interface IPublicModelEditor extends StrictEventEmitter<EventEmitter, GlobalEvent.EventConfig> {
get: <T = undefined, KeyOrType = any>( get: <T = undefined, KeyOrType = any>(
keyOrType: KeyOrType, keyOrType: KeyOrType,
opt?: GetOptions opt?: IPublicTypeEditorGetOptions
) => GetReturnType<T, KeyOrType> | undefined; ) => IPublicTypeEditorGetResult<T, KeyOrType> | undefined;
has: (keyOrType: KeyType) => boolean; has: (keyOrType: IPublicTypeEditorValueKey) => boolean;
set: (key: KeyType, data: any) => void | Promise<void>; set: (key: IPublicTypeEditorValueKey, data: any) => void | Promise<void>;
onceGot: <T = undefined, KeyOrType extends KeyType = any>(keyOrType: KeyOrType) => Promise<GetReturnType<T, KeyOrType>>; onceGot: <T = undefined, KeyOrType extends IPublicTypeEditorValueKey = any>(keyOrType: KeyOrType) => Promise<IPublicTypeEditorGetResult<T, KeyOrType>>;
onGot: <T = undefined, KeyOrType extends KeyType = any>( onGot: <T = undefined, KeyOrType extends IPublicTypeEditorValueKey = any>(
keyOrType: KeyOrType, keyOrType: KeyOrType,
fn: (data: GetReturnType<T, KeyOrType>) => void fn: (data: IPublicTypeEditorGetResult<T, KeyOrType>) => void
) => () => void; ) => () => void;
register: (data: any, key?: KeyType, options?: PowerDIRegisterOptions) => void; register: (data: any, key?: IPublicTypeEditorValueKey, options?: IPublicTypeEditorRegisterOptions) => void;
get eventBus(): IPublicApiEvent; get eventBus(): IPublicApiEvent;
} }

View File

@ -1,49 +1,62 @@
import { IPublicTypeDisposable } from '../type';
export interface IPublicModelHistory { export interface IPublicModelHistory {
/** /**
* *
* go to a specific history
* @param cursor * @param cursor
*/ */
go(cursor: number): void; go(cursor: number): void;
/** /**
* 退 * 退
* go backward in history
*/ */
back(): void; back(): void;
/** /**
* *
* go forward in history
*/ */
forward(): void; forward(): void;
/** /**
* *
* do save current change as a record in history
*/ */
savePoint(): void; savePoint(): void;
/** /**
* *
* @returns * check if there is unsaved change for history
*/ */
isSavePoint(): boolean; isSavePoint(): boolean;
/** /**
* state退 * state退
* @returns * get flags in number which indicat current change state
*
* | 1 | 1 | 1 |
* | -------- | -------- | -------- |
* | modified | redoable | undoable |
* eg.
* 7 means : modified && redoable && undoable
* 5 means : modified && undoable
*/ */
getState(): any; getState(): number;
/** /**
* state * state
* monitor on stateChange event
* @param func * @param func
* @returns
*/ */
onChangeState(func: () => any): () => void; onChangeState(func: () => any): IPublicTypeDisposable;
/** /**
* *
* monitor on cursorChange event
* @param func * @param func
* @returns
*/ */
onChangeCursor(func: () => any): () => void; onChangeCursor(func: () => any): IPublicTypeDisposable;
} }

View File

@ -27,3 +27,5 @@ export * from './engine-config';
export * from './editor'; export * from './editor';
export * from './preference'; export * from './preference';
export * from './plugin-instance'; export * from './plugin-instance';
export * from './sensor';
export * from './resource';

View File

@ -4,6 +4,7 @@ import { IPublicEnumTransformStage } from '../enum';
import { IPublicModelNodeChildren, IPublicModelComponentMeta, IPublicModelProp, IPublicModelProps, IPublicModelSettingTopEntry, IPublicModelDocumentModel, IPublicModelExclusiveGroup } from './'; import { IPublicModelNodeChildren, IPublicModelComponentMeta, IPublicModelProp, IPublicModelProps, IPublicModelSettingTopEntry, IPublicModelDocumentModel, IPublicModelExclusiveGroup } from './';
export interface IPublicModelNode { export interface IPublicModelNode {
/** /**
* id * id
* node id * node id

View File

@ -3,6 +3,7 @@ import { IPublicTypeCompositeValue } from '../type';
import { IPublicModelNode } from './'; import { IPublicModelNode } from './';
export interface IPublicModelProp { export interface IPublicModelProp {
/** /**
* id * id
*/ */
@ -10,50 +11,60 @@ export interface IPublicModelProp {
/** /**
* key * key
* get key of prop
*/ */
get key(): string | number | undefined; get key(): string | number | undefined;
/** /**
* prop * prop
* get path of current prop
*/ */
get path(): any[]; get path(): string[];
/** /**
* *
* get node instance, which this prop belongs to
*/ */
get node(): IPublicModelNode | null; get node(): IPublicModelNode | null;
/** /**
* prop Slot slotNode
* return the slot node (only if the current prop represents a slot) * return the slot node (only if the current prop represents a slot)
* @since v1.1.0
*/ */
get slotNode(): IPublicModelNode | null; get slotNode(): IPublicModelNode | undefined | null;
/** /**
* judge if it is a prop or not * Prop , true
* check if it is a prop or not, and of course always return true
* @experimental
*/ */
get isProp(): boolean; get isProp(): boolean;
/** /**
* *
* set value for this prop
* @param val * @param val
*/ */
setValue(val: IPublicTypeCompositeValue): void; setValue(val: IPublicTypeCompositeValue): void;
/** /**
* *
* @returns * get value of this prop
*/ */
getValue(): any; getValue(): any;
/** /**
* *
* remove value of this prop
* @since v1.0.16
*/ */
remove(): void; remove(): void;
/** /**
* *
* export schema
* @param stage * @param stage
* @returns
*/ */
exportSchema(stage: IPublicEnumTransformStage): IPublicTypeCompositeValue; exportSchema(stage: IPublicEnumTransformStage): IPublicTypeCompositeValue;
} }

View File

@ -2,6 +2,7 @@ import { IPublicTypeCompositeValue } from '../type';
import { IPublicModelNode, IPublicModelProp } from './'; import { IPublicModelNode, IPublicModelProp } from './';
export interface IPublicModelProps { export interface IPublicModelProps {
/** /**
* id * id
*/ */
@ -9,8 +10,9 @@ export interface IPublicModelProps {
/** /**
* props * props
* return path of current props
*/ */
get path(): any[]; get path(): string[];
/** /**
* node * node
@ -19,62 +21,64 @@ export interface IPublicModelProps {
/** /**
* path * path
* get prop by path
* @param path a / a.b / a.0 * @param path a / a.b / a.0
* @returns
*/ */
getProp(path: string): IPublicModelProp | null; getProp(path: string): IPublicModelProp | null;
/** /**
* path * path
* get value of prop by path
* @param path a / a.b / a.0 * @param path a / a.b / a.0
* @returns
*/ */
getPropValue(path: string): any; getPropValue(path: string): any;
/** /**
* path * path
* props props * props props
* get extra prop by path
* @param path a / a.b / a.0 * @param path a / a.b / a.0
* @returns
*/ */
getExtraProp(path: string): IPublicModelProp | null; getExtraProp(path: string): IPublicModelProp | null;
/** /**
* path * path
* props props * props props
* get value of extra prop by path
* @param path a / a.b / a.0 * @param path a / a.b / a.0
* @returns
*/ */
getExtraPropValue(path: string): any; getExtraPropValue(path: string): any;
/** /**
* path * path
* set value of prop by path
* @param path a / a.b / a.0 * @param path a / a.b / a.0
* @param value * @param value
* @returns
*/ */
setPropValue(path: string, value: IPublicTypeCompositeValue): void; setPropValue(path: string, value: IPublicTypeCompositeValue): void;
/** /**
* path * path
* set value of extra prop by path
* @param path a / a.b / a.0 * @param path a / a.b / a.0
* @param value * @param value
* @returns
*/ */
setExtraPropValue(path: string, value: IPublicTypeCompositeValue): void; setExtraPropValue(path: string, value: IPublicTypeCompositeValue): void;
/** /**
* test if the specified key is existing or not. * props prop
* check if the specified key is existing or not.
* @param key * @param key
* @returns * @since v1.1.0
*/ */
has(key: string): boolean; has(key: string): boolean;
/** /**
* prop
* add a key with given value * add a key with given value
* @param value * @param value
* @param key * @param key
* @returns * @since v1.1.0
*/ */
add(value: IPublicTypeCompositeValue, key?: string | number | undefined): any; add(value: IPublicTypeCompositeValue, key?: string | number | undefined): any;

View File

@ -0,0 +1,16 @@
import { ReactElement } from 'react';
import { IPublicModelResourceType } from './resource-type';
export interface IPublicModelResource {
get title(): string | undefined;
get icon(): ReactElement | undefined;
get options(): Object;
get name(): string | undefined;
get type(): string | undefined;
get category(): string | undefined;
}

View File

@ -1,66 +1,76 @@
import { IPublicModelNode } from './'; import { IPublicModelNode } from './';
import { IPublicTypeDisposable } from '../type';
export interface IPublicModelSelection { export interface IPublicModelSelection {
/** /**
* id * id
* get ids of selected nodes
*/ */
get selected(): string[]; get selected(): string[];
/** /**
* return selected Node instance *
* return selected Node instancereturn the first one if multiple nodes are selected
* @since v1.1.0
*/ */
get node(): IPublicModelNode | null; get node(): IPublicModelNode | null;
/** /**
* *
* select node with id, this will override current selection
* @param id * @param id
*/ */
select(id: string): void; select(id: string): void;
/** /**
* *
* select node with ids, this will override current selection
*
* @param ids * @param ids
*/ */
selectAll(ids: string[]): void; selectAll(ids: string[]): void;
/** /**
* *
* remove node from selection with node id
* @param id * @param id
*/ */
remove(id: string): void; remove(id: string): void;
/** /**
* *
* clear current selection
*/ */
clear(): void; clear(): void;
/** /**
* *
* check if node with specific id is selected
* @param id * @param id
* @returns
*/ */
has(id: string): boolean; has(id: string): boolean;
/** /**
* *
* add node with specific id to selection
* @param id * @param id
*/ */
add(id: string): void; add(id: string): void;
/** /**
* *
* @returns * get selected nodes
*/ */
getNodes(): IPublicModelNode[]; getNodes(): IPublicModelNode[];
/** /**
* *
* get seleted top nodes
* for example: * for example:
* getNodes() returns [A, subA, B], then * getNodes() returns [A, subA, B], then
* getTopNodes() will return [A, B], subA will be removed * getTopNodes() will return [A, B], subA will be removed
* @since v1.0.16 * @since v1.0.16
* @returns
*/ */
getTopNodes(includeRoot?: boolean): IPublicModelNode[]; getTopNodes(includeRoot?: boolean): IPublicModelNode[];
@ -69,5 +79,5 @@ export interface IPublicModelSelection {
* set callback which will be called when selection is changed * set callback which will be called when selection is changed
* @since v1.1.0 * @since v1.1.0
*/ */
onSelectionChange(fn: (ids: string[]) => void): () => void; onSelectionChange(fn: (ids: string[]) => void): IPublicTypeDisposable;
} }

View File

@ -0,0 +1,42 @@
import { IPublicTypeNodeInstance } from '../type/node-instance';
import {
IPublicModelLocateEvent,
IPublicModelDropLocation,
IPublicTypeComponentInstance,
} from '..';
/**
*
*/
export interface IPublicModelSensor {
/**
* false
*/
readonly sensorAvailable: boolean;
/**
*
*/
fixEvent(e: IPublicModelLocateEvent): IPublicModelLocateEvent;
/**
*
*/
locate(e: IPublicModelLocateEvent): IPublicModelDropLocation | undefined | null;
/**
*
*/
isEnter(e: IPublicModelLocateEvent): boolean;
/**
*
*/
deactiveSensor(): void;
/**
*
*/
getNodeInstanceFromElement?: (e: Element | null) => IPublicTypeNodeInstance<IPublicTypeComponentInstance> | null;
}

View File

@ -1,6 +1,21 @@
import { ReactElement } from 'react';
import { IPublicTypeNodeSchema } from '../type'; import { IPublicTypeNodeSchema } from '../type';
import { IPublicModelResource } from './resource';
export interface IPublicModelWindow { export interface IPublicModelWindow {
/** 窗口 id */
id: string;
/** 窗口标题 */
title?: string;
/** 窗口 icon */
icon?: ReactElement;
/** 窗口资源类型 */
resource?: IPublicModelResource;
/** 当前窗口导入 schema */ /** 当前窗口导入 schema */
importSchema(schema: IPublicTypeNodeSchema): void; importSchema(schema: IPublicTypeNodeSchema): void;
@ -9,13 +24,4 @@ export interface IPublicModelWindow {
/** 调用当前窗口视图保存钩子 */ /** 调用当前窗口视图保存钩子 */
save(): Promise<any>; save(): Promise<any>;
/** 窗口 id */
id: string;
/** 窗口标题 */
title?: string;
/** 窗口资源名字 */
resourceName?: string;
} }

View File

@ -0,0 +1,5 @@
export interface IPublicTypeEditorGetOptions {
forceNew?: boolean;
sourceCls?: new (...args: any[]) => any;
}

View File

@ -0,0 +1,4 @@
export type IPublicTypeEditorGetResult<T, ClsType> = T extends undefined ? ClsType extends {
prototype: infer R;
} ? R : any : T;

View File

@ -0,0 +1,19 @@
/**
* duck-typed power-di
*
* @see https://www.npmjs.com/package/power-di
*/
export interface IPublicTypeEditorRegisterOptions {
/**
* default: true
*/
singleton?: boolean;
/**
* if data a class, auto new a instance.
* if data a function, auto run(lazy).
* default: true
*/
autoNew?: boolean;
}

View File

@ -0,0 +1,2 @@
export type IPublicTypeEditorValueKey = (new (...args: any[]) => any) | symbol | string;

View File

@ -0,0 +1,8 @@
export interface IPublicEditorViewConfig {
/** 视图初始化钩子 */
init?: () => Promise<void>;
/** 资源保存时,会调用视图的钩子 */
save?: () => Promise<void>;
}

View File

@ -0,0 +1,12 @@
import { IPublicEditorViewConfig } from './editor-view-config';
export interface IPublicTypeEditorView {
/** 资源名字 */
viewName: string;
/** 资源类型 */
viewType?: 'editor' | 'webview';
(ctx: any, options: any): IPublicEditorViewConfig;
}

View File

@ -1,6 +1,6 @@
// this folder contains all interfaces/types working as type definition // this folder contains all interfaces/types working as type definition
// - some exists as type TypeName // - some exists as type TypeName
// - some althought exists as interfaces , but there won`t be a class implements them. // - some althought exists as interfaces , but there won`t be any class implements them.
// all of above cases will with prefix IPublicType, eg. IPublicTypeSomeName // all of above cases will with prefix IPublicType, eg. IPublicTypeSomeName
export * from './location'; export * from './location';
export * from './active-target'; export * from './active-target';
@ -73,5 +73,17 @@ export * from './tip-config';
export * from './widget-config-area'; export * from './widget-config-area';
export * from './hotkey-callback'; export * from './hotkey-callback';
export * from './plugin-register-options'; export * from './plugin-register-options';
export * from './resource-options'; export * from './resource-list';
export * from './engine-options'; export * from './engine-options';
export * from './on-change-options';
export * from './slot-schema';
export * from './node-data-type';
export * from './node-instance';
export * from './editor-value-key';
export * from './editor-get-options';
export * from './editor-get-result';
export * from './editor-register-options';
export * from './editor-view';
export * from './resource-type';
export * from './resource-type-config';
export * from './editor-view-config';

View File

@ -0,0 +1,3 @@
import { IPublicTypeNodeData } from './node-data';
export type IPublicTypeNodeDataType = IPublicTypeNodeData | IPublicTypeNodeData[];

View File

@ -0,0 +1,8 @@
import { IPublicTypeComponentInstance, IPublicModelNode } from '..';
export interface IPublicTypeNodeInstance<T = IPublicTypeComponentInstance> {
docId: string;
nodeId: string;
instance: T;
node?: IPublicModelNode | null;
}

View File

@ -0,0 +1,6 @@
import { IPublicModelNode } from '..';
export interface IPublicTypeOnChangeOptions {
type: string;
node: IPublicModelNode;
}

View File

@ -0,0 +1,10 @@
export interface IPublicResourceData {
resourceName: string;
title: string;
category: string;
options: {
[key: string]: any;
};
}
export type IPublicResourceList = IPublicResourceData[];

View File

@ -1,44 +0,0 @@
export interface IPublicViewFunctions {
/** 视图初始化钩子 */
init?: () => Promise<void>;
/** 资源保存时,会调用视图的钩子 */
save?: () => Promise<void>;
}
export interface IPublicEditorView {
/** 资源名字 */
viewName: string;
/** 资源类型 */
viewType?: 'editor' | 'webview';
(ctx: any): IPublicViewFunctions;
}
export interface IPublicResourceOptions {
/** 资源名字 */
name: string;
/** 资源描述 */
description?: string;
/** 资源 icon 标识 */
icon?: React.ReactElement;
/** 默认视图类型 */
defaultViewType: string;
/** 资源视图 */
editorViews: IPublicEditorView[];
/** save 钩子 */
save?: (schema: {
[viewName: string]: any;
}) => Promise<void>;
/** import 钩子 */
import?: (schema: any) => Promise<{
[viewName: string]: any;
}>;
/** 默认标题 */
defaultTitle?: string;
}

View File

@ -0,0 +1,31 @@
import { IPublicTypeEditorView } from './editor-view';
export interface IPublicResourceTypeConfig {
/** 资源描述 */
description?: string;
/** 资源 icon 标识 */
icon?: React.ReactElement;
/** 默认视图类型 */
defaultViewType: string;
/** 资源视图 */
editorViews: IPublicTypeEditorView[];
init?: () => void;
/** save 钩子 */
save?: (schema: {
[viewName: string]: any;
}) => Promise<void>;
/** import 钩子 */
import?: (schema: any) => Promise<{
[viewName: string]: any;
}>;
/** 默认标题 */
defaultTitle?: string;
}

View File

@ -0,0 +1,10 @@
import { IPublicModelPluginContext } from '../model';
import { IPublicResourceTypeConfig } from './resource-type-config';
export interface IPublicTypeResourceType {
resourceName: string;
resourceType: string;
(ctx: IPublicModelPluginContext): IPublicResourceTypeConfig;
}

View File

@ -0,0 +1,17 @@
import { IPublicTypeNodeSchema } from './node-schema';
/**
* Slot schema
*/
export interface IPublicTypeSlotSchema extends IPublicTypeNodeSchema {
componentName: 'Slot';
name?: string;
title?: string;
params?: string[];
props?: {
slotTitle?: string;
slotName?: string;
slotParams?: string[];
};
children?: IPublicTypeNodeSchema[];
}

View File

@ -7,16 +7,19 @@ import { IPublicTypeNodeData, IPublicTypeCompositeValue, IPublicTypeNodeSchema }
*/ */
export interface IPublicTypeJSExpression { export interface IPublicTypeJSExpression {
type: 'JSExpression'; type: 'JSExpression';
/** /**
* *
*/ */
value: string; value: string;
/** /**
* *
* *
* @todo * @todo
*/ */
mock?: any; mock?: any;
/** /**
* *
* *
@ -33,6 +36,7 @@ export interface IPublicTypeJSExpression {
*/ */
export interface IPublicTypeJSFunction { export interface IPublicTypeJSFunction {
type: 'JSFunction'; type: 'JSFunction';
/** /**
* *
*/ */
@ -66,21 +70,34 @@ export interface IPublicTypeJSFunction {
* ReactNode Function return ReactNode * ReactNode Function return ReactNode
*/ */
export interface IPublicTypeJSSlot { export interface IPublicTypeJSSlot {
/**
* type
*/
type: 'JSSlot'; type: 'JSSlot';
/** /**
* @todo * @todo
*/ */
title?: string; title?: string;
/**
* @todo
*/
id?: string;
/** /**
* Function return ReactNode * Function return ReactNode
* *
* this[] * this[]
*/ */
params?: string[]; params?: string[];
/** /**
* *
*/ */
value?: IPublicTypeNodeData[] | IPublicTypeNodeData; value?: IPublicTypeNodeData[] | IPublicTypeNodeData;
/** /**
* @todo * @todo
*/ */

View File

@ -119,6 +119,10 @@ function getNodeSchemaFromPropsById(props: any, nodeId: string): IPublicTypeNode
} }
} }
/**
* TODO: not sure if this is used anywhere
* @deprecated
*/
export function applyActivities(pivotSchema: IPublicTypeRootSchema, activities: any, options?: any): IPublicTypeRootSchema { export function applyActivities(pivotSchema: IPublicTypeRootSchema, activities: any, options?: any): IPublicTypeRootSchema {
let schema = { ...pivotSchema }; let schema = { ...pivotSchema };
if (!Array.isArray(activities)) { if (!Array.isArray(activities)) {

View File

@ -1,5 +1,5 @@
import { makeObservable, obx } from '@alilc/lowcode-editor-core'; import { makeObservable, obx } from '@alilc/lowcode-editor-core';
import { IPublicEditorView, IPublicViewFunctions } from '@alilc/lowcode-types'; import { IPublicEditorViewConfig, IPublicTypeEditorView } from '@alilc/lowcode-types';
import { flow } from 'mobx'; import { flow } from 'mobx';
import { Workspace as InnerWorkspace } from '../workspace'; import { Workspace as InnerWorkspace } from '../workspace';
import { BasicContext } from '../base-context'; import { BasicContext } from '../base-context';
@ -9,31 +9,12 @@ import { getWebviewPlugin } from '../inner-plugins/webview';
export class Context extends BasicContext { export class Context extends BasicContext {
viewName = 'editor-view'; viewName = 'editor-view';
instance: IPublicViewFunctions; instance: IPublicEditorViewConfig;
viewType: 'editor' | 'webview'; viewType: 'editor' | 'webview';
constructor(public workspace: InnerWorkspace, public editorWindow: EditorWindow, public editorView: IPublicEditorView) {
super(workspace, editorView.viewName, editorWindow);
this.viewType = editorView.viewType || 'editor';
this.viewName = editorView.viewName;
this.instance = editorView(this.innerPlugins._getLowCodePluginContext({
pluginName: 'any',
}));
makeObservable(this);
}
@obx _activate = false; @obx _activate = false;
setActivate = (_activate: boolean) => {
this._activate = _activate;
this.innerHotkey.activate(this._activate);
};
get active() {
return this._activate;
}
@obx isInit: boolean = false; @obx isInit: boolean = false;
init = flow(function* (this: any) { init = flow(function* (this: any) {
@ -48,6 +29,25 @@ export class Context extends BasicContext {
this.isInit = true; this.isInit = true;
}); });
constructor(public workspace: InnerWorkspace, public editorWindow: EditorWindow, public editorView: IPublicTypeEditorView, options: Object) {
super(workspace, editorView.viewName, editorWindow);
this.viewType = editorView.viewType || 'editor';
this.viewName = editorView.viewName;
this.instance = editorView(this.innerPlugins._getLowCodePluginContext({
pluginName: 'any',
}), options);
makeObservable(this);
}
setActivate = (_activate: boolean) => {
this._activate = _activate;
this.innerHotkey.activate(this._activate);
};
get active() {
return this._activate;
}
async save() { async save() {
return await this.instance?.save?.(); return await this.instance?.save?.();
} }

View File

@ -8,16 +8,16 @@ export class EditorWindow {
id: string = uniqueId('window'); id: string = uniqueId('window');
icon: React.ReactElement | undefined; icon: React.ReactElement | undefined;
constructor(readonly resource: Resource, readonly workspace: Workspace, public title: string | undefined = '') { @obx.ref editorView: Context;
@obx editorViews: Map<string, Context> = new Map<string, Context>();
constructor(readonly resource: Resource, readonly workspace: Workspace, public title: string | undefined = '', private options: Object = {}) {
makeObservable(this); makeObservable(this);
this.init(); this.init();
this.icon = resource.icon; this.icon = resource.icon;
} }
get resourceName(): string {
return this.resource.options.name;
}
async importSchema(schema: any) { async importSchema(schema: any) {
const newSchema = await this.resource.import(schema); const newSchema = await this.resource.import(schema);
@ -72,16 +72,12 @@ export class EditorWindow {
this.changeViewType(this.resource.defaultViewType); this.changeViewType(this.resource.defaultViewType);
}; };
@obx.ref editorView: Context;
@obx editorViews: Map<string, Context> = new Map<string, Context>();
initViewType = async (name: string) => { initViewType = async (name: string) => {
const viewInfo = this.resource.getEditorView(name); const viewInfo = this.resource.getEditorView(name);
if (this.editorViews.get(name)) { if (this.editorViews.get(name)) {
return; return;
} }
const editorView = new Context(this.workspace, this, viewInfo as any); const editorView = new Context(this.workspace, this, viewInfo as any, this.options);
this.editorViews.set(name, editorView); this.editorViews.set(name, editorView);
}; };

View File

@ -1,4 +1,4 @@
export { Workspace } from './workspace'; export { Workspace } from './workspace';
export { Resource } from './resource';
export * from './editor-window/context'; export * from './editor-window/context';
export * from './layouts/workbench'; export * from './layouts/workbench';
export { Resource } from './resource';

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