diff --git a/projects/components/src/multi-select/multi-select.component.scss b/projects/components/src/multi-select/multi-select.component.scss index 93d399954..280ba0f46 100644 --- a/projects/components/src/multi-select/multi-select.component.scss +++ b/projects/components/src/multi-select/multi-select.component.scss @@ -54,11 +54,22 @@ display: flex; width: 100%; align-items: center; - padding-left: 8px; .trigger-label { @include body-2-medium(); padding-left: 8px; + width: calc(100% - 32px - 38px); + flex-grow: 1; + } + + .trigger-more-items { + @include semi-bold(); + @include font-label($gray-9); + background-color: $gray-2; + padding: 0 4px; + border-radius: 4px; + margin-left: 8px; + max-width: 38px; } .trigger-icon { diff --git a/projects/components/src/multi-select/multi-select.component.test.ts b/projects/components/src/multi-select/multi-select.component.test.ts index 4c0b7ad41..246f53479 100644 --- a/projects/components/src/multi-select/multi-select.component.test.ts +++ b/projects/components/src/multi-select/multi-select.component.test.ts @@ -72,6 +72,10 @@ describe('Multi Select Component', () => { expect(spectator.query('.trigger-label-container')).toExist(); expect(spectator.query('.trigger-label')).toExist(); expect(spectator.query('.trigger-icon')).toExist(); + expect(spectator.query('.trigger-more-items')).not.toExist(); + + // Selected element is 1 as set in hostProps + expect(spectator.component.selectedItemsCount).toBe(1); const popoverComponent = spectator.query(PopoverComponent); expect(popoverComponent?.closeOnClick).toEqual(false); @@ -94,6 +98,8 @@ describe('Multi Select Component', () => { spectator.tick(); const selectedCheckboxElements = spectator.queryAll('ht-checkbox', { root: true }); + expect(spectator.query('.trigger-more-items')).toExist(); + expect(spectator.component.selectedItemsCount).toBe(2); expect( selectedCheckboxElements.filter(checkboxElement => checkboxElement.getAttribute('ng-reflect-checked') === 'true') .length @@ -127,6 +133,8 @@ describe('Multi Select Component', () => { expect(optionElements.length).toBe(6); const selectedCheckboxElements = spectator.queryAll('ht-checkbox', { root: true }); + expect(spectator.query('.trigger-more-items')).toExist(); + expect(spectator.component.selectedItemsCount).toBe(2); expect( selectedCheckboxElements.filter(checkboxElement => checkboxElement.getAttribute('ng-reflect-checked') === 'true') .length @@ -193,7 +201,9 @@ describe('Multi Select Component', () => { expect(onChange).toHaveBeenCalledTimes(1); expect(onChange).toHaveBeenCalledWith([selectionOptions[1].value, selectionOptions[2].value]); - expect(spectator.query(LabelComponent)?.label).toEqual('second and 1 more'); + expect(spectator.query('.trigger-more-items')).toExist(); + expect(spectator.component.selectedItemsCount).toBe(2); + expect(spectator.query(LabelComponent)?.label).toEqual('second'); flush(); })); @@ -260,6 +270,8 @@ describe('Multi Select Component', () => { ).toBe(0); expect(onChange).toHaveBeenCalledTimes(1); expect(onChange).toHaveBeenLastCalledWith([]); + expect(spectator.query('.trigger-more-items')).not.toExist(); + expect(spectator.query(LabelComponent)?.label).toEqual('Select options'); const allOptionElement = spectator.query('.select-all', { root: true }); @@ -268,10 +280,13 @@ describe('Multi Select Component', () => { spectator.tick(); const selectedCheckboxElements = spectator.queryAll('ht-checkbox', { root: true }); + expect(spectator.query('.trigger-more-items')).toExist(); expect(selectedCheckboxElements.length).toBe(6); expect(onChange).toHaveBeenCalledWith(selectionOptions.map(option => option.value)); - expect(spectator.query(LabelComponent)?.label).toEqual('first and 5 more'); + expect(spectator.query(LabelComponent)?.label).toEqual('first'); + + expect(spectator.query('.trigger-more-items')).toHaveText('+5'); spectator.setHostInput({ searchMode: MultiSelectSearchMode.Disabled @@ -314,6 +329,8 @@ describe('Multi Select Component', () => { expect(onChange).toHaveBeenCalledTimes(1); expect(onChange).toHaveBeenCalledWith([selectionOptions[1].value, selectionOptions[2].value]); expect(spectator.query(LabelComponent)?.label).toEqual('Placeholder'); + expect(spectator.query('.trigger-more-items')).not.toExist(); + expect(spectator.component.selectedItemsCount).toBe(0); flush(); })); diff --git a/projects/components/src/multi-select/multi-select.component.ts b/projects/components/src/multi-select/multi-select.component.ts index a8903689d..11b0b8a49 100644 --- a/projects/components/src/multi-select/multi-select.component.ts +++ b/projects/components/src/multi-select/multi-select.component.ts @@ -50,6 +50,9 @@ import { MultiSelectJustify } from './multi-select-justify';
+ +{{ this.selectedItemsCount - 1 }}
@@ -159,6 +162,7 @@ export class MultiSelectComponent implements AfterContentInit, OnChanges { public popoverOpen: boolean = false; public triggerLabel?: string; + public selectedItemsCount: number = 0; public ngAfterContentInit(): void { this.allOptions$ = this.allOptionsList !== undefined ? queryListAndChanges$(this.allOptionsList) : EMPTY; @@ -234,13 +238,11 @@ export class MultiSelectComponent implements AfterContentInit, OnChanges { const selectedItems: SelectOptionComponent[] | undefined = this.allOptionsList?.filter(item => this.isSelectedItem(item) ); - if (selectedItems === undefined || selectedItems.length === 0) { - this.triggerLabel = this.placeholder; - } else if (selectedItems.length === 1) { - this.triggerLabel = selectedItems[0].label; - } else { - this.triggerLabel = `${selectedItems[0].label} and ${selectedItems.length - 1} more`; - } + + this.selectedItemsCount = selectedItems?.length ?? 0; + + // Trigger label is placeholder in case there is element selected on multiselect + this.triggerLabel = this.selectedItemsCount === 0 ? this.placeholder : (selectedItems || [])[0]?.label; } }