design-system-next 2.9.3 → 2.9.5
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 +3641 -3577
- 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/calendar/calendar.vue +10 -5
- package/src/components/select/select-ladderized/select-ladderized.ts +1 -0
- package/src/components/select/select-ladderized/select-ladderized.vue +1 -0
- package/src/components/select/select-multiple/select-multiple.ts +10 -3
- package/src/components/select/select-multiple/select-multiple.vue +50 -36
- package/src/components/select/select-multiple/use-select-multiple.ts +18 -5
- package/src/components/select/select.ts +9 -0
- package/src/components/select/select.vue +59 -47
- package/src/components/select/use-select.ts +34 -31
|
@@ -23,46 +23,60 @@
|
|
|
23
23
|
width: props.width,
|
|
24
24
|
}"
|
|
25
25
|
>
|
|
26
|
-
<div
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
<div ref="multiSelectRef">
|
|
27
|
+
<div @click="handleOptionsToggle">
|
|
28
|
+
<spr-input
|
|
29
|
+
v-model="inputText"
|
|
30
|
+
:id="props.id"
|
|
31
|
+
:class="{
|
|
32
|
+
'spr-cursor-pointer': true,
|
|
33
|
+
}"
|
|
34
|
+
:placeholder="props.placeholder"
|
|
35
|
+
autocomplete="off"
|
|
36
|
+
:helper-text="props.helperText"
|
|
37
|
+
:helper-icon="props.helperIcon"
|
|
38
|
+
:display-helper="props.displayHelper"
|
|
39
|
+
:active="props.active"
|
|
40
|
+
:readonly="true"
|
|
41
|
+
:disabled="props.disabled"
|
|
42
|
+
:error="props.error"
|
|
43
|
+
>
|
|
44
|
+
<template #icon>
|
|
45
|
+
<div class="spr-flex spr-items-center spr-gap-1">
|
|
46
|
+
<Icon
|
|
47
|
+
v-if="props.clearable && inputText"
|
|
48
|
+
class="spr-cursor-pointer"
|
|
49
|
+
icon="ph:x"
|
|
50
|
+
@click.stop="handleClear"
|
|
51
|
+
/>
|
|
52
|
+
<Icon icon="ph:caret-down" />
|
|
53
|
+
</div>
|
|
54
|
+
</template>
|
|
55
|
+
|
|
56
|
+
<template #helperMessage>
|
|
57
|
+
<slot name="helperMessage" />
|
|
58
|
+
</template>
|
|
59
|
+
</spr-input>
|
|
60
|
+
|
|
61
|
+
<!-- Hidden Select for QA automation -->
|
|
62
|
+
<select v-if="multiSelectOptions && multiSelectOptions.length" v-model="multiSelectModel" multiple hidden>
|
|
63
|
+
<option v-for="option in multiSelectOptions" :key="option.value" :value="option.value">
|
|
64
|
+
{{ option.text }}
|
|
65
|
+
</option>
|
|
66
|
+
</select>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<!-- This div used to poppulate popper menu -->
|
|
70
|
+
<div
|
|
71
|
+
:id="props.id"
|
|
72
|
+
:style="{
|
|
73
|
+
width: props.popperWidth,
|
|
31
74
|
}"
|
|
32
|
-
|
|
33
|
-
:readonly="true"
|
|
34
|
-
:disabled="props.disabled"
|
|
35
|
-
autocomplete="off"
|
|
36
|
-
:helper-text="props.helperText"
|
|
37
|
-
:helper-icon="props.helperIcon"
|
|
38
|
-
:display-helper="props.displayHelper"
|
|
39
|
-
>
|
|
40
|
-
<template #icon>
|
|
41
|
-
<div class="spr-flex spr-items-center spr-gap-1">
|
|
42
|
-
<Icon
|
|
43
|
-
v-if="props.clearable && inputText"
|
|
44
|
-
class="spr-cursor-pointer"
|
|
45
|
-
icon="ph:x"
|
|
46
|
-
@click.stop="handleClear"
|
|
47
|
-
/>
|
|
48
|
-
<Icon icon="ph:caret-down" />
|
|
49
|
-
</div>
|
|
50
|
-
</template>
|
|
51
|
-
</spr-input>
|
|
75
|
+
></div>
|
|
52
76
|
</div>
|
|
53
77
|
|
|
54
|
-
<div
|
|
55
|
-
:id="props.id"
|
|
56
|
-
:style="{
|
|
57
|
-
width: props.popperWidth,
|
|
58
|
-
}"
|
|
59
|
-
></div>
|
|
60
|
-
|
|
61
78
|
<template #popper>
|
|
62
|
-
<div
|
|
63
|
-
ref="multiSelectRef"
|
|
64
|
-
class="spr-grid spr-max-h-[300px] spr-gap-0.5 spr-overflow-y-auto spr-overflow-x-hidden spr-p-2"
|
|
65
|
-
>
|
|
79
|
+
<div class="spr-grid spr-max-h-[300px] spr-gap-0.5 spr-overflow-y-auto spr-overflow-x-hidden spr-p-2">
|
|
66
80
|
<template v-if="multiSelectOptions.length > 0">
|
|
67
81
|
<spr-list
|
|
68
82
|
v-model="multiSelectedListItems"
|
|
@@ -118,7 +118,7 @@ export const useMultiSelect = (props: MultiSelectPropTypes, emit: SetupContext<M
|
|
|
118
118
|
* Opens the multi-select options.
|
|
119
119
|
*/
|
|
120
120
|
const handleOptionsToggle = () => {
|
|
121
|
-
multiSelectPopperState.value =
|
|
121
|
+
multiSelectPopperState.value = !multiSelectPopperState.value;
|
|
122
122
|
};
|
|
123
123
|
|
|
124
124
|
/**
|
|
@@ -140,7 +140,6 @@ export const useMultiSelect = (props: MultiSelectPropTypes, emit: SetupContext<M
|
|
|
140
140
|
|
|
141
141
|
hasUserSelected.value = true;
|
|
142
142
|
multiSelectModel.value = selectedValues;
|
|
143
|
-
multiSelectPopperState.value = true;
|
|
144
143
|
inputTextBackup.value =
|
|
145
144
|
multiSelectedItems.length > 3
|
|
146
145
|
? `${multiSelectedItems.length} items selected`
|
|
@@ -224,9 +223,23 @@ export const useMultiSelect = (props: MultiSelectPropTypes, emit: SetupContext<M
|
|
|
224
223
|
updateMultiSelectedItemsFromValue();
|
|
225
224
|
});
|
|
226
225
|
|
|
227
|
-
watch(
|
|
228
|
-
|
|
229
|
-
|
|
226
|
+
watch(
|
|
227
|
+
multiSelectOptions,
|
|
228
|
+
() => {
|
|
229
|
+
updateMultiSelectedItemsFromValue();
|
|
230
|
+
},
|
|
231
|
+
{ deep: true },
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
// Add watcher for options prop to re-process options when changed
|
|
235
|
+
watch(
|
|
236
|
+
options,
|
|
237
|
+
() => {
|
|
238
|
+
processOptions();
|
|
239
|
+
updateMultiSelectedItemsFromValue();
|
|
240
|
+
},
|
|
241
|
+
{ deep: true },
|
|
242
|
+
);
|
|
230
243
|
|
|
231
244
|
/**
|
|
232
245
|
* Handles closing the multi-select when clicking outside.
|
|
@@ -29,6 +29,7 @@ export const selectPropTypes = {
|
|
|
29
29
|
id: {
|
|
30
30
|
type: String,
|
|
31
31
|
required: true,
|
|
32
|
+
default: 'select',
|
|
32
33
|
},
|
|
33
34
|
modelValue: {
|
|
34
35
|
type: [String, Number, Object, Array] as PropType<
|
|
@@ -102,10 +103,18 @@ export const selectPropTypes = {
|
|
|
102
103
|
type: String,
|
|
103
104
|
default: '',
|
|
104
105
|
},
|
|
106
|
+
active: {
|
|
107
|
+
type: Boolean,
|
|
108
|
+
default: false,
|
|
109
|
+
},
|
|
105
110
|
disabled: {
|
|
106
111
|
type: Boolean,
|
|
107
112
|
default: false,
|
|
108
113
|
},
|
|
114
|
+
error: {
|
|
115
|
+
type: Boolean,
|
|
116
|
+
default: false,
|
|
117
|
+
},
|
|
109
118
|
clearable: {
|
|
110
119
|
type: Boolean,
|
|
111
120
|
default: false,
|
|
@@ -23,58 +23,69 @@
|
|
|
23
23
|
width: props.width,
|
|
24
24
|
}"
|
|
25
25
|
>
|
|
26
|
-
<div
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
26
|
+
<div ref="selectRef">
|
|
27
|
+
<div @click="handleOptionsToggle">
|
|
28
|
+
<spr-input
|
|
29
|
+
:id="props.id"
|
|
30
|
+
v-model="inputText"
|
|
31
|
+
:class="{
|
|
32
|
+
'spr-cursor-pointer': !props.searchable,
|
|
33
|
+
}"
|
|
34
|
+
:placeholder="props.placeholder"
|
|
35
|
+
autocomplete="off"
|
|
36
|
+
:helper-text="props.helperText"
|
|
37
|
+
:helper-icon="props.helperIcon"
|
|
38
|
+
:display-helper="props.displayHelper"
|
|
39
|
+
:active="props.active"
|
|
40
|
+
:readonly="!props.searchable"
|
|
41
|
+
:disabled="props.disabled"
|
|
42
|
+
:error="props.error"
|
|
43
|
+
@keyup="handleSearch"
|
|
44
|
+
>
|
|
45
|
+
<template #icon>
|
|
46
|
+
<div class="spr-flex spr-cursor-pointer spr-items-center">
|
|
47
|
+
<Icon
|
|
48
|
+
v-if="props.clearable && inputText"
|
|
49
|
+
class="spr-cursor-pointer"
|
|
50
|
+
icon="ph:x"
|
|
51
|
+
@click.stop="handleClear"
|
|
52
|
+
/>
|
|
53
|
+
<Icon icon="ph:caret-down" />
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
<template #helperMessage>
|
|
58
|
+
<slot name="helperMessage" />
|
|
59
|
+
</template>
|
|
60
|
+
</spr-input>
|
|
61
|
+
|
|
62
|
+
<!-- Hidden Select for QA automation -->
|
|
63
|
+
<select
|
|
64
|
+
v-if="selectOptions && selectOptions.length"
|
|
65
|
+
:value="Array.isArray(selectModel) ? selectModel[0] : selectModel"
|
|
66
|
+
data-testid="qa-hidden-select"
|
|
67
|
+
tabindex="-1"
|
|
68
|
+
aria-hidden="true"
|
|
69
|
+
hidden
|
|
70
|
+
>
|
|
71
|
+
<option v-for="item in selectOptions" :key="item.value" :value="item.value">
|
|
72
|
+
{{ item.text }}
|
|
73
|
+
</option>
|
|
74
|
+
</select>
|
|
75
|
+
</div>
|
|
67
76
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
<!-- This div used to poppulate popper menu -->
|
|
78
|
+
<div
|
|
79
|
+
:id="props.id"
|
|
80
|
+
:style="{
|
|
81
|
+
width: props.popperWidth,
|
|
82
|
+
}"
|
|
83
|
+
></div>
|
|
84
|
+
</div>
|
|
74
85
|
|
|
75
86
|
<template #popper>
|
|
76
87
|
<div
|
|
77
|
-
ref="
|
|
88
|
+
ref="selectPopperRef"
|
|
78
89
|
class="spr-grid spr-max-h-[300px] spr-gap-0.5 spr-overflow-y-auto spr-overflow-x-hidden spr-p-2"
|
|
79
90
|
>
|
|
80
91
|
<template v-if="isSearching">
|
|
@@ -153,6 +164,7 @@ const {
|
|
|
153
164
|
selectClasses,
|
|
154
165
|
selectPopperState,
|
|
155
166
|
selectRef,
|
|
167
|
+
selectPopperRef,
|
|
156
168
|
selectModel,
|
|
157
169
|
selectOptions,
|
|
158
170
|
filteredSelectOptions,
|
|
@@ -34,6 +34,7 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
|
|
|
34
34
|
const isSelectPopperDisabled = computed(() => disabled.value);
|
|
35
35
|
|
|
36
36
|
// Select Variables
|
|
37
|
+
const selectPopperRef = ref<HTMLDivElement | null>(null);
|
|
37
38
|
const selectModel = useVModel(props, 'modelValue', emit);
|
|
38
39
|
const selectedListItems = ref<MenuListType[]>();
|
|
39
40
|
const selectOptions = ref<MenuListType[]>([]);
|
|
@@ -44,12 +45,6 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
|
|
|
44
45
|
const inputTextBackup = ref<string | number>('');
|
|
45
46
|
const isSearching = ref<boolean>(false);
|
|
46
47
|
|
|
47
|
-
const handleOptionsToggle = () => {
|
|
48
|
-
selectPopperState.value = true;
|
|
49
|
-
|
|
50
|
-
isSearching.value = false;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
48
|
// Normalized value for internal use - always an array
|
|
54
49
|
const normalizedValue = computed(() => {
|
|
55
50
|
// If already an array, use it
|
|
@@ -147,14 +142,6 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
|
|
|
147
142
|
return selectOptions.value.filter((item) => item.text?.toString().toLowerCase().includes(query));
|
|
148
143
|
});
|
|
149
144
|
|
|
150
|
-
watch(
|
|
151
|
-
options,
|
|
152
|
-
() => {
|
|
153
|
-
processOptions();
|
|
154
|
-
},
|
|
155
|
-
{ deep: true },
|
|
156
|
-
);
|
|
157
|
-
|
|
158
145
|
// Search handler: always emit search-string, but only filter locally if local search is enabled
|
|
159
146
|
const handleSearch = () => {
|
|
160
147
|
isSearching.value = true;
|
|
@@ -166,24 +153,12 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
|
|
|
166
153
|
emit('search-string', inputText.value);
|
|
167
154
|
}, 300);
|
|
168
155
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
// If user was searching, restore inputText from backup
|
|
173
|
-
if (isSearching.value) {
|
|
174
|
-
inputText.value = inputTextBackup.value;
|
|
175
|
-
}
|
|
156
|
+
// Toggle options popper state
|
|
157
|
+
const handleOptionsToggle = () => {
|
|
158
|
+
selectPopperState.value = !selectPopperState.value;
|
|
176
159
|
|
|
177
160
|
isSearching.value = false;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
useInfiniteScroll(
|
|
181
|
-
selectRef,
|
|
182
|
-
() => {
|
|
183
|
-
emit('infinite-scroll-trigger', true);
|
|
184
|
-
},
|
|
185
|
-
{ distance: 10 },
|
|
186
|
-
);
|
|
161
|
+
};
|
|
187
162
|
|
|
188
163
|
// Handle selected item for simple list component
|
|
189
164
|
const handleSelectedItem = (selectedItems: MenuListType[]) => {
|
|
@@ -336,6 +311,33 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
|
|
|
336
311
|
updateSelectedItemsFromValue();
|
|
337
312
|
});
|
|
338
313
|
|
|
314
|
+
watch(
|
|
315
|
+
options,
|
|
316
|
+
() => {
|
|
317
|
+
processOptions();
|
|
318
|
+
},
|
|
319
|
+
{ deep: true },
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
onClickOutside(selectRef, () => {
|
|
323
|
+
selectPopperState.value = false;
|
|
324
|
+
|
|
325
|
+
// If user was searching, restore inputText from backup
|
|
326
|
+
if (isSearching.value) {
|
|
327
|
+
inputText.value = inputTextBackup.value;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
isSearching.value = false;
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
useInfiniteScroll(
|
|
334
|
+
selectPopperRef,
|
|
335
|
+
() => {
|
|
336
|
+
emit('infinite-scroll-trigger', true);
|
|
337
|
+
},
|
|
338
|
+
{ distance: 10 },
|
|
339
|
+
);
|
|
340
|
+
|
|
339
341
|
onMounted(() => {
|
|
340
342
|
processOptions();
|
|
341
343
|
|
|
@@ -351,8 +353,8 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
|
|
|
351
353
|
return {
|
|
352
354
|
selectClasses,
|
|
353
355
|
selectPopperState,
|
|
354
|
-
handleOptionsToggle,
|
|
355
356
|
selectRef,
|
|
357
|
+
selectPopperRef,
|
|
356
358
|
selectModel: compatPreSelectedItems, // Use compatible format for lists
|
|
357
359
|
selectOptions,
|
|
358
360
|
filteredSelectOptions,
|
|
@@ -360,6 +362,7 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
|
|
|
360
362
|
inputText,
|
|
361
363
|
isSelectPopperDisabled,
|
|
362
364
|
isSearching,
|
|
365
|
+
handleOptionsToggle,
|
|
363
366
|
handleSelectedItem,
|
|
364
367
|
handleSearch,
|
|
365
368
|
handleClear,
|