diff --git a/projects/ngx-datatable/src/lib/components/header/header-cell.component.spec.ts b/projects/ngx-datatable/src/lib/components/header/header-cell.component.spec.ts index d1726003d..c70457dc9 100644 --- a/projects/ngx-datatable/src/lib/components/header/header-cell.component.spec.ts +++ b/projects/ngx-datatable/src/lib/components/header/header-cell.component.spec.ts @@ -1,12 +1,23 @@ import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; -import { AfterViewInit, Component, signal, TemplateRef, viewChild } from '@angular/core'; +import { + AfterViewInit, + Component, + inputBinding, + outputBinding, + signal, + TemplateRef, + viewChild, + WritableSignal +} from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { userEvent } from '@vitest/browser/context'; import { InnerSortEvent, SortableTableColumnInternal, TableColumnInternal } from '../../types/internal.types'; +import { SortPropDir } from '../../types/public.types'; import { toInternalColumn } from '../../utils/column-helper'; import { DataTableHeaderCellComponent } from './header-cell.component'; import { HeaderCellHarness } from './testing/header-cell.harnes'; @@ -160,3 +171,66 @@ describe('DataTableHeaderCellComponent with template', () => { }); }); }); + +describe('DataTableHeaderCellComponent - custom sort icons', () => { + let fixture: ComponentFixture; + let sorts: WritableSignal; + const column = signal({ + name: 'test', + prop: 'test', + sortable: true, + resizeable: false, + width: signal(20) + }); + const sortAscendingIcon = signal('icon up'); + const sortDescendingIcon = signal('icon down'); + + beforeEach(async () => { + sorts = signal([]); + fixture = TestBed.createComponent(DataTableHeaderCellComponent, { + bindings: [ + inputBinding('sortType', () => 'single'), + inputBinding('ariaHeaderCheckboxMessage', () => 'Select All'), + inputBinding('sortAscendingIcon', sortAscendingIcon), + inputBinding('sortDescendingIcon', sortDescendingIcon), + inputBinding('column', column), + inputBinding('sorts', sorts), + inputBinding('showResizeHandle', () => false), + outputBinding('sort', (event: InnerSortEvent) => { + sorts.set([{ prop: event.column.prop!, dir: event.newValue! }]); + }) + ] + }); + await fixture.whenStable(); + }); + + it('should apply custom sortAscendingIcon class when toggling to ascending sort', async () => { + const label = fixture.nativeElement.querySelector('.datatable-header-cell-label'); + await userEvent.click(label); + await fixture.whenStable(); + + const sortBtn = fixture.nativeElement.querySelector('.sort-btn'); + + expect(sortBtn).toHaveClass('sort-btn'); + expect(sortBtn).toHaveClass('sort-asc'); + expect(sortBtn).toHaveClass('icon'); + expect(sortBtn).toHaveClass('up'); + expect(sortBtn).not.toHaveClass('datatable-icon-up'); + }); + + it('should apply custom sortDescendingIcon class when toggling to descending sort', async () => { + const label = fixture.nativeElement.querySelector('.datatable-header-cell-label'); + await userEvent.click(label); + await fixture.whenStable(); + + await userEvent.click(label); + await fixture.whenStable(); + + const sortButton = fixture.nativeElement.querySelector('.sort-btn'); + expect(sortButton).toHaveClass('sort-btn'); + expect(sortButton).toHaveClass('sort-desc'); + expect(sortButton).toHaveClass('icon'); + expect(sortButton).toHaveClass('down'); + expect(sortButton).not.toHaveClass('datatable-icon-down'); + }); +}); diff --git a/projects/ngx-datatable/src/lib/components/header/header-cell.component.ts b/projects/ngx-datatable/src/lib/components/header/header-cell.component.ts index 02ef93dad..229eba95e 100644 --- a/projects/ngx-datatable/src/lib/components/header/header-cell.component.ts +++ b/projects/ngx-datatable/src/lib/components/header/header-cell.component.ts @@ -142,8 +142,8 @@ export class DataTableHeaderCellComponent implements OnInit, OnDestroy { protected readonly isCheckboxable = computed(() => this.column().headerCheckboxable); - protected readonly sortClass = computed(() => { - return this.calcSortClass(this.sortDir()); + protected readonly sortClass = computed(() => { + return this.calcSortClass(this.sortDir())?.join(' '); }); protected readonly sortDir = computed(() => { return this.calcSortDir(this.sorts()); diff --git a/projects/ngx-datatable/tsconfig.spec.json b/projects/ngx-datatable/tsconfig.spec.json index 85bae40c8..5341e83e9 100644 --- a/projects/ngx-datatable/tsconfig.spec.json +++ b/projects/ngx-datatable/tsconfig.spec.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "../../out-tsc/spec", - "types": ["vitest/globals"] + "types": ["vitest/globals", "vitest/browser"] }, "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] }