@dckj-npm/dc-material 0.1.376 → 0.1.377

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 (42) hide show
  1. package/build/docs/colorful-button.html +3 -3
  2. package/build/docs/colorful-input.html +3 -3
  3. package/build/docs/index.html +3 -3
  4. package/build/docs/teletext-list.html +3 -3
  5. package/build/docs/umi.6f6bf535.js +1 -0
  6. package/build/docs/{umi.6743fcd4.css → umi.9770df27.css} +1 -1
  7. package/build/docs/~demos/colorful-button-demo.html +3 -3
  8. package/build/docs/~demos/colorful-input-demo.html +3 -3
  9. package/build/docs/~demos/teletext-list-demo-1.html +3 -3
  10. package/build/docs/~demos/teletext-list-demo.html +3 -3
  11. package/build/lowcode/assets-daily.json +13 -13
  12. package/build/lowcode/assets-dev.json +2 -2
  13. package/build/lowcode/assets-prod.json +13 -13
  14. package/build/lowcode/meta.design.js +1 -1
  15. package/build/lowcode/meta.js +1 -1
  16. package/build/lowcode/render/default/view.css +1 -1
  17. package/build/lowcode/render/default/view.js +1 -1
  18. package/build/lowcode/view.css +1 -1
  19. package/build/lowcode/view.js +1 -1
  20. package/dist/BizComps.css +1 -1
  21. package/dist/BizComps.js +2 -2
  22. package/dist/BizComps.js.map +1 -1
  23. package/es/components/teletext-list/teletext-list-item.d.ts +14 -77
  24. package/es/components/teletext-list/teletext-list-item.js +153 -165
  25. package/es/components/teletext-list/teletext-list-item.scss +53 -4
  26. package/es/components/teletext-list/teletext-list.d.ts +60 -4
  27. package/es/components/teletext-list/teletext-list.js +55 -37
  28. package/lib/components/teletext-list/teletext-list-item.d.ts +14 -77
  29. package/lib/components/teletext-list/teletext-list-item.js +153 -164
  30. package/lib/components/teletext-list/teletext-list-item.scss +53 -4
  31. package/lib/components/teletext-list/teletext-list.d.ts +60 -4
  32. package/lib/components/teletext-list/teletext-list.js +55 -37
  33. package/lowcode/teletext-list/meta.ts +457 -703
  34. package/lowcode/teletext-list/meta.ts.bak +821 -0
  35. package/lowcode_es/meta.js +1 -1
  36. package/lowcode_es/teletext-list/meta.js +689 -598
  37. package/lowcode_es/teletext-list/meta.ts.bak +821 -0
  38. package/lowcode_lib/meta.js +1 -1
  39. package/lowcode_lib/teletext-list/meta.js +689 -598
  40. package/lowcode_lib/teletext-list/meta.ts.bak +821 -0
  41. package/package.json +3 -3
  42. package/build/docs/umi.d20b1d99.js +0 -1
@@ -38,427 +38,484 @@ const TeletextListMeta: IPublicTypeComponentMetadata = {
38
38
  },
