@chamn/render 0.0.9 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/commonComponent/index.d.ts +12 -0
  2. package/dist/const/index.d.ts +2 -0
  3. package/dist/core/ReactErrorBoundary.d.ts +26 -0
  4. package/dist/core/adapter.d.ts +64 -0
  5. package/dist/core/adapterReact.d.ts +108 -0
  6. package/dist/core/designReactRender.d.ts +47 -0
  7. package/dist/core/refManager.d.ts +7 -0
  8. package/dist/core/render.d.ts +32 -0
  9. package/dist/core/storeManager.d.ts +11 -0
  10. package/dist/core/type.d.ts +9 -0
  11. package/dist/{index.cjs.js → index.js} +2 -2
  12. package/dist/index.js.map +1 -0
  13. package/dist/{index.es.js → index.mjs} +94 -83
  14. package/dist/index.mjs.map +1 -0
  15. package/dist/index.umd.js +1 -1
  16. package/dist/index.umd.js.map +1 -1
  17. package/dist/util/assetsLoader.d.ts +15 -0
  18. package/dist/util/index.d.ts +20 -0
  19. package/package.json +14 -9
  20. package/.eslintignore +0 -1
  21. package/.eslintrc.js +0 -30
  22. package/.prettierrc.json +0 -7
  23. package/CHANGELOG.md +0 -40
  24. package/__tests__/demo.test.ts +0 -3
  25. package/build.config.ts +0 -20
  26. package/dist/index.cjs.js.map +0 -1
  27. package/dist/index.es.js.map +0 -1
  28. package/index.html +0 -16
  29. package/jest.config.js +0 -196
  30. package/public/vite.svg +0 -1
  31. package/src/_dev_/components.tsx +0 -12
  32. package/src/_dev_/dev.tsx +0 -12
  33. package/src/_dev_/index.css +0 -13
  34. package/src/_dev_/page/DesignerRenderDemo.tsx +0 -65
  35. package/src/_dev_/page/RenderDemo.tsx +0 -60
  36. package/src/_dev_/router.tsx +0 -15
  37. package/src/commonComponent/index.tsx +0 -184
  38. package/src/const/index.ts +0 -5
  39. package/src/core/ReactErrorBoundary.ts +0 -91
  40. package/src/core/adapter.ts +0 -133
  41. package/src/core/adapterReact.ts +0 -734
  42. package/src/core/designReactRender.ts +0 -325
  43. package/src/core/refManager.ts +0 -18
  44. package/src/core/render.ts +0 -123
  45. package/src/core/storeManager.ts +0 -57
  46. package/src/core/type.ts +0 -10
  47. package/src/util/assetsLoader.ts +0 -73
  48. package/src/util/index.ts +0 -164
  49. package/src/vite-env.d.ts +0 -1
  50. package/stats.html +0 -6177
  51. package/tsconfig.json +0 -26
  52. /package/{src/index.ts → dist/index.d.ts} +0 -0
