@ticatec/uniface-element 0.2.3 → 0.3.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.
Files changed (178) hide show
  1. package/dist/accordion/README.md +169 -0
  2. package/dist/accordion/README_CN.md +176 -0
  3. package/dist/action-bar/README.md +275 -0
  4. package/dist/action-bar/README_CN.md +285 -0
  5. package/dist/app-layout/README.md +374 -0
  6. package/dist/app-layout/README_CN.md +381 -0
  7. package/dist/app-top-bar/README.md +357 -0
  8. package/dist/app-top-bar/README_CN.md +365 -0
  9. package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
  10. package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
  11. package/dist/base-calendar/CalendarBase.svelte +0 -3
  12. package/dist/box/README.md +385 -0
  13. package/dist/box/README_CN.md +393 -0
  14. package/dist/breadcrumbs/README.md +442 -0
  15. package/dist/breadcrumbs/README_CN.md +442 -0
  16. package/dist/button/Button.svelte +27 -7
  17. package/dist/button/Button.svelte.d.ts +3 -1
  18. package/dist/button/IconButton.svelte +26 -6
  19. package/dist/button/IconButton.svelte.d.ts +3 -1
  20. package/dist/button/IconButton_README.md +513 -0
  21. package/dist/button/IconButton_README_CN.md +513 -0
  22. package/dist/button/README.md +428 -0
  23. package/dist/button/README_CN.md +428 -0
  24. package/dist/button/TextButton.svelte +26 -6
  25. package/dist/button/TextButton.svelte.d.ts +3 -1
  26. package/dist/button/TextButton_README.md +571 -0
  27. package/dist/button/TextButton_README_CN.md +571 -0
  28. package/dist/card/README.md +666 -0
  29. package/dist/card/README_CN.md +666 -0
  30. package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
  31. package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
  32. package/dist/cascade-options-select/README.md +663 -2
  33. package/dist/cascade-options-select/README_CN.md +664 -0
  34. package/dist/checkbox/CheckBox.svelte +20 -6
  35. package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
  36. package/dist/checkbox/README.md +562 -0
  37. package/dist/checkbox/README_CN.md +727 -0
  38. package/dist/common-editor/NumberInput.svelte +39 -26
  39. package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
  40. package/dist/concise-data-table/ConciseListTable.svelte +133 -36
  41. package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
  42. package/dist/concise-data-table/DataCell.svelte +5 -6
  43. package/dist/concise-data-table/DataRow.svelte +22 -2
  44. package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
  45. package/dist/concise-data-table/README.md +606 -0
  46. package/dist/concise-data-table/README_CN.md +611 -0
  47. package/dist/context-menu/ContextMenu.svelte +138 -21
  48. package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
  49. package/dist/context-menu/ContextMenuItem.d.ts +20 -4
  50. package/dist/context-menu/README.md +551 -0
  51. package/dist/context-menu/README_CN.md +551 -0
  52. package/dist/criteria-field/CriteriaField.svelte +3 -5
  53. package/dist/criteria-field/README.md +532 -0
  54. package/dist/criteria-field/README_CN.md +532 -0
  55. package/dist/data-table/README.md +712 -0
  56. package/dist/data-table/README_CN.md +712 -0
  57. package/dist/date-picker/DatePicker.svelte +44 -7
  58. package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
  59. package/dist/date-picker/DateTimePicker.svelte +32 -8
  60. package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
  61. package/dist/date-picker/README.md +326 -0
  62. package/dist/date-picker/README_CN.md +316 -0
  63. package/dist/date-picker/ScrollBar.svelte +18 -8
  64. package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
  65. package/dist/date-picker/TimePanel.svelte +5 -5
  66. package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
  67. package/dist/date-range/README.md +374 -0
  68. package/dist/date-range/README_CN.md +374 -0
  69. package/dist/dialog/DialogBoard.svelte +1 -1
  70. package/dist/dialog/README.md +596 -0
  71. package/dist/dialog/README_CN.md +596 -0
  72. package/dist/drawer/README.md +679 -1
  73. package/dist/drawer/README_CN.md +679 -0
  74. package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
  75. package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
  76. package/dist/group-box/group-check-box/README.md +749 -0
  77. package/dist/group-box/group-check-box/README_CN.md +750 -0
  78. package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
  79. package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
  80. package/dist/group-box/group-radio-box/README.md +920 -0
  81. package/dist/group-box/group-radio-box/README_CN.md +920 -0
  82. package/dist/image-files/README.md +1346 -0
  83. package/dist/image-files/README_CN.md +1346 -0
  84. package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
  85. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
  86. package/dist/lib/forwardAllEvents.d.ts +3 -0
  87. package/dist/lib/forwardAllEvents.js +24 -0
  88. package/dist/list-box/README.md +579 -0
  89. package/dist/list-box/README_CN.md +682 -0
  90. package/dist/lookup-editor/LookupEditor.svelte +15 -3
  91. package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
  92. package/dist/lookup-editor/README.md +684 -0
  93. package/dist/lookup-editor/README_CN.md +684 -0
  94. package/dist/memo-editor/MemoEditor.svelte +77 -27
  95. package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
  96. package/dist/memo-editor/README.md +819 -0
  97. package/dist/memo-editor/README_CN.md +819 -0
  98. package/dist/message-box/README.md +398 -0
  99. package/dist/message-box/README_CN.md +398 -0
  100. package/dist/number-editor/NumberEditor.svelte +2 -2
  101. package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
  102. package/dist/number-editor/README.md +353 -22
  103. package/dist/number-editor/README_CN.md +357 -0
  104. package/dist/number-range/README.md +443 -0
  105. package/dist/number-range/README_CN.md +443 -0
  106. package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
  107. package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
  108. package/dist/options-multi-select/README.md +480 -0
  109. package/dist/options-multi-select/README_CN.md +480 -0
  110. package/dist/options-select/OptionsSelect.svelte +36 -5
  111. package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
  112. package/dist/options-select/README.md +632 -0
  113. package/dist/options-select/README_CN.md +632 -0
  114. package/dist/page/README.md +605 -0
  115. package/dist/page/README_CN.md +605 -0
  116. package/dist/pagination/README.md +946 -0
  117. package/dist/pagination/README_CN.md +946 -0
  118. package/dist/pagination-panel/README.md +1075 -0
  119. package/dist/pagination-panel/README_CN.md +1075 -0
  120. package/dist/popup-hint/README.md +841 -0
  121. package/dist/popup-hint/README_CN.md +840 -0
  122. package/dist/progress-bar/README.md +242 -0
  123. package/dist/progress-bar/README_CN.md +242 -0
  124. package/dist/progress-step-bar/README.md +316 -0
  125. package/dist/progress-step-bar/README_CN.md +316 -0
  126. package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
  127. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
  128. package/dist/prompts-text-editor/README.md +329 -0
  129. package/dist/prompts-text-editor/README_CN.md +329 -0
  130. package/dist/property-editor/README.md +969 -0
  131. package/dist/property-editor/README_CN.md +969 -0
  132. package/dist/radio-button/README.md +372 -0
  133. package/dist/radio-button/README_CN.md +372 -0
  134. package/dist/radio-button/RadioButton.svelte +32 -3
  135. package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
  136. package/dist/search-box/README.md +425 -0
  137. package/dist/search-box/README_CN.md +424 -0
  138. package/dist/search-box/SearchBox.svelte +22 -6
  139. package/dist/search-box/SearchBox.svelte.d.ts +4 -1
  140. package/dist/tabs/README.md +919 -0
  141. package/dist/tabs/README_CN.md +920 -0
  142. package/dist/tag/README.md +922 -0
  143. package/dist/tag/README_CN.md +922 -0
  144. package/dist/text-editor/PasswordEditor.svelte +17 -2
  145. package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
  146. package/dist/text-editor/PasswordEditor_README.md +551 -0
  147. package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
  148. package/dist/text-editor/README.md +466 -0
  149. package/dist/text-editor/README_CN.md +466 -0
  150. package/dist/text-editor/TextEditor.svelte +51 -19
  151. package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
  152. package/dist/ticatec-uniface-web.css +1 -0
  153. package/dist/time-editor/README.md +498 -24
  154. package/dist/time-editor/README_CN.md +498 -0
  155. package/dist/time-editor/TimeEditor.svelte +7 -3
  156. package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
  157. package/dist/toast/README.md +667 -0
  158. package/dist/toast/README_CN.md +667 -0
  159. package/dist/transfer/README.md +795 -0
  160. package/dist/transfer/Transfer.svelte +6 -4
  161. package/dist/transfer/Transfer.svelte.d.ts +3 -1
  162. package/dist/tree-view/README.md +761 -0
  163. package/dist/tree-view/README_CN.md +761 -0
  164. package/dist/tree-view/TreeView.svelte +5 -3
  165. package/dist/tree-view/TreeView.svelte.d.ts +3 -1
  166. package/dist/unit-number-editor/README.md +546 -20
  167. package/dist/unit-number-editor/README_CN.md +525 -0
  168. package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
  169. package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
  170. package/docs/form-field/cn/README_CN.md +364 -0
  171. package/docs/form-field/en/README.md +364 -0
  172. package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
  173. package/docs/form-panel/flex-form/en/README.md +586 -0
  174. package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
  175. package/docs/form-panel/flex-row-form/en/README.md +787 -0
  176. package/docs/form-panel/grid-form/en/README.md +744 -0
  177. package/package.json +1 -1
  178. package/dist/drawer/README-CN.md +0 -1
