Fixed #6654 - For TreeSelect

pull/6674/head
tugcekucukoglu 2024-10-28 14:30:12 +03:00
parent a01f8cec46
commit 4c9a2d56fb
5 changed files with 62 additions and 4 deletions

View File

@ -51,6 +51,14 @@ export default {
type: String, type: String,
default: 'mask' default: 'mask'
}, },
showClear: {
type: Boolean,
default: false
},
clearIcon: {
type: String,
default: undefined
},
filter: { filter: {
type: Boolean, type: Boolean,
default: false default: false

View File

@ -80,6 +80,10 @@ export interface TreeSelectPassThroughOptions {
* Used to pass attributes to the label's DOM element. * Used to pass attributes to the label's DOM element.
*/ */
label?: TreeSelectPassThroughOptionType; label?: TreeSelectPassThroughOptionType;
/**
* Used to pass attributes to the clear icon's DOM element.
*/
clearIcon?: TreeSelectPassThroughOptionType;
/** /**
* Used to pass attributes to the chip's DOM element. * Used to pass attributes to the chip's DOM element.
*/ */
@ -189,6 +193,15 @@ export interface TreeSelectProps {
* A map of keys to represent the expansion state in controlled mode. * A map of keys to represent the expansion state in controlled mode.
*/ */
expandedKeys?: TreeExpandedKeys; expandedKeys?: TreeExpandedKeys;
/**
* 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;
/** /**
* Height of the viewport, a scrollbar is defined if height of list exceeds this value. * Height of the viewport, a scrollbar is defined if height of list exceeds this value.
* @defaultValue 20rem * @defaultValue 20rem
@ -473,6 +486,17 @@ export interface TreeSelectSlots {
*/ */
partialChecked: boolean; partialChecked: boolean;
}): VNode[]; }): 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[];
} }
/** /**

View File

@ -37,6 +37,9 @@
</slot> </slot>
</div> </div>
</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')" role="button" aria-haspopup="tree" :aria-expanded="overlayVisible" v-bind="ptm('dropdown')"> <div :class="cx('dropdown')" role="button" aria-haspopup="tree" :aria-expanded="overlayVisible" v-bind="ptm('dropdown')">
<!-- TODO: triggericon is deprecated since v4.0 --> <!-- TODO: triggericon is deprecated since v4.0 -->
<slot :name="$slots.dropdownicon ? 'dropdownicon' : 'triggericon'" :class="cx('dropdownIcon')"> <slot :name="$slots.dropdownicon ? 'dropdownicon' : 'triggericon'" :class="cx('dropdownIcon')">
@ -121,7 +124,7 @@
<script> <script>
import { absolutePosition, addStyle, find, findSingle, focus, getFirstFocusableElement, getFocusableElements, getLastFocusableElement, getOuterWidth, isTouchDevice, relativePosition } from '@primeuix/utils/dom'; import { absolutePosition, addStyle, find, findSingle, focus, getFirstFocusableElement, getFocusableElements, getLastFocusableElement, getOuterWidth, isTouchDevice, relativePosition } from '@primeuix/utils/dom';
import { isEmpty } from '@primeuix/utils/object'; import { isEmpty, isNotEmpty } from '@primeuix/utils/object';
import { ZIndex } from '@primeuix/utils/zindex'; import { ZIndex } from '@primeuix/utils/zindex';
import { ConnectedOverlayScrollHandler, UniqueComponentId } from '@primevue/core/utils'; import { ConnectedOverlayScrollHandler, UniqueComponentId } from '@primevue/core/utils';
import ChevronDownIcon from '@primevue/icons/chevrondown'; import ChevronDownIcon from '@primevue/icons/chevrondown';
@ -131,6 +134,7 @@ import Portal from 'primevue/portal';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
import Tree from 'primevue/tree'; import Tree from 'primevue/tree';
import BaseTreeSelect from './BaseTreeSelect.vue'; import BaseTreeSelect from './BaseTreeSelect.vue';
import TimesIcon from '@primevue/icons/times';
export default { export default {
name: 'TreeSelect', name: 'TreeSelect',
@ -217,13 +221,18 @@ export default {
return; return;
} }
if (!this.disabled && (!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.disabled && (!this.overlay || !this.overlay.contains(event.target))) {
if (this.overlayVisible) this.hide(); if (this.overlayVisible) this.hide();
else this.show(); else this.show();
focus(this.$refs.focusInput); focus(this.$refs.focusInput);
} }
}, },
onClearClick(event) {
this.onSelectionChange(null);
},
onSelectionChange(keys) { onSelectionChange(keys) {
this.selfChange = true; this.selfChange = true;
this.writeValue(keys); this.writeValue(keys);
@ -525,13 +534,17 @@ export default {
}, },
hasFluid() { hasFluid() {
return isEmpty(this.fluid) ? !!this.$pcFluid : this.fluid; return isEmpty(this.fluid) ? !!this.$pcFluid : this.fluid;
},
isClearIconVisible() {
return this.showClear && this.d_value != null && isNotEmpty(this.options);
} }
}, },
components: { components: {
TSTree: Tree, TSTree: Tree,
Chip, Chip,
Portal: Portal, Portal,
ChevronDownIcon: ChevronDownIcon ChevronDownIcon,
TimesIcon
}, },
directives: { directives: {
ripple: Ripple ripple: Ripple

View File

@ -22,6 +22,10 @@ export enum TreeSelectClasses {
* Class name of the label element * Class name of the label element
*/ */
label = 'p-treeselect-label', label = 'p-treeselect-label',
/**
* Class name of the clear icon element
*/
clearIcon = 'p-select-clear-icon',
/** /**
* Class name of the chip item element * Class name of the chip item element
*/ */

View File

@ -48,6 +48,14 @@ const theme = ({ dt }) => `
background: ${dt('treeselect.disabled.background')}; background: ${dt('treeselect.disabled.background')};
} }
.p-treeselect-clear-icon {
position: absolute;
top: 50%;
margin-top: -0.5rem;
color: ${dt('treeselect.clear.icon.color')};
inset-inline-end: ${dt('treeselect.dropdown.width')};
}
.p-treeselect-dropdown { .p-treeselect-dropdown {
display: flex; display: flex;
align-items: center; align-items: center;
@ -192,6 +200,7 @@ const classes = {
'p-treeselect-label-empty': !props.placeholder && instance.emptyValue 'p-treeselect-label-empty': !props.placeholder && instance.emptyValue
} }
], ],
clearIcon: 'p-treeselect-clear-icon',
chip: 'p-treeselect-chip-item', chip: 'p-treeselect-chip-item',
pcChip: 'p-treeselect-chip', pcChip: 'p-treeselect-chip',
dropdown: 'p-treeselect-dropdown', dropdown: 'p-treeselect-dropdown',