Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
"js/ts.tsdk.promptToUseWorkspaceVersion": true,
"js/ts.tsdk.path": "node_modules/typescript/lib",
"js/ts.experimental.useTsgo": true,
"eslint.options": {
"flags": ["unstable_native_nodejs_ts_config"]
},
"eslint.problems.shortenToSingleLine": true,
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now lints won't span multiple lines anymore, which was inconvenient.
https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint

"files.readonlyInclude": {
"**/routeTree.gen.ts": true
},
Expand Down
33 changes: 10 additions & 23 deletions eslint.config.js → eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,10 @@ export default defineConfig([
'unicode-bom': 1,

// React Hooks
// https://www.npmjs.com/package/eslint-plugin-react-hooks
// https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks
// https://react.dev/reference/eslint-plugin-react-hooks
'react-hooks/rules-of-hooks': 1,
'react-hooks/exhaustive-deps': 1,
'react-hooks/component-hook-factories': 1,
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rule is deprecated and a no-op
facebook/react@bc24980

'react-hooks/config': 1,
'react-hooks/error-boundaries': 1,
'react-hooks/gating': 1,
Expand Down Expand Up @@ -365,9 +365,11 @@ copy(
'@eslint-react/jsx-no-children-prop': 1,
'@eslint-react/jsx-no-children-prop-with-children': 1,
'@eslint-react/jsx-no-comment-textnodes': 1,
'@eslint-react/jsx-no-useless-fragment': [1, { allowExpressions: false }],
'@eslint-react/jsx-no-key-after-spread': 1,
'@eslint-react/jsx-no-leaked-dollar': 1,
'@eslint-react/jsx-no-leaked-semicolon': 1,
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'@eslint-react/jsx-no-namespace': 1,
'@eslint-react/jsx-no-useless-fragment': [1, { allowExpressions: false }],
'@eslint-react/rsc-function-definition': 1,
'@eslint-react/dom-no-dangerously-set-innerhtml': 1,
'@eslint-react/dom-no-dangerously-set-innerhtml-with-children': 1,
Expand Down Expand Up @@ -395,7 +397,7 @@ copy(
'@eslint-react/naming-convention-ref-name': 1,

// SonarJS rules
// https://github.com/SonarSource/SonarJS/blob/master/packages/jsts/src/rules/README.md#rules
// https://github.com/SonarSource/SonarJS/blob/master/packages/analysis/src/jsts/rules/README.md#rules
/*
// copy all the rules from the rules table for easy pasting
copy(
Expand Down Expand Up @@ -442,11 +444,12 @@ copy(
'sonarjs/aws-sqs-unencrypted-queue': 0,
'sonarjs/bitwise-operators': 1,
'sonarjs/block-scoped-var': 1,
'sonarjs/bool-param-default': 0,
'sonarjs/bool-param-default': 1,
'sonarjs/call-argument-line': 1,
'sonarjs/chai-determinate-assertion': 1,
'sonarjs/class-name': 1,
'sonarjs/class-prototype': 1,
'sonarjs/code-eval': 1,
'sonarjs/cognitive-complexity': 0,
'sonarjs/comma-or-logical-or-case': 1,
'sonarjs/comment-regex': 1,
Expand All @@ -466,6 +469,7 @@ copy(
'sonarjs/disabled-auto-escaping': 1,
'sonarjs/disabled-resource-integrity': 1,
'sonarjs/disabled-timeout': 1,
'sonarjs/dompurify-unsafe-config': 1,
'sonarjs/duplicates-in-character-class': 1,
'sonarjs/dynamically-constructed-templates': 1,
'sonarjs/elseif-without-else': 0,
Expand Down Expand Up @@ -517,7 +521,7 @@ copy(
'sonarjs/no-code-after-done': 1,
'sonarjs/no-collapsible-if': 1,
'sonarjs/no-collection-size-mischeck': 1,
'sonarjs/no-commented-code': 0,
'sonarjs/no-commented-code': 1,
'sonarjs/no-control-regex': 1,
'sonarjs/no-dead-store': 1,
'sonarjs/no-delete-var': 1,
Expand Down Expand Up @@ -598,7 +602,6 @@ copy(
'sonarjs/no-undefined-assignment': 0,
'sonarjs/no-unenclosed-multiline-block': 1,
'sonarjs/no-uniq-key': 1,
'sonarjs/no-unsafe-unzip': 1,
'sonarjs/no-unthrown-error': 1,
'sonarjs/no-unused-collection': 1,
'sonarjs/no-unused-function-argument': 1,
Expand All @@ -617,7 +620,6 @@ copy(
'sonarjs/null-dereference': 1,
'sonarjs/object-alt-content': 1,
'sonarjs/operation-returning-nan': 1,
'sonarjs/os-command': 1,
'sonarjs/post-message': 1,
'sonarjs/prefer-default-last': 1,
'sonarjs/prefer-immediate-return': 1,
Expand Down Expand Up @@ -1028,21 +1030,6 @@ copy(
}
},

{
name: 'node',

files: ['**/*.js'],

rules: {
// Best Practices
'default-param-last': 1,
// Possible Errors
'no-console': 0,
'no-undef': 1,
'no-use-before-define': [1, { functions: false, classes: false, variables: false }]
}
},

{
name: 'markdown',
files: ['**/*.md'],
Expand Down
41 changes: 19 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,49 +42,46 @@
"test:ci:update": "vitest run --project visual --update",
"format": "oxfmt",
"format:check": "oxfmt --check",
"eslint": "eslint --max-warnings 0 --cache --cache-location .cache/eslint --cache-strategy content",
"eslint": "eslint --max-warnings 0 --cache --cache-location .cache/eslint --cache-strategy content --flag unstable_native_nodejs_ts_config",
"eslint:fix": "node --run eslint -- --fix",
"typecheck": "tsgo --build"
},
"devDependencies": {
"@eslint-react/eslint-plugin": "^4.2.1",
"@eslint-react/eslint-plugin": "^4.2.3",
"@eslint/markdown": "^8.0.1",
"@faker-js/faker": "^10.3.0",
"@tanstack/react-router": "^1.166.7",
"@tanstack/router-plugin": "^1.166.7",
"@tsdown/css": "^0.21.7",
"@types/node": "^25.5.0",
"@tsdown/css": "^0.21.9",
"@types/node": "^25.6.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@typescript/native-preview": "^7.0.0-dev.20260407.1",
"@typescript/native-preview": "^7.0.0-dev.20260421.1",
"@vitejs/plugin-react": "^6.0.1",
"@vitest/browser-playwright": "^4.1.3",
"@vitest/coverage-istanbul": "^4.1.3",
"@vitest/eslint-plugin": "^1.6.14",
"@vitest/browser-playwright": "^4.1.5",
"@vitest/coverage-istanbul": "^4.1.5",
"@vitest/eslint-plugin": "^1.6.16",
"clsx": "^2.1.1",
"ecij": "^0.4.1",
"eslint": "^10.0.3",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-sonarjs": "^4.0.2",
"eslint": "^10.2.1",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-sonarjs": "^4.0.3",
"jspdf": "^4.2.0",
"jspdf-autotable": "^5.0.7",
"oxfmt": "0.45.0",
"oxfmt": "0.46.0",
"playwright": "~1.59.0",
"postcss": "^8.5.2",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"tsdown": "^0.21.7",
"typescript": "~6.0.2",
"typescript-eslint": "^8.58.0",
"vite": "^8.0.6",
"vitest": "^4.1.3",
"react": "^19.2.5",
"react-dom": "^19.2.5",
"tsdown": "^0.21.9",
"typescript": "~6.0.3",
"typescript-eslint": "^8.59.0",
"vite": "^8.0.9",
"vitest": "^4.1.5",
"vitest-browser-react": "^2.2.0"
},
"peerDependencies": {
"react": "^19.2",
"react-dom": "^19.2"
},
"overrides": {
"eslint": "$eslint"
}
}
2 changes: 1 addition & 1 deletion src/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function Cell<R, SR>({
);
const isEditable = isCellEditableUtil(column, row);

function setActivePositionWrapper(enableEditor?: boolean) {
function setActivePositionWrapper(enableEditor = false) {
Copy link
Copy Markdown
Collaborator Author

@nstepien nstepien Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caught by sonarjs/bool-param-default, decided to keep this rule enabled.

setActivePosition({ rowIdx, idx: column.idx }, { enableEditor });
}

Expand Down
1 change: 1 addition & 0 deletions src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
} else {
focusCell(gridRef.current!);
}
// eslint-disable-next-line react-hooks/set-state-in-effect
setShouldFocusPosition(false);
}
}, [shouldFocusPosition, activePositionIsRow, gridRef]);
Expand Down
3 changes: 1 addition & 2 deletions test/browser/TreeDataGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ function TestGrid({
}

function rowGrouper(rows: readonly Row[], columnKey: string) {
Comment thread
amanmahajan7 marked this conversation as resolved.
// @ts-expect-error
return Object.groupBy(rows, (r) => r[columnKey]) as Record<string, readonly R[]>;
return Object.groupBy(rows, (r) => r[columnKey as keyof Row]) as Record<string, readonly Row[]>;
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We used an incorrect R type, which these 3 @ts-expect-errors hid from us

}

function setup(groupBy: string[], groupIdGetter?: (groupKey: string, parentId?: string) => string) {
Expand Down
3 changes: 1 addition & 2 deletions test/visual/treeGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,5 @@ function rowKeyGetter(row: Row) {
}

function rowGrouper(rows: readonly Row[], columnKey: string) {
// @ts-expect-error
return Object.groupBy(rows, (r) => r[columnKey]) as Record<string, readonly R[]>;
return Object.groupBy(rows, (r) => r[columnKey as keyof Row]) as Record<string, readonly Row[]>;
}
1 change: 0 additions & 1 deletion tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"jsx": "react-jsx",
"lib": [],
"moduleDetection": "force",
"moduleResolution": "bundler",
"noImplicitReturns": true,
"noUnusedLocals": true,
"outDir": "./.cache/ts",
Expand Down
12 changes: 0 additions & 12 deletions tsconfig.js.json

This file was deleted.

2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"include": [],
"references": [
{ "path": "tsconfig.js.json" },
{ "path": "tsconfig.node.json" },
{ "path": "tsconfig.src.json" },
{ "path": "tsconfig.test.json" },
{ "path": "tsconfig.vite.json" },
Expand Down
8 changes: 8 additions & 0 deletions tsconfig.node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"lib": ["ESNext"],
"module": "NodeNext"
},
"include": ["eslint.config.ts"]
}
8 changes: 7 additions & 1 deletion tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { ecij } from 'ecij/plugin';
import { Features } from 'lightningcss';
import { defineConfig } from 'tsdown';

import pkg from './package.json' with { type: 'json' };

export default defineConfig({
outDir: 'lib',
target: ['baseline-widely-available', 'node24.0.0'],
Copy link
Copy Markdown
Collaborator Author

@nstepien nstepien Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They've added support for baseline-widely-available so I've added it.
Also added node 24 as it's the current LTS version.
There's 0 difference in the output of index.js/index.js.map/index.d.ts.
https://github.com/rolldown/tsdown/releases

ℹ targets: chrome111, edge111, firefox114, safari16.4, ios16.4, node24.0.0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

platform: 'neutral',
sourcemap: true,
deps: {
skipNodeModulesBundle: true
},
css: {
fileName: 'styles.css'
fileName: 'styles.css',
lightningcss: {
// https://github.com/parcel-bundler/lightningcss/issues/873
exclude: Features.Nesting | Features.LightDark
}
Copy link
Copy Markdown
Collaborator Author

@nstepien nstepien Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of changing the css.target to not break light-dark(), I've set this lightningcss configuration.

https://tsdown.dev/options/css#css-target
https://tsdown.dev/options/css#lightning-css

The only before/after difference is this:

Image

Safari only supports the prefixed property, so this is actually a bug fix!

https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/user-select#browser_compatibility

},
dts: {
build: true,
Expand Down
22 changes: 19 additions & 3 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { tanstackRouter } from '@tanstack/router-plugin/vite';
import react from '@vitejs/plugin-react';
import { playwright, type PlaywrightProviderOptions } from '@vitest/browser-playwright';
import { ecij } from 'ecij/plugin';
import { Features } from 'lightningcss';
import { defineConfig, type ViteUserConfig } from 'vitest/config';
import type { BrowserCommand } from 'vitest/node';

Expand Down Expand Up @@ -56,9 +57,24 @@ export default defineConfig(
build: {
modulePreload: { polyfill: false },
sourcemap: true,
reportCompressedSize: false,
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vite is fast now, so I removed reportCompressedSize: false

// https://github.com/parcel-bundler/lightningcss/issues/873
cssTarget: 'esnext'
rolldownOptions: {
output: {
codeSplitting: {
groups: [
{
name: 'faker',
test: '@faker-js/faker'
Copy link
Copy Markdown
Collaborator Author

@nstepien nstepien Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Faker is the biggest dependency we have, and it doesn't get updates too often, might be worth splitting it into its own chunk.

dist/assets/faker-DefjNDsx.js                   410.66 kB │ gzip: 153.89 kB │ map:   696.97 kB

https://rolldown.rs/in-depth/manual-code-splitting#improve-loading-performance

Wonder if we should split react/react-dom together too 🤔

}
]
}
}
}
},
css: {
lightningcss: {
// https://github.com/parcel-bundler/lightningcss/issues/873
exclude: Features.Nesting | Features.LightDark
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied the same lightningcss strategy here to fix the missing -webkit-user-select property.

},
plugins: isPreview
? []
Expand Down
3 changes: 1 addition & 2 deletions website/routes/RowGrouping.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,5 @@ function RowGrouping() {
}

function rowGrouper(rows: readonly Row[], columnKey: string) {
// @ts-expect-error
return Object.groupBy(rows, (r) => r[columnKey]) as Record<string, readonly R[]>;
return Object.groupBy(rows, (r) => r[columnKey as keyof Row]) as Record<string, readonly Row[]>;
}