@@ -1,734 +0,0 @@
1
- import React from 'react';
2
- import {
3
- CNode,
4
- CPage,
5
- CProp,
6
- CPropDataType,
7
- CRootNode,
8
- FunctionPropType,
9
- getRandomStr,
10
- InnerComponentNameEnum,
11
- isExpression,
12
- isFunction,
13
- isNodeModel,
14
- isPropModel,
15
- isSlotModel,
16
- JSExpressionPropType,
17
- } from '@chamn/model';
18
- import { AdapterOptionType, ContextType, getAdapter } from './adapter';
19
- import { isArray, isPlainObject } from 'lodash-es';
20
- import {
21
- canAcceptsRef,
22
- compWrapper,
23
- convertCodeStringToFunction,
24
- formatSourceStylePropertyName,
25
- getCSSTextValue,
26
- getObjFromArrayMap,
27
- runExpression,
28
- shouldConstruct,
29
- } from '../util';
30
- import { DYNAMIC_COMPONENT_TYPE, InnerPropList } from '../const';
31
- import { StoreApi } from 'zustand/vanilla';
32
- import { StoreManager } from './storeManager';
33
-
34
- export class DefineReactAdapter {
35
- renderMode: AdapterOptionType['renderMode'] = 'normal';
36
- components: AdapterOptionType['components'] = {};
37
- storeManager = new StoreManager();
38
- runtimeComponentCache = new Map();
39
- onGetRef?: AdapterOptionType['onGetRef'];
40
- onGetComponent: AdapterOptionType['onGetComponent'];
41
- onComponentMount: AdapterOptionType['onComponentMount'];
42
-
43
- onComponentDestroy: AdapterOptionType['onComponentDestroy'];
44
-
45
- // 处理 props 钩子
46
- processNodeConfigHook?: AdapterOptionType['processNodeConfigHook'];
47
- getComponent(currentNode: CNode | CRootNode) {
48
- const componentName = currentNode.value.componentName;
49
- let res: any = this.components[componentName] || (() => `Component [${componentName}] not found`);
50
- // check component can accept ref
51
- if (!canAcceptsRef(res)) {
52
- res = compWrapper(res);
53
- this.components[componentName] = res;
54
- }
55
- // 定制钩子
56
- if (this.onGetComponent) {
57
- res = this.onGetComponent?.(res, currentNode);
58
- }
59
-
60
- return res;
61
- }
62
-
63
- getContext(data: ContextType = {}, ctx?: ContextType | null): ContextType {
64
- let newCtx: ContextType = data;
65
- if (ctx) {
66
- newCtx = {
67
- ...data,
68
- };
69
- (newCtx as any).__proto__ = ctx || null;
70
- }
71
- return newCtx;
72
- }
73
-
74
- pageRender(
75
- pageModel: CPage,
76
- {
77
- components,
78
- onGetRef,
79
- $$context = {},
80
- onGetComponent,
81
- onComponentMount,
82
- onComponentDestroy,
83
- renderMode,
84
- processNodeConfigHook,
85
- }: AdapterOptionType
86
- ) {
87
- this.renderMode = renderMode;
88
- this.components = components;
89
- this.onGetRef = onGetRef;
90
- this.onGetComponent = onGetComponent;
91
- this.onComponentMount = onComponentMount;
92
- this.onComponentDestroy = onComponentDestroy;
93
- this.processNodeConfigHook = processNodeConfigHook;
94
-
95
- //做一些全局 store 操作
96
- const rootNode = pageModel.value.componentsTree;
97
- const component = this.getComponent(rootNode);
98
-
99
- const newComp = this.convertModelToComponent(component, pageModel.value.componentsTree);
100
-
101
- const props: Record<string, any> = {};
102
- const propsModel = rootNode.props;
103
- Object.keys(propsModel).forEach((key) => {
104
- props[key] = propsModel[key].value;
105
- });
106
- props.$$context = $$context;
107
- return this.render(newComp, props);
108
- }
109
-
110
- transformProps(
111
- originalProps: Record<string, any> = {},
112
- {
113
- $$context: parentContext,
114
- }: {
115
- $$context: ContextType;
116
- }
117
- ) {
118
- const propsModel = originalProps;
119
- const handlePropVal: (propVal: CPropDataType) => Record<string, any> = (propVal: CPropDataType) => {
120
- if (Array.isArray(propVal)) {
121
- return propVal.map((it) => handlePropVal(it));
122
- } else if (isPropModel(propVal)) {
123
- return handlePropVal(propVal.value);
124
- } else if (isSlotModel(propVal)) {
125
- const slotProp = propVal.value;
126
- const tempVal = slotProp.value;
127
- if (!tempVal) {
128
- console.warn('slot value is null, this maybe cause some error, pls check it', originalProps);
129
- // eslint-disable-next-line @typescript-eslint/no-empty-function
130
- return () => {};
131
- }
132
- const handleSingleSlot = (it: CNode) => {
133
- const key = `${it.id}-${DYNAMIC_COMPONENT_TYPE}`;
134
-
135
- // 复用
136
- if (this.runtimeComponentCache.get(it.id)) {
137
- return {
138
- key: key,
139
- component: this.runtimeComponentCache.get(it.id),
140
- };
141
- }
142
- const component = this.getComponent(it);
143
- const PropNodeRender = this.convertModelToComponent(component, it);
144
- const parmaList = slotProp.params || [];
145
- // 运行时组件函数
146
- const PropNodeFuncWrap = (...args: any) => {
147
- const params: Record<any, any> = getObjFromArrayMap(args, parmaList);
148
- const $$context = this.getContext(
149
- {
150
- params,
151
- },
152
- parentContext
153
- );
154
- return this.render(PropNodeRender, {
155
- $$context,
156
- key,
157
- });
158
- };
159
- const res = {
160
- component: PropNodeFuncWrap,
161
- key,
162
- };
163
- return res;
164
- };
165
- if (Array.isArray(tempVal)) {
166
- const renderList = tempVal?.map((it: any) => {
167
- return handleSingleSlot(it);
168
- });
169
- // TODO: 需要做额外的处理
170
- return (...args: any[]) => {
171
- return renderList.map((renderItem) => {
172
- const isClassComponent = shouldConstruct(renderItem.component);
173
-
174
- if (isClassComponent) {
175
- return React.createElement(renderItem.component, {
176
- $$context: parentContext,
177
- key: renderItem.key,
178
- });
179
- } else {
180
- return renderItem.component(...args);
181
- }
182
- });
183
- };
184
- } else {
185
- return handleSingleSlot(tempVal).component;
186
- }
187
- } else if (isExpression(propVal)) {
188
- const expProp = propVal as JSExpressionPropType;
189
- const newVal = runExpression(expProp.value, parentContext || {});
190
- return newVal;
191
- } else if (isFunction(propVal)) {
192
- const funcProp = propVal as FunctionPropType;
193
- return convertCodeStringToFunction(funcProp.value, parentContext, this.storeManager);
194
- } else if (isPlainObject(propVal)) {
195
- // 可能是 普通的 props 模型
196
- let specialPropVal = propVal;
197
- if (isPropModel(propVal)) {
198
- specialPropVal = (propVal as CProp).value;
199
- }
200
- const objPropVal = specialPropVal as Record<string, any>;
201
- const newVal: Record<string, any> = {};
202
- Object.keys(specialPropVal).forEach((k) => {
203
- newVal[k] = handlePropVal(objPropVal[k]);
204
- });
205
- return newVal;
206
- } else {
207
- return propVal;
208
- }
209
- };
210
- const newProps: Record<string, any> = {};
211
- Object.keys(propsModel).forEach((propKey) => {
212
- const propVal = propsModel[propKey];
213
- newProps[propKey] = handlePropVal(propVal);
214
- });
215
-
216
- return newProps;
217
- }
218
-
219
- collectSpecialProps(originalProps: Record<string, unknown> = {}, isValidate: (val: unknown) => boolean) {
220
- const res: { keyPath: string[]; val: any }[] = [];
221
- const cb = (keyPath: string[], val: Record<string, any>) => {
222
- let tempVal: any = val;
223
- if (isPropModel(val)) {
224
- tempVal = val.value;
225
- }
226
- if (isValidate(tempVal)) {
227
- res.push({
228
- keyPath,
229
- val: tempVal,
230
- });
231
- } else if (isArray(tempVal)) {
232
- tempVal.forEach((it, index) => {
233
- cb([...keyPath, String(index)], it);
234
- });
235
- } else if (isPlainObject(tempVal)) {
236
- Object.keys(tempVal).forEach((key) => {
237
- cb([...keyPath, key], tempVal[key]);
238
- });
239
- }
240
- };
241
-
242
- cb(['$root'], originalProps);
243
- return res;
244
- }
245
-
246
- convertModelToComponent(originalComponent: any, nodeModel: CNode | CRootNode) {
247
- // eslint-disable-next-line @typescript-eslint/no-this-alias
248
- const that = this;
249
- type PropsType = {
250
- $$context: ContextType;
251
- $$nodeModel: CNode | CRootNode;
252
- };
253
-
254
- class DynamicComponent extends React.Component<PropsType> {
255
- static __CP_TYPE__ = DYNAMIC_COMPONENT_TYPE;
256
- _CONDITION = true;
257
- _DESIGN_BOX = false;
258
- _NODE_MODEL = nodeModel;
259
- _NODE_ID = nodeModel.id;
260
-
261
- UNIQUE_ID = `${nodeModel.id}_${getRandomStr()}`;
262
- targetComponentRef: React.MutableRefObject<any>;
263
- listenerHandle: (() => void)[] = [];
264
- storeState: StoreApi<any>;
265
- // not react data
266
- staticState: Record<string, any> = {};
267
- storeListenDisposeLint: (() => void)[] = [];
268
- // save dom and media css
269
- domHeader: HTMLHeadElement | undefined;
270
- mediaStyleDomMap: Record<string, HTMLStyleElement> = {};
271
-
272
- constructor(props: PropsType) {
273
- super(props);
274
- this.targetComponentRef = React.createRef();
275
- this.state = nodeModel.value.state || {};
276
- const storeName = nodeModel.value.stateName || nodeModel.id;
277
-
278
- const nodeStore = that.storeManager.getStore(storeName);
279
- if (!nodeStore) {
280
- // add to global store manager
281
- this.storeState = that.storeManager.addStore(storeName, () => {
282
- return {
283
- ...(nodeModel.value.state || {}),
284
- };
285
- });
286
- } else {
287
- this.storeState = nodeStore;
288
- nodeStore.setState({
289
- ...(nodeModel.value.state || {}),
290
- });
291
- }
292
-
293
- // sync storeState to component state;
294
- this.storeState.subscribe((newState) => {
295
- this.setState({
296
- ...newState,
297
- });
298
- });
299
- this.connectStore();
300
- }
301
-
302
- updateState = (newState: any) => {
303
- this.storeState.setState(newState);
304
- this.forceUpdate();
305
- };
306
-
307
- connectStore() {
308
- // props
309
- const expressionList = that.collectSpecialProps(nodeModel.props, (val) => {
310
- if (isExpression(val)) {
311
- return true;
312
- } else {
313
- return false;
314
- }
315
- });
316
-
317
- // TODO: css props、classNames props
318
- const cssAndClassExpressionList = that.collectSpecialProps(
319
- {
320
- css: nodeModel.value.css,
321
- class: nodeModel.value.classNames,
322
- },
323
- (val) => {
324
- if (isExpression(val)) {
325
- return true;
326
- } else {
327
- return false;
328
- }
329
- }
330
- );
331
-
332
- const list = [...expressionList, ...cssAndClassExpressionList]
333
- .map((el) => {
334
- const targetVal: JSExpressionPropType = el.val;
335
- const reg = /\$\$context.stateManager\.(.+?)\./gim;
336
- const res = reg.exec(targetVal.value);
337
- if (res?.length) {
338
- return res[1];
339
- } else {
340
- return '';
341
- }
342
- })
343
- .filter(Boolean);
344
- const uniqueList = Array.from(new Set(list));
345
- // TODO: list need now repeat
346
- const disposeList: (() => void)[] = [];
347
- if (uniqueList.length) {
348
- uniqueList.forEach((storeName) => {
349
- const store = that.storeManager.getStore(storeName);
350
- if (!store) {
351
- that.storeManager.addStore(storeName, () => {
352
- return {};
353
- });
354
- console.log(that.storeManager, storeName, 'not exits');
355
- }
356
- const handle = that.storeManager.connect(storeName, () => {
357
- this.forceUpdate();
358
- });
359
- disposeList.push(handle);
360
- });
361
- }
362
- this.storeListenDisposeLint = disposeList;
363
- }
364
-
365
- getStyleDomById = (id: string) => {
366
- const mediaStyleDomMap = this.mediaStyleDomMap;
367
- let styleEl = mediaStyleDomMap[id];
368
- if (!styleEl) {
369
- styleEl = document.createElement('style');
370
- styleEl.type = 'text/css';
371
- mediaStyleDomMap[id] = styleEl;
372
- }
373
- styleEl.id = id;
374
- return styleEl;
375
- };
376
-
377
- addMediaCSS = () => {
378
- let header = this.domHeader;
379
- if (!header) {
380
- header = document.getElementsByTagName('head')?.[0];
381
- this.domHeader = header;
382
- }
383
-
384
- if (!this.domHeader) {
385
- return;
386
- }
387
- const css = this._NODE_MODEL.value.css;
388
- if (!css) {
389
- return;
390
- }
391
- css.value.forEach((el) => {
392
- const normalId = `${this.UNIQUE_ID}_${el.state}`;
393
- let className = `.${css.class}`;
394
- if (el.state !== 'normal') {
395
- className = `${className}:${el.state}`;
396
- }
397
- if (Object.keys(el.style).length !== 0) {
398
- const styleEl = this.getStyleDomById(normalId);
399
- styleEl.innerText = `${className} { ${getCSSTextValue(el.style)} }`;
400
- header?.appendChild(styleEl);
401
- }
402
-
403
- if (el.media?.length) {
404
- el.media.forEach((it) => {
405
- const mediaId = `${normalId}_${it.type}_${it.value}`;
406
- const styleDom = this.getStyleDomById(mediaId);
407
- styleDom.media = `screen and (${it.type}:${it.value}px)`;
408
- styleDom.innerHTML = `${className} { ${getCSSTextValue(it.style)} }`;
409
- header?.appendChild(styleDom);
410
- });
411
- }
412
- });
413
- };
414
-
415
- removeMediaCSS = () => {
416
- const mediaStyleDomMap = this.mediaStyleDomMap;
417
- Object.keys(mediaStyleDomMap).forEach((key) => {
418
- this.domHeader?.removeChild(mediaStyleDomMap[key]);
419
- });
420
- };
421
-
422
- componentDidMount(): void {
423
- this.addMediaCSS();
424
- if (that.onGetRef) {
425
- that.onGetRef(this.targetComponentRef, nodeModel, this as any);
426
- }
427
- that.onComponentMount?.(this, nodeModel);
428
- const forceUpdate = () => {
429
- // stateName maybe changed
430
- that.storeManager.setStore(nodeModel.value.stateName || nodeModel.id, this.storeState);
431
- this.storeState.setState({
432
- ...this.state,
433
- ...(nodeModel.value.state || {}),
434
- });
435
- this.rebuildNode();
436
- };
437
- nodeModel.onChange(forceUpdate);
438
- }
439
-
440
- rebuildNode = () => {
441
- this.storeListenDisposeLint.forEach((el) => el());
442
- this.removeMediaCSS();
443
- this.connectStore();
444
- this.addMediaCSS();
445
- this.forceUpdate();
446
- };
447
-
448
- componentWillUnmount(): void {
449
- this.storeListenDisposeLint.forEach((el) => el());
450
- this.removeMediaCSS();
451
- that.onComponentDestroy?.(this, nodeModel);
452
- }
453
-
454
- render(): React.ReactNode {
455
- const { $$context, ...props } = this.props;
456
- const newOriginalProps = {
457
- key: nodeModel.id,
458
- ...nodeModel.props,
459
- ...props,
460
- };
461
- const tempContext: ContextType = {
462
- state: this.state || {},
463
- updateState: this.updateState,
464
- staticState: this.staticState,
465
- };
466
-
467
- if (nodeModel.value.componentName === InnerComponentNameEnum.ROOT_CONTAINER) {
468
- tempContext.globalState = this.state;
469
- tempContext.updateGlobalState = this.updateState;
470
- }
471
-
472
- tempContext.stateManager = that.storeManager.getStateSnapshot();
473
- const newContext = that.getContext(tempContext, $$context);
474
-
475
- // 处理循环
476
- const loopObj = nodeModel.value.loop;
477
- let loopRes: any[] = [];
478
- if (loopObj && loopObj.open) {
479
- this.targetComponentRef.current = [];
480
- let loopList: any[] = (loopObj.data as any[]) || [];
481
- if (isExpression(loopObj.data)) {
482
- const expProp = loopObj.data as JSExpressionPropType;
483
- loopList = runExpression(expProp.value, newContext || {});
484
- }
485
- loopRes = loopList.map((...args) => {
486
- const innerIndex = args[1];
487
- const argsName = [loopObj.forName || 'item', loopObj.forIndex || 'index'];
488
- const loopData = getObjFromArrayMap(args, argsName);
489
- let loopDataName = 'loopData';
490
- // loopDataName: loopData or loopData${xxx}, xxx is capitalize
491
- if (loopObj.name) {
492
- loopDataName = `${loopDataName}${loopObj.name}`;
493
- }
494
- const loopContext = that.getContext(
495
- {
496
- [loopDataName]: loopData,
497
- staticState: this.staticState,
498
- },
499
- newContext
500
- );
501
- // handle props
502
- const newProps: Record<string, any> = that.transformProps(newOriginalProps, {
503
- $$context: loopContext,
504
- });
505
- // 处理 className
506
- const classNames =
507
- nodeModel.value.classNames?.map((it) => {
508
- const name = it.name;
509
- const status = isExpression(it.status) ? runExpression(String(it.status?.value || ''), loopContext) : false;
510
- if (status) {
511
- return name;
512
- }
513
- return '';
514
- }) || [];
515
- let finalClsx = `${newProps.className ?? ''} ${classNames.join(' ')}`.trim();
516
- if (nodeModel.value.css) {
517
- // 每个节点添加一个 表示节点唯一的 className, 使用 node.id
518
- const className = `${nodeModel.value.css.class} ${finalClsx}`.trim();
519
- finalClsx = className;
520
- }
521
- newProps.className = finalClsx;
522
-
523
- // 处理 style
524
- const newStyle: Record<string, any> = that.transformProps(nodeModel.value.style, {
525
- $$context: loopContext,
526
- });
527
- // font-size to fontSize
528
- if (nodeModel.value.style) {
529
- newProps.style = formatSourceStylePropertyName(newStyle || {});
530
- }
531
-
532
- const { children } = newProps;
533
- let newChildren: React.ReactNode[] = [];
534
- if (children !== undefined) {
535
- delete newProps.children;
536
- newChildren = Array.isArray(children) ? children : [children];
537
- } else {
538
- const children: React.ReactNode[] = [];
539
- const childModel = nodeModel.value.children;
540
- childModel.forEach((node, index) => {
541
- const child = that.buildComponent(node, {
542
- $$context: loopContext,
543
- idx: index,
544
- });
545
- children.push(child);
546
- });
547
- newChildren = children;
548
- }
549
-
550
- newProps.key = `${newProps.key}-${innerIndex}`;
551
- if (isExpression(loopObj.key)) {
552
- const keyObj = loopObj.key as JSExpressionPropType;
553
- const specialKey = runExpression(keyObj.value, loopContext || {});
554
- newProps.key += `-${specialKey}`;
555
- }
556
- newProps.ref = (ref: any) => {
557
- this.targetComponentRef.current = this.targetComponentRef.current || [];
558
- this.targetComponentRef.current[innerIndex] = ref;
559
- };
560
-
561
- // handle children
562
- return that.render(originalComponent, newProps, ...newChildren);
563
- });
564
-
565
- // 结束循环渲染
566
- return loopRes;
567
- }
568
-
569
- // handle props
570
- const newProps: Record<string, any> = that.transformProps(newOriginalProps, {
571
- $$context: newContext,
572
- });
573
-
574
- const { children } = newProps;
575
- let newChildren: React.ReactNode[] = [];
576
- if (children !== undefined) {
577
- delete newProps.children;
578
- newChildren = Array.isArray(children) ? children : [children];
579
- } else {
580
- const children: React.ReactNode[] = [];
581
- const childModel = nodeModel.value.children;
582
- childModel.forEach((node, index) => {
583
- const child = that.buildComponent(node, {
584
- $$context: newContext,
585
- idx: index,
586
- });
587
- children.push(child);
588
- });
589
- newChildren = children;
590
- }
591
-
592
- newProps.ref = this.targetComponentRef;
593
- // 处理 className
594
- const classNames =
595
- nodeModel.value.classNames?.map((it) => {
596
- const name = it.name;
597
- const status = isExpression(it.status) ? runExpression(it.status?.value || '', newContext) : false;
598
- if (status) {
599
- return name;
600
- }
601
- return '';
602
- }) || [];
603
-
604
- let finalClsx = `${newProps.className ?? ''} ${classNames.join(' ')}`.trim();
605
- if (nodeModel.value.css) {
606
- // 每个节点添加一个 表示节点唯一的 className, 使用 node.id
607
- const className = `${nodeModel.value.css.class} ${finalClsx}`.trim();
608
- finalClsx = className;
609
- }
610
-
611
- newProps.className = finalClsx;
612
-
613
- // 处理 style
614
- const newStyle: Record<string, any> = that.transformProps(nodeModel.value.style, {
615
- $$context: newContext,
616
- });
617
- // font-size to fontSize
618
- if (nodeModel.value.style) {
619
- newProps.style = formatSourceStylePropertyName(newStyle || {});
620
- }
621
-
622
- // handle children
623
- let condition = nodeModel.value.condition ?? true;
624
- if (typeof condition !== 'boolean') {
625
- const conditionObj = condition as JSExpressionPropType;
626
- condition = runExpression(conditionObj.value, newContext || {}) as boolean;
627
- }
628
- let finalNodeConfig = {
629
- condition,
630
- props: newProps,
631
- };
632
- if (that.processNodeConfigHook) {
633
- finalNodeConfig = that.processNodeConfigHook(finalNodeConfig, nodeModel as CNode);
634
- }
635
-
636
- const renderView = that.render(originalComponent, finalNodeConfig.props, ...newChildren);
637
-
638
- this._CONDITION = finalNodeConfig.condition as boolean;
639
- if (!finalNodeConfig.condition) {
640
- return React.createElement(
641
- 'div',
642
- {
643
- style: {
644
- display: 'none',
645
- },
646
- },
647
- renderView
648
- );
649
- }
650
-
651
- return renderView;
652
- // 可能能复用 end
653
- }
654
- }
655
-
656
- (DynamicComponent as any).displayName = `${nodeModel.value.componentName}Dynamic`;
657
-
658
- return DynamicComponent;
659
- }
660
-
661
- // 递归建页面组件结构
662
- buildComponent(
663
- node: CNode | CRootNode | string,
664
- {
665
- $$context = {},
666
- }: {
667
- $$context: ContextType;
668
- idx?: number;
669
- }
670
- ) {
671
- const runtimeComponentCache = this.runtimeComponentCache;
672
- if (typeof node === 'string') {
673
- return this.render(node);
674
- }
675
-
676
- if (!isNodeModel(node)) {
677
- return;
678
- }
679
- const handleNode = ({ currentNode }: { currentNode: CRootNode | CNode }) => {
680
- const nodeId = currentNode.value.id;
681
- let component = null;
682
- if (runtimeComponentCache.get(nodeId)) {
683
- component = runtimeComponentCache.get(nodeId);
684
- } else {
685
- const originalComponent = this.getComponent(currentNode);
686
-
687
- component = this.convertModelToComponent(originalComponent, currentNode);
688
- }
689
-
690
- // cache runtime component
691
- if (!runtimeComponentCache.get(nodeId) && this.renderMode !== 'design') {
692
- runtimeComponentCache.set(nodeId, component);
693
- }
694
- const key = `${nodeId}-${DYNAMIC_COMPONENT_TYPE}`;
695
- const props: Record<string, any> = {
696
- $$context,
697
- $$nodeModel: node,
698
- key: key,
699
- };
700
-
701
- return this.render(component, props);
702
- };
703
-
704
- return handleNode({
705
- currentNode: node,
706
- });
707
- }
708
-
709
- // 真实渲染
710
- render(
711
- originalComponent: React.ComponentClass<any> | React.FunctionComponent | string,
712
- props: Record<any, any> = {},
713
- ...children: React.ReactNode[]
714
- ) {
715
- if (typeof originalComponent === 'string' || typeof originalComponent === 'number') {
716
- return String(originalComponent);
717
- }
718
- InnerPropList.forEach((key) => {
719
- if (key in props && (originalComponent as any).__CP_TYPE__ !== DYNAMIC_COMPONENT_TYPE) {
720
- delete props[key];
721
- }
722
- });
723
- const res = React.createElement(originalComponent, props, ...children);
724
- return res;
725
- }
726
-
727
- clear() {
728
- this.runtimeComponentCache.clear();
729
- this.storeManager.destroy();
730
- }
731
- }
732
-
733
- // eslint-disable-next-line @typescript-eslint/no-empty-function
734
- export const ReactAdapter = getAdapter(new DefineReactAdapter());