✨ feature: Select component improved
This commit is contained in:
parent
5f5c532d8e
commit
fd143ea7a5
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Select from 'primevue/select';
|
import Select, { type SelectSlots } from 'primevue/select';
|
||||||
import type IVSelect from './IVSelect.type.js';
|
import type IVSelect from './IVSelect.type.js';
|
||||||
import { useId, computed, watch, ref } from 'vue';
|
import { useId, computed, watch, ref } from 'vue';
|
||||||
import VLabel from '../label/VLabel.vue';
|
import VLabel from '../label/VLabel.vue';
|
||||||
|
@ -29,9 +29,7 @@ const props = withDefaults(defineProps<IVSelect>(), {
|
||||||
selectionMessage: 'Elements sélectionnés',
|
selectionMessage: 'Elements sélectionnés',
|
||||||
emptySelectionMessage: 'Aucun élément sélectionné',
|
emptySelectionMessage: 'Aucun élément sélectionné',
|
||||||
emptyFilterMessage: 'Aucun résultat trouvé',
|
emptyFilterMessage: 'Aucun résultat trouvé',
|
||||||
emptyMessage: 'Aucune option disponible',
|
emptyMessage: 'Aucune option disponible'
|
||||||
optionTemplate: false,
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
|
@ -78,6 +76,33 @@ const labelState = computed(() => {
|
||||||
else if(props.errorMessage && !props.successMessage && !props.disabled) return 'error';
|
else if(props.errorMessage && !props.successMessage && !props.disabled) return 'error';
|
||||||
else return undefined
|
else return undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
type VSelectSlots = SelectSlots & {
|
||||||
|
required?: (props: Record<string, unknown>) => unknown
|
||||||
|
};
|
||||||
|
|
||||||
|
const slots = defineSlots<VSelectSlots>();
|
||||||
|
|
||||||
|
const selectSlotKeys = [
|
||||||
|
'value',
|
||||||
|
'header',
|
||||||
|
'footer',
|
||||||
|
'option',
|
||||||
|
'optiongroup',
|
||||||
|
'emptyfilter',
|
||||||
|
'empty',
|
||||||
|
'content',
|
||||||
|
'loader',
|
||||||
|
'clearicon',
|
||||||
|
'dropdownicon',
|
||||||
|
'loadingicon',
|
||||||
|
'filtericon'
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
const availableSlots = computed(() =>
|
||||||
|
selectSlotKeys.filter((key) => !!slots[key]).map((key) => [key, slots[key]])
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -92,7 +117,7 @@ const labelState = computed(() => {
|
||||||
:hint="props.hint"
|
:hint="props.hint"
|
||||||
>
|
>
|
||||||
<template #required-type v-if="props.required">
|
<template #required-type v-if="props.required">
|
||||||
<slot name="required-type"/>
|
<slot name="required"/>
|
||||||
</template>
|
</template>
|
||||||
</VLabel>
|
</VLabel>
|
||||||
<Select
|
<Select
|
||||||
|
@ -141,8 +166,12 @@ const labelState = computed(() => {
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<template v-if="props.optionTemplate" #option="{option, selected, index}">
|
<template
|
||||||
<slot name="option" :option="option" :selected="selected" :index="index"/>
|
v-for="([name]) in availableSlots"
|
||||||
|
:key="name"
|
||||||
|
v-slot:[name]="slotProps"
|
||||||
|
>
|
||||||
|
<slot :name="name" v-bind="slotProps" />
|
||||||
</template>
|
</template>
|
||||||
</Select>
|
</Select>
|
||||||
<div
|
<div
|
||||||
|
@ -174,6 +203,8 @@ const labelState = computed(() => {
|
||||||
--p-select-dropdown-color: var(--text-disabled-grey);
|
--p-select-dropdown-color: var(--text-disabled-grey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-select.error, .p-select.success{border-width: var(--large-border-width);}
|
||||||
|
|
||||||
.p-select.error{
|
.p-select.error{
|
||||||
--p-select-border-color: var(--border-plain-error);
|
--p-select-border-color: var(--border-plain-error);
|
||||||
--p-select-hover-border-color: var(--border-plain-error);
|
--p-select-hover-border-color: var(--border-plain-error);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user