Skip to content

Commit dbdaeff

Browse files
committed
Merge branch 'main' into react19
2 parents 97c7af2 + dd76e81 commit dbdaeff

19 files changed

+335
-278
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- uses: actions/checkout@v4
1313
- uses: actions/setup-node@v4
1414
with:
15-
node-version: 22
15+
node-version: 23
1616
check-latest: true
1717
- name: npm install
1818
run: npm i

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ interface Renderers<TRow, TSummaryRow> {
224224
renderCheckbox?: Maybe<(props: RenderCheckboxProps) => ReactNode>;
225225
renderRow?: Maybe<(key: Key, props: RenderRowProps<TRow, TSummaryRow>) => ReactNode>;
226226
renderSortStatus?: Maybe<(props: RenderSortStatusProps) => ReactNode>;
227+
renderCell?: Maybe<(key: Key, props: CellRendererProps<TRow, TSummaryRow>) => ReactNode>;
227228
noRowsFallback?: Maybe<ReactNode>;
228229
}
229230
```

eslint.config.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import tsParser from '@typescript-eslint/parser';
44
import vitest from '@vitest/eslint-plugin';
55
import jestDom from 'eslint-plugin-jest-dom';
66
import react from 'eslint-plugin-react';
7+
import reactCompiler from 'eslint-plugin-react-compiler';
78
import reactHooks from 'eslint-plugin-react-hooks';
9+
import reactHooksExtra from 'eslint-plugin-react-hooks-extra';
810
import sonarjs from 'eslint-plugin-sonarjs';
911
import testingLibrary from 'eslint-plugin-testing-library';
1012

@@ -18,7 +20,9 @@ export default [
1820

1921
plugins: {
2022
react,
23+
'react-compiler': reactCompiler,
2124
'react-hooks': fixupPluginRules(reactHooks),
25+
'react-hooks-extra': reactHooksExtra,
2226
sonarjs,
2327
'@typescript-eslint': typescriptEslint
2428
},
@@ -371,11 +375,22 @@ export default [
371375
'react/style-prop-object': 0,
372376
'react/void-dom-elements-no-children': 1,
373377

378+
// React Compiler
379+
// https://react.dev/learn/react-compiler#installing-eslint-plugin-react-compiler
380+
'react-compiler/react-compiler': 1,
381+
374382
// React Hooks
375383
// https://www.npmjs.com/package/eslint-plugin-react-hooks
376384
'react-hooks/rules-of-hooks': 1,
377385
'react-hooks/exhaustive-deps': 1,
378386

387+
// React Hooks Extra
388+
// https://eslint-react.xyz/
389+
'react-hooks-extra/no-redundant-custom-hook': 1,
390+
'react-hooks-extra/no-unnecessary-use-callback': 1,
391+
'react-hooks-extra/no-unnecessary-use-memo': 1,
392+
'react-hooks-extra/prefer-use-state-lazy-initialization': 1,
393+
379394
// SonarJS rules
380395
// https://github.com/SonarSource/eslint-plugin-sonarjs#rules
381396
'sonarjs/no-all-duplicated-branches': 1,
@@ -467,13 +482,14 @@ export default [
467482
'@typescript-eslint/no-this-alias': 0,
468483
'@typescript-eslint/no-type-alias': 0,
469484
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 1,
470-
'@typescript-eslint/no-unnecessary-condition': 1,
485+
'@typescript-eslint/no-unnecessary-condition': [1, { checkTypePredicates: true }],
471486
'@typescript-eslint/no-unnecessary-parameter-property-assignment': 1,
472487
'@typescript-eslint/no-unnecessary-qualifier': 0,
473488
'@typescript-eslint/no-unnecessary-template-expression': 1,
474489
'@typescript-eslint/no-unnecessary-type-arguments': 1,
475490
'@typescript-eslint/no-unnecessary-type-assertion': 1,
476491
'@typescript-eslint/no-unnecessary-type-constraint': 1,
492+
'@typescript-eslint/no-unnecessary-type-parameters': 1,
477493
'@typescript-eslint/no-unsafe-argument': 0,
478494
'@typescript-eslint/no-unsafe-assignment': 0,
479495
'@typescript-eslint/no-unsafe-call': 0,
@@ -553,10 +569,6 @@ export default [
553569
{
554570
name: '@testing-library/dom',
555571
message: 'Import @testing-library/react instead.'
556-
},
557-
{
558-
name: 'lodash',
559-
message: 'Import lodash-es instead.'
560572
}
561573
],
562574
'@typescript-eslint/no-shadow': 0,
@@ -582,7 +594,7 @@ export default [
582594
plugins: {
583595
vitest,
584596
'jest-dom': jestDom,
585-
'testing-library': fixupPluginRules(testingLibrary)
597+
'testing-library': testingLibrary
586598
},
587599

588600
rules: {
@@ -642,6 +654,7 @@ export default [
642654
'vitest/prefer-to-contain': 1,
643655
'vitest/prefer-to-have-length': 1,
644656
'vitest/prefer-todo': 1,
657+
'vitest/prefer-vi-mocked': 1,
645658
'vitest/require-hook': 0,
646659
'vitest/require-local-test-context-for-concurrent-snapshots': 0,
647660
'vitest/require-to-throw-message': 0,

package.json

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,38 +61,40 @@
6161
"@babel/preset-react": "^7.18.6",
6262
"@babel/preset-typescript": "^7.18.6",
6363
"@babel/runtime": "^7.21.5",
64-
"@biomejs/biome": "1.9.3",
65-
"@eslint/compat": "^1.1.1",
64+
"@biomejs/biome": "1.9.4",
65+
"@eslint/compat": "^1.2.2",
6666
"@faker-js/faker": "^9.0.0",
6767
"@ianvs/prettier-plugin-sort-imports": "^4.0.2",
6868
"@linaria/core": "^6.0.0",
6969
"@microsoft/api-extractor": "^7.23.0",
7070
"@rollup/plugin-babel": "^6.0.3",
7171
"@rollup/plugin-node-resolve": "^15.1.0",
72-
"@tanstack/react-router": "^1.57.13",
73-
"@tanstack/router-plugin": "^1.57.13",
72+
"@tanstack/react-router": "^1.70.0",
73+
"@tanstack/router-plugin": "^1.69.1",
7474
"@testing-library/dom": "^10.1.0",
7575
"@testing-library/react": "^16.0.0",
7676
"@testing-library/user-event": "^14.5.2",
7777
"@types/node": "^22.0.0",
7878
"@types/react": "npm:types-react@rc",
7979
"@types/react-dom": "npm:types-react-dom@rc",
80-
"@typescript-eslint/eslint-plugin": "^8.7.0",
81-
"@typescript-eslint/parser": "^8.7.0",
80+
"@typescript-eslint/eslint-plugin": "^8.13.0",
81+
"@typescript-eslint/parser": "^8.13.0",
8282
"@vitejs/plugin-react": "^4.3.1",
8383
"@vitest/browser": "^2.1.1",
8484
"@vitest/coverage-v8": "^2.1.1",
85-
"@vitest/eslint-plugin": "^1.1.4",
85+
"@vitest/eslint-plugin": "^1.1.8",
8686
"@wyw-in-js/rollup": "^0.5.0",
8787
"@wyw-in-js/vite": "^0.5.0",
8888
"babel-plugin-optimize-clsx": "^2.6.2",
8989
"browserslist": "^4.24.0",
90-
"eslint": "^9.11.1",
90+
"eslint": "^9.14.0",
9191
"eslint-plugin-jest-dom": "^5.0.1",
92-
"eslint-plugin-react": "^7.36.1",
93-
"eslint-plugin-react-hooks": "^4.6.2",
94-
"eslint-plugin-sonarjs": "^2.0.2",
95-
"eslint-plugin-testing-library": "^6.3.0",
92+
"eslint-plugin-react": "^7.37.2",
93+
"eslint-plugin-react-compiler": "^19.0.0-beta-a7bf2bd-20241110",
94+
"eslint-plugin-react-hooks": "^5.0.0",
95+
"eslint-plugin-react-hooks-extra": "^1.16.1",
96+
"eslint-plugin-sonarjs": "^2.0.4",
97+
"eslint-plugin-testing-library": "^6.4.0",
9698
"jspdf": "^2.5.1",
9799
"jspdf-autotable": "^3.5.23",
98100
"playwright": "^1.45.1",

src/Cell.tsx

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { memo } from 'react';
1+
import { forwardRef, memo, type RefAttributes } from 'react';
22
import { css } from '@linaria/core';
33

44
import { useRovingTabIndex } from './hooks';
@@ -25,31 +25,37 @@ const cellDraggedOver = css`
2525

