design-system-next 2.7.44 → 2.8.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 (28) hide show
  1. package/dist/design-system-next.js +6416 -5577
  2. package/dist/design-system-next.js.gz +0 -0
  3. package/dist/main.css +1 -1
  4. package/dist/main.css.gz +0 -0
  5. package/dist/package.json.d.ts +1 -1
  6. package/package.json +1 -1
  7. package/src/assets/styles/tailwind.css +3 -1
  8. package/src/components/date-picker/use-date-picker.ts +3 -10
  9. package/src/components/dropdown/__tests__/dropdown-fixes.spec.ts +106 -0
  10. package/src/components/dropdown/__tests__/dropdown-value-types.spec.ts +213 -0
  11. package/src/components/list/ladderized-list/ladderized-list.ts +12 -0
  12. package/src/components/list/ladderized-list/ladderized-list.vue +6 -0
  13. package/src/components/list/list.ts +15 -3
  14. package/src/components/list/list.vue +37 -9
  15. package/src/components/list/use-list.ts +116 -47
  16. package/src/components/select/select-ladderized/select-ladderized.ts +108 -0
  17. package/src/components/select/select-ladderized/select-ladderized.vue +111 -0
  18. package/src/components/select/select-ladderized/use-select-ladderized.ts +165 -0
  19. package/src/components/select/select-multiple/select-multiple.ts +128 -115
  20. package/src/components/select/select-multiple/select-multiple.vue +149 -88
  21. package/src/components/select/select-multiple/use-select-multiple.ts +367 -499
  22. package/src/components/select/select.ts +34 -4
  23. package/src/components/select/select.vue +137 -59
  24. package/src/components/select/use-select.ts +166 -249
  25. package/src/components/select/select-laderrized/select-laderrized.ts +0 -122
  26. package/src/components/select/select-laderrized/select-laderrized.vue +0 -110
  27. package/src/components/select/select-laderrized/use-select-laderrized.ts +0 -499
  28. package/src/examples/select-number-multi-select.vue +0 -71
@@ -1,21 +1,54 @@
1
- import { ref, toRefs, computed, onMounted, watch } from 'vue';
2
- import { onClickOutside, useInfiniteScroll, useVModel } from '@vueuse/core';
1
+ import { ref, toRefs, computed, ComputedRef, onMounted, watch } from 'vue';
2
+ import { onClickOutside, useInfiniteScroll, useVModel, useDebounceFn } from '@vueuse/core';
3
+
4
+ import classNames from 'classnames';
3
5
 
4
6
  import type { SetupContext } from 'vue';
5
7
  import type { SelectPropTypes, SelectEmitTypes } from './select';
6
8
  import type { MenuListType } from '../list/list';
7
9
 
10
+ interface SelectClasses {
11
+ baseClasses: string;
12
+ labelClasses: string;
13
+ }
14
+
8
15
  export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitTypes>['emit']) => {
9
- const { menuList, searchString, disabled, textField, valueField } = toRefs(props);
16
+ const { displayText, menuList, disabled, textField, valueField, disabledLocalSearch } = toRefs(props);
17
+
18
+ const selectClasses: ComputedRef<SelectClasses> = computed(() => {
19
+ const baseClasses = classNames('spr-flex spr-flex-col spr-gap-size-spacing-4xs');
20
+
21
+ const labelClasses = classNames('spr-body-sm-regular spr-text-color-strong spr-block', {
22
+ 'spr-text-color-on-fill-disabled': disabled.value,
23
+ });
24
+
25
+ return {
26
+ baseClasses,
27
+ labelClasses,
28
+ };
29
+ });
10
30
 
31
+ // Popper Variables
11
32
  const selectRef = ref<HTMLDivElement | null>(null);
12
33
  const selectPopperState = ref<boolean>(false);
13
34
  const isSelectPopperDisabled = computed(() => disabled.value);
14
35
 
36
+ // Select Variables
15
37
  const selectModel = useVModel(props, 'modelValue', emit);
16
- const inputText = ref('');
17
- const selectedListItems = ref<MenuListType[]>([]);
38
+ const selectedListItems = ref<MenuListType[]>();
18
39
  const selectMenuList = ref<MenuListType[]>([]);
40
+ const hasUserSelected = ref(false);
41
+
42
+ // Input Text Variables
43
+ const inputText = ref<string | number>('');
44
+ const inputTextBackup = ref<string | number>('');
45
+ const isSearching = ref<boolean>(false);
46
+
47
+ const handleMenuToggle = () => {
48
+ selectPopperState.value = true;
49
+
50
+ isSearching.value = false;
51
+ };
19
52
 
20
53
  // Normalized value for internal use - always an array
21
54
  const normalizedValue = computed(() => {
@@ -35,21 +68,20 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
35
68
 
36
69
  // Compatibility layer for pre-selected items (List component expects string[] format)
37
70
  const compatPreSelectedItems = computed(() => {
38
- return selectModel.value !== undefined && selectModel.value !== null
39
- ? [
40
- typeof selectModel.value === 'object'
41
- ? selectModel.value
42
- : typeof selectModel.value === 'number'
43
- ? selectModel.value
44
- : selectModel.value.toString(),
45
- ]
46
- : [];
71
+ if (selectModel.value === undefined || selectModel.value === null) return [];
72
+
73
+ if (Array.isArray(selectModel.value)) {
74
+ return selectModel.value;
75
+ }
76
+
77
+ return [selectModel.value];
47
78
  });
48
79
 
49
80
  const processMenuList = () => {
50
81
  // Handle empty array or non-array values
51
82
  if (!menuList.value || !Array.isArray(menuList.value) || menuList.value.length === 0) {
52
83
  selectMenuList.value = [];
84
+
53
85
  return;
54
86
  }
55
87
 
@@ -71,6 +103,7 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
71
103
  text: item.toString(),
72
104
  value: item, // Keep the value as a number instead of converting to string
73
105
  }));
106
+
74
107
  return;
75
108
  }
