@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,1217 @@
1
+ # 杂项组件
2
+
3
+ Uniface Element 库提供了一组实用工具和布局组件,用于构建现代 Svelte 应用程序。这些组件处理常见的 UI 模式并提供灵活的布局。
4
+
5
+ ## 目录
6
+
7
+ - [Split 组件](#split-组件)
8
+ - [Drawer 组件](#drawer-组件)
9
+ - [Tag 组件](#tag-组件)
10
+ - [Card 组件](#card-组件)
11
+ - [最佳实践](#最佳实践)
12
+
13
+ ## Split 组件
14
+
15
+ Split 组件提供可调整大小的分隔符,用于创建具有可拖动分隔符的分割面板布局。
16
+
17
+ ### 特性
18
+
19
+ - **水平和垂直**: 支持水平和垂直分割
20
+ - **可拖动调整**: 支持鼠标拖动的交互式调整句柄
21
+ - **可逆方向**: 使用 reverse 属性控制调整方向
22
+ - **面板绑定**: 绑定到特定面板以进行受控调整
23
+ - **固定模式**: 可选择禁用调整以实现静态布局
24
+
25
+ ### 基本用法
26
+
27
+ ```svelte
28
+ <script lang="ts">
29
+ import Split from '@ticatec/uniface-element/Split';
30
+
31
+ let leftPanel;
32
+ let topPanel;
33
+ </script>
34
+
35
+ <!-- 垂直分割(左/右面板) -->
36
+ <div class="split-container">
37
+ <div class="left-panel" bind:this={leftPanel}>
38
+ 左侧面板内容
39
+ </div>
40
+
41
+ <Split
42
+ direction="vertical"
43
+ width={4}
44
+ bindingPanel={leftPanel}
45
+ />
46
+
47
+ <div class="right-panel">
48
+ 右侧面板内容
49
+ </div>
50
+ </div>
51
+
52
+ <!-- 水平分割(上/下面板) -->
53
+ <div class="split-container horizontal">
54
+ <div class="top-panel" bind:this={topPanel}>
55
+ 顶部面板内容
56
+ </div>
57
+
58
+ <Split
59
+ direction="horizontal"
60
+ width={4}
61
+ bindingPanel={topPanel}
62
+ />
63
+
64
+ <div class="bottom-panel">
65
+ 底部面板内容
66
+ </div>
67
+ </div>
68
+
69
+ <style>
70
+ .split-container {
71
+ display: flex;
72
+ height: 400px;
73
+ width: 100%;
74
+ border: 1px solid #ddd;
75
+ }
76
+
77
+ .split-container.horizontal {
78
+ flex-direction: column;
79
+ }
80
+
81
+ .left-panel, .right-panel {
82
+ flex: 1;
83
+ padding: 16px;
84
+ overflow: auto;
85
+ }
86
+
87
+ .top-panel, .bottom-panel {
88
+ flex: 1;
89
+ padding: 16px;
90
+ overflow: auto;
91
+ }
92
+
93
+ .left-panel {
94
+ background: #f8f9fa;
95
+ min-width: 150px;
96
+ }
97
+
98
+ .right-panel {
99
+ background: #fff;
100
+ }
101
+
102
+ .top-panel {
103
+ background: #f8f9fa;
104
+ min-height: 100px;
105
+ }
106
+
107
+ .bottom-panel {
108
+ background: #fff;
109
+ }
110
+ </style>
111
+ ```
112
+
113
+ ### 高级布局
114
+
115
+ ```svelte
116
+ <script lang="ts">
117
+ import Split from '@ticatec/uniface-element/Split';
118
+
119
+ let sidebar;
120
+ let contentLeft;
121
+ let contentTop;
122
+ </script>
123
+
124
+ <!-- 复杂分割布局:侧边栏 + 主内容区域与嵌套分割 -->
125
+ <div class="app-layout">
126
+ <!-- 侧边栏 -->
127
+ <div class="sidebar" bind:this={sidebar}>
128
+ <h3>导航</h3>
129
+ <nav>
130
+ <ul>
131
+ <li>仪表板</li>
132
+ <li>项目</li>
133
+ <li>设置</li>
134
+ </ul>
135
+ </nav>
136
+ </div>
137
+
138
+ <!-- 垂直分隔符 -->
139
+ <Split
140
+ direction="vertical"
141
+ width={3}
142
+ bindingPanel={sidebar}
143
+ />
144
+
145
+ <!-- 主内容区域 -->
146
+ <div class="main-content">
147
+ <!-- 顶部内容区域 -->
148
+ <div class="content-top" bind:this={contentTop}>
149
+ <h2>主内容</h2>
150
+ <p>这是可以调整大小的主内容区域。</p>
151
+ </div>
152
+
153
+ <!-- 水平分隔符 -->
154
+ <Split
155
+ direction="horizontal"
156
+ width={3}
157
+ bindingPanel={contentTop}
158
+ reverse={true}
159
+ />
160
+
161
+ <!-- 底部内容区域 -->
162
+ <div class="content-bottom">
163
+ <h3>详细信息面板</h3>
164
+ <p>附加的详细信息和信息。</p>
165
+ </div>
166
+ </div>
167
+ </div>
168
+
169
+ <style>
170
+ .app-layout {
171
+ display: flex;
172
+ height: 500px;
173
+ width: 100%;
174
+ border: 1px solid #ccc;
175
+ border-radius: 4px;
176
+ overflow: hidden;
177
+ }
178
+
179
+ .sidebar {
180
+ width: 200px;
181
+ min-width: 150px;
182
+ background: #2c3e50;
183
+ color: white;
184
+ padding: 16px;
185
+ }
186
+
187
+ .sidebar h3 {
188
+ margin: 0 0 16px 0;
189
+ color: #ecf0f1;
190
+ }
191
+
192
+ .sidebar nav ul {
193
+ list-style: none;
194
+ padding: 0;
195
+ margin: 0;
196
+ }
197
+
198
+ .sidebar nav li {
199
+ padding: 8px 0;
200
+ cursor: pointer;
201
+ transition: color 0.2s;
202
+ }
203
+
204
+ .sidebar nav li:hover {
205
+ color: #3498db;
206
+ }
207
+
208
+ .main-content {
209
+ flex: 1;
210
+ display: flex;
211
+ flex-direction: column;
212
+ }
213
+
214
+ .content-top {
215
+ flex: 1;
216
+ min-height: 200px;
217
+ padding: 16px;
218
+ background: #fff;
219
+ }
220
+
221
+ .content-bottom {
222
+ height: 150px;
223
+ min-height: 100px;
224
+ padding: 16px;
225
+ background: #f8f9fa;
226
+ border-top: 1px solid #dee2e6;
227
+ }
228
+ </style>
229
+ ```
230
+
231
+ ### Split 属性
232
+
233
+ | 属性 | 类型 | 默认值 | 描述 |
234
+ |------|------|--------|------|
235
+ | `direction` | `'horizontal' \| 'vertical'` | `'vertical'` | 分割方向 |
236
+ | `width` | `number` | `2` | 分隔符厚度(像素) |
237
+ | `bindingPanel` | `HTMLElement \| null` | `null` | 要调整大小的面板元素 |
238
+ | `reverse` | `boolean` | `false` | 反转调整方向 |
239
+
240
+ ## Drawer 组件
241
+
242
+ Drawer 组件提供一个滑出面板,可以位于屏幕的左侧或右侧。
243
+
244
+ ### 特性
245
+
246
+ - **侧边定位**: 左侧或右侧定位
247
+ - **流畅动画**: 飞入/飞出过渡效果,可配置持续时间
248
+ - **可自定义宽度**: 可调整的抽屉宽度
249
+ - **背景交互**: 点击外部即可关闭
250
+ - **插槽支持**: 通过插槽灵活内容
251
+
252
+ ### 基本用法
253
+
254
+ ```svelte
255
+ <script lang="ts">
256
+ import Drawer from '@ticatec/uniface-element/Drawer';
257
+
258
+ let leftDrawerVisible = false;
259
+ let rightDrawerVisible = false;
260
+
261
+ const toggleLeftDrawer = () => {
262
+ leftDrawerVisible = !leftDrawerVisible;
263
+ };
264
+
265
+ const toggleRightDrawer = () => {
266
+ rightDrawerVisible = !rightDrawerVisible;
267
+ };
268
+ </script>
269
+
270
+ <div class="drawer-demo">
271
+ <h2>Drawer 组件演示</h2>
272
+
273
+ <div class="buttons">
274
+ <button on:click={toggleLeftDrawer}>
275
+ 切换左侧抽屉
276
+ </button>
277
+
278
+ <button on:click={toggleRightDrawer}>
279
+ 切换右侧抽屉
280
+ </button>
281
+ </div>
282
+
283
+ <p>点击上面的按钮来打开/关闭抽屉。</p>
284
+ </div>
285
+
286
+ <!-- 左侧抽屉 -->
287
+ <Drawer bind:visible={leftDrawerVisible} position="left" width={300}>
288
+ <div class="drawer-content">
289
+ <h3>左侧导航</h3>
290
+ <nav>
291
+ <a href="#home">首页</a>
292
+ <a href="#about">关于</a>
293
+ <a href="#services">服务</a>
294
+ <a href="#contact">联系</a>
295
+ </nav>
296
+ </div>
297
+ </Drawer>
298
+
299
+ <!-- 右侧抽屉 -->
300
+ <Drawer bind:visible={rightDrawerVisible} position="right" width={350}>
301
+ <div class="drawer-content">
302
+ <h3>设置面板</h3>
303
+ <div class="settings">
304
+ <label>
305
+ <input type="checkbox" /> 深色模式
306
+ </label>
307
+ <label>
308
+ <input type="checkbox" checked /> 通知
309
+ </label>
310
+ <label>
311
+ <input type="checkbox" /> 自动保存
312
+ </label>
313
+ </div>
314
+ </div>
315
+ </Drawer>
316
+
317
+ <style>
318
+ .drawer-demo {
319
+ padding: 40px;
320
+ text-align: center;
321
+ }
322
+
323
+ .buttons {
324
+ margin: 20px 0;
325
+ display: flex;
326
+ gap: 16px;
327
+ justify-content: center;
328
+ }
329
+
330
+ .buttons button {
331
+ padding: 10px 20px;
332
+ border: 1px solid #007bff;
333
+ background: #007bff;
334
+ color: white;
335
+ border-radius: 4px;
336
+ cursor: pointer;
337
+ transition: background-color 0.2s;
338
+ }
339
+
340
+ .buttons button:hover {
341
+ background: #0056b3;
342
+ }
343
+
344
+ .drawer-content {
345
+ padding: 20px;
346
+ height: 100%;
347
+ }
348
+
349
+ .drawer-content h3 {
350
+ margin: 0 0 20px 0;
351
+ color: #333;
352
+ border-bottom: 1px solid #eee;
353
+ padding-bottom: 10px;
354
+ }
355
+
356
+ .drawer-content nav {
357
+ display: flex;
358
+ flex-direction: column;
359
+ gap: 12px;
360
+ }
361
+
362
+ .drawer-content nav a {
363
+ padding: 8px 12px;
364
+ color: #007bff;
365
+ text-decoration: none;
366
+ border-radius: 4px;
367
+ transition: background-color 0.2s;
368
+ }
369
+
370
+ .drawer-content nav a:hover {
371
+ background: #f8f9fa;
372
+ }
373
+
374
+ .settings {
375
+ display: flex;
376
+ flex-direction: column;
377
+ gap: 12px;
378
+ }
379
+
380
+ .settings label {
381
+ display: flex;
382
+ align-items: center;
383
+ gap: 8px;
384
+ cursor: pointer;
385
+ }
386
+ </style>
387
+ ```
388
+
389
+ ### 移动菜单示例
390
+
391
+ ```svelte
392
+ <script lang="ts">
393
+ import Drawer from '@ticatec/uniface-element/Drawer';
394
+
395
+ let menuVisible = false;
396
+
397
+ const toggleMenu = () => {
398
+ menuVisible = !menuVisible;
399
+ };
400
+
401
+ const closeMenu = () => {
402
+ menuVisible = false;
403
+ };
404
+ </script>
405
+
406
+ <!-- 移动端头部 -->
407
+ <header class="mobile-header">
408
+ <button class="menu-button" on:click={toggleMenu}>
409
+ <span class="hamburger">☰</span>
410
+ </button>
411
+ <h1>我的应用</h1>
412
+ <div class="header-actions">
413
+ <!-- 头部操作 -->
414
+ </div>
415
+ </header>
416
+
417
+ <!-- 移动端导航抽屉 -->
418
+ <Drawer bind:visible={menuVisible} position="left" width={280}>
419
+ <div class="mobile-menu">
420
+ <div class="menu-header">
421
+ <h2>菜单</h2>
422
+ <button class="close-button" on:click={closeMenu}>×</button>
423
+ </div>
424
+
425
+ <nav class="menu-nav">
426
+ <a href="#dashboard" on:click={closeMenu}>仪表板</a>
427
+ <a href="#projects" on:click={closeMenu}>项目</a>
428
+ <a href="#team" on:click={closeMenu}>团队</a>
429
+ <a href="#settings" on:click={closeMenu}>设置</a>
430
+
431
+ <div class="menu-divider"></div>
432
+
433
+ <a href="#help" on:click={closeMenu}>帮助与支持</a>
434
+ <a href="#logout" on:click={closeMenu}>退出登录</a>
435
+ </nav>
436
+ </div>
437
+ </Drawer>
438
+
439
+ <style>
440
+ .mobile-header {
441
+ display: flex;
442
+ align-items: center;
443
+ padding: 12px 16px;
444
+ background: #fff;
445
+ border-bottom: 1px solid #eee;
446
+ position: sticky;
447
+ top: 0;
448
+ z-index: 100;
449
+ }
450
+
451
+ .menu-button {
452
+ background: none;
453
+ border: none;
454
+ font-size: 20px;
455
+ cursor: pointer;
456
+ padding: 8px;
457
+ margin-right: 12px;
458
+ }
459
+
460
+ .mobile-header h1 {
461
+ flex: 1;
462
+ margin: 0;
463
+ font-size: 1.2em;
464
+ color: #333;
465
+ }
466
+
467
+ .mobile-menu {
468
+ height: 100%;
469
+ background: #fff;
470
+ display: flex;
471
+ flex-direction: column;
472
+ }
473
+
474
+ .menu-header {
475
+ display: flex;
476
+ justify-content: space-between;
477
+ align-items: center;
478
+ padding: 16px 20px;
479
+ border-bottom: 1px solid #eee;
480
+ }
481
+
482
+ .menu-header h2 {
483
+ margin: 0;
484
+ color: #333;
485
+ }
486
+
487
+ .close-button {
488
+ background: none;
489
+ border: none;
490
+ font-size: 24px;
491
+ cursor: pointer;
492
+ color: #666;
493
+ width: 32px;
494
+ height: 32px;
495
+ display: flex;
496
+ align-items: center;
497
+ justify-content: center;
498
+ }
499
+
500
+ .menu-nav {
501
+ flex: 1;
502
+ padding: 16px 0;
503
+ display: flex;
504
+ flex-direction: column;
505
+ }
506
+
507
+ .menu-nav a {
508
+ padding: 12px 20px;
509
+ color: #333;
510
+ text-decoration: none;
511
+ border-bottom: 1px solid #f5f5f5;
512
+ transition: background-color 0.2s;
513
+ }
514
+
515
+ .menu-nav a:hover {
516
+ background: #f8f9fa;
517
+ }
518
+
519
+ .menu-divider {
520
+ height: 1px;
521
+ background: #ddd;
522
+ margin: 8px 20px;
523
+ }
524
+ </style>
525
+ ```
526
+
527
+ ### Drawer 属性
528
+
529
+ | 属性 | 类型 | 默认值 | 描述 |
530
+ |------|------|--------|------|
531
+ | `visible` | `boolean` | `false` | 控制抽屉可见性 |
532
+ | `width` | `number` | `300` | 抽屉宽度(像素) |
533
+ | `position` | `'left' \| 'right'` | `'left'` | 抽屉位置 |
534
+
535
+ ## Tag 组件
536
+
537
+ Tag 组件显示带有可选删除功能的标记信息。
538
+
539
+ ### 特性
540
+
541
+ - **多种尺寸**: 大、中、小尺寸变体
542
+ - **样式变体**: 无边框、有边框和圆角样式
543
+ - **可移除**: 带有自定义处理器的可选删除按钮
544
+ - **颜色支持**: 可定制的颜色和颜色类
545
+ - **灵活文本**: 显示任何文本内容
546
+
547
+ ### 基本用法
548
+
549
+ ```svelte
550
+ <script lang="ts">
551
+ import Tag from '@ticatec/uniface-element/Tag';
552
+
553
+ let tags = [
554
+ { id: 1, text: 'JavaScript', color: 'blue' },
555
+ { id: 2, text: 'TypeScript', color: 'blue' },
556
+ { id: 3, text: 'Svelte', color: 'orange' },
557
+ { id: 4, text: 'CSS', color: 'green' }
558
+ ];
559
+
560
+ const removeTag = (tagId: number) => {
561
+ tags = tags.filter(tag => tag.id !== tagId);
562
+ };
563
+ </script>
564
+
565
+ <div class="tag-demo">
566
+ <h3>默认标签</h3>
567
+ <div class="tag-group">
568
+ {#each tags as tag}
569
+ <Tag
570
+ text={tag.text}
571
+ removable={true}
572
+ removeHandler={() => removeTag(tag.id)}
573
+ />
574
+ {/each}
575
+ </div>
576
+
577
+ <h3>尺寸变体</h3>
578
+ <div class="tag-group">
579
+ <Tag text="小标签" size="small" />
580
+ <Tag text="中等标签" size="middle" />
581
+ <Tag text="大标签" size="big" />
582
+ </div>
583
+
584
+ <h3>样式变体</h3>
585
+ <div class="tag-group">
586
+ <Tag text="无边框" variant="borderless" />
587
+ <Tag text="有边框" variant="border" />
588
+ <Tag text="圆角" variant="round" />
589
+ </div>
590
+
591
+ <h3>不可移除标签</h3>
592
+ <div class="tag-group">
593
+ <Tag text="状态:活跃" removable={false} color="green" />
594
+ <Tag text="优先级:高" removable={false} color="red" />
595
+ <Tag text="类型:错误" removable={false} color="orange" />
596
+ </div>
597
+ </div>
598
+
599
+ <style>
600
+ .tag-demo {
601
+ padding: 20px;
602
+ }
603
+
604
+ .tag-group {
605
+ display: flex;
606
+ flex-wrap: wrap;
607
+ gap: 8px;
608
+ margin: 12px 0 24px 0;
609
+ }
610
+
611
+ .tag-demo h3 {
612
+ margin: 20px 0 8px 0;
613
+ color: #333;
614
+ font-size: 1.1em;
615
+ }
616
+ </style>
617
+ ```
618
+
619
+ ### 动态标签管理
620
+
621
+ ```svelte
622
+ <script lang="ts">
623
+ import Tag from '@ticatec/uniface-element/Tag';
624
+
625
+ let newTagText = '';
626
+ let tags = [
627
+ { id: 1, text: '前端', color: 'blue' },
628
+ { id: 2, text: '后端', color: 'green' },
629
+ { id: 3, text: '数据库', color: 'purple' }
630
+ ];
631
+ let nextId = 4;
632
+
633
+ const addTag = () => {
634
+ if (newTagText.trim()) {
635
+ tags = [...tags, {
636
+ id: nextId++,
637
+ text: newTagText.trim(),
638
+ color: getRandomColor()
639
+ }];
640
+ newTagText = '';
641
+ }
642
+ };
643
+
644
+ const removeTag = (tagId: number) => {
645
+ tags = tags.filter(tag => tag.id !== tagId);
646
+ };
647
+
648
+ const getRandomColor = () => {
649
+ const colors = ['blue', 'green', 'red', 'orange', 'purple', 'pink'];
650
+ return colors[Math.floor(Math.random() * colors.length)];
651
+ };
652
+
653
+ const handleKeyPress = (event: KeyboardEvent) => {
654
+ if (event.key === 'Enter') {
655
+ addTag();
656
+ }
657
+ };
658
+ </script>
659
+
660
+ <div class="tag-manager">
661
+ <h3>技能标签管理器</h3>
662
+
663
+ <!-- 添加新标签 -->
664
+ <div class="add-tag-form">
665
+ <input
666
+ type="text"
667
+ bind:value={newTagText}
668
+ placeholder="输入技能..."
669
+ on:keypress={handleKeyPress}
670
+ />
671
+ <button on:click={addTag} disabled={!newTagText.trim()}>
672
+ 添加标签
673
+ </button>
674
+ </div>
675
+
676
+ <!-- 标签列表 -->
677
+ <div class="tag-list">
678
+ {#each tags as tag (tag.id)}
679
+ <Tag
680
+ text={tag.text}
681
+ color={tag.color}
682
+ variant="round"
683
+ removable={true}
684
+ removeHandler={() => removeTag(tag.id)}
685
+ />
686
+ {/each}
687
+
688
+ {#if tags.length === 0}
689
+ <p class="empty-state">还没有标签。在上面添加一些技能!</p>
690
+ {/if}
691
+ </div>
692
+
693
+ <!-- 标签统计 -->
694
+ <div class="tag-stats">
695
+ <small>总技能数:{tags.length}</small>
696
+ </div>
697
+ </div>
698
+
699
+ <style>
700
+ .tag-manager {
701
+ max-width: 500px;
702
+ padding: 20px;
703
+ border: 1px solid #ddd;
704
+ border-radius: 8px;
705
+ background: #fff;
706
+ }
707
+
708
+ .add-tag-form {
709
+ display: flex;
710
+ gap: 8px;
711
+ margin-bottom: 16px;
712
+ }
713
+
714
+ .add-tag-form input {
715
+ flex: 1;
716
+ padding: 8px 12px;
717
+ border: 1px solid #ddd;
718
+ border-radius: 4px;
719
+ font-size: 14px;
720
+ }
721
+
722
+ .add-tag-form button {
723
+ padding: 8px 16px;
724
+ background: #007bff;
725
+ color: white;
726
+ border: none;
727
+ border-radius: 4px;
728
+ cursor: pointer;
729
+ font-size: 14px;
730
+ transition: background-color 0.2s;
731
+ }
732
+
733
+ .add-tag-form button:hover:not(:disabled) {
734
+ background: #0056b3;
735
+ }
736
+
737
+ .add-tag-form button:disabled {
738
+ background: #6c757d;
739
+ cursor: not-allowed;
740
+ }
741
+
742
+ .tag-list {
743
+ display: flex;
744
+ flex-wrap: wrap;
745
+ gap: 8px;
746
+ min-height: 40px;
747
+ margin-bottom: 12px;
748
+ }
749
+
750
+ .empty-state {
751
+ color: #666;
752
+ font-style: italic;
753
+ margin: 0;
754
+ }
755
+
756
+ .tag-stats {
757
+ text-align: right;
758
+ color: #666;
759
+ }
760
+ </style>
761
+ ```
762
+
763
+ ### Tag 属性
764
+
765
+ | 属性 | 类型 | 默认值 | 描述 |
766
+ |------|------|--------|------|
767
+ | `size` | `'big' \| 'middle' \| 'small'` | `'middle'` | 标签大小变体 |
768
+ | `variant` | `'borderless' \| 'border' \| 'round'` | `'border'` | 视觉样式变体 |
769
+ | `removable` | `boolean` | `true` | 显示删除按钮 |
770
+ | `text` | `string` | `''` | 标签文本内容 |
771
+ | `style` | `string` | `''` | 自定义 CSS 样式 |
772
+ | `class` | `string` | `''` | CSS 类名 |
773
+ | `removeHandler` | `MouseClickHandler` | - | 删除按钮点击处理器 |
774
+ | `color` | `string` | - | 颜色类标识符 |
775
+
776
+ ## Card 组件
777
+
778
+ Card 组件提供一个带有可选头部、内容和操作区域的容器。
779
+
780
+ ### 特性
781
+
782
+ - **灵活布局**: 头部、内容和操作部分
783
+ - **样式变体**: 朴素和 3D 阴影变体
784
+ - **操作支持**: 内置操作栏,支持可配置操作
785
+ - **插槽系统**: 通过命名插槽提供灵活内容
786
+ - **数据绑定**: 向操作传递数据上下文
787
+
788
+ ### 基本用法
789
+
790
+ ```svelte
791
+ <script lang="ts">
792
+ import Card from '@ticatec/uniface-element/Card';
793
+ import type { CardAction } from '@ticatec/uniface-element';
794
+
795
+ const user = {
796
+ name: '张三',
797
+ email: 'zhangsan@example.com',
798
+ avatar: '/avatars/zhangsan.jpg'
799
+ };
800
+
801
+ const cardActions: CardAction[] = [
802
+ {
803
+ icon: 'icon_google_edit',
804
+ hint: '编辑个人资料',
805
+ callback: (data) => {
806
+ console.log('编辑用户:', data);
807
+ }
808
+ },
809
+ {
810
+ icon: 'icon_google_delete',
811
+ hint: '删除用户',
812
+ callback: (data) => {
813
+ console.log('删除用户:', data);
814
+ }
815
+ }
816
+ ];
817
+ </script>
818
+
819
+ <div class="card-demo">
820
+ <!-- 带标题的简单卡片 -->
821
+ <Card title="用户个人资料" variant="plain">
822
+ <div class="profile-content">
823
+ <img src={user.avatar} alt={user.name} class="avatar" />
824
+ <div class="user-info">
825
+ <h3>{user.name}</h3>
826
+ <p>{user.email}</p>
827
+ </div>
828
+ </div>
829
+ </Card>
830
+
831
+ <!-- 带操作的卡片 -->
832
+ <Card
833
+ title="用户管理"
834
+ variant="3d"
835
+ actions={cardActions}
836
+ data={user}
837
+ >
838
+ <div class="user-details">
839
+ <p><strong>姓名:</strong> {user.name}</p>
840
+ <p><strong>邮箱:</strong> {user.email}</p>
841
+ <p><strong>状态:</strong> 活跃</p>
842
+ </div>
843
+ </Card>
844
+
845
+ <!-- 带自定义头部的卡片 -->
846
+ <Card variant="plain">
847
+ <div slot="header-bar" class="custom-header">
848
+ <h3>自定义头部</h3>
849
+ <span class="status-badge">在线</span>
850
+ </div>
851
+
852
+ <div class="card-body">
853
+ <p>这个卡片有一个带有附加元素的自定义头部。</p>
854
+ </div>
855
+
856
+ <div slot="action-bar" class="custom-actions">
857
+ <button class="btn-primary">保存</button>
858
+ <button class="btn-secondary">取消</button>
859
+ </div>
860
+ </Card>
861
+ </div>
862
+
863
+ <style>
864
+ .card-demo {
865
+ display: grid;
866
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
867
+ gap: 20px;
868
+ padding: 20px;
869
+ }
870
+
871
+ .profile-content {
872
+ display: flex;
873
+ align-items: center;
874
+ gap: 16px;
875
+ padding: 16px;
876
+ }
877
+
878
+ .avatar {
879
+ width: 60px;
880
+ height: 60px;
881
+ border-radius: 50%;
882
+ object-fit: cover;
883
+ }
884
+
885
+ .user-info h3 {
886
+ margin: 0 0 4px 0;
887
+ color: #333;
888
+ }
889
+
890
+ .user-info p {
891
+ margin: 0;
892
+ color: #666;
893
+ font-size: 0.9em;
894
+ }
895
+
896
+ .user-details {
897
+ padding: 16px;
898
+ }
899
+
900
+ .user-details p {
901
+ margin: 8px 0;
902
+ }
903
+
904
+ .custom-header {
905
+ display: flex;
906
+ justify-content: space-between;
907
+ align-items: center;
908
+ padding: 12px 16px;
909
+ }
910
+
911
+ .custom-header h3 {
912
+ margin: 0;
913
+ color: #333;
914
+ }
915
+
916
+ .status-badge {
917
+ background: #28a745;
918
+ color: white;
919
+ padding: 4px 8px;
920
+ border-radius: 12px;
921
+ font-size: 0.8em;
922
+ }
923
+
924
+ .card-body {
925
+ padding: 16px;
926
+ }
927
+
928
+ .custom-actions {
929
+ display: flex;
930
+ gap: 8px;
931
+ padding: 12px 16px;
932
+ background: #f8f9fa;
933
+ }
934
+
935
+ .btn-primary, .btn-secondary {
936
+ padding: 6px 12px;
937
+ border-radius: 4px;
938
+ border: none;
939
+ cursor: pointer;
940
+ font-size: 0.9em;
941
+ }
942
+
943
+ .btn-primary {
944
+ background: #007bff;
945
+ color: white;
946
+ }
947
+
948
+ .btn-secondary {
949
+ background: #6c757d;
950
+ color: white;
951
+ }
952
+ </style>
953
+ ```
954
+
955
+ ### 卡片网格布局
956
+
957
+ ```svelte
958
+ <script lang="ts">
959
+ import Card from '@ticatec/uniface-element/Card';
960
+
961
+ const projects = [
962
+ {
963
+ id: 1,
964
+ title: '电子商务平台',
965
+ description: '使用 React 和 Node.js 的现代在线购物平台',
966
+ status: '进行中',
967
+ progress: 75
968
+ },
969
+ {
970
+ id: 2,
971
+ title: '移动银行应用',
972
+ description: '适用于 iOS 和 Android 的安全移动银行应用',
973
+ status: '已完成',
974
+ progress: 100
975
+ },
976
+ {
977
+ id: 3,
978
+ title: '数据分析仪表板',
979
+ description: '带有交互式图表的实时分析仪表板',
980
+ status: '规划中',
981
+ progress: 25
982
+ }
983
+ ];
984
+
985
+ const getProjectActions = (project) => [
986
+ {
987
+ icon: 'icon_google_visibility',
988
+ hint: '查看项目',
989
+ callback: (data) => console.log('查看项目:', data.title)
990
+ },
991
+ {
992
+ icon: 'icon_google_edit',
993
+ hint: '编辑项目',
994
+ callback: (data) => console.log('编辑项目:', data.title)
995
+ },
996
+ {
997
+ icon: 'icon_google_more_vert',
998
+ hint: '更多选项',
999
+ callback: (data) => console.log('更多选项:', data.title)
1000
+ }
1001
+ ];
1002
+ </script>
1003
+
1004
+ <div class="project-grid">
1005
+ <h2>项目仪表板</h2>
1006
+
1007
+ <div class="grid">
1008
+ {#each projects as project}
1009
+ <Card
1010
+ title={project.title}
1011
+ variant="3d"
1012
+ actions={getProjectActions(project)}
1013
+ data={project}
1014
+ >
1015
+ <div class="project-card-content">
1016
+ <p class="description">{project.description}</p>
1017
+
1018
+ <div class="project-meta">
1019
+ <div class="status">
1020
+ <span class="status-label">状态:</span>
1021
+ <span class="status-value status-{project.status.toLowerCase().replace(' ', '-')}">
1022
+ {project.status}
1023
+ </span>
1024
+ </div>
1025
+
1026
+ <div class="progress">
1027
+ <span class="progress-label">进度:</span>
1028
+ <div class="progress-bar">
1029
+ <div
1030
+ class="progress-fill"
1031
+ style="width: {project.progress}%"
1032
+ ></div>
1033
+ </div>
1034
+ <span class="progress-text">{project.progress}%</span>
1035
+ </div>
1036
+ </div>
1037
+ </div>
1038
+ </Card>
1039
+ {/each}
1040
+ </div>
1041
+ </div>
1042
+
1043
+ <style>
1044
+ .project-grid {
1045
+ padding: 20px;
1046
+ }
1047
+
1048
+ .project-grid h2 {
1049
+ margin: 0 0 24px 0;
1050
+ color: #333;
1051
+ }
1052
+
1053
+ .grid {
1054
+ display: grid;
1055
+ grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
1056
+ gap: 20px;
1057
+ }
1058
+
1059
+ .project-card-content {
1060
+ padding: 16px;
1061
+ }
1062
+
1063
+ .description {
1064
+ color: #666;
1065
+ line-height: 1.5;
1066
+ margin: 0 0 16px 0;
1067
+ }
1068
+
1069
+ .project-meta {
1070
+ display: flex;
1071
+ flex-direction: column;
1072
+ gap: 12px;
1073
+ }
1074
+
1075
+ .status, .progress {
1076
+ display: flex;
1077
+ align-items: center;
1078
+ gap: 8px;
1079
+ font-size: 0.9em;
1080
+ }
1081
+
1082
+ .status-label, .progress-label {
1083
+ font-weight: 500;
1084
+ color: #333;
1085
+ min-width: 60px;
1086
+ }
1087
+
1088
+ .status-value {
1089
+ padding: 2px 8px;
1090
+ border-radius: 12px;
1091
+ font-size: 0.8em;
1092
+ font-weight: 500;
1093
+ }
1094
+
1095
+ .status-已完成 {
1096
+ background: #d4edda;
1097
+ color: #155724;
1098
+ }
1099
+
1100
+ .status-进行中 {
1101
+ background: #d1ecf1;
1102
+ color: #0c5460;
1103
+ }
1104
+
1105
+ .status-规划中 {
1106
+ background: #fff3cd;
1107
+ color: #856404;
1108
+ }
1109
+
1110
+ .progress-bar {
1111
+ flex: 1;
1112
+ height: 6px;
1113
+ background: #e9ecef;
1114
+ border-radius: 3px;
1115
+ overflow: hidden;
1116
+ }
1117
+
1118
+ .progress-fill {
1119
+ height: 100%;
1120
+ background: #007bff;
1121
+ transition: width 0.3s ease;
1122
+ }
1123
+
1124
+ .progress-text {
1125
+ min-width: 35px;
1126
+ text-align: right;
1127
+ font-size: 0.8em;
1128
+ color: #666;
1129
+ }
1130
+ </style>
1131
+ ```
1132
+
1133
+ ### Card 属性
1134
+
1135
+ | 属性 | 类型 | 默认值 | 描述 |
1136
+ |------|------|--------|------|
1137
+ | `style` | `string` | `''` | 自定义 CSS 样式 |
1138
+ | `title` | `string` | - | 卡片标题文本 |
1139
+ | `actions` | `CardAction[]` | `[]` | 操作按钮配置 |
1140
+ | `variant` | `'plain' \| '3d'` | `'plain'` | 视觉样式变体 |
1141
+ | `iconColor` | `string \| null` | `null` | 操作图标颜色 |
1142
+ | `data` | `any` | - | 传递给操作处理器的数据 |
1143
+
1144
+ ### CardAction 接口
1145
+
1146
+ ```typescript
1147
+ interface CardAction {
1148
+ icon?: string; // 图标类名
1149
+ img?: string; // 图片源 URL
1150
+ hint?: string; // 工具提示文本
1151
+ disabled?: boolean; // 禁用操作
1152
+ callback: (data: any) => void; // 点击处理器
1153
+ }
1154
+ ```
1155
+
1156
+ ## 最佳实践
1157
+
1158
+ ### 1. Split 组件使用
1159
+
1160
+ ```svelte
1161
+ <!-- 为面板提供最小尺寸 -->
1162
+ <style>
1163
+ .resizable-panel {
1164
+ min-width: 200px;
1165
+ min-height: 150px;
1166
+ }
1167
+ </style>
1168
+
1169
+ <!-- 使用适当的绑定 -->
1170
+ <Split bindingPanel={panelElement} direction="vertical" />
1171
+ ```
1172
+
1173
+ ### 2. Drawer 无障碍访问
1174
+
1175
+ ```svelte
1176
+ <!-- 添加适当的 ARIA 标签和键盘支持 -->
1177
+ <Drawer bind:visible={drawerOpen} position="left">
1178
+ <div role="navigation" aria-label="主导航">
1179
+ <!-- 导航内容 -->
1180
+ </div>
1181
+ </Drawer>
1182
+ ```
1183
+
1184
+ ### 3. Tag 管理
1185
+
1186
+ ```svelte
1187
+ <!-- 为可移除标签提供清晰的视觉反馈 -->
1188
+ <Tag
1189
+ text="可移除标签"
1190
+ removable={true}
1191
+ removeHandler={() => handleRemove()}
1192
+ aria-label="删除标签"
1193
+ />
1194
+ ```
1195
+
1196
+ ### 4. Card 组织
1197
+
1198
+ ```svelte
1199
+ <!-- 在网格中使用一致的卡片布局 -->
1200
+ <div class="card-grid">
1201
+ {#each items as item}
1202
+ <Card title={item.title} variant="3d">
1203
+ <!-- 一致的内容结构 -->
1204
+ </Card>
1205
+ {/each}
1206
+ </div>
1207
+
1208
+ <style>
1209
+ .card-grid {
1210
+ display: grid;
1211
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
1212
+ gap: 20px;
1213
+ }
1214
+ </style>
1215
+ ```
1216
+
1217
+ 这些杂项组件为现代应用程序提供了基本的 UI 模式,在保持可用性和无障碍标准的同时提供灵活性和一致的设计。