Refactor #6654 - For CascadeSelect
parent
dea17c98a9
commit
5925e1ef5d
|
@ -18,6 +18,14 @@ export default {
|
|||
default: '960px'
|
||||
},
|
||||
dataKey: null,
|
||||
showClear: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
clearIcon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
inputId: {
|
||||
type: String,
|
||||
default: null
|
||||
|
|
|
@ -327,6 +327,15 @@ export interface CascadeSelectProps {
|
|||
* 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;
|
||||
/**
|
||||
* Identifier of the underlying input element.
|
||||
*/
|
||||
|
@ -553,6 +562,17 @@ export interface CascadeSelectSlots {
|
|||
*/
|
||||
options: any[];
|
||||
}): 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[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
{{ label }}
|
||||
</slot>
|
||||
</span>
|
||||
<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')" role="button" tabindex="-1" 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')" />
|
||||
|
@ -101,6 +104,7 @@ import OverlayEventBus from 'primevue/overlayeventbus';
|
|||
import Portal from 'primevue/portal';
|
||||
import BaseCascadeSelect from './BaseCascadeSelect.vue';
|
||||
import CascadeSelectSub from './CascadeSelectSub.vue';
|
||||
import TimesIcon from '@primevue/icons/times';
|
||||
|
||||
export default {
|
||||
name: 'CascadeSelect',
|
||||
|
@ -383,7 +387,9 @@ export default {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!this.overlay || !this.overlay.contains(event.target)) {
|
||||
if (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() : this.show();
|
||||
focus(this.$refs.focusInput);
|
||||
}
|
||||
|
@ -391,6 +397,9 @@ export default {
|
|||
this.clicked = true;
|
||||
this.$emit('click', event);
|
||||
},
|
||||
onClearClick(event) {
|
||||
this.updateModel(event, null);
|
||||
},
|
||||
onOverlayClick(event) {
|
||||
OverlayEventBus.emit('overlay-click', {
|
||||
originalEvent: event,
|
||||
|
@ -841,14 +850,18 @@ export default {
|
|||
},
|
||||
focusedOptionId() {
|
||||
return this.focusedOptionInfo.index !== -1 ? `${this.id}${isNotEmpty(this.focusedOptionInfo.parentKey) ? '_' + this.focusedOptionInfo.parentKey : ''}_${this.focusedOptionInfo.index}` : null;
|
||||
},
|
||||
isClearIconVisible() {
|
||||
return this.showClear && this.d_value != null && isNotEmpty(this.options);
|
||||
}
|
||||
},
|
||||
components: {
|
||||
CascadeSelectSub: CascadeSelectSub,
|
||||
Portal: Portal,
|
||||
ChevronDownIcon: ChevronDownIcon,
|
||||
SpinnerIcon: SpinnerIcon,
|
||||
AngleRightIcon: AngleRightIcon
|
||||
CascadeSelectSub,
|
||||
Portal,
|
||||
ChevronDownIcon,
|
||||
SpinnerIcon,
|
||||
AngleRightIcon,
|
||||
TimesIcon
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -26,6 +26,10 @@ export enum CascadeSelectClasses {
|
|||
* Class name of the loading icon element
|
||||
*/
|
||||
loadingIcon = 'p-cascadeselect-loading-icon',
|
||||
/**
|
||||
* Class name of the dropdown icon element
|
||||
*/
|
||||
clearIcon = 'p-cascadeselect-clear-icon',
|
||||
/**
|
||||
* Class name of the dropdown icon element
|
||||
*/
|
||||
|
|
|
@ -60,6 +60,14 @@ const theme = ({ dt }) => `
|
|||
border-end-end-radius: ${dt('border.radius.md')};
|
||||
}
|
||||
|
||||
.p-cascadeselect-clear-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -0.5rem;
|
||||
color: ${dt('cascadeselect.clear.icon.color')};
|
||||
inset-inline-end: ${dt('cascadeselect.dropdown.width')};
|
||||
}
|
||||
|
||||
.p-cascadeselect-label {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
|
@ -262,6 +270,7 @@ const classes = {
|
|||
'p-cascadeselect-label-empty': !instance.$slots['value'] && (instance.label === 'p-emptylabel' || instance.label.length === 0)
|
||||
}
|
||||
],
|
||||
clearIcon: 'p-cascadeselect-clear-icon',
|
||||
dropdown: 'p-cascadeselect-dropdown',
|
||||
loadingIcon: 'p-cascadeselect-loading-icon',
|
||||
dropdownIcon: 'p-cascadeselect-dropdown-icon',
|
||||
|
|
Loading…
Reference in New Issue