Skip to content

Commit 278e419

Browse files
authored
Merge branch 'main' into externaldimensions
2 parents 4625957 + 79c92ee commit 278e419

9 files changed

Lines changed: 126 additions & 109 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
"eslint-plugin-testing-library": "^7.16.0",
6969
"jspdf": "^4.2.0",
7070
"jspdf-autotable": "^5.0.7",
71-
"oxfmt": "0.41.0",
71+
"oxfmt": "0.42.0",
7272
"playwright": "~1.58.0",
7373
"postcss": "^8.5.2",
7474
"react": "^19.2.4",

src/DataGrid.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ import {
2929
isCtrlKeyHeldDown,
3030
isDefaultCellInput,
3131
renderMeasuringCells,
32-
scrollIntoView,
33-
sign
32+
scrollIntoView
3433
} from './utils';
3534
import type {
3635
CalculatedColumn,
@@ -411,7 +410,7 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
411410
);
412411

413412
const headerSelectionValue = useMemo((): HeaderRowSelectionContextValue => {
414-
// no rows to select = explicitely unchecked
413+
// no rows to select = explicitly unchecked
415414
let hasSelectedRow = false;
416415
let hasUnselectedRow = false;
417416

@@ -573,8 +572,10 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
573572
previousRowIdx !== rowIdx &&
574573
previousRowIdx < rows.length
575574
) {
576-
const step = sign(rowIdx - previousRowIdx);
577-
for (let i = previousRowIdx + step; i < rowIdx; i += step) {
575+
const [min, max] =
576+
previousRowIdx < rowIdx ? [previousRowIdx, rowIdx] : [rowIdx, previousRowIdx];
577+
578+
for (let i = min + 1; i < max; i++) {
578579
const row = rows[i];
579580
if (isRowSelectionDisabled?.(row) === true) continue;
580581
if (checked) {
@@ -736,7 +737,7 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
736737
setDraggedOverRowIdx(overRowIdx);
737738
const ariaRowIndex = headerAndTopSummaryRowsCount + overRowIdx + 1;
738739
const el = gridEl.querySelector(
739-
`:scope > [aria-rowindex="${ariaRowIndex}"] > [aria-colindex="${activePosition.idx + 1}"]`
740+
`& > [aria-rowindex="${ariaRowIndex}"] > [aria-colindex="${activePosition.idx + 1}"]`
740741
);
741742
scrollIntoView(el);
742743
}
@@ -1293,11 +1294,11 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
12931294
}
12941295

12951296
function getRowToScroll(gridEl: HTMLDivElement) {
1296-
return gridEl.querySelector<HTMLDivElement>(':scope > [role="row"][tabindex="0"]');
1297+
return gridEl.querySelector<HTMLDivElement>('& > [role="row"][tabindex="0"]');
12971298
}
12981299

12991300
function getCellToScroll(gridEl: HTMLDivElement) {
1300-
return gridEl.querySelector<HTMLDivElement>(':scope > [role="row"] > [tabindex="0"]');
1301+
return gridEl.querySelector<HTMLDivElement>('& > [role="row"] > [tabindex="0"]');
13011302
}
13021303

13031304
function isSamePosition(p1: Position, p2: Position) {

src/utils/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export * from './keyboardUtils';
88
export * from './renderMeasuringCells';
99
export * from './styleUtils';
1010

11-
export const { min, max, floor, sign, abs } = Math;
11+
export const { min, max, floor, abs } = Math;
1212

1313
export function assertIsValidKeyGetter<R, K extends React.Key>(
1414
keyGetter: Maybe<(row: NoInfer<R>) => K>

test/browser/column/resizable.test.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useState } from 'react';
2-
import { commands, page, userEvent } from 'vitest/browser';
2+
import { commands, page, server, userEvent } from 'vitest/browser';
33

44
import { DataGrid, type Column, type ColumnWidth, type ColumnWidths } from '../../../src';
55
import { setup } from '../utils';
@@ -313,11 +313,8 @@ test('should use columnWidths and onColumnWidthsChange props when provided', asy
313313
});
314314

315315
async function testGridTemplateColumns(chrome: string, firefox: string, firefoxCI = firefox) {
316-
const gridTemplateColumns = navigator.userAgent.includes('Chrome')
317-
? chrome
318-
: __IS_CI__
319-
? firefoxCI
320-
: firefox;
316+
const gridTemplateColumns =
317+
server.browser === 'chromium' ? chrome : import.meta.env.CI ? firefoxCI : firefox;
321318

322319
await expect.element(grid).toHaveStyle({ gridTemplateColumns });
323320
}

test/browser/rowSelection.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,16 +239,34 @@ test('extra keys are preserved when updating the selectedRows Set', async () =>
239239

240240
test('select/deselect rows using shift click', async () => {
241241
await setup();
242+
243+
// forward selection
242244
await toggleSelection(0);
243245
await toggleSelection(2, true);
244246
await testSelection(0, true);
245247
await testSelection(1, true);
246248
await testSelection(2, true);
249+
250+
// forward deselection
247251
await toggleSelection(0);
248252
await toggleSelection(2, true);
249253
await testSelection(0, false);
250254
await testSelection(1, false);
251255
await testSelection(2, false);
256+
257+
// backward selection
258+
await toggleSelection(2);
259+
await toggleSelection(0, true);
260+
await testSelection(0, true);
261+
await testSelection(1, true);
262+
await testSelection(2, true);
263+
264+
// backward deselection
265+
await toggleSelection(2);
266+
await toggleSelection(0, true);
267+
await testSelection(0, false);
268+
await testSelection(1, false);
269+
await testSelection(2, false);
252270
});
253271

254272
test('select rows using shift space', async () => {

test/browser/virtualization.test.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,18 +220,29 @@ test('zero rows', async () => {
220220
await expect.element(rows).toHaveLength(0);
221221
});
222222

223-
test('virtualization is enable with not enough columns or rows to virtualize', async () => {
223+
test('virtualization is enabled with not enough columns or rows to virtualize', async () => {
224224
await setupGrid(true, 5, 5);
225225

226226
await assertHeaderCells(5, 0, 4);
227227
await assertRows(5, 0, 4);
228228
await expect.element(cells).toHaveLength(5 * 5);
229229
});
230230

231-
test('enableVirtualization is disabled', async () => {
231+
test('virtualization is disabled with no frozen columns', async () => {
232232
await setupGrid(false, 40, 100);
233233

234234
await assertHeaderCells(40, 0, 39);
235235
await assertRows(100, 0, 99);
236236
await expect.element(cells).toHaveLength(40 * 100);
237237
});
238+
239+
// failing test
240+
// cannot use `test.fails` as console logs lead to timeout in parallel tests
241+
// https://github.com/vitest-dev/vitest/issues/9941
242+
test.skip('virtualization is disabled with some frozen columns', async () => {
243+
await setupGrid(false, 40, 100, 3);
244+
245+
await assertHeaderCells(40, 0, 39);
246+
await assertRows(100, 0, 99);
247+
await expect.element(cells).toHaveLength(40 * 100);
248+
});

test/failOnConsole.ts

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,23 @@
1-
let consoleErrorOrConsoleWarnWereCalled = false;
1+
beforeEach(({ onTestFinished }) => {
2+
vi.spyOn(console, 'warn').mockName('console.warn');
3+
vi.spyOn(console, 'error').mockName('console.error');
24

3-
beforeAll(() => {
4-
console.error = (...params) => {
5-
consoleErrorOrConsoleWarnWereCalled = true;
6-
console.log(...params);
7-
};
8-
9-
console.warn = (...params) => {
10-
consoleErrorOrConsoleWarnWereCalled = true;
11-
console.log(...params);
12-
};
13-
});
14-
15-
afterEach(({ task, signal }) => {
165
// Wait for the test and all `afterEach` hooks to complete to ensure all logs are caught
17-
onTestFinished(() => {
6+
onTestFinished(({ expect, task, signal }) => {
187
// avoid failing test runs twice
19-
if (task.result!.state !== 'fail' || signal.aborted) {
20-
expect
21-
.soft(
22-
consoleErrorOrConsoleWarnWereCalled,
23-
'errors/warnings were logged to the console during the test'
24-
)
25-
.toBe(false);
26-
}
8+
if (task.result?.state === 'fail' || signal.aborted) return;
279

28-
consoleErrorOrConsoleWarnWereCalled = false;
10+
expect
11+
.soft(
12+
console.warn,
13+
'console.warn() was called during the test; please resolve unexpected warnings'
14+
)
15+
.toHaveBeenCalledTimes(0);
16+
expect
17+
.soft(
18+
console.error,
19+
'console.error() was called during the test; please resolve unexpected errors'
20+
)
21+
.toHaveBeenCalledTimes(0);
2922
});
3023
});

test/globals.d.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
declare global {
2-
const __IS_CI__: boolean;
2+
interface ImportMeta {
3+
readonly env: {
4+
readonly CI: boolean;
5+
};
6+
}
37
}
48

59
declare module 'vitest/browser' {

vite.config.ts

Lines changed: 59 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import react from '@vitejs/plugin-react';
33
import { playwright, type PlaywrightProviderOptions } from '@vitest/browser-playwright';
44
import { ecij } from 'ecij/plugin';
55
import { defineConfig, type ViteUserConfig } from 'vitest/config';
6-
import type { BrowserCommand, BrowserInstanceOption } from 'vitest/node';
6+
import type { BrowserCommand } from 'vitest/node';
77

88
const isCI = process.env.CI === 'true';
9-
const isTest = process.env.NODE_ENV === 'test';
9+
const isTest = process.env.VITEST === 'true';
1010

1111
// TODO: remove when `userEvent.pointer` is supported
1212
const resizeColumn: BrowserCommand<[name: string, resizeBy: number | readonly number[]]> = async (
@@ -48,59 +48,42 @@ const playwrightOptions: PlaywrightProviderOptions = {
4848
}
4949
};
5050

51-
// vitest modifies the instance objects, so we cannot rely on static objects
52-
// https://github.com/vitest-dev/vitest/issues/9877
53-
function getInstances(): BrowserInstanceOption[] {
54-
return [
55-
{
56-
browser: 'chromium',
57-
provider: playwright({
58-
...playwrightOptions,
59-
launchOptions: {
60-
channel: 'chromium'
61-
}
62-
})
63-
},
64-
{
65-
browser: 'firefox',
66-
provider: playwright(playwrightOptions),
67-
// TODO: remove when FF tests are stable
68-
fileParallelism: false
69-
}
70-
];
71-
}
72-
7351
export default defineConfig(
7452
({ isPreview }): ViteUserConfig => ({
7553
base: '/react-data-grid/',
7654
cacheDir: '.cache/vite',
7755
clearScreen: false,
78-
define: isTest ? { __IS_CI__: JSON.stringify(isCI) } : {},
7956
build: {
8057
modulePreload: { polyfill: false },
8158
sourcemap: true,
8259
reportCompressedSize: false,
8360
// https://github.com/parcel-bundler/lightningcss/issues/873
8461
cssTarget: 'esnext'
8562
},
86-
plugins: [
87-
ecij(),
88-
(!isTest || isPreview) &&
89-
tanstackRouter({
90-
target: 'react',
91-
generatedRouteTree: 'website/routeTree.gen.ts',
92-
routesDirectory: 'website/routes',
93-
autoCodeSplitting: true
94-
}),
95-
react()
96-
],
63+
plugins: isPreview
64+
? []
65+
: [
66+
ecij(),
67+
!isTest &&
68+
tanstackRouter({
69+
target: 'react',
70+
generatedRouteTree: 'website/routeTree.gen.ts',
71+
routesDirectory: 'website/routes',
72+
autoCodeSplitting: true
73+
}),
74+
react()
75+
],
9776
server: {
9877
open: true
9978
},
10079
test: {
10180
dir: 'test',
10281
globals: true,
10382
printConsoleTrace: true,
83+
env: {
84+
// @ts-expect-error
85+
CI: isCI
86+
},
10487
coverage: {
10588
provider: 'istanbul',
10689
enabled: isCI,
@@ -120,20 +103,51 @@ export default defineConfig(
120103
}
121104
},
122105
slowTestThreshold: 1000,
106+
browser: {
107+
headless: true,
108+
ui: false,
109+
viewport,
110+
commands: { resizeColumn, dragFill },
111+
expect: {
112+
toMatchScreenshot: {
113+
resolveScreenshotPath({
114+
root,
115+
testFileDirectory,
116+
testFileName,
117+
arg,
118+
browserName,
119+
platform,
120+
ext
121+
}) {
122+
return `${root}/${testFileDirectory}/screenshots/${testFileName}/${arg}-${browserName}-${platform}${ext}`;
123+
}
124+
}
125+
},
126+
instances: [
127+
{
128+
browser: 'chromium',
129+
provider: playwright({
130+
...playwrightOptions,
131+
launchOptions: {
132+
channel: 'chromium'
133+
}
134+
})
135+
},
136+
{
137+
browser: 'firefox',
138+
provider: playwright(playwrightOptions),
139+
// TODO: remove when FF tests are stable
140+
fileParallelism: false
141+
}
142+
]
143+
},
123144
projects: [
124145
{
125146
extends: true,
126147
test: {
127148
name: 'browser',
128149
include: ['browser/**/*.test.*'],
129-
browser: {
130-
enabled: true,
131-
instances: getInstances(),
132-
commands: { resizeColumn, dragFill },
133-
viewport,
134-
headless: true,
135-
ui: false
136-
},
150+
browser: { enabled: true },
137151
setupFiles: ['test/browser/styles.css', 'test/setupBrowser.ts', 'test/failOnConsole.ts']
138152
}
139153
},
@@ -142,28 +156,7 @@ export default defineConfig(
142156
test: {
143157
name: 'visual',
144158
include: ['visual/*.test.*'],
145-
browser: {
146-
enabled: true,
147-
instances: getInstances(),
148-
viewport,
149-
headless: true,
150-
ui: false,
151-
expect: {
152-
toMatchScreenshot: {
153-
resolveScreenshotPath({
154-
root,
155-
testFileDirectory,
156-
testFileName,
157-
arg,
158-
browserName,
159-
platform,
160-
ext
161-
}) {
162-
return `${root}/${testFileDirectory}/screenshots/${testFileName}/${arg}-${browserName}-${platform}${ext}`;
163-
}
164-
}
165-
}
166-
},
159+
browser: { enabled: true },
167160
setupFiles: ['test/setupBrowser.ts', 'test/failOnConsole.ts']
168161
}
169162
},

0 commit comments

Comments
 (0)