design-system-next 2.7.36 → 2.7.37
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 +3652 -3459
- package/dist/design-system-next.js.gz +0 -0
- package/dist/main.css +1 -1
- package/dist/main.css.gz +0 -0
- package/package.json +1 -1
- package/src/components/dropdown/__tests__/dropdown-fixes.spec.ts +106 -0
- package/src/components/dropdown/__tests__/dropdown-value-types.spec.ts +213 -0
- package/src/components/dropdown/dropdown.ts +14 -3
- package/src/components/dropdown/fix-multi-number.ts +92 -0
- package/src/components/dropdown/use-dropdown.ts +328 -23
- package/src/components/filter/filter.vue +3 -3
- package/src/components/filter/use-filter.ts +3 -6
- package/src/components/list/list.ts +4 -3
- package/src/components/list/use-list.ts +158 -7
- package/src/examples/dropdown-number-multi-select.vue +76 -0
|
@@ -6,30 +6,149 @@ import type { DropdownPropTypes, DropdownEmitTypes } from './dropdown';
|
|
|
6
6
|
import type { MenuListType } from '../list/list';
|
|
7
7
|
|
|
8
8
|
export const useDropdown = (props: DropdownPropTypes, emit: SetupContext<DropdownEmitTypes>['emit']) => {
|
|
9
|
-
const { menuList, searchString, disabled, multiSelect, removeCurrentLevelInBackLabel, ladderized } = toRefs(props);
|
|
9
|
+
const { menuList, searchString, disabled, multiSelect, removeCurrentLevelInBackLabel, ladderized, textField, valueField } = toRefs(props);
|
|
10
10
|
|
|
11
11
|
// Dropdown component ref variables
|
|
12
|
-
const dropdownValue = useVModel(props, 'modelValue', emit); // v-model value of
|
|
12
|
+
const dropdownValue = useVModel(props, 'modelValue', emit); // v-model value of dropdown component
|
|
13
13
|
const dropdownRef = ref<HTMLDivElement | null>(null);
|
|
14
14
|
|
|
15
15
|
// List component ref variables
|
|
16
16
|
const selectedListItems = ref<MenuListType[]>([]); // v-model value of the list component
|
|
17
17
|
const dropdownMenuList = ref<MenuListType[]>([]); // menu list for the list component
|
|
18
18
|
|
|
19
|
+
// Normalized value for internal use - always an array
|
|
20
|
+
const normalizedValue = computed(() => {
|
|
21
|
+
// If already an array, use it
|
|
22
|
+
if (Array.isArray(dropdownValue.value)) {
|
|
23
|
+
return dropdownValue.value;
|
|
24
|
+
}
|
|
25
|
+
// If not an array but has a value, make it a single-item array
|
|
26
|
+
if (dropdownValue.value !== undefined && dropdownValue.value !== null) {
|
|
27
|
+
return [dropdownValue.value];
|
|
28
|
+
}
|
|
29
|
+
// Default empty array
|
|
30
|
+
return [];
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Compatibility layer for pre-selected items (List component expects string[] format)
|
|
34
|
+
const compatPreSelectedItems = computed(() => {
|
|
35
|
+
// For ladderized dropdown with search, handle the special format
|
|
36
|
+
if (props.ladderized && Array.isArray(dropdownValue.value) && dropdownValue.value.length === 2) {
|
|
37
|
+
// We return only the second value from the [subvalue, value] format which is the actual selected value
|
|
38
|
+
return [dropdownValue.value[1]?.toString() || ''];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// For regular arrays (multi-select)
|
|
42
|
+
if (Array.isArray(dropdownValue.value)) {
|
|
43
|
+
return dropdownValue.value.map(item => {
|
|
44
|
+
if (item === undefined || item === null) return '';
|
|
45
|
+
|
|
46
|
+
// For numbers, preserve the original number value instead of converting to string
|
|
47
|
+
if (typeof item === 'number') return item;
|
|
48
|
+
|
|
49
|
+
// For objects, pass the original object reference
|
|
50
|
+
// This is key for proper multi-select of objects
|
|
51
|
+
if (typeof item === 'object') return item;
|
|
52
|
+
|
|
53
|
+
// For strings, pass as is
|
|
54
|
+
return item.toString();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// For single values (single-select)
|
|
59
|
+
return dropdownValue.value !== undefined && dropdownValue.value !== null
|
|
60
|
+
? [typeof dropdownValue.value === 'object' ?
|
|
61
|
+
// Pass object reference directly instead of stringifying
|
|
62
|
+
dropdownValue.value :
|
|
63
|
+
// For numbers, preserve the original number value
|
|
64
|
+
typeof dropdownValue.value === 'number' ?
|
|
65
|
+
dropdownValue.value :
|
|
66
|
+
dropdownValue.value.toString()]
|
|
67
|
+
: [];
|
|
68
|
+
});
|
|
69
|
+
|
|
19
70
|
// Popper state
|
|
20
71
|
const dropdownPopperState = ref<boolean>(false);
|
|
21
72
|
const isDropdownPopperDisabled = computed(() => disabled.value);
|
|
22
73
|
|
|
23
74
|
const isLadderizedSearch = computed(
|
|
24
|
-
() => ladderized.value && searchString.value !== '' &&
|
|
75
|
+
() => ladderized.value && searchString.value !== '' && normalizedValue.value.length === 0,
|
|
25
76
|
);
|
|
26
77
|
|
|
27
|
-
const
|
|
28
|
-
|
|
78
|
+
const processMenuList = () => {
|
|
79
|
+
// Handle empty array or non-array values
|
|
80
|
+
if (!menuList.value || !Array.isArray(menuList.value) || menuList.value.length === 0) {
|
|
81
|
+
dropdownMenuList.value = [];
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// If ladderized is true and menu list items already conform to MenuListType, don't transform
|
|
86
|
+
if (ladderized.value) {
|
|
87
|
+
// Verify the items have the required structure for ladderized lists
|
|
88
|
+
const allValid = menuList.value.every(item =>
|
|
89
|
+
typeof item === 'object' && item !== null && 'text' in item && 'value' in item
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if (allValid) {
|
|
93
|
+
dropdownMenuList.value = menuList.value as MenuListType[];
|
|
94
|
+
} else {
|
|
95
|
+
console.warn('Ladderized dropdown requires menu items in {text, value} format');
|
|
96
|
+
dropdownMenuList.value = [];
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const firstItem = menuList.value[0];
|
|
102
|
+
|
|
103
|
+
// Handle array of strings
|
|
104
|
+
if (typeof firstItem === 'string') {
|
|
105
|
+
dropdownMenuList.value = (menuList.value as string[]).map(item => ({
|
|
106
|
+
text: item,
|
|
107
|
+
value: item
|
|
108
|
+
}));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Handle array of numbers
|
|
113
|
+
if (typeof firstItem === 'number') {
|
|
114
|
+
dropdownMenuList.value = (menuList.value as number[]).map(item => ({
|
|
115
|
+
text: item.toString(),
|
|
116
|
+
value: item // Keep the value as a number instead of converting to string
|
|
117
|
+
}));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Handle array of objects with dynamic attributes
|
|
122
|
+
if (typeof firstItem === 'object' && firstItem !== null) {
|
|
123
|
+
// Check if it's already in MenuListType format
|
|
124
|
+
if ('text' in firstItem && 'value' in firstItem) {
|
|
125
|
+
dropdownMenuList.value = menuList.value as MenuListType[];
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Transform to MenuListType format using textField and valueField
|
|
130
|
+
dropdownMenuList.value = (menuList.value as Record<string, unknown>[]).map(item => {
|
|
131
|
+
const displayText = item[textField.value] || 'Unnamed';
|
|
132
|
+
// Use the specified value field if available, otherwise use the entire object
|
|
133
|
+
const itemValue = valueField.value && item[valueField.value] !== undefined
|
|
134
|
+
? item[valueField.value]
|
|
135
|
+
: item;
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
text: displayText,
|
|
139
|
+
value: typeof itemValue === 'object' ? JSON.stringify(itemValue) : itemValue.toString(),
|
|
140
|
+
_originalObject: item // Store the original object for reference
|
|
141
|
+
};
|
|
142
|
+
});
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Default fallback
|
|
147
|
+
dropdownMenuList.value = menuList.value as MenuListType[];
|
|
29
148
|
};
|
|
30
149
|
|
|
31
150
|
watch(menuList, () => {
|
|
32
|
-
|
|
151
|
+
processMenuList();
|
|
33
152
|
});
|
|
34
153
|
|
|
35
154
|
const handleSearch = () => {
|
|
@@ -40,8 +159,13 @@ export const useDropdown = (props: DropdownPropTypes, emit: SetupContext<Dropdow
|
|
|
40
159
|
if (!multiSelect.value) {
|
|
41
160
|
singleSelectSearch();
|
|
42
161
|
} else {
|
|
43
|
-
|
|
44
|
-
|
|
162
|
+
// Process menu list for searching
|
|
163
|
+
processMenuList();
|
|
164
|
+
|
|
165
|
+
// Handle multi-select search - filter based on search string
|
|
166
|
+
if (searchString.value.trim() !== '') {
|
|
167
|
+
dropdownMenuList.value = getFilteredMenuList(dropdownMenuList.value);
|
|
168
|
+
}
|
|
45
169
|
}
|
|
46
170
|
};
|
|
47
171
|
|
|
@@ -54,19 +178,25 @@ export const useDropdown = (props: DropdownPropTypes, emit: SetupContext<Dropdow
|
|
|
54
178
|
};
|
|
55
179
|
|
|
56
180
|
const basicSearch = () => {
|
|
57
|
-
|
|
181
|
+
// Process menu list first
|
|
182
|
+
processMenuList();
|
|
183
|
+
|
|
184
|
+
// Then filter based on search string
|
|
185
|
+
if (searchString.value.trim() !== '') {
|
|
186
|
+
dropdownMenuList.value = getFilteredMenuList(dropdownMenuList.value);
|
|
187
|
+
}
|
|
58
188
|
};
|
|
59
189
|
|
|
60
190
|
const ladderizedSearch = () => {
|
|
61
191
|
//revert to initial list if search string is empty or dropdownValue is not empty
|
|
62
|
-
if (searchString.value === '' ||
|
|
63
|
-
dropdownMenuList.value = [...menuList.value];
|
|
192
|
+
if (searchString.value === '' || normalizedValue.value.length > 0) {
|
|
193
|
+
dropdownMenuList.value = [...menuList.value] as MenuListType[];
|
|
64
194
|
return;
|
|
65
195
|
}
|
|
66
196
|
|
|
67
|
-
const menuListSubLevels = getAllSublevelItems(menuList.value);
|
|
197
|
+
const menuListSubLevels = getAllSublevelItems(menuList.value as MenuListType[]);
|
|
68
198
|
|
|
69
|
-
const filteredMenuList = getFilteredMenuList(menuList.value);
|
|
199
|
+
const filteredMenuList = getFilteredMenuList(menuList.value as MenuListType[]);
|
|
70
200
|
const filteredMenuListSubLevels = getFilteredMenuList(menuListSubLevels);
|
|
71
201
|
|
|
72
202
|
if (filteredMenuList.length > 0) {
|
|
@@ -83,12 +213,12 @@ export const useDropdown = (props: DropdownPropTypes, emit: SetupContext<Dropdow
|
|
|
83
213
|
// compile sublevel items from menuList to a single array
|
|
84
214
|
// and add text and value of the parent item to all sublevel items as subtext and subvalue
|
|
85
215
|
const getAllSublevelItems = (menuList: MenuListType[]) => {
|
|
86
|
-
return menuList.reduce((currentValue, currentItem) => {
|
|
216
|
+
return menuList.reduce<MenuListType[]>((currentValue, currentItem) => {
|
|
87
217
|
if (currentItem.sublevel) {
|
|
88
218
|
const mappedSublevel = currentItem.sublevel.map((sublevelItem: MenuListType) => ({
|
|
89
219
|
...sublevelItem, //text and value of a sublevel item
|
|
90
220
|
subtext: currentItem.text, // text of parent of a sublevel item
|
|
91
|
-
subvalue: currentItem.value, // value of parent of a sublevel item
|
|
221
|
+
subvalue: typeof currentItem.value === 'string' ? currentItem.value : String(currentItem.value), // value of parent of a sublevel item as string
|
|
92
222
|
}));
|
|
93
223
|
|
|
94
224
|
return [...currentValue, ...mappedSublevel];
|
|
@@ -125,15 +255,80 @@ export const useDropdown = (props: DropdownPropTypes, emit: SetupContext<Dropdow
|
|
|
125
255
|
// Handle selected item for simple list component
|
|
126
256
|
const handleSelectedItem = (selectedItems: MenuListType[]) => {
|
|
127
257
|
if (!props.ladderized) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
258
|
+
// Determine the type of value to emit based on the original data type and multiSelect
|
|
259
|
+
if (multiSelect.value) {
|
|
260
|
+
// For multi-select, always return an array
|
|
261
|
+
const values = selectedItems.map(item => {
|
|
262
|
+
// If we stored the original object, use it
|
|
263
|
+
if ('_originalObject' in item) {
|
|
264
|
+
return item._originalObject;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// For simple types, handle value type conversion properly
|
|
268
|
+
const val = item.value;
|
|
269
|
+
|
|
270
|
+
// If it's already a number, keep it as a number
|
|
271
|
+
if (typeof val === 'number') {
|
|
272
|
+
return val;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// For strings that look like numbers, convert them
|
|
276
|
+
if (typeof val === 'string' && !isNaN(Number(val)) && val.trim() !== '') {
|
|
277
|
+
// Only convert if it looks like a proper number format
|
|
278
|
+
if (/^-?\d+(\.\d+)?$/.test(val)) {
|
|
279
|
+
return Number(val);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Return the original value for all other cases
|
|
284
|
+
return val;
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
dropdownValue.value = values as (string | number | Record<string, unknown>)[];
|
|
288
|
+
} else {
|
|
289
|
+
// For single-select
|
|
290
|
+
if (selectedItems.length === 0) {
|
|
291
|
+
dropdownValue.value = props.multiSelect ? [] : '';
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const item = selectedItems[0];
|
|
296
|
+
|
|
297
|
+
// If we stored the original object, use it
|
|
298
|
+
if ('_originalObject' in item) {
|
|
299
|
+
dropdownValue.value = item._originalObject as Record<string, unknown>;
|
|
300
|
+
} else {
|
|
301
|
+
// For simple types, return the value (try to convert number strings to numbers)
|
|
302
|
+
const val = item.value;
|
|
303
|
+
if (typeof val === 'string' && !isNaN(Number(val)) && val.trim() !== '') {
|
|
304
|
+
dropdownValue.value = Number(val);
|
|
305
|
+
} else {
|
|
306
|
+
dropdownValue.value = val;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
} else if (props.ladderized) {
|
|
311
|
+
if (props.searchString !== '') {
|
|
133
312
|
// generate dropdown value if ladderized with search string
|
|
134
|
-
|
|
313
|
+
const subvalue = selectedItems[0]?.subvalue;
|
|
314
|
+
const value = selectedItems[0]?.value;
|
|
315
|
+
if (subvalue !== undefined && value !== undefined) {
|
|
316
|
+
dropdownValue.value = [subvalue, value] as [string, string | number];
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
// For regular ladderized dropdown selection without search
|
|
320
|
+
if (selectedItems.length > 0) {
|
|
321
|
+
const item = selectedItems[0];
|
|
322
|
+
// Use the value directly for ladderized items
|
|
323
|
+
if (item && item.value) {
|
|
324
|
+
dropdownValue.value = item.value;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
135
327
|
}
|
|
328
|
+
}
|
|
136
329
|
|
|
330
|
+
// Always close dropdown for single selection, regardless of value type
|
|
331
|
+
if (!multiSelect.value) {
|
|
137
332
|
setTimeout(() => {
|
|
138
333
|
dropdownPopperState.value = false;
|
|
139
334
|
}, 10);
|
|
@@ -142,6 +337,11 @@ export const useDropdown = (props: DropdownPropTypes, emit: SetupContext<Dropdow
|
|
|
142
337
|
|
|
143
338
|
// Handle selected item for ladderized list component
|
|
144
339
|
const handleSelectedLadderizedItem = (selectedItems: string[]) => {
|
|
340
|
+
// Update the model value with the selected ladderized items
|
|
341
|
+
if (selectedItems.length > 0) {
|
|
342
|
+
dropdownValue.value = selectedItems;
|
|
343
|
+
}
|
|
344
|
+
|
|
145
345
|
// If item is from last sublevel, close the dropdown
|
|
146
346
|
if (checkIfItemFromLastSublevel(selectedItems)) {
|
|
147
347
|
dropdownPopperState.value = false;
|
|
@@ -164,8 +364,113 @@ export const useDropdown = (props: DropdownPropTypes, emit: SetupContext<Dropdow
|
|
|
164
364
|
return true;
|
|
165
365
|
};
|
|
166
366
|
|
|
367
|
+
// Update selected items when model value changes externally
|
|
368
|
+
const updateSelectedItemsFromValue = () => {
|
|
369
|
+
if (!dropdownMenuList.value.length) return;
|
|
370
|
+
|
|
371
|
+
const values = normalizedValue.value;
|
|
372
|
+
if (!values || !values.length) {
|
|
373
|
+
selectedListItems.value = [];
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Store both original values and string versions for flexible matching
|
|
378
|
+
const valueData = values.map(val => {
|
|
379
|
+
if (val === undefined || val === null) return { original: '', string: '' };
|
|
380
|
+
|
|
381
|
+
// For objects, use JSON string representation
|
|
382
|
+
if (typeof val === 'object') {
|
|
383
|
+
return {
|
|
384
|
+
original: val,
|
|
385
|
+
string: JSON.stringify(val),
|
|
386
|
+
isObject: true,
|
|
387
|
+
id: 'id' in val ? val.id : undefined
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// For numbers and strings, keep original and string versions
|
|
392
|
+
return {
|
|
393
|
+
original: val,
|
|
394
|
+
string: val.toString(),
|
|
395
|
+
isObject: false
|
|
396
|
+
};
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// Extract just string values for comparison
|
|
400
|
+
const valueStrings = valueData.map(v => v.string);
|
|
401
|
+
|
|
402
|
+
if (props.ladderized) {
|
|
403
|
+
// Special handling for ladderized dropdowns
|
|
404
|
+
if (Array.isArray(dropdownValue.value) && dropdownValue.value.length === 2) {
|
|
405
|
+
// Handle [subvalue, value] format used in ladderized dropdowns with search
|
|
406
|
+
const subvalue = dropdownValue.value[0]?.toString() || '';
|
|
407
|
+
const value = dropdownValue.value[1]?.toString() || '';
|
|
408
|
+
|
|
409
|
+
selectedListItems.value = dropdownMenuList.value.filter(item => {
|
|
410
|
+
return item.value === value && (!item.subvalue || item.subvalue === subvalue);
|
|
411
|
+
});
|
|
412
|
+
} else {
|
|
413
|
+
// Regular ladderized dropdown value
|
|
414
|
+
selectedListItems.value = dropdownMenuList.value.filter(item => {
|
|
415
|
+
// Convert both to strings for comparison or check direct equality for numbers
|
|
416
|
+
if (typeof item.value === 'number') {
|
|
417
|
+
return valueData.some(v => v.original === item.value || v.string === String(item.value));
|
|
418
|
+
} else {
|
|
419
|
+
return valueStrings.includes(String(item.value));
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
} else {
|
|
424
|
+
// Regular dropdown value
|
|
425
|
+
selectedListItems.value = dropdownMenuList.value.filter(item => {
|
|
426
|
+
// Handle objects with _originalObject property
|
|
427
|
+
if ('_originalObject' in item && item._originalObject) {
|
|
428
|
+
return valueData.some(v => {
|
|
429
|
+
// If both are objects, compare by JSON string or by ID
|
|
430
|
+
if (v.isObject && typeof v.original === 'object') {
|
|
431
|
+
const originalObj = item._originalObject as Record<string, unknown>;
|
|
432
|
+
|
|
433
|
+
// First try direct equality comparison
|
|
434
|
+
if (v.original === originalObj) return true;
|
|
435
|
+
|
|
436
|
+
// Try JSON string comparison
|
|
437
|
+
const itemJson = JSON.stringify(originalObj);
|
|
438
|
+
if (v.string === itemJson) return true;
|
|
439
|
+
|
|
440
|
+
// Try ID-based comparison if both have ID fields
|
|
441
|
+
if (v.id !== undefined && 'id' in originalObj) {
|
|
442
|
+
return v.id === originalObj.id;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return false;
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Handle both numeric and string values correctly
|
|
450
|
+
if (typeof item.value === 'number') {
|
|
451
|
+
return valueData.some(v => v.original === item.value || v.string === String(item.value));
|
|
452
|
+
} else {
|
|
453
|
+
return valueStrings.includes(String(item.value));
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
watch(dropdownValue, () => {
|
|
460
|
+
updateSelectedItemsFromValue();
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
watch(dropdownMenuList, () => {
|
|
464
|
+
updateSelectedItemsFromValue();
|
|
465
|
+
});
|
|
466
|
+
|
|
167
467
|
onMounted(() => {
|
|
168
|
-
|
|
468
|
+
processMenuList();
|
|
469
|
+
|
|
470
|
+
// Set initial selected items based on model value
|
|
471
|
+
if (normalizedValue.value.length > 0) {
|
|
472
|
+
updateSelectedItemsFromValue();
|
|
473
|
+
}
|
|
169
474
|
});
|
|
170
475
|
|
|
171
476
|
return {
|
|
@@ -176,7 +481,7 @@ export const useDropdown = (props: DropdownPropTypes, emit: SetupContext<Dropdow
|
|
|
176
481
|
selectedListItems,
|
|
177
482
|
handleSelectedItem,
|
|
178
483
|
handleSelectedLadderizedItem,
|
|
179
|
-
dropdownValue,
|
|
484
|
+
dropdownValue: compatPreSelectedItems, // Use compatible format for lists
|
|
180
485
|
removeCurrentLevelInBackLabel,
|
|
181
486
|
isLadderizedSearch,
|
|
182
487
|
};
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
:key="menu.field"
|
|
78
78
|
v-model:shown="mappedFilterMenuList[menu.field].isFilterVisible"
|
|
79
79
|
aria-id="filter-menu-wrapper"
|
|
80
|
-
placement="right
|
|
80
|
+
placement="right"
|
|
81
81
|
:triggers="['click']"
|
|
82
82
|
:auto-hide="false"
|
|
83
83
|
>
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
|
|
119
119
|
<div
|
|
120
120
|
v-if="getSelectedFilterMenuOption.length > 0"
|
|
121
|
-
class="spr-space-x-2 spr-space-y-2 spr-p-size-spacing-2xs"
|
|
121
|
+
class="spr-h-[70px] spr-space-x-2 spr-space-y-2 spr-overflow-auto spr-p-size-spacing-2xs"
|
|
122
122
|
>
|
|
123
123
|
<spr-chips
|
|
124
124
|
v-for="(FilterMenuOption, i) in getSelectedFilterMenuOption"
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
v-if="getFiltereredMenuOption.length > 0"
|
|
134
134
|
:id="menu.field"
|
|
135
135
|
ref="filterMenuOptionList"
|
|
136
|
-
class="spr-
|
|
136
|
+
class="spr-h-[264px] spr-space-y-size-spacing-6xs spr-overflow-auto spr-p-size-spacing-2xs"
|
|
137
137
|
>
|
|
138
138
|
<div
|
|
139
139
|
v-for="(option, key) in getFiltereredMenuOption"
|
|
@@ -144,11 +144,6 @@ export const useFilter = (props: FilterPropTypes, emit: SetupContext<FilterEmitT
|
|
|
144
144
|
emit('infiniteScrollTrigger', true);
|
|
145
145
|
};
|
|
146
146
|
|
|
147
|
-
watch(loading, () => {
|
|
148
|
-
if (loading.value) return;
|
|
149
|
-
getMappedMenuOptionList();
|
|
150
|
-
});
|
|
151
|
-
|
|
152
147
|
watch(selectedColumn, (_value) => {
|
|
153
148
|
setFilterVisible(_value);
|
|
154
149
|
});
|
|
@@ -222,7 +217,9 @@ export const useFilter = (props: FilterPropTypes, emit: SetupContext<FilterEmitT
|
|
|
222
217
|
const PopperContentClasses = classNames(
|
|
223
218
|
'spr-flex spr-w-[328px] spr-flex-wrap spr-gap-size-spacing-2xs spr-p-size-spacing-xs',
|
|
224
219
|
);
|
|
225
|
-
const LoadingStateClasses = classNames(
|
|
220
|
+
const LoadingStateClasses = classNames(
|
|
221
|
+
'spr-h-[264px] spr-p-size-spacing-sm spr-flex spr-items-center spr-justify-center',
|
|
222
|
+
);
|
|
226
223
|
const ActionButtonClasses = classNames('spr-flex spr-justify-end spr-gap-2 spr-p-size-spacing-2xs');
|
|
227
224
|
const filterListClasses = classNames(
|
|
228
225
|
'spr-body-xs-regular spr-flex spr-cursor-pointer spr-justify-between spr-rounded-border-radius-md spr-p-size-spacing-4xs',
|
|
@@ -7,11 +7,12 @@ const GROUPED_ITEMS_BY_TYPES = ['A-Z', 'Z-A', 'default'] as const;
|
|
|
7
7
|
export type MenuListType = {
|
|
8
8
|
text: string;
|
|
9
9
|
subtext?: string;
|
|
10
|
-
value: string;
|
|
10
|
+
value: string | number; // Allow both string and number values
|
|
11
11
|
subvalue?: string;
|
|
12
12
|
sublevel?: MenuListType[];
|
|
13
13
|
group?: string;
|
|
14
14
|
disabled?: boolean;
|
|
15
|
+
_originalObject?: Record<string, unknown>; // Store original object reference when mapping complex objects
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export type GroupedMenuListType = {
|
|
@@ -40,8 +41,8 @@ export const listPropTypes = {
|
|
|
40
41
|
default: false,
|
|
41
42
|
},
|
|
42
43
|
preSelectedItems: {
|
|
43
|
-
type: Array as PropType<string[]>,
|
|
44
|
-
default: [],
|
|
44
|
+
type: Array as PropType<(string | number | Record<string, unknown>)[]>,
|
|
45
|
+
default: () => [],
|
|
45
46
|
},
|
|
46
47
|
ladderized: {
|
|
47
48
|
type: Boolean,
|