@@ -0,0 +1,969 @@
1
+ # PropertyEditor 属性编辑器组件
2
+
3
+ 一个动态属性编辑器组件,根据元数据配置渲染表单字段。支持多种字段类型、嵌套对象、自动组件选择和国际化。非常适合管理面板、表单构建器和配置界面。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install @ticatec/uniface-element
9
+ ```
10
+
11
+ ## 导入
12
+
13
+ ```typescript
14
+ import PropertyEditor from "@ticatec/uniface-element/PropertyEditor";
15
+ import { MetaEditorType, type PropertyField } from "@ticatec/uniface-element/PropertyEditor";
16
+ ```
17
+
18
+ ## 基本用法
19
+
20
+ ```svelte
21
+ <script>
22
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
23
+
24
+ let userData = {
25
+ name: "张伟",
26
+ age: 30,
27
+ email: "zhangwei@example.com",
28
+ isActive: true
29
+ };
30
+
31
+ const userFields = [
32
+ {
33
+ name: "name",
34
+ label: "姓名",
35
+ type: MetaEditorType.Text,
36
+ attrs: {
37
+ placeholder: "请输入姓名",
38
+ maxLength: 50
39
+ }
40
+ },
41
+ {
42
+ name: "age",
43
+ label: "年龄",
44
+ type: MetaEditorType.Number,
45
+ attrs: {
46
+ min: 0,
47
+ max: 120
48
+ }
49
+ },
50
+ {
51
+ name: "email",
52
+ label: "电子邮件",
53
+ type: MetaEditorType.Text,
54
+ attrs: {
55
+ placeholder: "请输入电子邮件",
56
+ type: "email"
57
+ }
58
+ },
59
+ {
60
+ name: "isActive",
61
+ label: "激活状态",
62
+ type: MetaEditorType.Boolean
63
+ }
64
+ ];
65
+ </script>
66
+
67
+ <PropertyEditor fields={userFields} bind:data={userData} />
68
+ ```
69
+
70
+ ## 属性
71
+
72
+ | 属性 | 类型 | 默认值 | 描述 |
73
+ |------|------|---------|-------------|
74
+ | `fields` | `Array<PropertyField>` | 必需 | 字段定义数组 |
75
+ | `data` | `any` | 必需 | 要编辑的数据对象 |
76
+
77
+ ## 类型定义
78
+
79
+ ### PropertyField
80
+ ```typescript
81
+ interface PropertyField {
82
+ name: string; // 字段名称(支持点符号表示嵌套)
83
+ label: string; // 字段显示标签
84
+ type: MetaEditorType; // 编辑器类型
85
+ attrs?: any; // 编辑器组件的附加属性
86
+ }
87
+ ```
88
+
89
+ ### MetaEditorType
90
+ ```typescript
91
+ enum MetaEditorType {
92
+ Text = 'Text', // 文本输入
93
+ CommonText = 'CommonText', // 带建议的文本输入
94
+ Number = 'Number', // 数字输入
95
+ Date = 'Date', // 日期选择器
96
+ DateTime = 'DateTime', // 日期时间选择器
97
+ Options = 'Options', // 下拉选择
98
+ Boolean = 'Boolean' // 布尔值(真/假)
99
+ }
100
+ ```
101
+
102
+ ## 字段类型
103
+
104
+ ### 文本字段
105
+
106
+ ```svelte
107
+ <script>
108
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
109
+
110
+ let textData = {
111
+ title: "",
112
+ description: "",
113
+ keywords: ""
114
+ };
115
+
116
+ const textFields = [
117
+ {
118
+ name: "title",
119
+ label: "标题",
120
+ type: MetaEditorType.Text,
121
+ attrs: {
122
+ placeholder: "请输入标题",
123
+ maxLength: 100
124
+ }
125
+ },
126
+ {
127
+ name: "description",
128
+ label: "描述",
129
+ type: MetaEditorType.Text,
130
+ attrs: {
131
+ placeholder: "请输入描述",
132
+ rows: 3
133
+ }
134
+ },
135
+ {
136
+ name: "keywords",
137
+ label: "关键词",
138
+ type: MetaEditorType.CommonText,
139
+ attrs: {
140
+ words: ["javascript", "svelte", "typescript", "前端"],
141
+ placeholder: "请输入关键词"
142
+ }
143
+ }
144
+ ];
145
+ </script>
146
+
147
+ <div class="text-editor-demo">
148
+ <h3>文本字段示例</h3>
149
+ <PropertyEditor fields={textFields} bind:data={textData} />
150
+
151
+ <div class="output">
152
+ <h4>当前值:</h4>
153
+ <pre>{JSON.stringify(textData, null, 2)}</pre>
154
+ </div>
155
+ </div>
156
+
157
+ <style>
158
+ .text-editor-demo {
159
+ max-width: 600px;
160
+ margin: 20px auto;
161
+ padding: 20px;
162
+ border: 1px solid #ddd;
163
+ border-radius: 8px;
164
+ }
165
+
166
+ .output {
167
+ margin-top: 20px;
168
+ padding: 16px;
169
+ background: #f8f9fa;
170
+ border-radius: 4px;
171
+ }
172
+
173
+ .output pre {
174
+ margin: 8px 0 0 0;
175
+ font-size: 12px;
176
+ overflow-x: auto;
177
+ }
178
+ </style>
179
+ ```
180
+
181
+ ### 数字字段
182
+
183
+ ```svelte
184
+ <script>
185
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
186
+
187
+ let productData = {
188
+ price: 99.99,
189
+ quantity: 10,
190
+ weight: 0,
191
+ rating: 5
192
+ };
193
+
194
+ const numberFields = [
195
+ {
196
+ name: "price",
197
+ label: "价格(¥)",
198
+ type: MetaEditorType.Number,
199
+ attrs: {
200
+ min: 0,
201
+ precision: 2,
202
+ step: 0.01
203
+ }
204
+ },
205
+ {
206
+ name: "quantity",
207
+ label: "数量",
208
+ type: MetaEditorType.Number,
209
+ attrs: {
210
+ min: 0,
211
+ precision: 0,
212
+ step: 1
213
+ }
214
+ },
215
+ {
216
+ name: "weight",
217
+ label: "重量(kg)",
218
+ type: MetaEditorType.Number,
219
+ attrs: {
220
+ min: 0,
221
+ precision: 3,
222
+ step: 0.001
223
+ }
224
+ },
225
+ {
226
+ name: "rating",
227
+ label: "评分",
228
+ type: MetaEditorType.Number,
229
+ attrs: {
230
+ min: 1,
231
+ max: 5,
232
+ precision: 0
233
+ }
234
+ }
235
+ ];
236
+ </script>
237
+
238
+ <div class="number-editor-demo">
239
+ <h3>数字字段示例</h3>
240
+ <PropertyEditor fields={numberFields} bind:data={productData} />
241
+
242
+ <div class="summary">
243
+ <h4>产品摘要</h4>
244
+ <p>价格:¥{productData.price}</p>
245
+ <p>数量:{productData.quantity} 件</p>
246
+ <p>重量:{productData.weight} kg</p>
247
+ <p>评分:{productData.rating}/5 星</p>
248
+ </div>
249
+ </div>
250
+
251
+ <style>
252
+ .number-editor-demo {
253
+ max-width: 600px;
254
+ margin: 20px auto;
255
+ padding: 20px;
256
+ border: 1px solid #ddd;
257
+ border-radius: 8px;
258
+ }
259
+
260
+ .summary {
261
+ margin-top: 20px;
262
+ padding: 16px;
263
+ background: #f8f9fa;
264
+ border-radius: 4px;
265
+ }
266
+
267
+ .summary h4 {
268
+ margin: 0 0 12px 0;
269
+ }
270
+
271
+ .summary p {
272
+ margin: 4px 0;
273
+ font-weight: 500;
274
+ }
275
+ </style>
276
+ ```
277
+
278
+ ### 日期和日期时间字段
279
+
280
+ ```svelte
281
+ <script>
282
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
283
+
284
+ let eventData = {
285
+ startDate: null,
286
+ endDate: null,
287
+ registrationDeadline: null,
288
+ createdAt: new Date().toISOString()
289
+ };
290
+
291
+ const dateFields = [
292
+ {
293
+ name: "startDate",
294
+ label: "开始日期",
295
+ type: MetaEditorType.Date,
296
+ attrs: {
297
+ placeholder: "选择开始日期"
298
+ }
299
+ },
300
+ {
301
+ name: "endDate",
302
+ label: "结束日期",
303
+ type: MetaEditorType.Date,
304
+ attrs: {
305
+ placeholder: "选择结束日期"
306
+ }
307
+ },
308
+ {
309
+ name: "registrationDeadline",
310
+ label: "注册截止日期",
311
+ type: MetaEditorType.DateTime,
312
+ attrs: {
313
+ placeholder: "选择截止日期"
314
+ }
315
+ },
316
+ {
317
+ name: "createdAt",
318
+ label: "创建时间",
319
+ type: MetaEditorType.DateTime,
320
+ attrs: {
321
+ readonly: true
322
+ }
323
+ }
324
+ ];
325
+ </script>
326
+
327
+ <div class="date-editor-demo">
328
+ <h3>日期字段示例</h3>
329
+ <PropertyEditor fields={dateFields} bind:data={eventData} />
330
+
331
+ <div class="event-info">
332
+ <h4>活动信息</h4>
333
+ {#if eventData.startDate && eventData.endDate}
334
+ <p>活动时间:{eventData.startDate} 至 {eventData.endDate}</p>
335
+ {/if}
336
+ {#if eventData.registrationDeadline}
337
+ <p>注册截止:{eventData.registrationDeadline}</p>
338
+ {/if}
339
+ <p>创建于:{new Date(eventData.createdAt).toLocaleDateString()}</p>
340
+ </div>
341
+ </div>
342
+
343
+ <style>
344
+ .date-editor-demo {
345
+ max-width: 600px;
346
+ margin: 20px auto;
347
+ padding: 20px;
348
+ border: 1px solid #ddd;
349
+ border-radius: 8px;
350
+ }
351
+
352
+ .event-info {
353
+ margin-top: 20px;
354
+ padding: 16px;
355
+ background: #f8f9fa;
356
+ border-radius: 4px;
357
+ }
358
+
359
+ .event-info h4 {
360
+ margin: 0 0 12px 0;
361
+ }
362
+
363
+ .event-info p {
364
+ margin: 4px 0;
365
+ }
366
+ </style>
367
+ ```
368
+
369
+ ### 选项和布尔字段
370
+
371
+ ```svelte
372
+ <script>
373
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
374
+
375
+ let settingsData = {
376
+ theme: "light",
377
+ language: "zh",
378
+ notifications: true,
379
+ autoSave: false,
380
+ privacy: "public"
381
+ };
382
+
383
+ const settingsFields = [
384
+ {
385
+ name: "theme",
386
+ label: "主题",
387
+ type: MetaEditorType.Options,
388
+ attrs: {
389
+ options: [
390
+ { code: "light", text: "浅色主题" },
391
+ { code: "dark", text: "深色主题" },
392
+ { code: "auto", text: "自动(系统)" }
393
+ ]
394
+ }
395
+ },
396
+ {
397
+ name: "language",
398
+ label: "语言",
399
+ type: MetaEditorType.Options,
400
+ attrs: {
401
+ options: [
402
+ { code: "en", text: "English" },
403
+ { code: "zh", text: "中文" },
404
+ { code: "es", text: "Español" },
405
+ { code: "fr", text: "Français" }
406
+ ]
407
+ }
408
+ },
409
+ {
410
+ name: "notifications",
411
+ label: "电子邮件通知",
412
+ type: MetaEditorType.Boolean
413
+ },
414
+ {
415
+ name: "autoSave",
416
+ label: "自动保存",
417
+ type: MetaEditorType.Boolean
418
+ },
419
+ {
420
+ name: "privacy",
421
+ label: "个人资料可见性",
422
+ type: MetaEditorType.Options,
423
+ attrs: {
424
+ options: [
425
+ { code: "public", text: "公开" },
426
+ { code: "friends", text: "仅限好友" },
427
+ { code: "private", text: "私有" }
428
+ ]
429
+ }
430
+ }
431
+ ];
432
+ </script>
433
+
434
+ <div class="settings-editor-demo">
435
+ <h3>选项和布尔字段</h3>
436
+ <PropertyEditor fields={settingsFields} bind:data={settingsData} />
437
+
438
+ <div class="settings-preview">
439
+ <h4>当前设置</h4>
440
+ <ul>
441
+ <li>主题:{settingsData.theme}</li>
442
+ <li>语言:{settingsData.language}</li>
443
+ <li>电子邮件通知:{settingsData.notifications ? '启用' : '禁用'}</li>
444
+ <li>自动保存:{settingsData.autoSave ? '启用' : '禁用'}</li>
445
+ <li>个人资料:{settingsData.privacy}</li>
446
+ </ul>
447
+ </div>
448
+ </div>
449
+
450
+ <style>
451
+ .settings-editor-demo {
452
+ max-width: 600px;
453
+ margin: 20px auto;
454
+ padding: 20px;
455
+ border: 1px solid #ddd;
456
+ border-radius: 8px;
457
+ }
458
+
459
+ .settings-preview {
460
+ margin-top: 20px;
461
+ padding: 16px;
462
+ background: #f8f9fa;
463
+ border-radius: 4px;
464
+ }
465
+
466
+ .settings-preview h4 {
467
+ margin: 0 0 12px 0;
468
+ }
469
+
470
+ .settings-preview ul {
471
+ margin: 0;
472
+ padding-left: 20px;
473
+ }
474
+
475
+ .settings-preview li {
476
+ margin: 6px 0;
477
+ }
478
+ </style>
479
+ ```
480
+
481
+ ### 嵌套对象支持
482
+
483
+ ```svelte
484
+ <script>
485
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
486
+
487
+ let profileData = {
488
+ personal: {
489
+ firstName: "张",
490
+ lastName: "伟",
491
+ birthDate: null
492
+ },
493
+ contact: {
494
+ email: "zhangwei@example.com",
495
+ phone: "",
496
+ address: {
497
+ street: "",
498
+ city: "",
499
+ country: "CN"
500
+ }
501
+ },
502
+ preferences: {
503
+ newsletter: true,
504
+ theme: "light"
505
+ }
506
+ };
507
+
508
+ const nestedFields = [
509
+ {
510
+ name: "personal.firstName",
511
+ label: "名",
512
+ type: MetaEditorType.Text,
513
+ attrs: { placeholder: "请输入名" }
514
+ },
515
+ {
516
+ name: "personal.lastName",
517
+ label: "姓",
518
+ type: MetaEditorType.Text,
519
+ attrs: { placeholder: "请输入姓" }
520
+ },
521
+ {
522
+ name: "personal.birthDate",
523
+ label: "出生日期",
524
+ type: MetaEditorType.Date
525
+ },
526
+ {
527
+ name: "contact.email",
528
+ label: "电子邮件",
529
+ type: MetaEditorType.Text,
530
+ attrs: { type: "email", placeholder: "请输入电子邮件" }
531
+ },
532
+ {
533
+ name: "contact.phone",
534
+ label: "电话",
535
+ type: MetaEditorType.Text,
536
+ attrs: { placeholder: "请输入电话号码" }
537
+ },
538
+ {
539
+ name: "contact.address.street",
540
+ label: "街道地址",
541
+ type: MetaEditorType.Text,
542
+ attrs: { placeholder: "请输入街道地址" }
543
+ },
544
+ {
545
+ name: "contact.address.city",
546
+ label: "城市",
547
+ type: MetaEditorType.Text,
548
+ attrs: { placeholder: "请输入城市" }
549
+ },
550
+ {
551
+ name: "contact.address.country",
552
+ label: "国家",
553
+ type: MetaEditorType.Options,
554
+ attrs: {
555
+ options: [
556
+ { code: "CN", text: "中国" },
557
+ { code: "US", text: "美国" },
558
+ { code: "UK", text: "英国" },
559
+ { code: "DE", text: "德国" },
560
+ { code: "FR", text: "法国" }
561
+ ]
562
+ }
563
+ },
564
+ {
565
+ name: "preferences.newsletter",
566
+ label: "订阅时事通讯",
567
+ type: MetaEditorType.Boolean
568
+ },
569
+ {
570
+ name: "preferences.theme",
571
+ label: "首选主题",
572
+ type: MetaEditorType.Options,
573
+ attrs: {
574
+ options: [
575
+ { code: "light", text: "浅色" },
576
+ { code: "dark", text: "深色" }
577
+ ]
578
+ }
579
+ }
580
+ ];
581
+ </script>
582
+
583
+ <div class="nested-editor-demo">
584
+ <h3>嵌套对象编辑器</h3>
585
+ <PropertyEditor fields={nestedFields} bind:data={profileData} />
586
+
587
+ <div class="profile-summary">
588
+ <h4>个人资料摘要</h4>
589
+ <div class="section">
590
+ <h5>个人信息</h5>
591
+ <p>姓名:{profileData.personal.firstName} {profileData.personal.lastName}</p>
592
+ {#if profileData.personal.birthDate}
593
+ <p>出生日期:{profileData.personal.birthDate}</p>
594
+ {/if}
595
+ </div>
596
+
597
+ <div class="section">
598
+ <h5>联系信息</h5>
599
+ <p>电子邮件:{profileData.contact.email}</p>
600
+ {#if profileData.contact.phone}
601
+ <p>电话:{profileData.contact.phone}</p>
602
+ {/if}
603
+ <p>地址:{profileData.contact.address.street}, {profileData.contact.address.city}, {profileData.contact.address.country}</p>
604
+ </div>
605
+
606
+ <div class="section">
607
+ <h5>偏好设置</h5>
608
+ <p>时事通讯:{profileData.preferences.newsletter ? '已订阅' : '未订阅'}</p>
609
+ <p>主题:{profileData.preferences.theme}</p>
610
+ </div>
611
+ </div>
612
+ </div>
613
+
614
+ <style>
615
+ .nested-editor-demo {
616
+ max-width: 700px;
617
+ margin: 20px auto;
618
+ padding: 20px;
619
+ border: 1px solid #ddd;
620
+ border-radius: 8px;
621
+ }
622
+
623
+ .profile-summary {
624
+ margin-top: 20px;
625
+ padding: 16px;
626
+ background: #f8f9fa;
627
+ border-radius: 4px;
628
+ }
629
+
630
+ .profile-summary h4 {
631
+ margin: 0 0 16px 0;
632
+ }
633
+
634
+ .section {
635
+ margin-bottom: 16px;
636
+ padding-bottom: 12px;
637
+ border-bottom: 1px solid #dee2e6;
638
+ }
639
+
640
+ .section:last-child {
641
+ border-bottom: none;
642
+ margin-bottom: 0;
643
+ }
644
+
645
+ .section h5 {
646
+ margin: 0 0 8px 0;
647
+ color: #495057;
648
+ font-size: 14px;
649
+ font-weight: 600;
650
+ text-transform: uppercase;
651
+ }
652
+
653
+ .section p {
654
+ margin: 4px 0;
655
+ font-size: 14px;
656
+ }
657
+ </style>
658
+ ```
659
+
660
+ ### 动态表单构建器
661
+
662
+ ```svelte
663
+ <script>
664
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
665
+
666
+ let formData = {};
667
+ let formFields = [
668
+ {
669
+ name: "name",
670
+ label: "姓名",
671
+ type: MetaEditorType.Text,
672
+ attrs: { placeholder: "请输入您的姓名" }
673
+ }
674
+ ];
675
+
676
+ const availableFieldTypes = [
677
+ { type: MetaEditorType.Text, label: "文本输入" },
678
+ { type: MetaEditorType.Number, label: "数字输入" },
679
+ { type: MetaEditorType.Date, label: "日期选择器" },
680
+ { type: MetaEditorType.Boolean, label: "布尔值(是/否)" },
681
+ { type: MetaEditorType.Options, label: "下拉列表" }
682
+ ];
683
+
684
+ function addField() {
685
+ const fieldName = prompt("请输入字段名称:");
686
+ if (!fieldName) return;
687
+
688
+ const fieldLabel = prompt("请输入字段标签:");
689
+ if (!fieldLabel) return;
690
+
691
+ const fieldType = prompt(`请输入字段类型 (${availableFieldTypes.map(t => t.type).join(', ')}):`);
692
+ const selectedType = availableFieldTypes.find(t => t.type === fieldType);
693
+
694
+ if (!selectedType) {
695
+ alert("无效的字段类型");
696
+ return;
697
+ }
698
+
699
+ const newField = {
700
+ name: fieldName,
701
+ label: fieldLabel,
702
+ type: selectedType.type,
703
+ attrs: {}
704
+ };
705
+
706
+ // 为选项类型添加默认选项
707
+ if (selectedType.type === MetaEditorType.Options) {
708
+ newField.attrs.options = [
709
+ { code: "option1", text: "选项 1" },
710
+ { code: "option2", text: "选项 2" }
711
+ ];
712
+ }
713
+
714
+ formFields = [...formFields, newField];
715
+ }
716
+
717
+ function removeField(index) {
718
+ formFields = formFields.filter((_, i) => i !== index);
719
+ }
720
+
721
+ function exportFormData() {
722
+ const exportData = {
723
+ fields: formFields,
724
+ data: formData
725
+ };
726
+
727
+ const blob = new Blob([JSON.stringify(exportData, null, 2)], {
728
+ type: 'application/json'
729
+ });
730
+
731
+ const url = URL.createObjectURL(blob);
732
+ const a = document.createElement('a');
733
+ a.href = url;
734
+ a.download = 'form-data.json';
735
+ a.click();
736
+ URL.revokeObjectURL(url);
737
+ }
738
+ </script>
739
+
740
+ <div class="form-builder-demo">
741
+ <div class="builder-header">
742
+ <h3>动态表单构建器</h3>
743
+ <div class="builder-actions">
744
+ <button on:click={addField}>添加字段</button>
745
+ <button on:click={exportFormData}>导出数据</button>
746
+ </div>
747
+ </div>
748
+
749
+ <div class="builder-content">
750
+ <div class="field-list">
751
+ <h4>表单字段</h4>
752
+ {#each formFields as field, index}
753
+ <div class="field-item">
754
+ <span>{field.label} ({field.type})</span>
755
+ <button on:click={() => removeField(index)}>移除</button>
756
+ </div>
757
+ {/each}
758
+ </div>
759
+
760
+ <div class="form-preview">
761
+ <h4>表单预览</h4>
762
+ <PropertyEditor fields={formFields} bind:data={formData} />
763
+ </div>
764
+ </div>
765
+
766
+ <div class="form-data">
767
+ <h4>表单数据</h4>
768
+ <pre>{JSON.stringify(formData, null, 2)}</pre>
769
+ </div>
770
+ </div>
771
+
772
+ <style>
773
+ .form-builder-demo {
774
+ max-width: 900px;
775
+ margin: 20px auto;
776
+ padding: 20px;
777
+ border: 1px solid #ddd;
778
+ border-radius: 8px;
779
+ }
780
+
781
+ .builder-header {
782
+ display: flex;
783
+ justify-content: space-between;
784
+ align-items: center;
785
+ margin-bottom: 20px;
786
+ padding-bottom: 12px;
787
+ border-bottom: 1px solid #eee;
788
+ }
789
+
790
+ .builder-header h3 {
791
+ margin: 0;
792
+ }
793
+
794
+ .builder-actions {
795
+ display: flex;
796
+ gap: 8px;
797
+ }
798
+
799
+ .builder-actions button {
800
+ padding: 8px 16px;
801
+ border: 1px solid #007bff;
802
+ background: white;
803
+ color: #007bff;
804
+ border-radius: 4px;
805
+ cursor: pointer;
806
+ }
807
+
808
+ .builder-actions button:hover {
809
+ background: #007bff;
810
+ color: white;
811
+ }
812
+
813
+ .builder-content {
814
+ display: grid;
815
+ grid-template-columns: 1fr 2fr;
816
+ gap: 20px;
817
+ margin-bottom: 20px;
818
+ }
819
+
820
+ .field-list h4,
821
+ .form-preview h4 {
822
+ margin: 0 0 12px 0;
823
+ font-size: 16px;
824
+ }
825
+
826
+ .field-item {
827
+ display: flex;
828
+ justify-content: space-between;
829
+ align-items: center;
830
+ padding: 8px 12px;
831
+ background: #f8f9fa;
832
+ border-radius: 4px;
833
+ margin-bottom: 8px;
834
+ }
835
+
836
+ .field-item button {
837
+ padding: 4px 8px;
838
+ background: #dc3545;
839
+ color: white;
840
+ border: none;
841
+ border-radius: 4px;
842
+ cursor: pointer;
843
+ font-size: 12px;
844
+ }
845
+
846
+ .form-preview {
847
+ padding: 16px;
848
+ background: #f8f9fa;
849
+ border-radius: 4px;
850
+ }
851
+
852
+ .form-data {
853
+ padding: 16px;
854
+ background: #f8f9fa;
855
+ border-radius: 4px;
856
+ }
857
+
858
+ .form-data h4 {
859
+ margin: 0 0 12px 0;
860
+ }
861
+
862
+ .form-data pre {
863
+ margin: 0;
864
+ font-size: 12px;
865
+ overflow-x: auto;
866
+ max-height: 200px;
867
+ overflow-y: auto;
868
+ }
869
+ </style>
870
+ ```
871
+
872
+ ## 功能
873
+
874
+ - **多种字段类型**:支持文本、数字、日期、日期时间、选项、布尔和常用文本类型
875
+ - **嵌套对象支持**:使用点符号编辑深层对象属性
876
+ - **动态组件选择**:根据字段类型自动选择合适的组件
877
+ - **灵活属性**:向底层编辑器组件传递自定义属性
878
+ - **双向数据绑定**:与数据对象实时同步
879
+ - **国际化**:内置对标签的 i18n 支持
880
+ - **可扩展**:易于添加新字段类型和组件
881
+
882
+ ## 字段类型详情
883
+
884
+ ### 文本字段
885
+ - **类型**:`MetaEditorType.Text`
886
+ - **组件**:TextEditor
887
+ - **属性**:placeholder, maxLength, type 等
888
+
889
+ ### 常用文本字段
890
+ - **类型**:`MetaEditorType.CommonText`
891
+ - **组件**:PromptsTextEditor
892
+ - **属性**:words(建议词数组), placeholder
893
+
894
+ ### 数字字段
895
+ - **类型**:`MetaEditorType.Number`
896
+ - **组件**:NumberEditor
897
+ - **属性**:min, max, precision, step
898
+
899
+ ### 日期字段
900
+ - **类型**:`MetaEditorType.Date`
901
+ - **组件**:DatePicker
902
+ - **属性**:format, placeholder, readonly
903
+
904
+ ### 日期时间字段
905
+ - **类型**:`MetaEditorType.DateTime`
906
+ - **组件**:DateTimePicker
907
+ - **属性**:format, placeholder, readonly
908
+
909
+ ### 选项字段
910
+ - **类型**:`MetaEditorType.Options`
911
+ - **组件**:OptionsSelector
912
+ - **属性**:options(包含 code 和 text 的对象数组)
913
+
914
+ ### 布尔字段
915
+ - **类型**:`MetaEditorType.Boolean`
916
+ - **组件**:OptionsSelector(提供 true/false 选项)
917
+ - **属性**:自动配置布尔选项
918
+
919
+ ## 样式
920
+
921
+ PropertyEditor 组件采用类似表格的布局:
922
+
923
+ ```css
924
+ /* 属性编辑器容器 */
925
+ .uniface-property-editor {
926
+ /* 自定义样式 */
927
+ }
928
+
929
+ /* 表头样式 */
930
+ .table-header {
931
+ display: grid;
932
+ grid-template-columns: 1fr 2fr;
933
+ /* 表头样式 */
934
+ }
935
+
936
+ /* 内容区域 */
937
+ .table-content {
938
+ /* 内容样式 */
939
+ }
940
+
941
+ /* 单个属性行 */
942
+ .property_label,
943
+ .property_control {
944
+ /* 属性行样式 */
945
+ }
946
+ ```
947
+
948
+ ## 最佳实践
949
+
950
+ 1. **字段定义**:将字段定义保存在单独的常量中以便复用
951
+ 2. **验证**:在父组件中实现验证逻辑
952
+ 3. **嵌套对象**:对嵌套属性使用一致的点符号
953
+ 4. **类型安全**:使用 TypeScript 进行更好的类型检查
954
+ 5. **性能**:对大型字段数组考虑使用记忆化
955
+ 6. **可访问性**:确保适当的标签和 ARIA 属性
956
+
957
+ ## 浏览器支持
958
+
959
+ - 支持完整事件处理的现代浏览器
960
+ - 兼容 Svelte 5+
961
+ - 支持 Grid 布局
962
+ - 完整的 TypeScript 支持
963
+
964
+ ## 相关组件
965
+
966
+ - `TextEditor` - 文本输入组件
967
+ - `NumberEditor` - 数字输入组件
968
+ - `DatePicker` - 日期选择组件
969
+ - `OptionsSelect` - 下拉选择组件