@ticatec/uniface-element 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/dist/accordion/README.md +169 -0
  2. package/dist/accordion/README_CN.md +176 -0
  3. package/dist/action-bar/README.md +275 -0
  4. package/dist/action-bar/README_CN.md +285 -0
  5. package/dist/app-layout/README.md +374 -0
  6. package/dist/app-layout/README_CN.md +381 -0
  7. package/dist/app-top-bar/README.md +357 -0
  8. package/dist/app-top-bar/README_CN.md +365 -0
  9. package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
  10. package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
  11. package/dist/base-calendar/CalendarBase.svelte +0 -3
  12. package/dist/box/README.md +385 -0
  13. package/dist/box/README_CN.md +393 -0
  14. package/dist/breadcrumbs/README.md +442 -0
  15. package/dist/breadcrumbs/README_CN.md +442 -0
  16. package/dist/button/Button.svelte +27 -7
  17. package/dist/button/Button.svelte.d.ts +3 -1
  18. package/dist/button/IconButton.svelte +26 -6
  19. package/dist/button/IconButton.svelte.d.ts +3 -1
  20. package/dist/button/IconButton_README.md +513 -0
  21. package/dist/button/IconButton_README_CN.md +513 -0
  22. package/dist/button/README.md +428 -0
  23. package/dist/button/README_CN.md +428 -0
  24. package/dist/button/TextButton.svelte +26 -6
  25. package/dist/button/TextButton.svelte.d.ts +3 -1
  26. package/dist/button/TextButton_README.md +571 -0
  27. package/dist/button/TextButton_README_CN.md +571 -0
  28. package/dist/card/README.md +666 -0
  29. package/dist/card/README_CN.md +666 -0
  30. package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
  31. package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
  32. package/dist/cascade-options-select/README.md +663 -2
  33. package/dist/cascade-options-select/README_CN.md +664 -0
  34. package/dist/checkbox/CheckBox.svelte +20 -6
  35. package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
  36. package/dist/checkbox/README.md +562 -0
  37. package/dist/checkbox/README_CN.md +727 -0
  38. package/dist/common-editor/NumberInput.svelte +39 -26
  39. package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
  40. package/dist/concise-data-table/ConciseListTable.svelte +133 -36
  41. package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
  42. package/dist/concise-data-table/DataCell.svelte +5 -6
  43. package/dist/concise-data-table/DataRow.svelte +22 -2
  44. package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
  45. package/dist/concise-data-table/README.md +606 -0
  46. package/dist/concise-data-table/README_CN.md +611 -0
  47. package/dist/context-menu/ContextMenu.svelte +138 -21
  48. package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
  49. package/dist/context-menu/ContextMenuItem.d.ts +20 -4
  50. package/dist/context-menu/README.md +551 -0
  51. package/dist/context-menu/README_CN.md +551 -0
  52. package/dist/criteria-field/CriteriaField.svelte +3 -5
  53. package/dist/criteria-field/README.md +532 -0
  54. package/dist/criteria-field/README_CN.md +532 -0
  55. package/dist/data-table/README.md +712 -0
  56. package/dist/data-table/README_CN.md +712 -0
  57. package/dist/date-picker/DatePicker.svelte +44 -7
  58. package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
  59. package/dist/date-picker/DateTimePicker.svelte +32 -8
  60. package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
  61. package/dist/date-picker/README.md +326 -0
  62. package/dist/date-picker/README_CN.md +316 -0
  63. package/dist/date-picker/ScrollBar.svelte +18 -8
  64. package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
  65. package/dist/date-picker/TimePanel.svelte +5 -5
  66. package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
  67. package/dist/date-range/README.md +374 -0
  68. package/dist/date-range/README_CN.md +374 -0
  69. package/dist/dialog/README.md +596 -0
  70. package/dist/dialog/README_CN.md +596 -0
  71. package/dist/drawer/README.md +679 -1
  72. package/dist/drawer/README_CN.md +679 -0
  73. package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
  74. package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
  75. package/dist/group-box/group-check-box/README.md +749 -0
  76. package/dist/group-box/group-check-box/README_CN.md +750 -0
  77. package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
  78. package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
  79. package/dist/group-box/group-radio-box/README.md +920 -0
  80. package/dist/group-box/group-radio-box/README_CN.md +920 -0
  81. package/dist/image-files/README.md +1346 -0
  82. package/dist/image-files/README_CN.md +1346 -0
  83. package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
  84. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
  85. package/dist/lib/forwardAllEvents.d.ts +3 -0
  86. package/dist/lib/forwardAllEvents.js +24 -0
  87. package/dist/list-box/README.md +579 -0
  88. package/dist/list-box/README_CN.md +682 -0
  89. package/dist/lookup-editor/LookupEditor.svelte +15 -3
  90. package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
  91. package/dist/lookup-editor/README.md +684 -0
  92. package/dist/lookup-editor/README_CN.md +684 -0
  93. package/dist/memo-editor/MemoEditor.svelte +77 -27
  94. package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
  95. package/dist/memo-editor/README.md +819 -0
  96. package/dist/memo-editor/README_CN.md +819 -0
  97. package/dist/message-box/README.md +398 -0
  98. package/dist/message-box/README_CN.md +398 -0
  99. package/dist/number-editor/NumberEditor.svelte +2 -2
  100. package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
  101. package/dist/number-editor/README.md +353 -22
  102. package/dist/number-editor/README_CN.md +357 -0
  103. package/dist/number-range/README.md +443 -0
  104. package/dist/number-range/README_CN.md +443 -0
  105. package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
  106. package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
  107. package/dist/options-multi-select/README.md +480 -0
  108. package/dist/options-multi-select/README_CN.md +480 -0
  109. package/dist/options-select/OptionsSelect.svelte +36 -5
  110. package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
  111. package/dist/options-select/README.md +632 -0
  112. package/dist/options-select/README_CN.md +632 -0
  113. package/dist/page/README.md +605 -0
  114. package/dist/page/README_CN.md +605 -0
  115. package/dist/pagination/README.md +946 -0
  116. package/dist/pagination/README_CN.md +946 -0
  117. package/dist/pagination-panel/README.md +1075 -0
  118. package/dist/pagination-panel/README_CN.md +1075 -0
  119. package/dist/popup-hint/README.md +841 -0
  120. package/dist/popup-hint/README_CN.md +840 -0
  121. package/dist/progress-bar/README.md +242 -0
  122. package/dist/progress-bar/README_CN.md +242 -0
  123. package/dist/progress-step-bar/README.md +316 -0
  124. package/dist/progress-step-bar/README_CN.md +316 -0
  125. package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
  126. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
  127. package/dist/prompts-text-editor/README.md +329 -0
  128. package/dist/prompts-text-editor/README_CN.md +329 -0
  129. package/dist/property-editor/README.md +969 -0
  130. package/dist/property-editor/README_CN.md +969 -0
  131. package/dist/radio-button/README.md +372 -0
  132. package/dist/radio-button/README_CN.md +372 -0
  133. package/dist/radio-button/RadioButton.svelte +32 -3
  134. package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
  135. package/dist/search-box/README.md +425 -0
  136. package/dist/search-box/README_CN.md +424 -0
  137. package/dist/search-box/SearchBox.svelte +22 -6
  138. package/dist/search-box/SearchBox.svelte.d.ts +4 -1
  139. package/dist/tabs/README.md +919 -0
  140. package/dist/tabs/README_CN.md +920 -0
  141. package/dist/tag/README.md +922 -0
  142. package/dist/tag/README_CN.md +922 -0
  143. package/dist/text-editor/PasswordEditor.svelte +17 -2
  144. package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
  145. package/dist/text-editor/PasswordEditor_README.md +551 -0
  146. package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
  147. package/dist/text-editor/README.md +466 -0
  148. package/dist/text-editor/README_CN.md +466 -0
  149. package/dist/text-editor/TextEditor.svelte +51 -19
  150. package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
  151. package/dist/time-editor/README.md +498 -24
  152. package/dist/time-editor/README_CN.md +498 -0
  153. package/dist/time-editor/TimeEditor.svelte +7 -3
  154. package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
  155. package/dist/toast/README.md +667 -0
  156. package/dist/toast/README_CN.md +667 -0
  157. package/dist/transfer/README.md +795 -0
  158. package/dist/transfer/Transfer.svelte +6 -4
  159. package/dist/transfer/Transfer.svelte.d.ts +3 -1
  160. package/dist/tree-view/README.md +761 -0
  161. package/dist/tree-view/README_CN.md +761 -0
  162. package/dist/tree-view/TreeView.svelte +5 -3
  163. package/dist/tree-view/TreeView.svelte.d.ts +3 -1
  164. package/dist/unit-number-editor/README.md +546 -20
  165. package/dist/unit-number-editor/README_CN.md +525 -0
  166. package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
  167. package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
  168. package/docs/form-field/cn/README_CN.md +364 -0
  169. package/docs/form-field/en/README.md +364 -0
  170. package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
  171. package/docs/form-panel/flex-form/en/README.md +586 -0
  172. package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
  173. package/docs/form-panel/flex-row-form/en/README.md +787 -0
  174. package/docs/form-panel/grid-form/en/README.md +744 -0
  175. package/package.json +1 -1
  176. package/dist/drawer/README-CN.md +0 -1
