Skip to content

Commit 05995cc

Browse files
committed
feat: add dynamicStyle addon
1 parent 3f3ad2f commit 05995cc

File tree

3 files changed

+141
-71
lines changed

3 files changed

+141
-71
lines changed

packages/editor-skeleton/src/transducers/addon-combine.ts

+20-4
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,18 @@ export default function (
8282
eventsDefinition.push({
8383
type: 'lifeCycleEvent',
8484
title: '生命周期',
85-
list: supportedLifecycles.map((event: any) => (typeof event === 'string' ? { name: event } : event)),
85+
list: supportedLifecycles.map((event: any) =>
86+
typeof event === 'string' ? { name: event } : event,
87+
),
8688
});
8789
}
8890
if (supports.events) {
8991
eventsDefinition.push({
9092
type: 'events',
9193
title: '事件',
92-
list: (supports.events || []).map((event: any) => (typeof event === 'string' ? { name: event } : event)),
94+
list: (supports.events || []).map((event: any) =>
95+
typeof event === 'string' ? { name: event } : event,
96+
),
9397
});
9498
}
9599
// 通用设置
@@ -192,6 +196,16 @@ export default function (
192196
},
193197
});
194198
}
199+
if (supports.dynamicStyle) {
200+
stylesGroup.push({
201+
name: 'dynamicStyle',
202+
title: { type: 'i18n', 'zh-CN': '动态样式', 'en-US': 'dynamicStyle' },
203+
setter: 'JsonSetter',
204+
extraProps: {
205+
display: 'block',
206+
},
207+
});
208+
}
195209
if (stylesGroup.length > 0) {
196210
combined.push({
197211
name: '#styles',
@@ -334,8 +348,10 @@ export default function (
334348
},
335349
tip: {
336350
type: 'i18n',
337-
'zh-CN': '搭配「条件渲染」或「循环渲染」时使用,和 react 组件中的 key 原理相同,点击查看帮助',
338-
'en-US': 'Used with 「Conditional Rendering」or「Cycle Rendering」, the same principle as the key in the react component, click to view the help',
351+
'zh-CN':
352+
'搭配「条件渲染」或「循环渲染」时使用,和 react 组件中的 key 原理相同,点击查看帮助',
353+
'en-US':
354+
'Used with 「Conditional Rendering」or「Cycle Rendering」, the same principle as the key in the react component, click to view the help',
339355
},
340356
docUrl: 'https://www.yuque.com/lce/doc/qm75w3',
341357
},

packages/renderer-core/src/hoc/leaf.tsx

+99-67
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { INode, IPublicTypePropChangeOptions } from '@alilc/lowcode-designer';
2-
import { GlobalEvent, IPublicEnumTransformStage, IPublicTypeNodeSchema, IPublicTypeEngineOptions } from '@alilc/lowcode-types';
2+
import {
3+
GlobalEvent,
4+
IPublicEnumTransformStage,
5+
IPublicTypeNodeSchema,
6+
IPublicTypeEngineOptions,
7+
} from '@alilc/lowcode-types';
38
import { isReactComponent, cloneEnumerableProperty } from '@alilc/lowcode-utils';
49
import { debounce } from '../utils/common';
510
import adapter from '../adapter';
@@ -40,7 +45,10 @@ export interface IComponentHoc {
4045
hoc: IComponentConstruct;
4146
}
4247

43-
export type IComponentConstruct = (Comp: types.IBaseRenderComponent, info: IComponentHocInfo) => types.IGeneralConstructor;
48+
export type IComponentConstruct = (
49+
Comp: types.IBaseRenderComponent,
50+
info: IComponentHocInfo,
51+
) => types.IGeneralConstructor;
4452

4553
interface IProps {
4654
_leaf: INode | undefined;
@@ -66,7 +74,6 @@ enum RerenderType {
6674

6775
// 缓存 Leaf 层组件,防止重新渲染问题
6876
class LeafCache {
69-
7077
/** 组件缓存 */
7178
component = new Map();
7279

@@ -82,24 +89,15 @@ class LeafCache {
8289

8390
ref = new Map();
8491

85-
constructor(public documentId: string, public device: string) {
86-
}
92+
constructor(public documentId: string, public device: string) {}
8793
}
8894

8995
let cache: LeafCache;
9096

9197
/** 部分没有渲染的 node 节点进行兜底处理 or 渲染方式没有渲染 LeafWrapper */
92-
function initRerenderEvent({
93-
schema,
94-
__debug,
95-
container,
96-
getNode,
97-
}: any) {
98+
function initRerenderEvent({ schema, __debug, container, getNode }: any) {
9899
const leaf = getNode?.(schema.id);
99-
if (!leaf
100-
|| cache.event.get(schema.id)?.clear
101-
|| leaf === cache.event.get(schema.id)
102-
) {
100+
if (!leaf || cache.event.get(schema.id)?.clear || leaf === cache.event.get(schema.id)) {
103101
return;
104102
}
105103
cache.event.get(schema.id)?.dispose.forEach((disposeFn: any) => disposeFn && disposeFn());
@@ -114,21 +112,27 @@ function initRerenderEvent({
114112
if (!container.autoRepaintNode) {
115113
return;
116114
}
117-
__debug(`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onPropsChange make rerender`);
115+
__debug(
116+
`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onPropsChange make rerender`,
117+
);
118118
debounceRerender();
119119
}),
120120
leaf?.onChildrenChange?.(() => {
121121
if (!container.autoRepaintNode) {
122122
return;
123123
}
124-
__debug(`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onChildrenChange make rerender`);
124+
__debug(
125+
`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onChildrenChange make rerender`,
126+
);
125127
debounceRerender();
126128
}) as Function,
127129
leaf?.onVisibleChange?.(() => {
128130
if (!container.autoRepaintNode) {
129131
return;
130132
}
131-
__debug(`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onVisibleChange make rerender`);
133+
__debug(
134+
`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onVisibleChange make rerender`,
135+
);
132136
debounceRerender();
133137
}),
134138
],
@@ -148,12 +152,10 @@ function clearRerenderEvent(id: string): void {
148152
}
149153

150154
// 给每个组件包裹一个 HOC Leaf,支持组件内部属性变化,自响应渲染
151-
export function leafWrapper(Comp: types.IBaseRenderComponent, {
152-
schema,
153-
baseRenderer,
154-
componentInfo,
155-
scope,
156-
}: IComponentHocInfo) {
155+
export function leafWrapper(
156+
Comp: types.IBaseRenderComponent,
157+
{ schema, baseRenderer, componentInfo, scope }: IComponentHocInfo,
158+
) {
157159
const {
158160
__debug,
159161
__getComponentProps: getProps,
@@ -171,13 +173,18 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
171173
const runtime = adapter.getRuntime();
172174
const { forwardRef, createElement } = runtime;
173175
const Component = runtime.Component as types.IGeneralConstructor<
174-
IComponentHocProps, IComponentHocState
176+
IComponentHocProps,
177+
IComponentHocState
175178
>;
176179

177180
const componentCacheId = schema.id;
178181

179-
if (!cache || (curDocumentId && curDocumentId !== cache.documentId) || (curDevice && curDevice !== cache.device)) {
180-
cache?.event.forEach(event => {
182+
if (
183+
!cache ||
184+
(curDocumentId && curDocumentId !== cache.documentId) ||
185+
(curDevice && curDevice !== cache.device)
186+
) {
187+
cache?.event.forEach((event) => {
181188
event.dispose?.forEach((disposeFn: any) => disposeFn && disposeFn());
182189
});
183190
cache = new LeafCache(curDocumentId, curDevice);
@@ -194,7 +201,11 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
194201
getNode,
195202
});
196203

197-
if (curDocumentId && cache.component.has(componentCacheId) && (cache.component.get(componentCacheId).Comp === Comp)) {
204+
if (
205+
curDocumentId &&
206+
cache.component.has(componentCacheId) &&
207+
cache.component.get(componentCacheId).Comp === Comp
208+
) {
198209
return cache.component.get(componentCacheId).LeafWrapper;
199210
}
200211

@@ -209,7 +220,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
209220

210221
static displayName = schema.componentName;
211222

212-
disposeFunctions: Array<((() => void) | Function)> = [];
223+
disposeFunctions: Array<(() => void) | Function> = [];
213224

214225
__component_tag = 'leafWrapper';
215226

@@ -244,7 +255,9 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
244255
constructor(props: IProps, context: any) {
245256
super(props, context);
246257
// 监听以下事件,当变化时更新自己
247-
__debug(`${schema.componentName}[${this.props.componentId}] leaf render in SimulatorRendererView`);
258+
__debug(
259+
`${schema.componentName}[${this.props.componentId}] leaf render in SimulatorRendererView`,
260+
);
248261
clearRerenderEvent(componentCacheId);
249262
this.curEventLeaf = this.leaf;
250263

@@ -266,7 +279,8 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
266279
}
267280
const endTime = Date.now();
268281
const nodeCount = host?.designer?.currentDocument?.getNodeCount?.();
269-
const componentName = this.recordInfo.node?.componentName || this.leaf?.componentName || 'UnknownComponent';
282+
const componentName =
283+
this.recordInfo.node?.componentName || this.leaf?.componentName || 'UnknownComponent';
270284
editor?.eventBus.emit(GlobalEvent.Node.Rerender, {
271285
componentName,
272286
time: endTime - this.recordInfo.startTime,
@@ -297,10 +311,8 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
297311
}
298312

299313
getDefaultState(nextProps: any) {
300-
const {
301-
hidden = false,
302-
condition = true,
303-
} = nextProps.__inner__ || this.leaf?.export?.(IPublicEnumTransformStage.Render) || {};
314+
const { hidden = false, condition = true } =
315+
nextProps.__inner__ || this.leaf?.export?.(IPublicEnumTransformStage.Render) || {};
304316
return {
305317
nodeChildren: null,
306318
childrenInState: false,
@@ -317,6 +329,12 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
317329
...state,
318330
__tag: this.props.__tag,
319331
});
332+
let style = state.nodeProps.style ?? {};
333+
const { dynamicStyle } = state.nodeProps;
334+
if (typeof dynamicStyle === 'object') {
335+
style = { ...style, ...dynamicStyle };
336+
}
337+
if (style && Object.keys(style).length) state.nodeProps.style = style;
320338
super.setState(state);
321339
}
322340

@@ -348,7 +366,9 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
348366
container?.rerender();
349367
return;
350368
}
351-
__debug(`${this.leaf?.componentName}(${this.props.componentId}) need render, make its minimalRenderUnit ${renderUnitInfo.minimalUnitName}(${renderUnitInfo.minimalUnitId})`);
369+
__debug(
370+
`${this.leaf?.componentName}(${this.props.componentId}) need render, make its minimalRenderUnit ${renderUnitInfo.minimalUnitName}(${renderUnitInfo.minimalUnitId})`,
371+
);
352372
ref.makeUnitRender();
353373
}
354374

@@ -400,20 +420,14 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
400420
this.curEventLeaf = _leaf;
401421
}
402422

403-
const {
404-
visible,
405-
...resetState
406-
} = this.getDefaultState(nextProps);
423+
const { visible, ...resetState } = this.getDefaultState(nextProps);
407424
this.setState(resetState);
408425
}
409426

410427
/** 监听参数变化 */
411428
initOnPropsChangeEvent(leaf = this.leaf): void {
412429
const handlePropsChange = debounce((propChangeInfo: IPublicTypePropChangeOptions) => {
413-
const {
414-
key,
415-
newValue = null,
416-
} = propChangeInfo;
430+
const { key, newValue = null } = propChangeInfo;
417431
const node = leaf;
418432

419433
if (key === '___condition___') {
@@ -439,21 +453,36 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
439453
this.beforeRender(RerenderType.PropsChanged);
440454
const { state } = this;
441455
const { nodeCacheProps } = state;
442-
const nodeProps = getProps(node?.export?.(IPublicEnumTransformStage.Render) as IPublicTypeNodeSchema, scope, Comp, componentInfo);
443-
if (key && !(key in nodeProps) && (key in this.props)) {
456+
const nodeProps = getProps(
457+
node?.export?.(IPublicEnumTransformStage.Render) as IPublicTypeNodeSchema,
458+
scope,
459+
Comp,
460+
componentInfo,
461+
);
462+
if (key && !(key in nodeProps) && key in this.props) {
444463
// 当 key 在 this.props 中时,且不存在在计算值中,需要用 newValue 覆盖掉 this.props 的取值
445464
nodeCacheProps[key] = newValue;
446465
}
447-
__debug(`${leaf?.componentName}[${this.props.componentId}] component trigger onPropsChange!`, nodeProps, nodeCacheProps, key, newValue);
448-
this.setState('children' in nodeProps ? {
449-
nodeChildren: nodeProps.children,
450-
nodeProps,
451-
childrenInState: true,
452-
nodeCacheProps,
453-
} : {
466+
__debug(
467+
`${leaf?.componentName}[${this.props.componentId}] component trigger onPropsChange!`,
454468
nodeProps,
455469
nodeCacheProps,
456-
});
470+
key,
471+
newValue,
472+
);
473+
this.setState(
474+
'children' in nodeProps
475+
? {
476+
nodeChildren: nodeProps.children,
477+
nodeProps,
478+
childrenInState: true,
479+
nodeCacheProps,
480+
}
481+
: {
482+
nodeProps,
483+
nodeCacheProps,
484+
},
485+
);
457486

458487
this.judgeMiniUnitRender();
459488
});
@@ -479,7 +508,9 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
479508
return;
480509
}
481510

482-
__debug(`${leaf?.componentName}[${this.props.componentId}] component trigger onVisibleChange(${flag}) event`);
511+
__debug(
512+
`${leaf?.componentName}[${this.props.componentId}] component trigger onVisibleChange(${flag}) event`,
513+
);
483514
this.beforeRender(RerenderType.VisibleChanged);
484515
this.setState({
485516
visible: flag,
@@ -498,16 +529,20 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
498529
if (!this.autoRepaintNode) {
499530
return;
500531
}
501-
const {
502-
type,
503-
node,
504-
} = param || {};
532+
const { type, node } = param || {};
505533
this.beforeRender(`${RerenderType.ChildChanged}-${type}`, node);
506534
// TODO: 缓存同级其他元素的 children。
507535
// 缓存二级 children Next 查询筛选组件有问题
508536
// 缓存一级 children Next Tab 组件有问题
509-
const nextChild = getChildren(leaf?.export?.(IPublicEnumTransformStage.Render) as types.ISchema, scope, Comp);
510-
__debug(`${schema.componentName}[${this.props.componentId}] component trigger onChildrenChange event`, nextChild);
537+
const nextChild = getChildren(
538+
leaf?.export?.(IPublicEnumTransformStage.Render) as types.ISchema,
539+
scope,
540+
Comp,
541+
);
542+
__debug(
543+
`${schema.componentName}[${this.props.componentId}] component trigger onChildrenChange event`,
544+
nextChild,
545+
);
511546
this.setState({
512547
nodeChildren: nextChild,
513548
childrenInState: true,
@@ -518,7 +553,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
518553
}
519554

520555
componentWillUnmount() {
521-
this.disposeFunctions.forEach(fn => fn());
556+
this.disposeFunctions.forEach((fn) => fn());
522557
}
523558

524559
get hasChildren(): boolean {
@@ -556,10 +591,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
556591
return null;
557592
}
558593

559-
const {
560-
forwardedRef,
561-
...rest
562-
} = this.props;
594+
const { forwardedRef, ...rest } = this.props;
563595

564596
const compProps = {
565597
...rest,
@@ -597,4 +629,4 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
597629
});
598630

599631
return LeafWrapper;
600-
}
632+
}

0 commit comments

Comments
 (0)