76
109
 
@@ -99,105 +132,45 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
99
132
  return;
100
133
  }
101
134
 
102
- // Default fallback
103
135
  selectMenuList.value = menuList.value as MenuListType[];
104
136
  };
105
137
 
106
- watch(menuList, () => {
107
- processMenuList();
108
- });
109
-
110
- const handleSearch = () => {
111
- if (menuList.value && menuList.value.length === 0) {
112
- return;
138
+ const filteredSelectMenuList = computed(() => {
139
+ if (disabledLocalSearch.value) {
140
+ return selectMenuList.value;
113
141
  }
114
142
 
115
- if (!multiSelect.value) {
116
- singleSelectSearch();
117
- } else {
118
- // Process menu list for searching
119
- processMenuList();
143
+ const query = inputText.value.toString().toLowerCase().trim();
120
144
 
121
- // Handle multi-select search - filter based on search string
122
- if (searchString.value.trim() !== '') {
123
- selectMenuList.value = getFilteredMenuList(selectMenuList.value);
124
- }
125
- }
126
- };
145
+ if (!query) return selectMenuList.value;
127
146
 
128
- const singleSelectSearch = () => {
129
- if (props.ladderized) {
130
- ladderizedSearch();
131
- } else {
132
- basicSearch();
133
- }
134
- };
147
+ return selectMenuList.value.filter((item) => item.text?.toString().toLowerCase().includes(query));
148
+ });
135
149
 
136
- const basicSearch = () => {
137
- // Process menu list first
150
+ watch(menuList, () => {
138
151
  processMenuList();
152
+ });
139
153
 
140
- // Then filter based on search string
141
- if (searchString.value.trim() !== '') {
142
- selectMenuList.value = getFilteredMenuList(selectMenuList.value);
143
- }
144
- };
145
-
146
- const ladderizedSearch = () => {
147
- //revert to initial list if search string is empty or selectModel is not empty
148
- if (searchString.value === '' || normalizedValue.value.length > 0) {
149
- selectMenuList.value = [...menuList.value] as MenuListType[];
150
- return;
151
- }
152
-
153
- const menuListSubLevels = getAllSublevelItems(menuList.value as MenuListType[]);
154
-
155
- const filteredMenuList = getFilteredMenuList(menuList.value as MenuListType[]);
156
- const filteredMenuListSubLevels = getFilteredMenuList(menuListSubLevels);
157
-
158
- if (filteredMenuList.length > 0) {
159
- //if there is a match at the top level of the menuList
160
- selectMenuList.value = getAllSublevelItems(filteredMenuList);
161
- } else if (filteredMenuListSubLevels.length > 0) {
162
- //if there is a match at the 2nd level (sublevel of a menuList item) of the menuList
163
- selectMenuList.value = filteredMenuListSubLevels;
164
- } else {
165
- selectMenuList.value = [];
166
- }
167
- };
168
-
169
- // compile sublevel items from menuList to a single array
170
- // and add text and value of the parent item to all sublevel items as subtext and subvalue
171
- const getAllSublevelItems = (menuList: MenuListType[]) => {
172
- return menuList.reduce<MenuListType[]>((currentValue, currentItem) => {
173
- if (currentItem.sublevel) {
174
- const mappedSublevel = currentItem.sublevel.map((sublevelItem: MenuListType) => ({
175
- ...sublevelItem, //text and value of a sublevel item
176
- subtext: currentItem.text, // text of parent of a sublevel item
177
- subvalue: typeof currentItem.value === 'string' ? currentItem.value : String(currentItem.value), // value of parent of a sublevel item as string
178
- }));
179
-
180
- return [...currentValue, ...mappedSublevel];
181
- }
182
-
183
- return currentValue;
184
- }, [] as MenuListType[]);
185
- };
154
+ // Search handler: always emit search-string, but only filter locally if local search is enabled
155
+ const handleSearch = () => {
156
+ isSearching.value = true;
186
157
 
187
- // filter list based on search string and menuList/sublevel texts
188
- const getFilteredMenuList = (list: MenuListType[]) => {
189
- return list.filter((item: MenuListType) => {
190
- const searchTerm = searchString.value.toLowerCase().trim();
191
- return item.text.toLowerCase().includes(searchTerm);
192
- });
158
+ debouncedEmitSearch();
193
159
  };
194
160
 
195
- watch(searchString, () => {
196
- handleSearch();
197
- });
161
+ const debouncedEmitSearch = useDebounceFn(() => {
162
+ emit('search-string', inputText.value);
163
+ }, 300);
198
164
 
199
165
  onClickOutside(selectRef, () => {
200
166
  selectPopperState.value = false;
167
+
168
+ // If user was searching, restore inputText from backup
169
+ if (isSearching.value) {
170
+ inputText.value = inputTextBackup.value;
171
+ }
172
+
173
+ isSearching.value = false;
201
174
  });
202
175
 
203
176
  useInfiniteScroll(
@@ -210,114 +183,40 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
210
183
 
211
184
  // Handle selected item for simple list component
212
185
  const handleSelectedItem = (selectedItems: MenuListType[]) => {
213
- if (!props.ladderized) {
214
- // Determine the type of value to emit based on the original data type and multiSelect
215
- if (multiSelect.value) {
216
- // For multi-select, always return an array
217
- const values = selectedItems.map((item) => {
218
- // If we stored the original object, use it
219
- if ('_originalObject' in item) {
220
- return item._originalObject;
221
- }
186
+ if (selectedItems.length === 0) {
187
+ selectModel.value = '';
222
188
 
223
- // For simple types, handle value type conversion properly
224
- const val = item.value;
189
+ return;
190
+ }
225
191
 
226
- // If it's already a number, keep it as a number
227
- if (typeof val === 'number') {
228
- return val;
229
- }
192
+ hasUserSelected.value = true; // User has now made a selection
230
193
 
231
- // For strings that look like numbers, convert them
232
- if (typeof val === 'string' && !isNaN(Number(val)) && val.trim() !== '') {
233
- // Only convert if it looks like a proper number format
234
- if (/^-?\d+(\.\d+)?$/.test(val)) {
235
- return Number(val);
236
- }
237
- }
194
+ const item = selectedItems[0];
238
195
 
239
- // Return the original value for all other cases
240
- return val;
241
- });
196
+ // If we stored the original object, use it
197
+ if ('_originalObject' in item) {
198
+ selectModel.value = item._originalObject as Record<string, unknown>;
199
+ } else {
200
+ // For simple types, return the value (try to convert number strings to numbers)
201
+ const itemValue = item.value;
202
+ const itemText = item.text || '';
242
203
 
243
- selectModel.value = values as (string | number | Record<string, unknown>)[];
204
+ if (typeof itemValue === 'string' && !isNaN(Number(itemValue)) && itemValue.trim() !== '') {
205
+ selectModel.value = Number(itemValue);
244
206
  } else {
245
- // For single-select
246
- if (selectedItems.length === 0) {
247
- selectModel.value = props.multiSelect ? [] : '';
248
- return;
249
- }
250
-
251
- const item = selectedItems[0];
252
-
253
- // If we stored the original object, use it
254
- if ('_originalObject' in item) {
255
- selectModel.value = item._originalObject as Record<string, unknown>;
256
- } else {
257
- // For simple types, return the value (try to convert number strings to numbers)
258
- const val = item.value;
259
- if (typeof val === 'string' && !isNaN(Number(val)) && val.trim() !== '') {
260
- selectModel.value = Number(val);
261
- } else {
262
- selectModel.value = val;
263
- }
264
- }
207
+ selectModel.value = itemValue;
265
208
  }
266
- } else if (props.ladderized) {
267
- if (props.searchString !== '') {
268
- // generate select value if ladderized with search string
269
- const subvalue = selectedItems[0]?.subvalue;
270
- const value = selectedItems[0]?.value;
271
- if (subvalue !== undefined && value !== undefined) {
272
- selectModel.value = [subvalue, value] as [string, string | number];
273
- }
274
- } else {
275
- // For regular ladderized select selection without search
276
- if (selectedItems.length > 0) {
277
- const item = selectedItems[0];
278
- // Use the value directly for ladderized items
279
- if (item && item.value) {
280
- selectModel.value = item.value;
281
- }
282
- }
283
- }
284
- }
285
209
 
286
- // Always close select for single selection, regardless of value type
287
- if (!multiSelect.value) {
288
- setTimeout(() => {
289
- selectPopperState.value = false;
290
- }, 10);
210
+ inputText.value = itemText;
291
211
  }
292
- };
293
212
 
294
- // Handle selected item for ladderized list component
295
- const handleSelectedLadderizedItem = (selectedItems: string[]) => {
296
- // Update the model value with the selected ladderized items
297
- if (selectedItems.length > 0) {
298
- selectModel.value = selectedItems;
299
- }
213
+ // Clone inputText to backup after selection
214
+ inputTextBackup.value = inputText.value;
300
215
 
301
- // If item is from last sublevel, close the select
302
- if (checkIfItemFromLastSublevel(selectedItems)) {
216
+ // Always close select for single selection
217
+ setTimeout(() => {
303
218
  selectPopperState.value = false;
304
- }
305
- };
306
-
307
- const checkIfItemFromLastSublevel = (selectedItems: string[]) => {
308
- let selectedItemsObject = selectMenuList.value;
309
-
310
- // Traverse to the last item in the selectedItems array
311
- selectedItems.forEach((selectedItem) => {
312
- selectedItemsObject = selectedItemsObject.find((item) => selectedItem === item.value)?.sublevel ?? [];
313
- });
314
-
315
- // If there is a sublevel, return false
316
- if (selectedItemsObject.length > 0) {
317
- return false;
318
- }
319
-
320
- return true;
219
+ }, 10);
321
220
  };
322
221
 
323
222
  // Update selected items when model value changes externally
@@ -325,8 +224,26 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
325
224
  if (!selectMenuList.value.length) return;
326
225
 
327
226
  const values = normalizedValue.value;
227
+
328
228
  if (!values || !values.length) {
329
229
  selectedListItems.value = [];
230
+
231
+ // Only set displayText if user hasn't typed anything
232
+ if (
233
+ displayText.value &&
234
+ !hasUserSelected.value &&
235
+ !isSearching.value &&
236
+ (!inputText.value || inputText.value === '')
237
+ ) {
238
+ inputText.value = displayText.value;
239
+
240
+ // Clone displayText to backup if present
241
+ inputTextBackup.value = displayText.value;
242
+ } else if (!hasUserSelected.value && (!inputText.value || inputText.value === '')) {
243
+ inputText.value = '';
244
+ inputTextBackup.value = '';
245
+ }
246
+
330
247
  return;
331
248
  }
332
249
 
@@ -355,63 +272,57 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
355
272
  // Extract just string values for comparison
356
273
  const valueStrings = valueData.map((v) => v.string);
357
274
 
358
- if (props.ladderized) {
359
- // Special handling for ladderized selects
360
- if (Array.isArray(selectModel.value) && selectModel.value.length === 2) {
361
- // Handle [subvalue, value] format used in ladderized selects with search
362
- const subvalue = selectModel.value[0]?.toString() || '';
363
- const value = selectModel.value[1]?.toString() || '';
275
+ selectedListItems.value = selectMenuList.value.filter((item) => {
276
+ // Handle objects with _originalObject property
277
+ if ('_originalObject' in item && item._originalObject) {
278
+ return valueData.some((v) => {
279
+ // If both are objects, compare by JSON string or by ID
280
+ if (v.isObject && typeof v.original === 'object') {
281
+ const originalObj = item._originalObject as Record<string, unknown>;
364
282
 
365
- selectedListItems.value = selectMenuList.value.filter((item) => {
366
- return item.value === value && (!item.subvalue || item.subvalue === subvalue);
367
- });
368
- } else {
369
- // Regular ladderized select value
370
- selectedListItems.value = selectMenuList.value.filter((item) => {
371
- // Convert both to strings for comparison or check direct equality for numbers
372
- if (typeof item.value === 'number') {
373
- return valueData.some((v) => v.original === item.value || v.string === String(item.value));
374
- } else {
375
- return valueStrings.includes(String(item.value));
283
+ if (v.original === originalObj) return true;
284
+
285
+ const itemJson = JSON.stringify(originalObj);
286
+
287
+ if (v.string === itemJson) return true;
288
+
289
+ if (v.id !== undefined && 'id' in originalObj) {
290
+ return v.id === originalObj.id;
291
+ }
376
292
  }
293
+ return false;
377
294
  });
378
295
  }
379
- } else {
380
- // Regular Select value
381
- selectedListItems.value = selectMenuList.value.filter((item) => {
382
- // Handle objects with _originalObject property
383
- if ('_originalObject' in item && item._originalObject) {
384
- return valueData.some((v) => {
385
- // If both are objects, compare by JSON string or by ID
386
- if (v.isObject && typeof v.original === 'object') {
387
- const originalObj = item._originalObject as Record<string, unknown>;
388
-
389
- // First try direct equality comparison
390
- if (v.original === originalObj) return true;
391
-
392
- // Try JSON string comparison
393
- const itemJson = JSON.stringify(originalObj);
394
- if (v.string === itemJson) return true;
395
-
396
- // Try ID-based comparison if both have ID fields
397
- if (v.id !== undefined && 'id' in originalObj) {
398
- return v.id === originalObj.id;
399
- }
400
- }
401
- return false;
402
- });
403
- }
404
-
405
- // Handle both numeric and string values correctly
406
- if (typeof item.value === 'number') {
407
- return valueData.some((v) => v.original === item.value || v.string === String(item.value));
408
- } else {
409
- return valueStrings.includes(String(item.value));
410
- }
411
- });
296
+
297
+ // Handle both numeric and string values correctly
298
+ if (typeof item.value === 'number') {
299
+ return valueData.some((v) => v.original === item.value || v.string === String(item.value));
300
+ } else {
301
+ return valueStrings.includes(String(item.value));
302
+ }
303
+ });
304
+
305
+ // Only update inputText if not searching
306
+ if (!isSearching.value) {
307
+ inputText.value = selectedListItems.value.map((item) => item.text).join(', ');
308
+
309
+ // Only use displayText.value if user hasn't selected anything yet
310
+ if (displayText.value && !hasUserSelected.value && (!inputText.value || inputText.value === '')) {
311
+ inputText.value = displayText.value;
312
+ inputTextBackup.value = displayText.value;
313
+ } else {
314
+ // Always update backup to match inputText if not searching
315
+ inputTextBackup.value = inputText.value;
316
+ }
412
317
  }
413
318
  };
414
319
 
320
+ const handleClear = () => {
321
+ emit('update:modelValue', '');
322
+
323
+ inputText.value = '';
324
+ };
325
+
415
326
  watch(selectModel, () => {
416
327
  updateSelectedItemsFromValue();
417
328
  });
@@ -426,20 +337,26 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
426
337
  // Set initial selected items based on model value
427
338
  if (normalizedValue.value.length > 0) {
428
339
  updateSelectedItemsFromValue();
340
+ } else if (displayText.value) {
341
+ inputText.value = displayText.value;
342
+ inputTextBackup.value = displayText.value;
429
343
  }
430
344
  });
431
345
 
432
346
  return {
347
+ selectClasses,
433
348
  selectPopperState,
349
+ handleMenuToggle,
434
350
  selectRef,
435
- inputText,
351
+ selectModel: compatPreSelectedItems, // Use compatible format for lists
436
352
  selectMenuList,
437
- isSelectPopperDisabled,
353
+ filteredSelectMenuList,
438
354
  selectedListItems,
355
+ inputText,
356
+ isSelectPopperDisabled,
357
+ isSearching,
439
358
  handleSelectedItem,
440
- handleSelectedLadderizedItem,
441
- selectModel: compatPreSelectedItems, // Use compatible format for lists
442
- removeCurrentLevelInBackLabel,
443
- isLadderizedSearch,
359
+ handleSearch,
360
+ handleClear,
444
361
  };
445
362
  };
@@ -1,122 +0,0 @@
1
- // import type { PropType, ExtractPropTypes } from 'vue';
2
- // import type { MenuListType } from '../list/list';
3
-
4
- // export const definePropType = <T>(val: unknown): PropType<T> => val as PropType<T>;
5
-
6
- // const GROUPED_ITEMS_BY_TYPES = ['A-Z', 'Z-A'] as const;
7
-
8
- // const PLACEMENTS_TYPES = [
9
- // 'auto',
10
- // 'auto-start',
11
- // 'auto-end',
12
- // 'top',
13
- // 'top-start',
14
- // 'top-end',
15
- // 'right',
16
- // 'right-start',
17
- // 'right-end',
18
- // 'bottom',
19
- // 'bottom-start',
20
- // 'bottom-end',
21
- // 'left',
22
- // 'left-start',
23
- // 'left-end',
24
- // ] as const;
25
-
26
- // const POPPER_STRATEGY_TYPES = ['fixed', 'absolute'] as const;
27
-
28
- // export const selectPropTypes = {
29
- // id: {
30
- // type: String,
31
- // required: true,
32
- // },
33
- // modelValue: {
34
- // type: [String, Number, Object, Array] as PropType<
35
- // string | number | Record<string, unknown> | (string | number | Record<string, unknown>)[]
36
- // >,
37
- // default: () => [],
38
- // },
39
- // menuList: {
40
- // type: Array as PropType<MenuListType[] | string[] | Record<string, unknown>[]>,
41
- // required: true,
42
- // default: [],
43
- // },
44
- // multiSelect: {
45
- // type: Boolean,
46
- // default: false,
47
- // },
48
- // groupItemsBy: {
49
- // type: String as PropType<(typeof GROUPED_ITEMS_BY_TYPES)[number]>,
50
- // validator: (value: (typeof GROUPED_ITEMS_BY_TYPES)[number] | undefined) => {
51
- // return value === undefined || GROUPED_ITEMS_BY_TYPES.includes(value);
52
- // },
53
- // },
54
- // textField: {
55
- // type: String,
56
- // default: 'text',
57
- // description: 'Field name to use for display text when using dynamic object arrays',
58
- // },
59
- // valueField: {
60
- // type: String,
61
- // default: 'value',
62
- // description: 'Field name to use for value when using dynamic object arrays',
63
- // },
64
- // placeholder: {
65
- // type: String,
66
- // },
67
- // searchString: {
68
- // type: String,
69
- // default: '',
70
- // },
71
- // placement: {
72
- // type: String as PropType<(typeof PLACEMENTS_TYPES)[number]>,
73
- // validator: (value: (typeof PLACEMENTS_TYPES)[number]) => PLACEMENTS_TYPES.includes(value),
74
- // default: 'bottom',
75
- // },
76
- // popperStrategy: {
77
- // type: String,
78
- // validator: (value: 'fixed' | 'absolute') => POPPER_STRATEGY_TYPES.includes(value),
79
- // default: 'absolute',
80
- // },
81
- // popperWidth: {
82
- // type: String,
83
- // default: '100%',
84
- // },
85
- // width: {
86
- // type: String,
87
- // default: '100%',
88
- // },
89
- // wrapperPosition: {
90
- // type: String,
91
- // default: 'relative',
92
- // },
93
- // disabled: {
94
- // type: Boolean,
95
- // default: false,
96
- // },
97
- // readonly: {
98
- // type: Boolean,
99
- // default: false,
100
- // },
101
- // ladderized: {
102
- // type: Boolean,
103
- // default: false,
104
- // },
105
- // removeCurrentLevelInBackLabel: {
106
- // type: Boolean,
107
- // default: false,
108
- // },
109
- // disabled: {
110
- // type: Boolean,
111
- // default: false,
112
- // },
113
- // };
114
-
115
- // export const selectEmitTypes = {
116
- // 'infinite-scroll-trigger': Boolean,
117
- // // eslint-disable-next-line @typescript-eslint/no-unused-vars
118
- // 'update:modelValue': (_value: unknown) => true, // Accept any type of value
119
- // };
120
-
121
- // export type SelectPropTypes = ExtractPropTypes<typeof selectPropTypes>;
122
- // export type SelectEmitTypes = typeof selectEmitTypes;