@@ -0,0 +1,480 @@
1
+ # 选项多选组件
2
+
3
+ 一个多选下拉组件,允许用户从预定义列表中选择多个选项,并将选中的项显示为可移除的标签。
4
+
5
+ ## 功能
6
+
7
+ - **多选**:从下拉列表中选择多个选项
8
+ - **标签显示**:以可移除标签的形式显示选中的项,支持自定义样式
9
+ - **复选框界面**:下拉菜单中直观的复选框选择
10
+ - **可自定义标签**:不同的标签变体(无边框、有边框、圆形)和颜色
11
+ - **选项控制**:隐藏或禁用特定选项
12
+ - **搜索集成**:与 CommonPicker 配合使用,提供一致的行为
13
+ - **焦点管理**:适当的焦点处理和键盘导航
14
+ - **显示模式**:支持编辑和查看模式
15
+ - **值管理**:基于分隔符的灵活值存储
16
+ - **空状态**:可自定义的占位符和空文本
17
+
18
+ ## 安装
19
+
20
+ ```bash
21
+ npm install @ticatec/uniface-element
22
+ ```
23
+
24
+ ## 基本用法
25
+
26
+ ```svelte
27
+ <script>
28
+ import OptionsMultiSelect from '@ticatec/uniface-element/OptionsMultiSelect';
29
+
30
+ let selectedValues = '';
31
+ let options = [
32
+ { code: 'JS', text: 'JavaScript' },
33
+ { code: 'TS', text: 'TypeScript' },
34
+ { code: 'PY', text: 'Python' },
35
+ { code: 'GO', text: 'Go' }
36
+ ];
37
+ </script>
38
+
39
+ <OptionsMultiSelect
40
+ {options}
41
+ bind:value={selectedValues}
42
+ />
43
+ ```
44
+
45
+ ## API 参考
46
+
47
+ ### 属性
48
+
49
+ | 属性 | 类型 | 默认值 | 描述 |
50
+ |------|------|---------|-------------|
51
+ | `value` | `string` | `''` | 以分隔符分隔的选中值字符串 |
52
+ | `options` | `Array<any>` | `[]` | 选项对象数组 |
53
+ | `keyField` | `string` | `'code'` | 选项键的属性名 |
54
+ | `textField` | `string` | `'text'` | 选项显示文本的属性名 |
55
+ | `delimiter` | `string` | `';'` | 分隔多个值的分隔符 |
56
+ | `variant` | `'' \| 'plain' \| 'outlined' \| 'filled'` | `''` | 视觉样式变体 |
57
+ | `compact` | `boolean` | `false` | 启用紧凑显示模式 |
58
+ | `disabled` | `boolean` | `false` | 禁用组件 |
59
+ | `readonly` | `boolean` | `false` | 使组件只读 |
60
+ | `style` | `string` | `''` | 自定义 CSS 样式 |
61
+ | `placeholder` | `string` | `''` | 未选择项时的占位符文本 |
62
+ | `emptyText` | `string` | `''` | 未选择项时显示的文本(覆盖占位符) |
63
+ | `disableOptions` | `Array<string>` | `[]` | 要禁用的选项键 |
64
+ | `hideOptions` | `Array<string>` | `[]` | 要隐藏的选项键 |
65
+ | `displayMode` | `DisplayMode` | `DisplayMode.Edit` | 编辑或查看模式 |
66
+ | `menu$height` | `number` | `0` | 下拉菜单的最大高度 |
67
+ | `tagColor` | `string` | `''` | 标签的颜色变体 |
68
+ | `tagVariant` | `'borderless' \| 'border' \| 'round'` | `'border'` | 标签视觉样式 |
69
+ | `onchange` | `OnChangeHandler<Array<string>>` | `null` | 更改事件处理程序 |
70
+ | `onfocus` | `(() => void) \| null` | `null` | 聚焦事件处理程序 |
71
+ | `onblur` | `(() => void) \| null` | `null` | 失焦事件处理程序 |
72
+
73
+ ### 方法
74
+
75
+ | 方法 | 描述 |
76
+ |--------|-------------|
77
+ | `setFocus()` | 以编程方式聚焦组件 |
78
+
79
+ ## 示例
80
+
81
+ ### 编程语言选择器
82
+
83
+ ```svelte
84
+ <script>
85
+ import OptionsMultiSelect from '@ticatec/uniface-element/OptionsMultiSelect';
86
+ import FormField from '@ticatec/uniface-element/FormField';
87
+
88
+ let languages = '';
89
+ let programmingLanguages = [
90
+ { code: 'JS', text: 'JavaScript' },
91
+ { code: 'TS', text: 'TypeScript' },
92
+ { code: 'PY', text: 'Python' },
93
+ { code: 'JAVA', text: 'Java' },
94
+ { code: 'CS', text: 'C#' },
95
+ { code: 'GO', text: 'Go' },
96
+ { code: 'RUST', text: 'Rust' },
97
+ { code: 'PHP', text: 'PHP' }
98
+ ];
99
+
100
+ function handleLanguageChange(selected) {
101
+ console.log('选择的语言:', selected);
102
+ }
103
+ </script>
104
+
105
+ <FormField label="编程语言">
106
+ <OptionsMultiSelect
107
+ options={programmingLanguages}
108
+ bind:value={languages}
109
+ variant="outlined"
110
+ tagColor="1"
111
+ tagVariant="round"
112
+ placeholder="选择编程语言"
113
+ onchange={handleLanguageChange}
114
+ />
115
+ </FormField>
116
+ ```
117
+
118
+ ### 技能评估
119
+
120
+ ```svelte
121
+ <script>
122
+ import OptionsMultiSelect from '@ticatec/uniface-element/OptionsMultiSelect';
123
+
124
+ let selectedSkills = '';
125
+ let skills = [
126
+ { code: 'FE', text: '前端开发' },
127
+ { code: 'BE', text: '后端开发' },
128
+ { code: 'DB', text: '数据库设计' },
129
+ { code: 'DEVOPS', text: '运维开发' },
130
+ { code: 'UI', text: 'UI/UX 设计' },
131
+ { code: 'TEST', text: '测试' },
132
+ { code: 'MOBILE', text: '移动开发' },
133
+ { code: 'ML', text: '机器学习' }
134
+ ];
135
+
136
+ let disabledSkills = ['ML']; // 机器学习暂时不可用
137
+
138
+ $: selectedArray = selectedSkills ? selectedSkills.split(';') : [];
139
+ </script>
140
+
141
+ <div class="skills-selector">
142
+ <h3>技术技能</h3>
143
+ <OptionsMultiSelect
144
+ options={skills}
145
+ bind:value={selectedSkills}
146
+ variant="filled"
147
+ tagColor="2"
148
+ tagVariant="border"
149
+ disableOptions={disabledSkills}
150
+ placeholder="选择你的技术技能"
151
+ menu$height={200}
152
+ />
153
+
154
+ <div class="selected-count">
155
+ 已选择:{selectedArray.length} 个技能
156
+ </div>
157
+ </div>
158
+ ```
159
+
160
+ ### 活动类别过滤器
161
+
162
+ ```svelte
163
+ <script>
164
+ import OptionsMultiSelect from '@ticatec/uniface-element/OptionsMultiSelect';
165
+
166
+ let filterCategories = '';
167
+ let eventCategories = [
168
+ { id: 'CONF', name: '会议' },
169
+ { id: 'WORK', name: '工作坊' },
170
+ { id: 'MEET', name: '聚会' },
171
+ { id: 'WEB', name: '网络研讨会' },
172
+ { id: 'HACK', name: '黑客马拉松' },
173
+ { id: 'NET', name: '网络活动' },
174
+ { id: 'TRAIN', name: '培训' },
175
+ { id: 'EXPO', name: '展览' }
176
+ ];
177
+
178
+ let hiddenCategories = ['EXPO']; // 当前地区不可用
179
+
180
+ function applyFilter(categories) {
181
+ console.log('按类别过滤活动:', categories);
182
+ // 在此应用过滤逻辑
183
+ }
184
+ </script>
185
+
186
+ <div class="event-filter">
187
+ <OptionsMultiSelect
188
+ options={eventCategories}
189
+ keyField="id"
190
+ textField="name"
191
+ bind:value={filterCategories}
192
+ variant="outlined"
193
+ tagColor="3"
194
+ tagVariant="borderless"
195
+ hideOptions={hiddenCategories}
196
+ placeholder="按活动类别过滤"
197
+ onchange={applyFilter}
198
+ />
199
+ </div>
200
+ ```
201
+
202
+ ### 团队分配
203
+
204
+ ```svelte
205
+ <script>
206
+ import OptionsMultiSelect from '@ticatec/uniface-element/OptionsMultiSelect';
207
+
208
+ let assignedMembers = '';
209
+ let teamMembers = [
210
+ { userId: '001', fullName: 'Alice Johnson' },
211
+ { userId: '002', fullName: 'Bob Smith' },
212
+ { userId: '003', fullName: 'Carol Davis' },
213
+ { userId: '004', fullName: 'David Wilson' },
214
+ { userId: '005', fullName: 'Eva Brown' },
215
+ { userId: '006', fullName: 'Frank Miller' }
216
+ ];
217
+
218
+ let unavailableMembers = ['003', '005']; // 休假中
219
+
220
+ function handleAssignment(members) {
221
+ console.log('分配的团队成员:', members);
222
+ // 发送分配通知
223
+ }
224
+ </script>
225
+
226
+ <div class="team-assignment">
227
+ <label>分配团队成员</label>
228
+ <OptionsMultiSelect
229
+ options={teamMembers}
230
+ keyField="userId"
231
+ textField="fullName"
232
+ bind:value={assignedMembers}
233
+ variant="outlined"
234
+ tagColor="4"
235
+ tagVariant="round"
236
+ disableOptions={unavailableMembers}
237
+ delimiter=","
238
+ placeholder="为该任务选择团队成员"
239
+ onchange={handleAssignment}
240
+ />
241
+ </div>
242
+ ```
243
+
244
+ ### 产品功能选择
245
+
246
+ ```svelte
247
+ <script>
248
+ import OptionsMultiSelect from '@ticatec/uniface-element/OptionsMultiSelect';
249
+
250
+ let selectedFeatures = '';
251
+ let productFeatures = [
252
+ { feature: 'AUTH', description: '用户认证' },
253
+ { feature: 'DASHBOARD', description: '仪表盘分析' },
254
+ { feature: 'REPORTS', description: '自定义报告' },
255
+ { feature: 'API', description: 'API 集成' },
256
+ { feature: 'EXPORT', description: '数据导出' },
257
+ { feature: 'NOTIFICATIONS', description: '推送通知' },
258
+ { feature: 'BACKUP', description: '自动备份' },
259
+ { feature: 'MULTI_LANG', description: '多语言支持' }
260
+ ];
261
+
262
+ let isReadonly = false;
263
+
264
+ function toggleReadonly() {
265
+ isReadonly = !isReadonly;
266
+ }
267
+
268
+ function calculatePrice(features) {
269
+ const featurePrices = {
270
+ 'AUTH': 10, 'DASHBOARD': 25, 'REPORTS': 20, 'API': 15,
271
+ 'EXPORT': 10, 'NOTIFICATIONS': 12, 'BACKUP': 18, 'MULTI_LANG': 8
272
+ };
273
+
274
+ return features.reduce((total, feature) => total + (featurePrices[feature] || 0), 0);
275
+ }
276
+
277
+ $: selectedArray = selectedFeatures ? selectedFeatures.split(';') : [];
278
+ $: totalPrice = calculatePrice(selectedArray);
279
+ </script>
280
+
281
+ <div class="product-config">
282
+ <h3>产品配置</h3>
283
+
284
+ <OptionsMultiSelect
285
+ options={productFeatures}
286
+ keyField="feature"
287
+ textField="description"
288
+ bind:value={selectedFeatures}
289
+ variant="filled"
290
+ tagColor="5"
291
+ tagVariant="border"
292
+ {readonly}
293
+ placeholder="选择产品功能"
294
+ menu$height={250}
295
+ />
296
+
297
+ <div class="config-summary">
298
+ <p>已选择功能:{selectedArray.length}</p>
299
+ <p>总价:${totalPrice}/月</p>
300
+ <button on:click={toggleReadonly}>
301
+ {isReadonly ? '编辑' : '锁定'} 配置
302
+ </button>
303
+ </div>
304
+ </div>
305
+ ```
306
+
307
+ ### 兴趣调查
308
+
309
+ ```svelte
310
+ <script>
311
+ import OptionsMultiSelect from '@ticatec/uniface-element/OptionsMultiSelect';
312
+
313
+ let interests = '';
314
+ let surveyOptions = [
315
+ { code: 'TECH', text: '科技' },
316
+ { code: 'HEALTH', text: '健康与健身' },
317
+ { code: 'TRAVEL', text: '旅行' },
318
+ { code: 'FOOD', text: '美食与烹饪' },
319
+ { code: 'SPORTS', text: '运动' },
320
+ { code: 'MUSIC', text: '音乐' },
321
+ { code: 'ART', text: '艺术与文化' },
322
+ { code: 'BOOKS', text: '书籍与文学' },
323
+ { code: 'GAMES', text: '游戏' },
324
+ { code: 'FINANCE', text: '个人理财' }
325
+ ];
326
+
327
+ function handleInterestChange(selected) {
328
+ console.log('用户兴趣更新:', selected);
329
+ // 保存到用户资料
330
+ }
331
+
332
+ function handleFocus() {
333
+ console.log('调查部分聚焦');
334
+ }
335
+
336
+ function handleBlur() {
337
+ console.log('调查部分失焦');
338
+ }
339
+ </script>
340
+
341
+ <div class="survey-section">
342
+ <h3>你对什么感兴趣?</h3>
343
+ <p>选择所有你感兴趣的主题(最少3个,最多7个)</p>
344
+
345
+ <OptionsMultiSelect
346
+ options={surveyOptions}
347
+ bind:value={interests}
348
+ variant="outlined"
349
+ tagColor="6"
350
+ tagVariant="round"
351
+ placeholder="选择你的兴趣"
352
+ emptyText="尚未选择任何兴趣"
353
+ onchange={handleInterestChange}
354
+ onfocus={handleFocus}
355
+ onblur={handleBlur}
356
+ />
357
+ </div>
358
+ ```
359
+
360
+ ### 紧凑表格用法
361
+
362
+ ```svelte
363
+ <script>
364
+ import OptionsMultiSelect from '@ticatec/uniface-element/OptionsMultiSelect';
365
+
366
+ let permissionOptions = [
367
+ { code: 'READ', text: '读取' },
368
+ { code: 'WRITE', text: '写入' },
369
+ { code: 'DELETE', text: '删除' },
370
+ { code: 'ADMIN', text: '管理员' }
371
+ ];
372
+
373
+ let users = [
374
+ { id: 1, name: 'John Doe', permissions: 'READ;WRITE' },
375
+ { id: 2, name: 'Jane Smith', permissions: 'READ;WRITE;DELETE' },
376
+ { id: 3, name: 'Admin User', permissions: 'READ;WRITE;DELETE;ADMIN' }
377
+ ];
378
+
379
+ function updatePermissions(userId, permissions) {
380
+ const user = users.find(u => u.id === userId);
381
+ if (user) {
382
+ user.permissions = permissions.join(';');
383
+ users = [...users];
384
+ }
385
+ }
386
+ </script>
387
+
388
+ <table class="permissions-table">
389
+ <thead>
390
+ <tr>
391
+ <th>用户</th>
392
+ <th>权限</th>
393
+ </tr>
394
+ </thead>
395
+ <tbody>
396
+ {#each users as user}
397
+ <tr>
398
+ <td>{user.name}</td>
399
+ <td>
400
+ <OptionsMultiSelect
401
+ options={permissionOptions}
402
+ value={user.permissions}
403
+ compact
404
+ variant="outlined"
405
+ tagColor="7"
406
+ tagVariant="borderless"
407
+ onchange={(perms) => updatePermissions(user.id, perms)}
408
+ />
409
+ </td>
410
+ </tr>
411
+ {/each}
412
+ </tbody>
413
+ </table>
414
+ ```
415
+
416
+ ## 标签样式
417
+
418
+ 组件支持不同的标签变体和颜色:
419
+
420
+ ### 标签变体
421
+ - `borderless`:无边框的干净标签
422
+ - `border`:带可见边框的标签
423
+ - `round`:圆形药丸样式标签
424
+
425
+ ### 标签颜色
426
+ 使用颜色字符串(例如 "1"、"2"、"3")为标签应用不同的配色方案。
427
+
428
+ ## 最佳实践
429
+
430
+ 1. **选项管理**:保持选项列表专注且相关
431
+ 2. **性能**:对于超大选项列表,考虑虚拟化
432
+ 3. **可访问性**:提供清晰的标签和描述
433
+ 4. **验证**:根据需要实现最小/最大选择限制
434
+ 5. **用户体验**:选择适合你设计系统的标签样式
435
+ 6. **数据格式**:选择不会与数据冲突的分隔符
436
+ 7. **状态管理**:处理动态选项的加载状态
437
+
438
+ ## 样式
439
+
440
+ ```css
441
+ .options-popover {
442
+ max-height: 300px;
443
+ overflow-y: auto;
444
+ border: 1px solid #e0e0e0;
445
+ border-radius: 4px;
446
+ background: white;
447
+ }
448
+
449
+ .option-item {
450
+ padding: 8px 12px;
451
+ display: flex;
452
+ align-items: center;
453
+ gap: 8px;
454
+ cursor: pointer;
455
+ }
456
+
457
+ .option-item:hover {
458
+ background-color: #f5f5f5;
459
+ }
460
+
461
+ .option-item.disabled {
462
+ opacity: 0.5;
463
+ cursor: not-allowed;
464
+ }
465
+ ```
466
+
467
+ ## 可访问性
468
+
469
+ - 全面支持键盘导航
470
+ - 为屏幕阅读器提供 ARIA 标签和角色
471
+ - 焦点管理和视觉指示器
472
+ - 高对比度模式兼容性
473
+ - 复选框可访问性标准
474
+
475
+ ## 相关组件
476
+
477
+ - [选项单选](../options-select/README.md) - 用于单一选项选择
478
+ - [标签](../tag/README.md) - 用于单个标签样式
479
+ - [表单字段](../form-field/README.md) - 用于表单布局和标签
480
+ - [通用选择器](../common/README.md) - 基础选择器功能
@@ -23,7 +23,9 @@
23
23
  export let displayMode: DisplayMode = DisplayMode.Edit;
