From b6b91336706eaafb4d0e943f65231c8bc703d66a Mon Sep 17 00:00:00 2001 From: didimmova Date: Mon, 25 Aug 2025 12:25:00 +0300 Subject: [PATCH 1/2] feat(combo): fix combo initial dropdown height --- .../src/lib/combo/combo.component.spec.ts | 54 +++++++++---------- .../src/lib/combo/themes/_base.scss | 2 +- .../src/lib/combo/themes/shared/indigo.scss | 4 ++ .../simple-combo.component.spec.ts | 10 ++-- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index 45c771076c9..c9feb201db0 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -56,7 +56,7 @@ const CSS_CLASS_EMPTY = 'igx-combo__empty'; const CSS_CLASS_ITEM_CHECKBOX = 'igx-combo__checkbox'; const CSS_CLASS_ITME_CHECKBOX_CHECKED = 'igx-checkbox--checked'; const defaultDropdownItemHeight = 40; -const defaultDropdownItemMaxHeight = 400; +const defaultDropdownItemMaxHeight = 240; describe('igxCombo', () => { let fixture: ComponentFixture; @@ -1211,13 +1211,11 @@ describe('igxCombo', () => { const dropdownItems = dropdownList.querySelectorAll(`.${CSS_CLASS_DROPDOWNLISTITEM}`); expect(dropdownItems[1].classList.contains(CSS_CLASS_SELECTED)).toBeFalsy(); expect(dropdownItems[3].classList.contains(CSS_CLASS_SELECTED)).toBeFalsy(); - expect(dropdownItems[7].classList.contains(CSS_CLASS_SELECTED)).toBeFalsy(); - combo.select(['Illinois', 'Mississippi', 'Ohio']); + combo.select(['Illinois', 'Ohio']); fixture.detectChanges(); expect(dropdownItems[1].classList.contains(CSS_CLASS_SELECTED)).toBeTruthy(); expect(dropdownItems[3].classList.contains(CSS_CLASS_SELECTED)).toBeTruthy(); - expect(dropdownItems[7].classList.contains(CSS_CLASS_SELECTED)).toBeTruthy(); combo.deselect(['Ohio']); fixture.detectChanges(); @@ -1237,9 +1235,9 @@ describe('igxCombo', () => { expect(focusedItem_1.classList.contains(CSS_CLASS_FOCUSED)).toBeTruthy(); // Change focus - dropdown.navigateItem(6); + dropdown.navigateItem(4); fixture.detectChanges(); - const focusedItem_2 = dropdownItems[5]; + const focusedItem_2 = dropdownItems[3]; expect(focusedItem_2.classList.contains(CSS_CLASS_FOCUSED)).toBeTruthy(); expect(focusedItem_1.classList.contains(CSS_CLASS_FOCUSED)).toBeFalsy(); }); @@ -1803,7 +1801,7 @@ describe('igxCombo', () => { dropdown.toggle(); fixture.detectChanges(); expect(dropdown.items).toBeDefined(); - expect(dropdown.items.length).toEqual(9); + expect(dropdown.items.length).toEqual(5); dropdown.onFocus(); expect(dropdown.focusedItem).toEqual(dropdown.items[0]); expect(dropdown.focusedItem.focused).toEqual(true); @@ -1925,17 +1923,17 @@ describe('igxCombo', () => { selectedItemsCount++; selectAndVerifyItem(0); - for (let index = 1; index < 7; index++) { + for (let index = 1; index < 5; index++) { focusAndVerifyItem(index, 'ArrowDown'); } selectedItemsCount++; - selectAndVerifyItem(6); + selectAndVerifyItem(4); - for (let index = 5; index > 3; index--) { + for (let index = 3; index >= 2; index--) { focusAndVerifyItem(index, 'ArrowUp'); } selectedItemsCount++; - selectAndVerifyItem(4); + selectAndVerifyItem(2); }); it('should properly navigate using HOME/END key', (async () => { let firstVisibleItem: Element; @@ -2093,7 +2091,7 @@ describe('igxCombo', () => { const scrollbar = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)).nativeElement as HTMLElement; expect(scrollbar.scrollTop).toEqual(0); - combo.virtualScrollContainer.scrollTo(16); + combo.virtualScrollContainer.scrollTo(12); await firstValueFrom(combo.virtualScrollContainer.chunkLoad); fixture.detectChanges(); let selectedItem = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[1]; @@ -2109,7 +2107,7 @@ describe('igxCombo', () => { // Content was scrolled to bottom expect(scrollbar.scrollHeight - scrollbar.scrollTop).toEqual(scrollbar.clientHeight); - combo.virtualScrollContainer.scrollTo(5); + combo.virtualScrollContainer.scrollTo(4); await firstValueFrom(combo.virtualScrollContainer.chunkLoad); fixture.detectChanges(); selectedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_SELECTED}`)); @@ -2184,15 +2182,14 @@ describe('igxCombo', () => { expect(input.nativeElement.value).toEqual(expectedOutput); }); it('should dismiss all selected items by pressing clear button', () => { - const expectedOutput = 'Kentucky, Ohio, Indiana'; - combo.select(['Kentucky', 'Ohio', 'Indiana']); + const expectedOutput = 'Ohio, Indiana'; + combo.select(['Ohio', 'Indiana']); fixture.detectChanges(); expect(input.nativeElement.value).toEqual(expectedOutput); combo.toggle(); fixture.detectChanges(); expect(combo.dropdown.items[1].selected).toBeTruthy(); expect(combo.dropdown.items[4].selected).toBeTruthy(); - expect(combo.dropdown.items[6].selected).toBeTruthy(); const clearBtn = fixture.debugElement.query(By.css(`.${CSS_CLASS_CLEARBUTTON}`)); clearBtn.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2205,7 +2202,6 @@ describe('igxCombo', () => { fixture.detectChanges(); expect(combo.dropdown.items[1].selected).toBeFalsy(); expect(combo.dropdown.items[4].selected).toBeFalsy(); - expect(combo.dropdown.items[6].selected).toBeFalsy(); }); it('should show/hide clear button after selecting/deselecting items', () => { // This is a workaround for issue github.com/angular/angular/issues/14235 @@ -2263,8 +2259,8 @@ describe('igxCombo', () => { cancel: false }); - const selectedItem_2 = dropdown.items[5]; - simulateComboItemClick(5); + const selectedItem_2 = dropdown.items[4]; + simulateComboItemClick(4); expect(combo.selection[1]).toEqual(selectedItem_2.value); expect(combo.value[1]).toEqual(selectedItem_2.value[combo.valueKey]); expect(selectedItem_2.selected).toBeTruthy(); @@ -2681,19 +2677,19 @@ describe('igxCombo', () => { combo.toggle(); fixture.detectChanges(); let headers = combo.dropdown.headers.map(header => header.element.nativeElement.textContent?.trim()); - expect(headers).toEqual(['Ángel', 'Boris', 'México', 'Méxícó']); + expect(headers).toEqual(['Ángel', 'Boris', 'México']); combo.groupSortingDirection = SortingDirection.Desc; combo.toggle(); fixture.detectChanges(); headers = combo.dropdown.headers.map(header => header.element.nativeElement.textContent?.trim()); - expect(headers).toEqual(['Méxícó', 'México', 'Boris', 'Ángel']); + expect(headers).toEqual(['Méxícó', 'México', 'Boris']); combo.groupSortingDirection = SortingDirection.None; combo.toggle(); fixture.detectChanges(); headers = combo.dropdown.headers.map(header => header.element.nativeElement.textContent?.trim()); - expect(headers).toEqual(['Méxícó', 'Ángel', 'México', 'Boris']); + expect(headers).toEqual(['Méxícó', 'Ángel', 'México']); }); }); describe('Filtering tests: ', () => { @@ -2852,8 +2848,8 @@ describe('igxCombo', () => { verifyFilteredItems('jose', 1); verifyFilteredItems('mexico', 3); - verifyFilteredItems('o', 7); - verifyFilteredItems('é', 7); + verifyFilteredItems('o', 6); + verifyFilteredItems('é', 6); })); it('should filter the dropdown items when typing in the search input', fakeAsync(() => { @@ -2878,9 +2874,9 @@ describe('igxCombo', () => { dropdownItems = dropdownList.querySelectorAll(`.${CSS_CLASS_DROPDOWNLISTITEM}`); expect(dropdownItems.length).toEqual(expectedItemsNumber); }; - verifyFilteredItems('M', 7); + verifyFilteredItems('M', 4); - verifyFilteredItems('Mi', 5); + verifyFilteredItems('Mi', 3); expectedValues = expectedValues.filter(data => data.field.toLowerCase().includes('mi')); checkFilteredItems(dropdownItems); @@ -2950,9 +2946,9 @@ describe('igxCombo', () => { expect(combo.filteredData.length).toEqual(expectedFilteredItemsNumber); }; - verifyFilteredItems('M', 7, 15); - verifyFilteredItems('Mi', 5, 5); - verifyFilteredItems('M', 7, 15); + verifyFilteredItems('M', 4, 15); + verifyFilteredItems('Mi', 3, 5); + verifyFilteredItems('M', 4, 15); combo.filteredData.forEach((item) => expect(combo.data).toContain(item)); }); it('should clear the search input and close the dropdown list on pressing ESC key', fakeAsync(() => { diff --git a/projects/igniteui-angular/src/lib/combo/themes/_base.scss b/projects/igniteui-angular/src/lib/combo/themes/_base.scss index 0127c25e638..69fad3dd38d 100644 --- a/projects/igniteui-angular/src/lib/combo/themes/_base.scss +++ b/projects/igniteui-angular/src/lib/combo/themes/_base.scss @@ -69,7 +69,7 @@ $theme: $base; position: relative; overflow: hidden; - max-height: calc(var(--size) * 10); + max-height: calc(var(--size) * 6); &:focus { outline: transparent; diff --git a/projects/igniteui-angular/src/lib/combo/themes/shared/indigo.scss b/projects/igniteui-angular/src/lib/combo/themes/shared/indigo.scss index 9f5f0b48e7d..0aaa2bda05c 100644 --- a/projects/igniteui-angular/src/lib/combo/themes/shared/indigo.scss +++ b/projects/igniteui-angular/src/lib/combo/themes/shared/indigo.scss @@ -15,4 +15,8 @@ $_theme: $indigo; --ig-size: 2; } } + + @include e(content) { + max-height: calc(var(--size) * 6 + rem(16px)); + } } diff --git a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts index a12afe7922a..be15185e685 100644 --- a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts @@ -699,8 +699,8 @@ describe('IgxSimpleCombo', () => { it('should render dropdown list and item height defaults properly', fakeAsync(() => { let itemHeight = 40; - // Initially there are 11 items inside the combo that's why it should be 440 - let dropdownHeight = 440; + // Initially there are 6 items inside the combo that's why it should be 240 + let dropdownHeight = 240; // NOTE: item height is 40px for a large variant fixture.componentInstance.size = "large"; @@ -721,7 +721,7 @@ describe('IgxSimpleCombo', () => { verifyDropdownItemHeight(); itemHeight = 48; - dropdownHeight = 480; + dropdownHeight = 288; combo.itemHeight = itemHeight; tick(); fixture.detectChanges(); @@ -760,9 +760,9 @@ describe('IgxSimpleCombo', () => { expect(focusedItem_1.classList.contains(CSS_CLASS_FOCUSED)).toBeTruthy(); // Change focus - dropdown.navigateItem(6); + dropdown.navigateItem(5); fixture.detectChanges(); - const focusedItem_2 = dropdownItems[5]; + const focusedItem_2 = dropdownItems[4]; expect(focusedItem_2.classList.contains(CSS_CLASS_FOCUSED)).toBeTruthy(); expect(focusedItem_1.classList.contains(CSS_CLASS_FOCUSED)).toBeFalsy(); }); From 03e06801e5e60a16b37a8cd32cf98455262610bb Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Mon, 15 Sep 2025 14:49:49 +0300 Subject: [PATCH 2/2] refactor(themes): update dropdown theme to use a CSS variable for item count --- projects/igniteui-angular/src/lib/combo/themes/_base.scss | 3 ++- .../igniteui-angular/src/lib/combo/themes/shared/indigo.scss | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/themes/_base.scss b/projects/igniteui-angular/src/lib/combo/themes/_base.scss index 69fad3dd38d..b31c7d92b91 100644 --- a/projects/igniteui-angular/src/lib/combo/themes/_base.scss +++ b/projects/igniteui-angular/src/lib/combo/themes/_base.scss @@ -11,6 +11,7 @@ $theme: $base; @include layer(base) { @include b(igx-drop-down) { + --item-count: 6; --_search-input-inline-padding: #{pad-inline(rem(4px), rem(8px), rem(16px))}; --_search-input-block-padding: #{pad-block(rem(8px))}; @@ -69,7 +70,7 @@ $theme: $base; position: relative; overflow: hidden; - max-height: calc(var(--size) * 6); + max-height: calc(var(--size) * var(--item-count)); &:focus { outline: transparent; diff --git a/projects/igniteui-angular/src/lib/combo/themes/shared/indigo.scss b/projects/igniteui-angular/src/lib/combo/themes/shared/indigo.scss index 0aaa2bda05c..0130052b55c 100644 --- a/projects/igniteui-angular/src/lib/combo/themes/shared/indigo.scss +++ b/projects/igniteui-angular/src/lib/combo/themes/shared/indigo.scss @@ -17,6 +17,6 @@ $_theme: $indigo; } @include e(content) { - max-height: calc(var(--size) * 6 + rem(16px)); + max-height: calc(var(--size) * var(--item-count) + rem(16px)); } }