@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,787 @@
1
+ # FlexRowForm (FormContainer) 弹性行表单
2
+
3
+ 基于结构化行的表单布局系统,提供明确的行和单元格组织,实现精确的表单布局和12列网格支持。
4
+
5
+ ## 特性
6
+
7
+ - **明确的行结构**: 手动行定义,实现精确的布局控制
8
+ - **12列网格系统**: 单元格可跨越1-12列,使用百分比宽度
9
+ - **布局模式**: 支持垂直和水平字段布局
10
+ - **结构化组织**: 行和单元格之间的清晰分离
11
+ - **FormField集成**: 与FormField组件无缝协作
12
+ - **响应式设计**: 灵活的网格系统,适应不同屏幕尺寸
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ npm install @ticatec/uniface-element
18
+ ```
19
+
20
+ ## 使用方法
21
+
22
+ ### 基本用法
23
+
24
+ ```svelte
25
+ <script>
26
+ import FormContainer, { Row, Cell } from '@ticatec/uniface-element/flex-row-form';
27
+ import FormField from '@ticatec/uniface-element/form-field';
28
+ import TextEditor from '@ticatec/uniface-element/text-editor';
29
+
30
+ let formData = {};
31
+ </script>
32
+
33
+ <FormContainer>
34
+ <Row>
35
+ <Cell span={6}>
36
+ <FormField label="名" required>
37
+ <TextEditor bind:value={formData.firstName} variant="filled" />
38
+ </FormField>
39
+ </Cell>
40
+
41
+ <Cell span={6}>
42
+ <FormField label="姓" required>
43
+ <TextEditor bind:value={formData.lastName} variant="filled" />
44
+ </FormField>
45
+ </Cell>
46
+ </Row>
47
+
48
+ <Row>
49
+ <Cell span={12}>
50
+ <FormField label="邮箱地址">
51
+ <TextEditor bind:value={formData.email} variant="filled" />
52
+ </FormField>
53
+ </Cell>
54
+ </Row>
55
+ </FormContainer>
56
+ ```
57
+
58
+ ### 完整表单示例
59
+
60
+ ```svelte
61
+ <script>
62
+ import FormContainer, { Row, Cell } from '@ticatec/uniface-element/flex-row-form';
63
+ import FormField from '@ticatec/uniface-element/form-field';
64
+ import TextEditor from '@ticatec/uniface-element/text-editor';
65
+ import DatePicker from '@ticatec/uniface-element/date-picker';
66
+ import OptionsSelect from '@ticatec/uniface-element/options-select';
67
+ import MemoEditor from '@ticatec/uniface-element/memo-editor';
68
+
69
+ let formData = {};
70
+ let errors = {};
71
+
72
+ const genderOptions = [
73
+ { code: 'F', text: '女' },
74
+ { code: 'M', text: '男' }
75
+ ];
76
+
77
+ const countries = [
78
+ { code: 'AU', text: '澳大利亚' },
79
+ { code: 'NZ', text: '新西兰' },
80
+ { code: 'US', text: '美国' }
81
+ ];
82
+ </script>
83
+
84
+ <FormContainer style="max-width: 800px; margin: 0 auto; border: 1px solid #e1e1e1; padding: 20px;">
85
+ <Row>
86
+ <Cell span={4}>
87
+ <FormField label="姓名" required error={errors.name}>
88
+ <TextEditor
89
+ bind:value={formData.name}
90
+ variant="filled"
91
+ placeholder="请输入姓名"
92
+ input$maxLength={50}
93
+ />
94
+ </FormField>
95
+ </Cell>
96
+
97
+ <Cell span={4}>
98
+ <FormField label="出生日期" required error={errors.dob}>
99
+ <DatePicker
100
+ bind:value={formData.dob}
101
+ variant="filled"
102
+ max={new Date()}
103
+ />
104
+ </FormField>
105
+ </Cell>
106
+
107
+ <Cell span={4}>
108
+ <FormField label="性别" required error={errors.gender}>
109
+ <OptionsSelect
110
+ bind:value={formData.gender}
111
+ variant="filled"
112
+ options={genderOptions}
113
+ />
114
+ </FormField>
115
+ </Cell>
116
+ </Row>
117
+
118
+ <Row>
119
+ <Cell span={6}>
120
+ <FormField label="国籍" error={errors.nationality}>
121
+ <OptionsSelect
122
+ bind:value={formData.nationality}
123
+ variant="filled"
124
+ options={countries}
125
+ />
126
+ </FormField>
127
+ </Cell>
128
+
129
+ <Cell span={6}>
130
+ <FormField label="电话号码" error={errors.phone}>
131
+ <TextEditor
132
+ bind:value={formData.phone}
133
+ variant="filled"
134
+ placeholder="请输入电话号码"
135
+ />
136
+ </FormField>
137
+ </Cell>
138
+ </Row>
139
+
140
+ <Row>
141
+ <Cell span={12}>
142
+ <FormField label="备注" error={errors.notes}>
143
+ <MemoEditor
144
+ bind:value={formData.notes}
145
+ variant="filled"
146
+ input$rows={4}
147
+ input$maxLength={300}
148
+ showIndicator
149
+ />
150
+ </FormField>
151
+ </Cell>
152
+ </Row>
153
+ </FormContainer>
154
+ ```
155
+
156
+ ### 水平布局
157
+
158
+ ```svelte
159
+ <FormContainer fieldLayout="horizontal">
160
+ <Row>
161
+ <Cell span={6}>
162
+ <FormField label="开始日期">
163
+ <DatePicker bind:value={startDate} variant="filled" />
164
+ </FormField>
165
+ </Cell>
166
+
167
+ <Cell span={6}>
168
+ <FormField label="结束日期">
169
+ <DatePicker bind:value={endDate} variant="filled" />
170
+ </FormField>
171
+ </Cell>
172
+ </Row>
173
+
174
+ <Row>
175
+ <Cell span={12}>
176
+ <FormField label="描述" label$alignment="top">
177
+ <MemoEditor bind:value={description} variant="filled" />
178
+ </FormField>
179
+ </Cell>
180
+ </Row>
181
+ </FormContainer>
182
+ ```
183
+
184
+ ## API 参考
185
+
186
+ ### FormContainer
187
+
188
+ 结构化行表单布局的主容器组件。
189
+
190
+ #### 属性
191
+
192
+ | 属性 | 类型 | 默认值 | 描述 |
193
+ |------|------|---------|-------------|
194
+ | `style` | `string` | `''` | 表单容器的自定义CSS样式 |
195
+ | `fieldLayout` | `'vertical' \| 'horizontal'` | `'vertical'` | 表单字段的布局模式 |
196
+ | `class` | `string` | `''` | 容器的额外CSS类 |
197
+
198
+ #### 插槽
199
+
200
+ | 插槽 | 描述 |
201
+ |------|-------------|
202
+ | default | 包含Row组件的表单内容 |
203
+
204
+ ### Row
205
+
206
+ 用于在水平行中组织单元格的容器组件。
207
+
208
+ #### 属性
209
+
210
+ | 属性 | 类型 | 默认值 | 描述 |
211
+ |------|------|---------|-------------|
212
+ | `style` | `string` | `''` | 行的自定义CSS样式 |
213
+ | `class` | `string` | `''` | 行的额外CSS类 |
214
+
215
+ #### 插槽
216
+
217
+ | 插槽 | 描述 |
218
+ |------|-------------|
219
+ | default | 行的Cell组件和内容 |
220
+
221
+ ### Cell
222
+
223
+ 在行内跨越指定列数的网格单元格组件。
224
+
225
+ #### 属性
226
+
227
+ | 属性 | 类型 | 默认值 | 描述 |
228
+ |------|------|---------|-------------|
229
+ | `span` | `number` | `1` | 跨越的列数(1-12) |
230
+ | `style` | `string` | `''` | 单元格的自定义CSS样式 |
231
+ | `class` | `string` | `''` | 单元格的额外CSS类 |
232
+
233
+ #### 插槽
234
+
235
+ | 插槽 | 描述 |
236
+ |------|-------------|
237
+ | default | 单元格的内容(通常是FormField组件) |
238
+
239
+ ## 网格系统
240
+
241
+ FlexRowForm使用12列网格系统,每个Cell可以跨越1-12列:
242
+
243
+ - **span={1}**: 8.33% 宽度 (1/12)
244
+ - **span={2}**: 16.67% 宽度 (2/12)
245
+ - **span={3}**: 25% 宽度 (3/12)
246
+ - **span={4}**: 33.33% 宽度 (4/12)
247
+ - **span={6}**: 50% 宽度 (6/12)
248
+ - **span={8}**: 66.67% 宽度 (8/12)
249
+ - **span={12}**: 100% 宽度 (12/12)
250
+
251
+ ## 布局示例
252
+
253
+ ### 多行复杂表单
254
+
255
+ ```svelte
256
+ <FormContainer>
257
+ <!-- 标题行 -->
258
+ <Row>
259
+ <Cell span={12}>
260
+ <FormField label="项目标题" required>
261
+ <TextEditor bind:value={project.title} variant="filled" />
262
+ </FormField>
263
+ </Cell>
264
+ </Row>
265
+
266
+ <!-- 详情行 -->
267
+ <Row>
268
+ <Cell span={4}>
269
+ <FormField label="开始日期" required>
270
+ <DatePicker bind:value={project.startDate} variant="filled" />
271
+ </FormField>
272
+ </Cell>
273
+
274
+ <Cell span={4}>
275
+ <FormField label="结束日期">
276
+ <DatePicker bind:value={project.endDate} variant="filled" />
277
+ </FormField>
278
+ </Cell>
279
+
280
+ <Cell span={4}>
281
+ <FormField label="优先级">
282
+ <OptionsSelect bind:value={project.priority} options={priorities} />
283
+ </FormField>
284
+ </Cell>
285
+ </Row>
286
+
287
+ <!-- 联系信息行 -->
288
+ <Row>
289
+ <Cell span={6}>
290
+ <FormField label="项目经理">
291
+ <TextEditor bind:value={project.manager} variant="filled" />
292
+ </FormField>
293
+ </Cell>
294
+
295
+ <Cell span={6}>
296
+ <FormField label="联系邮箱">
297
+ <TextEditor bind:value={project.email} variant="filled" />
298
+ </FormField>
299
+ </Cell>
300
+ </Row>
301
+
302
+ <!-- 描述行 -->
303
+ <Row>
304
+ <Cell span={12}>
305
+ <FormField label="项目描述" label$alignment="top">
306
+ <MemoEditor bind:value={project.description} variant="filled" />
307
+ </FormField>
308
+ </Cell>
309
+ </Row>
310
+ </FormContainer>
311
+ ```
312
+
313
+ ### 不对称布局
314
+
315
+ ```svelte
316
+ <FormContainer>
317
+ <Row>
318
+ <Cell span={8}>
319
+ <FormField label="主要信息">
320
+ <TextEditor bind:value={mainInfo} variant="filled" />
321
+ </FormField>
322
+ </Cell>
323
+
324
+ <Cell span={4}>
325
+ <FormField label="代码">
326
+ <TextEditor bind:value={code} variant="filled" />
327
+ </FormField>
328
+ </Cell>
329
+ </Row>
330
+
331
+ <Row>
332
+ <Cell span={3}>
333
+ <FormField label="类型">
334
+ <OptionsSelect bind:value={type} options={typeOptions} />
335
+ </FormField>
336
+ </Cell>
337
+
338
+ <Cell span={3}>
339
+ <FormField label="状态">
340
+ <OptionsSelect bind:value={status} options={statusOptions} />
341
+ </FormField>
342
+ </Cell>
343
+
344
+ <Cell span={6}>
345
+ <FormField label="参考">
346
+ <TextEditor bind:value={reference} variant="filled" />
347
+ </FormField>
348
+ </Cell>
349
+ </Row>
350
+ </FormContainer>
351
+ ```
352
+
353
+ ### 表单分区
354
+
355
+ ```svelte
356
+ <FormContainer>
357
+ <!-- 个人信息分区 -->
358
+ <Row>
359
+ <Cell span={12}>
360
+ <h3>个人信息</h3>
361
+ </Cell>
362
+ </Row>
363
+
364
+ <Row>
365
+ <Cell span={6}>
366
+ <FormField label="名" required>
367
+ <TextEditor bind:value={personal.firstName} variant="filled" />
368
+ </FormField>
369
+ </Cell>
370
+
371
+ <Cell span={6}>
372
+ <FormField label="姓" required>
373
+ <TextEditor bind:value={personal.lastName} variant="filled" />
374
+ </FormField>
375
+ </Cell>
376
+ </Row>
377
+
378
+ <!-- 联系信息分区 -->
379
+ <Row>
380
+ <Cell span={12}>
381
+ <h3>联系信息</h3>
382
+ </Cell>
383
+ </Row>
384
+
385
+ <Row>
386
+ <Cell span={8}>
387
+ <FormField label="邮箱地址" required>
388
+ <TextEditor bind:value={contact.email} variant="filled" />
389
+ </FormField>
390
+ </Cell>
391
+
392
+ <Cell span={4}>
393
+ <FormField label="电话">
394
+ <TextEditor bind:value={contact.phone} variant="filled" />
395
+ </FormField>
396
+ </Cell>
397
+ </Row>
398
+ </FormContainer>
399
+ ```
400
+
401
+ ## 验证和错误处理
402
+
403
+ ```svelte
404
+ <script>
405
+ let formData = {
406
+ name: '',
407
+ email: '',
408
+ phone: '',
409
+ notes: ''
410
+ };
411
+
412
+ let errors = {};
413
+
414
+ function validateForm() {
415
+ errors = {};
416
+
417
+ if (!formData.name?.trim()) {
418
+ errors.name = '姓名为必填项';
419
+ }
420
+
421
+ if (!formData.email?.trim()) {
422
+ errors.email = '邮箱为必填项';
423
+ } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
424
+ errors.email = '请输入有效的邮箱地址';
425
+ }
426
+
427
+ if (formData.phone && !/^\+?[\d\s\-()]+$/.test(formData.phone)) {
428
+ errors.phone = '请输入有效的电话号码';
429
+ }
430
+
431
+ return Object.keys(errors).length === 0;
432
+ }
433
+
434
+ function handleSubmit() {
435
+ if (validateForm()) {
436
+ console.log('表单提交:', formData);
437
+ }
438
+ }
439
+ </script>
440
+
441
+ <FormContainer>
442
+ <Row>
443
+ <Cell span={6}>
444
+ <FormField label="姓名" required error={errors.name}>
445
+ <TextEditor
446
+ bind:value={formData.name}
447
+ variant="filled"
448
+ placeholder="请输入您的姓名"
449
+ />
450
+ </FormField>
451
+ </Cell>
452
+
453
+ <Cell span={6}>
454
+ <FormField label="电话号码" error={errors.phone}>
455
+ <TextEditor
456
+ bind:value={formData.phone}
457
+ variant="filled"
458
+ placeholder="请输入电话号码"
459
+ />
460
+ </FormField>
461
+ </Cell>
462
+ </Row>
463
+
464
+ <Row>
465
+ <Cell span={12}>
466
+ <FormField label="邮箱地址" required error={errors.email}>
467
+ <TextEditor
468
+ bind:value={formData.email}
469
+ variant="filled"
470
+ placeholder="请输入邮箱地址"
471
+ />
472
+ </FormField>
473
+ </Cell>
474
+ </Row>
475
+
476
+ <Row>
477
+ <Cell span={12}>
478
+ <FormField label="备注">
479
+ <MemoEditor
480
+ bind:value={formData.notes}
481
+ variant="filled"
482
+ placeholder="请输入备注信息..."
483
+ />
484
+ </FormField>
485
+ </Cell>
486
+ </Row>
487
+
488
+ <Row>
489
+ <Cell span={12} style="text-align: right; margin-top: 20px;">
490
+ <button type="button" on:click={handleSubmit}>
491
+ 提交表单
492
+ </button>
493
+ </Cell>
494
+ </Row>
495
+ </FormContainer>
496
+ ```
497
+
498
+ ## 样式
499
+
500
+ ### 自定义表单样式
501
+
502
+ ```svelte
503
+ <FormContainer
504
+ style="
505
+ max-width: 900px;
506
+ margin: 2rem auto;
507
+ padding: 2rem;
508
+ border: 1px solid #e2e8f0;
509
+ border-radius: 8px;
510
+ background: #ffffff;
511
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
512
+ "
513
+ >
514
+ <Row style="margin-bottom: 1.5rem;">
515
+ <Cell span={12}>
516
+ <h2 style="margin: 0; color: #2d3748;">表单标题</h2>
517
+ </Cell>
518
+ </Row>
519
+
520
+ <!-- 表单内容 -->
521
+ </FormContainer>
522
+ ```
523
+
524
+ ### CSS 类
525
+
526
+ ```css
527
+ .custom-form-container {
528
+ max-width: 800px;
529
+ margin: 0 auto;
530
+ padding: 2rem;
531
+ background: white;
532
+ border-radius: 8px;
533
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
534
+ }
535
+
536
+ .custom-form-container .form-row {
537
+ margin-bottom: 1.5rem;
538
+ }
539
+
540
+ .custom-form-container .form-row:last-child {
541
+ margin-bottom: 0;
542
+ }
543
+
544
+ .custom-form-container .form-cell {
545
+ padding: 0 0.5rem;
546
+ }
547
+ ```
548
+
549
+ ## 响应式设计
550
+
551
+ ```svelte
552
+ <FormContainer class="responsive-form">
553
+ <Row>
554
+ <Cell span={4}>
555
+ <FormField label="字段1">
556
+ <TextEditor bind:value={field1} />
557
+ </FormField>
558
+ </Cell>
559
+
560
+ <Cell span={4}>
561
+ <FormField label="字段2">
562
+ <TextEditor bind:value={field2} />
563
+ </FormField>
564
+ </Cell>
565
+
566
+ <Cell span={4}>
567
+ <FormField label="字段3">
568
+ <TextEditor bind:value={field3} />
569
+ </FormField>
570
+ </Cell>
571
+ </Row>
572
+ </FormContainer>
573
+
574
+ <style>
575
+ @media (max-width: 768px) {
576
+ :global(.responsive-form .form-cell) {
577
+ width: 100% !important;
578
+ margin-bottom: 1rem;
579
+ }
580
+ }
581
+
582
+ @media (max-width: 480px) {
583
+ :global(.responsive-form) {
584
+ padding: 1rem;
585
+ }
586
+ }
587
+ </style>
588
+ ```
589
+
590
+ ## 最佳实践
591
+
592
+ ### 1. 逻辑行组织
593
+
594
+ 在同一行中分组相关字段:
595
+
596
+ ```svelte
597
+ <FormContainer>
598
+ <!-- 一行中的个人详情 -->
599
+ <Row>
600
+ <Cell span={4}>
601
+ <FormField label="名" required>
602
+ <TextEditor bind:value={firstName} />
603
+ </FormField>
604
+ </Cell>
605
+
606
+ <Cell span={4}>
607
+ <FormField label="姓" required>
608
+ <TextEditor bind:value={lastName} />
609
+ </FormField>
610
+ </Cell>
611
+
612
+ <Cell span={4}>
613
+ <FormField label="出生日期">
614
+ <DatePicker bind:value={dateOfBirth} />
615
+ </FormField>
616
+ </Cell>
617
+ </Row>
618
+
619
+ <!-- 另一行中的联系详情 -->
620
+ <Row>
621
+ <Cell span={8}>
622
+ <FormField label="邮箱地址" required>
623
+ <TextEditor bind:value={email} />
624
+ </FormField>
625
+ </Cell>
626
+
627
+ <Cell span={4}>
628
+ <FormField label="电话">
629
+ <TextEditor bind:value={phone} />
630
+ </FormField>
631
+ </Cell>
632
+ </Row>
633
+ </FormContainer>
634
+ ```
635
+
636
+ ### 2. 一致的间距
637
+
638
+ 对相似字段类型使用一致的单元格跨度:
639
+
640
+ ```svelte
641
+ <FormContainer>
642
+ <Row>
643
+ <!-- 标准文本字段:各6列 -->
644
+ <Cell span={6}>
645
+ <FormField label="用户名" required>
646
+ <TextEditor bind:value={username} />
647
+ </FormField>
648
+ </Cell>
649
+
650
+ <Cell span={6}>
651
+ <FormField label="部门">
652
+ <TextEditor bind:value={department} />
653
+ </FormField>
654
+ </Cell>
655
+ </Row>
656
+
657
+ <Row>
658
+ <!-- 重要字段:全宽 -->
659
+ <Cell span={12}>
660
+ <FormField label="描述">
661
+ <MemoEditor bind:value={description} />
662
+ </FormField>
663
+ </Cell>
664
+ </Row>
665
+ </FormContainer>
666
+ ```
667
+
668
+ ### 3. 表单分区
669
+
670
+ 使用行创建清晰的表单分区:
671
+
672
+ ```svelte
673
+ <FormContainer>
674
+ <!-- 分区标题 -->
675
+ <Row>
676
+ <Cell span={12}>
677
+ <h3 style="border-bottom: 1px solid #e2e8f0; padding-bottom: 0.5rem;">
678
+ 账户信息
679
+ </h3>
680
+ </Cell>
681
+ </Row>
682
+
683
+ <!-- 分区字段 -->
684
+ <Row>
685
+ <Cell span={6}>
686
+ <FormField label="用户名" required>
687
+ <TextEditor bind:value={username} />
688
+ </FormField>
689
+ </Cell>
690
+
691
+ <Cell span={6}>
692
+ <FormField label="邮箱" required>
693
+ <TextEditor bind:value={email} />
694
+ </FormField>
695
+ </Cell>
696
+ </Row>
697
+ </FormContainer>
698
+ ```
699
+
700
+ ## 与FlexForm的比较
701
+
702
+ | 特性 | FlexRowForm | FlexForm |
703
+ |---------|-------------|----------|
704
+ | 结构 | 明确的行和单元格 | 自动换行 |
705
+ | 布局控制 | 高精度 | 自动流动 |
706
+ | 行管理 | 手动换行 | 自动换行 |
707
+ | 使用场景 | 复杂结构化表单 | 简单流动表单 |
708
+ | 复杂度 | 较高 | 较低 |
709
+
710
+ ## 与其他组件集成
711
+
712
+ ### 动态内容
713
+
714
+ ```svelte
715
+ <script>
716
+ let items = [
717
+ { id: 1, name: '', value: '' },
718
+ { id: 2, name: '', value: '' }
719
+ ];
720
+
721
+ function addItem() {
722
+ items = [...items, { id: Date.now(), name: '', value: '' }];
723
+ }
724
+
725
+ function removeItem(id) {
726
+ items = items.filter(item => item.id !== id);
727
+ }
728
+ </script>
729
+
730
+ <FormContainer>
731
+ {#each items as item, index}
732
+ <Row>
733
+ <Cell span={5}>
734
+ <FormField label="名称">
735
+ <TextEditor bind:value={item.name} variant="filled" />
736
+ </FormField>
737
+ </Cell>
738
+
739
+ <Cell span={5}>
740
+ <FormField label="值">
741
+ <TextEditor bind:value={item.value} variant="filled" />
742
+ </FormField>
743
+ </Cell>
744
+
745
+ <Cell span={2} style="display: flex; align-items: end;">
746
+ <button type="button" on:click={() => removeItem(item.id)}>
747
+ 删除
748
+ </button>
749
+ </Cell>
750
+ </Row>
751
+ {/each}
752
+
753
+ <Row>
754
+ <Cell span={12} style="text-align: center; margin-top: 1rem;">
755
+ <button type="button" on:click={addItem}>
756
+ 添加项目
757
+ </button>
758
+ </Cell>
759
+ </Row>
760
+ </FormContainer>
761
+ ```
762
+
763
+ ## 无障碍功能
764
+
765
+ - **语义结构**: 具有逻辑tab顺序的正确表单组织
766
+ - **键盘导航**: 标准表单导航模式
767
+ - **屏幕阅读器支持**: 清晰的行和单元格结构
768
+ - **错误关联**: 错误消息与字段的正确关联
769
+ - **焦点管理**: 通过行和单元格的逻辑焦点流
770
+
771
+ ## 浏览器支持
772
+
773
+ - **现代浏览器**: Chrome、Firefox、Safari、Edge(最新版本)
774
+ - **移动浏览器**: iOS Safari、Chrome Mobile、Firefox Mobile
775
+ - **CSS Flexbox**: 布局功能必需
776
+
777
+ ## 相关组件
778
+
779
+ - **FormField**: 带标签和验证的表单字段包装器
780
+ - **FlexForm**: 替代的自动换行表单布局
781
+ - **TextEditor**: 单行文本输入组件
782
+ - **DatePicker**: 日期选择组件
783
+ - **OptionsSelect**: 下拉选择组件
784
+
785
+ ## 许可证
786
+
787
+ MIT许可证 - 详情请参阅LICENSE文件。