@ticatec/uniface-element 0.2.4 → 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 (176) 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/README.md +596 -0
  70. package/dist/dialog/README_CN.md +596 -0
  71. package/dist/drawer/README.md +679 -1
  72. package/dist/drawer/README_CN.md +679 -0
  73. package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
  74. package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
  75. package/dist/group-box/group-check-box/README.md +749 -0
  76. package/dist/group-box/group-check-box/README_CN.md +750 -0
  77. package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
  78. package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
  79. package/dist/group-box/group-radio-box/README.md +920 -0
  80. package/dist/group-box/group-radio-box/README_CN.md +920 -0
  81. package/dist/image-files/README.md +1346 -0
  82. package/dist/image-files/README_CN.md +1346 -0
  83. package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
  84. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
  85. package/dist/lib/forwardAllEvents.d.ts +3 -0
  86. package/dist/lib/forwardAllEvents.js +24 -0
  87. package/dist/list-box/README.md +579 -0
  88. package/dist/list-box/README_CN.md +682 -0
  89. package/dist/lookup-editor/LookupEditor.svelte +15 -3
  90. package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
  91. package/dist/lookup-editor/README.md +684 -0
  92. package/dist/lookup-editor/README_CN.md +684 -0
  93. package/dist/memo-editor/MemoEditor.svelte +77 -27
  94. package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
  95. package/dist/memo-editor/README.md +819 -0
  96. package/dist/memo-editor/README_CN.md +819 -0
  97. package/dist/message-box/README.md +398 -0
  98. package/dist/message-box/README_CN.md +398 -0
  99. package/dist/number-editor/NumberEditor.svelte +2 -2
  100. package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
  101. package/dist/number-editor/README.md +353 -22
  102. package/dist/number-editor/README_CN.md +357 -0
  103. package/dist/number-range/README.md +443 -0
  104. package/dist/number-range/README_CN.md +443 -0
  105. package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
  106. package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
  107. package/dist/options-multi-select/README.md +480 -0
  108. package/dist/options-multi-select/README_CN.md +480 -0
  109. package/dist/options-select/OptionsSelect.svelte +36 -5
  110. package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
  111. package/dist/options-select/README.md +632 -0
  112. package/dist/options-select/README_CN.md +632 -0
  113. package/dist/page/README.md +605 -0
  114. package/dist/page/README_CN.md +605 -0
  115. package/dist/pagination/README.md +946 -0
  116. package/dist/pagination/README_CN.md +946 -0
  117. package/dist/pagination-panel/README.md +1075 -0
  118. package/dist/pagination-panel/README_CN.md +1075 -0
  119. package/dist/popup-hint/README.md +841 -0
  120. package/dist/popup-hint/README_CN.md +840 -0
  121. package/dist/progress-bar/README.md +242 -0
  122. package/dist/progress-bar/README_CN.md +242 -0
  123. package/dist/progress-step-bar/README.md +316 -0
  124. package/dist/progress-step-bar/README_CN.md +316 -0
  125. package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
  126. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
  127. package/dist/prompts-text-editor/README.md +329 -0
  128. package/dist/prompts-text-editor/README_CN.md +329 -0
  129. package/dist/property-editor/README.md +969 -0
  130. package/dist/property-editor/README_CN.md +969 -0
  131. package/dist/radio-button/README.md +372 -0
  132. package/dist/radio-button/README_CN.md +372 -0
  133. package/dist/radio-button/RadioButton.svelte +32 -3
  134. package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
  135. package/dist/search-box/README.md +425 -0
  136. package/dist/search-box/README_CN.md +424 -0
  137. package/dist/search-box/SearchBox.svelte +22 -6
  138. package/dist/search-box/SearchBox.svelte.d.ts +4 -1
  139. package/dist/tabs/README.md +919 -0
  140. package/dist/tabs/README_CN.md +920 -0
  141. package/dist/tag/README.md +922 -0
  142. package/dist/tag/README_CN.md +922 -0
  143. package/dist/text-editor/PasswordEditor.svelte +17 -2
  144. package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
  145. package/dist/text-editor/PasswordEditor_README.md +551 -0
  146. package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
  147. package/dist/text-editor/README.md +466 -0
  148. package/dist/text-editor/README_CN.md +466 -0
  149. package/dist/text-editor/TextEditor.svelte +51 -19
  150. package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
  151. package/dist/time-editor/README.md +498 -24
  152. package/dist/time-editor/README_CN.md +498 -0
  153. package/dist/time-editor/TimeEditor.svelte +7 -3
  154. package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
  155. package/dist/toast/README.md +667 -0
  156. package/dist/toast/README_CN.md +667 -0
  157. package/dist/transfer/README.md +795 -0
  158. package/dist/transfer/Transfer.svelte +6 -4
  159. package/dist/transfer/Transfer.svelte.d.ts +3 -1
  160. package/dist/tree-view/README.md +761 -0
  161. package/dist/tree-view/README_CN.md +761 -0
  162. package/dist/tree-view/TreeView.svelte +5 -3
  163. package/dist/tree-view/TreeView.svelte.d.ts +3 -1
  164. package/dist/unit-number-editor/README.md +546 -20
  165. package/dist/unit-number-editor/README_CN.md +525 -0
  166. package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
  167. package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
  168. package/docs/form-field/cn/README_CN.md +364 -0
  169. package/docs/form-field/en/README.md +364 -0
  170. package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
  171. package/docs/form-panel/flex-form/en/README.md +586 -0
  172. package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
  173. package/docs/form-panel/flex-row-form/en/README.md +787 -0
  174. package/docs/form-panel/grid-form/en/README.md +744 -0
  175. package/package.json +1 -1
  176. package/dist/drawer/README-CN.md +0 -1
