1
0

feat: withDefaults for Multiselect

This commit is contained in:
Dominik Pschenitschni 2024-07-06 14:35:20 +02:00 committed by konrad
parent 3317280062
commit 413d1f9ad7

View File

@ -119,9 +119,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { import {computed, onBeforeUnmount, onMounted, ref, toRefs, watch, type ComponentPublicInstance} from 'vue'
computed, onBeforeUnmount, onMounted, ref, toRefs, watch, type ComponentPublicInstance, type PropType,
} from 'vue'
import {useI18n} from 'vue-i18n' import {useI18n} from 'vue-i18n'
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside' import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
@ -129,132 +127,75 @@ import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import BaseButton from '@/components/base/BaseButton.vue' import BaseButton from '@/components/base/BaseButton.vue'
import CustomTransition from '@/components/misc/CustomTransition.vue' import CustomTransition from '@/components/misc/CustomTransition.vue'
const props = defineProps({ const props = withDefaults(defineProps<{
/** /** When true, shows a loading spinner */
* When true, shows a loading spinner loading: boolean
*/ /** The placeholder of the search input */
loading: { placeholder: string
type: Boolean, /** The search results where the @search listener needs to put the results into */
default: false, // eslint-disable-next-line @typescript-eslint/no-explicit-any
}, searchResults: { [id: string]: any }[]
/** /** The name of the property of the searched object to show the user. If empty the component will show all raw data of an entry */
* The placeholder of the search input label: string
*/ /** The object with the value, updated every time an entry is selected */
placeholder: { // eslint-disable-next-line @typescript-eslint/no-explicit-any
type: String, modelValue: { [id: string]: any }
default: '', /** If true, will provide an 'add this as a new value' entry which fires an @create event when clicking on it. */
}, creatable: boolean
/** /** The text shown next to the new value option. */
* The search results where the @search listener needs to put the results into createPlaceholder: string
*/ /** The text shown next to an option. */
searchResults: { selectPlaceholder: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any /** If true, allows for selecting multiple items. v-model will be an array with all selected values in that case. */
type: Array as PropType<{ [id: string]: any }>, multiple: boolean
default: () => [], /** If true, displays the search results inline instead of using a dropdown. */
}, inline: boolean
/** /** If true, shows search results when no query is specified. */
* The name of the property of the searched object to show the user. showEmpty: boolean
* If empty the component will show all raw data of an entry. /** The delay in ms after which the search event will be fired. Used to avoid hitting the network on every keystroke. */
*/ searchDelay: number
label: { /** If true, closes the dropdown after an entry is selected */
type: String, closeAfterSelect: boolean
default: '', /** If false, the search input will get the autocomplete="off" attributes attached to it. */
}, autocompleteEnabled: boolean
/** }>(), {
* The object with the value, updated every time an entry is selected. loading: false,
*/ placeholder: '',
modelValue: { searchResults: () => [],
// eslint-disable-next-line @typescript-eslint/no-explicit-any label: '',
type: [Object] as PropType<{ [key: string]: any }>, modelValue: null,
default: null, creatable: false,
}, createPlaceholder: () => useI18n().t('input.multiselect.createPlaceholder'),
/** selectPlaceholder: () => useI18n().t('input.multiselect.selectPlaceholder'),
* If true, will provide an "add this as a new value" entry which fires an @create event when clicking on it. multiple: false,
*/ inline: false,
creatable: { showEmpty: false,
type: Boolean, searchDelay: 200,
default: false, closeAfterSelect: true,
}, autocompleteEnabled: true,
/**
* The text shown next to the new value option.
*/
createPlaceholder: {
type: String,
default() {
const {t} = useI18n({useScope: 'global'})
return t('input.multiselect.createPlaceholder')
},
},
/**
* The text shown next to an option.
*/
selectPlaceholder: {
type: String,
default() {
const {t} = useI18n({useScope: 'global'})
return t('input.multiselect.selectPlaceholder')
},
},
/**
* If true, allows for selecting multiple items. v-model will be an array with all selected values in that case.
*/
multiple: {
type: Boolean,
default: false,
},
/**
* If true, displays the search results inline instead of using a dropdown.
*/
inline: {
type: Boolean,
default: false,
},
/**
* If true, shows search results when no query is specified.
*/
showEmpty: {
type: Boolean,
default: true,
},
/**
* The delay in ms after which the search event will be fired. Used to avoid hitting the network on every keystroke.
*/
searchDelay: {
type: Number,
default: 200,
},
closeAfterSelect: {
type: Boolean,
default: true,
},
/**
* If false, the search input will get the autocomplete="off" attributes attached to it.
*/
autocompleteEnabled: {
type: Boolean,
default: true,
},
}) })
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:modelValue', value: null): void // eslint-disable-next-line @typescript-eslint/no-explicit-any
'update:modelValue': [value: { [key: string]: any }[] | null],
/** /**
* Triggered every time the search query input changes * Triggered every time the search query input changes
*/ */
(e: 'search', query: string): void 'search': [query: string],
/** /**
* Triggered every time an option from the search results is selected. Also triggers a change in v-model. * Triggered every time an option from the search results is selected. Also triggers a change in v-model.
*/ */
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
(e: 'select', value: { [key: string]: any }): void 'select': [value: { [key: string]: any }],
/** /**
* If nothing or no exact match was found and `creatable` is true, this event is triggered with the current value of the search query. * If nothing or no exact match was found and `creatable` is true, this event is triggered with the current value of the search query.
*/ */
(e: 'create', query: string): void 'create': [query: string],
/** /**
* If `multiple` is enabled, this will be fired every time an item is removed from the array of selected items. * If `multiple` is enabled, this will be fired every time an item is removed from the array of selected items.
*/ */
(e: 'remove', value: null): void // eslint-disable-next-line @typescript-eslint/no-explicit-any
'remove': [value: { [key: string]: any }],
}>() }>()
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any