km-card-layout-component-miniprogram 0.1.8 → 0.1.10

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 (66) hide show
  1. package/example/pages/home/index.js +382 -16
  2. package/miniprogram_dist/components/card-layout/elements/custom-element/index.js +31 -0
  3. package/miniprogram_dist/components/card-layout/elements/custom-element/index.json +3 -0
  4. package/miniprogram_dist/components/card-layout/elements/custom-element/index.wxml +5 -0
  5. package/miniprogram_dist/components/card-layout/elements/custom-element/index.wxss +14 -0
  6. package/miniprogram_dist/components/card-layout/elements/icon-element/index.js +43 -0
  7. package/miniprogram_dist/components/card-layout/elements/icon-element/index.json +3 -0
  8. package/miniprogram_dist/components/card-layout/elements/icon-element/index.wxml +5 -0
  9. package/miniprogram_dist/components/card-layout/elements/icon-element/index.wxss +37 -0
  10. package/miniprogram_dist/components/card-layout/elements/image-element/index.js +36 -0
  11. package/miniprogram_dist/components/card-layout/elements/image-element/index.json +3 -0
  12. package/miniprogram_dist/components/card-layout/elements/image-element/index.wxml +8 -0
  13. package/miniprogram_dist/components/card-layout/elements/image-element/index.wxss +10 -0
  14. package/miniprogram_dist/components/card-layout/elements/text-element/index.js +52 -0
  15. package/miniprogram_dist/components/card-layout/elements/text-element/index.json +3 -0
  16. package/miniprogram_dist/components/card-layout/elements/text-element/index.wxml +29 -0
  17. package/miniprogram_dist/components/card-layout/elements/text-element/index.wxss +59 -0
  18. package/miniprogram_dist/components/card-layout/index.js +23 -38
  19. package/miniprogram_dist/components/card-layout/index.json +7 -1
  20. package/miniprogram_dist/components/card-layout/index.wxml +15 -63
  21. package/miniprogram_dist/components/card-layout/index.wxss +0 -65
  22. package/miniprogram_dist/utils/card-schema.js +12 -3
  23. package/miniprogram_dist/vendor/km-card-layout-core/bindings.js +4 -0
  24. package/miniprogram_dist/vendor/km-card-layout-core/data.js +1 -1
  25. package/miniprogram_dist/vendor/km-card-layout-core/index.js +37 -6
  26. package/miniprogram_dist/vendor/km-card-layout-core/interface/index.js +0 -1
  27. package/miniprogram_dist/vendor/km-card-layout-core/ops/changeBackground.js +8 -1
  28. package/miniprogram_dist/vendor/km-card-layout-core/render/helpers.js +143 -0
  29. package/miniprogram_dist/vendor/km-card-layout-core/render/tool.js +16 -0
  30. package/package.json +1 -1
  31. package/script/sync-core.js +3 -0
  32. package/src/components/card-layout/elements/custom-element/index.json +3 -0
  33. package/src/components/card-layout/elements/custom-element/index.ts +34 -0
  34. package/src/components/card-layout/elements/custom-element/index.wxml +5 -0
  35. package/src/components/card-layout/elements/custom-element/index.wxss +14 -0
  36. package/src/components/card-layout/elements/icon-element/index.json +3 -0
  37. package/src/components/card-layout/elements/icon-element/index.ts +46 -0
  38. package/src/components/card-layout/elements/icon-element/index.wxml +5 -0
  39. package/src/components/card-layout/elements/icon-element/index.wxss +37 -0
  40. package/src/components/card-layout/elements/image-element/index.json +3 -0
  41. package/src/components/card-layout/elements/image-element/index.ts +40 -0
  42. package/src/components/card-layout/elements/image-element/index.wxml +8 -0
  43. package/src/components/card-layout/elements/image-element/index.wxss +10 -0
  44. package/src/components/card-layout/elements/text-element/index.json +3 -0
  45. package/src/components/card-layout/elements/text-element/index.ts +57 -0
  46. package/src/components/card-layout/elements/text-element/index.wxml +29 -0
  47. package/src/components/card-layout/elements/text-element/index.wxss +59 -0
  48. package/src/components/card-layout/index.json +7 -1
  49. package/src/components/card-layout/index.ts +40 -47
  50. package/src/components/card-layout/index.wxml +15 -63
  51. package/src/components/card-layout/index.wxss +0 -65
  52. package/src/utils/card-schema.ts +11 -4
  53. package/src/vendor/km-card-layout-core/bindings.ts +3 -0
  54. package/src/vendor/km-card-layout-core/data.ts +1 -2
  55. package/src/vendor/km-card-layout-core/index.ts +37 -5
  56. package/src/vendor/km-card-layout-core/interface/data/payload.ts +1 -0
  57. package/src/vendor/km-card-layout-core/interface/index.ts +1 -2
  58. package/src/vendor/km-card-layout-core/ops/changeBackground.ts +14 -4
  59. package/src/vendor/km-card-layout-core/render/helpers.ts +159 -0
  60. package/src/vendor/km-card-layout-core/render/tool.ts +21 -0
  61. package/src/vendor/km-card-layout-core/types.d.ts +74 -15
  62. package/src/vendor/km-card-layout-core/utils.ts +4 -0
  63. package/miniprogram_dist/vendor/km-card-layout-core/interface/render.js +0 -2
  64. package/miniprogram_dist/vendor/km-card-layout-core/render/builder.js +0 -210
  65. package/src/vendor/km-card-layout-core/interface/render.ts +0 -53
  66. package/src/vendor/km-card-layout-core/render/builder.ts +0 -288