24
24
  export let itemRender: any = null;
25
25
  export let emptyText: string = null as unknown as string;
26
- export let onChange: OnChangeHandler<any> = null as unknown as OnChangeHandler<any>;
26
+ export let onchange: OnChangeHandler<any> = null as unknown as OnChangeHandler<any>;
27
+ export let onfocus: (() => void) | null = null;
28
+ export let onblur: (() => void) | null = null;
27
29
  export let onSelected: OnSelectedHandler = null as unknown as OnSelectedHandler;
28
30
 
29
31
 
@@ -38,6 +40,8 @@
38
40
  let oldValue = value;
39
41
  let showPopup: boolean = false;
40
42
  let mh;
43
+ let popupContainer: HTMLElement;
44
+ let hasFocus: boolean = false;
41
45
 
42
46
  const generateText = (v: string): string => {
43
47
  let item = (options || []).find(el => el[keyField] == value);
@@ -52,8 +56,8 @@
52
56
  if (disableOptions.indexOf(data[keyField]) < 0) {
53
57
  onSelected?.(data);
54
58
  value = data[keyField];
55
- editor.focus();
56
59
  showPopup = false;
60
+ editor.focus();
57
61
  }
58
62
  }
59
63
 
@@ -66,7 +70,7 @@
66
70
  $: mh = `height: ${menu$height > 0 ? menu$height + 'px' : 'auto'}`;
