diff --git a/packages/primevue/src/treeselect/BaseTreeSelect.vue b/packages/primevue/src/treeselect/BaseTreeSelect.vue index b73cc1663..832a5413d 100644 --- a/packages/primevue/src/treeselect/BaseTreeSelect.vue +++ b/packages/primevue/src/treeselect/BaseTreeSelect.vue @@ -23,6 +23,14 @@ export default { type: String, default: 'single' }, + selectedItemsLabel: { + type: String, + default: null + }, + maxSelectedLabels: { + type: Number, + default: null + }, appendTo: { type: [String, Object], default: 'body' diff --git a/packages/primevue/src/treeselect/TreeSelect.d.ts b/packages/primevue/src/treeselect/TreeSelect.d.ts index 17a34865c..d85ac0585 100644 --- a/packages/primevue/src/treeselect/TreeSelect.d.ts +++ b/packages/primevue/src/treeselect/TreeSelect.d.ts @@ -207,33 +207,6 @@ export interface TreeSelectProps { * @defaultValue 20rem */ scrollHeight?: string | undefined; - /** - * Label to display when there are no selections. - */ - placeholder?: string | undefined; - /** - * Defines the size of the component. - */ - size?: 'small' | 'large' | undefined; - /** - * When present, it specifies that the component should have invalid state style. - * @defaultValue false - */ - invalid?: boolean | undefined; - /** - * When present, it specifies that the component should be disabled. - * @defaultValue false - */ - disabled?: boolean | undefined; - /** - * Specifies the input variant of the component. - * @defaultValue outlined - */ - variant?: 'outlined' | 'filled' | undefined; - /** - * Index of the element in tabbing order. - */ - tabindex?: string | undefined; /** * Defines the selection mode. */ @@ -248,16 +221,20 @@ export interface TreeSelectProps { * @defaultValue body */ appendTo?: HintedString<'body' | 'self'> | undefined | HTMLElement; - /** - * Text to display when there are no options available. Defaults to value from PrimeVue locale configuration. - * @defaultValue No available options - */ - emptyMessage?: string | undefined; /** * Defines how the selected items are displayed. * @defaultValue comma */ display?: 'comma' | 'chip' | undefined; + /** + * Label to display after exceeding max selected labels. + * @defaultValue null + */ + selectedItemsLabel?: string | undefined; + /** + * Decides how many selected item labels to show at most. + */ + maxSelectedLabels?: number | undefined; /** * Defines how multiple items can be selected, when true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually. * On touch enabled devices, metaKeySelection is turned off automatically. @@ -301,6 +278,38 @@ export interface TreeSelectProps { * Locale to use in filtering. The default locale is the host environment's current locale. */ filterLocale?: string | undefined; + /** + * Text to display when there are no options available. Defaults to value from PrimeVue locale configuration. + * @defaultValue No available options + */ + emptyMessage?: string | undefined; + /** + * Label to display when there are no selections. + */ + placeholder?: string | undefined; + /** + * Defines the size of the component. + */ + size?: 'small' | 'large' | undefined; + /** + * When present, it specifies that the component should have invalid state style. + * @defaultValue false + */ + invalid?: boolean | undefined; + /** + * When present, it specifies that the component should be disabled. + * @defaultValue false + */ + disabled?: boolean | undefined; + /** + * Specifies the input variant of the component. + * @defaultValue outlined + */ + variant?: 'outlined' | 'filled' | undefined; + /** + * Index of the element in tabbing order. + */ + tabindex?: string | undefined; /** * Identifier of the underlying input element. */ diff --git a/packages/primevue/src/treeselect/TreeSelect.vue b/packages/primevue/src/treeselect/TreeSelect.vue index 8e1a3dcb9..67d2a5fa9 100644 --- a/packages/primevue/src/treeselect/TreeSelect.vue +++ b/packages/primevue/src/treeselect/TreeSelect.vue @@ -29,10 +29,15 @@ {{ label || 'empty' }} @@ -253,6 +258,16 @@ export default { this.$emit('update:expandedKeys', this.d_expandedKeys); }, + getSelectedItemsLabel() { + let pattern = /{(.*?)}/; + const selectedItemsLabel = this.selectedItemsLabel || this.$primevue.config.locale.selectionMessage; + + if (pattern.test(selectedItemsLabel)) { + return selectedItemsLabel.replace(selectedItemsLabel.match(pattern)[0], Object.keys(this.d_value).length + ''); + } + + return selectedItemsLabel; + }, onFirstHiddenFocus(event) { const focusableEl = event.relatedTarget === this.$refs.focusInput ? getFirstFocusableElement(this.overlay, ':not([data-p-hidden-focusable="true"])') : this.$refs.focusInput; @@ -517,8 +532,22 @@ export default { }, label() { let value = this.selectedNodes; + let label; - return value.length ? value.map((node) => node.label).join(', ') : this.placeholder; + if (value.length) { + if (isNotEmpty(this.maxSelectedLabels) && value.length > this.maxSelectedLabels) { + label = this.getSelectedItemsLabel(); + } else { + label = value.map((node) => node.label).join(', '); + } + } else { + label = this.placeholder; + } + + return label; + }, + chipSelectedItems() { + return isNotEmpty(this.maxSelectedLabels) && this.d_value && Object.keys(this.d_value).length > this.maxSelectedLabels; }, emptyMessageText() { return this.emptyMessage || this.$primevue.config.locale.emptyMessage;