@ticatec/uniface-element 0.2.0 → 0.2.2

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 (209) hide show
  1. package/README.md +320 -1
  2. package/README_CN.md +392 -0
  3. package/dist/accordion/Accordion.svelte +1 -1
  4. package/dist/action-bar/ActionBar.svelte +7 -1
  5. package/dist/attachment-files/FileRender.svelte +1 -1
  6. package/dist/attachment-files/FileUploadBar.svelte +7 -6
  7. package/dist/attachment-files/FileUploadPanel.svelte +2 -2
  8. package/dist/base-calendar/DateContext.js +5 -4
  9. package/dist/base-calendar/YearPickupPanel.svelte +4 -4
  10. package/dist/card/Card.svelte +1 -1
  11. package/dist/card/Card.svelte.d.ts +1 -1
  12. package/dist/cascade-options-select/CascadeOptionSelect.svelte +2 -3
  13. package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +46 -1
  14. package/dist/cascade-options-select/CascadePanel.svelte +1 -1
  15. package/dist/checkbox/CheckBox.svelte +1 -1
  16. package/dist/color-picker/ColorPicker.svelte +9 -9
  17. package/dist/color-picker/ColorPicker.svelte.d.ts +0 -2
  18. package/dist/color-picker/ColorPickerPanel.svelte +11 -15
  19. package/dist/color-picker/ColorPickerPanel.svelte.d.ts +1 -1
  20. package/dist/common/CommonPicker.svelte +2 -2
  21. package/dist/common/CommonPicker.svelte.d.ts +1 -1
  22. package/dist/common/MouseClickHandler.d.ts +1 -1
  23. package/dist/common/Popover.svelte +28 -6
  24. package/dist/common/Popover.svelte.d.ts +9 -3
  25. package/dist/common/uniface-utils.js +6 -4
  26. package/dist/common-editor/CommonEditor.svelte +1 -1
  27. package/dist/common-editor/CommonEditor.svelte.d.ts +1 -1
  28. package/dist/common-editor/NumberInput.svelte +1 -1
  29. package/dist/common-editor/NumberInput.svelte.d.ts +1 -1
  30. package/dist/concise-data-table/ConciseListTable.svelte +7 -2
  31. package/dist/concise-data-table/ConciseListTable.svelte.d.ts +1 -0
  32. package/dist/concise-data-table/DataRow.svelte +1 -1
  33. package/dist/concise-data-table/TableOptions.d.ts +1 -1
  34. package/dist/data-table/DataTable.svelte +1 -1
  35. package/dist/data-table/parts/ActionsPanel.svelte +4 -3
  36. package/dist/data-table/parts/ActionsRow.svelte +3 -3
  37. package/dist/data-table/parts/ContentPanel.svelte +3 -2
  38. package/dist/data-table/parts/FixedColumnsPanel.svelte +0 -1
  39. package/dist/data-table/parts/FixedColumnsPanel.svelte.d.ts +1 -2
  40. package/dist/data-table/parts/FixedHeaderPanel.svelte +2 -2
  41. package/dist/data-table/parts/FixedRow.svelte +2 -1
  42. package/dist/data-table/parts/FixedRow.svelte.d.ts +1 -1
  43. package/dist/data-table/parts/HrefCell.svelte +23 -2
  44. package/dist/data-table/parts/PopupMenu.svelte +25 -2
  45. package/dist/data-table/parts/PopupMenu.svelte.d.ts +8 -1
  46. package/dist/date-picker/DatePicker.svelte +0 -1
  47. package/dist/date-picker/DateTimePicker.svelte +3 -3
  48. package/dist/date-picker/ScrollBar.svelte +4 -7
  49. package/dist/date-range/DateRangeEditor.svelte +1 -1
  50. package/dist/dialog/CommonDialog.svelte +8 -5
  51. package/dist/dialog/CommonDialog.svelte.d.ts +2 -1
  52. package/dist/dialog/Dialog.svelte +37 -12
  53. package/dist/dialog/Dialog.svelte.d.ts +4 -3
  54. package/dist/dialog/DialogBoard.svelte +11 -8
  55. package/dist/dialog/DialogWrapper.svelte +10 -0
  56. package/dist/{common-editor/DateInput.svelte.d.ts → dialog/DialogWrapper.svelte.d.ts} +6 -13
  57. package/dist/dialog/Dialogs.js +1 -1
  58. package/dist/dialog/ModalResult.d.ts +5 -0
  59. package/dist/dialog/ModalResult.js +5 -0
  60. package/dist/drawer/Drawer.svelte +1 -1
  61. package/dist/form-field/FormField.svelte +2 -1
  62. package/dist/form-field/FormField.svelte.d.ts +1 -0
  63. package/dist/form-panel/flex-row-form/FormContainer.svelte +1 -1
  64. package/dist/form-panel/grid-form/EmptyCell.svelte +8 -7
  65. package/dist/form-panel/grid-form/EmptyCell.svelte.d.ts +2 -2
  66. package/dist/form-panel/grid-form/GridField.svelte +1 -1
  67. package/dist/i18nRes/i18nRes.d.ts +2 -0
  68. package/dist/i18nRes/i18nRes.js +44 -0
  69. package/dist/i18nRes/index.d.ts +2 -0
  70. package/dist/i18nRes/index.js +2 -0
  71. package/dist/image-files/ImageFilesField.svelte +1 -1
  72. package/dist/indicator/IndicatorBoard.svelte +1 -1
  73. package/dist/inline-cell-editor/InvalidEditor.svelte +1 -0
  74. package/dist/input-options-select/InputOptionsSelect.svelte +6 -6
  75. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +1 -1
  76. package/dist/layout/flex/FlexBlock.svelte +1 -1
  77. package/dist/lookup-editor/LookupEditor.svelte +1 -1
  78. package/dist/memo-editor/MemoEditor.svelte +2 -2
  79. package/dist/message-box/IMessageBox.d.ts +2 -4
  80. package/dist/message-box/IMessageBox.js +4 -6
  81. package/dist/message-box/MessageBoxBoard.svelte +1 -3
  82. package/dist/options-multi-select/OptionsMultiSelect.svelte +1 -1
  83. package/dist/prompts-text-editor/PromptsTextEditor.svelte +2 -2
  84. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +1 -1
  85. package/dist/property-editor/PropertyEditor.svelte +3 -3
  86. package/dist/text-editor/PasswordEditor.svelte +1 -1
  87. package/dist/transfer/Transfer.svelte +17 -12
  88. package/dist/transfer/Transfer.svelte.d.ts +0 -1
  89. package/dist/unit-number-editor/UnitNumberEditor.svelte +2 -2
  90. package/docs/buttons/cn/ActionBar.md +459 -0
  91. package/docs/buttons/cn/Button.md +228 -0
  92. package/docs/buttons/cn/IconButton.md +294 -0
  93. package/docs/buttons/cn/README.md +600 -0
  94. package/docs/buttons/cn/TextButton.md +163 -0
  95. package/docs/buttons/en/ActionBar.md +459 -0
  96. package/docs/buttons/en/Button.md +228 -0
  97. package/docs/buttons/en/IconButton.md +294 -0
  98. package/docs/buttons/en/README.md +600 -0
  99. package/docs/buttons/en/TextButton.md +163 -0
  100. package/docs/containers/cn/accordion.md +622 -0
  101. package/docs/containers/cn/box.md +445 -0
  102. package/docs/containers/cn/card.md +404 -0
  103. package/docs/containers/cn/page.md +576 -0
  104. package/docs/containers/cn/tabs.md +686 -0
  105. package/docs/containers/en/accordion.md +622 -0
  106. package/docs/containers/en/box.md +445 -0
  107. package/docs/containers/en/card.md +404 -0
  108. package/docs/containers/en/page.md +576 -0
  109. package/docs/containers/en/tabs.md +686 -0
  110. package/docs/data-display/cn/concise-data-table.md +731 -0
  111. package/docs/data-display/cn/listbox.md +786 -0
  112. package/docs/data-display/cn/treeview.md +863 -0
  113. package/docs/data-display/en/concise-data-table.md +732 -0
  114. package/docs/data-display/en/listbox.md +786 -0
  115. package/docs/data-display/en/treeview.md +863 -0
  116. package/docs/data-table/cn/README.md +596 -0
  117. package/docs/data-table/en/README.md +596 -0
  118. package/docs/dialog/cn/README.md +767 -0
  119. package/docs/dialog/en/README.md +767 -0
  120. package/docs/form/cn/README.md +847 -0
  121. package/docs/form/en/README.md +847 -0
  122. package/docs/form-components/cn/README.md +495 -0
  123. package/docs/form-components/cn/attachmentfilesfield.md +757 -0
  124. package/docs/form-components/cn/cascade-options-select.md +374 -0
  125. package/docs/form-components/cn/checkbox.md +58 -0
  126. package/docs/form-components/cn/date-picker.md +138 -0
  127. package/docs/form-components/cn/datetime-picker.md +228 -0
  128. package/docs/form-components/cn/group-checkbox.md +405 -0
  129. package/docs/form-components/cn/group-radiobox.md +525 -0
  130. package/docs/form-components/cn/imagefilesfield.md +651 -0
  131. package/docs/form-components/cn/input-options-select.md +250 -0
  132. package/docs/form-components/cn/lookup-editor.md +406 -0
  133. package/docs/form-components/cn/memoeditor.md +409 -0
  134. package/docs/form-components/cn/number-editor.md +261 -0
  135. package/docs/form-components/cn/options-multi-select.md +177 -0
  136. package/docs/form-components/cn/options-select.md +83 -0
  137. package/docs/form-components/cn/passwordeditor.md +538 -0
  138. package/docs/form-components/cn/prompts-text-editor.md +241 -0
  139. package/docs/form-components/cn/radiobutton.md +84 -0
  140. package/docs/form-components/cn/switch.md +178 -0
  141. package/docs/form-components/cn/text-editor.md +142 -0
  142. package/docs/form-components/cn/time-editor.md +159 -0
  143. package/docs/form-components/cn/unit-number-editor.md +164 -0
  144. package/docs/form-components/en/README.md +463 -0
  145. package/docs/form-components/en/attachmentfilesfield.md +757 -0
  146. package/docs/form-components/en/cascade-options-select.md +358 -0
  147. package/docs/form-components/en/checkbox.md +59 -0
  148. package/docs/form-components/en/date-picker.md +138 -0
  149. package/docs/form-components/en/datetime-picker.md +228 -0
  150. package/docs/form-components/en/group-checkbox.md +395 -0
  151. package/docs/form-components/en/group-radiobox.md +498 -0
  152. package/docs/form-components/en/imagefilesfield.md +651 -0
  153. package/docs/form-components/en/input-options-select.md +239 -0
  154. package/docs/form-components/en/lookup-editor.md +389 -0
  155. package/docs/form-components/en/memoeditor.md +409 -0
  156. package/docs/form-components/en/number-editor.md +249 -0
  157. package/docs/form-components/en/options-multi-select.md +177 -0
  158. package/docs/form-components/en/options-select.md +83 -0
  159. package/docs/form-components/en/passwordeditor.md +538 -0
  160. package/docs/form-components/en/prompts-text-editor.md +241 -0
  161. package/docs/form-components/en/radiobutton.md +84 -0
  162. package/docs/form-components/en/switch.md +180 -0
  163. package/docs/form-components/en/text-editor.md +142 -0
  164. package/docs/form-components/en/time-editor.md +159 -0
  165. package/docs/form-components/en/unit-number-editor.md +164 -0
  166. package/docs/form-layout/cn/criteria-field.md +652 -0
  167. package/docs/form-layout/cn/flex-form.md +454 -0
  168. package/docs/form-layout/cn/flex-row-form.md +542 -0
  169. package/docs/form-layout/cn/form-field.md +923 -0
  170. package/docs/form-layout/cn/grid-form.md +676 -0
  171. package/docs/form-layout/en/criteria-field.md +652 -0
  172. package/docs/form-layout/en/flex-form.md +454 -0
  173. package/docs/form-layout/en/flex-row-form.md +542 -0
  174. package/docs/form-layout/en/form-field.md +923 -0
  175. package/docs/form-layout/en/grid-form.md +676 -0
  176. package/docs/global/cn/README.md +534 -0
  177. package/docs/global/en/README.md +534 -0
  178. package/docs/layout/cn/classiclayout.md +460 -0
  179. package/docs/layout/cn/headerlayout.md +524 -0
  180. package/docs/layout/cn/sidebarlayout.md +263 -0
  181. package/docs/layout/en/classiclayout.md +951 -0
  182. package/docs/layout/en/headerlayout.md +524 -0
  183. package/docs/layout/en/sidebarlayout.md +262 -0
  184. package/docs/misc/cn/README.md +1217 -0
  185. package/docs/misc/en/README.md +1217 -0
  186. package/docs/navigation/cn/breadcrumb.md +291 -0
  187. package/docs/navigation/cn/navigator.md +322 -0
  188. package/docs/navigation/cn/navigatormenu.md +512 -0
  189. package/docs/navigation/cn/progressbar.md +199 -0
  190. package/docs/navigation/cn/progressstepbar.md +299 -0
  191. package/docs/navigation/en/breadcrumb.md +291 -0
  192. package/docs/navigation/en/navigator.md +322 -0
  193. package/docs/navigation/en/navigatormenu.md +512 -0
  194. package/docs/navigation/en/progressbar.md +199 -0
  195. package/docs/navigation/en/progressstepbar.md +299 -0
  196. package/docs/search-filters/cn/daterange.md +1156 -0
  197. package/docs/search-filters/cn/numberrange.md +688 -0
  198. package/docs/search-filters/cn/searchbox.md +1582 -0
  199. package/docs/search-filters/en/daterange.md +1156 -0
  200. package/docs/search-filters/en/numberrange.md +688 -0
  201. package/docs/search-filters/en/searchbox.md +1582 -0
  202. package/package.json +53 -13
  203. package/dist/common-editor/DateInput.svelte +0 -27
  204. package/dist/i18n_resources/index.d.ts +0 -3
  205. package/dist/i18n_resources/index.js +0 -3
  206. /package/dist/{i18n_resources → i18nRes}/uniface_cn_resource.d.ts +0 -0
  207. /package/dist/{i18n_resources → i18nRes}/uniface_cn_resource.js +0 -0
  208. /package/dist/{i18n_resources → i18nRes}/uniface_en_resource.d.ts +0 -0
  209. /package/dist/{i18n_resources → i18nRes}/uniface_en_resource.js +0 -0