67
71
 
68
72
  $: if (value != oldValue) {
69
- onChange?.(value);
73
+ onchange?.(value);
70
74
  oldValue = value;
71
75
  }
72
76
 
@@ -74,21 +78,48 @@
74
78
  editor.focus();
75
79
  }
76
80
 
81
+ // 监听popup关闭,如果是点击外部关闭且之前有焦点,触发blur
82
+ $: if (!showPopup && hasFocus) {
83
+ // 延迟检查,如果input仍然有焦点,说明是选择项目导致的关闭
84
+ setTimeout(() => {
85
+ if (document.activeElement !== editor) {
86
+ hasFocus = false;
87
+ onblur?.();
88
+ }
89
+ }, 50);
90
+ }
91
+
77
92
  const handleKeyDown = (event: KeyboardEvent) => {
78
93
  if (event.key=='Tab') {
79
94
  showPopup = false;
80
95
  }
81
96
  }
82
97
 
98
+ const handleFocus = () => {
99
+ if (!hasFocus) {
100
+ hasFocus = true;
101
+ onfocus?.();
102
+ }
103
+ }
104
+
105
+ const handleBlur = (event: FocusEvent) => {
106
+ // 如果popup没有打开,立即触发blur
107
+ if (!showPopup) {
108
+ hasFocus = false;
109
+ onblur?.();
110
+ }
111
+ // 如果popup打开,不触发blur,让popup关闭时处理
112
+ }
113
+
83
114
  </script>
