@ticatec/uniface-element 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/dist/accordion/README.md +169 -0
  2. package/dist/accordion/README_CN.md +176 -0
  3. package/dist/action-bar/README.md +275 -0
  4. package/dist/action-bar/README_CN.md +285 -0
  5. package/dist/app-layout/README.md +374 -0
  6. package/dist/app-layout/README_CN.md +381 -0
  7. package/dist/app-top-bar/README.md +357 -0
  8. package/dist/app-top-bar/README_CN.md +365 -0
  9. package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
  10. package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
  11. package/dist/base-calendar/CalendarBase.svelte +0 -3
  12. package/dist/box/README.md +385 -0
  13. package/dist/box/README_CN.md +393 -0
  14. package/dist/breadcrumbs/README.md +442 -0
  15. package/dist/breadcrumbs/README_CN.md +442 -0
  16. package/dist/button/Button.svelte +27 -7
  17. package/dist/button/Button.svelte.d.ts +3 -1
  18. package/dist/button/IconButton.svelte +26 -6
  19. package/dist/button/IconButton.svelte.d.ts +3 -1
  20. package/dist/button/IconButton_README.md +513 -0
  21. package/dist/button/IconButton_README_CN.md +513 -0
  22. package/dist/button/README.md +428 -0
  23. package/dist/button/README_CN.md +428 -0
  24. package/dist/button/TextButton.svelte +26 -6
  25. package/dist/button/TextButton.svelte.d.ts +3 -1
  26. package/dist/button/TextButton_README.md +571 -0
  27. package/dist/button/TextButton_README_CN.md +571 -0
  28. package/dist/card/README.md +666 -0
  29. package/dist/card/README_CN.md +666 -0
  30. package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
  31. package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
  32. package/dist/cascade-options-select/README.md +663 -2
  33. package/dist/cascade-options-select/README_CN.md +664 -0
  34. package/dist/checkbox/CheckBox.svelte +20 -6
  35. package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
  36. package/dist/checkbox/README.md +562 -0
  37. package/dist/checkbox/README_CN.md +727 -0
  38. package/dist/common-editor/NumberInput.svelte +39 -26
  39. package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
  40. package/dist/concise-data-table/ConciseListTable.svelte +133 -36
  41. package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
  42. package/dist/concise-data-table/DataCell.svelte +5 -6
  43. package/dist/concise-data-table/DataRow.svelte +22 -2
  44. package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
  45. package/dist/concise-data-table/README.md +606 -0
  46. package/dist/concise-data-table/README_CN.md +611 -0
  47. package/dist/context-menu/ContextMenu.svelte +138 -21
  48. package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
  49. package/dist/context-menu/ContextMenuItem.d.ts +20 -4
  50. package/dist/context-menu/README.md +551 -0
  51. package/dist/context-menu/README_CN.md +551 -0
  52. package/dist/criteria-field/CriteriaField.svelte +3 -5
  53. package/dist/criteria-field/README.md +532 -0
  54. package/dist/criteria-field/README_CN.md +532 -0
  55. package/dist/data-table/README.md +712 -0
  56. package/dist/data-table/README_CN.md +712 -0
  57. package/dist/date-picker/DatePicker.svelte +44 -7
  58. package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
  59. package/dist/date-picker/DateTimePicker.svelte +32 -8
  60. package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
  61. package/dist/date-picker/README.md +326 -0
  62. package/dist/date-picker/README_CN.md +316 -0
  63. package/dist/date-picker/ScrollBar.svelte +18 -8
  64. package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
  65. package/dist/date-picker/TimePanel.svelte +5 -5
  66. package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
  67. package/dist/date-range/README.md +374 -0
  68. package/dist/date-range/README_CN.md +374 -0
  69. package/dist/dialog/DialogBoard.svelte +1 -1
  70. package/dist/dialog/README.md +596 -0
  71. package/dist/dialog/README_CN.md +596 -0
  72. package/dist/drawer/README.md +679 -1
  73. package/dist/drawer/README_CN.md +679 -0
  74. package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
  75. package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
  76. package/dist/group-box/group-check-box/README.md +749 -0
  77. package/dist/group-box/group-check-box/README_CN.md +750 -0
  78. package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
  79. package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
  80. package/dist/group-box/group-radio-box/README.md +920 -0
  81. package/dist/group-box/group-radio-box/README_CN.md +920 -0
  82. package/dist/image-files/README.md +1346 -0
  83. package/dist/image-files/README_CN.md +1346 -0
  84. package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
  85. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
  86. package/dist/lib/forwardAllEvents.d.ts +3 -0
  87. package/dist/lib/forwardAllEvents.js +24 -0
  88. package/dist/list-box/README.md +579 -0
  89. package/dist/list-box/README_CN.md +682 -0
  90. package/dist/lookup-editor/LookupEditor.svelte +15 -3
  91. package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
  92. package/dist/lookup-editor/README.md +684 -0
  93. package/dist/lookup-editor/README_CN.md +684 -0
  94. package/dist/memo-editor/MemoEditor.svelte +77 -27
  95. package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
  96. package/dist/memo-editor/README.md +819 -0
  97. package/dist/memo-editor/README_CN.md +819 -0
  98. package/dist/message-box/README.md +398 -0
  99. package/dist/message-box/README_CN.md +398 -0
  100. package/dist/number-editor/NumberEditor.svelte +2 -2
  101. package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
  102. package/dist/number-editor/README.md +353 -22
  103. package/dist/number-editor/README_CN.md +357 -0
  104. package/dist/number-range/README.md +443 -0
  105. package/dist/number-range/README_CN.md +443 -0
  106. package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
  107. package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
  108. package/dist/options-multi-select/README.md +480 -0
  109. package/dist/options-multi-select/README_CN.md +480 -0
  110. package/dist/options-select/OptionsSelect.svelte +36 -5
  111. package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
  112. package/dist/options-select/README.md +632 -0
  113. package/dist/options-select/README_CN.md +632 -0
  114. package/dist/page/README.md +605 -0
  115. package/dist/page/README_CN.md +605 -0
  116. package/dist/pagination/README.md +946 -0
  117. package/dist/pagination/README_CN.md +946 -0
  118. package/dist/pagination-panel/README.md +1075 -0
  119. package/dist/pagination-panel/README_CN.md +1075 -0
  120. package/dist/popup-hint/README.md +841 -0
  121. package/dist/popup-hint/README_CN.md +840 -0
  122. package/dist/progress-bar/README.md +242 -0
  123. package/dist/progress-bar/README_CN.md +242 -0
  124. package/dist/progress-step-bar/README.md +316 -0
  125. package/dist/progress-step-bar/README_CN.md +316 -0
  126. package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
  127. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
  128. package/dist/prompts-text-editor/README.md +329 -0
  129. package/dist/prompts-text-editor/README_CN.md +329 -0
  130. package/dist/property-editor/README.md +969 -0
  131. package/dist/property-editor/README_CN.md +969 -0
  132. package/dist/radio-button/README.md +372 -0
  133. package/dist/radio-button/README_CN.md +372 -0
  134. package/dist/radio-button/RadioButton.svelte +32 -3
  135. package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
  136. package/dist/search-box/README.md +425 -0
  137. package/dist/search-box/README_CN.md +424 -0
  138. package/dist/search-box/SearchBox.svelte +22 -6
  139. package/dist/search-box/SearchBox.svelte.d.ts +4 -1
  140. package/dist/tabs/README.md +919 -0
  141. package/dist/tabs/README_CN.md +920 -0
  142. package/dist/tag/README.md +922 -0
  143. package/dist/tag/README_CN.md +922 -0
  144. package/dist/text-editor/PasswordEditor.svelte +17 -2
  145. package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
  146. package/dist/text-editor/PasswordEditor_README.md +551 -0
  147. package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
  148. package/dist/text-editor/README.md +466 -0
  149. package/dist/text-editor/README_CN.md +466 -0
  150. package/dist/text-editor/TextEditor.svelte +51 -19
  151. package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
  152. package/dist/ticatec-uniface-web.css +1 -0
  153. package/dist/time-editor/README.md +498 -24
  154. package/dist/time-editor/README_CN.md +498 -0
  155. package/dist/time-editor/TimeEditor.svelte +7 -3
  156. package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
  157. package/dist/toast/README.md +667 -0
  158. package/dist/toast/README_CN.md +667 -0
  159. package/dist/transfer/README.md +795 -0
  160. package/dist/transfer/Transfer.svelte +6 -4
  161. package/dist/transfer/Transfer.svelte.d.ts +3 -1
  162. package/dist/tree-view/README.md +761 -0
  163. package/dist/tree-view/README_CN.md +761 -0
  164. package/dist/tree-view/TreeView.svelte +5 -3
  165. package/dist/tree-view/TreeView.svelte.d.ts +3 -1
  166. package/dist/unit-number-editor/README.md +546 -20
  167. package/dist/unit-number-editor/README_CN.md +525 -0
  168. package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
  169. package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
  170. package/docs/form-field/cn/README_CN.md +364 -0
  171. package/docs/form-field/en/README.md +364 -0
  172. package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
  173. package/docs/form-panel/flex-form/en/README.md +586 -0
  174. package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
  175. package/docs/form-panel/flex-row-form/en/README.md +787 -0
  176. package/docs/form-panel/grid-form/en/README.md +744 -0
  177. package/package.json +1 -1
  178. package/dist/drawer/README-CN.md +0 -1