@@ -0,0 +1,495 @@
1
+ # Uniface 表单组件文档
2
+
3
+ 这是 Uniface 表单组件的中文文档,涵盖了所有可用的表单输入和选择组件。
4
+
5
+ ## 组件概览
6
+
7
+ ### 基础输入组件
8
+ - [TextEditor](text-editor.md) - 文本输入框
9
+ - [NumberEditor](number-editor.md) - 数字输入框
10
+ - [TimeEditor](time-editor.md) - 时间输入框
11
+ - [UnitNumberEditor](unit-number-editor.md) - 带单位的数字输入框
12
+ - [PromptsTextEditor](prompts-text-editor.md) - 带提示的文本输入框
13
+
14
+ ### 选择组件
15
+ - [CheckBox](checkbox.md) - 复选框
16
+ - [RadioButton](radiobutton.md) - 单选按钮
17
+ - [GroupCheckBox](group-checkbox.md) - 复选框组
18
+ - [GroupRadioBox](group-radiobox.md) - 单选按钮组
19
+ - [Switch](switch.md) - 开关
20
+ - [OptionsSelect](options-select.md) - 选项选择器
21
+ - [OptionsMultiSelect](options-multi-select.md) - 多选选择器
22
+ - [InputOptionsSelect](input-options-select.md) - 输入选项选择器
23
+ - [LookupEditor](lookup-editor.md) - 查找编辑器
24
+ - [CascadeOptionsSelect](cascade-options-select.md) - 级联选择器
25
+
26
+ ### 日期时间组件
27
+ - [DatePicker](date-picker.md) - 日期选择器
28
+ - [DateTimePicker](datetime-picker.md) - 日期时间选择器
29
+
30
+ ## 架构概述
31
+
32
+ ### 核心包装组件
33
+ 所有表单组件都基于两个核心包装组件:
34
+ - **CommonEditor** - 为输入类组件提供统一样式和行为
35
+ - **CommonPicker** - 为选择类组件提供下拉面板功能
36
+
37
+ ### 显示模式
38
+ 所有组件都支持 `DisplayMode` 枚举:
39
+ ```typescript
40
+ enum DisplayMode {
41
+ Edit = 0, // 编辑模式(默认)
42
+ View = 1, // 查看模式
43
+ Display = 2 // 显示模式
44
+ }
45
+ ```
46
+
47
+ ### 通用属性
48
+ 大部分组件共享以下属性:
49
+ - `variant: '' | 'plain' | 'outlined' | 'filled'` - 外观变体
50
+ - `disabled: boolean` - 是否禁用
51
+ - `readonly: boolean` - 是否只读
52
+ - `compact: boolean` - 是否紧凑模式
53
+ - `style: string` - 自定义 CSS 样式
54
+ - `displayMode: DisplayMode` - 显示模式
55
+
56
+ ## 样式和主题
57
+
58
+ ### CSS 自定义属性
59
+
60
+ 所有组件都支持通过 CSS 自定义属性进行主题定制:
61
+
62
+ ```css
63
+ :root {
64
+ /* 颜色 */
65
+ --uniface-primary-color: #007bff;
66
+ --uniface-secondary-color: #6c757d;
67
+ --uniface-success-color: #28a745;
68
+ --uniface-danger-color: #dc3545;
69
+ --uniface-warning-color: #ffc107;
70
+ --uniface-info-color: #17a2b8;
71
+ --uniface-light-color: #f8f9fa;
72
+ --uniface-dark-color: #343a40;
73
+
74
+ /* 边框 */
75
+ --uniface-border-color: #dee2e6;
76
+ --uniface-border-radius: 4px;
77
+ --uniface-border-width: 1px;
78
+
79
+ /* 间距 */
80
+ --uniface-padding-sm: 4px 8px;
81
+ --uniface-padding-md: 8px 12px;
82
+ --uniface-padding-lg: 12px 16px;
83
+
84
+ /* 字体 */
85
+ --uniface-font-size-sm: 12px;
86
+ --uniface-font-size-md: 14px;
87
+ --uniface-font-size-lg: 16px;
88
+
89
+ /* 阴影 */
90
+ --uniface-box-shadow: 0 2px 4px rgba(0,0,0,0.1);
91
+ --uniface-box-shadow-hover: 0 4px 8px rgba(0,0,0,0.15);
92
+ }
93
+ ```
94
+
95
+ ### 变体样式
96
+
97
+ #### Plain 变体
98
+ ```css
99
+ .uniface-editor.plain {
100
+ border: none;
101
+ background: transparent;
102
+ }
103
+ ```
104
+
105
+ #### Outlined 变体
106
+ ```css
107
+ .uniface-editor.outlined {
108
+ border: 1px solid var(--uniface-border-color);
109
+ background: white;
110
+ }
111
+ ```
112
+
113
+ #### Filled 变体
114
+ ```css
115
+ .uniface-editor.filled {
116
+ border: none;
117
+ background: var(--uniface-light-color);
118
+ }
119
+ ```
120
+
121
+ ### 紧凑模式
122
+ ```css
123
+ .uniface-editor.compact {
124
+ padding: var(--uniface-padding-sm);
125
+ font-size: var(--uniface-font-size-sm);
126
+ }
127
+ ```
128
+
129
+ ## 图标使用
130
+
131
+ 所有组件都使用 `@ticatec/uniface-google-material-icons` 图标库,这是对 Google Material Icons 的封装。
132
+
133
+ ### 常用图标
134
+
135
+ | 图标类 | 描述 | 使用场景 |
136
+ |--------|------|----------|
137
+ | `icon_google_add` | 添加 | 添加按钮、新建操作 |
138
+ | `icon_google_edit` | 编辑 | 编辑按钮、修改操作 |
139
+ | `icon_google_delete` | 删除 | 删除按钮、移除操作 |
140
+ | `icon_google_search` | 搜索 | 搜索框、查找功能 |
141
+ | `icon_google_clear` | 清除 | 清空输入、重置操作 |
142
+ | `icon_google_arrow_drop_down` | 下拉箭头 | 下拉选择组件 |
143
+ | `icon_google_arrow_drop_up` | 上拉箭头 | 收起下拉面板 |
144
+ | `icon_google_check` | 勾选 | 复选框、确认操作 |
145
+ | `icon_google_close` | 关闭 | 关闭按钮、取消操作 |
146
+ | `icon_google_calendar_today` | 日历 | 日期选择器 |
147
+ | `icon_google_access_time` | 时间 | 时间选择器 |
148
+ | `icon_google_keyboard_arrow_down` | 键盘下箭头 | 级联选择组件 |
149
+ | `icon_google_keyboard_control` | 控制键 | 查找编辑器 |
150
+
151
+ ### 图标使用示例
152
+
153
+ ```svelte
154
+ <!-- 在HTML中直接使用 -->
155
+ <i class="icon_google_search"></i>
156
+
157
+ <!-- 在组件属性中使用 -->
158
+ <Button icon="icon_google_add" label="添加用户" />
159
+
160
+ <!-- 在CSS中使用 -->
161
+ <style>
162
+ .custom-icon::before {
163
+ content: '';
164
+ @extend .icon_google_settings;
165
+ }
166
+ </style>
167
+ ```
168
+
169
+ ## 国际化支持
170
+
171
+ ### 使用 @ticatec/i18n
172
+
173
+ ```svelte
174
+ <script lang="ts">
175
+ import i18n from '@ticatec/i18n';
176
+
177
+ // 获取本地化文本
178
+ const getText = (key: string, defaultText: string): string => {
179
+ return i18n.getText(key, defaultText);
180
+ };
181
+ </script>
182
+
183
+ <TextEditor
184
+ placeholder={getText('uniface.editor.placeholder', '请输入内容')}
185
+ />
186
+
187
+ <Button
188
+ label={getText('uniface.button.save', '保存')}
189
+ />
190
+ ```
191
+
192
+ ### 常用国际化键值
193
+
194
+ | 键值 | 中文 | 英文 |
195
+ |------|------|------|
196
+ | `uniface.button.save` | 保存 | Save |
197
+ | `uniface.button.cancel` | 取消 | Cancel |
198
+ | `uniface.button.delete` | 删除 | Delete |
199
+ | `uniface.button.edit` | 编辑 | Edit |
200
+ | `uniface.loadMore` | 加载更多 | Load more |
201
+ | `uniface.noData` | 暂无数据 | No data |
202
+ | `uniface.loading` | 加载中... | Loading... |
203
+ | `uniface.error.required` | 此字段为必填项 | This field is required |
204
+ | `uniface.error.invalid` | 输入格式无效 | Invalid input format |
205
+
206
+ ## 最佳实践
207
+
208
+ ### 1. 响应式设计
209
+ ```svelte
210
+ <style>
211
+ .form-container {
212
+ display: grid;
213
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
214
+ gap: 16px;
215
+ }
216
+
217
+ @media (max-width: 768px) {
218
+ .form-container {
219
+ grid-template-columns: 1fr;
220
+ }
221
+ }
222
+ </style>
223
+ ```
224
+
225
+ ### 2. 无障碍访问
226
+ ```svelte
227
+ <!-- 为每个表单字段添加标签 -->
228
+ <label for="username">用户名:</label>
229
+ <TextEditor id="username" placeholder="请输入用户名" />
230
+
231
+ <!-- 为选择组件添加描述 -->
232
+ <OptionsSelect
233
+ aria-describedby="country-description"
234
+ placeholder="请选择国家"
235
+ options={countries}
236
+ />
237
+ <div id="country-description" class="form-help">
238
+ 请选择您所在的国家或地区
239
+ </div>
240
+ ```
241
+
242
+ ### 3. 性能优化
243
+ ```svelte
244
+ <script lang="ts">
245
+ import { onMount } from 'svelte';
246
+
247
+ interface Option {
248
+ value: string;
249
+ label: string;
250
+ }
251
+
252
+ let options: Option[] = [];
253
+
254
+ // 延迟加载大量选项数据
255
+ onMount(async (): Promise<void> => {
256
+ const response = await fetch('/api/options');
257
+ options = await response.json() as Option[];
258
+ });
259
+
260
+ // 使用防抖处理搜索
261
+ let searchTimeout: NodeJS.Timeout;
262
+ const handleSearch = (keyword: string): void => {
263
+ clearTimeout(searchTimeout);
264
+ searchTimeout = setTimeout(() => {
265
+ performSearch(keyword);
266
+ }, 300);
267
+ };
268
+
269
+ const performSearch = (keyword: string): void => {
270
+ // 实现搜索逻辑
271
+ };
272
+ </script>
273
+ ```
274
+
275
+ ### 4. 错误处理
276
+ ```svelte
277
+ <script lang="ts">
278
+ let loading: boolean = false;
279
+ let error: string | null = null;
280
+
281
+ const handleAsyncOperation = async (): Promise<void> => {
282
+ loading = true;
283
+ error = null;
284
+
285
+ try {
286
+ await performOperation();
287
+ } catch (err: unknown) {
288
+ error = err instanceof Error ? err.message : '未知错误';
289
+ console.error('操作失败:', err);
290
+ } finally {
291
+ loading = false;
292
+ }
293
+ };
294
+
295
+ const performOperation = async (): Promise<void> => {
296
+ // 实现异步操作逻辑
297
+ };
298
+ </script>
299
+
300
+ {#if error}
301
+ <div class="error-alert">
302
+ <i class="icon_google_error"></i>
303
+ {error}
304
+ </div>
305
+ {/if}
306
+ ```
307
+
308
+ ## 表单验证示例
309
+
310
+ ```svelte
311
+ <script lang="ts">
312
+ import TextEditor from '@ticatec/uniface-element/TextEditor';
313
+ import NumberEditor from '@ticatec/uniface-element/NumberEditor';
314
+ import CheckBox from '@ticatec/uniface-element/Checkbox';
315
+
316
+ interface FormData {
317
+ name: string;
318
+ email: string;
319
+ age: number | null;
320
+ agreed: boolean;
321
+ }
322
+
323
+ interface FormErrors {
324
+ [key: string]: string;
325
+ }
326
+
327
+ type ValidatorFunction = (value: any) => string | null;
328
+
329
+ interface Validators {
330
+ [key: string]: ValidatorFunction;
331
+ }
332
+
333
+ let formData: FormData = {
334
+ name: '',
335
+ email: '',
336
+ age: null,
337
+ agreed: false
338
+ };
339
+
340
+ let errors: FormErrors = {};
341
+
342
+ // 验证规则
343
+ const validators: Validators = {
344
+ name: (value: string): string | null => {
345
+ if (!value || value.trim().length === 0) {
346
+ return '姓名不能为空';
347
+ }
348
+ if (value.length < 2) {
349
+ return '姓名至少需要2个字符';
350
+ }
351
+ return null;
352
+ },
353
+ email: (value: string): string | null => {
354
+ if (!value) return '邮箱不能为空';
355
+ const emailRegex: RegExp = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
356
+ if (!emailRegex.test(value)) {
357
+ return '请输入有效的邮箱地址';
358
+ }
359
+ return null;
360
+ },
361
+ age: (value: number | null): string | null => {
362
+ if (value === null) return '年龄不能为空';
363
+ if (value < 18) return '年龄必须满18岁';
364
+ if (value > 120) return '请输入有效的年龄';
365
+ return null;
366
+ },
367
+ agreed: (value: boolean): string | null => {
368
+ if (!value) return '请同意服务条款';
369
+ return null;
370
+ }
371
+ };
372
+
373
+ // 验证单个字段
374
+ const validateField = (field: keyof FormData, value: any): void => {
375
+ const error = validators[field]?.(value);
376
+ if (error) {
377
+ errors[field] = error;
378
+ } else {
379
+ delete errors[field];
380
+ }
381
+ errors = { ...errors };
382
+ };
383
+
384
+ // 验证整个表单
385
+ const validateForm = (): boolean => {
386
+ const newErrors: FormErrors = {};
387
+ (Object.keys(validators) as Array<keyof FormData>).forEach(field => {
388
+ const error = validators[field](formData[field]);
389
+ if (error) {
390
+ newErrors[field] = error;
391
+ }
392
+ });
393
+ errors = newErrors;
394
+ return Object.keys(errors).length === 0;
395
+ };
396
+
397
+ const handleSubmit = (): void => {
398
+ if (validateForm()) {
399
+ console.log('表单提交成功', formData);
400
+ } else {
401
+ console.log('表单验证失败', errors);
402
+ }
403
+ };
404
+ </script>
405
+
406
+ <form on:submit|preventDefault={handleSubmit}>
407
+ <!-- 姓名输入 -->
408
+ <div class="form-field">
409
+ <TextEditor
410
+ placeholder="请输入姓名"
411
+ bind:value={formData.name}
412
+ onChange={(value: string) => validateField('name', value)}
413
+ />
414
+ {#if errors.name}
415
+ <div class="error-message">{errors.name}</div>
416
+ {/if}
417
+ </div>
418
+
419
+ <!-- 邮箱输入 -->
420
+ <div class="form-field">
421
+ <TextEditor
422
+ placeholder="请输入邮箱"
423
+ bind:value={formData.email}
424
+ onChange={(value: string) => validateField('email', value)}
425
+ />
426
+ {#if errors.email}
427
+ <div class="error-message">{errors.email}</div>
428
+ {/if}
429
+ </div>
430
+
431
+ <!-- 年龄输入 -->
432
+ <div class="form-field">
433
+ <NumberEditor
434
+ placeholder="请输入年龄"
435
+ min={1}
436
+ max={120}
437
+ bind:value={formData.age}
438
+ onChange={(value: number | null) => validateField('age', value)}
439
+ />
440
+ {#if errors.age}
441
+ <div class="error-message">{errors.age}</div>
442
+ {/if}
443
+ </div>
444
+
445
+ <!-- 同意条款 -->
446
+ <div class="form-field">
447
+ <CheckBox
448
+ label="我同意服务条款和隐私政策"
449
+ bind:value={formData.agreed}
450
+ onChange={(value: boolean) => validateField('agreed', value)}
451
+ />
452
+ {#if errors.agreed}
453
+ <div class="error-message">{errors.agreed}</div>
454
+ {/if}
455
+ </div>
456
+
457
+ <button type="submit" disabled={Object.keys(errors).length > 0}>
458
+ 提交表单
459
+ </button>
460
+ </form>
461
+
462
+ <style>
463
+ .form-field {
464
+ margin-bottom: 16px;
465
+ }
466
+
467
+ .error-message {
468
+ color: var(--uniface-danger-color);
469
+ font-size: 12px;
470
+ margin-top: 4px;
471
+ }
472
+
473
+ button:disabled {
474
+ opacity: 0.5;
475
+ cursor: not-allowed;
476
+ }
477
+ </style>
478
+ ```
479
+
480
+ ---
481
+
482
+ ## 总结
483
+
484
+ 本文档涵盖了 Uniface 表单组件库的完整 API 和使用方法。每个组件都遵循统一的设计原则和交互模式,确保了良好的用户体验和开发体验。
485
+
486
+ 主要特性:
487
+ - 🎨 统一的视觉设计和交互体验
488
+ - 🔧 TypeScript 支持,提供完整的类型定义
489
+ - 🌍 国际化支持
490
+ - ♿ 考虑无障碍访问需求
491
+ - 📱 响应式设计
492
+ - 🎯 高性能实现
493
+ - 🔌 灵活的扩展机制
494
+
495
+ 如需更多信息或遇到问题,请参考相关组件的源代码或联系开发团队。