design-system-next 2.8.0 → 2.8.3
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.
- package/dist/design-system-next.js +4900 -4996
- package/dist/design-system-next.js.gz +0 -0
- package/dist/main.css +1 -1
- package/dist/main.css.gz +0 -0
- package/dist/package.json.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/list/ladderized-list/use-ladderized-list.ts +11 -1
- package/src/components/select/select-ladderized/select-ladderized.ts +3 -3
- package/src/components/select/select-ladderized/select-ladderized.vue +7 -7
- package/src/components/select/select-ladderized/use-select-ladderized.ts +13 -14
- package/src/components/select/select-multiple/select-multiple.ts +1 -15
- package/src/components/select/select-multiple/select-multiple.vue +17 -72
- package/src/components/select/select-multiple/use-select-multiple.ts +112 -215
- package/src/components/select/select.ts +2 -2
- package/src/components/select/select.vue +12 -12
- package/src/components/select/use-select.ts +26 -25
- package/src/components/snackbar/snack/snack.vue +6 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ref, toRefs, computed, ComputedRef, onMounted, watch } from 'vue';
|
|
2
|
-
import { onClickOutside,
|
|
2
|
+
import { onClickOutside, useVModel } from '@vueuse/core';
|
|
3
3
|
|
|
4
4
|
import classNames from 'classnames';
|
|
5
5
|
|
|
@@ -13,7 +13,7 @@ interface MultiSelectClasses {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export const useMultiSelect = (props: MultiSelectPropTypes, emit: SetupContext<MultiSelectEmitTypes>['emit']) => {
|
|
16
|
-
const { displayText,
|
|
16
|
+
const { displayText, options, disabled, textField, valueField } = toRefs(props);
|
|
17
17
|
|
|
18
18
|
const multiSelectClasses: ComputedRef<MultiSelectClasses> = computed(() => {
|
|
19
19
|
const baseClasses = classNames('spr-flex spr-flex-col spr-gap-size-spacing-4xs');
|
|
@@ -28,57 +28,47 @@ export const useMultiSelect = (props: MultiSelectPropTypes, emit: SetupContext<M
|
|
|
28
28
|
};
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
// Popper Variables
|
|
32
31
|
const multiSelectRef = ref<HTMLDivElement | null>(null);
|
|
33
32
|
const multiSelectPopperState = ref<boolean>(false);
|
|
34
33
|
const isMultiSelectPopperDisabled = computed(() => disabled.value);
|
|
35
34
|
|
|
36
|
-
// Multi-Select Variables
|
|
37
35
|
const multiSelectModel = useVModel(props, 'modelValue', emit);
|
|
38
|
-
const multiSelectedListItems = ref<MenuListType[]>();
|
|
39
|
-
const
|
|
36
|
+
const multiSelectedListItems = ref<MenuListType[]>([]);
|
|
37
|
+
const multiSelectOptions = ref<MenuListType[]>([]);
|
|
40
38
|
const hasUserSelected = ref(false);
|
|
41
39
|
|
|
42
|
-
// Input Text Variables
|
|
43
40
|
const inputText = ref<string | number>('');
|
|
44
41
|
const inputTextBackup = ref<string | number>('');
|
|
45
|
-
const isSearching = ref<boolean>(false);
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
isSearching.value = false;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// Normalized value for internal use - always an array
|
|
43
|
+
/**
|
|
44
|
+
* Returns the normalized value of the model as an array for internal use.
|
|
45
|
+
*/
|
|
54
46
|
const normalizedValue = computed(() => {
|
|
55
|
-
// If already an array, use it
|
|
56
47
|
if (Array.isArray(multiSelectModel.value)) {
|
|
57
48
|
return multiSelectModel.value;
|
|
58
49
|
}
|
|
59
50
|
|
|
60
|
-
// If not an array but has a value, make it a single-item array
|
|
61
51
|
if (multiSelectModel.value !== undefined && multiSelectModel.value !== null) {
|
|
62
52
|
return [multiSelectModel.value];
|
|
63
53
|
}
|
|
64
54
|
|
|
65
|
-
// Default empty array
|
|
66
55
|
return [];
|
|
67
56
|
});
|
|
68
57
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Processes the options prop and normalizes it into MenuListType[] for the multi-select.
|
|
60
|
+
*/
|
|
61
|
+
const processOptions = () => {
|
|
62
|
+
if (!options.value || !Array.isArray(options.value) || options.value.length === 0) {
|
|
63
|
+
multiSelectOptions.value = [];
|
|
73
64
|
|
|
74
65
|
return;
|
|
75
66
|
}
|
|
76
67
|
|
|
77
|
-
const firstItem =
|
|
68
|
+
const firstItem = options.value[0];
|
|
78
69
|
|
|
79
|
-
// Handle array of strings
|
|
80
70
|
if (typeof firstItem === 'string') {
|
|
81
|
-
|
|
71
|
+
multiSelectOptions.value = (options.value as string[]).map((item) => ({
|
|
82
72
|
text: item,
|
|
83
73
|
value: item,
|
|
84
74
|
}));
|
|
@@ -86,245 +76,147 @@ export const useMultiSelect = (props: MultiSelectPropTypes, emit: SetupContext<M
|
|
|
86
76
|
return;
|
|
87
77
|
}
|
|
88
78
|
|
|
89
|
-
// Handle array of numbers
|
|
90
79
|
if (typeof firstItem === 'number') {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
80
|
+
multiSelectOptions.value = (options.value as Array<number | string | Record<string, unknown>>)
|
|
81
|
+
.filter((item): item is number => typeof item === 'number')
|
|
82
|
+
.map((item) => ({
|
|
83
|
+
text: item.toString(),
|
|
84
|
+
value: item,
|
|
85
|
+
}));
|
|
95
86
|
|
|
96
87
|
return;
|
|
97
88
|
}
|
|
98
89
|
|
|
99
|
-
// Handle array of objects with dynamic attributes
|
|
100
90
|
if (typeof firstItem === 'object' && firstItem !== null) {
|
|
101
|
-
// Check if it's already in MenuListType format
|
|
102
91
|
if ('text' in firstItem && 'value' in firstItem) {
|
|
103
|
-
|
|
92
|
+
multiSelectOptions.value = options.value as MenuListType[];
|
|
93
|
+
|
|
104
94
|
return;
|
|
105
95
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// Ensure displayText is a string
|
|
96
|
+
|
|
97
|
+
multiSelectOptions.value = (options.value as Record<string, unknown>[]).map((item) => {
|
|
109
98
|
const displayText = item[textField.value] !== undefined ? String(item[textField.value]) : 'Unnamed';
|
|
110
|
-
|
|
99
|
+
|
|
111
100
|
let itemValue = valueField.value && item[valueField.value] !== undefined ? item[valueField.value] : item;
|
|
112
|
-
|
|
101
|
+
|
|
113
102
|
if (itemValue === undefined) itemValue = '';
|
|
103
|
+
|
|
114
104
|
return {
|
|
115
105
|
text: displayText,
|
|
116
106
|
value: typeof itemValue === 'object' ? JSON.stringify(itemValue) : String(itemValue),
|
|
117
|
-
_originalObject: item,
|
|
107
|
+
_originalObject: item,
|
|
118
108
|
};
|
|
119
109
|
});
|
|
110
|
+
|
|
120
111
|
return;
|
|
121
112
|
}
|
|
122
113
|
|
|
123
|
-
|
|
114
|
+
multiSelectOptions.value = options.value as MenuListType[];
|
|
124
115
|
};
|
|
125
116
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const query = inputText.value.toString().toLowerCase().trim();
|
|
132
|
-
|
|
133
|
-
if (!query) return multiSelectMenuList.value;
|
|
134
|
-
|
|
135
|
-
return multiSelectMenuList.value.filter((item) => item.text?.toString().toLowerCase().includes(query));
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
watch(menuList, () => {
|
|
139
|
-
processMenuList();
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
// Search handler: always emit search-string, but only filter locally if local search is enabled
|
|
143
|
-
const handleSearch = () => {
|
|
144
|
-
isSearching.value = true;
|
|
145
|
-
|
|
146
|
-
debouncedEmitSearch();
|
|
117
|
+
/**
|
|
118
|
+
* Opens the multi-select options.
|
|
119
|
+
*/
|
|
120
|
+
const handleOptionsToggle = () => {
|
|
121
|
+
multiSelectPopperState.value = true;
|
|
147
122
|
};
|
|
148
123
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
onClickOutside(multiSelectRef, () => {
|
|
154
|
-
multiSelectPopperState.value = false;
|
|
155
|
-
// If user was searching, restore inputText from backup
|
|
156
|
-
if (isSearching.value) {
|
|
157
|
-
inputText.value = inputTextBackup.value;
|
|
158
|
-
}
|
|
159
|
-
isSearching.value = false;
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
useInfiniteScroll(
|
|
163
|
-
multiSelectRef,
|
|
164
|
-
() => {
|
|
165
|
-
emit('infinite-scroll-trigger', true);
|
|
166
|
-
},
|
|
167
|
-
{ distance: 10 },
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
// Handle multi-selected item for simple list component
|
|
124
|
+
/**
|
|
125
|
+
* Handles selection changes from the multi-select and updates the model value.
|
|
126
|
+
* Converts stringified objects back to objects if needed.
|
|
127
|
+
*/
|
|
171
128
|
const handleMultiSelectedItem = (multiSelectedItems: MenuListType[]) => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
lastValue = lastClicked._originalObject ?? lastClicked.value;
|
|
180
|
-
} else if (typeof lastClicked.value === 'number') {
|
|
181
|
-
lastValue = lastClicked.value;
|
|
182
|
-
} else if (
|
|
183
|
-
typeof lastClicked.value === 'string' &&
|
|
184
|
-
!isNaN(Number(lastClicked.value)) &&
|
|
185
|
-
lastClicked.value.trim() !== '' &&
|
|
186
|
-
/^-?\d+(\.\d+)?$/.test(lastClicked.value)
|
|
187
|
-
) {
|
|
188
|
-
lastValue = Number(lastClicked.value);
|
|
189
|
-
} else {
|
|
190
|
-
lastValue = lastClicked.value;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Always normalize current selection to an array
|
|
194
|
-
let current: (string | number | Record<string, unknown>)[] = [];
|
|
195
|
-
if (Array.isArray(multiSelectModel.value)) {
|
|
196
|
-
current = [...multiSelectModel.value];
|
|
197
|
-
} else if (
|
|
198
|
-
multiSelectModel.value !== undefined &&
|
|
199
|
-
multiSelectModel.value !== null &&
|
|
200
|
-
multiSelectModel.value !== ''
|
|
201
|
-
) {
|
|
202
|
-
current = [multiSelectModel.value];
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Find if already selected (deep compare for objects, strict for primitives)
|
|
206
|
-
const isSelected = current.some((sel) => {
|
|
207
|
-
if (typeof sel === 'object' && typeof lastValue === 'object') {
|
|
208
|
-
return JSON.stringify(sel) === JSON.stringify(lastValue);
|
|
129
|
+
const selectedValues = multiSelectedItems.map((item) => {
|
|
130
|
+
if (typeof item.value === 'string' && item.value.startsWith('{') && item.value.endsWith('}')) {
|
|
131
|
+
try {
|
|
132
|
+
return JSON.parse(item.value);
|
|
133
|
+
} catch {
|
|
134
|
+
return item.value;
|
|
135
|
+
}
|
|
209
136
|
}
|
|
210
|
-
return sel === lastValue;
|
|
211
|
-
});
|
|
212
137
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
current = current.filter((sel) => {
|
|
216
|
-
if (typeof sel === 'object' && typeof lastValue === 'object') {
|
|
217
|
-
return JSON.stringify(sel) !== JSON.stringify(lastValue);
|
|
218
|
-
}
|
|
219
|
-
return sel !== lastValue;
|
|
220
|
-
});
|
|
221
|
-
} else {
|
|
222
|
-
// Add to selection
|
|
223
|
-
current.push(lastValue);
|
|
224
|
-
}
|
|
138
|
+
return item.value;
|
|
139
|
+
});
|
|
225
140
|
|
|
226
141
|
hasUserSelected.value = true;
|
|
227
|
-
multiSelectModel.value =
|
|
142
|
+
multiSelectModel.value = selectedValues;
|
|
228
143
|
multiSelectPopperState.value = true;
|
|
229
|
-
|
|
230
|
-
|
|
144
|
+
inputTextBackup.value =
|
|
145
|
+
multiSelectedItems.length > 3
|
|
146
|
+
? `${multiSelectedItems.length} items selected`
|
|
147
|
+
: multiSelectedItems.map((item) => item.text).join(', ');
|
|
148
|
+
|
|
149
|
+
updateMultiSelectedItemsFromValue();
|
|
231
150
|
};
|
|
232
151
|
|
|
233
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Updates the selected items in the multi-select based on the current model value.
|
|
154
|
+
* Handles stringified objects and updates the input text accordingly.
|
|
155
|
+
*/
|
|
234
156
|
const updateMultiSelectedItemsFromValue = () => {
|
|
235
|
-
if (!
|
|
157
|
+
if (!multiSelectOptions.value.length) return;
|
|
236
158
|
|
|
237
159
|
const values = normalizedValue.value;
|
|
238
160
|
|
|
239
161
|
if (!values || !values.length) {
|
|
240
162
|
multiSelectedListItems.value = [];
|
|
241
|
-
|
|
242
|
-
// Always clear inputText and backup if nothing is selected
|
|
243
163
|
inputText.value = '';
|
|
244
164
|
inputTextBackup.value = '';
|
|
245
165
|
|
|
246
166
|
return;
|
|
247
167
|
}
|
|
248
168
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
// For objects, use JSON string representation
|
|
254
|
-
if (typeof val === 'object') {
|
|
255
|
-
return {
|
|
256
|
-
original: val,
|
|
257
|
-
string: JSON.stringify(val),
|
|
258
|
-
isObject: true,
|
|
259
|
-
id: 'id' in val ? val.id : undefined,
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// For numbers and strings, keep original and string versions
|
|
264
|
-
return {
|
|
265
|
-
original: val,
|
|
266
|
-
string: val.toString(),
|
|
267
|
-
isObject: false,
|
|
268
|
-
};
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
// Extract just string values for comparison
|
|
272
|
-
const valueStrings = valueData.map((v) => v.string);
|
|
273
|
-
|
|
274
|
-
multiSelectedListItems.value = multiSelectMenuList.value.filter((item) => {
|
|
275
|
-
// Handle objects with _originalObject property
|
|
276
|
-
if ('_originalObject' in item && item._originalObject) {
|
|
277
|
-
return valueData.some((v) => {
|
|
278
|
-
// If both are objects, compare by JSON string or by ID
|
|
279
|
-
if (v.isObject && typeof v.original === 'object') {
|
|
280
|
-
const originalObj = item._originalObject as Record<string, unknown>;
|
|
281
|
-
|
|
282
|
-
if (v.original === originalObj) return true;
|
|
169
|
+
multiSelectedListItems.value = multiSelectOptions.value.filter((item) => {
|
|
170
|
+
return values.some((val) => {
|
|
171
|
+
let itemVal = item.value;
|
|
172
|
+
let valToCompare = val;
|
|
283
173
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
174
|
+
if (typeof itemVal === 'string' && itemVal.startsWith('{') && itemVal.endsWith('}')) {
|
|
175
|
+
try {
|
|
176
|
+
itemVal = JSON.parse(itemVal);
|
|
177
|
+
} catch {
|
|
178
|
+
// ignore
|
|
179
|
+
}
|
|
180
|
+
}
|
|
287
181
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
182
|
+
if (typeof valToCompare === 'string' && valToCompare.startsWith('{') && valToCompare.endsWith('}')) {
|
|
183
|
+
try {
|
|
184
|
+
valToCompare = JSON.parse(valToCompare);
|
|
185
|
+
} catch {
|
|
186
|
+
// ignore
|
|
291
187
|
}
|
|
292
|
-
|
|
293
|
-
});
|
|
294
|
-
}
|
|
188
|
+
}
|
|
295
189
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
return
|
|
301
|
-
}
|
|
190
|
+
if (typeof itemVal === 'object' && typeof valToCompare === 'object') {
|
|
191
|
+
return JSON.stringify(itemVal) === JSON.stringify(valToCompare);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return itemVal == valToCompare;
|
|
195
|
+
});
|
|
302
196
|
});
|
|
303
197
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
inputText.value = multiSelectedListItems.value.map((item) => item.text).join(', ');
|
|
310
|
-
}
|
|
198
|
+
if (multiSelectedListItems.value.length > 3) {
|
|
199
|
+
inputText.value = `${multiSelectedListItems.value.length} items selected`;
|
|
200
|
+
} else {
|
|
201
|
+
inputText.value = multiSelectedListItems.value.map((item) => item.text).join(', ');
|
|
202
|
+
}
|
|
311
203
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
inputTextBackup.value = inputText.value;
|
|
319
|
-
}
|
|
204
|
+
// Always update backup to match inputText after update
|
|
205
|
+
inputTextBackup.value = inputText.value;
|
|
206
|
+
|
|
207
|
+
if (displayText.value && !hasUserSelected.value && (!inputText.value || inputText.value === '')) {
|
|
208
|
+
inputText.value = displayText.value;
|
|
209
|
+
inputTextBackup.value = displayText.value;
|
|
320
210
|
}
|
|
321
211
|
};
|
|
322
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Clears the selection and input text, and closes the multi-select.
|
|
215
|
+
*/
|
|
323
216
|
const handleClear = () => {
|
|
324
|
-
emit('update:modelValue',
|
|
217
|
+
emit('update:modelValue', []);
|
|
325
218
|
|
|
326
219
|
inputText.value = '';
|
|
327
|
-
|
|
328
220
|
multiSelectPopperState.value = false;
|
|
329
221
|
};
|
|
330
222
|
|
|
@@ -332,14 +224,22 @@ export const useMultiSelect = (props: MultiSelectPropTypes, emit: SetupContext<M
|
|
|
332
224
|
updateMultiSelectedItemsFromValue();
|
|
333
225
|
});
|
|
334
226
|
|
|
335
|
-
watch(
|
|
227
|
+
watch(multiSelectOptions, () => {
|
|
228
|
+
updateMultiSelectedItemsFromValue();
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Handles closing the multi-select when clicking outside.
|
|
233
|
+
*/
|
|
234
|
+
onClickOutside(multiSelectRef, () => {
|
|
235
|
+
multiSelectPopperState.value = false;
|
|
236
|
+
|
|
336
237
|
updateMultiSelectedItemsFromValue();
|
|
337
238
|
});
|
|
338
239
|
|
|
339
240
|
onMounted(() => {
|
|
340
|
-
|
|
241
|
+
processOptions();
|
|
341
242
|
|
|
342
|
-
// Set initial multi-selected items based on model value
|
|
343
243
|
if (normalizedValue.value.length > 0) {
|
|
344
244
|
updateMultiSelectedItemsFromValue();
|
|
345
245
|
} else if (displayText.value) {
|
|
@@ -353,15 +253,12 @@ export const useMultiSelect = (props: MultiSelectPropTypes, emit: SetupContext<M
|
|
|
353
253
|
multiSelectPopperState,
|
|
354
254
|
multiSelectRef,
|
|
355
255
|
multiSelectModel,
|
|
356
|
-
|
|
357
|
-
filteredMultiSelectMenuList,
|
|
256
|
+
multiSelectOptions,
|
|
358
257
|
multiSelectedListItems,
|
|
359
258
|
inputText,
|
|
360
259
|
isMultiSelectPopperDisabled,
|
|
361
|
-
isSearching,
|
|
362
260
|
handleMultiSelectedItem,
|
|
363
|
-
handleSearch,
|
|
364
261
|
handleClear,
|
|
365
|
-
|
|
262
|
+
handleOptionsToggle,
|
|
366
263
|
};
|
|
367
264
|
};
|
|
@@ -34,9 +34,9 @@ export const selectPropTypes = {
|
|
|
34
34
|
type: [String, Number, Object, Array] as PropType<
|
|
35
35
|
string | number | Record<string, unknown> | (string | number | Record<string, unknown>)[]
|
|
36
36
|
>,
|
|
37
|
-
default:
|
|
37
|
+
default: '',
|
|
38
38
|
},
|
|
39
|
-
|
|
39
|
+
options: {
|
|
40
40
|
type: Array as PropType<MenuListType[] | string[] | Record<string, unknown>[]>,
|
|
41
41
|
required: true,
|
|
42
42
|
default: [],
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
width: props.width,
|
|
24
24
|
}"
|
|
25
25
|
>
|
|
26
|
-
<div @click="
|
|
26
|
+
<div @click="handleOptionsToggle">
|
|
27
27
|
<spr-input
|
|
28
28
|
v-model="inputText"
|
|
29
29
|
:class="{
|
|
@@ -52,14 +52,14 @@
|
|
|
52
52
|
</spr-input>
|
|
53
53
|
|
|
54
54
|
<select
|
|
55
|
-
v-if="
|
|
55
|
+
v-if="selectOptions && selectOptions.length"
|
|
56
56
|
:value="Array.isArray(selectModel) ? selectModel[0] : selectModel"
|
|
57
57
|
data-testid="qa-hidden-select"
|
|
58
58
|
tabindex="-1"
|
|
59
59
|
aria-hidden="true"
|
|
60
60
|
hidden
|
|
61
61
|
>
|
|
62
|
-
<option v-for="item in
|
|
62
|
+
<option v-for="item in selectOptions" :key="item.value" :value="item.value">
|
|
63
63
|
{{ item.text }}
|
|
64
64
|
</option>
|
|
65
65
|
</select>
|
|
@@ -79,10 +79,10 @@
|
|
|
79
79
|
>
|
|
80
80
|
<template v-if="isSearching">
|
|
81
81
|
<template v-if="!props.disabledLocalSearch">
|
|
82
|
-
<template v-if="
|
|
82
|
+
<template v-if="filteredSelectOptions.length > 0">
|
|
83
83
|
<spr-list
|
|
84
84
|
v-model="selectedListItems"
|
|
85
|
-
:menu-list="
|
|
85
|
+
:menu-list="filteredSelectOptions"
|
|
86
86
|
:group-items-by="props.groupItemsBy"
|
|
87
87
|
:pre-selected-items="Array.isArray(selectModel) ? selectModel.flat() : [selectModel]"
|
|
88
88
|
@update:model-value="handleSelectedItem"
|
|
@@ -95,10 +95,10 @@
|
|
|
95
95
|
</template>
|
|
96
96
|
</template>
|
|
97
97
|
<template v-else>
|
|
98
|
-
<template v-if="
|
|
98
|
+
<template v-if="selectOptions.length > 0">
|
|
99
99
|
<spr-list
|
|
100
100
|
v-model="selectedListItems"
|
|
101
|
-
:menu-list="
|
|
101
|
+
:menu-list="selectOptions"
|
|
102
102
|
:group-items-by="props.groupItemsBy"
|
|
103
103
|
:pre-selected-items="Array.isArray(selectModel) ? selectModel.flat() : [selectModel]"
|
|
104
104
|
@update:model-value="handleSelectedItem"
|
|
@@ -112,10 +112,10 @@
|
|
|
112
112
|
</template>
|
|
113
113
|
</template>
|
|
114
114
|
<template v-else>
|
|
115
|
-
<template v-if="
|
|
115
|
+
<template v-if="selectOptions.length > 0">
|
|
116
116
|
<spr-list
|
|
117
117
|
v-model="selectedListItems"
|
|
118
|
-
:menu-list="
|
|
118
|
+
:menu-list="selectOptions"
|
|
119
119
|
:group-items-by="props.groupItemsBy"
|
|
120
120
|
:pre-selected-items="Array.isArray(selectModel) ? selectModel.flat() : [selectModel]"
|
|
121
121
|
@update:model-value="handleSelectedItem"
|
|
@@ -154,8 +154,8 @@ const {
|
|
|
154
154
|
selectPopperState,
|
|
155
155
|
selectRef,
|
|
156
156
|
selectModel,
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
selectOptions,
|
|
158
|
+
filteredSelectOptions,
|
|
159
159
|
selectedListItems,
|
|
160
160
|
inputText,
|
|
161
161
|
isSelectPopperDisabled,
|
|
@@ -163,6 +163,6 @@ const {
|
|
|
163
163
|
handleSelectedItem,
|
|
164
164
|
handleSearch,
|
|
165
165
|
handleClear,
|
|
166
|
-
|
|
166
|
+
handleOptionsToggle,
|
|
167
167
|
} = useSelect(props, emit);
|
|
168
168
|
</script>
|