Refactor #6654 - For MultiSelect

pull/6674/head
tugcekucukoglu 2024-10-28 14:00:24 +03:00
parent aa7965204f
commit b019abd939
4 changed files with 63 additions and 1 deletions

View File

@ -38,6 +38,18 @@ export default {
default: null
},
dataKey: null,
showClear: {
type: Boolean,
default: false
},
clearIcon: {
type: String,
default: undefined
},
resetFilterOnClear: {
type: Boolean,
default: false
},
filter: Boolean,
filterPlaceholder: String,
filterLocale: String,

View File

@ -131,6 +131,10 @@ export interface MultiSelectPassThroughOptions {
* Used to pass attributes to the label's DOM element.
*/
label?: MultiSelectPassThroughOptionType;
/**
* Used to pass attributes to the label's DOM element.
*/
clearIcon?: MultiSelectPassThroughOptionType;
/**
* Used to pass attributes to the chip's DOM element.
*/
@ -407,6 +411,20 @@ export interface MultiSelectProps {
* A property to uniquely identify an option.
*/
dataKey?: string | undefined;
/**
* When enabled, a clear icon is displayed to clear the value.
* @defaultValue false
*/
showClear?: boolean | undefined;
/**
* Icon to display in clear button.
*/
clearIcon?: string | undefined;
/**
* Clears the filter value when clicking on the clear icon.
* @defaultValue false
*/
resetFilterOnClear?: boolean;
/**
* When specified, displays a filter input at header.
* @defaultValue false
@ -803,6 +821,17 @@ export interface MultiSelectSlots {
*/
class: string;
}): VNode[];
/**
* Custom clear icon template.
* @param {Object} scope - clear icon slot's params.
*/
clearicon(scope: {
/**
* Clear icon click function.
* @param {Event} event - Browser event
*/
clearCallback: (event: Event) => void;
}): VNode[];
/**
* Custom dropdown icon template.
* @param {Object} scope - dropdownicon slot's params.

View File

@ -50,6 +50,9 @@
</slot>
</div>
</div>
<slot v-if="isClearIconVisible" name="clearicon" :class="cx('clearIcon')" :clearCallback="onClearClick">
<component :is="clearIcon ? 'i' : 'TimesIcon'" ref="clearIcon" :class="[cx('clearIcon'), clearIcon]" @click="onClearClick" v-bind="ptm('clearIcon')" data-pc-section="clearicon" />
</slot>
<div :class="cx('dropdown')" v-bind="ptm('dropdown')">
<slot v-if="loading" name="loadingicon" :class="cx('loadingIcon')">
<span v-if="loadingIcon" :class="[cx('loadingIcon'), 'pi-spin', loadingIcon]" aria-hidden="true" v-bind="ptm('loadingIcon')" />
@ -458,12 +461,18 @@ export default {
return;
}
if (!this.overlay || !this.overlay.contains(event.target)) {
if (event.target.tagName === 'INPUT' || event.target.getAttribute('data-pc-section') === 'clearicon' || event.target.closest('[data-pc-section="clearicon"]')) {
return;
} else if (!this.overlay || !this.overlay.contains(event.target)) {
this.overlayVisible ? this.hide(true) : this.show(true);
}
this.clicked = true;
},
onClearClick(event) {
this.updateModel(event, null);
this.resetFilterOnClear && (this.filterValue = null);
},
onFirstHiddenFocus(event) {
const focusableEl = event.relatedTarget === this.$refs.focusInput ? getFirstFocusableElement(this.overlay, ':not([data-p-hidden-focusable="true"])') : this.$refs.focusInput;
@ -1121,6 +1130,9 @@ export default {
},
hasFluid() {
return isEmpty(this.fluid) ? !!this.$pcFluid : this.fluid;
},
isClearIconVisible() {
return this.showClear && this.d_value != null && isNotEmpty(this.options);
}
},
directives: {

View File

@ -60,6 +60,14 @@ const theme = ({ dt }) => `
border-end-end-radius: ${dt('multiselect.border.radius')};
}
.p-multiselect-clear-icon {
position: absolute;
top: 50%;
margin-top: -0.5rem;
color: ${dt('multiselect.clear.icon.color')};
inset-inline-end: ${dt('multiselect.dropdown.width')};
}
.p-multiselect-label-container {
overflow: hidden;
flex: 1 1 auto;
@ -253,6 +261,7 @@ const classes = {
'p-multiselect-label-empty': !props.placeholder && (!props.modelValue || props.modelValue.length === 0)
}
],
clearIcon: 'p-multiselect-clear-icon',
chipItem: 'p-multiselect-chip-item',
pcChip: 'p-multiselect-chip',
chipIcon: 'p-multiselect-chip-icon',