@@ -0,0 +1,364 @@
1
+ # FormField 表单字段组件
2
+
3
+ 一个灵活的表单字段包装组件,为表单控件提供一致的标签、验证显示和布局选项。
4
+
5
+ ## 特性
6
+
7
+ - **灵活布局**: 支持垂直和水平标签排列
8
+ - **验证显示**: 内置错误消息显示,样式一致
9
+ - **必填字段指示器**: 必填字段的可视化星号指示器
10
+ - **可自定义样式**: 支持CSS变量和标签自定义样式
11
+ - **响应式设计**: 适配不同屏幕尺寸和表单布局
12
+ - **无障碍访问**: 为屏幕阅读器提供适当的语义结构
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ npm install @ticatec/uniface-element
18
+ ```
19
+
20
+ ## 使用方法
21
+
22
+ ### 基本用法
23
+
24
+ ```svelte
25
+ <script>
26
+ import FormField from '@ticatec/uniface-element/form-field';
27
+ import TextEditor from '@ticatec/uniface-element/text-editor';
28
+
29
+ let name = '';
30
+ </script>
31
+
32
+ <FormField label="姓名">
33
+ <TextEditor bind:value={name} placeholder="请输入姓名" />
34
+ </FormField>
35
+ ```
36
+
37
+ ### 必填字段
38
+
39
+ ```svelte
40
+ <FormField required label="邮箱">
41
+ <TextEditor bind:value={email} placeholder="请输入邮箱地址" />
42
+ </FormField>
43
+ ```
44
+
45
+ ### 带错误消息的字段
46
+
47
+ ```svelte
48
+ <script>
49
+ let email = '';
50
+ let emailError = '请输入有效的邮箱地址';
51
+ </script>
52
+
53
+ <FormField required label="邮箱" error={emailError}>
54
+ <TextEditor bind:value={email} placeholder="请输入邮箱地址" />
55
+ </FormField>
56
+ ```
57
+
58
+ ### 水平布局
59
+
60
+ ```svelte
61
+ <div class="field-layout-horizontal">
62
+ <FormField label="出生日期">
63
+ <DatePicker bind:value={dateOfBirth} />
64
+ </FormField>
65
+ </div>
66
+ ```
67
+
68
+ ### 自定义标签样式
69
+
70
+ ```svelte
71
+ <FormField
72
+ label="重要字段"
73
+ label$style="color: #2F54EB; font-weight: bold;"
74
+ >
75
+ <TextEditor bind:value={value} />
76
+ </FormField>
77
+ ```
78
+
79
+ ### 多行控件的顶部对齐标签
80
+
81
+ ```svelte
82
+ <FormField
83
+ label="描述"
84
+ label$alignment="top"
85
+ >
86
+ <MemoEditor bind:value={description} resize="vertical" />
87
+ </FormField>
88
+ ```
89
+
90
+ ## API 参考
91
+
92
+ ### 属性
93
+
94
+ | 属性 | 类型 | 默认值 | 描述 |
95
+ |------|------|---------|-------------|
96
+ | `label` | `string` | `"Label:"` | 表单字段的标签文本 |
97
+ | `style` | `string` | `''` | 表单字段容器的自定义CSS样式 |
98
+ | `label$style` | `string \| null` | `null` | 标签元素的自定义CSS样式 |
99
+ | `required` | `boolean` | `false` | 字段是否必填(显示星号指示器) |
100
+ | `error` | `string \| null` | `null` | 在字段下方显示的错误消息 |
101
+ | `labelSuffix` | `string` | `':'` | 附加到标签后的文本(如冒号) |
102
+ | `label$alignment` | `'center' \| 'top'` | `'center'` | 标签的垂直对齐方式 |
103
+ | `height` | `string` | `null` | 字段容器的自定义高度 |
104
+ | `class` | `string` | `''` | 表单字段的额外CSS类 |
105
+
106
+ ### 插槽
107
+
108
+ | 插槽 | 描述 |
109
+ |------|-------------|
110
+ | default | 表单控件内容(输入框、选择器等) |
111
+
112
+ ## 布局类
113
+
114
+ ### 水平布局
115
+
116
+ 在父容器中添加 `field-layout-horizontal` 类来水平排列表单字段:
117
+
118
+ ```svelte
119
+ <div class="field-layout-horizontal">
120
+ <FormField label="名">
121
+ <TextEditor bind:value={firstName} />
122
+ </FormField>
123
+ <FormField label="姓">
124
+ <TextEditor bind:value={lastName} />
125
+ </FormField>
126
+ </div>
127
+ ```
128
+
129
+ ## 样式
130
+
131
+ ### CSS 变量
132
+
133
+ FormField组件使用CSS变量进行一致的主题化:
134
+
135
+ ```css
136
+ :root {
137
+ --uniface-form-field-required-indicator-color: #ff3e00;
138
+ --uniface-form-field-label-color: #374151;
139
+ --uniface-form-field-invalid-message-color: #ff3e00;
140
+ --uniface-form-field-label-width: 120px;
141
+ --uniface-form-field-label-alignment: right;
142
+ --uniface-form-field-padding: 6px 4px;
143
+ --uniface-field-gap: 4px;
144
+ }
145
+ ```
146
+
147
+ ### 自定义样式
148
+
149
+ ```css
150
+ .custom-form-field {
151
+ --uniface-form-field-label-color: #2563eb;
152
+ --uniface-form-field-label-width: 150px;
153
+ }
154
+ ```
155
+
156
+ ## 示例
157
+
158
+ ### 完整表单示例
159
+
160
+ ```svelte
161
+ <script>
162
+ import FormField from '@ticatec/uniface-element/form-field';
163
+ import TextEditor from '@ticatec/uniface-element/text-editor';
164
+ import DatePicker from '@ticatec/uniface-element/date-picker';
165
+ import MemoEditor from '@ticatec/uniface-element/memo-editor';
166
+
167
+ let formData = {
168
+ name: '',
169
+ email: '',
170
+ dateOfBirth: null,
171
+ notes: ''
172
+ };
173
+
174
+ let errors = {};
175
+
176
+ function validateForm() {
177
+ errors = {};
178
+
179
+ if (!formData.name) {
180
+ errors.name = '姓名为必填项';
181
+ }
182
+
183
+ if (!formData.email) {
184
+ errors.email = '邮箱为必填项';
185
+ } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
186
+ errors.email = '请输入有效的邮箱地址';
187
+ }
188
+
189
+ return Object.keys(errors).length === 0;
190
+ }
191
+ </script>
192
+
193
+ <form on:submit|preventDefault={validateForm}>
194
+ <FormField required label="姓名" error={errors.name}>
195
+ <TextEditor
196
+ variant="filled"
197
+ bind:value={formData.name}
198
+ placeholder="请输入您的姓名"
199
+ />
200
+ </FormField>
201
+
202
+ <FormField required label="邮箱地址" error={errors.email}>
203
+ <TextEditor
204
+ variant="filled"
205
+ bind:value={formData.email}
206
+ placeholder="请输入邮箱地址"
207
+ />
208
+ </FormField>
209
+
210
+ <div class="field-layout-horizontal">
211
+ <FormField label="出生日期">
212
+ <DatePicker variant="filled" bind:value={formData.dateOfBirth} />
213
+ </FormField>
214
+ </div>
215
+
216
+ <FormField label="备注" label$alignment="top">
217
+ <MemoEditor
218
+ variant="filled"
219
+ bind:value={formData.notes}
220
+ resize="vertical"
221
+ placeholder="请输入备注信息..."
222
+ />
223
+ </FormField>
224
+
225
+ <button type="submit">提交</button>
226
+ </form>
227
+ ```
228
+
229
+ ### 响应式表单布局
230
+
231
+ ```svelte
232
+ <div class="responsive-form">
233
+ <div class="field-row">
234
+ <FormField label="名" error={errors.firstName}>
235
+ <TextEditor bind:value={formData.firstName} />
236
+ </FormField>
237
+
238
+ <FormField label="姓" error={errors.lastName}>
239
+ <TextEditor bind:value={formData.lastName} />
240
+ </FormField>
241
+ </div>
242
+
243
+ <FormField label="邮箱地址" error={errors.email}>
244
+ <TextEditor bind:value={formData.email} />
245
+ </FormField>
246
+ </div>
247
+
248
+ <style>
249
+ .responsive-form {
250
+ max-width: 600px;
251
+ margin: 0 auto;
252
+ }
253
+
254
+ .field-row {
255
+ display: grid;
256
+ grid-template-columns: 1fr 1fr;
257
+ gap: 16px;
258
+ }
259
+
260
+ @media (max-width: 768px) {
261
+ .field-row {
262
+ grid-template-columns: 1fr;
263
+ }
264
+ }
265
+ </style>
266
+ ```
267
+
268
+ ## 最佳实践
269
+
270
+ ### 1. 一致的标签格式
271
+
272
+ 在表单中使用一致的标签格式:
273
+
274
+ ```svelte
275
+ <FormField label="名" labelSuffix="">
276
+ <TextEditor bind:value={firstName} />
277
+ </FormField>
278
+
279
+ <FormField label="姓" labelSuffix="">
280
+ <TextEditor bind:value={lastName} />
281
+ </FormField>
282
+ ```
283
+
284
+ ### 2. 必填字段指示器
285
+
286
+ 始终用 `required` 属性标记必填字段:
287
+
288
+ ```svelte
289
+ <FormField required label="邮箱">
290
+ <TextEditor bind:value={email} />
291
+ </FormField>
292
+ ```
293
+
294
+ ### 3. 错误处理
295
+
296
+ 提供清晰、可操作的错误消息:
297
+
298
+ ```svelte
299
+ <FormField
300
+ required
301
+ label="密码"
302
+ error={passwordError || (password && password.length < 8 ? '密码长度至少8位' : null)}
303
+ >
304
+ <TextEditor type="password" bind:value={password} />
305
+ </FormField>
306
+ ```
307
+
308
+ ### 4. 无障碍访问
309
+
310
+ 确保表单的无障碍访问:
311
+
312
+ ```svelte
313
+ <FormField
314
+ required
315
+ label="用户名"
316
+ error={usernameError}
317
+ >
318
+ <TextEditor
319
+ bind:value={username}
320
+ input$aria-describedby={usernameError ? 'username-error' : undefined}
321
+ />
322
+ </FormField>
323
+ ```
324
+
325
+ ### 5. 布局考虑
326
+
327
+ 对相关字段使用水平布局:
328
+
329
+ ```svelte
330
+ <div class="field-layout-horizontal">
331
+ <FormField label="开始日期">
332
+ <DatePicker bind:value={startDate} />
333
+ </FormField>
334
+
335
+ <FormField label="结束日期">
336
+ <DatePicker bind:value={endDate} />
337
+ </FormField>
338
+ </div>
339
+ ```
340
+
341
+ ## 无障碍功能
342
+
343
+ - **语义化HTML**: 使用适当的表单字段结构
344
+ - **必填指示器**: 必填字段的可视化星号
345
+ - **错误关联**: 错误消息与字段正确关联
346
+ - **标签关联**: 标签与表单控件语义连接
347
+ - **键盘导航**: 支持标准表单导航模式
348
+
349
+ ## 浏览器支持
350
+
351
+ - **现代浏览器**: Chrome、Firefox、Safari、Edge(最新版本)
352
+ - **移动浏览器**: iOS Safari、Chrome Mobile、Firefox Mobile
353
+ - **CSS Grid支持**: 布局功能必需
354
+
355
+ ## 相关组件
356
+
357
+ - **TextEditor**: 单行文本输入组件
358
+ - **MemoEditor**: 多行文本区域组件
359
+ - **DatePicker**: 日期选择组件
360
+ - **DateTimePicker**: 日期时间选择组件
361
+
362
+ ## 许可证
363
+
364
+ MIT许可证 - 详情请参阅LICENSE文件。
@@ -0,0 +1,364 @@
1
+ # FormField
2
+
3
+ A flexible form field wrapper component that provides consistent labeling, validation display, and layout options for form controls.
4
+
5
+ ## Features
6
+
7
+ - **Flexible Layout**: Supports both vertical and horizontal label arrangements
8
+ - **Validation Display**: Built-in error message display with consistent styling
9
+ - **Required Field Indicator**: Visual asterisk indicator for required fields
10
+ - **Customizable Styling**: CSS variables and custom style support for labels
11
+ - **Responsive Design**: Adapts to different screen sizes and form layouts
12
+ - **Accessibility**: Proper semantic structure for screen readers
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @ticatec/uniface-element
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### Basic Usage
23
+
24
+ ```svelte
25
+ <script>
26
+ import FormField from '@ticatec/uniface-element/form-field';
27
+ import TextEditor from '@ticatec/uniface-element/text-editor';
28
+
29
+ let name = '';
30
+ </script>
31
+
32
+ <FormField label="Name">
33
+ <TextEditor bind:value={name} placeholder="Enter your name" />
34
+ </FormField>
35
+ ```
36
+
37
+ ### Required Field
38
+
39
+ ```svelte
40
+ <FormField required label="Email">
41
+ <TextEditor bind:value={email} placeholder="Enter your email" />
42
+ </FormField>
43
+ ```
44
+
45
+ ### Field with Error Message
46
+
47
+ ```svelte
48
+ <script>
49
+ let email = '';
50
+ let emailError = 'Please enter a valid email address';
51
+ </script>
52
+
53
+ <FormField required label="Email" error={emailError}>
54
+ <TextEditor bind:value={email} placeholder="Enter your email" />
55
+ </FormField>
56
+ ```
57
+
58
+ ### Horizontal Layout
59
+
60
+ ```svelte
61
+ <div class="field-layout-horizontal">
62
+ <FormField label="Date of Birth">
63
+ <DatePicker bind:value={dateOfBirth} />
64
+ </FormField>
65
+ </div>
66
+ ```
67
+
68
+ ### Custom Label Styling
69
+
70
+ ```svelte
71
+ <FormField
72
+ label="Important Field"
73
+ label$style="color: #2F54EB; font-weight: bold;"
74
+ >
75
+ <TextEditor bind:value={value} />
76
+ </FormField>
77
+ ```
78
+
79
+ ### Top-Aligned Label for Multi-line Controls
80
+
81
+ ```svelte
82
+ <FormField
83
+ label="Description"
84
+ label$alignment="top"
85
+ >
86
+ <MemoEditor bind:value={description} resize="vertical" />
87
+ </FormField>
88
+ ```
89
+
90
+ ## API Reference
91
+
92
+ ### Props
93
+
94
+ | Prop | Type | Default | Description |
95
+ |------|------|---------|-------------|
96
+ | `label` | `string` | `"Label:"` | The label text for the form field |
97
+ | `style` | `string` | `''` | Custom CSS styles for the form field container |
98
+ | `label$style` | `string \| null` | `null` | Custom CSS styles for the label element |
99
+ | `required` | `boolean` | `false` | Whether the field is required (shows asterisk indicator) |
100
+ | `error` | `string \| null` | `null` | Error message to display below the field |
101
+ | `labelSuffix` | `string` | `':'` | Text to append to the label (e.g., colon) |
102
+ | `label$alignment` | `'center' \| 'top'` | `'center'` | Vertical alignment of the label |
103
+ | `height` | `string` | `null` | Custom height for the field container |
104
+ | `class` | `string` | `''` | Additional CSS classes for the form field |
105
+
106
+ ### Slots
107
+
108
+ | Slot | Description |
109
+ |------|-------------|
110
+ | default | The form control content (input, select, etc.) |
111
+
112
+ ## Layout Classes
113
+
114
+ ### Horizontal Layout
115
+
116
+ Add the `field-layout-horizontal` class to a parent container to arrange form fields horizontally:
117
+
118
+ ```svelte
119
+ <div class="field-layout-horizontal">
120
+ <FormField label="First Name">
121
+ <TextEditor bind:value={firstName} />
122
+ </FormField>
123
+ <FormField label="Last Name">
124
+ <TextEditor bind:value={lastName} />
125
+ </FormField>
126
+ </div>
127
+ ```
128
+
129
+ ## Styling
130
+
131
+ ### CSS Variables
132
+
133
+ The FormField component uses CSS variables for consistent theming:
134
+
135
+ ```css
136
+ :root {
137
+ --uniface-form-field-required-indicator-color: #ff3e00;
138
+ --uniface-form-field-label-color: #374151;
139
+ --uniface-form-field-invalid-message-color: #ff3e00;
140
+ --uniface-form-field-label-width: 120px;
141
+ --uniface-form-field-label-alignment: right;
142
+ --uniface-form-field-padding: 6px 4px;
143
+ --uniface-field-gap: 4px;
144
+ }
145
+ ```
146
+
147
+ ### Custom Styling
148
+
149
+ ```css
150
+ .custom-form-field {
151
+ --uniface-form-field-label-color: #2563eb;
152
+ --uniface-form-field-label-width: 150px;
153
+ }
154
+ ```
155
+
156
+ ## Examples
157
+
158
+ ### Complete Form Example
159
+
160
+ ```svelte
161
+ <script>
162
+ import FormField from '@ticatec/uniface-element/form-field';
163
+ import TextEditor from '@ticatec/uniface-element/text-editor';
164
+ import DatePicker from '@ticatec/uniface-element/date-picker';
165
+ import MemoEditor from '@ticatec/uniface-element/memo-editor';
166
+
167
+ let formData = {
168
+ name: '',
169
+ email: '',
170
+ dateOfBirth: null,
171
+ notes: ''
172
+ };
173
+
174
+ let errors = {};
175
+
176
+ function validateForm() {
177
+ errors = {};
178
+
179
+ if (!formData.name) {
180
+ errors.name = 'Name is required';
181
+ }
182
+
183
+ if (!formData.email) {
184
+ errors.email = 'Email is required';
185
+ } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
186
+ errors.email = 'Please enter a valid email address';
187
+ }
188
+
189
+ return Object.keys(errors).length === 0;
190
+ }
191
+ </script>
192
+
193
+ <form on:submit|preventDefault={validateForm}>
194
+ <FormField required label="Full Name" error={errors.name}>
195
+ <TextEditor
196
+ variant="filled"
197
+ bind:value={formData.name}
198
+ placeholder="Enter your full name"
199
+ />
200
+ </FormField>
201
+
202
+ <FormField required label="Email Address" error={errors.email}>
203
+ <TextEditor
204
+ variant="filled"
205
+ bind:value={formData.email}
206
+ placeholder="Enter your email"
207
+ />
208
+ </FormField>
209
+
210
+ <div class="field-layout-horizontal">
211
+ <FormField label="Date of Birth">
212
+ <DatePicker variant="filled" bind:value={formData.dateOfBirth} />
213
+ </FormField>
214
+ </div>
215
+
216
+ <FormField label="Additional Notes" label$alignment="top">
217
+ <MemoEditor
218
+ variant="filled"
219
+ bind:value={formData.notes}
220
+ resize="vertical"
221
+ placeholder="Enter any additional notes..."
222
+ />
223
+ </FormField>
224
+
225
+ <button type="submit">Submit</button>
226
+ </form>
227
+ ```
228
+
229
+ ### Responsive Form Layout
230
+
231
+ ```svelte
232
+ <div class="responsive-form">
233
+ <div class="field-row">
234
+ <FormField label="First Name" error={errors.firstName}>
235
+ <TextEditor bind:value={formData.firstName} />
236
+ </FormField>
237
+
238
+ <FormField label="Last Name" error={errors.lastName}>
239
+ <TextEditor bind:value={formData.lastName} />
240
+ </FormField>
241
+ </div>
242
+
243
+ <FormField label="Email Address" error={errors.email}>
244
+ <TextEditor bind:value={formData.email} />
245
+ </FormField>
246
+ </div>
247
+
248
+ <style>
249
+ .responsive-form {
250
+ max-width: 600px;
251
+ margin: 0 auto;
252
+ }
253
+
254
+ .field-row {
255
+ display: grid;
256
+ grid-template-columns: 1fr 1fr;
257
+ gap: 16px;
258
+ }
259
+
260
+ @media (max-width: 768px) {
261
+ .field-row {
262
+ grid-template-columns: 1fr;
263
+ }
264
+ }
265
+ </style>
266
+ ```
267
+
268
+ ## Best Practices
269
+
270
+ ### 1. Consistent Labeling
271
+
272
+ Use consistent label formatting across your forms:
273
+
274
+ ```svelte
275
+ <FormField label="First Name" labelSuffix="">
276
+ <TextEditor bind:value={firstName} />
277
+ </FormField>
278
+
279
+ <FormField label="Last Name" labelSuffix="">
280
+ <TextEditor bind:value={lastName} />
281
+ </FormField>
282
+ ```
283
+
284
+ ### 2. Required Field Indicators
285
+
286
+ Always mark required fields with the `required` prop:
287
+
288
+ ```svelte
289
+ <FormField required label="Email">
290
+ <TextEditor bind:value={email} />
291
+ </FormField>
292
+ ```
293
+
294
+ ### 3. Error Handling
295
+
296
+ Provide clear, actionable error messages:
297
+
298
+ ```svelte
299
+ <FormField
300
+ required
301
+ label="Password"
302
+ error={passwordError || (password && password.length < 8 ? 'Password must be at least 8 characters' : null)}
303
+ >
304
+ <TextEditor type="password" bind:value={password} />
305
+ </FormField>
306
+ ```
307
+
308
+ ### 4. Accessibility
309
+
310
+ Ensure proper form accessibility:
311
+
312
+ ```svelte
313
+ <FormField
314
+ required
315
+ label="Username"
316
+ error={usernameError}
317
+ >
318
+ <TextEditor
319
+ bind:value={username}
320
+ input$aria-describedby={usernameError ? 'username-error' : undefined}
321
+ />
322
+ </FormField>
323
+ ```
324
+
325
+ ### 5. Layout Considerations
326
+
327
+ Use horizontal layout for related fields:
328
+
329
+ ```svelte
330
+ <div class="field-layout-horizontal">
331
+ <FormField label="Start Date">
332
+ <DatePicker bind:value={startDate} />
333
+ </FormField>
334
+
335
+ <FormField label="End Date">
336
+ <DatePicker bind:value={endDate} />
337
+ </FormField>
338
+ </div>
339
+ ```
340
+
341
+ ## Accessibility Features
342
+
343
+ - **Semantic HTML**: Uses proper form field structure
344
+ - **Required Indicators**: Visual asterisk for required fields
345
+ - **Error Association**: Error messages are properly associated with fields
346
+ - **Label Association**: Labels are semantically connected to form controls
347
+ - **Keyboard Navigation**: Supports standard form navigation patterns
348
+
349
+ ## Browser Support
350
+
351
+ - **Modern Browsers**: Chrome, Firefox, Safari, Edge (latest versions)
352
+ - **Mobile Browsers**: iOS Safari, Chrome Mobile, Firefox Mobile
353
+ - **CSS Grid Support**: Required for layout functionality
354
+
355
+ ## Related Components
356
+
357
+ - **TextEditor**: Single-line text input component
358
+ - **MemoEditor**: Multi-line text area component
359
+ - **DatePicker**: Date selection component
360
+ - **DateTimePicker**: Date and time selection component
361
+
362
+ ## License
363
+
364
+ MIT License - see LICENSE file for details.