39
39
  configure: {
40
40
  props: [
41
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
42
+ // 分组一:数据与内容
43
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
41
44
  {
42
- title: {
43
- label: {
44
- type: 'i18n',
45
- 'en-US': 'type',
46
- 'zh-CN': '类型',
45
+ type: 'group',
46
+ title: '数据与内容',
47
+ display: 'accordion',
48
+ items: [
49
+ {
50
+ title: '标题',
51
+ name: 'title',
52
+ description: '列表头部标题文本',
53
+ setter: { componentName: 'StringSetter', isRequired: false, initialValue: '' },
47
54
  },
48
- },
49
- name: 'type',
50
- description: '类型',
51
- setter: {
52
- componentName: 'RadioGroupSetter',
53
- props: {
54
- dataSource: [
55
- {
56
- label: '图文',
57
- value: 'textAndImg',
55
+ {
56
+ title: '更多文字',
57
+ name: 'moreText',
58
+ description: '更多按钮文字,为空时不显示',
59
+ setter: { componentName: 'StringSetter', isRequired: false, initialValue: '' },
60
+ },
61
+ {
62
+ title: '文本槽位数',
63
+ name: 'textLines',
64
+ description: '每项渲染几个文本字段:2=标题+说明,3=加text3,4=加text3+text4。这是"显示几格",不是"每格显示几行"——行数截断请到"标题/说明文字样式"分组修改"最大行数"。',
65
+ setter: {
66
+ componentName: 'NumberSetter',
67
+ isRequired: false,
68
+ initialValue: 2,
69
+ defaultValue: 2,
70
+ props: { min: 2, max: 4 },
71
+ },
72
+ extraProps: {
73
+ setValue(target, value) {
74
+ target.getProps().setPropValue('textLines', value)
75
+ const dataListBindProp = (target?.parent as any)?.items?.find(
76
+ (item: any) => item.name === 'dataListBind',
77
+ )
78
+ if (dataListBindProp?.setter) {
79
+ const baseChildren = [
80
+ { label: '图片链接', value: 'image' },
81
+ { label: '类型', value: 'itemType' },
82
+ { label: '标题', value: 'title' },
83
+ { label: '说明', value: 'description' },
84
+ ]
85
+ const textChildren = value > 2
86
+ ? Array.from({ length: value - 2 }).map((_, i) => ({
87
+ label: `文本${i + 3}`,
88
+ value: `text${i + 3}`,
89
+ }))
90
+ : []
91
+ dataListBindProp.setter.props.attributes[0].children = [
92
+ ...baseChildren,
93
+ ...textChildren,
94
+ ]
95
+ }
58
96
  },
59
- {
60
- label: '仅有图片',
61
- value: 'imgOnly',
97
+ },
98
+ },
99
+ {
100
+ title: '数据源绑定',
101
+ name: 'dataListBind',
102
+ setter: {
103
+ componentName: 'SetterFormVariable',
104
+ props: {
105
+ attributes: [
106
+ {
107
+ label: '图文数据',
108
+ value: 'dataList',
109
+ children: [
110
+ { label: '图片链接', value: 'image' },
111
+ { label: '行类型(值为"开关"时该行显示开关控件)', value: 'itemType' },
112
+ { label: '标题', value: 'title' },
113
+ { label: '说明', value: 'description' },
114
+ ],
115
+ },
116
+ ],
62
117
  },
63
- {
64
- label: '仅有文字',
65
- value: 'textOnly',
118
+ },
119
+ extraProps: {},
120
+ },
121
+ {
122
+ title: { label: { type: 'i18n', 'en-US': 'dataList', 'zh-CN': '静态数据' }, tip: 'dataList | 静态数据' },
123
+ name: 'dataList',
124
+ description: '列表静态数据,绑定数据源后此项被覆盖',
125
+ setter: {
126
+ componentName: 'ArraySetter',
127
+ props: {
128
+ itemSetter: {
129
+ componentName: 'ObjectSetter',
130
+ props: {
131
+ config: {
132
+ items: [
133
+ {
134
+ title: { label: { type: 'i18n', 'en-US': 'title', 'zh-CN': '标题' } },
135
+ name: 'title',
136
+ setter: { componentName: 'StringSetter', isRequired: false, initialValue: '' },
137
+ },
138
+ {
139
+ title: { label: { type: 'i18n', 'en-US': 'image', 'zh-CN': '图片地址' } },
140
+ name: 'image',
141
+ setter: { componentName: 'CustomImageSetter', isRequired: false, initialValue: '' },
142
+ },
143
+ {
144
+ title: { label: { type: 'i18n', 'en-US': 'description', 'zh-CN': '描述' } },
145
+ name: 'description',
146
+ setter: { componentName: 'StringSetter', isRequired: false, initialValue: '' },
147
+ },
148
+ {
149
+ title: { label: { type: 'i18n', 'en-US': 'text3', 'zh-CN': '文本3' } },
150
+ name: 'text3',
151
+ description: '文本槽位数 ≥ 3 时显示',
152
+ setter: { componentName: 'StringSetter', isRequired: false, initialValue: '' },
153
+ },
154
+ {
155
+ title: { label: { type: 'i18n', 'en-US': 'text4', 'zh-CN': '文本4' } },
156
+ name: 'text4',
157
+ description: '文本槽位数 = 4 时显示',
158
+ setter: { componentName: 'StringSetter', isRequired: false, initialValue: '' },
159
+ },
160
+ {
161
+ title: { label: { type: 'i18n', 'en-US': 'itemType', 'zh-CN': '行类型' } },
162
+ name: 'itemType',
163
+ description: '值为"开关"时该行显示开关控件,留空为默认文字行',
164
+ setter: {
165
+ componentName: 'SelectSetter',
166
+ props: {
167
+ options: [
168
+ { label: '默认(文字行)', value: '' },
169
+ { label: '开关', value: '开关' },
170
+ ],
171
+ },
172
+ initialValue: '',
173
+ },
174
+ },
175
+ ],
176
+ extraSetter: { componentName: 'MixedSetter', isRequired: false, props: {} },
177
+ },
178
+ },
179
+ },
66
180
  },
67
- ],
68
- options: [
69
- {
70
- label: '图文',
71
- value: 'textAndImg',
181
+ initialValue: (target) => {
182
+ const existing = target?.node?.schema?.props?.dataList
183
+ ?? target?.getProps?.()?.getPropValue?.('dataList')
184
+ if (existing !== undefined) return existing
185
+ return DEFAULT_DATA_LIST
72
186
  },
73
- {
74
- label: '仅有图片',
75
- value: 'imgOnly',
187
+ },
188
+ extraProps: {
189
+ ignoreDefaultValue: () => true,
190
+ getValue: (target: any, currentValue: any) => {
191
+ if (currentValue !== undefined) return currentValue
192
+ const fromSchema = target?.node?.schema?.props?.dataList
193
+ if (fromSchema !== undefined) return fromSchema
194
+ return undefined
76
195
  },
77
- {
78
- label: '仅有文字',
79
- value: 'textOnly',
196
+ },
197
+ },
198
+ {
199
+ title: '类型',
200
+ name: 'type',
201
+ description: '列表类型',
202
+ setter: {
203
+ componentName: 'RadioGroupSetter',
204
+ props: {
205
+ options: [
206
+ { label: '图文', value: 'textAndImg' },
207
+ { label: '仅图片', value: 'imgOnly' },
208
+ { label: '仅文字', value: 'textOnly' },
209
+ ],
80
210
  },
81
- ],
211
+ initialValue: 'textAndImg',
212
+ },
82
213
  },
83
- initialValue: 'textAndImg',
84
- },
214
+ {
215
+ title: '是否购物车列表',
216
+ name: 'isShoppingCart',
217
+ setter: { componentName: 'BoolSetter', isRequired: true, initialValue: false },
218
+ },
219
+ {
220
+ title: '是否愿望单列表',
221
+ name: 'isWishList',
222
+ setter: { componentName: 'BoolSetter', isRequired: true, initialValue: false },
223
+ },
224
+ {
225
+ title: '是否用户菜单列表',
226
+ name: 'isUserMenu',
227
+ setter: { componentName: 'BoolSetter', isRequired: true, initialValue: false },
228
+ },
229
+ ],
85
230
  },
231
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
232
+ // 分组二:列表布局
233
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
86
234
  {
87
- title: {
88
- label: {
89
- type: 'i18n',
90
- 'en-US': 'imagePlacement',
91
- 'zh-CN': '图片位置',
92
- },
93
- },
94
- name: 'imagePlacement',
95
- description: '图片位置',
96
- setter: {
97
- componentName: 'RadioGroupSetter',
98
- props: {
99
- dataSource: [
100
- {
101
- label: '左',
102
- value: 'left',
103
- },
104
- {
105
- label: '右',
106
- value: 'right',
107
- },
108
- {
109
- label: '上',
110
- value: 'top',
111
- },
112
- {
113
- label: '下',
114
- value: 'bottom',
115
- },
116
- {
117
- label: '无',
118
- value: 'none',
119
- },
120
- ],
121
- options: [
122
- {
123
- label: '左',
124
- value: 'left',
125
- },
126
- {
127
- label: '右',
128
- value: 'right',
129
- },
130
- {
131
- label: '上',
132
- value: 'top',
235
+ type: 'group',
236
+ title: '列表布局',
237
+ display: 'accordion',
238
+ items: [
239
+ {
240
+ title: '子项分布',
241
+ name: 'itemRowAlign',
242
+ description: '列方向或横向一行滚动',
243
+ setter: {
244
+ componentName: 'RadioGroupSetter',
245
+ props: {
246
+ options: [
247
+ { label: '纵向列表', value: 'column' },
248
+ { label: '横向滚动', value: 'row' },
249
+ ],
133
250
  },
134
- {
135
- label: '下',
136
- value: 'bottom',
251
+ initialValue: 'column',
252
+ },
253
+ },
254
+ {
255
+ title: '子项列数',
256
+ name: 'itemColumns',
257
+ description: '纵向模式时的列数(1-4)',
258
+ setter: {
259
+ componentName: 'NumberSetter',
260
+ isRequired: false,
261
+ initialValue: (target) => {
262
+ const p = target.getProps().getPropValue('imagePlacement')
263
+ return p === 'top' || p === 'bottom' ? 2 : 1
137
264
  },
138
- {
139
- label: '',
140
- value: 'none',
265
+ defaultValue: (target) => {
266
+ const p = target.getProps().getPropValue('imagePlacement')
267
+ return p === 'top' || p === 'bottom' ? 2 : 1
141
268
  },
142
- ],
269
+ props: { min: 1, max: 4 },
270
+ },
143
271
  },
144
- initialValue: 'left',
145
- },
146
- extraProps: {
147
- // 引擎已自动 setPropValue('imagePlacement', value),无需再做任何额外写入
148
- // 之前的快照-还原逻辑反而触发多余的 MobX 响应链,导致 dataList 被覆盖
149
- },
150
- },
151
- {
152
- title: '图片宽度',
153
- name: 'imgWidth',
154
- description: '图片宽度',
155
- setter: {
156
- componentName: 'NumberSetter',
157
- isRequired: false,
158
- initialValue: 100,
159
- },
160
- extraProps: {
161
- /**
162
- * ignoreDefaultValue: 防止布局面板修改 Image 子节点 style 后,
163
- * 引擎 remount SettingFieldView 时 initDefaultValue 把 imgWidth 重置为 100。
164
- * 与 dataList 同理:只要 prop 有值就永远不应被 initialValue 覆盖。
165
- */
166
- ignoreDefaultValue: () => true,
167
- getValue: (target: any, value: any) => {
168
- // 优先使用引擎传入的当前 prop 值
169
- const parsed = parsePxNumber(value)
170
- if (parsed !== undefined) return parsed
171
- // 二级兜底:从 schema 快照读取(防止引擎传入 undefined 时丢失已保存的值)
172
- const fromSchema = parsePxNumber(target?.node?.schema?.props?.imgWidth)
173
- if (fromSchema !== undefined) return fromSchema
174
- return 100
272
+ {
273
+ title: '子项间距',
274
+ name: 'itemGap',
275
+ description: '子项之间的间距(px)',
276
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 10, defaultValue: 10, props: { min: 0 } },
175
277
  },
176
- },
278
+ ],
177
279
  },
280
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
281
+ // 分组三:列表项样式
282
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
178
283
  {
179
- title: '图片高度',
180
- name: 'imgHeight',
181
- description: '图片高度',
182
- setter: {
183
- componentName: 'NumberSetter',
184
- isRequired: false,
185
- initialValue: 100,
186
- },
187
- extraProps: {
188
- ignoreDefaultValue: () => true,
189
- getValue: (target: any, value: any) => {
190
- const parsed = parsePxNumber(value)
191
- if (parsed !== undefined) return parsed
192
- const fromSchema = parsePxNumber(target?.node?.schema?.props?.imgHeight)
193
- if (fromSchema !== undefined) return fromSchema
194
- return 100
284
+ type: 'group',
285
+ title: '子项样式',
286
+ display: 'accordion',
287
+ items: [
288
+ {
289
+ title: '内边距',
290
+ name: 'itemPadding',
291
+ description: '列表项内边距(px)',
292
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 0, defaultValue: 0, props: { min: 0 } },
195
293
  },
196
- },
294
+ {
295
+ title: '背景颜色',
296
+ name: 'itemBgColor',
297
+ description: '列表项背景颜色',
298
+ setter: { componentName: 'ColorSetter', isRequired: false, initialValue: '#ffffff' },
299
+ },
300
+ {
301
+ title: '圆角',
302
+ name: 'itemBorderRadius',
303
+ description: '列表项圆角(px)',
304
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 0, defaultValue: 0, props: { min: 0 } },
305
+ },
306
+ {
307
+ title: '边框颜色',
308
+ name: 'itemBorderColor',
309
+ description: '列表项边框颜色',
310
+ setter: { componentName: 'ColorSetter', isRequired: false, initialValue: '' },
311
+ },
312
+ {
313
+ title: '边框宽度',
314
+ name: 'itemBorderWidth',
315
+ description: '列表项边框宽度(px),设置边框颜色后生效',
316
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 0, defaultValue: 0, props: { min: 0, max: 10 } },
317
+ },
318
+ ],
197
319
  },
320
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
321
+ // 分组四:图片样式
322
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
198
323
  {
199
- title: '数据源绑定',
200
- name: 'dataListBind',
201
- setter: {
202
- componentName: 'SetterFormVariable',
203
- props: {
204
- attributes: [
205
- {
206
- label: '图文数据',
207
- value: 'dataList',
208
- children: [
209
- { label: '图片链接', value: 'image' },
210
- { label: '类型', value: 'itemType' },
211
- { label: '标题', value: 'title' },
212
- { label: '说明', value: 'description' },
324
+ type: 'group',
325
+ title: '图片样式',
326
+ display: 'accordion',
327
+ items: [
328
+ {
329
+ title: '图片位置',
330
+ name: 'imagePlacement',
331
+ setter: {
332
+ componentName: 'RadioGroupSetter',
333
+ props: {
334
+ options: [
335
+ { label: '', value: 'left' },
336
+ { label: '', value: 'right' },
337
+ { label: '', value: 'top' },
338
+ { label: '下', value: 'bottom' },
339
+ { label: '无', value: 'none' },
213
340
  ],
214
341
  },
215
- ],
342
+ initialValue: 'left',
343
+ },
344
+ extraProps: {},
216
345
  },
217
- },
218
- extraProps: {
219
- // 引擎已自动 node.setPropValue('dataListBind', value),无需重复写入
220
- },
221
- },
222
- {
223
- title: '标题',
224
- name: 'title',
225
- description: '标题',
226
- setter: {
227
- componentName: 'StringSetter',
228
- isRequired: false,
229
- initialValue: '',
230
- },
231
- },
232
- {
233
- title: {
234
- label: {
235
- type: 'i18n',
236
- 'en-US': 'moreText',
237
- 'zh-CN': '更多文字',
346
+ {
347
+ title: '图文对齐',
348
+ name: 'textAlign',
349
+ description: '图片与文字的交叉轴对齐方式',
350
+ setter: {
351
+ componentName: 'RadioGroupSetter',
352
+ props: {
353
+ options: [
354
+ { label: '顶对齐', value: 'flex-start' },
355
+ { label: '居中', value: 'center' },
356
+ { label: '底对齐', value: 'flex-end' },
357
+ ],
358
+ },
359
+ initialValue: 'flex-start',
360
+ },
238
361
  },
239
- tip: 'moreText | 更多文字',
240
- },
241
- name: 'moreText',
242
- description: '更多文字',
243
- setter: {
244
- componentName: 'StringSetter',
245
- isRequired: false,
246
- initialValue: '',
247
- },
248
- },
249
- {
250
- title: '文字行数',
251
- name: 'textLines',
252
- description: '文字行数',
253
- setter: {
254
- componentName: 'NumberSetter',
255
- isRequired: false,
256
- initialValue: 2,
257
- defaultValue: 2,
258
- props: {
259
- min: 2,
260
- max: 4,
362
+ {
363
+ title: '图文间距',
364
+ name: 'textImgGap',
365
+ description: '图片与文字区域之间的间距(px)',
366
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 16, defaultValue: 16, props: { min: 0 } },
261
367
  },
262
- },
263
- extraProps: {
264
- setValue(target, value) {
265
- target.getProps().setPropValue('textLines', value)
266
- const schema: any = target?.node?.schema
267
- const node: any = target?.node
268
- const schemaChildren: any[] = Array.isArray(schema?.children) ? schema.children : []
269
-
270
- // 获取当前文本组件数量
271
- const currentLength =
272
- schemaChildren.filter(
273
- (child) =>
274
- child.componentName === 'NextText' && child?.props?.key?.startsWith('text-'),
275
- )?.length || 0
276
-
277
- if (value > currentLength) {
278
- // 需要添加新的文本组件
279
- for (let i = currentLength + 1; i <= value; i++) {
280
- const newChild = {
281
- componentName: 'NextText',
282
- props: {
283
- type: 'inherit',
284
- children: '基于 Ali-Lowcode-Engine 快速打造高生产力的低代码研发平台',
285
- key: `text-${i}`,
286
- },
287
- }
288
- node?.children?.push(newChild)
289
- }
290
- } else if (value < currentLength) {
291
- // 收集需要移除的节点,再调用 child.remove() 通过引擎 API 逐个删除
292
- // 避免 node.children = [...] 直接赋值(IPublicModelNodeChildren 不支持重新赋值)
293
- const nodesToRemove: any[] = []
294
- node?.children?.forEach?.((child: any) => {
295
- const key = child?.schema?.props?.key
296
- if (
297
- child?.componentName === 'NextText' &&
298
- typeof key === 'string' &&
299
- key.startsWith('text-')
300
- ) {
301
- const order = Number(key.split('-')[1])
302
- if (!Number.isNaN(order) && order > value) {
303
- nodesToRemove.push(child)
304
- }
305
- }
306
- })
307
- nodesToRemove.forEach((child) => child?.remove?.())
308
- }
309
-
310
- // 更新数据源绑定的配置
311
- const dataListBindProp = (target?.parent as any)?.items?.find(
312
- (item) => item.name === 'dataListBind',
313
- )
314
- if (dataListBindProp && dataListBindProp.setter) {
315
- const baseChildren = [
316
- { label: '图片链接', value: 'image' },
317
- { label: '类型', value: 'itemType' },
318
- { label: '标题', value: 'title' },
319
- { label: '说明', value: 'description' },
320
- ]
321
-
322
- // 只有当value大于2时才添加额外的文本字段
323
- const textChildren =
324
- value > 2
325
- ? Array.from({ length: value - 2 }).map((_, index) => ({
326
- label: `文本${index + 3}`,
327
- value: `text${index + 3}`,
328
- }))
329
- : []
330
-
331
- // 更新setter的attributes
332
- dataListBindProp.setter.props.attributes[0].children = [
333
- ...baseChildren,
334
- ...textChildren,
335
- ]
336
- }
368
+ {
369
+ title: '宽度',
370
+ name: 'imgWidth',
371
+ description: '图片宽度(px)',
372
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 100, props: { min: 10 } },
373
+ extraProps: {
374
+ ignoreDefaultValue: () => true,
375
+ getValue: (target: any, value: any) => {
376
+ const parsed = parsePxNumber(value)
377
+ if (parsed !== undefined) return parsed
378
+ const fromSchema = parsePxNumber(target?.node?.schema?.props?.imgWidth)
379
+ if (fromSchema !== undefined) return fromSchema
380
+ return 100
381
+ },
382
+ },
337
383
  },
338
- },
339
- },
340
- {
341
- title: '子项列数',
342
- name: 'itemColumns',
343
- description: '子项列数',
344
- setter: {
345
- componentName: 'NumberSetter',
346
- isRequired: false,
347
- initialValue: (target) => {
348
- const isTwoColumns =
349
- target.getProps().getPropValue('imagePlacement') === 'top' ||
350
- target.getProps().getPropValue('imagePlacement') === 'bottom'
351
- return isTwoColumns ? 2 : 1
352
- },
353
- defaultValue: (target) => {
354
- const isTwoColumns =
355
- target.getProps().getPropValue('imagePlacement') === 'top' ||
356
- target.getProps().getPropValue('imagePlacement') === 'bottom'
357
- return isTwoColumns ? 2 : 1
384
+ {
385
+ title: '高度',
386
+ name: 'imgHeight',
387
+ description: '图片高度(px)',
388
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 100, props: { min: 10 } },
389
+ extraProps: {
390
+ ignoreDefaultValue: () => true,
391
+ getValue: (target: any, value: any) => {
392
+ const parsed = parsePxNumber(value)
393
+ if (parsed !== undefined) return parsed
394
+ const fromSchema = parsePxNumber(target?.node?.schema?.props?.imgHeight)
395
+ if (fromSchema !== undefined) return fromSchema
396
+ return 100
397
+ },
398
+ },
358
399
  },
359
- props: {
360
- min: 1,
361
- max: 2,
400
+ {
401
+ title: '圆角',
402
+ name: 'imgBorderRadius',
403
+ description: '图片圆角(px),设为 999 可得到圆形',
404
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 0, defaultValue: 0, props: { min: 0 } },
362
405
  },
363
- },
364
- },
365
- {
366
- title: '子项间距',
367
- name: 'itemGap',
368
- description: '子项间距',
369
- setter: {
370
- componentName: 'NumberSetter',
371
- isRequired: false,
372
- initialValue: 10,
373
- defaultValue: 10,
374
- },
375
- },
376
- {
377
- title: '子项内边距',
378
- name: 'itemPadding',
379
- description: '子项内边距',
380
- setter: {
381
- componentName: 'NumberSetter',
382
- isRequired: false,
383
- initialValue: 0,
384
- defaultValue: 0,
385
- },
386
- },
387
- {
388
- title: '子项背景颜色',
389
- name: 'itemBgColor',
390
- description: '子项背景颜色',
391
- setter: {
392
- componentName: 'ColorSetter',
393
- isRequired: false,
394
- initialValue: '#fff',
395
- defaultValue: '#fff',
396
- },
397
- },
398
- {
399
- title: '子项分布',
400
- name: 'itemRowAlign',
401
- description: '子项分布',
402
- setter: {
403
- componentName: 'SelectSetter',
404
- props: {
405
- options: [
406
- {
407
- label: '列分布',
408
- value: 'column',
409
- },
410
- {
411
- label: '一行显示',
412
- value: 'row',
406
+ {
407
+ title: '填充方式',
408
+ name: 'imgObjectFit',
409
+ description: '图片在容器内的填充方式',
410
+ setter: {
411
+ componentName: 'RadioGroupSetter',
412
+ props: {
413
+ options: [
414
+ { label: '覆盖', value: 'cover' },
415
+ { label: '适应', value: 'contain' },
416
+ { label: '拉伸', value: 'fill' },
417
+ { label: '原始', value: 'none' },
418
+ ],
413
419
  },
414
- ],
420
+ initialValue: 'cover',
421
+ },
415
422
  },
416
- initialValue: 'column',
417
- },
423
+ ],
418
424
  },
425
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
426
+ // 分组五:标题文字样式
427
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
419
428
  {
420
- title: '图文对齐方式',
421
- name: 'textAlign',
422
- description: '图文对齐方式',
423
- setter: {
424
- componentName: 'SelectSetter',
425
- props: {
426
- options: [
427
- {
428
- label: '左对齐',
429
- value: 'flex-start',
430
- },
431
- {
432
- label: '右对齐',
433
- value: 'flex-end',
434
- },
435
- {
436
- label: '居中对齐',
437
- value: 'center',
429
+ type: 'group',
430
+ title: '标题文字样式',
431
+ display: 'accordion',
432
+ items: [
433
+ {
434
+ title: '颜色',
435
+ name: 'titleColor',
436
+ setter: { componentName: 'ColorSetter', isRequired: false, initialValue: '' },
437
+ },
438
+ {
439
+ title: '字体大小',
440
+ name: 'titleFontSize',
441
+ description: '标题字体大小(px)',
442
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 14, defaultValue: 14, props: { min: 10, max: 60 } },
443
+ },
444
+ {
445
+ title: '字重',
446
+ name: 'titleFontWeight',
447
+ setter: {
448
+ componentName: 'RadioGroupSetter',
449
+ props: {
450
+ options: [
451
+ { label: '常规', value: 'normal' },
452
+ { label: '中等', value: '500' },
453
+ { label: '半粗', value: '600' },
454
+ { label: '粗体', value: 'bold' },
455
+ ],
438
456
  },
439
- ],
457
+ initialValue: '600',
458
+ },
440
459
  },
441
- initialValue: 'flex-start',
442
- },
460
+ {
461
+ title: '最大行数',
462
+ name: 'titleLineClamp',
463
+ description: '超出后显示省略号,0 表示不限制',
464
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 1, defaultValue: 1, props: { min: 0, max: 10 } },
465
+ },
466
+ ],
443
467
  },
468
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
469
+ // 分组六:说明文字样式
470
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
444
471
  {
445
- title: '图文间距',
446
- name: 'textImgGap',
447
- description: '图文间距',
448
- setter: {
449
- componentName: 'NumberSetter',
450
- isRequired: false,
451
- initialValue: 0,
452
- defaultValue: 0,
453
- },
472
+ type: 'group',
473
+ title: '说明文字样式',
474
+ display: 'accordion',
475
+ items: [
476
+ {
477
+ title: '颜色',
478
+ name: 'descriptionColor',
479
+ setter: { componentName: 'ColorSetter', isRequired: false, initialValue: '' },
480
+ },
481
+ {
482
+ title: '字体大小',
483
+ name: 'descriptionFontSize',
484
+ description: '说明字体大小(px)',
485
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 13, defaultValue: 13, props: { min: 10, max: 60 } },
486
+ },
487
+ {
488
+ title: '字重',
489
+ name: 'descriptionFontWeight',
490
+ setter: {
491
+ componentName: 'RadioGroupSetter',
492
+ props: {
493
+ options: [
494
+ { label: '常规', value: 'normal' },
495
+ { label: '中等', value: '500' },
496
+ { label: '半粗', value: '600' },
497
+ { label: '粗体', value: 'bold' },
498
+ ],
499
+ },
500
+ initialValue: 'normal',
501
+ },
502
+ },
503
+ {
504
+ title: '最大行数',
505
+ name: 'descriptionLineClamp',
506
+ description: '超出后显示省略号,0 表示不限制',
507
+ setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 1, defaultValue: 1, props: { min: 0, max: 10 } },
508
+ },
509
+ ],
454
510
  },
511
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
512
+ // 浮层图标
513
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
455
514
  {
456
- title: '图标配置',
515
+ title: '浮层图标',
457
516
  name: 'iconList',
458
- extraProps: {
459
- display: 'accordion',
460
- defaultCollapsed: false,
461
- },
517
+ description: '在每个列表项上叠加绝对定位图标(如角标、标签等)',
518
+ extraProps: { display: 'accordion', defaultCollapsed: true },
462
519
  setter: {
463
520
  componentName: 'ArraySetter',
464
521
  props: {
@@ -472,9 +529,7 @@ const TeletextListMeta: IPublicTypeComponentMetadata = {
472
529
  title: '图标',
473
530
  setter: 'IconSetter',
474
531
  isRequired: true,
475
- props: {
476
- hasClear: false,
477
- },
532
+ props: { hasClear: false },
478
533
  },
479
534
  {
480
535
  name: 'size',
@@ -483,42 +538,15 @@ const TeletextListMeta: IPublicTypeComponentMetadata = {
483
538
  componentName: 'SelectSetter',
484
539
  props: {
485
540
  options: [
486
- {
487
- label: 'xxs',
488
- value: 'xxs',
489
- },
490
- {
491
- label: 'xs',
492
- value: 'xs',
493
- },
494
- {
495
- label: 'small',
496
- value: 'small',
497
- },
498
- {
499
- label: 'medium',
500
- value: 'medium',
501
- },
502
- {
503
- label: 'large',
504
- value: 'large',
505
- },
506
- {
507
- label: 'xl',
508
- value: 'xl',
509
- },
510
- {
511
- label: 'xxl',
512
- value: 'xxl',
513
- },
514
- {
515
- label: 'xxxl',
516
- value: 'xxxl',
517
- },
518
- {
519
- label: 'inherit',
520
- value: 'inherit',
521
- },
541
+ { label: 'xxs', value: 'xxs' },
542
+ { label: 'xs', value: 'xs' },
543
+ { label: 'small', value: 'small' },
544
+ { label: 'medium', value: 'medium' },
545
+ { label: 'large', value: 'large' },
546
+ { label: 'xl', value: 'xl' },
547
+ { label: 'xxl', value: 'xxl' },
548
+ { label: 'xxxl', value: 'xxxl' },
549
+ { label: 'inherit', value: 'inherit' },
522
550
  ],
523
551
  },
524
552
  },
@@ -533,26 +561,11 @@ const TeletextListMeta: IPublicTypeComponentMetadata = {
533
561
  componentName: 'SelectSetter',
534
562
  props: {
535
563
  options: [
536
- {
537
- label: '左上角',
538
- value: 'leftTop',
539
- },
540
- {
541
- label: '左下角',
542
- value: 'leftBottom',
543
- },
544
- {
545
- label: '右上角',
546
- value: 'rightTop',
547
- },
548
- {
549
- label: '右下角',
550
- value: 'rightBottom',
551
- },
552
- {
553
- label: '自定义',
554
- value: 'customize',
555
- },
564
+ { label: '左上角', value: 'leftTop' },
565
+ { label: '左下角', value: 'leftBottom' },
566
+ { label: '右上角', value: 'rightTop' },
567
+ { label: '右下角', value: 'rightBottom' },
568
+ { label: '自定义', value: 'customize' },
556
569
  ],
557
570
  },
558
571
  },
@@ -567,169 +580,23 @@ const TeletextListMeta: IPublicTypeComponentMetadata = {
567
580
  title: '右偏移',
568
581
  setter: 'NumberSetter',
569
582
  defaultValue: 0,
570
- condition: (target) => {
571
- return target.getProps().getPropValue('position') === 'customize'
572
- },
583
+ condition: (target) => target.getProps().getPropValue('position') === 'customize',
573
584
  },
574
585
  {
575
586
  name: 'topOffset',
576
587
  title: '上偏移',
577
588
  setter: 'NumberSetter',
578
589
  defaultValue: 0,
579
- condition: (target) => {
580
- return target.getProps().getPropValue('position') === 'customize'
581
- },
590
+ condition: (target) => target.getProps().getPropValue('position') === 'customize',
582
591
  },
583
592
  ],
584
593
  },
585
594
  },
586
- initialValue: {
587
- size: 'medium',
588
- position: 'rightTop',
589
- rightOffset: 0,
590
- topOffset: 0,
591
- },
595
+ initialValue: { size: 'medium', position: 'rightTop', rightOffset: 0, topOffset: 0 },
592
596
  },
593
597
  },
594
598
  },
595
599
  },
596
- {
597
- title: '是否为购物车列表',
598
- name: 'isShoppingCart',
599
- description: '是否为购物车列表',
600
- setter: {
601
- componentName: 'BoolSetter',
602
- isRequired: true,
603
- initialValue: false,
604
- },
605
- },
606
- {
607
- title: '是否为愿望单列表',
608
- name: 'isWishList',
609
- description: '是否为愿望单列表',
610
- setter: {
611
- componentName: 'BoolSetter',
612
- isRequired: true,
613
- initialValue: false,
614
- },
615
- },
616
- {
617
- title: '是否为用户菜单列表',
618
- name: 'isUserMenu',
619
- description: '是否为用户菜单列表',
620
- setter: {
621
- componentName: 'BoolSetter',
622
- isRequired: true,
623
- initialValue: false,
624
- },
625
- },
626
- {
627
- title: {
628
- label: {
629
- type: 'i18n',
630
- 'en-US': 'dataList',
631
- 'zh-CN': '数据',
632
- },
633
- tip: 'dataList | 数据',
634
- },
635
- name: 'dataList',
636
- description: '数据',
637
- setter: {
638
- componentName: 'ArraySetter',
639
- props: {
640
- itemSetter: {
641
- componentName: 'ObjectSetter',
642
- props: {
643
- config: {
644
- items: [
645
- {
646
- title: {
647
- label: {
648
- type: 'i18n',
649
- 'en-US': 'title',
650
- 'zh-CN': '标题',
651
- },
652
- },
653
- name: 'title',
654
- description: '标题',
655
- setter: {
656
- componentName: 'StringSetter',
657
- isRequired: false,
658
- initialValue: '',
659
- },
660
- },
661
- {
662
- title: {
663
- label: {
664
- type: 'i18n',
665
- 'en-US': 'image',
666
- 'zh-CN': '图片地址',
667
- },
668
- },
669
- name: 'image',
670
- description: '图片地址',
671
- setter: {
672
- componentName: 'CustomImageSetter',
673
- isRequired: false,
674
- initialValue: '',
675
- },
676
- },
677
- {
678
- title: {
679
- label: {
680
- type: 'i18n',
681
- 'en-US': 'description',
682
- 'zh-CN': '描述',
683
- },
684
- },
685
- name: 'description',
686
- description: '描述',
687
- setter: {
688
- componentName: 'StringSetter',
689
- isRequired: false,
690
- initialValue: '',
691
- },
692
- },
693
- ],
694
- extraSetter: {
695
- componentName: 'MixedSetter',
696
- isRequired: false,
697
- props: {},
698
- },
699
- },
700
- },
701
- },
702
- },
703
- initialValue: (target) => {
704
- // ignoreDefaultValue: () => true 保证此函数在 SettingFieldView remount 时
705
- // 永远不会被 initDefaultValue 调用,仅作为安全兜底保留。
706
- // 正常的首次创建数据由 snippet.props.dataList 提供。
707
- const existing = target?.node?.schema?.props?.dataList
708
- ?? target?.getProps?.()?.getPropValue?.('dataList')
709
- if (existing !== undefined) return existing
710
- return DEFAULT_DATA_LIST
711
- },
712
- },
713
- extraProps: {
714
- /**
715
- * ignoreDefaultValue: 彻底阻止引擎在 SettingFieldView remount 时
716
- * 调用 initDefaultValue → 把 initialValue(默认数据数组)通过 field.setValue
717
- * 写入 dataList prop,覆盖已绑定的 JSExpression。
718
- *
719
- * 这是根本性解决方案:在引擎层面阻断 initDefaultValue 的执行,
720
- * 而不是试图在 initialValue/getValue/setValue 中做缓存和还原来补救。
721
- */
722
- ignoreDefaultValue: () => true,
723
- getValue: (target: any, currentValue: any) => {
724
- // currentValue 已有值时直接返回
725
- if (currentValue !== undefined) return currentValue
726
- // 从 schema 快照兜底读取(最可靠的源头数据,始终反映持久化状态)
727
- const fromSchema = target?.node?.schema?.props?.dataList
728
- if (fromSchema !== undefined) return fromSchema
729
- return undefined
730
- },
731
- },
732
- },
733
600
  ],
734
601
  supports: {
735
602
  style: true,
@@ -777,121 +644,8 @@ const getSnippets = (textLines = 2): IPublicTypeSnippet[] => [
777
644
  // SettingFieldView remount 时覆盖已绑定的 JSExpression,
778
645
  // 所以 initDefaultValue 永远不会运行,首次拖入的初始数据必须由 snippet 提供。
779
646
  dataList: DEFAULT_DATA_LIST,
647
+ title: '列表标题',
780
648
  },
781
- children: [
782
- {
783
- componentName: 'NextText',
784
- props: {
785
- type: 'h5',
786
- children: '列表标题',
787
- key: 'box-title',
788
- style: {
789
- fontSize: '16px',
790
- fontWeight: 'bold',
791
- },
792
- },
793
- },
794
- {
795
- componentName: 'Image',
796
- props: {
797
- imgSrc: 'https://img.alicdn.com/tps/TB16TQvOXXXXXbiaFXXXXXXXXXX-120-120.svg',
798
- key: 'image',
799
- },
800
- },
801
- // 动态生成文本组件
802
- // ...Array.from({ length: textLines }).map((_, index) => ({
803
- // componentName: 'NextText',
804
- // props: {
805
- // type: index === 0 ? 'h5' : 'inherit',
806
- // children:
807
- // index === 0
808
- // ? '标题标题'
809
- // : '基于1 Ali-Lowcode-Engine 快速打造高生产力的低代码研发平台, 基于自然布局体系快速搭建页面',
810
- // key: `text-${index + 1}`,
811
- // },
812
- // })),
813
- {
814
- componentName: 'NextText',
815
- props: {
816
- type: 'h5',
817
- children: '标题标题',
818
- key: `text-1`,
819
- },
820
- },
821
- {
822
- componentName: 'NextText',
823
- props: {
824
- type: 'inherit',
825
- children:
826
- '基于1 Ali-Lowcode-Engine 快速打造高生产力的低代码研发平台, 基于自然布局体系快速搭建页面',
827
- key: `text-2`,
828
- },
829
- },
830
- {
831
- componentName: 'NextText',
832
- props: {
833
- type: 'inherit',
834
- children:
835
- '基于1 Ali-Lowcode-Engine 快速打造高生产力的低代码研发平台, 基于自然布局体系快速搭建页面',
836
- key: `text-3`,
837
- },
838
- },
839
- {
840
- componentName: 'NextText',
841
- props: {
842
- type: 'inherit',
843
- children:
844
- '基于1 Ali-Lowcode-Engine 快速打造高生产力的低代码研发平台, 基于自然布局体系快速搭建页面',
845
- key: `text-4`,
846
- },
847
- },
848
- {
849
- componentName: 'Select',
850
- props: {
851
- popType: 'dialog',
852
- selectType: 'number',
853
- value: 1,
854
- prefix: '数量: ',
855
- dialogTitle: '选择数量',
856
- btnText: '确定',
857
- key: 'select-box-1',
858
- },
859
- },
860
- {
861
- componentName: 'Select',
862
- props: {
863
- popType: 'dialog',
864
- selectType: 'string',
865
- dataList: [
866
- {
867
- label: 'M',
868
- value: 'M',
869
- },
870
- {
871
- label: 'X',
872
- value: 'X',
873
- },
874
- {
875
- label: 'XL',
876
- value: 'XL',
877
- },
878
- ],
879
- value: 'X',
880
- prefix: '尺码: ',
881
- dialogTitle: '选择尺码',
882
- btnText: '确定',
883
- key: 'select-box-2',
884
- },
885
- },
886
- {
887
- componentName: 'Switch',
888
- props: {
889
- size: 'small',
890
- disabled: false,
891
- key: 'switch-1',
892
- },
893
- },
894
- ],
895
649
  },
896
650
  },
897
651
  ]