84
115
 
85
116
  <CommonPicker {displayMode} {variant} {style} {compact} dropDownIcon="icon_google_arrow_drop_down"
86
117
  bind:showPopup canClean={!mandatory && value!=null} autoFit clean={cleanData} {textValue} {readonly} {disabled}>
87
118
 
88
119
  <input style="width: 100%" bind:this={editor} on:click={openPopup} {placeholder} readonly
89
- class="text-editor" bind:value={textValue} on:blur on:focus on:keydown={handleKeyDown}/>
120
+ class="text-editor" bind:value={textValue} on:blur={handleBlur} on:focus={handleFocus} on:keydown={handleKeyDown}/>
90
121
 
91
- <div class="options-popover" style={mh} slot="popup-panel">
122
+ <div class="options-popover" style={mh} slot="popup-panel" bind:this={popupContainer}>
92
123
  {#each options as op}
93
124
  {#if hideOptions.indexOf(op[keyField]) < 0}
94
125
  {#if itemRender != null}
@@ -32,13 +32,12 @@ declare const OptionsSelect: $$__sveltets_2_IsomorphicComponent<{
32
32
  displayMode?: DisplayMode;
33
33
  itemRender?: any;
34
34
  emptyText?: string;
35
- onChange?: OnChangeHandler<any>;
35
+ onchange?: OnChangeHandler<any>;
36
+ onfocus?: (() => void) | null;
37
+ onblur?: (() => void) | null;
36
38
  onSelected?: OnSelectedHandler;
37
39
  setFocus?: () => void;
38
40
  }, {
39
- blur: FocusEvent;
40
- focus: FocusEvent;
41
- } & {
42
41
  [evt: string]: CustomEvent<any>;
43
42
  }, {}, {
44
43
  setFocus: () => void;