@@ -0,0 +1,727 @@
1
+ # CheckBox 复选框组件
2
+
3
+ 一个功能丰富的复选框组件,支持多种状态包括半选状态,具备全面的事件处理和无障碍访问功能。非常适合单项选择、开关选项和表单控件。
4
+
5
+ ## 功能特性
6
+
7
+ - **多种状态**: 选中、未选中和半选状态
8
+ - **事件处理**: 支持点击、值变化、聚焦和失焦事件
9
+ - **无障碍访问**: 正确的ARIA属性和键盘导航
10
+ - **自动聚焦**: 可选的自动聚焦功能
11
+ - **自定义样式**: 灵活的样式定制和紧凑模式
12
+ - **只读和禁用**: 支持非交互状态
13
+ - **程序化控制**: 聚焦管理和值控制
14
+
15
+ ## 基本用法
16
+
17
+ ```svelte
18
+ <script>
19
+ import CheckBox from '@ticatec/uniface-element/CheckBox';
20
+
21
+ let isChecked = false;
22
+
23
+ const handleChange = (value) => {
24
+ console.log('复选框状态变化:', value);
25
+ isChecked = value;
26
+ };
27
+ </script>
28
+
29
+ <CheckBox
30
+ label="接受条款和条件"
31
+ bind:value={isChecked}
32
+ onChange={handleChange}
33
+ />
34
+ ```
35
+
36
+ ## 属性参数
37
+
38
+ | 属性 | 类型 | 默认值 | 描述 |
39
+ |------|------|---------|-------------|
40
+ | `label` | `string \| null` | `null` | 复选框旁边显示的文本标签 |
41
+ | `readonly` | `boolean` | `false` | 是否为只读状态 |
42
+ | `disabled` | `boolean` | `false` | 是否禁用复选框 |
43
+ | `value` | `boolean` | `false` | 复选框的选中状态 |
44
+ | `indeterminate` | `boolean` | `false` | 半选状态(部分选择) |
45
+ | `style` | `string` | `''` | 自定义CSS样式 |
46
+ | `compact` | `boolean` | `false` | 紧凑显示模式 |
47
+ | `onclick` | `((event: MouseEvent) => void) \| null` | `null` | 点击事件处理器 |
48
+ | `onchange` | `OnChangeHandler<boolean>` | - | 值变化事件处理器 |
49
+ | `onfocus` | `((event: FocusEvent) => void) \| null` | `null` | 聚焦事件处理器 |
50
+ | `onblur` | `((event: FocusEvent) => void) \| null` | `null` | 失焦事件处理器 |
51
+ | `autoFocus` | `boolean` | `false` | 是否在组件挂载时自动聚焦 |
52
+
53
+ ## 方法
54
+
55
+ | 方法 | 描述 |
56
+ |------|-----|
57
+ | `setFocus()` | 程序化地使复选框获得焦点 |
58
+
59
+ ## 基本示例
60
+
61
+ ### 简单复选框
62
+
63
+ ```svelte
64
+ <script>
65
+ let agreed = false;
66
+ </script>
67
+
68
+ <CheckBox
69
+ label="我同意条款"
70
+ bind:value={agreed}
71
+ />
72
+
73
+ <p>状态: {agreed ? '已同意' : '未同意'}</p>
74
+ ```
75
+
76
+ ### 带变化处理器
77
+
78
+ ```svelte
79
+ <script>
80
+ let notifications = true;
81
+
82
+ const handleNotificationChange = (value) => {
83
+ console.log('通知设置:', value ? '启用' : '禁用');
84
+ notifications = value;
85
+ };
86
+ </script>
87
+
88
+ <CheckBox
89
+ label="启用通知"
90
+ value={notifications}
91
+ onChange={handleNotificationChange}
92
+ />
93
+ ```
94
+
95
+ ### 半选状态
96
+
97
+ ```svelte
98
+ <script>
99
+ let parentChecked = false;
100
+ let parentIndeterminate = false;
101
+ let childItems = [
102
+ { id: 1, name: '项目 1', checked: true },
103
+ { id: 2, name: '项目 2', checked: false },
104
+ { id: 3, name: '项目 3', checked: true }
105
+ ];
106
+
107
+ $: {
108
+ const checkedCount = childItems.filter(item => item.checked).length;
109
+ parentChecked = checkedCount === childItems.length;
110
+ parentIndeterminate = checkedCount > 0 && checkedCount < childItems.length;
111
+ }
112
+
113
+ const handleParentChange = (value) => {
114
+ childItems = childItems.map(item => ({ ...item, checked: value }));
115
+ };
116
+
117
+ const handleChildChange = (id) => (value) => {
118
+ childItems = childItems.map(item =>
119
+ item.id === id ? { ...item, checked: value } : item
120
+ );
121
+ };
122
+ </script>
123
+
124
+ <CheckBox
125
+ label="全选"
126
+ value={parentChecked}
127
+ indeterminate={parentIndeterminate}
128
+ onChange={handleParentChange}
129
+ />
130
+
131
+ {#each childItems as item}
132
+ <div style="margin-left: 20px;">
133
+ <CheckBox
134
+ label={item.name}
135
+ value={item.checked}
136
+ onChange={handleChildChange(item.id)}
137
+ />
138
+ </div>
139
+ {/each}
140
+ ```
141
+
142
+ ## 事件处理
143
+
144
+ ```svelte
145
+ <script>
146
+ let value = false;
147
+ let focusCount = 0;
148
+ let clickCount = 0;
149
+
150
+ const handleChange = (newValue) => {
151
+ console.log('值变化为:', newValue);
152
+ value = newValue;
153
+ };
154
+
155
+ const handleClick = (event) => {
156
+ clickCount++;
157
+ console.log('复选框被点击', clickCount, '次');
158
+ };
159
+
160
+ const handleFocus = (event) => {
161
+ focusCount++;
162
+ console.log('复选框获得焦点');
163
+ };
164
+
165
+ const handleBlur = (event) => {
166
+ console.log('复选框失去焦点');
167
+ };
168
+ </script>
169
+
170
+ <CheckBox
171
+ label="交互式复选框"
172
+ {value}
173
+ onChange={handleChange}
174
+ onClick={handleClick}
175
+ onfocus={handleFocus}
176
+ onblur={handleBlur}
177
+ />
178
+
179
+ <div>
180
+ <p>当前值: {value}</p>
181
+ <p>聚焦次数: {focusCount}</p>
182
+ <p>点击次数: {clickCount}</p>
183
+ </div>
184
+ ```
185
+
186
+ ## 状态和模式
187
+
188
+ ### 禁用状态
189
+
190
+ ```svelte
191
+ <CheckBox
192
+ label="禁用未选中"
193
+ value={false}
194
+ disabled={true}
195
+ />
196
+
197
+ <CheckBox
198
+ label="禁用已选中"
199
+ value={true}
200
+ disabled={true}
201
+ />
202
+ ```
203
+
204
+ ### 只读状态
205
+
206
+ ```svelte
207
+ <CheckBox
208
+ label="只读未选中"
209
+ value={false}
210
+ readonly={true}
211
+ />
212
+
213
+ <CheckBox
214
+ label="只读已选中"
215
+ value={true}
216
+ readonly={true}
217
+ />
218
+ ```
219
+
220
+ ### 紧凑模式
221
+
222
+ ```svelte
223
+ <div style="display: flex; gap: 16px; align-items: center;">
224
+ <CheckBox label="普通" value={true} />
225
+ <CheckBox label="紧凑" value={true} compact={true} />
226
+ </div>
227
+ ```
228
+
229
+ ### 自动聚焦
230
+
231
+ ```svelte
232
+ <CheckBox
233
+ label="自动聚焦的复选框"
234
+ autoFocus={true}
235
+ />
236
+ ```
237
+
238
+ ## 高级示例
239
+
240
+ ### 表单集成
241
+
242
+ ```svelte
243
+ <script>
244
+ let formData = {
245
+ newsletter: false,
246
+ terms: false,
247
+ privacy: false
248
+ };
249
+
250
+ $: canSubmit = formData.terms && formData.privacy;
251
+
252
+ const handleSubmit = () => {
253
+ if (canSubmit) {
254
+ console.log('表单提交:', formData);
255
+ }
256
+ };
257
+
258
+ const updateField = (field) => (value) => {
259
+ formData = { ...formData, [field]: value };
260
+ };
261
+ </script>
262
+
263
+ <form on:submit|preventDefault={handleSubmit}>
264
+ <div class="form-section">
265
+ <CheckBox
266
+ label="订阅邮件(可选)"
267
+ value={formData.newsletter}
268
+ onChange={updateField('newsletter')}
269
+ />
270
+ </div>
271
+
272
+ <div class="form-section">
273
+ <CheckBox
274
+ label="我接受服务条款 *"
275
+ value={formData.terms}
276
+ onChange={updateField('terms')}
277
+ />
278
+ </div>
279
+
280
+ <div class="form-section">
281
+ <CheckBox
282
+ label="我接受隐私政策 *"
283
+ value={formData.privacy}
284
+ onChange={updateField('privacy')}
285
+ />
286
+ </div>
287
+
288
+ <button type="submit" disabled={!canSubmit}>
289
+ 提交
290
+ </button>
291
+ </form>
292
+
293
+ <style>
294
+ .form-section {
295
+ margin: 16px 0;
296
+ }
297
+ </style>
298
+ ```
299
+
300
+ ### 设置面板
301
+
302
+ ```svelte
303
+ <script>
304
+ let settings = {
305
+ darkMode: false,
306
+ notifications: true,
307
+ autoSave: true,
308
+ soundEffects: false
309
+ };
310
+
311
+ const updateSetting = (key) => (value) => {
312
+ settings = { ...settings, [key]: value };
313
+ localStorage.setItem('app-settings', JSON.stringify(settings));
314
+ };
315
+
316
+ // 组件挂载时加载设置
317
+ import { onMount } from 'svelte';
318
+
319
+ onMount(() => {
320
+ const saved = localStorage.getItem('app-settings');
321
+ if (saved) {
322
+ settings = { ...settings, ...JSON.parse(saved) };
323
+ }
324
+ });
325
+ </script>
326
+
327
+ <div class="settings-panel">
328
+ <h3>应用设置</h3>
329
+
330
+ <div class="setting-group">
331
+ <h4>外观</h4>
332
+ <CheckBox
333
+ label="深色模式"
334
+ value={settings.darkMode}
335
+ onChange={updateSetting('darkMode')}
336
+ />
337
+ </div>
338
+
339
+ <div class="setting-group">
340
+ <h4>通知</h4>
341
+ <CheckBox
342
+ label="启用通知"
343
+ value={settings.notifications}
344
+ onChange={updateSetting('notifications')}
345
+ />
346
+ </div>
347
+
348
+ <div class="setting-group">
349
+ <h4>编辑器</h4>
350
+ <CheckBox
351
+ label="自动保存文档"
352
+ value={settings.autoSave}
353
+ onChange={updateSetting('autoSave')}
354
+ />
355
+ </div>
356
+
357
+ <div class="setting-group">
358
+ <h4>音频</h4>
359
+ <CheckBox
360
+ label="音效"
361
+ value={settings.soundEffects}
362
+ onChange={updateSetting('soundEffects')}
363
+ />
364
+ </div>
365
+ </div>
366
+
367
+ <style>
368
+ .settings-panel {
369
+ max-width: 400px;
370
+ padding: 20px;
371
+ border: 1px solid #ddd;
372
+ border-radius: 8px;
373
+ }
374
+
375
+ .setting-group {
376
+ margin: 20px 0;
377
+ }
378
+
379
+ .setting-group h4 {
380
+ margin: 0 0 12px 0;
381
+ color: #666;
382
+ font-size: 14px;
383
+ text-transform: uppercase;
384
+ }
385
+ </style>
386
+ ```
387
+
388
+ ### 待办事项列表与全选
389
+
390
+ ```svelte
391
+ <script>
392
+ let todos = [
393
+ { id: 1, text: '买菜', completed: false },
394
+ { id: 2, text: '遛狗', completed: true },
395
+ { id: 3, text: '看书', completed: false },
396
+ { id: 4, text: '给妈妈打电话', completed: true }
397
+ ];
398
+
399
+ $: completedCount = todos.filter(todo => todo.completed).length;
400
+ $: allCompleted = completedCount === todos.length;
401
+ $: someCompleted = completedCount > 0 && completedCount < todos.length;
402
+
403
+ const toggleAll = (value) => {
404
+ todos = todos.map(todo => ({ ...todo, completed: value }));
405
+ };
406
+
407
+ const toggleTodo = (id) => (completed) => {
408
+ todos = todos.map(todo =>
409
+ todo.id === id ? { ...todo, completed } : todo
410
+ );
411
+ };
412
+ </script>
413
+
414
+ <div class="todo-list">
415
+ <h3>待办事项</h3>
416
+
417
+ <CheckBox
418
+ label={`全选 (${completedCount}/${todos.length})`}
419
+ value={allCompleted}
420
+ indeterminate={someCompleted}
421
+ onChange={toggleAll}
422
+ style="border-bottom: 1px solid #ddd; padding-bottom: 12px; margin-bottom: 12px;"
423
+ />
424
+
425
+ {#each todos as todo}
426
+ <div class="todo-item" class:completed={todo.completed}>
427
+ <CheckBox
428
+ label={todo.text}
429
+ value={todo.completed}
430
+ onChange={toggleTodo(todo.id)}
431
+ />
432
+ </div>
433
+ {/each}
434
+
435
+ <div class="todo-summary">
436
+ 已完成 {completedCount} / {todos.length} 项
437
+ </div>
438
+ </div>
439
+
440
+ <style>
441
+ .todo-list {
442
+ max-width: 400px;
443
+ border: 1px solid #ddd;
444
+ border-radius: 8px;
445
+ padding: 16px;
446
+ }
447
+
448
+ .todo-item {
449
+ margin: 8px 0;
450
+ transition: opacity 0.2s;
451
+ }
452
+
453
+ .todo-item.completed {
454
+ opacity: 0.6;
455
+ }
456
+
457
+ .todo-summary {
458
+ margin-top: 16px;
459
+ padding-top: 12px;
460
+ border-top: 1px solid #ddd;
461
+ font-size: 14px;
462
+ color: #666;
463
+ text-align: center;
464
+ }
465
+ </style>
466
+ ```
467
+
468
+ ### 权限管理
469
+
470
+ ```svelte
471
+ <script>
472
+ let permissions = {
473
+ read: true,
474
+ write: false,
475
+ delete: false,
476
+ admin: false
477
+ };
478
+
479
+ const updatePermission = (key) => (value) => {
480
+ // 自动管理依赖关系
481
+ if (key === 'admin' && value) {
482
+ permissions = { read: true, write: true, delete: true, admin: true };
483
+ } else if (key === 'admin' && !value) {
484
+ permissions = { ...permissions, admin: false };
485
+ } else if (key === 'read' && !value) {
486
+ permissions = { read: false, write: false, delete: false, admin: false };
487
+ } else if ((key === 'write' || key === 'delete') && value && !permissions.read) {
488
+ permissions = { ...permissions, read: true, [key]: value };
489
+ } else {
490
+ permissions = { ...permissions, [key]: value };
491
+ }
492
+ };
493
+
494
+ $: canWrite = permissions.read;
495
+ $: canDelete = permissions.read;
496
+ $: canAdmin = permissions.read && permissions.write && permissions.delete;
497
+ </script>
498
+
499
+ <div class="permissions-panel">
500
+ <h3>用户权限</h3>
501
+
502
+ <CheckBox
503
+ label="读取权限"
504
+ value={permissions.read}
505
+ onChange={updatePermission('read')}
506
+ />
507
+
508
+ <CheckBox
509
+ label="写入权限"
510
+ value={permissions.write}
511
+ disabled={!canWrite}
512
+ onChange={updatePermission('write')}
513
+ style="margin-left: 20px;"
514
+ />
515
+
516
+ <CheckBox
517
+ label="删除权限"
518
+ value={permissions.delete}
519
+ disabled={!canDelete}
520
+ onChange={updatePermission('delete')}
521
+ style="margin-left: 20px;"
522
+ />
523
+
524
+ <CheckBox
525
+ label="管理员"
526
+ value={permissions.admin}
527
+ disabled={!canAdmin}
528
+ onChange={updatePermission('admin')}
529
+ style="margin-top: 16px; padding-top: 16px; border-top: 1px solid #ddd;"
530
+ />
531
+
532
+ <div class="permission-summary">
533
+ <h4>当前访问级别:</h4>
534
+ <p>
535
+ {#if permissions.admin}
536
+ 管理员(完全访问)
537
+ {:else if permissions.delete}
538
+ 编辑者(读取、写入、删除)
539
+ {:else if permissions.write}
540
+ 贡献者(读取、写入)
541
+ {:else if permissions.read}
542
+ 查看者(仅读取)
543
+ {:else}
544
+ 无访问权限
545
+ {/if}
546
+ </p>
547
+ </div>
548
+ </div>
549
+
550
+ <style>
551
+ .permissions-panel {
552
+ max-width: 350px;
553
+ padding: 20px;
554
+ border: 1px solid #ddd;
555
+ border-radius: 8px;
556
+ }
557
+
558
+ .permission-summary {
559
+ margin-top: 20px;
560
+ padding: 16px;
561
+ background: #f5f5f5;
562
+ border-radius: 4px;
563
+ }
564
+
565
+ .permission-summary h4 {
566
+ margin: 0 0 8px 0;
567
+ font-size: 14px;
568
+ }
569
+
570
+ .permission-summary p {
571
+ margin: 0;
572
+ font-weight: 500;
573
+ }
574
+ </style>
575
+ ```
576
+
577
+ ### 功能开关列表
578
+
579
+ ```svelte
580
+ <script>
581
+ let features = [
582
+ { id: 'beta-ui', name: 'Beta UI 功能', enabled: false, description: '尝试新的界面元素' },
583
+ { id: 'analytics', name: '使用分析', enabled: true, description: '帮助改进应用' },
584
+ { id: 'experiments', name: '实验性功能', enabled: false, description: '访问前沿功能' },
585
+ { id: 'debug', name: '调试模式', enabled: false, description: '显示额外的调试信息' }
586
+ ];
587
+
588
+ const toggleFeature = (id) => (enabled) => {
589
+ features = features.map(feature =>
590
+ feature.id === id ? { ...feature, enabled } : feature
591
+ );
592
+ };
593
+
594
+ $: enabledCount = features.filter(f => f.enabled).length;
595
+ </script>
596
+
597
+ <div class="feature-toggles">
598
+ <h3>功能开关 (已启用 {enabledCount} 个)</h3>
599
+
600
+ {#each features as feature}
601
+ <div class="feature-item">
602
+ <CheckBox
603
+ label={feature.name}
604
+ value={feature.enabled}
605
+ onChange={toggleFeature(feature.id)}
606
+ />
607
+ <p class="feature-description">{feature.description}</p>
608
+ </div>
609
+ {/each}
610
+ </div>
611
+
612
+ <style>
613
+ .feature-toggles {
614
+ max-width: 500px;
615
+ }
616
+
617
+ .feature-item {
618
+ margin: 16px 0;
619
+ padding: 12px;
620
+ border: 1px solid #e0e0e0;
621
+ border-radius: 4px;
622
+ }
623
+
624
+ .feature-description {
625
+ margin: 8px 0 0 24px;
626
+ font-size: 13px;
627
+ color: #666;
628
+ }
629
+ </style>
630
+ ```
631
+
632
+ ## 程序化控制
633
+
634
+ ```svelte
635
+ <script>
636
+ let checkbox;
637
+ let value = false;
638
+
639
+ const focusCheckbox = () => {
640
+ checkbox?.setFocus();
641
+ };
642
+
643
+ const toggleValue = () => {
644
+ value = !value;
645
+ };
646
+ </script>
647
+
648
+ <div class="controls">
649
+ <button on:click={focusCheckbox}>聚焦复选框</button>
650
+ <button on:click={toggleValue}>切换值</button>
651
+ </div>
652
+
653
+ <CheckBox
654
+ bind:this={checkbox}
655
+ label="程序化控制"
656
+ {value}
657
+ onChange={(v) => value = v}
658
+ />
659
+
660
+ <style>
661
+ .controls {
662
+ margin-bottom: 16px;
663
+ display: flex;
664
+ gap: 8px;
665
+ }
666
+ </style>
667
+ ```
668
+
669
+ ## 自定义样式
670
+
671
+ ```svelte
672
+ <CheckBox
673
+ label="自定义样式复选框"
674
+ value={true}
675
+ style="
676
+ padding: 12px;
677
+ background: #f0f8ff;
678
+ border: 2px solid #007acc;
679
+ border-radius: 8px;
680
+ font-weight: 500;
681
+ "
682
+ />
683
+ ```
684
+
685
+ ## 无障碍访问
686
+
687
+ CheckBox组件包含:
688
+
689
+ - 正确的语义化`input[type="checkbox"]`元素
690
+ - 为屏幕阅读器关联的标签
691
+ - 键盘导航支持(Tab、空格键)
692
+ - 聚焦和失焦事件处理
693
+ - 禁用状态管理
694
+ - 半选状态的ARIA属性
695
+
696
+ ### 最佳实践
697
+
698
+ ```svelte
699
+ <!-- 良好:清晰、描述性的标签 -->
700
+ <CheckBox label="启用双重认证" />
701
+
702
+ <!-- 良好:相关复选框分组 -->
703
+ <fieldset>
704
+ <legend>通知偏好</legend>
705
+ <CheckBox label="邮件通知" />
706
+ <CheckBox label="短信通知" />
707
+ <CheckBox label="推送通知" />
708
+ </fieldset>
709
+
710
+ <!-- 良好:标明必填字段 -->
711
+ <CheckBox label="我同意服务条款 *" />
712
+ ```
713
+
714
+ ## 浏览器支持
715
+
716
+ 在支持以下特性的所有现代浏览器中工作:
717
+ - ES6+ JavaScript
718
+ - 现代DOM API
719
+ - CSS自定义属性
720
+ - HTML5表单元素
721
+
722
+ ## 性能考虑
723
+
724
+ - 高效的事件处理和适当的清理
725
+ - 响应式更新的最小重新渲染
726
+ - 轻量级DOM结构
727
+ - 优化的焦点管理