2626
const cellDraggedOverClassname = `rdg-cell-dragged-over ${cellDraggedOver}`;
2727

28-
function Cell<R, SR>({
29-
column,
30-
colSpan,
31-
isCellSelected,
32-
isCopied,
33-
isDraggedOver,
34-
row,
35-
rowIdx,
36-
onClick,
37-
onDoubleClick,
38-
onContextMenu,
39-
onRowChange,
40-
selectCell,
41-
...props
42-
}: CellRendererProps<R, SR>) {
28+
function Cell<R, SR>(
29+
{
30+
column,
31+
colSpan,
32+
isCellSelected,
33+
isCopied,
34+
isDraggedOver,
35+
row,
36+
rowIdx,
37+
className,
38+
onClick,
39+
onDoubleClick,
40+
onContextMenu,
41+
onRowChange,
42+
selectCell,
43+
style,
44+
...props
45+
}: CellRendererProps<R, SR>,
46+
ref: React.Ref<HTMLDivElement>
47+
) {
4348
const { tabIndex, childTabIndex, onFocus } = useRovingTabIndex(isCellSelected);
4449

4550
const { cellClass } = column;
46-
const className = getCellClassname(
51+
className = getCellClassname(
4752
column,
4853
{
4954
[cellCopiedClassname]: isCopied,
5055
[cellDraggedOverClassname]: isDraggedOver
5156
},
52-
typeof cellClass === 'function' ? cellClass(row) : cellClass
57+
typeof cellClass === 'function' ? cellClass(row) : cellClass,
58+
className
5359
);
5460
const isEditable = isCellEditableUtil(column, row);
5561

@@ -95,9 +101,13 @@ function Cell<R, SR>({
95101
aria-colspan={colSpan}
96102
aria-selected={isCellSelected}
97103
aria-readonly={!isEditable || undefined}
104+
ref={ref}
98105
tabIndex={tabIndex}
99106
className={className}
100-
style={getCellStyle(column, colSpan)}
107+
style={{
108+
...getCellStyle(column, colSpan),
109+
...style
110+
}}
101111
onClick={handleClick}
102112
onDoubleClick={handleDoubleClick}
103113
onContextMenu={handleContextMenu}
@@ -116,4 +126,12 @@ function Cell<R, SR>({
116126
);
117127
}
118128

119-
export default memo(Cell) as <R, SR>(props: CellRendererProps<R, SR>) => React.JSX.Element;
129+
const CellComponent = memo(forwardRef(Cell)) as <R, SR>(
130+
props: CellRendererProps<R, SR> & RefAttributes<HTMLDivElement>
131+
) => React.JSX.Element;
132+
133+
export default CellComponent;
134+
135+
export function defaultRenderCell<R, SR>(key: React.Key, props: CellRendererProps<R, SR>) {
136+
return <CellComponent key={key} {...props} />;
137+
}

0 commit comments

Comments
 (0)