km-card-layout-core 0.1.0
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 +18 -0
- package/dist/index.js +524 -0
- package/dist/interface/data/payload.js +2 -0
- package/dist/interface/elements.js +2 -0
- package/dist/interface/index.js +19 -0
- package/dist/interface/layout.js +2 -0
- package/dist/interface/render.js +2 -0
- package/dist/utils.js +64 -0
- package/index.js +481 -0
- package/index.ts +614 -0
- package/interface/data/payload.ts +24 -0
- package/interface/elements.ts +110 -0
- package/interface/index.ts +3 -0
- package/interface/layout.ts +19 -0
- package/interface/render.ts +42 -0
- package/package.json +12 -0
- package/tsconfig.build.json +15 -0
- package/types.d.ts +46 -0
- package/utils.ts +67 -0
package/index.js
ADDED
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CardMaster 布局 JSON 渲染核心。
|
|
4
|
+
*
|
|
5
|
+
* - 平台无关:不依赖 DOM/小程序 API,方便在 Web/小程序/Node 复用。
|
|
6
|
+
* - 职责:将布局 Schema 与业务数据合成为带内联样式的渲染树,外层只需将节点映射到各端组件。
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.buildRenderResult = exports.buildRenderNodes = exports.resolveBindingValue = exports.normalizeLayout = exports.styleObjectToString = exports.addUnit = void 0;
|
|
10
|
+
/** ---------- 常量 ---------- */
|
|
11
|
+
const DEFAULT_CARD_WIDTH = 343; // 默认卡片宽度(像素)
|
|
12
|
+
const DEFAULT_CARD_HEIGHT = 210; // 默认卡片高度(像素)
|
|
13
|
+
const DEFAULT_GROUP_GAP = 22; // repeatable-item 默认纵向间距
|
|
14
|
+
const DIMENSION_PROPS = new Set([
|
|
15
|
+
'width',
|
|
16
|
+
'height',
|
|
17
|
+
'top',
|
|
18
|
+
'right',
|
|
19
|
+
'bottom',
|
|
20
|
+
'left',
|
|
21
|
+
'padding',
|
|
22
|
+
'paddingTop',
|
|
23
|
+
'paddingBottom',
|
|
24
|
+
'paddingLeft',
|
|
25
|
+
'paddingRight',
|
|
26
|
+
'margin',
|
|
27
|
+
'marginTop',
|
|
28
|
+
'marginBottom',
|
|
29
|
+
'marginLeft',
|
|
30
|
+
'marginRight',
|
|
31
|
+
'fontSize',
|
|
32
|
+
'lineHeight',
|
|
33
|
+
'borderRadius',
|
|
34
|
+
'borderWidth',
|
|
35
|
+
'letterSpacing',
|
|
36
|
+
'gap',
|
|
37
|
+
'rowGap',
|
|
38
|
+
'columnGap',
|
|
39
|
+
'flexBasis',
|
|
40
|
+
]);
|
|
41
|
+
/** ---------- 基础工具 ---------- */
|
|
42
|
+
|
|
43
|
+
const toNumber = (value) => {
|
|
44
|
+
const num = Number(value);
|
|
45
|
+
return Number.isFinite(num) ? num : undefined;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const toKebab = (key) => key.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
49
|
+
|
|
50
|
+
const addUnit = (value, unit) => {
|
|
51
|
+
if (value === undefined || value === null || value === '')
|
|
52
|
+
return undefined;
|
|
53
|
+
if (typeof value === 'number')
|
|
54
|
+
return `${value}${unit}`;
|
|
55
|
+
return `${value}`;
|
|
56
|
+
};
|
|
57
|
+
exports.addUnit = addUnit;
|
|
58
|
+
|
|
59
|
+
const styleObjectToString = (style, unit = 'px') => {
|
|
60
|
+
if (!style)
|
|
61
|
+
return '';
|
|
62
|
+
const pairs = [];
|
|
63
|
+
Object.keys(style).forEach(key => {
|
|
64
|
+
const value = style[key];
|
|
65
|
+
if (value === undefined || value === null || value === '')
|
|
66
|
+
return;
|
|
67
|
+
const useUnit = typeof value === 'number' && DIMENSION_PROPS.has(key)
|
|
68
|
+
? (0, exports.addUnit)(value, unit)
|
|
69
|
+
: value;
|
|
70
|
+
pairs.push(`${toKebab(key)}:${useUnit}`);
|
|
71
|
+
});
|
|
72
|
+
return pairs.join(';');
|
|
73
|
+
};
|
|
74
|
+
exports.styleObjectToString = styleObjectToString;
|
|
75
|
+
/**
|
|
76
|
+
* 容错 JSON 解析:字符串用 JSON.parse,其他保持原样或返回 null。
|
|
77
|
+
*/
|
|
78
|
+
const parseJson = (input) => {
|
|
79
|
+
if (typeof input !== 'string')
|
|
80
|
+
return input !== null && input !== void 0 ? input : null;
|
|
81
|
+
try {
|
|
82
|
+
return JSON.parse(input);
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
console.warn('[km-card-layout-core] JSON parse failed', err);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const isObject = (val) => Boolean(val) && typeof val === 'object';
|
|
90
|
+
const getAbsLayout = (el) => el.layout && el.layout.mode === 'absolute'
|
|
91
|
+
? el.layout
|
|
92
|
+
: null;
|
|
93
|
+
const getFlexLayout = (el) => el.layout && el.layout.mode === 'flex'
|
|
94
|
+
? el.layout
|
|
95
|
+
: null;
|
|
96
|
+
/** ---------- 布局与数据解析 ---------- */
|
|
97
|
+
/**
|
|
98
|
+
* 归一化布局输入(对象或 JSON 字符串),补齐宽高/容器/children 默认值。
|
|
99
|
+
*/
|
|
100
|
+
const normalizeLayout = (layout) => {
|
|
101
|
+
var _a, _b;
|
|
102
|
+
if (!layout)
|
|
103
|
+
return null;
|
|
104
|
+
const parsed = typeof layout === 'string' ? parseJson(layout) : layout;
|
|
105
|
+
if (!parsed || typeof parsed !== 'object')
|
|
106
|
+
return null;
|
|
107
|
+
return {
|
|
108
|
+
...parsed,
|
|
109
|
+
width: (_a = toNumber(parsed.width)) !== null && _a !== void 0 ? _a : DEFAULT_CARD_WIDTH,
|
|
110
|
+
height: (_b = toNumber(parsed.height)) !== null && _b !== void 0 ? _b : DEFAULT_CARD_HEIGHT,
|
|
111
|
+
container: parsed.container || { mode: 'absolute' },
|
|
112
|
+
children: Array.isArray(parsed.children)
|
|
113
|
+
? parsed.children
|
|
114
|
+
: [],
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
exports.normalizeLayout = normalizeLayout;
|
|
118
|
+
/**
|
|
119
|
+
* 将绑定路径拆分为片段,支持点语法与数组下标。
|
|
120
|
+
*/
|
|
121
|
+
const pathToSegments = (path) => `${path || ''}`
|
|
122
|
+
.replace(/\[(\d+)\]/g, '.$1')
|
|
123
|
+
.split('.')
|
|
124
|
+
.map(p => p.trim())
|
|
125
|
+
.filter(Boolean);
|
|
126
|
+
/**
|
|
127
|
+
* 按路径访问对象/数组,缺失时返回 undefined/null。
|
|
128
|
+
*/
|
|
129
|
+
const readByPath = (data, path) => {
|
|
130
|
+
if (path === undefined || path === null || path === '')
|
|
131
|
+
return data;
|
|
132
|
+
const segments = pathToSegments(path);
|
|
133
|
+
let cursor = data;
|
|
134
|
+
for (let i = 0; i < segments.length; i += 1) {
|
|
135
|
+
if (!isObject(cursor) && !Array.isArray(cursor))
|
|
136
|
+
return undefined;
|
|
137
|
+
cursor = cursor[segments[i]];
|
|
138
|
+
if (cursor === undefined || cursor === null) {
|
|
139
|
+
return cursor;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return cursor;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const resolveBindingValue = (binding, rootData, context) => {
|
|
146
|
+
if (!binding)
|
|
147
|
+
return undefined;
|
|
148
|
+
const { contextBinding, contextData } = context || {};
|
|
149
|
+
let target = rootData;
|
|
150
|
+
let path = binding;
|
|
151
|
+
// repeatable-group: binding 等于 dataPath 或以其为前缀时,切换到当前条目数据
|
|
152
|
+
if (contextBinding &&
|
|
153
|
+
(binding === contextBinding || binding.startsWith(`${contextBinding}.`))) {
|
|
154
|
+
target = contextData;
|
|
155
|
+
path =
|
|
156
|
+
binding === contextBinding
|
|
157
|
+
? ''
|
|
158
|
+
: binding.slice(contextBinding.length + 1);
|
|
159
|
+
}
|
|
160
|
+
else if (binding.startsWith('$item.')) {
|
|
161
|
+
target = contextData;
|
|
162
|
+
path = binding.slice('$item.'.length);
|
|
163
|
+
}
|
|
164
|
+
const value = readByPath(target, path);
|
|
165
|
+
return value === undefined ? undefined : value;
|
|
166
|
+
};
|
|
167
|
+
exports.resolveBindingValue = resolveBindingValue;
|
|
168
|
+
/** ---------- 样式构建 ---------- */
|
|
169
|
+
const justifyByTextAlign = (textAlign) => {
|
|
170
|
+
if (textAlign === 'center')
|
|
171
|
+
return 'center';
|
|
172
|
+
if (textAlign === 'right')
|
|
173
|
+
return 'flex-end';
|
|
174
|
+
return 'flex-start';
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* 生成元素外层样式;
|
|
179
|
+
绝对 / 弹性布局;
|
|
180
|
+
始终返回内联样式字符串;
|
|
181
|
+
*
|
|
182
|
+
* @param {*} el
|
|
183
|
+
* @param {*} unit
|
|
184
|
+
* @returns
|
|
185
|
+
*/
|
|
186
|
+
const buildWrapperStyle = (el, unit) => {
|
|
187
|
+
var _a;
|
|
188
|
+
const abs = getAbsLayout(el);
|
|
189
|
+
if (abs) {
|
|
190
|
+
const justifyContent = justifyByTextAlign((_a = el === null || el === void 0 ? void 0 : el.style) === null || _a === void 0 ? void 0 : _a.textAlign);
|
|
191
|
+
return (0, exports.styleObjectToString)({
|
|
192
|
+
position: 'absolute',
|
|
193
|
+
left: (0, exports.addUnit)(abs.x, unit),
|
|
194
|
+
top: (0, exports.addUnit)(abs.y, unit),
|
|
195
|
+
width: (0, exports.addUnit)(abs.width, unit),
|
|
196
|
+
height: (0, exports.addUnit)(abs.height, unit),
|
|
197
|
+
zIndex: abs.zIndex,
|
|
198
|
+
display: 'flex',
|
|
199
|
+
alignItems: 'center',
|
|
200
|
+
justifyContent,
|
|
201
|
+
boxSizing: 'border-box',
|
|
202
|
+
}, unit);
|
|
203
|
+
}
|
|
204
|
+
const flex = getFlexLayout(el);
|
|
205
|
+
const item = flex.item || {};
|
|
206
|
+
return (0, exports.styleObjectToString)({
|
|
207
|
+
width: (0, exports.addUnit)(flex.width, unit),
|
|
208
|
+
height: (0, exports.addUnit)(flex.height, unit),
|
|
209
|
+
order: item.order,
|
|
210
|
+
flexGrow: item.flexGrow,
|
|
211
|
+
flexShrink: item.flexShrink,
|
|
212
|
+
flexBasis: item.flexBasis,
|
|
213
|
+
alignSelf: item.alignSelf,
|
|
214
|
+
display: 'flex',
|
|
215
|
+
alignItems: 'center',
|
|
216
|
+
boxSizing: 'border-box',
|
|
217
|
+
}, unit);
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
*
|
|
221
|
+
* @param {*} padding 数组 / 数字转;
|
|
222
|
+
* @param {*} unit
|
|
223
|
+
* @returns
|
|
224
|
+
*/
|
|
225
|
+
const formatPadding = (padding, unit) => {
|
|
226
|
+
if (padding === undefined || padding === null)
|
|
227
|
+
return undefined;
|
|
228
|
+
if (typeof padding === 'number')
|
|
229
|
+
return (0, exports.addUnit)(padding, unit);
|
|
230
|
+
if (Array.isArray(padding)) {
|
|
231
|
+
const list = padding
|
|
232
|
+
.filter(v => v !== undefined && v !== null)
|
|
233
|
+
.map(v => (0, exports.addUnit)(v, unit));
|
|
234
|
+
if (!list.length)
|
|
235
|
+
return undefined;
|
|
236
|
+
if (list.length === 2)
|
|
237
|
+
return `${list[0]} ${list[1]}`;
|
|
238
|
+
if (list.length === 3)
|
|
239
|
+
return `${list[0]} ${list[1]} ${list[2]}`;
|
|
240
|
+
if (list.length >= 4)
|
|
241
|
+
return `${list[0]} ${list[1]} ${list[2]} ${list[3]}`;
|
|
242
|
+
}
|
|
243
|
+
return undefined;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const buildPanelStyle = (el, unit) => {
|
|
247
|
+
const options = (el.container && el.container.options) || {};
|
|
248
|
+
const style = {
|
|
249
|
+
display: 'flex',
|
|
250
|
+
flexDirection: options.direction || 'row',
|
|
251
|
+
flexWrap: options.wrap || 'nowrap',
|
|
252
|
+
justifyContent: options.justifyContent,
|
|
253
|
+
alignItems: options.alignItems,
|
|
254
|
+
padding: formatPadding(options.padding, unit),
|
|
255
|
+
};
|
|
256
|
+
if (options.gap && typeof options.gap === 'number') {
|
|
257
|
+
style.gap = (0, exports.addUnit)(options.gap, unit);
|
|
258
|
+
}
|
|
259
|
+
else if (options.gap && isObject(options.gap)) {
|
|
260
|
+
style.rowGap = (0, exports.addUnit)(options.gap.row, unit);
|
|
261
|
+
style.columnGap = (0, exports.addUnit)(options.gap.column, unit);
|
|
262
|
+
}
|
|
263
|
+
return (0, exports.styleObjectToString)(style, unit);
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const normalizeElementStyle = (style, unit) => {
|
|
267
|
+
if (!style)
|
|
268
|
+
return '';
|
|
269
|
+
return (0, exports.styleObjectToString)(style, unit);
|
|
270
|
+
};
|
|
271
|
+
/** ---------- Repeatable 相关 ---------- */
|
|
272
|
+
|
|
273
|
+
const inferGroupGap = (group) => {
|
|
274
|
+
const items = group.items || [];
|
|
275
|
+
if (items.length >= 2) {
|
|
276
|
+
const first = (items[0].elements || []).map(getAbsLayout).find(Boolean);
|
|
277
|
+
const second = (items[1].elements || []).map(getAbsLayout).find(Boolean);
|
|
278
|
+
if (first &&
|
|
279
|
+
second &&
|
|
280
|
+
typeof first.y === 'number' &&
|
|
281
|
+
typeof second.y === 'number') {
|
|
282
|
+
return Math.abs(second.y - first.y);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return DEFAULT_GROUP_GAP;
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const materializeRepeatableItems = (group, rootData) => {
|
|
289
|
+
const result = [];
|
|
290
|
+
const dataset = (0, exports.resolveBindingValue)(group.dataPath, rootData, {}) || [];
|
|
291
|
+
const dataList = Array.isArray(dataset) ? dataset : [];
|
|
292
|
+
const maxItems = group.maxItems ||
|
|
293
|
+
dataList.length ||
|
|
294
|
+
(group.items || []).length ||
|
|
295
|
+
(group.itemTemplate || []).length;
|
|
296
|
+
const template = (group.items && group.items[0] && group.items[0].elements) ||
|
|
297
|
+
group.itemTemplate ||
|
|
298
|
+
[];
|
|
299
|
+
const gap = inferGroupGap(group);
|
|
300
|
+
// Use saved items (from designer) first
|
|
301
|
+
if (group.items && group.items.length) {
|
|
302
|
+
group.items.slice(0, maxItems).forEach((item, idx) => {
|
|
303
|
+
const payload = dataList[idx] !== undefined ? dataList[idx] : item.data;
|
|
304
|
+
(item.elements || []).forEach(el => {
|
|
305
|
+
result.push({
|
|
306
|
+
element: el,
|
|
307
|
+
contextData: payload,
|
|
308
|
+
contextBinding: group.dataPath,
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
return result;
|
|
313
|
+
}
|
|
314
|
+
// Otherwise clone from template by gap
|
|
315
|
+
dataList.slice(0, maxItems).forEach((payload, idx) => {
|
|
316
|
+
template.forEach(el => {
|
|
317
|
+
const abs = getAbsLayout(el);
|
|
318
|
+
const cloned = abs
|
|
319
|
+
? {
|
|
320
|
+
...el,
|
|
321
|
+
layout: { ...abs, y: abs.y + idx * gap },
|
|
322
|
+
}
|
|
323
|
+
: el;
|
|
324
|
+
result.push({
|
|
325
|
+
element: cloned,
|
|
326
|
+
contextData: payload,
|
|
327
|
+
contextBinding: group.dataPath,
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
return result;
|
|
332
|
+
};
|
|
333
|
+
/** ---------- 渲染树构建 ---------- */
|
|
334
|
+
|
|
335
|
+
const buildRenderNodes = (children, rootData, unit = 'px', context = {}) => {
|
|
336
|
+
if (!Array.isArray(children))
|
|
337
|
+
return [];
|
|
338
|
+
// Mark mutually exclusive bindings to hide them when repeatable-group is present
|
|
339
|
+
const excluded = new Set();
|
|
340
|
+
children.forEach(el => {
|
|
341
|
+
if (el && el.type === 'repeatable-group' && !!el.visible) {
|
|
342
|
+
(el.mutualExcludes || []).forEach(b => excluded.add(b));
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
const nodes = [];
|
|
346
|
+
children.forEach(el => {
|
|
347
|
+
if (!el || el.visible === false)
|
|
348
|
+
return;
|
|
349
|
+
if (el.type === 'repeatable-group') {
|
|
350
|
+
const instances = materializeRepeatableItems(el, rootData);
|
|
351
|
+
instances.forEach(({ element, contextData, contextBinding }) => {
|
|
352
|
+
const node = buildNode(element, rootData, unit, {
|
|
353
|
+
...context,
|
|
354
|
+
contextData,
|
|
355
|
+
contextBinding,
|
|
356
|
+
});
|
|
357
|
+
if (node)
|
|
358
|
+
nodes.push(node);
|
|
359
|
+
});
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (el.binding && excluded.has(el.binding))
|
|
363
|
+
return;
|
|
364
|
+
const node = buildNode(el, rootData, unit, context);
|
|
365
|
+
if (node)
|
|
366
|
+
nodes.push(node);
|
|
367
|
+
});
|
|
368
|
+
return nodes;
|
|
369
|
+
};
|
|
370
|
+
exports.buildRenderNodes = buildRenderNodes;
|
|
371
|
+
|
|
372
|
+
const buildNode = (el, rootData, unit, context) => {
|
|
373
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
374
|
+
if (!el || el.visible === false)
|
|
375
|
+
return null;
|
|
376
|
+
const wrapperStyle = buildWrapperStyle(el, unit);
|
|
377
|
+
if (el.type === 'layout-panel') {
|
|
378
|
+
return {
|
|
379
|
+
id: el.id,
|
|
380
|
+
type: el.type,
|
|
381
|
+
visible: !!el.visible,
|
|
382
|
+
wrapperStyle,
|
|
383
|
+
contentStyle: buildPanelStyle(el, unit),
|
|
384
|
+
children: (0, exports.buildRenderNodes)(el.children || [], rootData, unit, context),
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
const baseStyle = normalizeElementStyle(el.style, unit);
|
|
388
|
+
if (el.type === 'text') {
|
|
389
|
+
const align = ((_a = el.style) === null || _a === void 0 ? void 0 : _a.textAlign) || el.align;
|
|
390
|
+
const textStyle = align ? `${baseStyle};text-align:${align}` : baseStyle;
|
|
391
|
+
const value = (_c = (_b = (0, exports.resolveBindingValue)(el.binding, rootData, context)) !== null && _b !== void 0 ? _b : el.defaultValue) !== null && _c !== void 0 ? _c : '';
|
|
392
|
+
return {
|
|
393
|
+
id: el.id,
|
|
394
|
+
type: el.type,
|
|
395
|
+
wrapperStyle,
|
|
396
|
+
contentStyle: textStyle,
|
|
397
|
+
text: `${value}`,
|
|
398
|
+
visible: !!el.visible,
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
if (el.type === 'image') {
|
|
402
|
+
const src = (_f = (_e = (_d = (0, exports.resolveBindingValue)(el.binding, rootData, context)) !== null && _d !== void 0 ? _d : el.defaultUrl) !== null && _e !== void 0 ? _e : el.defaultValue) !== null && _f !== void 0 ? _f : '';
|
|
403
|
+
const mode = el.fit === 'contain' ? 'aspectFit' : 'aspectFill';
|
|
404
|
+
return {
|
|
405
|
+
id: el.id,
|
|
406
|
+
type: el.type,
|
|
407
|
+
wrapperStyle,
|
|
408
|
+
contentStyle: baseStyle,
|
|
409
|
+
src,
|
|
410
|
+
mode,
|
|
411
|
+
visible: !!el.visible,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
if (el.type === 'icon') {
|
|
415
|
+
const text = (_j = (_h = (_g = (0, exports.resolveBindingValue)(el.binding, rootData, context)) !== null && _g !== void 0 ? _g : el.name) !== null && _h !== void 0 ? _h : el.defaultValue) !== null && _j !== void 0 ? _j : '';
|
|
416
|
+
return {
|
|
417
|
+
id: el.id,
|
|
418
|
+
type: el.type,
|
|
419
|
+
wrapperStyle,
|
|
420
|
+
contentStyle: baseStyle,
|
|
421
|
+
text: `${text}`,
|
|
422
|
+
visible: !!el.visible,
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
if (el.type === 'custom') {
|
|
426
|
+
return {
|
|
427
|
+
id: el.id,
|
|
428
|
+
type: el.type,
|
|
429
|
+
wrapperStyle,
|
|
430
|
+
contentStyle: baseStyle,
|
|
431
|
+
visible: !!el.visible,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
// Unknown type fallback to simple text node
|
|
435
|
+
return {
|
|
436
|
+
id: el.id,
|
|
437
|
+
type: 'text',
|
|
438
|
+
wrapperStyle,
|
|
439
|
+
contentStyle: baseStyle,
|
|
440
|
+
text: el.defaultValue || '',
|
|
441
|
+
visible: !!el.visible,
|
|
442
|
+
};
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
const buildRenderResult = (layoutInput, dataInput, unit = 'px') => {
|
|
446
|
+
const layout = (0, exports.normalizeLayout)(layoutInput);
|
|
447
|
+
if (!layout) {
|
|
448
|
+
return {
|
|
449
|
+
renderTree: [],
|
|
450
|
+
cardStyle: '',
|
|
451
|
+
backgroundImage: '',
|
|
452
|
+
backgroundStyle: '',
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
const cardStyle = (0, exports.styleObjectToString)({
|
|
456
|
+
width: (0, exports.addUnit)(layout.width, unit),
|
|
457
|
+
height: (0, exports.addUnit)(layout.height, unit),
|
|
458
|
+
color: layout.fontColor,
|
|
459
|
+
borderRadius: layout.borderRadius !== undefined
|
|
460
|
+
? (0, exports.addUnit)(layout.borderRadius, unit)
|
|
461
|
+
: undefined,
|
|
462
|
+
padding: layout.padding !== undefined
|
|
463
|
+
? (0, exports.addUnit)(layout.padding, unit)
|
|
464
|
+
: undefined,
|
|
465
|
+
position: 'relative',
|
|
466
|
+
}, unit);
|
|
467
|
+
const bgStyle = (0, exports.styleObjectToString)({
|
|
468
|
+
zIndex: layout.backgroundZIndex,
|
|
469
|
+
borderRadius: layout.borderRadius !== undefined
|
|
470
|
+
? (0, exports.addUnit)(layout.borderRadius, unit)
|
|
471
|
+
: undefined,
|
|
472
|
+
}, unit);
|
|
473
|
+
const renderTree = (0, exports.buildRenderNodes)(layout.children || [], dataInput || {}, unit);
|
|
474
|
+
return {
|
|
475
|
+
renderTree,
|
|
476
|
+
cardStyle,
|
|
477
|
+
backgroundImage: layout.backgroundImage || '',
|
|
478
|
+
backgroundStyle: bgStyle,
|
|
479
|
+
};
|
|
480
|
+
};
|
|
481
|
+
exports.buildRenderResult = buildRenderResult;
|