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.
- package/dist/design-system-next.js +6416 -5577
- 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/assets/styles/tailwind.css +3 -1
- package/src/components/date-picker/use-date-picker.ts +3 -10
- 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/list/ladderized-list/ladderized-list.ts +12 -0
- package/src/components/list/ladderized-list/ladderized-list.vue +6 -0
- package/src/components/list/list.ts +15 -3
- package/src/components/list/list.vue +37 -9
- package/src/components/list/use-list.ts +116 -47
- package/src/components/select/select-ladderized/select-ladderized.ts +108 -0
- package/src/components/select/select-ladderized/select-ladderized.vue +111 -0
- package/src/components/select/select-ladderized/use-select-ladderized.ts +165 -0
- package/src/components/select/select-multiple/select-multiple.ts +128 -115
- package/src/components/select/select-multiple/select-multiple.vue +149 -88
- package/src/components/select/select-multiple/use-select-multiple.ts +367 -499
- package/src/components/select/select.ts +34 -4
- package/src/components/select/select.vue +137 -59
- package/src/components/select/use-select.ts +166 -249
- package/src/components/select/select-laderrized/select-laderrized.ts +0 -122
- package/src/components/select/select-laderrized/select-laderrized.vue +0 -110
- package/src/components/select/select-laderrized/use-select-laderrized.ts +0 -499
- package/src/examples/select-number-multi-select.vue +0 -71
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { PropType, ExtractPropTypes } from 'vue';
|
|
2
|
+
import type { MenuListType } from '@/components/list/list';
|
|
3
|
+
|
|
4
|
+
const PLACEMENTS_TYPES = [
|
|
5
|
+
'auto',
|
|
6
|
+
'auto-start',
|
|
7
|
+
'auto-end',
|
|
8
|
+
'top',
|
|
9
|
+
'top-start',
|
|
10
|
+
'top-end',
|
|
11
|
+
'right',
|
|
12
|
+
'right-start',
|
|
13
|
+
'right-end',
|
|
14
|
+
'bottom',
|
|
15
|
+
'bottom-start',
|
|
16
|
+
'bottom-end',
|
|
17
|
+
'left',
|
|
18
|
+
'left-start',
|
|
19
|
+
'left-end',
|
|
20
|
+
] as const;
|
|
21
|
+
|
|
22
|
+
const POPPER_STRATEGY_TYPES = ['fixed', 'absolute'] as const;
|
|
23
|
+
|
|
24
|
+
export const selectLadderizedPropTypes = {
|
|
25
|
+
id: {
|
|
26
|
+
type: String,
|
|
27
|
+
required: true,
|
|
28
|
+
},
|
|
29
|
+
modelValue: {
|
|
30
|
+
type: Array as PropType<string[]>,
|
|
31
|
+
default: () => [],
|
|
32
|
+
},
|
|
33
|
+
menuList: {
|
|
34
|
+
type: Array as PropType<MenuListType[]>,
|
|
35
|
+
required: true,
|
|
36
|
+
default: () => [],
|
|
37
|
+
},
|
|
38
|
+
label: {
|
|
39
|
+
type: String,
|
|
40
|
+
default: '',
|
|
41
|
+
},
|
|
42
|
+
placeholder: {
|
|
43
|
+
type: String,
|
|
44
|
+
default: '',
|
|
45
|
+
},
|
|
46
|
+
helperText: {
|
|
47
|
+
type: String,
|
|
48
|
+
default: '',
|
|
49
|
+
},
|
|
50
|
+
helperIcon: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: null,
|
|
53
|
+
},
|
|
54
|
+
displayHelper: {
|
|
55
|
+
type: Boolean,
|
|
56
|
+
default: false,
|
|
57
|
+
},
|
|
58
|
+
clearable: {
|
|
59
|
+
type: Boolean,
|
|
60
|
+
default: false,
|
|
61
|
+
},
|
|
62
|
+
searchableMenu: {
|
|
63
|
+
type: Boolean,
|
|
64
|
+
default: false,
|
|
65
|
+
},
|
|
66
|
+
searchableMenuPlaceholder: {
|
|
67
|
+
type: String,
|
|
68
|
+
default: 'Search...',
|
|
69
|
+
},
|
|
70
|
+
placement: {
|
|
71
|
+
type: String as PropType<(typeof PLACEMENTS_TYPES)[number]>,
|
|
72
|
+
validator: (value: (typeof PLACEMENTS_TYPES)[number]) => PLACEMENTS_TYPES.includes(value),
|
|
73
|
+
default: 'bottom',
|
|
74
|
+
},
|
|
75
|
+
wrapperPosition: {
|
|
76
|
+
type: String,
|
|
77
|
+
default: 'relative',
|
|
78
|
+
},
|
|
79
|
+
width: {
|
|
80
|
+
type: String,
|
|
81
|
+
default: '100%',
|
|
82
|
+
},
|
|
83
|
+
popperWidth: {
|
|
84
|
+
type: String,
|
|
85
|
+
default: '100%',
|
|
86
|
+
},
|
|
87
|
+
popperStrategy: {
|
|
88
|
+
type: String,
|
|
89
|
+
validator: (value: 'fixed' | 'absolute') => POPPER_STRATEGY_TYPES.includes(value),
|
|
90
|
+
default: 'absolute',
|
|
91
|
+
},
|
|
92
|
+
disabled: {
|
|
93
|
+
type: Boolean,
|
|
94
|
+
default: false,
|
|
95
|
+
},
|
|
96
|
+
removeCurrentLevelInBackLabel: {
|
|
97
|
+
type: Boolean,
|
|
98
|
+
default: false,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const selectLadderizedEmitTypes = {
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
104
|
+
'update:modelValue': (_value: unknown) => true,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export type SelectLadderizedPropTypes = ExtractPropTypes<typeof selectLadderizedPropTypes>;
|
|
108
|
+
export type SelectLadderizedEmitTypes = typeof selectLadderizedEmitTypes;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="ladderizedClasses.baseClasses">
|
|
3
|
+
<label v-if="props.label" :for="props.id" :class="ladderizedClasses.labelClasses">
|
|
4
|
+
{{ props.label }}
|
|
5
|
+
</label>
|
|
6
|
+
|
|
7
|
+
<Menu
|
|
8
|
+
:shown="ladderizedSelectPopperState"
|
|
9
|
+
aria-id="ladderized-select-wrapper"
|
|
10
|
+
distance="4"
|
|
11
|
+
:placement="props.placement"
|
|
12
|
+
:triggers="[]"
|
|
13
|
+
:popper-hide-triggers="[]"
|
|
14
|
+
:auto-hide="false"
|
|
15
|
+
:disabled="isLadderizedSelectPopperDisabled"
|
|
16
|
+
:container="'#ladderized-select-wrapper'"
|
|
17
|
+
:strategy="
|
|
18
|
+
props.popperStrategy === 'fixed' || props.popperStrategy === 'absolute' ? props.popperStrategy : 'absolute'
|
|
19
|
+
"
|
|
20
|
+
:delay="0"
|
|
21
|
+
:style="{
|
|
22
|
+
position: props.wrapperPosition,
|
|
23
|
+
width: props.width,
|
|
24
|
+
}"
|
|
25
|
+
>
|
|
26
|
+
<div @click="handleMenuToggle">
|
|
27
|
+
<spr-input
|
|
28
|
+
v-model="inputText"
|
|
29
|
+
class="spr-cursor-pointer"
|
|
30
|
+
:placeholder="props.placeholder"
|
|
31
|
+
autocomplete="off"
|
|
32
|
+
:helper-text="props.helperText"
|
|
33
|
+
:helper-icon="props.helperIcon"
|
|
34
|
+
:display-helper="props.displayHelper"
|
|
35
|
+
readonly
|
|
36
|
+
:disabled="props.disabled"
|
|
37
|
+
@keyup="handleSearch"
|
|
38
|
+
>
|
|
39
|
+
<template #icon>
|
|
40
|
+
<div class="spr-flex spr-items-center spr-gap-1">
|
|
41
|
+
<Icon
|
|
42
|
+
v-if="props.clearable && inputText"
|
|
43
|
+
class="spr-cursor-pointer"
|
|
44
|
+
icon="ph:x"
|
|
45
|
+
@click.stop="handleClear"
|
|
46
|
+
/>
|
|
47
|
+
<Icon icon="ph:caret-down" />
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
</spr-input>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div id="ladderized-select-wrapper" :style="{ width: props.popperWidth }"></div>
|
|
54
|
+
|
|
55
|
+
<template #popper>
|
|
56
|
+
<div
|
|
57
|
+
ref="ladderizedSelectRef"
|
|
58
|
+
class="spr-grid spr-max-h-[300px] spr-gap-0.5 spr-overflow-y-auto spr-overflow-x-hidden"
|
|
59
|
+
>
|
|
60
|
+
<template v-if="ladderizedSelectMenuList.length > 0">
|
|
61
|
+
<spr-ladderized-list
|
|
62
|
+
v-model="ladderizedSelectModel"
|
|
63
|
+
:ladderized="true"
|
|
64
|
+
:menu-list="ladderizedSelectMenuList"
|
|
65
|
+
:menu-level="ladderizedSelectModel.length"
|
|
66
|
+
:remove-current-level-in-back-label="props.removeCurrentLevelInBackLabel"
|
|
67
|
+
:searchable-menu="props.searchableMenu"
|
|
68
|
+
:searchable-menu-placeholder="props.searchableMenuPlaceholder"
|
|
69
|
+
@update:model-value="handleSelectedLadderizedItem"
|
|
70
|
+
/>
|
|
71
|
+
</template>
|
|
72
|
+
<template v-else>
|
|
73
|
+
<div class="spr-flex spr-items-center spr-justify-center spr-p-2 spr-text-center">
|
|
74
|
+
<span class="spr-body-sm-regular spr-m-0">No results found</span>
|
|
75
|
+
</div>
|
|
76
|
+
</template>
|
|
77
|
+
</div>
|
|
78
|
+
</template>
|
|
79
|
+
</Menu>
|
|
80
|
+
</div>
|
|
81
|
+
</template>
|
|
82
|
+
|
|
83
|
+
<script lang="ts" setup>
|
|
84
|
+
import { Menu } from 'floating-vue';
|
|
85
|
+
import { Icon } from '@iconify/vue';
|
|
86
|
+
|
|
87
|
+
import 'floating-vue/dist/style.css';
|
|
88
|
+
|
|
89
|
+
import SprInput from '@/components/input/input.vue';
|
|
90
|
+
import SprLadderizedList from '@/components/list/ladderized-list/ladderized-list.vue';
|
|
91
|
+
|
|
92
|
+
import { selectLadderizedPropTypes, selectLadderizedEmitTypes } from './select-ladderized';
|
|
93
|
+
import { useSelectLadderized } from './use-select-ladderized';
|
|
94
|
+
|
|
95
|
+
const props = defineProps(selectLadderizedPropTypes);
|
|
96
|
+
const emit = defineEmits(selectLadderizedEmitTypes);
|
|
97
|
+
|
|
98
|
+
const {
|
|
99
|
+
ladderizedClasses,
|
|
100
|
+
ladderizedSelectPopperState,
|
|
101
|
+
ladderizedSelectRef,
|
|
102
|
+
ladderizedSelectMenuList,
|
|
103
|
+
isLadderizedSelectPopperDisabled,
|
|
104
|
+
ladderizedSelectModel,
|
|
105
|
+
inputText,
|
|
106
|
+
handleSelectedLadderizedItem,
|
|
107
|
+
handleSearch,
|
|
108
|
+
handleClear,
|
|
109
|
+
handleMenuToggle,
|
|
110
|
+
} = useSelectLadderized(props, emit);
|
|
111
|
+
</script>
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { ref, computed, watch } from 'vue';
|
|
2
|
+
import { useDebounceFn, onClickOutside } from '@vueuse/core';
|
|
3
|
+
|
|
4
|
+
import type { SelectLadderizedPropTypes } from './select-ladderized';
|
|
5
|
+
|
|
6
|
+
import type { MenuListType } from '@/components/list/list';
|
|
7
|
+
|
|
8
|
+
export const useSelectLadderized = (
|
|
9
|
+
props: SelectLadderizedPropTypes,
|
|
10
|
+
emit: (event: string, ...args: unknown[]) => void,
|
|
11
|
+
) => {
|
|
12
|
+
const ladderizedClasses = computed(() => ({
|
|
13
|
+
baseClasses: 'spr-flex spr-flex-col spr-gap-size-spacing-4xs',
|
|
14
|
+
labelClasses: 'spr-body-sm-regular spr-text-color-strong spr-block',
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
// Popper Variables
|
|
18
|
+
const ladderizedSelectPopperState = ref(false);
|
|
19
|
+
const ladderizedSelectRef = ref(null);
|
|
20
|
+
const isLadderizedSelectPopperDisabled = computed(() => props.disabled);
|
|
21
|
+
|
|
22
|
+
// Ladderized Select Model
|
|
23
|
+
const ladderizedSelectModel = computed({
|
|
24
|
+
get: () => props.modelValue,
|
|
25
|
+
set: (val) => emit('update:modelValue', val),
|
|
26
|
+
});
|
|
27
|
+
const ladderizedSelectMenuList = computed(() => props.menuList);
|
|
28
|
+
|
|
29
|
+
// Input Variables
|
|
30
|
+
const inputText = ref<string>('');
|
|
31
|
+
const isSearching = ref(false);
|
|
32
|
+
const wasCleared = ref(false);
|
|
33
|
+
|
|
34
|
+
const isLeafNode = (item: MenuListType): boolean => {
|
|
35
|
+
return !item.sublevel || item.sublevel.length === 0;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Helper to find the path to a selected value in the menu tree
|
|
39
|
+
const findPathToValue = (items: MenuListType[], value: string | number, path: string[] = []): string[] | null => {
|
|
40
|
+
for (const item of items) {
|
|
41
|
+
const newPath = [...path, item.text];
|
|
42
|
+
|
|
43
|
+
if (item.value === value) {
|
|
44
|
+
return newPath;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (item.sublevel) {
|
|
48
|
+
const result = findPathToValue(item.sublevel, value, newPath);
|
|
49
|
+
|
|
50
|
+
if (result) return result;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return null;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const handleSelectedLadderizedItem = (selectedItems: string[], selectedItem?: MenuListType) => {
|
|
58
|
+
wasCleared.value = false;
|
|
59
|
+
ladderizedSelectModel.value = selectedItems;
|
|
60
|
+
|
|
61
|
+
let itemToCheck = selectedItem;
|
|
62
|
+
|
|
63
|
+
// Fallback: if selectedItem is not provided, try to find it from the value
|
|
64
|
+
if (!itemToCheck && selectedItems.length > 0) {
|
|
65
|
+
const findItemByValue = (items: MenuListType[], value: string | number): MenuListType | undefined => {
|
|
66
|
+
for (const item of items) {
|
|
67
|
+
if (item.value === value) return item;
|
|
68
|
+
|
|
69
|
+
if (item.sublevel) {
|
|
70
|
+
const found = findItemByValue(item.sublevel, value);
|
|
71
|
+
|
|
72
|
+
if (found) return found;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return undefined;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
itemToCheck = findItemByValue(ladderizedSelectMenuList.value, selectedItems[selectedItems.length - 1]);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (itemToCheck) {
|
|
83
|
+
const path = findPathToValue(ladderizedSelectMenuList.value, itemToCheck.value);
|
|
84
|
+
|
|
85
|
+
inputText.value = path ? path.join(' > ') : itemToCheck.text || '';
|
|
86
|
+
|
|
87
|
+
if (isLeafNode(itemToCheck)) {
|
|
88
|
+
ladderizedSelectPopperState.value = false;
|
|
89
|
+
}
|
|
90
|
+
} else if (selectedItems.length === 0 && !wasCleared.value) {
|
|
91
|
+
inputText.value = '';
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const handleSearch = () => {
|
|
96
|
+
isSearching.value = true;
|
|
97
|
+
|
|
98
|
+
debouncedEmitSearch();
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const debouncedEmitSearch = useDebounceFn(() => {
|
|
102
|
+
// Optionally emit search event here if needed
|
|
103
|
+
}, 300);
|
|
104
|
+
|
|
105
|
+
const handleClear = () => {
|
|
106
|
+
wasCleared.value = true;
|
|
107
|
+
|
|
108
|
+
inputText.value = '';
|
|
109
|
+
|
|
110
|
+
emit('update:modelValue', []);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const handleMenuToggle = () => {
|
|
114
|
+
ladderizedSelectPopperState.value = true;
|
|
115
|
+
|
|
116
|
+
isSearching.value = false;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// Watch for changes in modelValue to update inputText
|
|
120
|
+
watch(
|
|
121
|
+
() => ladderizedSelectModel.value,
|
|
122
|
+
(newVal) => {
|
|
123
|
+
if (wasCleared.value) {
|
|
124
|
+
inputText.value = '';
|
|
125
|
+
wasCleared.value = false;
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (Array.isArray(newVal) && newVal.length > 0) {
|
|
130
|
+
// Treat the array as a single path for ladderized select
|
|
131
|
+
let currentLevel = ladderizedSelectMenuList.value;
|
|
132
|
+
|
|
133
|
+
const pathTexts: string[] = [];
|
|
134
|
+
|
|
135
|
+
for (const value of newVal) {
|
|
136
|
+
const found = currentLevel.find((item) => item.value === value);
|
|
137
|
+
if (!found) break;
|
|
138
|
+
pathTexts.push(found.text);
|
|
139
|
+
currentLevel = found.sublevel || [];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
inputText.value = pathTexts.join(' > ');
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
{ immediate: true },
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
onClickOutside(ladderizedSelectRef, () => {
|
|
149
|
+
ladderizedSelectPopperState.value = false;
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
ladderizedClasses,
|
|
154
|
+
ladderizedSelectPopperState,
|
|
155
|
+
ladderizedSelectRef,
|
|
156
|
+
ladderizedSelectMenuList,
|
|
157
|
+
isLadderizedSelectPopperDisabled,
|
|
158
|
+
ladderizedSelectModel,
|
|
159
|
+
inputText,
|
|
160
|
+
handleSelectedLadderizedItem,
|
|
161
|
+
handleSearch,
|
|
162
|
+
handleClear,
|
|
163
|
+
handleMenuToggle,
|
|
164
|
+
};
|
|
165
|
+
};
|
|
@@ -1,122 +1,135 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import type { PropType, ExtractPropTypes } from 'vue';
|
|
2
|
+
import type { MenuListType } from '../../list/list';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
export const definePropType = <T>(val: unknown): PropType<T> => val as PropType<T>;
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const GROUPED_ITEMS_BY_TYPES = ['A-Z', 'Z-A'] as const;
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
25
|
|
|
26
|
-
|
|
26
|
+
const POPPER_STRATEGY_TYPES = ['fixed', 'absolute'] as const;
|
|
27
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
28
|
+
export const multiSelectPropTypes = {
|
|
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
|
+
groupItemsBy: {
|
|
45
|
+
type: String as PropType<(typeof GROUPED_ITEMS_BY_TYPES)[number]>,
|
|
46
|
+
validator: (value: (typeof GROUPED_ITEMS_BY_TYPES)[number] | undefined) => {
|
|
47
|
+
return value === undefined || GROUPED_ITEMS_BY_TYPES.includes(value);
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
textField: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: 'text',
|
|
53
|
+
description: 'Field name to use for display text when using dynamic object arrays',
|
|
54
|
+
},
|
|
55
|
+
valueField: {
|
|
56
|
+
type: String,
|
|
57
|
+
default: 'value',
|
|
58
|
+
description: 'Field name to use for value when using dynamic object arrays',
|
|
59
|
+
},
|
|
60
|
+
placeholder: {
|
|
61
|
+
type: String,
|
|
62
|
+
},
|
|
63
|
+
label: {
|
|
64
|
+
type: String,
|
|
65
|
+
default: '',
|
|
66
|
+
},
|
|
67
|
+
placement: {
|
|
68
|
+
type: String as PropType<(typeof PLACEMENTS_TYPES)[number]>,
|
|
69
|
+
validator: (value: (typeof PLACEMENTS_TYPES)[number]) => PLACEMENTS_TYPES.includes(value),
|
|
70
|
+
default: 'bottom',
|
|
71
|
+
},
|
|
72
|
+
popperStrategy: {
|
|
73
|
+
type: String,
|
|
74
|
+
validator: (value: 'fixed' | 'absolute') => POPPER_STRATEGY_TYPES.includes(value),
|
|
75
|
+
default: 'absolute',
|
|
76
|
+
},
|
|
77
|
+
popperWidth: {
|
|
78
|
+
type: String,
|
|
79
|
+
default: '100%',
|
|
80
|
+
},
|
|
81
|
+
width: {
|
|
82
|
+
type: String,
|
|
83
|
+
default: '100%',
|
|
84
|
+
},
|
|
85
|
+
wrapperPosition: {
|
|
86
|
+
type: String,
|
|
87
|
+
default: 'relative',
|
|
88
|
+
},
|
|
89
|
+
displayText: {
|
|
90
|
+
type: String,
|
|
91
|
+
default: '',
|
|
92
|
+
},
|
|
93
|
+
displayHelper: {
|
|
94
|
+
type: Boolean,
|
|
95
|
+
default: false,
|
|
96
|
+
},
|
|
97
|
+
helperIcon: {
|
|
98
|
+
type: String,
|
|
99
|
+
default: null,
|
|
100
|
+
},
|
|
101
|
+
helperText: {
|
|
102
|
+
type: String,
|
|
103
|
+
default: '',
|
|
104
|
+
},
|
|
105
|
+
disabled: {
|
|
106
|
+
type: Boolean,
|
|
107
|
+
default: false,
|
|
108
|
+
},
|
|
109
|
+
clearable: {
|
|
110
|
+
type: Boolean,
|
|
111
|
+
default: false,
|
|
112
|
+
},
|
|
113
|
+
searchable: {
|
|
114
|
+
type: Boolean,
|
|
115
|
+
default: false,
|
|
116
|
+
},
|
|
117
|
+
disabledLocalSearch: {
|
|
118
|
+
type: Boolean,
|
|
119
|
+
default: false,
|
|
120
|
+
},
|
|
121
|
+
};
|
|
114
122
|
|
|
115
|
-
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
// 'update:modelValue': (_value: unknown) => true, // Accept any type of value
|
|
119
|
-
// };
|
|
123
|
+
export const multiSelectEmitTypes = {
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
125
|
+
'update:modelValue': (_value: unknown) => true,
|
|
120
126
|
|
|
121
|
-
//
|
|
122
|
-
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
128
|
+
'infinite-scroll-trigger': (_triggered: boolean) => true,
|
|
129
|
+
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
131
|
+
'search-string': (_search: string | number) => true,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export type MultiSelectPropTypes = ExtractPropTypes<typeof multiSelectPropTypes>;
|
|
135
|
+
export type MultiSelectEmitTypes = typeof multiSelectEmitTypes;
|