@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,228 @@
1
+ # DateTimePicker 组件
2
+
3
+ 日期时间选择器组件。
4
+
5
+ ## 属性
6
+
7
+ | 属性 | 类型 | 默认值 | 描述 |
8
+ |------|------|--------|------|
9
+ | `variant` | `'' \| 'plain' \| 'outlined' \| 'filled'` | `''` | 外观变体 |
10
+ | `disabled` | `boolean` | `false` | 是否禁用 |
11
+ | `readonly` | `boolean` | `false` | 是否只读 |
12
+ | `compact` | `boolean` | `false` | 是否紧凑模式 |
13
+ | `value` | `Date \| string \| null` | `null` | 日期时间值 |
14
+ | `format` | `string` | `'YYYY-MM-DD HH:mm'` | 日期时间格式 |
15
+ | `placeholder` | `string` | `''` | 占位符文本 |
16
+ | `displayMode` | `DisplayMode` | `DisplayMode.Edit` | 显示模式 |
17
+ | `minDateTime` | `Date \| string \| null` | `null` | 最小日期时间 |
18
+ | `maxDateTime` | `Date \| string \| null` | `null` | 最大日期时间 |
19
+ | `minuteStep` | `number` | `1` | 分钟步长 |
20
+ | `locale` | `string` | `'zh-CN'` | 语言区域 |
21
+ | `style` | `string` | `''` | 自定义样式 |
22
+ | `onChange` | `OnChangeHandler<Date>` | - | 值变化回调 |
23
+
24
+ ## 使用示例
25
+
26
+ ```svelte
27
+ <script lang="ts">
28
+ import DateTimePicker from '@ticatec/uniface-element/DateTimePicker';
29
+
30
+ let appointmentTime: Date | null = null;
31
+ let eventStartTime: Date = new Date();
32
+ let eventEndTime: Date | null = null;
33
+
34
+ const handleAppointmentChange = (dateTime: Date): void => {
35
+ appointmentTime = dateTime;
36
+ console.log('预约时间:', dateTime);
37
+ };
38
+
39
+ const handleEventStartChange = (dateTime: Date): void => {
40
+ eventStartTime = dateTime;
41
+ // 自动设置结束时间为开始时间后1小时
42
+ if (!eventEndTime) {
43
+ eventEndTime = new Date(dateTime.getTime() + 60 * 60 * 1000);
44
+ }
45
+ };
46
+
47
+ const handleEventEndChange = (dateTime: Date): void => {
48
+ eventEndTime = dateTime;
49
+ };
50
+ </script>
51
+
52
+ <!-- 预约时间选择 -->
53
+ <DateTimePicker
54
+ placeholder="请选择预约时间"
55
+ minDateTime={new Date()}
56
+ minuteStep={15}
57
+ bind:value={appointmentTime}
58
+ onChange={handleAppointmentChange}
59
+ />
60
+
61
+ <!-- 事件开始时间 -->
62
+ <DateTimePicker
63
+ placeholder="请选择开始时间"
64
+ bind:value={eventStartTime}
65
+ onChange={handleEventStartChange}
66
+ />
67
+
68
+ <!-- 事件结束时间 -->
69
+ <DateTimePicker
70
+ placeholder="请选择结束时间"
71
+ minDateTime={eventStartTime}
72
+ bind:value={eventEndTime}
73
+ onChange={handleEventEndChange}
74
+ />
75
+ ```
76
+
77
+ ## 高级用法
78
+
79
+ ### 会议室预订
80
+ ```svelte
81
+ <script lang="ts">
82
+ interface MeetingSlot {
83
+ start: Date;
84
+ end: Date;
85
+ duration: number; // 分钟
86
+ }
87
+
88
+ let meetingStart: Date | null = null;
89
+ let meetingEnd: Date | null = null;
90
+
91
+ // 工作时间限制
92
+ const getWorkingHourLimits = (date: Date): { min: Date; max: Date } => {
93
+ const workStart = new Date(date);
94
+ workStart.setHours(9, 0, 0, 0);
95
+
96
+ const workEnd = new Date(date);
97
+ workEnd.setHours(18, 0, 0, 0);
98
+
99
+ return { min: workStart, max: workEnd };
100
+ };
101
+
102
+ const handleMeetingStartChange = (startTime: Date): void => {
103
+ meetingStart = startTime;
104
+
105
+ // 自动设置结束时间(默认1小时后)
106
+ if (!meetingEnd) {
107
+ meetingEnd = new Date(startTime.getTime() + 60 * 60 * 1000);
108
+ }
109
+ };
110
+
111
+ const calculateDuration = (start: Date | null, end: Date | null): number => {
112
+ if (!start || !end) return 0;
113
+ return Math.round((end.getTime() - start.getTime()) / (1000 * 60));
114
+ };
115
+
116
+ $: meetingDuration = calculateDuration(meetingStart, meetingEnd);
117
+ $: workingLimits = meetingStart ? getWorkingHourLimits(meetingStart) : null;
118
+ </script>
119
+
120
+ <div class="meeting-booking">
121
+ <div class="datetime-field">
122
+ <label>会议开始时间:</label>
123
+ <DateTimePicker
124
+ placeholder="请选择开始时间"
125
+ minDateTime={new Date()}
126
+ minuteStep={15}
127
+ bind:value={meetingStart}
128
+ onChange={handleMeetingStartChange}
129
+ />
130
+ </div>
131
+
132
+ <div class="datetime-field">
133
+ <label>会议结束时间:</label>
134
+ <DateTimePicker
135
+ placeholder="请选择结束时间"
136
+ minDateTime={meetingStart}
137
+ maxDateTime={workingLimits?.max}
138
+ minuteStep={15}
139
+ bind:value={meetingEnd}
140
+ />
141
+ </div>
142
+
143
+ {#if meetingDuration > 0}
144
+ <div class="duration-info">
145
+ 会议时长:{Math.floor(meetingDuration / 60)}小时{meetingDuration % 60}分钟
146
+ </div>
147
+ {/if}
148
+
149
+ {#if workingLimits && meetingEnd && meetingEnd > workingLimits.max}
150
+ <div class="warning">注意:会议结束时间超出工作时间</div>
151
+ {/if}
152
+ </div>
153
+ ```
154
+
155
+ ## 最佳实践
156
+
157
+ ### 1. 设置合理的时间范围
158
+ ```svelte
159
+ <script lang="ts">
160
+ // 预约:只能选择未来时间
161
+ const futureOnly: Date = new Date();
162
+ futureOnly.setMinutes(futureOnly.getMinutes() + 30); // 至少提前30分钟
163
+
164
+ // 工作时间:限制在工作日的工作时间内
165
+ const isWorkingTime = (date: Date): boolean => {
166
+ const day: number = date.getDay();
167
+ const hour: number = date.getHours();
168
+ return day >= 1 && day <= 5 && hour >= 9 && hour <= 18;
169
+ };
170
+ </script>
171
+
172
+ <!-- 预约系统 -->
173
+ <DateTimePicker
174
+ minDateTime={futureOnly}
175
+ minuteStep={30}
176
+ placeholder="选择预约时间"
177
+ />
178
+ ```
179
+
180
+ ### 2. 本地化和格式化
181
+ ```svelte
182
+ <DateTimePicker
183
+ locale="zh-CN"
184
+ format="YYYY年MM月DD日 HH:mm"
185
+ placeholder="请选择日期时间"
186
+ />
187
+
188
+ <DateTimePicker
189
+ locale="en-US"
190
+ format="MM/DD/YYYY hh:mm A"
191
+ placeholder="Select date and time"
192
+ />
193
+ ```
194
+
195
+ ### 3. 表单验证
196
+ ```svelte
197
+ <script lang="ts">
198
+ let selectedDateTime: Date | null = null;
199
+ let error: string = '';
200
+
201
+ const validateDateTime = (dateTime: Date | null): void => {
202
+ if (!dateTime) {
203
+ error = '请选择日期时间';
204
+ return;
205
+ }
206
+
207
+ const now: Date = new Date();
208
+ const minTime: Date = new Date(now.getTime() + 24 * 60 * 60 * 1000); // 24小时后
209
+
210
+ if (dateTime < minTime) {
211
+ error = '请选择24小时后的时间';
212
+ return;
213
+ }
214
+
215
+ error = '';
216
+ };
217
+
218
+ $: validateDateTime(selectedDateTime);
219
+ </script>
220
+
221
+ <DateTimePicker
222
+ bind:value={selectedDateTime}
223
+ onChange={validateDateTime}
224
+ />
225
+ {#if error}
226
+ <div class="error-message">{error}</div>
227
+ {/if}
228
+ ```
@@ -0,0 +1,405 @@
1
+ # GroupCheckBox 组件
2
+
3
+ 复选框组组件,将多个复选框选项组织在一起,支持位运算和字符串分隔符两种值存储模式。通常用于多选场景,比单独使用多个CheckBox更加方便。
4
+
5
+ ## 属性
6
+
7
+ | 属性 | 类型 | 默认值 | 描述 |
8
+ |------|------|--------|------|
9
+ | `variant` | `'' \| 'plain' \| 'outlined' \| 'filled'` | `''` | 外观变体 |
10
+ | `disabled` | `boolean` | `false` | 是否禁用 |
11
+ | `readonly` | `boolean` | `false` | 是否只读 |
12
+ | `compact` | `boolean` | `false` | 是否紧凑模式 |
13
+ | `value` | `string \| number` | - | 选中的值(字符串或位值) |
14
+ | `bitBase` | `boolean` | `false` | 是否使用位运算模式 |
15
+ | `options` | `Array<OptionItem>` | - | 选项数组 |
16
+ | `keyField` | `string` | `'code'` | 值字段名 |
17
+ | `textField` | `string` | `'text'` | 显示字段名 |
18
+ | `delimiter` | `string` | `';'` | 字符串模式下的分隔符 |
19
+ | `displayMode` | `DisplayMode` | `DisplayMode.Edit` | 显示模式 |
20
+ | `item$style` | `string` | `''` | 单个复选框的样式 |
21
+ | `disabledOptions` | `Array<string>` | `[]` | 禁用的选项值 |
22
+ | `hideOptions` | `Array<string>` | `[]` | 隐藏的选项值 |
23
+ | `style` | `string` | `''` | 自定义样式 |
24
+ | `onChange` | `OnChangeHandler<string \| number>` | - | 值变化回调 |
25
+
26
+ ## 使用示例
27
+
28
+ ```svelte
29
+ <script lang="ts">
30
+ import type { OptionItem } from '@ticatec/uniface-element/types';
31
+ import GroupCheckBox from '@ticatec/uniface-element/GroupCheckBox';
32
+
33
+ // 权限选项
34
+ const permissions: OptionItem[] = [
35
+ { code: 'read', text: '读取权限' },
36
+ { code: 'write', text: '写入权限' },
37
+ { code: 'delete', text: '删除权限' },
38
+ { code: 'admin', text: '管理权限' }
39
+ ];
40
+
41
+ // 兴趣爱好选项
42
+ const hobbies: OptionItem[] = [
43
+ { code: 'sports', text: '运动' },
44
+ { code: 'music', text: '音乐' },
45
+ { code: 'reading', text: '阅读' },
46
+ { code: 'travel', text: '旅行' },
47
+ { code: 'cooking', text: '烹饪' }
48
+ ];
49
+
50
+ let userPermissions: number = 0; // 使用位运算
51
+ let userHobbies: string = ''; // 使用字符串分隔符
52
+ let userSkills: string = '';
53
+
54
+ const handlePermissionChange = (value: number): void => {
55
+ userPermissions = value;
56
+ console.log('用户权限(位值):', value);
57
+
58
+ // 解析位值以查看具体权限
59
+ const selectedPermissions: string[] = [];
60
+ let bitValue: number = value;
61
+ let index: number = 0;
62
+ while (bitValue > 0) {
63
+ if (bitValue & 1) {
64
+ selectedPermissions.push(permissions[index].text);
65
+ }
66
+ bitValue >>= 1;
67
+ index++;
68
+ }
69
+ console.log('选中的权限:', selectedPermissions);
70
+ };
71
+
72
+ const handleHobbiesChange = (value: string): void => {
73
+ userHobbies = value;
74
+ console.log('用户爱好:', value);
75
+ };
76
+ </script>
77
+
78
+ <!-- 权限选择(位运算模式) -->
79
+ <div class="form-group">
80
+ <label>用户权限:</label>
81
+ <GroupCheckBox
82
+ options={permissions}
83
+ keyField="code"
84
+ textField="text"
85
+ bitBase={true}
86
+ bind:value={userPermissions}
87
+ onChange={handlePermissionChange}
88
+ />
89
+ </div>
90
+
91
+ <!-- 兴趣爱好选择(字符串分隔符模式) -->
92
+ <div class="form-group">
93
+ <label>兴趣爱好:</label>
94
+ <GroupCheckBox
95
+ options={hobbies}
96
+ keyField="code"
97
+ textField="text"
98
+ delimiter=";"
99
+ bind:value={userHobbies}
100
+ onChange={handleHobbiesChange}
101
+ />
102
+ </div>
103
+
104
+ <!-- 紧凑模式的复选框组 -->
105
+ <div class="form-group">
106
+ <label>技能标签:</label>
107
+ <GroupCheckBox
108
+ options={[
109
+ { code: 'js', text: 'JavaScript' },
110
+ { code: 'ts', text: 'TypeScript' },
111
+ { code: 'svelte', text: 'Svelte' },
112
+ { code: 'vue', text: 'Vue.js' }
113
+ ]}
114
+ keyField="code"
115
+ textField="text"
116
+ compact={true}
117
+ item$style="margin-right: 12px;"
118
+ bind:value={userSkills}
119
+ />
120
+ </div>
121
+ ```
122
+
123
+ ## 位运算模式说明
124
+
125
+ 当 `bitBase` 为 `true` 时,组件使用位运算来存储选中状态:
126
+ - 第1个选项:位值 1 (二进制 0001)
127
+ - 第2个选项:位值 2 (二进制 0010)
128
+ - 第3个选项:位值 4 (二进制 0100)
129
+ - 第4个选项:位值 8 (二进制 1000)
130
+
131
+ 选择多个选项时,位值相加。例如选择第1和第3个选项,值为 1 + 4 = 5。
132
+
133
+ ### 位运算工具函数
134
+
135
+ ```typescript
136
+ // 检查是否包含某个权限
137
+ const hasPermission = (permissions: number, permission: string): boolean => {
138
+ const permissionIndex: number = permissionList.findIndex(p => p.code === permission);
139
+ return (permissions & (1 << permissionIndex)) !== 0;
140
+ };
141
+
142
+ // 添加权限
143
+ const addPermission = (permissions: number, permission: string): number => {
144
+ const permissionIndex: number = permissionList.findIndex(p => p.code === permission);
145
+ return permissions | (1 << permissionIndex);
146
+ };
147
+
148
+ // 移除权限
149
+ const removePermission = (permissions: number, permission: string): number => {
150
+ const permissionIndex: number = permissionList.findIndex(p => p.code === permission);
151
+ return permissions & ~(1 << permissionIndex);
152
+ };
153
+
154
+ // 解析权限列表
155
+ const parsePermissions = (permissions: number): string[] => {
156
+ const result: string[] = [];
157
+ let bitValue: number = permissions;
158
+ let index: number = 0;
159
+ while (bitValue > 0) {
160
+ if (bitValue & 1) {
161
+ result.push(permissionList[index].code);
162
+ }
163
+ bitValue >>= 1;
164
+ index++;
165
+ }
166
+ return result;
167
+ };
168
+ ```
169
+
170
+ ## 高级用法
171
+
172
+ ### 动态选项加载
173
+ ```svelte
174
+ <script lang="ts">
175
+ import type { OptionItem } from '@ticatec/uniface-element/types';
176
+ import { onMount } from 'svelte';
177
+
178
+ let options: OptionItem[] = [];
179
+ let selectedValues: string = '';
180
+ let loading: boolean = true;
181
+
182
+ onMount(async (): Promise<void> => {
183
+ try {
184
+ const response: Response = await fetch('/api/categories');
185
+ options = await response.json();
186
+ } catch (error) {
187
+ console.error('加载选项失败:', error);
188
+ } finally {
189
+ loading = false;
190
+ }
191
+ });
192
+
193
+ const saveUserPreferences = async (preferences: string): Promise<void> => {
194
+ // 实现保存逻辑
195
+ };
196
+
197
+ const handleChange = (value: string): void => {
198
+ selectedValues = value;
199
+ // 同步到服务器
200
+ saveUserPreferences(value);
201
+ };
202
+ </script>
203
+
204
+ {#if loading}
205
+ <div class="loading">加载选项中...</div>
206
+ {:else}
207
+ <GroupCheckBox
208
+ {options}
209
+ keyField="id"
210
+ textField="name"
211
+ bind:value={selectedValues}
212
+ onChange={handleChange}
213
+ />
214
+ {/if}
215
+ ```
216
+
217
+ ### 条件禁用和隐藏
218
+ ```svelte
219
+ <script lang="ts">
220
+ import type { OptionItem } from '@ticatec/uniface-element/types';
221
+
222
+ type UserLevel = 'basic' | 'premium' | 'enterprise';
223
+
224
+ const features: OptionItem[] = [
225
+ { code: 'basic', text: '基础功能' },
226
+ { code: 'advanced', text: '高级功能' },
227
+ { code: 'premium', text: '高级功能' },
228
+ { code: 'enterprise', text: '企业功能' }
229
+ ];
230
+
231
+ let userLevel: UserLevel = 'basic'; // basic, premium, enterprise
232
+ let selectedFeatures: string = '';
233
+
234
+ // 根据用户级别动态设置禁用选项
235
+ $: disabledOptions = ((): string[] => {
236
+ switch (userLevel) {
237
+ case 'basic':
238
+ return ['advanced', 'premium', 'enterprise'];
239
+ case 'premium':
240
+ return ['enterprise'];
241
+ case 'enterprise':
242
+ return [];
243
+ default:
244
+ return ['advanced', 'premium', 'enterprise'];
245
+ }
246
+ })();
247
+
248
+ // 隐藏企业功能(如果不是企业用户)
249
+ $: hideOptions: string[] = userLevel !== 'enterprise' ? ['enterprise'] : [];
250
+ </script>
251
+
252
+ <div class="form-group">
253
+ <label>用户级别:</label>
254
+ <select bind:value={userLevel}>
255
+ <option value="basic">基础用户</option>
256
+ <option value="premium">高级用户</option>
257
+ <option value="enterprise">企业用户</option>
258
+ </select>
259
+ </div>
260
+
261
+ <div class="form-group">
262
+ <label>可用功能:</label>
263
+ <GroupCheckBox
264
+ options={features}
265
+ keyField="code"
266
+ textField="text"
267
+ {disabledOptions}
268
+ hideOptions={hideOptions}
269
+ bind:value={selectedFeatures}
270
+ />
271
+ </div>
272
+ ```
273
+
274
+ ### 全选/全不选功能
275
+ ```svelte
276
+ <script lang="ts">
277
+ import type { OptionItem } from '@ticatec/uniface-element/types';
278
+
279
+ const allOptions: OptionItem[] = [
280
+ { code: 'option1', text: '选项1' },
281
+ { code: 'option2', text: '选项2' },
282
+ { code: 'option3', text: '选项3' },
283
+ { code: 'option4', text: '选项4' }
284
+ ];
285
+
286
+ let selectedValues: string = '';
287
+
288
+ // 检查是否全选
289
+ $: isAllSelected = ((): boolean => {
290
+ if (!selectedValues) return false;
291
+ const selected: string[] = selectedValues.split(';');
292
+ return allOptions.every(option => selected.includes(option.code));
293
+ })();
294
+
295
+ // 检查是否有部分选中
296
+ $: isIndeterminate = ((): boolean => {
297
+ if (!selectedValues) return false;
298
+ const selected: string[] = selectedValues.split(';');
299
+ return selected.length > 0 && selected.length < allOptions.length;
300
+ })();
301
+
302
+ const handleSelectAll = (checked: boolean): void => {
303
+ if (checked) {
304
+ selectedValues = allOptions.map(opt => opt.code).join(';');
305
+ } else {
306
+ selectedValues = '';
307
+ }
308
+ };
309
+
310
+ const handleChange = (value: string): void => {
311
+ selectedValues = value;
312
+ };
313
+ </script>
314
+
315
+ <div class="select-all-container">
316
+ <CheckBox
317
+ label="全选"
318
+ value={isAllSelected}
319
+ indeterminate={isIndeterminate}
320
+ onChange={handleSelectAll}
321
+ />
322
+ </div>
323
+
324
+ <GroupCheckBox
325
+ options={allOptions}
326
+ keyField="code"
327
+ textField="text"
328
+ bind:value={selectedValues}
329
+ onChange={handleChange}
330
+ />
331
+ ```
332
+
333
+ ## 样式定制
334
+
335
+ ```css
336
+ .form-group {
337
+ margin-bottom: 20px;
338
+ }
339
+
340
+ .form-group label {
341
+ display: block;
342
+ margin-bottom: 8px;
343
+ font-weight: 500;
344
+ color: #333;
345
+ }
346
+
347
+ .select-all-container {
348
+ padding: 8px 0;
349
+ border-bottom: 1px solid #e1e5e9;
350
+ margin-bottom: 12px;
351
+ }
352
+
353
+ .loading {
354
+ padding: 20px;
355
+ text-align: center;
356
+ color: #6c757d;
357
+ }
358
+
359
+ /* 自定义复选框组样式 */
360
+ .custom-checkbox-group {
361
+ display: grid;
362
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
363
+ gap: 12px;
364
+ padding: 16px;
365
+ background: #f8f9fa;
366
+ border-radius: 8px;
367
+ }
368
+ ```
369
+
370
+ ## 组件优势
371
+
372
+ **相比单独使用CheckBox的优势:**
373
+
374
+ 1. **统一管理**:所有相关选项集中在一个组件中管理
375
+ 2. **数据绑定简化**:只需绑定一个值,而不是多个独立的值
376
+ 3. **样式一致性**:所有选项具有统一的样式和间距
377
+ 4. **选项动态管理**:可以轻松地显示/隐藏、启用/禁用特定选项
378
+ 5. **位运算支持**:适合权限系统等需要位运算的场景
379
+ 6. **更好的语义化**:明确表达了选项之间的关联关系
380
+
381
+ ## 最佳实践
382
+
383
+ ### 1. 选择合适的存储模式
384
+ ```svelte
385
+ <!-- 权限系统:使用位运算 -->
386
+ <GroupCheckBox bitBase={true} />
387
+
388
+ <!-- 普通多选:使用字符串分隔符 -->
389
+ <GroupCheckBox delimiter="," />
390
+ ```
391
+
392
+ ### 2. 提供清晰的标签
393
+ ```svelte
394
+ <label>请选择您感兴趣的技术栈:</label>
395
+ <GroupCheckBox
396
+ options={techStack}
397
+ placeholder="选择技术栈"
398
+ />
399
+ ```
400
+
401
+ ### 3. 合理使用紧凑模式
402
+ ```svelte
403
+ <!-- 选项较多时使用紧凑模式 -->
404
+ <GroupCheckBox compact={true} />
405
+ ```