km-card-layout-component-miniprogram 0.1.10 → 0.1.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 (24) hide show
  1. package/miniprogram_dist/components/card-layout/index.js +22 -1
  2. package/miniprogram_dist/vendor/km-card-layout-core/bindings.js +1 -11
  3. package/miniprogram_dist/vendor/km-card-layout-core/index.js +9 -18
  4. package/miniprogram_dist/vendor/km-card-layout-core/layout.js +1 -17
  5. package/miniprogram_dist/vendor/km-card-layout-core/ops/changeBackground.js +46 -97
  6. package/miniprogram_dist/vendor/km-card-layout-core/render/helpers.js +22 -15
  7. package/miniprogram_dist/vendor/km-card-layout-core/render/init.js +82 -0
  8. package/package.json +1 -1
  9. package/script/sync-core.js +0 -1
  10. package/src/components/card-layout/index.ts +30 -4
  11. package/src/vendor/km-card-layout-core/bindings.ts +1 -17
  12. package/src/vendor/km-card-layout-core/index.ts +7 -26
  13. package/src/vendor/km-card-layout-core/interface/data/payload.ts +3 -3
  14. package/src/vendor/km-card-layout-core/interface/elements.ts +1 -0
  15. package/src/vendor/km-card-layout-core/interface/layout.ts +0 -1
  16. package/src/vendor/km-card-layout-core/layout.ts +0 -18
  17. package/src/vendor/km-card-layout-core/ops/changeBackground.ts +47 -130
  18. package/src/vendor/km-card-layout-core/render/helpers.ts +55 -32
  19. package/src/vendor/km-card-layout-core/render/init.ts +107 -0
  20. package/src/vendor/km-card-layout-core/types.d.ts +32 -95
  21. package/miniprogram_dist/vendor/km-card-layout-core/render/tool.js +0 -16
  22. package/miniprogram_dist/vendor/km-card-layout-core/utils.js +0 -25
  23. package/src/vendor/km-card-layout-core/render/tool.ts +0 -21
  24. package/src/vendor/km-card-layout-core/utils.ts +0 -13
