Skip to content

Commit f6537f5

Browse files
liujupingJackLian
authored andcommitted
feat: lowCode components support project schema
1 parent fb3aea4 commit f6537f5

File tree

11 files changed

+111
-49
lines changed

11 files changed

+111
-49
lines changed

packages/designer/src/builtin-simulator/renderer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { Component } from '../simulator';
2-
import { IPublicTypeNodeSchema, IPublicTypeComponentInstance, IPublicTypeNodeInstance, Asset } from '@alilc/lowcode-types';
2+
import { IPublicTypeComponentInstance, IPublicTypeNodeInstance, Asset, IPublicTypeComponentSchema, IPublicTypeProjectSchema, IPublicTypeLowCodeComponent } from '@alilc/lowcode-types';
33

44
export interface BuiltinSimulatorRenderer {
55
readonly isSimulatorRenderer: true;
66
autoRepaintNode?: boolean;
77
components: Record<string, Component>;
88
rerender: () => void;
9-
createComponent(schema: IPublicTypeNodeSchema): Component | null;
9+
createComponent(schema: IPublicTypeProjectSchema<IPublicTypeComponentSchema>): Component | null;
1010
getComponent(componentName: string): Component;
1111
getClosestNodeInstance(
1212
from: IPublicTypeComponentInstance,

packages/rax-simulator-renderer/src/renderer.ts

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { BuiltinSimulatorRenderer, Component, DocumentModel, Node } from '@alilc/lowcode-designer';
2-
import { IPublicTypeComponentSchema, IPublicTypeNodeSchema, IPublicTypeNpmInfo, IPublicEnumTransformStage, IPublicTypeNodeInstance } from '@alilc/lowcode-types';
3-
import { Asset, compatibleLegaoSchema, cursor, isElement, isESModule, isPlainObject, isReactComponent, setNativeSelection } from '@alilc/lowcode-utils';
1+
import { BuiltinSimulatorRenderer, Component, IBaseNode, IDocumentModel } from '@alilc/lowcode-designer';
2+
import { IPublicTypeComponentSchema, IPublicTypeNodeSchema, IPublicTypeNpmInfo, IPublicEnumTransformStage, IPublicTypeNodeInstance, IPublicTypeProjectSchema } from '@alilc/lowcode-types';
3+
import { Asset, compatibleLegaoSchema, cursor, isElement, isESModule, isLowcodeProjectSchema, isComponentSchema, isPlainObject, isReactComponent, setNativeSelection } from '@alilc/lowcode-utils';
44
import LowCodeRenderer from '@alilc/lowcode-rax-renderer';
55
import { computed, observable as obx, makeObservable, configure } from 'mobx';
66
import DriverUniversal from 'driver-universal';
@@ -47,15 +47,23 @@ const builtinComponents = {
4747
function buildComponents(
4848
libraryMap: LibraryMap,
4949
componentsMap: { [componentName: string]: IPublicTypeNpmInfo | ComponentType<any> | IPublicTypeComponentSchema },
50-
createComponent: (schema: IPublicTypeComponentSchema) => Component | null,
50+
createComponent: (schema: IPublicTypeProjectSchema<IPublicTypeComponentSchema>) => Component | null,
5151
) {
5252
const components: any = {
5353
...builtinComponents,
5454
};
5555
Object.keys(componentsMap).forEach((componentName) => {
5656
let component = componentsMap[componentName];
57-
if (component && (component as IPublicTypeComponentSchema).componentName === 'Component') {
58-
components[componentName] = createComponent(component as IPublicTypeComponentSchema);
57+
if (component && (isLowcodeProjectSchema(component) || isComponentSchema(component))) {
58+
if (isComponentSchema(component)) {
59+
components[componentName] = createComponent({
60+
version: '',
61+
componentsMap: [],
62+
componentsTree: [component],
63+
});
64+
} else {
65+
components[componentName] = createComponent(component);
66+
}
5967
} else if (isReactComponent(component)) {
6068
components[componentName] = component;
6169
} else {
@@ -110,7 +118,7 @@ export class DocumentInstance {
110118
return this.document.export(IPublicEnumTransformStage.Render);
111119
}
112120

113-
constructor(readonly container: SimulatorRendererContainer, readonly document: DocumentModel) {
121+
constructor(readonly container: SimulatorRendererContainer, readonly document: IDocumentModel) {
114122
makeObservable(this);
115123
}
116124

@@ -221,7 +229,7 @@ export class DocumentInstance {
221229
return this.instancesMap.get(id) || null;
222230
}
223231

224-
getNode(id: string): Node<IPublicTypeNodeSchema> | null {
232+
getNode(id: string): IBaseNode<IPublicTypeNodeSchema> | null {
225233
return this.document.getNode(id);
226234
}
227235
}
@@ -256,6 +264,8 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
256264
// sync designMode
257265
this._designMode = host.designMode;
258266

267+
this._locale = host.locale;
268+
259269
// sync requestHandlersMap
260270
this._requestHandlersMap = host.requestHandlersMap;
261271

@@ -343,11 +353,11 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
343353
// TODO: remove this.createComponent
344354
this._components = buildComponents(this._libraryMap, this._componentsMap, this.createComponent.bind(this));
345355
}
346-
@obx.ref private _components: any = {};
347-
@computed get components(): object {
356+
@obx.ref private _components: Record<string, React.FC | React.ComponentClass> | null = {};
357+
@computed get components(): Record<string, React.FC | React.ComponentClass> {
348358
// 根据 device 选择不同组件,进行响应式
349359
// 更好的做法是,根据 device 选择加载不同的组件资源,甚至是 simulatorUrl
350-
return this._components;
360+
return this._components || {};
351361
}
352362
// context from: utils、constants、history、location、match
353363
@obx.ref private _appContext = {};
@@ -362,6 +372,10 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
362372
@computed get device() {
363373
return this._device;
364374
}
375+
@obx.ref private _locale: string | undefined = undefined;
376+
@computed get locale() {
377+
return this._locale;
378+
}
365379
@obx.ref private _requestHandlersMap = null;
366380
@computed get requestHandlersMap(): any {
367381
return this._requestHandlersMap;
@@ -378,12 +392,15 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
378392
return loader.load(asset);
379393
}
380394

395+
async loadAsyncLibrary(asyncLibraryMap: Record<string, any>) {
396+
}
397+
381398
getComponent(componentName: string) {
382399
const paths = componentName.split('.');
383400
const subs: string[] = [];
384401

385402
while (true) {
386-
const component = this._components[componentName];
403+
const component = this._components?.[componentName];
387404
if (component) {
388405
return getSubComponent(component, subs);
389406
}
@@ -416,7 +433,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
416433
// if (instance && SYMBOL_VNID in instance) {
417434
// const docId = (instance.props as any).schema.docId;
418435
return {
419-
docId: instance.props._leaf.document.id,
436+
docId: instance.props._leaf.document?.id || '',
420437
nodeId: instance.props._leaf.getId(),
421438
instance,
422439
node: instance.props._leaf,
@@ -497,17 +514,26 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
497514
this.currentDocumentInstance?.refresh();
498515
}
499516

500-
createComponent(schema: IPublicTypeNodeSchema): Component | null {
501-
const _schema: any = {
502-
...compatibleLegaoSchema(schema),
517+
stopAutoRepaintNode() {
518+
}
519+
520+
enableAutoRepaintNode() {
521+
}
522+
523+
createComponent(schema: IPublicTypeProjectSchema<IPublicTypeComponentSchema>): Component | null {
524+
const _schema: IPublicTypeProjectSchema<IPublicTypeComponentSchema> = {
525+
...schema,
526+
componentsTree: schema.componentsTree.map(compatibleLegaoSchema),
503527
};
504528

505-
if (schema.componentName === 'Component' && (schema as IPublicTypeComponentSchema).css) {
529+
const componentsTreeSchema = _schema.componentsTree[0];
530+
531+
if (componentsTreeSchema.componentName === 'Component' && componentsTreeSchema.css) {
506532
const doc = window.document;
507533
const s = doc.createElement('style');
508534
s.setAttribute('type', 'text/css');
509-
s.setAttribute('id', `Component-${schema.id || ''}`);
510-
s.appendChild(doc.createTextNode((schema as IPublicTypeComponentSchema).css || ''));
535+
s.setAttribute('id', `Component-${componentsTreeSchema.id || ''}`);
536+
s.appendChild(doc.createTextNode(componentsTreeSchema.css || ''));
511537
doc.getElementsByTagName('head')[0].appendChild(s);
512538
}
513539

@@ -520,9 +546,11 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
520546
// @ts-ignore
521547
return createElement(LowCodeRenderer, {
522548
...extraProps,
523-
schema: _schema,
549+
schema: componentsTreeSchema,
524550
components,
525551
designMode: '',
552+
locale: renderer.locale,
553+
messages: _schema.i18n || {},
526554
device: renderer.device,
527555
appHelper: renderer.context,
528556
rendererName: 'LowCodeRenderer',

packages/react-simulator-renderer/src/renderer.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ import {
1717
AssetLoader,
1818
getProjectUtils,
1919
} from '@alilc/lowcode-utils';
20-
import { IPublicTypeComponentSchema, IPublicEnumTransformStage, IPublicTypeNodeSchema, IPublicTypeNodeInstance } from '@alilc/lowcode-types';
20+
import { IPublicTypeComponentSchema, IPublicEnumTransformStage, IPublicTypeNodeInstance, IPublicTypeProjectSchema } from '@alilc/lowcode-types';
2121
// just use types
22-
import { BuiltinSimulatorRenderer, Component, DocumentModel, Node } from '@alilc/lowcode-designer';
22+
import { BuiltinSimulatorRenderer, Component, IDocumentModel, INode } from '@alilc/lowcode-designer';
2323
import LowCodeRenderer from '@alilc/lowcode-react-renderer';
2424
import { createMemoryHistory, MemoryHistory } from 'history';
2525
import Slot from './builtin-components/slot';
@@ -94,7 +94,7 @@ export class DocumentInstance {
9494
return this.document.id;
9595
}
9696

97-
constructor(readonly container: SimulatorRendererContainer, readonly document: DocumentModel) {
97+
constructor(readonly container: SimulatorRendererContainer, readonly document: IDocumentModel) {
9898
makeObservable(this);
9999
}
100100

@@ -173,7 +173,7 @@ export class DocumentInstance {
173173
mountContext() {
174174
}
175175

176-
getNode(id: string): Node | null {
176+
getNode(id: string): INode | null {
177177
return this.document.getNode(id);
178178
}
179179

@@ -207,12 +207,12 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
207207

208208
private _libraryMap: { [key: string]: string } = {};
209209

210-
private _components: any = {};
210+
private _components: Record<string, React.FC | React.ComponentClass> | null = {};
211211

212-
get components(): object {
212+
get components(): Record<string, React.FC | React.ComponentClass> {
213213
// 根据 device 选择不同组件,进行响应式
214214
// 更好的做法是,根据 device 选择加载不同的组件资源,甚至是 simulatorUrl
215-
return this._components;
215+
return this._components || {};
216216
}
217217
// context from: utils、constants、history、location、match
218218
@obx.ref private _appContext: any = {};
@@ -388,7 +388,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
388388
const subs: string[] = [];
389389

390390
while (true) {
391-
const component = this._components[componentName];
391+
const component = this._components?.[componentName];
392392
if (component) {
393393
return getSubComponent(component, subs);
394394
}
@@ -430,17 +430,20 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
430430
cursor.release();
431431
}
432432

433-
createComponent(schema: IPublicTypeNodeSchema): Component | null {
434-
const _schema: any = {
435-
...compatibleLegaoSchema(schema),
433+
createComponent(schema: IPublicTypeProjectSchema<IPublicTypeComponentSchema>): Component | null {
434+
const _schema: IPublicTypeProjectSchema<IPublicTypeComponentSchema> = {
435+
...schema,
436+
componentsTree: schema.componentsTree.map(compatibleLegaoSchema),
436437
};
437438

438-
if (schema.componentName === 'Component' && (schema as IPublicTypeComponentSchema).css) {
439+
const componentsTreeSchema = _schema.componentsTree[0];
440+
441+
if (componentsTreeSchema.componentName === 'Component' && componentsTreeSchema.css) {
439442
const doc = window.document;
440443
const s = doc.createElement('style');
441444
s.setAttribute('type', 'text/css');
442-
s.setAttribute('id', `Component-${schema.id || ''}`);
443-
s.appendChild(doc.createTextNode((schema as IPublicTypeComponentSchema).css || ''));
445+
s.setAttribute('id', `Component-${componentsTreeSchema.id || ''}`);
446+
s.appendChild(doc.createTextNode(componentsTreeSchema.css || ''));
444447
doc.getElementsByTagName('head')[0].appendChild(s);
445448
}
446449

@@ -452,9 +455,11 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
452455
return createElement(LowCodeRenderer, {
453456
...extraProps, // 防止覆盖下面内置属性
454457
// 使用 _schema 为了使低代码组件在页面设计中使用变量,同 react 组件使用效果一致
455-
schema: _schema,
458+
schema: componentsTreeSchema,
456459
components: renderer.components,
457460
designMode: '',
461+
locale: renderer.locale,
462+
messages: _schema.i18n || {},
458463
device: renderer.device,
459464
appHelper: renderer.context,
460465
rendererName: 'LowCodeRenderer',

packages/types/src/shell/type/package.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { EitherOr } from '../../utils';
2-
import { IPublicTypeComponentSchema } from './';
2+
import { IPublicTypeComponentSchema, IPublicTypeProjectSchema } from './';
33

44
/**
55
* 定义组件大包及 external 资源的信息
@@ -51,5 +51,5 @@ export type IPublicTypePackage = EitherOr<{
5151
/**
5252
* 低代码组件 schema 内容
5353
*/
54-
schema?: IPublicTypeComponentSchema;
54+
schema?: IPublicTypeProjectSchema<IPublicTypeComponentSchema>;
5555
}, 'package', 'id'>;

packages/types/src/shell/type/project-schema.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export type IPublicTypeUtilsMap = IPublicTypeUtilItem[];
1919
* 应用描述
2020
*/
2121

22-
export interface IPublicTypeProjectSchema {
22+
export interface IPublicTypeProjectSchema<T = IPublicTypeRootSchema> {
2323
id?: string;
2424
/**
2525
* 当前应用协议版本号
@@ -34,7 +34,7 @@ export interface IPublicTypeProjectSchema {
3434
* 低代码业务组件树描述
3535
* 是长度固定为 1 的数组,即数组内仅包含根容器的描述(低代码业务组件容器类型)
3636
*/
37-
componentsTree: IPublicTypeRootSchema[];
37+
componentsTree: T[];
3838
/**
3939
* 国际化语料
4040
*/

packages/utils/src/build-components.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { ComponentType, forwardRef, createElement, FunctionComponent } from 'react';
2-
import { IPublicTypeNpmInfo, IPublicTypeComponentSchema } from '@alilc/lowcode-types';
2+
import { IPublicTypeNpmInfo, IPublicTypeComponentSchema, IPublicTypeProjectSchema } from '@alilc/lowcode-types';
33
import { isESModule } from './is-es-module';
44
import { isReactComponent, acceptsRef, wrapReactClass } from './is-react';
55
import { isObject } from './is-object';
6+
import { isLowcodeProjectSchema } from './check-types';
7+
import { isComponentSchema } from './check-types/is-component-schema';
68

79
type Component = ComponentType<any> | object;
810
interface LibraryMap {
@@ -95,12 +97,20 @@ function isMixinComponent(components: any) {
9597

9698
export function buildComponents(libraryMap: LibraryMap,
9799
componentsMap: { [componentName: string]: IPublicTypeNpmInfo | ComponentType<any> | IPublicTypeComponentSchema },
98-
createComponent: (schema: IPublicTypeComponentSchema) => Component | null) {
100+
createComponent: (schema: IPublicTypeProjectSchema<IPublicTypeComponentSchema>) => Component | null) {
99101
const components: any = {};
100102
Object.keys(componentsMap).forEach((componentName) => {
101103
let component = componentsMap[componentName];
102-
if (component && (component as IPublicTypeComponentSchema).componentName === 'Component') {
103-
components[componentName] = createComponent(component as IPublicTypeComponentSchema);
104+
if (component && (isLowcodeProjectSchema(component) || isComponentSchema(component))) {
105+
if (isComponentSchema(component)) {
106+
components[componentName] = createComponent({
107+
version: '',
108+
componentsMap: [],
109+
componentsTree: [component],
110+
});
111+
} else {
112+
components[componentName] = createComponent(component);
113+
}
104114
} else if (isReactComponent(component)) {
105115
if (!acceptsRef(component)) {
106116
component = wrapReactClass(component as FunctionComponent);

packages/utils/src/check-types/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,7 @@ export * from './is-drag-any-object';
2020
export * from './is-location-children-detail';
2121
export * from './is-node';
2222
export * from './is-location-data';
23-
export * from './is-setting-field';
23+
export * from './is-setting-field';
24+
export * from './is-lowcode-component-type';
25+
export * from './is-lowcode-project-schema';
26+
export * from './is-component-schema';
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { IPublicTypeComponentSchema } from "@alilc/lowcode-types";
2+
3+
export function isComponentSchema(schema: any): schema is IPublicTypeComponentSchema {
4+
if (typeof schema === 'object') {
5+
return schema.componentName === 'Component';
6+
}
7+
return false
8+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { isProCodeComponentType } from './is-procode-component-type';
2-
import { IPublicTypeComponentMap } from '@alilc/lowcode-types';
2+
import { IPublicTypeComponentMap, IPublicTypeLowCodeComponent } from '@alilc/lowcode-types';
33

44

5-
export function isLowCodeComponentType(desc: IPublicTypeComponentMap): boolean {
5+
export function isLowCodeComponentType(desc: IPublicTypeComponentMap): desc is IPublicTypeLowCodeComponent {
66
return !isProCodeComponentType(desc);
77
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { IPublicTypeComponentSchema, IPublicTypeProjectSchema } from "@alilc/lowcode-types";
2+
import { isComponentSchema } from "./is-component-schema";
3+
4+
export function isLowcodeProjectSchema(data: any): data is IPublicTypeProjectSchema<IPublicTypeComponentSchema> {
5+
return data && data.componentsTree && data.componentsTree.length && isComponentSchema(data.componentsTree[0]);
6+
}

0 commit comments

Comments
 (0)