km-card-layout-core 0.1.25 → 0.1.27
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.
- package/README.md +1 -2
- package/bindings.ts +9 -20
- package/data.ts +1 -3
- package/dist/bindings.js +6 -14
- package/dist/data.js +1 -1
- package/dist/index.js +9 -18
- package/dist/interface/index.js +0 -1
- package/dist/layout.js +1 -17
- package/dist/ops/changeBackground.js +45 -97
- package/dist/render/helpers.js +41 -21
- package/dist/render/init.js +81 -0
- package/index.ts +7 -26
- package/interface/data/payload.ts +3 -3
- package/interface/elements.ts +2 -1
- package/interface/index.ts +0 -1
- package/interface/layout.ts +2 -1
- package/layout.ts +0 -18
- package/ops/changeBackground.ts +47 -130
- package/package.json +1 -1
- package/render/helpers.ts +72 -28
- package/render/init.ts +107 -0
- package/types.d.ts +35 -98
- package/dist/interface/context.js +0 -2
- package/dist/interface/render.js +0 -2
- package/dist/render/builder.js +0 -209
- package/dist/render/tool.js +0 -15
- package/dist/utils.js +0 -25
- package/interface/context.ts +0 -6
- package/render/tool.ts +0 -21
- package/utils.ts +0 -13
package/index.ts
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* - 平台无关:不依赖 DOM/小程序 API,方便在 Web/小程序/Node 复用。
|
|
5
|
-
* - 职责:将布局 Schema 与业务数据合成可渲染树,外层只需将节点映射到各端组件。
|
|
2
|
+
* Core exports for card layout helpers.
|
|
3
|
+
* Platform-agnostic utilities shared by web/mini-program renderers.
|
|
6
4
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
5
|
export * from './interface/index';
|
|
13
6
|
export { addUnit, styleObjectToString, toNumber, isObject } from './helpers';
|
|
14
7
|
export {
|
|
@@ -17,27 +10,12 @@ export {
|
|
|
17
10
|
sanitizeElement,
|
|
18
11
|
roundToInt,
|
|
19
12
|
getAbsLayout,
|
|
20
|
-
collectBindings,
|
|
21
13
|
normalizeId,
|
|
22
14
|
parseLayout,
|
|
23
|
-
areChildrenEqual,
|
|
24
15
|
} from './layout';
|
|
25
16
|
export { resolveBindingValue } from './data';
|
|
26
|
-
export {
|
|
27
|
-
|
|
28
|
-
applyItemCollectBindings,
|
|
29
|
-
getTemplateItems,
|
|
30
|
-
getTemplateBackgrounds,
|
|
31
|
-
} from './bindings';
|
|
32
|
-
export {
|
|
33
|
-
backgroundChange,
|
|
34
|
-
DEFAULT_DECOR_COLOR,
|
|
35
|
-
resolveSpecialStyle,
|
|
36
|
-
applySpecialStyle,
|
|
37
|
-
applyBackground,
|
|
38
|
-
updateElementsStyle,
|
|
39
|
-
} from './ops/changeBackground';
|
|
40
|
-
export { buildRenderData } from './render/tool';
|
|
17
|
+
export { stripLayoutBindings, applyItemCollectBindings } from './bindings';
|
|
18
|
+
export { backgroundChange } from './ops/changeBackground';
|
|
41
19
|
export {
|
|
42
20
|
buildWrapperStyle,
|
|
43
21
|
buildCardStyle,
|
|
@@ -45,9 +23,12 @@ export {
|
|
|
45
23
|
buildBaseContentStyle,
|
|
46
24
|
buildPanelContentStyle,
|
|
47
25
|
buildTextContentStyle,
|
|
26
|
+
buildTextValueStyle,
|
|
48
27
|
buildImageContentStyle,
|
|
49
28
|
getTextValue,
|
|
50
29
|
getImageSrc,
|
|
51
30
|
getIconName,
|
|
52
31
|
buildTextIconMeta,
|
|
53
32
|
} from './render/helpers';
|
|
33
|
+
|
|
34
|
+
export { handleSpecialFields, processCardLayout } from './render/init';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CardLayoutSchema } from
|
|
1
|
+
import { CardLayoutSchema } from '../layout';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 背景项
|
|
@@ -20,11 +20,10 @@ export interface TemplateItem {
|
|
|
20
20
|
name: string;
|
|
21
21
|
bind: string;
|
|
22
22
|
key?: string;
|
|
23
|
-
icon?: string;
|
|
24
23
|
extra?: { icon?: string };
|
|
25
24
|
default?: string;
|
|
26
25
|
type: 'text' | 'image';
|
|
27
|
-
cate: number;
|
|
26
|
+
cate: number; // 1 内置 | 2 特殊
|
|
28
27
|
required?: 0 | 1;
|
|
29
28
|
}
|
|
30
29
|
|
|
@@ -43,4 +42,5 @@ export interface TemplateLayoutInfo {
|
|
|
43
42
|
isBgCustomize?: 0 | 1;
|
|
44
43
|
createAt?: string;
|
|
45
44
|
updateAt?: string;
|
|
45
|
+
illustration?: string;
|
|
46
46
|
}
|
package/interface/elements.ts
CHANGED
|
@@ -32,13 +32,14 @@ export interface TextIconConfig {
|
|
|
32
32
|
gap?: number;
|
|
33
33
|
align?: 'left' | 'right';
|
|
34
34
|
enable?: boolean;
|
|
35
|
-
style?: 'fill' | 'dot' | 'line';
|
|
35
|
+
style?: 'fill' | 'dot' | 'line' | 'text';
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export interface TextElement extends CardElementBase {
|
|
39
39
|
type: 'text';
|
|
40
40
|
align?: 'left' | 'center' | 'right';
|
|
41
41
|
icon?: TextIconConfig;
|
|
42
|
+
label?: string;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
export interface ImageElement extends CardElementBase {
|
package/interface/index.ts
CHANGED
package/interface/layout.ts
CHANGED
|
@@ -10,10 +10,11 @@ export interface CardLayoutSchema {
|
|
|
10
10
|
backgroundImage?: string;
|
|
11
11
|
backgroundZIndex?: number;
|
|
12
12
|
fontColor?: string;
|
|
13
|
-
borderRadius?: number;
|
|
14
13
|
padding?: number;
|
|
15
14
|
children: CardElement[];
|
|
16
15
|
thumbnail?: string;
|
|
16
|
+
backgroundWidth?: number;
|
|
17
|
+
backgroundHeight?: number;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export type CardLayoutInput = CardLayoutSchema[];
|
package/layout.ts
CHANGED
|
@@ -54,17 +54,6 @@ export const sanitizeLayout = (layout: CardLayoutSchema): CardLayoutSchema => ({
|
|
|
54
54
|
children: (layout.children || []).map(child => sanitizeElement(child)),
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
export const collectBindings = (elements: CardElement[] = []): string[] => {
|
|
58
|
-
const result: string[] = [];
|
|
59
|
-
elements.forEach(el => {
|
|
60
|
-
if (el.binding) result.push(el.binding);
|
|
61
|
-
if (el.type === 'layout-panel' && el.children) {
|
|
62
|
-
result.push(...collectBindings(el.children));
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
return Array.from(new Set(result));
|
|
66
|
-
};
|
|
67
|
-
|
|
68
57
|
export const normalizeId = (id?: string | number | null) => {
|
|
69
58
|
if (id === undefined || id === null) return undefined;
|
|
70
59
|
const num = Number(id);
|
|
@@ -120,10 +109,3 @@ export const normalizeLayout = (
|
|
|
120
109
|
})
|
|
121
110
|
.filter((value): value is CardLayoutSchema => Boolean(value));
|
|
122
111
|
};
|
|
123
|
-
|
|
124
|
-
export const areChildrenEqual = (
|
|
125
|
-
a?: CardLayoutSchema | null,
|
|
126
|
-
b?: CardLayoutSchema | null
|
|
127
|
-
): boolean => {
|
|
128
|
-
return JSON.stringify(a?.children) === JSON.stringify(b?.children);
|
|
129
|
-
};
|
package/ops/changeBackground.ts
CHANGED
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import type { CardElement, CardLayoutSchema } from '../interface';
|
|
2
2
|
import type { TemplateBackground } from '../interface/data/payload';
|
|
3
3
|
|
|
4
|
-
type BackgroundColorMap = {
|
|
5
|
-
name: string | string[];
|
|
6
|
-
color: string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
type CoreBackgroundConfig = {
|
|
10
|
-
id?: string | number;
|
|
11
|
-
name?: string;
|
|
12
|
-
imageUrl?: string;
|
|
13
|
-
mainColor?: string;
|
|
14
|
-
specialColors?: BackgroundColorMap[];
|
|
15
|
-
};
|
|
16
|
-
|
|
17
4
|
const toNameArray = (name?: string | string[]) => {
|
|
18
5
|
if (Array.isArray(name)) return name.filter(Boolean);
|
|
19
6
|
if (!name) return [];
|
|
@@ -27,10 +14,11 @@ export function backgroundChange(
|
|
|
27
14
|
bg: TemplateBackground,
|
|
28
15
|
layout: CardLayoutSchema
|
|
29
16
|
): CardLayoutSchema {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
17
|
+
const extras = bg.fontColorExtra || [];
|
|
18
|
+
const iconSpecialColor =
|
|
19
|
+
extras.find(sc => toNameArray(sc.name).some(n => n === 'icon'))?.color;
|
|
33
20
|
|
|
21
|
+
const applySpecialColor = (el: CardElement): CardElement => {
|
|
34
22
|
const keys: string[] = [];
|
|
35
23
|
if (el.binding) keys.push(String(el.binding));
|
|
36
24
|
if (el.id) keys.push(String(el.id));
|
|
@@ -40,13 +28,49 @@ export function backgroundChange(
|
|
|
40
28
|
const matched = extras.find(sc =>
|
|
41
29
|
toNameArray(sc.name).some(n => keys.some(k => k?.startsWith(n)))
|
|
42
30
|
);
|
|
43
|
-
if (!matched) return el;
|
|
44
31
|
|
|
45
32
|
const baseStyle = { ...(el.style || {}) };
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
let nextEl: CardElement = el;
|
|
34
|
+
|
|
35
|
+
if (matched) {
|
|
36
|
+
if (el.type === 'custom') {
|
|
37
|
+
nextEl = { ...el, style: { ...baseStyle, backgroundColor: matched.color } };
|
|
38
|
+
} else {
|
|
39
|
+
nextEl = { ...el, style: { ...baseStyle, color: matched.color } };
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
const nextStyle = { ...baseStyle };
|
|
43
|
+
let changed = false;
|
|
44
|
+
if (el.type === 'custom') {
|
|
45
|
+
if ('backgroundColor' in nextStyle) {
|
|
46
|
+
delete nextStyle.backgroundColor;
|
|
47
|
+
changed = true;
|
|
48
|
+
}
|
|
49
|
+
if ('background' in nextStyle) {
|
|
50
|
+
delete nextStyle.background;
|
|
51
|
+
changed = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if ('color' in nextStyle) {
|
|
55
|
+
delete nextStyle.color;
|
|
56
|
+
changed = true;
|
|
57
|
+
}
|
|
58
|
+
if (changed) {
|
|
59
|
+
nextEl = { ...el, style: nextStyle };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (nextEl.type === 'text' && (nextEl as any).icon) {
|
|
64
|
+
const nextIcon = { ...(nextEl as any).icon };
|
|
65
|
+
if (iconSpecialColor) {
|
|
66
|
+
nextIcon.color = iconSpecialColor;
|
|
67
|
+
} else if ('color' in nextIcon) {
|
|
68
|
+
delete nextIcon.color;
|
|
69
|
+
}
|
|
70
|
+
nextEl = { ...(nextEl as any), icon: nextIcon } as CardElement;
|
|
48
71
|
}
|
|
49
|
-
|
|
72
|
+
|
|
73
|
+
return nextEl;
|
|
50
74
|
};
|
|
51
75
|
|
|
52
76
|
const traverse = (children: CardElement[] = []): CardElement[] =>
|
|
@@ -61,119 +85,12 @@ export function backgroundChange(
|
|
|
61
85
|
return applySpecialColor(el);
|
|
62
86
|
});
|
|
63
87
|
|
|
88
|
+
const nextChildren = traverse(layout.children || []);
|
|
89
|
+
|
|
64
90
|
return {
|
|
65
91
|
...layout,
|
|
66
92
|
backgroundImage: bg.imgUrl,
|
|
67
93
|
fontColor: bg.fontColor || layout.fontColor,
|
|
68
|
-
children:
|
|
94
|
+
children: nextChildren,
|
|
69
95
|
};
|
|
70
96
|
}
|
|
71
|
-
|
|
72
|
-
export const DEFAULT_DECOR_COLOR = '#94a3b8';
|
|
73
|
-
|
|
74
|
-
export const resolveSpecialStyle = (
|
|
75
|
-
element: CardElement,
|
|
76
|
-
background?: CoreBackgroundConfig | null
|
|
77
|
-
) => {
|
|
78
|
-
if (!background) return {};
|
|
79
|
-
const keys: string[] = [];
|
|
80
|
-
if (element.binding) keys.push(String(element.binding));
|
|
81
|
-
if (element.id) keys.push(String(element.id));
|
|
82
|
-
if (element.type === 'icon') keys.push('icon');
|
|
83
|
-
if (element.type === 'custom') keys.push('decor');
|
|
84
|
-
|
|
85
|
-
const matched = background.specialColors?.find(sc => {
|
|
86
|
-
const names = toNameArray(sc.name);
|
|
87
|
-
return names.some(n => keys.some(k => k?.startsWith(n)));
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
if (!matched) return {};
|
|
91
|
-
if (element.type === 'custom') {
|
|
92
|
-
return { backgroundColor: matched.color };
|
|
93
|
-
}
|
|
94
|
-
return { color: matched.color };
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
export const applySpecialStyle = (
|
|
98
|
-
el: CardElement,
|
|
99
|
-
background: CoreBackgroundConfig | null = null,
|
|
100
|
-
options: { overrideExisting?: boolean; defaultDecorColor?: string } = {}
|
|
101
|
-
): CardElement => {
|
|
102
|
-
const specialStyle = resolveSpecialStyle(el, background);
|
|
103
|
-
const baseStyle = { ...(el.style || {}) };
|
|
104
|
-
const isCustom = el.type === 'custom';
|
|
105
|
-
const hasExplicit = isCustom
|
|
106
|
-
? Boolean(baseStyle.backgroundColor || baseStyle.background)
|
|
107
|
-
: baseStyle.color !== undefined && baseStyle.color !== null;
|
|
108
|
-
|
|
109
|
-
const overrideExisting = options.overrideExisting === true;
|
|
110
|
-
const hasSpecial = Object.keys(specialStyle).length > 0;
|
|
111
|
-
const defaultDecorColor = options.defaultDecorColor || DEFAULT_DECOR_COLOR;
|
|
112
|
-
|
|
113
|
-
if (hasSpecial) {
|
|
114
|
-
if (hasExplicit && !overrideExisting) return el;
|
|
115
|
-
return { ...el, style: { ...baseStyle, ...specialStyle } };
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (overrideExisting && hasExplicit) {
|
|
119
|
-
const nextStyle = { ...baseStyle };
|
|
120
|
-
if (isCustom) {
|
|
121
|
-
nextStyle.backgroundColor = background?.mainColor || defaultDecorColor;
|
|
122
|
-
} else {
|
|
123
|
-
delete nextStyle.color;
|
|
124
|
-
}
|
|
125
|
-
return { ...el, style: nextStyle };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return el;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
export const applyBackground = (
|
|
132
|
-
layout: CardLayoutSchema,
|
|
133
|
-
background: CoreBackgroundConfig,
|
|
134
|
-
_options: {
|
|
135
|
-
previousBackground?: CoreBackgroundConfig | null;
|
|
136
|
-
defaultDecorColor?: string;
|
|
137
|
-
} = {}
|
|
138
|
-
): CardLayoutSchema => {
|
|
139
|
-
const bgId = Number(background.id);
|
|
140
|
-
const payload: TemplateBackground = {
|
|
141
|
-
id: Number.isFinite(bgId) ? bgId : 0,
|
|
142
|
-
name: background.name!,
|
|
143
|
-
imgUrl: background.imageUrl!,
|
|
144
|
-
fontColor: background.mainColor,
|
|
145
|
-
fontColorExtra:
|
|
146
|
-
background.specialColors?.map(sc => ({
|
|
147
|
-
name: sc.name,
|
|
148
|
-
color: sc.color,
|
|
149
|
-
})) || [],
|
|
150
|
-
};
|
|
151
|
-
return backgroundChange(payload, layout);
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
export const updateElementsStyle = (
|
|
155
|
-
layout: CardLayoutSchema,
|
|
156
|
-
targetIds: string[],
|
|
157
|
-
updates: Record<string, any>
|
|
158
|
-
): CardLayoutSchema => {
|
|
159
|
-
const targets = new Set(targetIds);
|
|
160
|
-
return {
|
|
161
|
-
...layout,
|
|
162
|
-
children: layout.children.map(el =>
|
|
163
|
-
targets.has(el.id)
|
|
164
|
-
? { ...el, style: { ...(el.style || {}), ...updates } }
|
|
165
|
-
: el
|
|
166
|
-
),
|
|
167
|
-
};
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
export const setElementVisible = (
|
|
171
|
-
layout: CardLayoutSchema[],
|
|
172
|
-
key: string,
|
|
173
|
-
visible: boolean
|
|
174
|
-
): CardLayoutSchema[] => {
|
|
175
|
-
return layout.map(la => ({
|
|
176
|
-
...la,
|
|
177
|
-
children: la.children.map(el => (el.key === key ? { ...el, visible } : el)),
|
|
178
|
-
}));
|
|
179
|
-
};
|
package/package.json
CHANGED
package/render/helpers.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { addUnit } from '../helpers';
|
|
2
2
|
import { getAbsLayout } from '../layout';
|
|
3
|
+
import { resolveBindingValue } from '../data';
|
|
3
4
|
import type {
|
|
4
5
|
CardElement,
|
|
5
6
|
CardLayoutSchema,
|
|
@@ -9,7 +10,10 @@ import type {
|
|
|
9
10
|
TextElement,
|
|
10
11
|
} from '../interface';
|
|
11
12
|
|
|
12
|
-
export const buildWrapperStyle = (
|
|
13
|
+
export const buildWrapperStyle = (
|
|
14
|
+
el: CardElement,
|
|
15
|
+
unit: 'px' | 'rpx' = 'px'
|
|
16
|
+
) => {
|
|
13
17
|
const abs = getAbsLayout(el);
|
|
14
18
|
if (!abs) return {};
|
|
15
19
|
return {
|
|
@@ -23,14 +27,13 @@ export const buildWrapperStyle = (el: CardElement, unit: 'px' | 'rpx' = 'px') =>
|
|
|
23
27
|
};
|
|
24
28
|
};
|
|
25
29
|
|
|
26
|
-
export const buildCardStyle = (
|
|
30
|
+
export const buildCardStyle = (
|
|
31
|
+
layout: CardLayoutSchema,
|
|
32
|
+
unit: 'px' | 'rpx' = 'px'
|
|
33
|
+
) => ({
|
|
27
34
|
width: addUnit(layout.width, unit),
|
|
28
35
|
height: addUnit(layout.height, unit),
|
|
29
36
|
color: layout.fontColor,
|
|
30
|
-
borderRadius:
|
|
31
|
-
layout.borderRadius !== undefined
|
|
32
|
-
? addUnit(layout.borderRadius, unit)
|
|
33
|
-
: undefined,
|
|
34
37
|
padding:
|
|
35
38
|
layout.padding !== undefined ? addUnit(layout.padding, unit) : undefined,
|
|
36
39
|
position: 'relative',
|
|
@@ -39,14 +42,17 @@ export const buildCardStyle = (layout: CardLayoutSchema, unit: 'px' | 'rpx' = 'p
|
|
|
39
42
|
backgroundColor: 'transparent',
|
|
40
43
|
});
|
|
41
44
|
|
|
42
|
-
export const buildBackgroundStyle = (
|
|
45
|
+
export const buildBackgroundStyle = (
|
|
46
|
+
layout: CardLayoutSchema,
|
|
47
|
+
unit: 'px' | 'rpx' = 'px'
|
|
48
|
+
) => ({
|
|
43
49
|
zIndex: layout.backgroundZIndex,
|
|
44
|
-
|
|
45
|
-
layout.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
width: layout.backgroundWidth
|
|
51
|
+
? addUnit(layout.backgroundWidth, unit)
|
|
52
|
+
: '100%',
|
|
53
|
+
height: layout.backgroundHeight
|
|
54
|
+
? addUnit(layout.backgroundHeight, unit)
|
|
55
|
+
: '100%',
|
|
50
56
|
position: 'absolute',
|
|
51
57
|
left: 0,
|
|
52
58
|
top: 0,
|
|
@@ -57,7 +63,10 @@ export const buildBaseContentStyle = (el: CardElement) => ({
|
|
|
57
63
|
boxSizing: 'border-box',
|
|
58
64
|
});
|
|
59
65
|
|
|
60
|
-
export const buildPanelContentStyle = (
|
|
66
|
+
export const buildPanelContentStyle = (
|
|
67
|
+
el: LayoutPanelElement,
|
|
68
|
+
unit: 'px' | 'rpx' = 'px'
|
|
69
|
+
) => ({
|
|
61
70
|
position: 'relative',
|
|
62
71
|
width: '100%',
|
|
63
72
|
height: '100%',
|
|
@@ -66,7 +75,10 @@ export const buildPanelContentStyle = (el: LayoutPanelElement, unit: 'px' | 'rpx
|
|
|
66
75
|
...(el.style || {}),
|
|
67
76
|
});
|
|
68
77
|
|
|
69
|
-
export const buildTextContentStyle = (
|
|
78
|
+
export const buildTextContentStyle = (
|
|
79
|
+
el: TextElement,
|
|
80
|
+
unit: 'px' | 'rpx' = 'px'
|
|
81
|
+
) => {
|
|
70
82
|
const textAlign =
|
|
71
83
|
(el.style?.textAlign as string | undefined) || el.align || undefined;
|
|
72
84
|
const style: Record<string, any> = {
|
|
@@ -83,28 +95,60 @@ export const buildTextContentStyle = (el: TextElement, unit: 'px' | 'rpx' = 'px'
|
|
|
83
95
|
return style;
|
|
84
96
|
};
|
|
85
97
|
|
|
86
|
-
export const
|
|
98
|
+
export const buildTextValueStyle = (
|
|
99
|
+
el: TextElement,
|
|
100
|
+
unit: 'px' | 'rpx' = 'px'
|
|
101
|
+
) => {
|
|
102
|
+
const style: Record<string, any> = {
|
|
103
|
+
letterSpacing:
|
|
104
|
+
el.style?.letterSpacing !== undefined && el.style?.letterSpacing !== null
|
|
105
|
+
? addUnit(el.style.letterSpacing as any, unit)
|
|
106
|
+
: '0',
|
|
107
|
+
};
|
|
108
|
+
return style;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const buildImageContentStyle = (
|
|
112
|
+
el: ImageElement,
|
|
113
|
+
unit: 'px' | 'rpx' = 'px'
|
|
114
|
+
) => {
|
|
87
115
|
const style: Record<string, any> = { ...(el.style || {}) };
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
116
|
+
style.borderWidth =
|
|
117
|
+
el.style?.borderWidth !== undefined && el.style?.borderWidth !== null
|
|
118
|
+
? addUnit(el.style.borderWidth as any, unit)
|
|
119
|
+
: '0';
|
|
120
|
+
style.borderRadius =
|
|
121
|
+
el.style?.borderRadius !== undefined && el.style?.borderRadius !== null
|
|
122
|
+
? addUnit(el.style.borderRadius as any, unit)
|
|
123
|
+
: '0';
|
|
93
124
|
return style;
|
|
94
125
|
};
|
|
95
126
|
|
|
96
|
-
export const getTextValue = (el: TextElement) =>
|
|
97
|
-
|
|
98
|
-
?
|
|
99
|
-
|
|
127
|
+
export const getTextValue = (el: TextElement, data?: Record<string, any>) => {
|
|
128
|
+
const bound =
|
|
129
|
+
el.binding && data ? resolveBindingValue(el.binding, data) : undefined;
|
|
130
|
+
const val =
|
|
131
|
+
bound !== undefined && bound !== null
|
|
132
|
+
? bound
|
|
133
|
+
: el.defaultValue !== undefined && el.defaultValue !== null
|
|
134
|
+
? el.defaultValue
|
|
135
|
+
: '';
|
|
136
|
+
return `${val ?? ''}`;
|
|
137
|
+
};
|
|
100
138
|
|
|
101
|
-
export const getImageSrc = (el: ImageElement) =>
|
|
102
|
-
|
|
139
|
+
export const getImageSrc = (el: ImageElement, data?: Record<string, any>) => {
|
|
140
|
+
const bound =
|
|
141
|
+
el.binding && data ? resolveBindingValue(el.binding, data) : undefined;
|
|
142
|
+
return (bound as any) || el.defaultUrl || el.defaultValue || '';
|
|
143
|
+
};
|
|
103
144
|
|
|
104
145
|
export const getIconName = (el: IconElement) =>
|
|
105
146
|
(el.name || el.defaultValue || '') as string;
|
|
106
147
|
|
|
107
|
-
export const buildTextIconMeta = (
|
|
148
|
+
export const buildTextIconMeta = (
|
|
149
|
+
el: TextElement,
|
|
150
|
+
unit: 'px' | 'rpx' = 'px'
|
|
151
|
+
) => {
|
|
108
152
|
const icon = el.icon;
|
|
109
153
|
const enabled = icon?.enable === true;
|
|
110
154
|
if (!icon || !enabled) return null;
|
package/render/init.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { CardElement, CardLayoutSchema } from "../interface";
|
|
2
|
+
|
|
3
|
+
type CompanyDuty = {
|
|
4
|
+
company: string;
|
|
5
|
+
duty: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function handleSpecialFields(data: { user: Record<string, any> }): {
|
|
9
|
+
user: Record<string, any>;
|
|
10
|
+
} {
|
|
11
|
+
const user = data.user ?? {};
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
...data,
|
|
15
|
+
user: {
|
|
16
|
+
...user,
|
|
17
|
+
// 1. 构造 baseCompanyDuty
|
|
18
|
+
baseCompanyDuty:
|
|
19
|
+
user.company && user.duty
|
|
20
|
+
? `${user.company} ${user.duty}`
|
|
21
|
+
: user.baseCompanyDuty,
|
|
22
|
+
|
|
23
|
+
// 2. 构造 moreCardInfo.company
|
|
24
|
+
moreCardInfo: user.moreCardInfo
|
|
25
|
+
? {
|
|
26
|
+
...user.moreCardInfo,
|
|
27
|
+
company: Array.isArray(user.moreCardInfo.company)
|
|
28
|
+
? (user.moreCardInfo.company as CompanyDuty[]).map(
|
|
29
|
+
item => `${item.company} ${item.duty}`
|
|
30
|
+
)
|
|
31
|
+
: user.moreCardInfo.company,
|
|
32
|
+
}
|
|
33
|
+
: user.moreCardInfo,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
type Data = { user: Record<string, any> };
|
|
43
|
+
|
|
44
|
+
const SHOW_KEYS = new Set([
|
|
45
|
+
"company_duty_custom",
|
|
46
|
+
"company_duty_1",
|
|
47
|
+
"company_duty_2",
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
const HIDE_KEYS = new Set(["company", "duty"]);
|
|
51
|
+
|
|
52
|
+
function getCompanyLen(data: Data): number {
|
|
53
|
+
const company = (data?.user as any)?.moreCardInfo?.company;
|
|
54
|
+
return Array.isArray(company) ? company.length : 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function updateElementsVisible(
|
|
58
|
+
elements: CardElement[] | undefined,
|
|
59
|
+
showMore: boolean
|
|
60
|
+
): CardElement[] | undefined {
|
|
61
|
+
if (!elements) return elements;
|
|
62
|
+
|
|
63
|
+
return elements.map((el) => {
|
|
64
|
+
// 先递归处理 layout-panel 的 children
|
|
65
|
+
let next: CardElement = el;
|
|
66
|
+
if (el.type === "layout-panel") {
|
|
67
|
+
next = {
|
|
68
|
+
...el,
|
|
69
|
+
children: updateElementsVisible(el.children, showMore),
|
|
70
|
+
} as CardElement;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const key = (next as any).key as string | undefined;
|
|
74
|
+
if (!key) return next;
|
|
75
|
+
|
|
76
|
+
// showMore=true: 显示 company_duty_*,隐藏 company/duty
|
|
77
|
+
// showMore=false: 反过来
|
|
78
|
+
if (SHOW_KEYS.has(key)) {
|
|
79
|
+
return { ...next, visible: showMore };
|
|
80
|
+
}
|
|
81
|
+
if (HIDE_KEYS.has(key)) {
|
|
82
|
+
return { ...next, visible: !showMore };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return next;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 根据 user.moreCardInfo.company 数组长度切换元素 visible:
|
|
91
|
+
* - length > 0: key in [company_duty_custom, company_duty_1, company_duty_2] => visible=true
|
|
92
|
+
* key in [company, duty] => visible=false
|
|
93
|
+
* - length === 0: 反之
|
|
94
|
+
*/
|
|
95
|
+
export function processCardLayout(
|
|
96
|
+
layout: CardLayoutSchema[],
|
|
97
|
+
data: Data
|
|
98
|
+
): CardLayoutSchema[] {
|
|
99
|
+
const companyLen = getCompanyLen(data);
|
|
100
|
+
const showMore = companyLen > 0;
|
|
101
|
+
|
|
102
|
+
return layout.map((card) => ({
|
|
103
|
+
...card,
|
|
104
|
+
children: (updateElementsVisible(card.children, showMore) ??
|
|
105
|
+
card.children) as CardElement[],
|
|
106
|
+
}));
|
|
107
|
+
}
|