@@ -39,6 +39,7 @@ 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 {
@@ -10,7 +10,6 @@ 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;
@@ -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
- };
@@ -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 applySpecialColor = (el: CardElement): CardElement => {
31
- const extras = bg.fontColorExtra || [];
32
- if (!extras.length) return el;
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
- if (el.type === 'custom') {
47
- return { ...el, style: { ...baseStyle, backgroundColor: matched.color } };
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
- return { ...el, style: { ...baseStyle, color: matched.color } };
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: traverse(layout.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
- };
@@ -10,7 +10,10 @@ import type {
10
10
  TextElement,
11
11
  } from '../interface';
12
12
 
13
- export const buildWrapperStyle = (el: CardElement, unit: 'px' | 'rpx' = 'px') => {
13
+ export const buildWrapperStyle = (
14
+ el: CardElement,
15
+ unit: 'px' | 'rpx' = 'px'
16
+ ) => {
14
17
  const abs = getAbsLayout(el);
15
18
  if (!abs) return {};
16
19
  return {
@@ -24,14 +27,13 @@ export const buildWrapperStyle = (el: CardElement, unit: 'px' | 'rpx' = 'px') =>
24
27
  };
25
28
  };
26
29
 
27
- export const buildCardStyle = (layout: CardLayoutSchema, unit: 'px' | 'rpx' = 'px') => ({
30
+ export const buildCardStyle = (
31
+ layout: CardLayoutSchema,
32
+ unit: 'px' | 'rpx' = 'px'
33
+ ) => ({
28
34
  width: addUnit(layout.width, unit),
29
35
  height: addUnit(layout.height, unit),
30
36
  color: layout.fontColor,
31
- borderRadius:
32
- layout.borderRadius !== undefined
33
- ? addUnit(layout.borderRadius, unit)
34
- : undefined,
35
37
  padding:
36
38
  layout.padding !== undefined ? addUnit(layout.padding, unit) : undefined,
37
39
  position: 'relative',
@@ -40,12 +42,11 @@ export const buildCardStyle = (layout: CardLayoutSchema, unit: 'px' | 'rpx' = 'p
40
42
  backgroundColor: 'transparent',
41
43
  });
42
44
 
43
- export const buildBackgroundStyle = (layout: CardLayoutSchema, unit: 'px' | 'rpx' = 'px') => ({
45
+ export const buildBackgroundStyle = (
46
+ layout: CardLayoutSchema,
47
+ unit: 'px' | 'rpx' = 'px'
48
+ ) => ({
44
49
  zIndex: layout.backgroundZIndex,
45
- borderRadius:
46
- layout.borderRadius !== undefined
47
- ? addUnit(layout.borderRadius, unit)
48
- : undefined,
49
50
  width: '100%',
50
51
  height: '100%',
51
52
  position: 'absolute',
@@ -58,7 +59,10 @@ export const buildBaseContentStyle = (el: CardElement) => ({
58
59
  boxSizing: 'border-box',
59
60
  });
60
61
 
61
- export const buildPanelContentStyle = (el: LayoutPanelElement, unit: 'px' | 'rpx' = 'px') => ({
62
+ export const buildPanelContentStyle = (
63
+ el: LayoutPanelElement,
64
+ unit: 'px' | 'rpx' = 'px'
65
+ ) => ({
62
66
  position: 'relative',
63
67
  width: '100%',
64
68
  height: '100%',
@@ -67,7 +71,10 @@ export const buildPanelContentStyle = (el: LayoutPanelElement, unit: 'px' | 'rpx
67
71
  ...(el.style || {}),
68
72
  });
69
73
 
70
- export const buildTextContentStyle = (el: TextElement, unit: 'px' | 'rpx' = 'px') => {
74
+ export const buildTextContentStyle = (
75
+ el: TextElement,
76
+ unit: 'px' | 'rpx' = 'px'
77
+ ) => {
71
78
  const textAlign =
72
79
  (el.style?.textAlign as string | undefined) || el.align || undefined;
73
80
  const style: Record<string, any> = {
@@ -84,42 +91,58 @@ export const buildTextContentStyle = (el: TextElement, unit: 'px' | 'rpx' = 'px'
84
91
  return style;
85
92
  };
86
93
 
87
- export const buildImageContentStyle = (el: ImageElement) => {
94
+ export const buildTextValueStyle = (
95
+ el: TextElement,
96
+ unit: 'px' | 'rpx' = 'px'
97
+ ) => {
98
+ const style: Record<string, any> = {
99
+ letterSpacing:
100
+ el.style?.letterSpacing !== undefined && el.style?.letterSpacing !== null
101
+ ? addUnit(el.style.letterSpacing as any, unit)
102
+ : '0',
103
+ };
104
+ return style;
105
+ };
106
+
107
+ export const buildImageContentStyle = (el: ImageElement, unit: 'px' | 'rpx' = 'px') => {
88
108
  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
- }
109
+ style.borderWidth =
110
+ el.style?.borderWidth !== undefined && el.style?.borderWidth !== null
111
+ ? addUnit(el.style.borderWidth as any, unit)
112
+ : '0';
113
+ style.borderRadius =
114
+ el.style?.borderRadius !== undefined && el.style?.borderRadius !== null
115
+ ? addUnit(el.style.borderRadius as any, unit)
116
+ : '0';
117
+ console.log(style);
94
118
  return style;
95
119
  };
96
120
 
97
- export const getTextValue = (
98
- el: TextElement,
99
- data?: Record<string, any>
100
- ) => {
101
- const bound = el.binding && data ? resolveBindingValue(el.binding, data) : undefined;
121
+ export const getTextValue = (el: TextElement, data?: Record<string, any>) => {
122
+ const bound =
123
+ el.binding && data ? resolveBindingValue(el.binding, data) : undefined;
102
124
  const val =
103
125
  bound !== undefined && bound !== null
104
126
  ? bound
105
127
  : el.defaultValue !== undefined && el.defaultValue !== null
106
- ? el.defaultValue
107
- : '';
128
+ ? el.defaultValue
129
+ : '';
108
130
  return `${val ?? ''}`;
109
131
  };
110
132
 
111
- export const getImageSrc = (
112
- el: ImageElement,
113
- data?: Record<string, any>
114
- ) => {
115
- const bound = el.binding && data ? resolveBindingValue(el.binding, data) : undefined;
133
+ export const getImageSrc = (el: ImageElement, data?: Record<string, any>) => {
134
+ const bound =
135
+ el.binding && data ? resolveBindingValue(el.binding, data) : undefined;
116
136
  return (bound as any) || el.defaultUrl || el.defaultValue || '';
117
137
  };
118
138
 
119
139
  export const getIconName = (el: IconElement) =>
120
140
  (el.name || el.defaultValue || '') as string;
121
141
 
122
- export const buildTextIconMeta = (el: TextElement, unit: 'px' | 'rpx' = 'px') => {
142
+ export const buildTextIconMeta = (
143
+ el: TextElement,
144
+ unit: 'px' | 'rpx' = 'px'
145
+ ) => {
123
146
  const icon = el.icon;
124
147
  const enabled = icon?.enable === true;
125
148
  if (!icon || !enabled) return null;
@@ -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
+ }