diff --git a/dev/ag-grid-angular/src/overview.ng.ts b/dev/ag-grid-angular/src/overview.ng.ts index cefdb2a..2e60580 100644 --- a/dev/ag-grid-angular/src/overview.ng.ts +++ b/dev/ag-grid-angular/src/overview.ng.ts @@ -313,6 +313,7 @@ export class DevAgGridStatusBarComponent { [pagination]="pagination()" [columnHoverHighlight]="columnHoverHighlight()" [suppressCellFocus]="suppressCellFocus()" + [alwaysMultiSort]="true" [tooltipShowDelay]="500" [animateRows]="animateRows()" [enableCellTextSelection]="cellTextSelection()" diff --git a/dev/ag-grid-angular/src/tests/__screenshots__/row-actions-hover-light.png b/dev/ag-grid-angular/src/tests/__screenshots__/row-actions-hover-light.png index 2b9af79..2c110ee 100644 Binary files a/dev/ag-grid-angular/src/tests/__screenshots__/row-actions-hover-light.png and b/dev/ag-grid-angular/src/tests/__screenshots__/row-actions-hover-light.png differ diff --git a/dev/ag-grid-angular/src/tests/__screenshots__/theme-default-dark.png b/dev/ag-grid-angular/src/tests/__screenshots__/theme-default-dark.png index c7a194e..8d04ed4 100644 Binary files a/dev/ag-grid-angular/src/tests/__screenshots__/theme-default-dark.png and b/dev/ag-grid-angular/src/tests/__screenshots__/theme-default-dark.png differ diff --git a/dev/ag-grid-angular/src/tests/__screenshots__/theme-default-light.png b/dev/ag-grid-angular/src/tests/__screenshots__/theme-default-light.png index ffef746..7ca2830 100644 Binary files a/dev/ag-grid-angular/src/tests/__screenshots__/theme-default-light.png and b/dev/ag-grid-angular/src/tests/__screenshots__/theme-default-light.png differ diff --git a/dev/ag-grid-angular/src/tests/__screenshots__/theme-filter-popup-dark.png b/dev/ag-grid-angular/src/tests/__screenshots__/theme-filter-popup-dark.png index 7258778..5b3aa29 100644 Binary files a/dev/ag-grid-angular/src/tests/__screenshots__/theme-filter-popup-dark.png and b/dev/ag-grid-angular/src/tests/__screenshots__/theme-filter-popup-dark.png differ diff --git a/dev/ag-grid-angular/src/tests/__screenshots__/theme-filter-popup-light.png b/dev/ag-grid-angular/src/tests/__screenshots__/theme-filter-popup-light.png index 5af5625..e937b0b 100644 Binary files a/dev/ag-grid-angular/src/tests/__screenshots__/theme-filter-popup-light.png and b/dev/ag-grid-angular/src/tests/__screenshots__/theme-filter-popup-light.png differ diff --git a/dev/ag-grid-angular/src/tests/__screenshots__/theme-pinned-columns-light.png b/dev/ag-grid-angular/src/tests/__screenshots__/theme-pinned-columns-light.png index 91a93c0..9c1db5c 100644 Binary files a/dev/ag-grid-angular/src/tests/__screenshots__/theme-pinned-columns-light.png and b/dev/ag-grid-angular/src/tests/__screenshots__/theme-pinned-columns-light.png differ diff --git a/dev/ag-grid-angular/src/tests/row-actions.ng.ts b/dev/ag-grid-angular/src/tests/row-actions.ng.ts index 563ea28..e8be8cd 100644 --- a/dev/ag-grid-angular/src/tests/row-actions.ng.ts +++ b/dev/ag-grid-angular/src/tests/row-actions.ng.ts @@ -1,5 +1,4 @@ -import { ChangeDetectionStrategy, Component, computed, inject, model } from '@angular/core'; -import { FormsModule } from '@angular/forms'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { KBQ_AG_GRID_ROW_ACTIONS_PARAMS, KbqAgGridThemeModule } from '@koobiq/ag-grid-angular-theme'; import { AgGridModule } from 'ag-grid-angular'; import { AllCommunityModule, ColDef, ModuleRegistry } from 'ag-grid-community'; @@ -39,26 +38,16 @@ export class DevRowActionsCellComponent { @Component({ standalone: true, - imports: [AgGridModule, KbqAgGridThemeModule, FormsModule], + imports: [AgGridModule, KbqAgGridThemeModule], selector: 'dev-row-actions', template: ` -
- - -
`, styles: ` @@ -79,10 +68,8 @@ export class DevRowActionsCellComponent { export class DevRowActions { readonly rowData = devInjectRowData(); readonly rowActionsComponent = DevRowActionsCellComponent; - readonly pinFirstColumn = model(false); - readonly pinLastColumn = model(false); - readonly columnDefs = computed(() => [ - { field: 'athlete', headerName: 'Athlete', pinned: this.pinFirstColumn() ? 'left' : false }, + readonly columnDefs: ColDef[] = [ + { field: 'athlete', headerName: 'Athlete' }, { field: 'age', headerName: 'Age' }, { field: 'country', headerName: 'Country' }, { field: 'year', headerName: 'Year' }, @@ -91,6 +78,6 @@ export class DevRowActions { { field: 'gold', headerName: 'Gold' }, { field: 'silver', headerName: 'Silver' }, { field: 'bronze', headerName: 'Bronze' }, - { field: 'total', headerName: 'Total', pinned: this.pinLastColumn() ? 'right' : false } - ]); + { field: 'total', headerName: 'Total' } + ]; } diff --git a/dev/ag-grid-angular/src/tests/row-actions.playwright-spec.ts b/dev/ag-grid-angular/src/tests/row-actions.playwright-spec.ts index 8cd7c91..88d6293 100644 --- a/dev/ag-grid-angular/src/tests/row-actions.playwright-spec.ts +++ b/dev/ag-grid-angular/src/tests/row-actions.playwright-spec.ts @@ -3,16 +3,22 @@ import { getAgGridApi } from './utils/api'; import { getRow } from './utils/helpers'; const getScreenshotTarget = (page: Page): Locator => page.getByTestId('e2eScreenshotTarget'); -const getPinFirstColumnToggle = (page: Page): Locator => page.getByTestId('e2ePinFirstColumnToggle'); -const getPinLastColumnToggle = (page: Page): Locator => page.getByTestId('e2ePinLastColumnToggle'); test.describe('KbqAgGridRowActions', () => { // Screenshot tests are only valid on CI. Do not update snapshots locally. test('shows actions overlay on hover with horizontal scroll', async ({ page }) => { await page.setViewportSize({ width: 650, height: 500 }); await page.goto('/e2e/row-actions'); - await getPinFirstColumnToggle(page).evaluate((label: HTMLLabelElement) => label.click()); - await getPinLastColumnToggle(page).evaluate((label: HTMLLabelElement) => label.click()); + await ( + await getAgGridApi(page) + ).evaluate((api) => { + api.applyColumnState({ + state: [ + { colId: 'athlete', pinned: 'left' }, + { colId: 'total', pinned: 'right' } + ] + }); + }); await getRow(page, 1).first().hover(); await expect(getScreenshotTarget(page)).toHaveScreenshot('row-actions-hover-light.png'); }); diff --git a/dev/ag-grid-angular/src/tests/theme.ng.ts b/dev/ag-grid-angular/src/tests/theme.ng.ts index ffbf050..581ece2 100644 --- a/dev/ag-grid-angular/src/tests/theme.ng.ts +++ b/dev/ag-grid-angular/src/tests/theme.ng.ts @@ -1,15 +1,7 @@ -import { ChangeDetectionStrategy, Component, computed, model } from '@angular/core'; -import { FormsModule } from '@angular/forms'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { KbqAgGridThemeModule } from '@koobiq/ag-grid-angular-theme'; import { AgGridModule } from 'ag-grid-angular'; -import { - AllCommunityModule, - ColDef, - FirstDataRenderedEvent, - GridReadyEvent, - ModuleRegistry, - RowSelectionOptions -} from 'ag-grid-community'; +import { AllCommunityModule, ColDef, GridReadyEvent, ModuleRegistry, RowSelectionOptions } from 'ag-grid-community'; import { devInjectRowData } from '../row-data'; ModuleRegistry.registerModules([AllCommunityModule]); @@ -28,36 +20,22 @@ const DEFAULT_COL_DEF: ColDef = { @Component({ standalone: true, - imports: [AgGridModule, KbqAgGridThemeModule, FormsModule], + imports: [AgGridModule, KbqAgGridThemeModule], selector: 'dev-theme', template: ` -
- - - -
`, styles: ` @@ -79,33 +57,20 @@ export class DevTheme { readonly rowData = devInjectRowData(); readonly rowSelection = ROW_SELECTION; readonly defaultColDef = DEFAULT_COL_DEF; - readonly pagination = model(false); - readonly pinFirstColumn = model(false); - readonly pinLastColumn = model(false); - readonly columnDefs = computed(() => [ - { field: 'athlete', headerName: 'Athlete', pinned: this.pinFirstColumn() ? 'left' : false }, - { field: 'age', headerName: 'Age' }, - { field: 'country', headerName: 'Country' }, + readonly columnDefs: ColDef[] = [ + { field: 'athlete', headerName: 'Athlete' }, { field: 'year', headerName: 'Year' }, { field: 'date', headerName: 'Date' }, + { field: 'country', headerName: 'Country' }, + { field: 'age', headerName: 'Age' }, { field: 'sport', headerName: 'Sport' }, { field: 'gold', headerName: 'Gold' }, { field: 'silver', headerName: 'Silver' }, { field: 'bronze', headerName: 'Bronze' }, - { field: 'total', headerName: 'Total', pinned: this.pinLastColumn() ? 'right' : false } - ]); + { field: 'total', headerName: 'Total' } + ]; onGridReady({ api }: GridReadyEvent): void { api.setColumnWidths([{ key: 'ag-Grid-SelectionColumn', newWidth: 36 }]); } - - onFirstDataRendered({ api }: FirstDataRenderedEvent): void { - api.setFocusedCell(0, 'athlete'); - - api.forEachNode((node) => { - if (node.rowIndex === 4 || node.rowIndex === 5) { - node.setSelected(true); - } - }); - } } diff --git a/dev/ag-grid-angular/src/tests/theme.playwright-spec.ts b/dev/ag-grid-angular/src/tests/theme.playwright-spec.ts index 183c657..a507a20 100644 --- a/dev/ag-grid-angular/src/tests/theme.playwright-spec.ts +++ b/dev/ag-grid-angular/src/tests/theme.playwright-spec.ts @@ -1,35 +1,66 @@ import { expect, Locator, Page, test } from '@playwright/test'; +import { getAgGridApi } from './utils/api'; import { enableDarkTheme } from './utils/theme'; -const getPaginationToggle = (page: Page): Locator => page.getByTestId('e2ePaginationToggle'); const getScreenshotTarget = (page: Page): Locator => page.getByTestId('e2eScreenshotTarget'); -const getPinFirstColumnToggle = (page: Page): Locator => page.getByTestId('e2ePinFirstColumnToggle'); -const getPinLastColumnToggle = (page: Page): Locator => page.getByTestId('e2ePinLastColumnToggle'); -// Screenshot tests are only valid on CI. Do not update snapshots locally. test.describe('KbqAgGridAngularTheme', () => { + // Screenshot tests are only valid on CI. Do not update snapshots locally. test('default state', async ({ page }) => { await page.setViewportSize({ width: 768, height: 500 }); await page.goto('/e2e/theme'); - await getPaginationToggle(page).evaluate((label: HTMLLabelElement) => label.click()); + await ( + await getAgGridApi(page) + ).evaluate((api) => { + api.setGridOption('pagination', true); + api.applyColumnState({ + state: [ + { colId: 'year', sort: 'asc', sortIndex: 1 }, + { colId: 'date', sort: 'asc', sortIndex: 2 } + ] + }); + api.setFocusedCell(0, 'athlete'); + api.forEachNode((node) => { + if (node.rowIndex === 4 || node.rowIndex === 5) { + node.setSelected(true); + } + }); + }); + await expect(page.locator('.ag-paging-panel')).toBeVisible(); await expect(getScreenshotTarget(page)).toHaveScreenshot('theme-default-light.png'); await enableDarkTheme(page); await expect(getScreenshotTarget(page)).toHaveScreenshot('theme-default-dark.png'); }); + // Screenshot tests are only valid on CI. Do not update snapshots locally. test('with pinned columns', async ({ page }) => { await page.setViewportSize({ width: 768, height: 500 }); await page.goto('/e2e/theme'); - await getPinFirstColumnToggle(page).evaluate((label: HTMLLabelElement) => label.click()); - await getPinLastColumnToggle(page).evaluate((label: HTMLLabelElement) => label.click()); + await ( + await getAgGridApi(page) + ).evaluate((api) => { + api.setFocusedCell(0, 'athlete'); + api.applyColumnState({ + state: [ + { colId: 'athlete', pinned: 'left' }, + { colId: 'total', pinned: 'right' } + ] + }); + api.forEachNode((node) => { + if (node.rowIndex === 4 || node.rowIndex === 5) { + node.setSelected(true); + } + }); + }); await page .locator('.ag-center-cols-viewport') .evaluate((element: HTMLElement) => element.scrollTo({ left: 10 })); await expect(getScreenshotTarget(page)).toHaveScreenshot('theme-pinned-columns-light.png'); }); + // Screenshot tests are only valid on CI. Do not update snapshots locally. test('with opened filter popup', async ({ page }) => { - await page.setViewportSize({ width: 500, height: 500 }); + await page.setViewportSize({ width: 768, height: 500 }); await page.goto('/e2e/theme'); await page.hover('.ag-header-cell[col-id="athlete"]'); await page.click('.ag-header-cell[col-id="athlete"] .ag-header-cell-filter-button'); diff --git a/packages/ag-grid-angular-theme/src/theme.scss b/packages/ag-grid-angular-theme/src/theme.scss index dfb1883..9b79986 100644 --- a/packages/ag-grid-angular-theme/src/theme.scss +++ b/packages/ag-grid-angular-theme/src/theme.scss @@ -548,6 +548,22 @@ } } +@mixin _ag-sort-indicator() { + .ag-sort-indicator-container { + .ag-sort-indicator-icon { + --ag-grid-size: var(--kbq-size-3xs); + + order: 1; + } + + // Should always be after the sort icon + .ag-sort-order { + order: 2; + color: var(--kbq-foreground-contrast); + } + } +} + @mixin _ag-row-border { .ag-row { border-bottom: unset; @@ -877,6 +893,7 @@ @include _ag-header-border(); @include _ag-cell-padding(); @include _ag-header-cell-border(); + @include _ag-sort-indicator(); @include _ag-text-field(); @include _ag-row-border(); @include _ag-cell-inline-editing();