@@ -1,25 +1,33 @@
1
1
  import type {
2
+ CardElement,
2
3
  CardLayoutInput,
3
4
  CardLayoutSchema,
4
- RenderNode,
5
+ LayoutPanelElement,
5
6
  } from '../../vendor/km-card-layout-core/index';
6
7
  import {
7
- buildRenderResult,
8
+ buildBackgroundStyle,
9
+ buildCardStyle,
10
+ buildPanelContentStyle,
11
+ buildWrapperStyle,
8
12
  normalizeLayout,
13
+ styleObjectToString,
9
14
  } from '../../vendor/km-card-layout-core/index';
10
- import { ICON_CODE_MAP } from './icon-map';
11
15
 
12
- type LayoutData = {
13
- [key: string]: any;
16
+ type PanelElement = LayoutPanelElement & {
17
+ wrapperStyle: string;
18
+ contentStyle: string;
19
+ children?: RenderElement[];
14
20
  };
15
21
 
16
- interface RenderCard {
22
+ type RenderElement = CardElement | PanelElement;
23
+
24
+ type RenderCard = {
17
25
  id: string;
18
26
  cardStyle: string;
19
27
  backgroundImage?: string;
20
28
  backgroundStyle: string;
21
- nodes: RenderNode[];
22
- }
29
+ elements: RenderElement[];
30
+ };
23
31
 
24
32
  const ensureArray = (input: CardLayoutInput | any): CardLayoutInput => {
25
33
  if (!input) return [];
@@ -31,43 +39,27 @@ const pickCardId = (layout: any, idx: number) => {
31
39
  return `card-${idx}`;
32
40
  };
33
41
 
34
- const mapIconGlyph = (name?: string, fallback?: string) => {
35
- if (!name) return fallback;
36
- const glyph = ICON_CODE_MAP[name];
37
- if (glyph) return String.fromCharCode(parseInt(glyph, 16));
38
- return fallback || name;
39
- };
40
-
41
- const mapRenderNode = (node: RenderNode): RenderNode => {
42
- const icon = node.icon
43
- ? {
44
- ...node.icon,
45
- text: mapIconGlyph(node.icon.name, node.icon.text),
46
- }
47
- : undefined;
48
- const children = node.children?.map(mapRenderNode);
49
- const mappedText =
50
- node.type === 'icon' ? mapIconGlyph(node.name, node.text) : node.text;
51
-
52
- return {
53
- ...node,
54
- text: mappedText,
55
- icon,
56
- children,
57
- };
58
- };
59
-
60
- const mapRenderTree = (nodes: RenderNode[]) =>
61
- Array.isArray(nodes) ? nodes.map(mapRenderNode) : [];
42
+ const decorateElements = (children: CardElement[] = []): RenderElement[] =>
43
+ (children || []).map(el => {
44
+ if (el.type === 'layout-panel') {
45
+ const panel = el as LayoutPanelElement;
46
+ return {
47
+ ...panel,
48
+ wrapperStyle: styleObjectToString(buildWrapperStyle(panel, 'rpx'), 'rpx'),
49
+ contentStyle: styleObjectToString(buildPanelContentStyle(panel, 'rpx'), 'rpx'),
50
+ children: decorateElements(panel.children || []),
51
+ };
52
+ }
53
+ return el;
54
+ });
62
55
 
63
- const buildCards = (layouts: CardLayoutSchema[], data: LayoutData) => {
64
- const renders = buildRenderResult(layouts as CardLayoutInput, data, 'rpx');
65
- return renders.map((render, idx) => ({
56
+ const buildCards = (layouts: CardLayoutSchema[]) => {
57
+ return layouts.map((layout, idx) => ({
66
58
  id: pickCardId(layouts[idx], idx),
67
- cardStyle: render.cardStyle,
68
- backgroundImage: render.backgroundImage || '',
69
- backgroundStyle: render.backgroundStyle,
70
- nodes: mapRenderTree(render.renderTree),
59
+ cardStyle: styleObjectToString(buildCardStyle(layout, 'rpx'), 'rpx'),
60
+ backgroundImage: layout.backgroundImage || '',
61
+ backgroundStyle: styleObjectToString(buildBackgroundStyle(layout, 'rpx'), 'rpx'),
62
+ elements: decorateElements(layout.children || []),
71
63
  }));
72
64
  };
73
65
 
@@ -90,6 +82,7 @@ Component({
90
82
  },
91
83
  data: {
92
84
  cards: [] as RenderCard[],
85
+ rootData: {} as Record<string, any>,
93
86
  },
94
87
  observers: {
95
88
  layout() {
@@ -107,17 +100,17 @@ Component({
107
100
  methods: {
108
101
  rebuild() {
109
102
  const layoutInput = ensureArray(this.data.layout as CardLayoutInput);
110
- const dataInput = (this.data.data || {}) as LayoutData;
103
+ const rootData = (this.data.data || {}) as Record<string, any>;
111
104
 
112
105
  if (!layoutInput.length) {
113
- this.setData({ cards: [] });
106
+ this.setData({ cards: [], rootData });
114
107
  return;
115
108
  }
116
109
 
117
110
  const normalizedLayouts = normalizeLayout(layoutInput);
118
- const cards = buildCards(normalizedLayouts, dataInput);
111
+ const cards = buildCards(normalizedLayouts);
119
112
 
120
- this.setData({ cards });
113
+ this.setData({ cards, rootData });
121
114
  },
122
115
  },
123
116
  });
@@ -9,82 +9,34 @@
9
9
  src="{{item.backgroundImage}}"
10
10
  mode="aspectFill"
11
11
  />
12
- <block wx:for="{{item.nodes}}" wx:key="id">
13
- <template is="render-node" data="{{node:item}}" />
12
+ <block wx:for="{{item.elements}}" wx:key="id">
13
+ <template is="render-element" data="{{el:item, rootData: rootData}}" />
14
14
  </block>
15
15
  </view>
16
16
  </view>
17
17
  </block>
18
18
  </view>
19
19
 
20
- <template name="render-node">
21
- <block wx:if="{{node.type === 'image'}}">
22
- <view class="km-node" style="{{node.wrapperStyle}}">
23
- <image
24
- class="km-node__image"
25
- style="{{node.contentStyle}}"
26
- src="{{node.src}}"
27
- mode="{{node.mode || 'aspectFill'}}"
28
- />
29
- </view>
20
+ <template name="render-element">
21
+ <block wx:if="{{el.type === 'image'}}">
22
+ <image-element element="{{el}}" rootData="{{rootData}}" />
30
23
  </block>
31
- <block wx:elif="{{node.type === 'icon'}}">
32
- <view class="km-node km-node--icon" style="{{node.wrapperStyle}}">
33
- <view
34
- wx:if="{{node.name === 'dot' || node.name === 'round'}}"
35
- class="km-node__icon-dot"
36
- style="{{node.contentStyle}}"
37
- />
38
- <view
39
- wx:else
40
- class="km-node__icon icon"
41
- style="{{node.contentStyle}}"
42
- >{{node.text || ''}}</view>
43
- </view>
24
+ <block wx:elif="{{el.type === 'icon'}}">
25
+ <icon-element element="{{el}}" rootData="{{rootData}}" />
44
26
  </block>
45
- <block wx:elif="{{node.type === 'layout-panel'}}">
46
- <view class="km-node" style="{{node.wrapperStyle}}">
47
- <view class="km-node__panel" style="{{node.contentStyle}}">
48
- <block wx:for="{{node.children}}" wx:key="id">
49
- <template is="render-node" data="{{node:item}}" />
27
+ <block wx:elif="{{el.type === 'layout-panel'}}">
28
+ <view class="km-node" style="{{el.wrapperStyle}}">
29
+ <view class="km-node__panel" style="{{el.contentStyle}}">
30
+ <block wx:for="{{el.children}}" wx:key="id">
31
+ <template is="render-element" data="{{el:item, rootData: rootData}}" />
50
32
  </block>
51
33
  </view>
52
34
  </view>
53
35
  </block>
54
- <block wx:elif="{{node.type === 'custom'}}">
55
- <view class="km-node km-node--custom" style="{{node.wrapperStyle}}">
56
- <view class="km-node__custom" style="{{node.contentStyle}}">
57
- <slot name="{{node.id}}"></slot>
58
- </view>
59
- </view>
36
+ <block wx:elif="{{el.type === 'custom'}}">
37
+ <custom-element element="{{el}}" rootData="{{rootData}}" />
60
38
  </block>
61
39
  <block wx:else>
62
- <view class="km-node km-node--text" style="{{node.wrapperStyle}}">
63
- <view class="km-node__text" style="{{node.contentStyle}}">
64
- <block wx:if="{{node.icon && node.icon.name}}">
65
- <view class="km-node__text-content">
66
- <block wx:if="{{node.icon.align === 'right'}}">
67
- <text class="km-node__text-value">{{node.text || ''}}</text>
68
- <view style="{{node.icon.wrapperStyle}}">
69
- <text
70
- class="km-node__text-icon icon"
71
- style="font-size: {{node.icon.size || '16px'}}; color: {{node.icon.color || ''}}; margin-right: {{node.icon.gap || ''}};">{{node.icon.text || node.icon.name || ''}}</text>
72
- </view>
73
- </block>
74
- <block wx:else>
75
- <view style="{{node.icon.wrapperStyle}}">
76
- <text
77
- class="km-node__text-icon icon"
78
- style="font-size: {{node.icon.size || '16px'}}; color: {{node.icon.color || ''}}; margin-right: {{node.icon.gap || ''}};">{{node.icon.text || node.icon.name || ''}}</text>
79
- </view>
80
- <text class="km-node__text-value">{{node.text || ''}}</text>
81
- </block>
82
- </view>
83
- </block>
84
- <block wx:else>
85
- <text class="km-node__text-value">{{node.text || ''}}</text>
86
- </block>
87
- </view>
88
- </view>
40
+ <text-element element="{{el}}" rootData="{{rootData}}" />
89
41
  </block>
90
42
  </template>
@@ -1,9 +1,6 @@
1
-
2
-
3
1
  .km-card-layout {
4
2
  display: flex;
5
3
  flex-direction: column;
6
- gap: 16rpx;
7
4
  }
8
5
 
9
6
  .km-card-layout__item {
@@ -33,76 +30,14 @@
33
30
  color: inherit;
34
31
  }
35
32
 
36
- .km-node--icon {
37
- display: flex;
38
- align-items: center;
39
- justify-content: center;
40
- }
41
-
42
- .km-node__image {
43
- width: 100%;
44
- height: 100%;
45
- display: block;
46
- }
47
-
48
- .km-node__icon {
49
- display: inline-flex;
50
- align-items: center;
51
- justify-content: center;
52
- width: 100%;
53
- height: 100%;
54
- font-family: 'km-icon', 'PingFang SC', 'Microsoft Yahei', sans-serif;
55
- font-style: normal;
56
- font-weight: normal;
57
- }
58
-
59
- .km-node__icon-dot {
60
- width: 100%;
61
- height: 100%;
62
- border-radius: 50%;
63
- background-color: #999;
64
- }
65
-
66
33
  .km-node__panel {
67
34
  width: 100%;
68
35
  height: 100%;
69
36
  box-sizing: border-box;
70
37
  }
71
38
 
72
- .km-node__custom {
73
- width: 100%;
74
- height: 100%;
75
- box-sizing: border-box;
76
- }
77
39
 
78
- .km-node__text {
79
- width: 100%;
80
- height: 100%;
81
- display: block;
82
- box-sizing: border-box;
83
- text-align: inherit;
84
- }
85
-
86
- .km-node__text-content {
87
- display: inline-block;
88
- vertical-align: middle;
89
- height: 100%;
90
- }
91
-
92
- .km-node__text-value {
93
- display: inline-block;
94
- white-space: pre-wrap;
95
- word-break: break-word;
96
- vertical-align: middle;
97
- }
98
- .km-node--text{
99
- /* 溢出隐藏 */
100
- }
101
- .km-node--text text {
102
- display: inline;
103
- }
104
40
 
105
- /* ICON */
106
41
 
107
42
 
108
43
  @font-face {
@@ -3,14 +3,21 @@ export type {
3
3
  CardElementType,
4
4
  CardLayoutInput,
5
5
  CardLayoutSchema,
6
- RenderNode,
7
- RenderResult
8
6
  } from '../vendor/km-card-layout-core/index'
9
7
 
10
8
  export {
11
9
  addUnit,
12
- buildRenderNodes,
13
- buildRenderResult,
10
+ buildWrapperStyle,
11
+ buildCardStyle,
12
+ buildBackgroundStyle,
13
+ buildBaseContentStyle,
14
+ buildPanelContentStyle,
15
+ buildTextContentStyle,
16
+ buildImageContentStyle,
17
+ buildTextIconMeta,
18
+ getTextValue,
19
+ getImageSrc,
20
+ getIconName,
14
21
  normalizeLayout,
15
22
  resolveBindingValue,
16
23
  styleObjectToString
@@ -54,6 +54,9 @@ export function applyItemCollectBindings(
54
54
  else delete base.defaultValue;
55
55
  if (key !== undefined) base.key = key;
56
56
  else delete base.key;
57
+ if (el.type === 'text' && meta?.extra?.icon) {
58
+ base.icon = { ...(base.icon || {}), name: meta.extra.icon };
59
+ }
57
60
 
58
61
  if (el.type === 'layout-panel') {
59
62
  return {
@@ -29,8 +29,7 @@ const readByPath = (data: any, path: string): any => {
29
29
 
30
30
  export const resolveBindingValue = (
31
31
  binding: string | undefined,
32
- rootData: Record<string, any>,
33
- context?: Record<string, any>
32
+ rootData: Record<string, any>
34
33
  ): any => {
35
34
  if (!binding) return undefined;
36
35
  const value = readByPath(rootData, binding);
@@ -5,11 +5,30 @@
5
5
  * - 职责:将布局 Schema 与业务数据合成可渲染树,外层只需将节点映射到各端组件。
6
6
  */
7
7
 
8
+
9
+
10
+
11
+
8
12
  export * from './interface/index';
9
- export * from './helpers';
10
- export * from './layout';
11
- export * from './data';
12
- export * from './bindings';
13
+ export { addUnit, styleObjectToString, toNumber, isObject } from './helpers';
14
+ export {
15
+ normalizeLayout,
16
+ sanitizeLayout,
17
+ sanitizeElement,
18
+ roundToInt,
19
+ getAbsLayout,
20
+ collectBindings,
21
+ normalizeId,
22
+ parseLayout,
23
+ areChildrenEqual,
24
+ } from './layout';
25
+ export { resolveBindingValue } from './data';
26
+ export {
27
+ stripLayoutBindings,
28
+ applyItemCollectBindings,
29
+ getTemplateItems,
30
+ getTemplateBackgrounds,
31
+ } from './bindings';
13
32
  export {
14
33
  backgroundChange,
15
34
  DEFAULT_DECOR_COLOR,
@@ -18,4 +37,17 @@ export {
18
37
  applyBackground,
19
38
  updateElementsStyle,
20
39
  } from './ops/changeBackground';
21
- export * from './render/builder';
40
+ export { buildRenderData } from './render/tool';
41
+ export {
42
+ buildWrapperStyle,
43
+ buildCardStyle,
44
+ buildBackgroundStyle,
45
+ buildBaseContentStyle,
46
+ buildPanelContentStyle,
47
+ buildTextContentStyle,
48
+ buildImageContentStyle,
49
+ getTextValue,
50
+ getImageSrc,
51
+ getIconName,
52
+ buildTextIconMeta,
53
+ } from './render/helpers';
@@ -21,6 +21,7 @@ export interface TemplateItem {
21
21
  bind: string;
22
22
  key?: string;
23
23
  icon?: string;
24
+ extra?: { icon?: string };
24
25
  default?: string;
25
26
  type: 'text' | 'image';
26
27
  cate: number;
@@ -1,4 +1,3 @@
1
1
  export * from './elements';
2
2
  export * from './layout';
3
- export * from './render';
4
- export * from './data/payload';
3
+ export * from './data/payload';
@@ -102,10 +102,9 @@ export const applySpecialStyle = (
102
102
  const specialStyle = resolveSpecialStyle(el, background);
103
103
  const baseStyle = { ...(el.style || {}) };
104
104
  const isCustom = el.type === 'custom';
105
- const hasExplicit =
106
- isCustom
107
- ? Boolean(baseStyle.backgroundColor || baseStyle.background)
108
- : baseStyle.color !== undefined && baseStyle.color !== null;
105
+ const hasExplicit = isCustom
106
+ ? Boolean(baseStyle.backgroundColor || baseStyle.background)
107
+ : baseStyle.color !== undefined && baseStyle.color !== null;
109
108
 
110
109
  const overrideExisting = options.overrideExisting === true;
111
110
  const hasSpecial = Object.keys(specialStyle).length > 0;
@@ -167,3 +166,14 @@ export const updateElementsStyle = (
167
166
  ),
168
167
  };
169
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
+ };
@@ -0,0 +1,159 @@
1
+ import { addUnit } from '../helpers';
2
+ import { getAbsLayout } from '../layout';
3
+ import { resolveBindingValue } from '../data';
4
+ import type {
5
+ CardElement,
6
+ CardLayoutSchema,
7
+ IconElement,
8
+ ImageElement,
9
+ LayoutPanelElement,
10
+ TextElement,
11
+ } from '../interface';
12
+
13
+ export const buildWrapperStyle = (el: CardElement, unit: 'px' | 'rpx' = 'px') => {
14
+ const abs = getAbsLayout(el);
15
+ if (!abs) return {};
16
+ return {
17
+ position: 'absolute',
18
+ left: addUnit(abs.x, unit),
19
+ top: addUnit(abs.y, unit),
20
+ width: addUnit(abs.width, unit),
21
+ height: addUnit(abs.height, unit),
22
+ zIndex: abs.zIndex,
23
+ boxSizing: 'border-box',
24
+ };
25
+ };
26
+
27
+ export const buildCardStyle = (layout: CardLayoutSchema, unit: 'px' | 'rpx' = 'px') => ({
28
+ width: addUnit(layout.width, unit),
29
+ height: addUnit(layout.height, unit),
30
+ color: layout.fontColor,
31
+ borderRadius:
32
+ layout.borderRadius !== undefined
33
+ ? addUnit(layout.borderRadius, unit)
34
+ : undefined,
35
+ padding:
36
+ layout.padding !== undefined ? addUnit(layout.padding, unit) : undefined,
37
+ position: 'relative',
38
+ overflow: 'hidden',
39
+ boxSizing: 'border-box',
40
+ backgroundColor: 'transparent',
41
+ });
42
+
43
+ export const buildBackgroundStyle = (layout: CardLayoutSchema, unit: 'px' | 'rpx' = 'px') => ({
44
+ zIndex: layout.backgroundZIndex,
45
+ borderRadius:
46
+ layout.borderRadius !== undefined
47
+ ? addUnit(layout.borderRadius, unit)
48
+ : undefined,
49
+ width: '100%',
50
+ height: '100%',
51
+ position: 'absolute',
52
+ left: 0,
53
+ top: 0,
54
+ });
55
+
56
+ export const buildBaseContentStyle = (el: CardElement) => ({
57
+ ...(el.style || {}),
58
+ boxSizing: 'border-box',
59
+ });
60
+
61
+ export const buildPanelContentStyle = (el: LayoutPanelElement, unit: 'px' | 'rpx' = 'px') => ({
62
+ position: 'relative',
63
+ width: '100%',
64
+ height: '100%',
65
+ display: 'block',
66
+ boxSizing: 'border-box',
67
+ ...(el.style || {}),
68
+ });
69
+
70
+ export const buildTextContentStyle = (el: TextElement, unit: 'px' | 'rpx' = 'px') => {
71
+ const textAlign =
72
+ (el.style?.textAlign as string | undefined) || el.align || undefined;
73
+ const style: Record<string, any> = {
74
+ ...(el.style || {}),
75
+ fontSize: addUnit(el.style?.fontSize, unit),
76
+ whiteSpace: 'pre-wrap',
77
+ wordBreak: 'break-word',
78
+ lineHeight:
79
+ el.style?.lineHeight !== undefined && el.style?.lineHeight !== null
80
+ ? addUnit(el.style.lineHeight as any, unit)
81
+ : '1',
82
+ };
83
+ if (textAlign) style.textAlign = textAlign;
84
+ return style;
85
+ };
86
+
87
+ export const buildImageContentStyle = (el: ImageElement) => {
88
+ const style: Record<string, any> = { ...(el.style || {}) };
89
+ const borderWidth = Number(style.borderWidth);
90
+ if (Number.isFinite(borderWidth) && borderWidth > 0) {
91
+ if (!style.borderStyle) style.borderStyle = 'solid';
92
+ if (!style.borderColor) style.borderColor = '#000000';
93
+ }
94
+ return style;
95
+ };
96
+
97
+ export const getTextValue = (
98
+ el: TextElement,
99
+ data?: Record<string, any>
100
+ ) => {
101
+ const bound = el.binding && data ? resolveBindingValue(el.binding, data) : undefined;
102
+ const val =
103
+ bound !== undefined && bound !== null
104
+ ? bound
105
+ : el.defaultValue !== undefined && el.defaultValue !== null
106
+ ? el.defaultValue
107
+ : '';
108
+ return `${val ?? ''}`;
109
+ };
110
+
111
+ export const getImageSrc = (
112
+ el: ImageElement,
113
+ data?: Record<string, any>
114
+ ) => {
115
+ const bound = el.binding && data ? resolveBindingValue(el.binding, data) : undefined;
116
+ return (bound as any) || el.defaultUrl || el.defaultValue || '';
117
+ };
118
+
119
+ export const getIconName = (el: IconElement) =>
120
+ (el.name || el.defaultValue || '') as string;
121
+
122
+ export const buildTextIconMeta = (el: TextElement, unit: 'px' | 'rpx' = 'px') => {
123
+ const icon = el.icon;
124
+ const enabled = icon?.enable === true;
125
+ if (!icon || !enabled) return null;
126
+
127
+ const style = icon.style || 'fill';
128
+ const baseName = icon.name || el.key || el.binding || el.id;
129
+ let name: string | undefined;
130
+ if (style === 'dot') name = 'round';
131
+ else if (style === 'line') name = baseName ? `${baseName}-line` : undefined;
132
+ else name = baseName || undefined;
133
+ if (!name) return null;
134
+
135
+ const size =
136
+ icon.size !== undefined && icon.size !== null
137
+ ? icon.size
138
+ : (el.style?.fontSize as any);
139
+ const gap = icon.gap !== undefined && icon.gap !== null ? icon.gap : 4;
140
+ const color =
141
+ icon.color ??
142
+ ((typeof el.style?.color === 'string' ? el.style.color : undefined) as
143
+ | string
144
+ | undefined);
145
+
146
+ return {
147
+ name: `${name}`,
148
+ size: addUnit(size as any, unit),
149
+ gap: addUnit(gap as any, unit),
150
+ color,
151
+ align: icon.align || 'left',
152
+ wrapperStyle: {
153
+ height:
154
+ el.style?.lineHeight !== undefined && el.style?.lineHeight !== null
155
+ ? addUnit(el.style.lineHeight, unit)
156
+ : el.style?.fontSize,
157
+ },
158
+ };
159
+ };
@@ -0,0 +1,21 @@
1
+ import { CardLayoutSchema, TemplateItem } from '../interface';
2
+ import { backgroundChange, setElementVisible } from '../ops/changeBackground';
3
+ import { Config } from '../types';
4
+ import { applyItemCollectBindings } from '../utils';
5
+
6
+ export function buildRenderData(
7
+ layout: CardLayoutSchema[],
8
+ items: TemplateItem[],
9
+ config: Config
10
+ ): CardLayoutSchema[] {
11
+ // 绑定数据
12
+ let renderLayout = applyItemCollectBindings(layout, items);
13
+ // 设置显示逻辑
14
+ renderLayout = setElementVisible(renderLayout, 'image', config.showAvatar);
15
+ renderLayout = setElementVisible(renderLayout, 'logo', config.showLogo);
16
+ // 设置背景
17
+ renderLayout = renderLayout.map((la, index) =>
18
+ config.currentBg[index] ? backgroundChange(config.currentBg[index], la) : la
19
+ );
20
+ return renderLayout;
21
+ }