From 6cc8797c4809da0073c839fb951abe4f2a3f2741 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 20 Oct 2026 01:29:29 +0100 Subject: [PATCH 01/15] Fix typos, grammar, and outdated text - Fix typos, conjugation, and grammar mistakes across the docs, comments, test names, and demos - Correct docs that no longer match the code, like the `rows` and `editable` JSDoc, the `onCellClick` examples, and outdated comments - Fix wrong PR links, a misnamed prop, and dead demo links in the changelog - Update outdated URLs - Use American English and serial commas consistently Co-Authored-By: Claude Opus 5.5 --- .github/workflows/update-screenshots.yml | 2 +- .vscode/settings.json | 2 +- AGENTS.md | 20 +-- CHANGELOG.md | 89 ++++++------- README.md | 140 +++++++++----------- src/Cell.tsx | 2 +- src/DataGrid.tsx | 45 +++---- src/EditCell.tsx | 12 +- src/GroupedColumnHeaderRow.tsx | 2 +- src/HeaderCell.tsx | 4 +- src/HeaderRow.tsx | 2 +- src/TreeDataGrid.tsx | 4 +- src/hooks/useActivePosition.ts | 4 +- src/hooks/useCalculatedColumns.ts | 2 +- src/hooks/useGridDimensions.ts | 2 +- src/hooks/useLatestFunc.ts | 2 +- src/hooks/useRovingTabIndex.ts | 2 +- src/hooks/useScrollState.ts | 6 +- src/hooks/useViewportColumns.ts | 4 +- src/hooks/useViewportRows.ts | 4 +- src/style/core.ts | 2 +- src/types.ts | 8 +- src/utils/frozenColumnUtils.ts | 2 +- src/utils/index.ts | 2 +- src/utils/keyboardUtils.ts | 8 +- test/browser/column/colSpan.test.ts | 14 +- test/browser/column/endFrozen.test.ts | 4 +- test/browser/column/renderCell.test.tsx | 6 +- test/browser/column/renderEditCell.test.tsx | 6 +- test/browser/column/resizable.test.tsx | 10 +- test/browser/column/startFrozen.test.ts | 2 +- test/browser/copyPaste.test.tsx | 4 +- test/browser/direction.test.ts | 6 +- test/browser/dragFill.test.tsx | 4 +- test/browser/events.test.tsx | 18 +-- test/browser/keyboardNavigation.test.tsx | 6 +- test/browser/renderers.test.tsx | 8 +- test/browser/scrollToCell.test.tsx | 6 +- test/browser/sorting.test.tsx | 6 +- test/browser/utils.tsx | 12 +- test/setupBrowser.ts | 12 +- website/Nav.tsx | 2 +- website/components/ChildRowDeleteButton.tsx | 2 +- website/routes/AllFeatures.tsx | 8 +- website/routes/CommonFeatures.tsx | 4 +- website/routes/CustomizableRenderers.tsx | 2 +- website/routes/HeaderFilters.tsx | 4 +- website/routes/RowGrouping.tsx | 6 +- website/routes/ScrollToCell.tsx | 2 +- website/routes/TreeView.tsx | 14 +- 50 files changed, 264 insertions(+), 276 deletions(-) diff --git a/.github/workflows/update-screenshots.yml b/.github/workflows/update-screenshots.yml index 6a91323eee..6c267d492a 100644 --- a/.github/workflows/update-screenshots.yml +++ b/.github/workflows/update-screenshots.yml @@ -15,7 +15,7 @@ env: # and only images, so the job that pushes can only commit images SCREENSHOTS: 'test/**/screenshots/**/*.png' -# dependencies only run in the read-only `screenshots` job, +# dependencies only run in the read-only `screenshots` job; # the jobs with write permissions only run gh and git jobs: remove-label: diff --git a/.vscode/settings.json b/.vscode/settings.json index 6a898b7f25..0e546f4539 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ "editor.formatOnSaveMode": "file", "js/ts.experimental.useTsgo": true, "js/ts.tsdk.path": "./node_modules/typescript", - // ESLint is only used for markdown; JS/TS is linted by the oxc extension + // ESLint is only used for Markdown; JS/TS is linted by the Oxc extension "eslint.validate": ["markdown"], "eslint.problems.shortenToSingleLine": true, "files.readonlyInclude": { diff --git a/AGENTS.md b/AGENTS.md index cfc1e0744e..eb766702fb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,11 +9,11 @@ src/ index.ts # public API surface; all exports go through here DataGrid.tsx # main component (generic: ) TreeDataGrid.tsx # wraps DataGrid, adds row grouping (role="treegrid") - types.ts # shared type definitions (e.g. Column, CalculatedColumn, render props, events) + types.ts # shared type definitions (e.g., Column, CalculatedColumn, render props, events) hooks/ # shared custom React hooks - utils/ # pure utilities (e.g. keyboard, DOM, events, colSpan, style) + utils/ # pure utilities (e.g., keyboard, DOM, events, colSpan, style) style/ # build-time CSS via ecij tagged templates; layers.css declares @layer order - cellRenderers/ # default cell renderers (e.g. checkbox, toggleGroup, value) + cellRenderers/ # default cell renderers (e.g., checkbox, toggleGroup, value) editors/ # default editors (renderTextEditor) test/ browser/ # vitest browser-mode tests (Playwright: Chromium, Firefox, WebKit) @@ -30,10 +30,10 @@ website/ # demo site (Vite + TanStack Router) - **TypeScript strict** with `exactOptionalPropertyTypes`, `verbatimModuleSyntax`, `erasableSyntaxOnly`. Distinguish missing properties from `undefined` values. - **`Maybe`** (`T | undefined | null`) — used for all nullable column/render props. Do not use bare `T | undefined`. - **`NoInfer<>`** — wrap callback parameters to prevent reverse type inference into component generics. -- **CSS layers** — all styles live in nested `@layer rdg.` sub-layers (e.g. `rdg.Cell`, `rdg.Row`; declared in `src/style/layers.css`). Use `ecij` `css` tagged templates (build-time extraction, not runtime CSS-in-JS). Co-locate styles in component files; `src/style/` is for shared styles. -- **Dual classnames** — components apply both a semantic class (`rdg-cell`) and a generated hash. Preserve both. +- **CSS layers** — all styles live in nested `@layer rdg.` sub-layers (e.g., `rdg.Cell`, `rdg.Row`; declared in `src/style/layers.css`). Use `ecij` `css` tagged templates (build-time extraction, not runtime CSS-in-JS). Co-locate styles in component files; `src/style/` is for shared styles. +- **Dual class names** — components apply both a semantic class (`rdg-cell`) and a generated hash. Preserve both. - **Light/dark mode** — handled via CSS `light-dark()` + `color-scheme`, not JS. -- **Accessibility first** — ARIA attributes (e.g. `aria-colindex`, `aria-rowindex`, `aria-selected`, roles) are required. Tests query by role. +- **Accessibility first** — ARIA attributes (e.g., `aria-colindex`, `aria-rowindex`, `aria-selected`, roles) are required. Tests query by role. - **Build** — `vp pack` bundles the library to `lib/`, then lints the packed package with publint; `ecij` plugin prefixes classes with `rdg-{version}-` (dots→dashes) to avoid cross-version conflicts. - **Workflows** — pin every action to a full commit SHA with its version in a comment (Dependabot updates both), pass expressions to `run` steps through `env` instead of inlining `${{ }}`, grant each job only the `permissions` it uses, and check out with `persist-credentials: false`. Jobs that install dependencies only get read permissions: publishing, pushing, and editing PRs happen in separate jobs that receive build output as artifacts and never install the project's dependencies. - **Releases** — the header of `.github/workflows/publish.yml` explains how to publish. Its read-only `build` job hands `lib/` to the `publish` job, so the project's dependencies never run with the `id-token: write` permission that npm's trusted publishing relies on, and a separate `release` job creates the GitHub release. @@ -43,14 +43,14 @@ website/ # demo site (Vite + TanStack Router) - Browser tests use `vite-plus/test/browser` + Playwright. `test/setupBrowser.ts` configures `page.render()` via `vitest-browser-react` and registers custom locators via `locators.extend()` — prefer `page.getGrid()`, `page.getCell({ name })`, `page.getRow()`, `page.getHeaderCell()`, `page.getActiveCell()`, etc. over raw `page.getByRole()`. - Test helpers in `test/browser/utils.tsx`: `setup()`, `getRowWithCell()`, `getCellsAtRowIndex()`, `validateCellPosition()`, `scrollGrid()`, `safeTab()`, `testCount()`, `testRowCount()`. - `test/failOnConsole.ts` fails tests on unexpected console warnings/errors. -- **Never run visual regression tests** — screenshots are environment-dependent so visual regression tests must run in CI only. +- **Never run visual regression tests** — screenshots are environment-dependent, so visual regression tests must run in CI only. ## Tooling The project uses [Vite+](https://viteplus.dev/guide/), whose global `vp` CLI wraps Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Run `vp` directly, not through `npx`. Its docs are in `node_modules/vite-plus/docs`. -- `vp ` runs a built-in command, e.g. `vp dev`, `vp check`, `vp test`, `vp pack`, `vp build`. -- `vp run ` runs a task from `vite.config.ts`, e.g. `vp run typecheck`, `vp run eslint`, `vp run ci`. +- `vp ` runs a built-in command, e.g., `vp dev`, `vp check`, `vp test`, `vp pack`, `vp build`. +- `vp run ` runs a task from `vite.config.ts`, e.g., `vp run typecheck`, `vp run eslint`, `vp run ci`. - Run `vp install` after pulling changes. ## Validation @@ -62,4 +62,4 @@ While iterating, run individual checks instead. The static checks take seconds, - `vp run typecheck` type checks with `tsc --build`; `vp check` does not type check. - `vp check --fix` formats and lints, fixing what it can. Without `--fix`, a formatting error stops it before linting. - `vp run eslint` lints Markdown files. -- `vp test ` runs specific test files, e.g. `vp test test/browser/sorting.test.tsx`. Add `--project "browser (chromium)"` to test in a single browser, or `--project node` to run the SSR test. The full suite takes about a minute. +- `vp test ` runs specific test files, e.g., `vp test test/browser/sorting.test.tsx`. Add `--project "browser (chromium)"` to test in a single browser, or `--project node` to run the SSR test. The full suite takes about a minute. diff --git a/CHANGELOG.md b/CHANGELOG.md index 6685f21a6f..985f08f5ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,11 +24,11 @@ ## v7.0.0-canary.45 -- Fixed issue where the scrollbars would flicker in edge cases ([PR](https://github.com/Comcast/react-data-grid/pull/2389)) +- Fixed an issue where the scrollbars would flicker in edge cases ([PR](https://github.com/Comcast/react-data-grid/pull/2389)) ## v7.0.0-canary.44 -- Use aria-selected to style selected cell/rows ([PR](https://github.com/Comcast/react-data-grid/pull/2386)) +- Use aria-selected to style selected cells/rows ([PR](https://github.com/Comcast/react-data-grid/pull/2386)) - Add support for variable row heights ([PR](https://github.com/Comcast/react-data-grid/pull/2384)) ## v7.0.0-canary.43 @@ -38,7 +38,7 @@ ## v7.0.0-canary.42 - Add missing `aria-colspan` ([PR](https://github.com/Comcast/react-data-grid/pull/2374)) -- Add `aria-readonly` to readonly cells ([PR](https://github.com/Comcast/react-data-grid/pull/2379)) +- Add `aria-readonly` to read-only cells ([PR](https://github.com/Comcast/react-data-grid/pull/2379)) ## v7.0.0-canary.41 @@ -48,11 +48,11 @@ ## v7.0.0-canary.40 - Add `column.colSpan` prop to merge cells ([PR](https://github.com/Comcast/react-data-grid/pull/2356)) -- Removed prefixed css properties from the generated style file ([PR](https://github.com/Comcast/react-data-grid/pull/2370)) +- Removed prefixed CSS properties from the generated style file ([PR](https://github.com/Comcast/react-data-grid/pull/2370)) ## v7.0.0-canary.39 -- Add `enableVirtualization` prop ([PR](https://github.com/Comcast/react-data-grid/pull/2355)). Grid renders all the rows/columns when it is set to false. +- Add `enableVirtualization` prop ([PR](https://github.com/Comcast/react-data-grid/pull/2355)). The grid renders all the rows/columns when it is set to `false`. ## v7.0.0-canary.38 @@ -65,11 +65,11 @@ ## v7.0.0-canary.36 -- Fixed column headers not showing when grid is horizontally scrolled ([PR](https://github.com/Comcast/react-data-grid/pull/2297)) +- Fixed column headers not showing when the grid is horizontally scrolled ([PR](https://github.com/Comcast/react-data-grid/pull/2297)) ## v7.0.0-canary.35 -- Migrate to css-in-js with linaria ([PR](https://github.com/Comcast/react-data-grid/pull/2256)). RDG now internally uses [linaria](https://github.com/callstack/linaria) to manage styles. The stylesheets are automatically injected and there is no stylesheet to manually import anymore. +- Migrate to CSS-in-JS with Linaria ([PR](https://github.com/Comcast/react-data-grid/pull/2256)). RDG now internally uses [Linaria](https://github.com/callstack/linaria) to manage styles. The stylesheets are automatically injected and there is no stylesheet to manually import anymore. - Expose data grid root element reference ([PR](https://github.com/Comcast/react-data-grid/pull/2258)). - (Bug fix) Tabbing into the grid should initiate keyboard navigation ([PR](https://github.com/Comcast/react-data-grid/pull/2289)). @@ -77,7 +77,7 @@ - Only show the vertical scrollbar when necessary ([PR](https://github.com/Comcast/react-data-grid/pull/2231)) - Fix `editorPortalTarget` default value for server-side rendering ([PR](https://github.com/Comcast/react-data-grid/pull/2245)) -- Use grid layout for rows, split column metrics from compute columns ([PR](https://github.com/Comcast/react-data-grid/pull/2272)). Resizing columns no longer recreates columns so less re-renders +- Use grid layout for rows, split column metrics from compute columns ([PR](https://github.com/Comcast/react-data-grid/pull/2272)). Resizing columns no longer recreates columns, so there are fewer re-renders - Augment `onRowsChange` with `indexes` and `column` data ([PR](https://github.com/Comcast/react-data-grid/pull/2278)) ## v7.0.0-canary.33 @@ -94,8 +94,8 @@ - Use a pseudo-element for header resizer ([PR](https://github.com/Comcast/react-data-grid/pull/2217)) - (new) Formatters now receive a new onRowChange prop ([PR](https://github.com/Comcast/react-data-grid/pull/2220)) - (new) Change `column.name` type from `string` to `string/ReactElement` ([PR](https://github.com/Comcast/react-data-grid/pull/2220)) -- Publish bundles instead of modules, use babel only for transpilation ([PR](https://github.com/Comcast/react-data-grid/pull/2214)) -- Use the new jsx runtime ([PR](https://github.com/Comcast/react-data-grid/pull/2184)). The minimum supported react version is 16.14 now. +- Publish bundles instead of modules, use Babel only for transpilation ([PR](https://github.com/Comcast/react-data-grid/pull/2214)) +- Use the new JSX runtime ([PR](https://github.com/Comcast/react-data-grid/pull/2184)). The minimum supported React version is 16.14 now. ## v7.0.0-canary.30 @@ -104,7 +104,7 @@ ## v7.0.0-canary.29 -- Fix crash when `rows` are `undefined` ([PR](https://github.com/Comcast/react-data-grid/pull/2197)) +- Fix crash when `rows` is `undefined` ([PR](https://github.com/Comcast/react-data-grid/pull/2197)) - Fix a scrolling bug caused by `scroll-behavior: smooth` ([PR](https://github.com/Comcast/react-data-grid/pull/2200)) ## v7.0.0-canary.28 @@ -116,11 +116,11 @@ - (Breaking) Removed old editor API ([PR](https://github.com/Comcast/react-data-grid/pull/2149)) - (Breaking) Removed `onCheckCellIsEditable` prop ([PR](https://github.com/Comcast/react-data-grid/pull/2016)). Use `column.editable` instead. - = (Breaking) Replaced rowKey prop with rowKeyGetter ([PR](https://github.com/Comcast/react-data-grid/pull/2190)) +- (Breaking) Replaced `rowKey` prop with `rowKeyGetter` ([PR](https://github.com/Comcast/react-data-grid/pull/2190)) ## v7.0.0-canary.26 -- Fixed Copy & Paste events not working properly in non-English keyboards ([PR](https://github.com/Comcast/react-data-grid/pull/2097)) +- Fixed Copy & Paste events not working properly with non-English keyboards ([PR](https://github.com/Comcast/react-data-grid/pull/2097)) ## v7.0.0-canary.25 @@ -128,7 +128,7 @@ ## v7.0.0-canary.24 -- Fixed a bug where grid was getting scrolled on cell focus +- Fixed a bug where the grid was getting scrolled on cell focus ## v7.0.0-canary.23 @@ -136,21 +136,21 @@ ## v7.0.0-canary.22 -- Add Grouping ([PR](https://github.com/Comcast/react-data-grid/pull/2106)). Check the new [example](https://comcast.github.io/react-data-grid/#/grouping). +- Add Grouping ([PR](https://github.com/Comcast/react-data-grid/pull/2106)). Check the new [example](https://comcast.github.io/react-data-grid/#/RowGrouping). - (Breaking) Removed `height` and `width` props and added new `className` and `style` props. We are now using `ResizeObserver` to calculate all the grid dimensions ([PR](https://github.com/Comcast/react-data-grid/pull/2130)) -- (Breaking) Removed formatterOptions. Grid now handles formatter focus internally so this prop is no longer required ([PR](https://github.com/Comcast/react-data-grid/pull/2138)) +- (Breaking) Removed formatterOptions. The grid now handles formatter focus internally, so this prop is no longer required ([PR](https://github.com/Comcast/react-data-grid/pull/2138)) - Added support for React 17 ## v7.0.0-canary.21 - Editor2 bug fixes ([PR](https://github.com/Comcast/react-data-grid/pull/2126)) -- `formatterOptions.focusable` can be a function now so different rows can have different focus behavior for the same column -- Grid now internally uses `ResizeObserver` API to calculate the available width ([PR](https://github.com/Comcast/react-data-grid/pull/2129)) +- `formatterOptions.focusable` can be a function now, so different rows can have different focus behavior for the same column +- The grid now internally uses the `ResizeObserver` API to calculate the available width ([PR](https://github.com/Comcast/react-data-grid/pull/2129)) ## v7.0.0-canary.20 -- A new editor api that does not require a ref ([PR](https://github.com/Comcast/react-data-grid/pull/2102)) -- A new `columnDefaultOptions` prop. This replaces `minColumnWidth` and `defaultFormatter` props ([PR](https://github.com/Comcast/react-data-grid/pull/2117)) +- A new editor API that does not require a ref ([PR](https://github.com/Comcast/react-data-grid/pull/2102)) +- A new `defaultColumnOptions` prop. This replaces the `minColumnWidth` and `defaultFormatter` props ([PR](https://github.com/Comcast/react-data-grid/pull/2117)) ## v7.0.0-canary.19 @@ -158,9 +158,9 @@ ## v7.0.0-canary.18 -- Accessibility improvements. Added various aria attributes. ([PR](https://github.com/Comcast/react-data-grid/pull/2084)) +- Accessibility improvements. Added various ARIA attributes. ([PR](https://github.com/Comcast/react-data-grid/pull/2084)) - Removed enableCellAutoFocus prop ([PR](https://github.com/Comcast/react-data-grid/pull/2073)) -- Removed InteractionMasks component. This is an internal change to prepare for grouping and it fixes a few selected cell position bugs +- Removed InteractionMasks component. This is an internal change to prepare for grouping, and it fixes a few selected cell position bugs - Improved focus for custom formatters using the new formatterOptions ([PR](https://github.com/Comcast/react-data-grid/pull/2104)) ## v7.0.0-canary.17 @@ -184,7 +184,7 @@ - `filters` - `onFiltersChange` - `rows` - - ⚠️ This replace the `rowGetter` and `rowsCount` props + - ⚠️ This replaces the `rowGetter` and `rowsCount` props - `rowClass` - `defaultColumnOptions` - ⚠️ This replaces the `minColumnWidth` and `defaultFormatter` props @@ -217,7 +217,7 @@ - ⚠️ `height` - ⚠️ `cellContentRenderer` - ⚠️ `contextMenu` - - Check the [Context Menu](https://comcast.github.io/react-data-grid/#/context-menu) example + - Check the [Context Menu](https://comcast.github.io/react-data-grid/#/ContextMenu) example - ⚠️ `enableCellSelect` - ⚠️ `enableCellAutoFocus` - ⚠️ `getValidFilterValues` @@ -243,7 +243,7 @@ - ⚠️ `value` (from `column.formatter` props) - **Ref handlers:** - ⚠️ `openCellEditor`, use `selectCell` instead. - - ⚠️ React elements are no longer supported, please use components instead. + - ⚠️ React elements are no longer supported; please use components instead. - For example: ```diff const column = { @@ -276,14 +276,14 @@ - ⚠️ Started publishing ES2019/ESM modules instead of ES5/CommonJS modules. - Using [`@babel/preset-env`](https://www.npmjs.com/package/@babel/preset-env) with [`core-js`](https://www.npmjs.com/package/core-js) is recommended to enable compatibility for the browsers your project aims to support. - ⚠️ Improved support for summary rows: - - `summaryRows` types are now independent from `rows` + - `summaryRows` types are now independent of `rows` - Added `column.summaryCellClass` and `column.summaryFormatter` props - `column.formatter` isn't used anymore to render summary row cells. - - Only visible headers cells are now rendered. [#1837](https://github.com/Comcast/react-data-grid/pull/1837) - - ⚠️ the `rowKeyGetter` prop is now required for row selection. + - Only visible header cells are now rendered. [#1837](https://github.com/Comcast/react-data-grid/pull/1837) + - ⚠️ The `rowKeyGetter` prop is now required for row selection. - ⚠️ `column.cellClass` does not affect header cells anymore. - - ⚠️ `onScroll` will directly pass the UIEvent rather than the scrollLeft and scrollRight only. - - ⚠️ The stylesheets are now automatically injected, there is no stylsheet to manually import anymore. + - ⚠️ `onScroll` will directly pass the UIEvent rather than only the scrollLeft and scrollTop. + - ⚠️ The stylesheets are now automatically injected; there is no stylesheet to manually import anymore. ## `main` to `alpha` @@ -302,7 +302,7 @@ - **Removed:** - **Packages:** - `react-data-grid-examples` - - Use the website as reference, or clone the repo locally and run `npm install` + `npm start` + - Use the website as a reference, or clone the repo locally and run `npm install` + `npm start` - **Props:** - ⚠️ `onCellsDragged` - ⚠️ `onDragHandleDoubleClick` @@ -315,11 +315,11 @@ - ⚠️ `ContainerEditorWrapper` - ⚠️ `EditorBase` - ⚠️ `setScrollLeft` from `Row` and `Cell` renderers - - `setScrollLeft` instance method was previously required on custom Cell and Row renderers and it can be safely removed now. + - The `setScrollLeft` instance method was previously required on custom Cell and Row renderers, and it can be safely removed now. - More info in [#1793](https://github.com/Comcast/react-data-grid/pull/1793) - ⚠️ Dropped ImmutableJS support. - ⚠️ Dropped dynamic height row support. - - This was not officially supported, but it was still possible to implement dynamic rows via custom Row renderer. This was a buggy feature so it has been removed. + - This was not officially supported, but it was still possible to implement dynamic rows via a custom Row renderer. This was a buggy feature, so it has been removed. - ⚠️ Removed row reordering support. - **Renamed:** - `ReactDataGrid` to `DataGrid` @@ -327,7 +327,7 @@ - ⚠️ The stylesheets are now bundled separately: - `react-data-grid/dist/react-data-grid.css` - ⚠️ Reimplemented stylesheets, renamed various class names [#1780](https://github.com/Comcast/react-data-grid/pull/1780) - - No longer depends on bootstrap + - No longer depends on Bootstrap - Resizing a column now immediately resizes all its cells instead of just its header. - Improved performance across the board. @@ -353,11 +353,10 @@ ## 6.0.0 (Nov 30, 2018) - **Bugfix:** Fix outside click logic for committing changes ([1404](https://github.com/Comcast/react-data-grid/pull/1404)) -- **TechDebt** Add ESLint Rules ([1396](https://github.com/Comcast/react-data-grid/pull/1396) [1397](https://github.com/Comcast/react-data-grid/pull/1397) [1396](https://github.com/Comcast/react-data-grid/pull/1398) [1399](https://github.com/Comcast/react-data-grid/pull/1399)) +- **TechDebt:** Add ESLint Rules ([1396](https://github.com/Comcast/react-data-grid/pull/1396) [1397](https://github.com/Comcast/react-data-grid/pull/1397) [1398](https://github.com/Comcast/react-data-grid/pull/1398) [1399](https://github.com/Comcast/react-data-grid/pull/1399)) - **TechDebt:** Upgrade build tools to latest versions ([1350](https://github.com/Comcast/react-data-grid/pull/1350)) - **Feature:** Cleanup zIndex logic ([1393](https://github.com/Comcast/react-data-grid/pull/1393)) -- **Breaking** Use react portals for cell editors ([1369](https://github.com/Comcast/react-data-grid/pull/1369)) -- **TechDebt:** Upgrade build tools to latest versions ([1350](https://github.com/Comcast/react-data-grid/pull/1350)) +- **Breaking:** Use React portals for cell editors ([1369](https://github.com/Comcast/react-data-grid/pull/1369)) ## 5.0.4 (Nov 14, 2018) @@ -365,16 +364,16 @@ - **Bugfix:** Fix website publishing and remove ImmutableJS dependency ([1366](https://github.com/Comcast/react-data-grid/pull/1366)) - **Bugfix:** Remove react-data-grid dependency from the addons package ([1354](https://github.com/Comcast/react-data-grid/pull/1354)) - **Bugfix:** Fix drag fill in IE 11 ([1359](https://github.com/Comcast/react-data-grid/pull/1359)) -- **Bugfix:** Ensure webpack uses correct common js external ref ([1370](https://github.com/Comcast/react-data-grid/pull/1370)) +- **Bugfix:** Ensure webpack uses correct CommonJS external ref ([1370](https://github.com/Comcast/react-data-grid/pull/1370)) - **Feature:** Move DropTargetRowContainer static styles to CSS class for user customization ([1308](https://github.com/Comcast/react-data-grid/pull/1308)) - **Bugfix:** Replace use of i for column index which is no longer passed in ([1344](https://github.com/Comcast/react-data-grid/pull/1344)) - **Bugfix:** Remove utils from documentation as an exported module ([1374](https://github.com/Comcast/react-data-grid/pull/1374)) -- **TechDebt:** Upgrade eslint packages ([1376](https://github.com/Comcast/react-data-grid/pull/1376)) +- **TechDebt:** Upgrade ESLint packages ([1376](https://github.com/Comcast/react-data-grid/pull/1376)) - **Bugfix:** Cleanup DraggableContainer and fix styles ([1379](https://github.com/Comcast/react-data-grid/pull/1379)) ## 5.0.3 (Nov 1, 2018) -- **Bugfix:** Fix frozen-columns source url ([1355](https://github.com/Comcast/react-data-grid/pull/1355)) +- **Bugfix:** Fix frozen-columns source URL ([1355](https://github.com/Comcast/react-data-grid/pull/1355)) - **TechDebt:** Defining the ref callback as a bound method ([1353](https://github.com/Comcast/react-data-grid/pull/1353)) - **Bugfix:** Fix cell focusing logic ([1352](https://github.com/Comcast/react-data-grid/pull/1352)) - **Bugfix:** RDG Tree Cell Expand Styling Issues ([1316](https://github.com/Comcast/react-data-grid/pull/1316)) @@ -382,14 +381,14 @@ ## 5.0.2 (Oct 30, 2018) - **Bugfix:** Fix grouping example ([1311](https://github.com/Comcast/react-data-grid/pull/1311)) -- **Bugfix:** Remove contain layout css ([1346](https://github.com/Comcast/react-data-grid/pull/1346)) -- **Bugfix:** Preserve window scroll position on cell selection ([1349](https://github.com/Comcast/react-data-grid/pull/1346)) +- **Bugfix:** Remove contain layout CSS ([1346](https://github.com/Comcast/react-data-grid/pull/1346)) +- **Bugfix:** Preserve window scroll position on cell selection ([1349](https://github.com/Comcast/react-data-grid/pull/1349)) ## 5.0.1 (Oct 22, 2018) ### React-Data-Grid -- **Bugfix:** Fix CopyMask columns ([1289](https://github.com/Comcast/react-data-grid/pull/1272)) +- **Bugfix:** Fix CopyMask columns ([1289](https://github.com/Comcast/react-data-grid/pull/1289)) ## 5.0.0 (Oct 22, 2018) @@ -412,8 +411,8 @@ - **Feature:** Support `React v16` ([#1116](https://github.com/Comcast/react-data-grid/pull/1116)) - **Feature:** Set sort column and direction with props ([#649](https://github.com/Comcast/react-data-grid/pull/649)) - **Bugfix:** Filtering should ignore null values ([#1147](https://github.com/Comcast/react-data-grid/pull/1147)) -- **Bugfix:** Resize column doesnt work on firefox when also draggable ([#1121](https://github.com/Comcast/react-data-grid/pull/1121)) +- **Bugfix:** Resize column doesn't work on Firefox when also draggable ([#1121](https://github.com/Comcast/react-data-grid/pull/1121)) ### React-Data-Grid-Addons -- **Breaking:** Migrate to `react-context-menu 2.9.2` ([#1081](https://github.com/Comcast/react-data-grid/pull/1081)) +- **Breaking:** Migrate to `react-contextmenu` 2.9.2 ([#1081](https://github.com/Comcast/react-data-grid/pull/1081)) diff --git a/README.md b/README.md index d2c6715295..5ae46de833 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,12 @@ The DataGrid component is designed to handle large datasets efficiently while offering a rich set of features for customization and interactivity. -## Table of contents +## Table of Contents - [Features](#features) - [Links](#links) - [Installation](#installation) -- [Getting started](#getting-started) +- [Getting Started](#getting-started) - [Styling and Customization](#styling-and-customization) - [API Reference](#api-reference) @@ -25,7 +25,7 @@ The DataGrid component is designed to handle large datasets efficiently while of - Great performance thanks to virtualization: columns and rows outside the viewport are not rendered - Strictly typed with TypeScript - [Keyboard accessibility](https://comcast.github.io/react-data-grid/#/CommonFeatures) -- Light and dark mode support out of the box via `color-scheme`. +- Light and dark mode support out of the box via `color-scheme` - [Frozen columns](https://comcast.github.io/react-data-grid/#/CommonFeatures): Freeze columns to keep them visible during horizontal scrolling. - [Column resizing](https://comcast.github.io/react-data-grid/#/CommonFeatures) - [Multi-column sorting](https://comcast.github.io/react-data-grid/#/CommonFeatures) @@ -40,10 +40,10 @@ The DataGrid component is designed to handle large datasets efficiently while of - [No rows fallback](https://comcast.github.io/react-data-grid/#/NoRows) - [Cell formatting](https://comcast.github.io/react-data-grid/#/CommonFeatures) - [Cell editing](https://comcast.github.io/react-data-grid/#/CommonFeatures) -- [Cell copy / pasting](https://comcast.github.io/react-data-grid/#/AllFeatures) +- [Cell copying / pasting](https://comcast.github.io/react-data-grid/#/AllFeatures) - [Cell value dragging / filling](https://comcast.github.io/react-data-grid/#/AllFeatures) -- [Customizable Renderers](https://comcast.github.io/react-data-grid/#/CustomizableRenderers) -- Right-to-left (RTL) support. +- [Customizable renderers](https://comcast.github.io/react-data-grid/#/CustomizableRenderers) +- Right-to-left (RTL) support ## Links @@ -77,17 +77,17 @@ import 'react-data-grid/lib/styles.css'; `react-data-grid` is published as ECMAScript modules for evergreen browsers, bundlers, and server-side rendering. > **Important** -> Vite 8+ by default uses `lightningcss` to minify css which has a [bug minifying light-dark syntax](https://github.com/parcel-bundler/lightningcss/issues/873). You can tweak the `cssMinify` or `cssTarget` [settings](https://main.vite.dev/config/build-options) as a workaround. +> Vite 8+ uses Lightning CSS by default to minify CSS, and Lightning CSS has a [bug minifying the `light-dark()` syntax](https://github.com/parcel-bundler/lightningcss/issues/873). You can tweak the `cssMinify` or `cssTarget` [settings](https://vite.dev/config/build-options) as a workaround. ```ts build: { - cssMinify: 'esbuild', + cssMinify: 'esbuild', // requires the `esbuild` package to be installed // or cssTarget: 'esnext' } ``` -## Getting started +## Getting Started Here is a basic example of how to use `react-data-grid` in your React application: @@ -218,7 +218,7 @@ Apply custom CSS classes to rows using the [`rowClass`](#rowclass-mayberow-r-row #### Cell Classes -Apply custom CSS classes to cells using the [`cellClass`](#cellclass-maybestring--row-trow--maybestring) property in column definitions. You can also use [`headerCellClass`](#headercellclass-maybestring) and [`summaryCellClass`](#summarycellclass-maybestring--row-tsummaryrow--maybestring) for header and summary cells respectively. +Apply custom CSS classes to cells using the [`cellClass`](#cellclass-maybestring--row-trow--maybestring) property in column definitions. You can also use [`headerCellClass`](#headercellclass-maybestring) and [`summaryCellClass`](#summarycellclass-maybestring--row-tsummaryrow--maybestring) for header and summary cells, respectively. #### Column Widths @@ -244,7 +244,7 @@ An array of column definitions and/or column groups. See the [`ColumnOrColumnGro ###### `rows: readonly R[]` -An array of rows, the rows data can be of any type. +An array of rows. The row data can be of any type. :bulb: **Performance:** The grid is optimized for efficient rendering: @@ -254,7 +254,7 @@ An array of rows, the rows data can be of any type. - **Best practice**: When updating rows, create a new array but reuse unchanged row objects. For example: ```tsx - // ✅ Good: Only changed row is re-rendered + // ✅ Good: Only the changed row is re-rendered setRows(rows.map((row, idx) => (idx === targetIdx ? { ...row, updated: true } : row))); // ❌ Avoid: Creates new references for all rows, causing all visible rows to re-render @@ -298,7 +298,7 @@ function MyGrid() { } ``` -:bulb: While optional, setting this prop is recommended for optimal performance as the returned value is used to set the `key` prop on the row elements. +:bulb: While optional, setting this prop is recommended for optimal performance, as the returned value is used to set the `key` prop on the row elements. :warning: **Performance:** Define this function outside your component or memoize it with `useCallback` to prevent unnecessary re-renders. @@ -365,7 +365,7 @@ Height of each summary row in pixels. ###### `columnWidths?: Maybe` -A map of column widths containing both measured and resized widths. If not provided then an internal state is used. +A map of column widths containing both measured and resized widths. If not provided, an internal state is used. ```tsx const [columnWidths, setColumnWidths] = useState((): ColumnWidths => new Map()); @@ -381,7 +381,7 @@ return void>` -Callback triggered when column widths change. If not provided then an internal state is used. +Callback triggered when column widths change. If not provided, an internal state is used. ###### `selectedRows?: Maybe>` @@ -397,7 +397,7 @@ Callback triggered when the selection changes. ```tsx import { useState } from 'react'; -import { DataGrid, SelectColumn } from 'react-data-grid'; +import { DataGrid, SelectColumn, type Column } from 'react-data-grid'; const rows: readonly Row[] = [...]; @@ -442,7 +442,7 @@ Callback triggered when sorting changes. ```tsx import { useState } from 'react'; -import { DataGrid, SelectColumn } from 'react-data-grid'; +import { DataGrid, type Column, type SortColumn } from 'react-data-grid'; const rows: readonly Row[] = [...]; @@ -469,7 +469,7 @@ function MyGrid() { } ``` -More than one column can be sorted via `ctrl (command) + click`. To disable multiple column sorting, change the `onSortColumnsChange` function to +More than one column can be sorted via Ctrl+Click (Cmd+Click on macOS). To disable multi-column sorting, change the `onSortColumnsChange` function to: ```tsx function onSortColumnsChange(sortColumns: SortColumn[]) { @@ -516,17 +516,7 @@ function onCellMouseDown(args: CellMouseArgs, event: CellMouseEvent) { Callback triggered when a cell is clicked. -```tsx -function onCellClick(args: CellMouseArgs, event: CellMouseEvent) { - if (args.column.key === 'id') { - event.preventGridDefault(); - } -} - -; -``` - -This event can be used to open cell editor on single click +This event can be used to open the cell editor on a single click: ```tsx function onCellClick(args: CellMouseArgs, event: CellMouseEvent) { @@ -534,6 +524,8 @@ function onCellClick(args: CellMouseArgs, event: CellMouseEvent) { args.setActivePosition(true); } } + +; ``` ###### `onCellDoubleClick?: CellMouseEventHandler` @@ -567,7 +559,7 @@ function onCellContextMenu(args: CellMouseArgs, event: CellMouseEvent) { ###### `onCellKeyDown?: Maybe<(args: CellKeyDownArgs, event: CellKeyboardEvent) => void>` -A function called when keydown event is triggered on a cell. This event can be used to customize cell navigation and editing behavior. +Callback triggered when a key is pressed in a cell. This event can be used to customize cell navigation and editing behavior. **Examples** @@ -591,7 +583,7 @@ function onCellKeyDown(args: CellKeyDownArgs, event: CellKeyboardEvent) { } ``` -Check [more examples](website/routes/CellNavigation.tsx) +See [more examples](website/routes/CellNavigation.tsx). ###### `onCellCopy?: Maybe<(args: CellCopyArgs, NoInfer>, event: CellClipboardEvent) => void>` @@ -605,7 +597,7 @@ Return the updated row; the grid will call `onRowsChange` with it. ###### `onActivePositionChange?: Maybe<(args: PositionChangeArgs) => void>` -Triggered when the active position changes. +Callback triggered when the active position changes. See the [`PositionChangeArgs`](#positionchangeargstrow-tsummaryrow) type in the Types section below. @@ -617,7 +609,7 @@ Native DOM `onScroll` prop. ###### `onColumnResize?: Maybe<(column: CalculatedColumn, width: number) => void>` -Callback triggered when column is resized. +Callback triggered when a column is resized. ###### `onColumnsReorder?: Maybe<(sourceColumnKey: string, targetColumnKey: string) => void>` @@ -718,7 +710,7 @@ Custom class name for the header row. ###### `direction?: Maybe<'ltr' | 'rtl'>` -This property sets the text direction of the grid, it defaults to `'ltr'` (left-to-right). Setting `direction` to `'rtl'` has the following effects: +This property sets the text direction of the grid. It defaults to `'ltr'` (left-to-right). Setting `direction` to `'rtl'` has the following effects: - Columns flow from right to left - Start-frozen columns are pinned on the right, and end-frozen columns are pinned on the left @@ -739,11 +731,11 @@ ARIA role for the grid container. Defaults to `grid`. ###### `'aria-label'?: string | undefined` -The label of the grid. We recommend providing a label using `aria-label` or `aria-labelledby` +The label of the grid. We recommend providing a label using `aria-label` or `aria-labelledby`. ###### `'aria-labelledby'?: string | undefined` -The id of the element containing a label for the grid. We recommend providing a label using `aria-label` or `aria-labelledby` +The id of the element containing a label for the grid. We recommend providing a label using `aria-label` or `aria-labelledby`. ###### `'aria-rowcount'?: number | undefined` @@ -757,7 +749,7 @@ If the grid has a caption or description, `aria-describedby` can be set on the g ###### `'data-testid'?: Maybe` -This prop can be used to add a testid for testing. We recommend querying the grid by its `role` and `name`. +This prop can be used to add a test ID for testing. We recommend querying the grid by its `role` and `name`. ```tsx function MyGrid() { @@ -789,7 +781,7 @@ Optional attribute to help with Cypress (or similar) selectors. **Keyboard Navigation:** - → (Right Arrow): Expand a collapsed group row when focused -- ← (Left Arrow): Collapse an expanded group row when focused, or navigate to parent group +- ← (Left Arrow): Collapse an expanded group row when focused, or navigate to the parent group **Unsupported Props:** @@ -884,7 +876,7 @@ Function to generate unique IDs for group rows. If not provided, a default imple ###### `rowHeight?: Maybe) => number)>` -**Note:** Unlike `DataGrid`, the `rowHeight` function receives [`RowHeightArgs`](#rowheightargstrow) which includes a `type` property to distinguish between regular rows and group rows: +**Note:** Unlike `DataGrid`, the `rowHeight` function receives [`RowHeightArgs`](#rowheightargstrow), which includes a `type` property to distinguish between regular rows and group rows: ```tsx function getRowHeight(args: RowHeightArgs): number { @@ -1083,13 +1075,13 @@ Renders a checkbox input with proper styling and accessibility. **Props:** -- `checked: boolean` - Whether the checkbox is checked -- `indeterminate?: boolean` - Whether the checkbox is in indeterminate state +- `checked?: boolean` - Whether the checkbox is checked +- `indeterminate?: boolean` - Whether the checkbox is in an indeterminate state - `disabled?: boolean` - Whether the checkbox is disabled - `onChange: (checked: boolean, shift: boolean) => void` - Change handler -- `tabIndex: number` - Tab index for keyboard navigation +- `tabIndex?: number` - Tab index for keyboard navigation - `aria-label?: string` - Accessible label -- `aria-labelledby?: string` - ID of labeling element +- `aria-labelledby?: string` - ID of the labeling element **Example:** @@ -1105,7 +1097,7 @@ import { DataGrid, renderCheckbox } from 'react-data-grid'; #### `renderToggleGroup(props: RenderGroupCellProps)` -The default group cell renderer used by the columns used for grouping (`groupBy` prop). This renders the expand/collapse toggle. +The default group cell renderer for the columns used for grouping (`groupBy` prop). This renders the expand/collapse toggle. ##### Props @@ -1185,7 +1177,7 @@ function AppProvider({ children }) { #### `SelectColumn: Column` A pre-configured column for row selection. -Includes checkbox renderers for header, regular rows, and grouped rows. +Includes checkbox renderers for the header row, regular rows, and group rows. **Example:** @@ -1235,13 +1227,13 @@ The name of the column. Displayed in the header cell by default. ##### `key: string` -A unique key to distinguish each column +A unique key to distinguish each column. ##### `width?: Maybe` -**Default** `auto` +**Default:** `auto` -Width can be any valid css grid column value. If not specified, it will be determined automatically based on grid width and specified widths of other columns. +Width can be any valid CSS grid column value. If not specified, it will be determined automatically based on grid width and specified widths of other columns. ```tsx const columns: Column[] = [ @@ -1279,7 +1271,7 @@ width: 'minmax(100px, max-content)', ##### `minWidth?: Maybe` -**Default**: `50` pixels +**Default:** `50` pixels Minimum column width in pixels. @@ -1313,7 +1305,7 @@ const columns: Column[] = [ } .status-inactive { - color: grey; + color: gray; } .text-right { @@ -1339,7 +1331,7 @@ Render function to render the content of the header cell. ##### `renderSummaryCell?: Maybe<(props: RenderSummaryCellProps) => ReactNode>` -Render function to render the content of summary cells +Render function to render the content of summary cells. ##### `renderGroupCell?: Maybe<(props: RenderGroupCellProps) => ReactNode>` @@ -1347,7 +1339,7 @@ Render function to render the content of group cells when using `TreeDataGrid`. ##### `renderEditCell?: Maybe<(props: RenderEditCellProps) => ReactNode>` -Render function to render the content of edit cells. When set, the column is automatically set to be editable +Render function to render the content of edit cells. When set, the column is automatically set to be editable. ##### `editable?: Maybe boolean)>` @@ -1378,11 +1370,11 @@ const columns: readonly Column[] = [ ##### `frozen?: Maybe` -**Default**: `false` +**Default:** `false` Determines whether the column is frozen, and on which edge. Frozen columns stay in place when the grid is scrolled horizontally. -- `'start'` (or `true` for backwards compatibility) — pins the column to the start edge (left in LTR, right in RTL). +- `'start'` (or `true` for backward compatibility) — pins the column to the start edge (left in LTR, right in RTL). - `'end'` — pins the column to the end edge (right in LTR, left in RTL). - `false` (default) — the column scrolls with the rest of the grid. @@ -1396,27 +1388,27 @@ const columns: readonly Column[] = [ ##### `resizable?: Maybe` -**Default**: `false` +**Default:** `false` -Enable resizing of the column +Enable resizing of the column. ##### `sortable?: Maybe` -**Default**: `false` +**Default:** `false` -Enable sorting of the column +Enable sorting of the column. ##### `draggable?: Maybe` -**Default**: `false` +**Default:** `false` -Enable dragging of the column +Enable dragging of the column. ##### `sortDescendingFirst?: Maybe` -**Default**: `false` +**Default:** `false` -Sets the column sort order to be descending instead of ascending the first time the column is sorted +Sets the column sort order to be descending instead of ascending the first time the column is sorted. ##### `editorOptions` @@ -1424,19 +1416,19 @@ Options for cell editing. ###### `displayCellContent?: Maybe` -**Default**: `false` +**Default:** `false` Render the cell content in addition to the edit cell content. Enable this option when the editor is rendered outside the grid, like a modal for example. ###### `commitOnOutsideClick?: Maybe` -**Default**: `true` +**Default:** `true` Commit changes when clicking outside the cell. ###### `closeOnExternalRowChange?: Maybe` -**Default**: `true` +**Default:** `true` Close the editor when the row value changes externally. @@ -1481,7 +1473,7 @@ Extends `Column` with additional computed properties used internally by the grid - `idx: number` - The column index - `level: number` - Nesting level when using column groups - `parent: CalculatedColumnParent | undefined` - Parent column group if nested -- Multiple Column properties have their values set to their default value +- Some `Column` properties, like `width`, `minWidth`, `resizable`, and `renderCell`, are resolved to their default values when not set #### `CalculatedColumnParent` @@ -1726,7 +1718,7 @@ Returns whether `preventGridDefault` was called. ```tsx import type { CellMouseArgs, CellMouseEvent } from 'react-data-grid'; -function onCellClick(args: CellMouseArgs, event: CellMouseEvent) { +function onCellMouseDown(args: CellMouseArgs, event: CellMouseEvent) { if (args.column.key === 'actions') { event.preventGridDefault(); // Prevent cell focus } @@ -1887,7 +1879,7 @@ type SortDirection = 'ASC' | 'DESC'; #### `RowsChangeData` -Data provided to `onRowsChange` callback. +Data provided to the `onRowsChange` callback. ```tsx interface RowsChangeData { @@ -1937,7 +1929,7 @@ Used with the `onFill` prop to handle cell value dragging. #### `GroupRow` (internal) -Represents a grouped row in `TreeDataGrid`. This helper type is not exported; the shape is shown for reference. +Represents a group row in `TreeDataGrid`. This helper type is not exported; the shape is shown for reference. ```tsx interface GroupRow { @@ -1966,7 +1958,7 @@ interface ColumnWidth { } ``` -Used with `columnWidths` and `onColumnWidthsChange` props to control column widths externally. +Used with the `columnWidths` and `onColumnWidthsChange` props to control column widths externally. #### `Position` @@ -1996,11 +1988,11 @@ Props for custom checkbox renderers. ```tsx interface RenderCheckboxProps { - checked: boolean; + checked?: boolean; indeterminate?: boolean; disabled?: boolean; onChange: (checked: boolean, shift: boolean) => void; - tabIndex: number; + tabIndex?: number; 'aria-label'?: string; 'aria-labelledby'?: string; } @@ -2053,7 +2045,7 @@ interface DataGridHandle { ```tsx import { useRef } from 'react'; -import { DataGrid, DataGridHandle } from 'react-data-grid'; +import { DataGrid, type DataGridHandle } from 'react-data-grid'; function MyGrid() { const gridRef = useRef(null); @@ -2086,7 +2078,7 @@ type DefaultColumnOptions = Pick< #### `Direction` -Grid layout bidirectionality. +Text direction of the grid. ```tsx type Direction = 'ltr' | 'rtl'; diff --git a/src/Cell.tsx b/src/Cell.tsx index 8f631cb607..5513db63a2 100644 --- a/src/Cell.tsx +++ b/src/Cell.tsx @@ -65,7 +65,7 @@ function Cell({ function handleMouseDown(event: MouseEvent) { onMouseDown?.(event); if (!handleMouseEvent(event, onCellMouseDown)) { - // select cell if the event is not prevented + // activate the cell if the event is not prevented setActivePositionWrapper(); } } diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 018f6c4983..9dc7f66952 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -114,11 +114,11 @@ type SharedDivProps = Pick< export interface DataGridProps extends SharedDivProps { ref?: Maybe>; /** - * Grid and data Props + * Grid and data props */ /** An array of column definitions */ columns: readonly ColumnOrColumnGroup, NoInfer>[]; - /** A function called for each rendered row that should return a plain key/value pair object */ + /** An array of rows, which can be of any type */ rows: readonly R[]; /** Rows pinned at the top of the grid for summary purposes */ topSummaryRows?: Maybe; @@ -139,12 +139,12 @@ export interface DataGridProps extends Sha rowHeight?: Maybe) => number)>; /** * Height of the header row in pixels - * @default 35 + * @default `rowHeight` when it is a number, otherwise 35 */ headerRowHeight?: Maybe; /** * Height of each summary row in pixels - * @default 35 + * @default `rowHeight` when it is a number, otherwise 35 */ summaryRowHeight?: Maybe; /** A map of column widths */ @@ -193,7 +193,7 @@ export interface DataGridProps extends Sha >; /** Function called whenever the active position is changed */ onActivePositionChange?: Maybe<(args: PositionChangeArgs, NoInfer>) => void>; - /** Callback triggered when column is resized */ + /** Callback triggered when a column is resized */ onColumnResize?: Maybe<(column: CalculatedColumn, width: number) => void>; /** Callback triggered when columns are reordered */ onColumnsReorder?: Maybe<(sourceColumnKey: string, targetColumnKey: string) => void>; @@ -224,7 +224,7 @@ export interface DataGridProps extends Sha } /** - * Main API Component to render a data grid of rows and columns + * Main API component to render a data grid of rows and columns * * @example * @@ -233,7 +233,7 @@ export interface DataGridProps extends Sha export function DataGrid(props: DataGridProps) { const { ref, - // Grid and data Props + // Grid and data props columns: rawColumns, rows, topSummaryRows, @@ -492,11 +492,11 @@ export function DataGrid(props: DataGridPr ); /** - * The identity of the wrapper function is stable so it won't break memoization + * The identity of the wrapper function is stable, so it won't break memoization */ const handleColumnResizeLatest = useLatestFunc(handleColumnResize); const handleColumnResizeEndLatest = useLatestFunc(handleColumnResizeEnd); - const onColumnsReorderLastest = useLatestFunc(onColumnsReorder); + const onColumnsReorderLatest = useLatestFunc(onColumnsReorder); const onSortColumnsChangeLatest = useLatestFunc(onSortColumnsChange); const onCellMouseDownLatest = useLatestFunc(onCellMouseDown); const onCellClickLatest = useLatestFunc(onCellClick); @@ -726,7 +726,7 @@ export function DataGrid(props: DataGridPr } function handleDragHandlePointerMove(event: React.PointerEvent) { - // find dragged over row using the pointer position + // find the dragged-over row using the pointer position const gridEl = gridRef.current!; const headerAndTopSummaryRowsHeight = headerRowsHeight + topSummaryRowsCount * summaryRowHeight; const offset = @@ -807,7 +807,7 @@ export function DataGrid(props: DataGridPr const row = rows[position.rowIdx]; setActivePosition({ ...position, mode: 'EDIT', row, originalRow: row }); } else if (samePosition) { - // Avoid re-renders if the selected cell state is the same + // Avoid re-renders if the active position is the same scrollIntoView(getCellToScroll(gridRef.current!)); } else { const newPosition: ActivePosition = { ...position, mode: 'ACTIVE' }; @@ -837,7 +837,7 @@ export function DataGrid(props: DataGridPr case 'ArrowUp': { const nextRowIdx = rowIdx - 1; return { - // avoid selecting header rows + // avoid focusing header rows idx: idx === -1 && nextRowIdx < -topSummaryRowsCount ? 0 : idx, rowIdx: nextRowIdx }; @@ -847,7 +847,7 @@ export function DataGrid(props: DataGridPr case leftKey: { const nextIdx = idx - 1; return { - // avoid selecting header rows + // avoid focusing header rows idx: rowIdx < -topSummaryRowsCount && nextIdx < 0 ? 0 : nextIdx, rowIdx }; @@ -857,11 +857,11 @@ export function DataGrid(props: DataGridPr case 'Tab': return { idx: idx + (shiftKey ? -1 : 1), rowIdx }; case 'Home': - // If row is selected then move focus to the first header row's cell. + // If the active position is a row, move focus to the first header row's cell. if (activePositionIsRow || ctrlKey) return { idx: 0, rowIdx: minRowIdx }; return { idx: 0, rowIdx }; case 'End': - // If row is selected then move focus to the last row. + // If the active position is a row, move focus to the last row. if (activePositionIsRow) return { idx, rowIdx: maxRowIdx }; return { idx: maxColIdx, rowIdx: ctrlKey ? maxRowIdx : rowIdx }; case 'PageUp': { @@ -1057,10 +1057,9 @@ export function DataGrid(props: DataGridPr function onRowChange(row: R, commitChanges: boolean, shouldFocus: boolean) { if (commitChanges) { - // Prevents two issues when editor is closed by clicking on a different cell - // - // Otherwise commitEditorChanges may be called before the cell state is changed to - // SELECT and this results in onRowChange getting called twice. + // Prevents an issue when the editor is closed by clicking on a different cell: + // otherwise, commitEditorChanges may be called before the cell state is changed to + // ACTIVE, which results in onRowChange getting called twice. flushSync(() => { updateRow(column, activePosition.rowIdx, row); closeEditor(shouldFocus); @@ -1122,7 +1121,7 @@ export function DataGrid(props: DataGridPr } return renderRow(key, { - // aria-rowindex is 1 based + // aria-rowindex is 1-based 'aria-rowindex': headerAndTopSummaryRowsCount + rowIdx + 1, 'aria-selected': isSelectable ? isRowSelected : undefined, rowIdx, @@ -1174,8 +1173,8 @@ export function DataGrid(props: DataGridPr aria-multiselectable={isSelectable ? true : undefined} aria-colcount={columns.length} aria-rowcount={ariaRowCount} - // Scrollable containers without tabIndex are keyboard focusable in Chrome only if there is no focusable element inside - // whereas they are always focusable in Firefox. We need to set tabIndex to have a consistent behavior across browsers. + // Scrollable containers without tabIndex are keyboard focusable in Chrome only if there is no focusable element inside, + // whereas they are always focusable in Firefox. We need to set tabIndex to have consistent behavior across browsers. tabIndex={-1} className={classnames(rootClassname, isDragging && viewportDraggingClassname, className)} style={{ @@ -1219,7 +1218,7 @@ export function DataGrid(props: DataGridPr iterateOverViewportColumnsForRow={iterateOverViewportColumnsForRow} onColumnResize={handleColumnResizeLatest} onColumnResizeEnd={handleColumnResizeEndLatest} - onColumnsReorder={onColumnsReorderLastest} + onColumnsReorder={onColumnsReorderLatest} sortColumns={sortColumns} onSortColumnsChange={onSortColumnsChangeLatest} activeCellIdx={ diff --git a/src/EditCell.tsx b/src/EditCell.tsx index bf5b234a4a..56c2362057 100644 --- a/src/EditCell.tsx +++ b/src/EditCell.tsx @@ -13,14 +13,14 @@ import type { /* * To check for outside `mousedown` events, we listen to all `mousedown` events at their birth, - * i.e. on the window during the capture phase, and at their death, i.e. on the window during the bubble phase. + * i.e., on the window during the capture phase, and at their death, i.e., on the window during the bubble phase. * * We schedule a check at the birth of the event, cancel the check when the event reaches the "inside" container, * and trigger the "outside" callback when the event bubbles back up to the window. * - * The event can be `stopPropagation()`ed halfway through, so they may not always bubble back up to the window, - * so an alternative check must be used. The check must happen after the event can reach the "inside" container, - * and not before it run to completion. `postTask`/`requestAnimationFrame` are the best way we know to achieve this. + * The event can be `stopPropagation()`ed halfway through, so it may not always bubble back up to the window, + * and an alternative check must be used. The check must happen after the event can reach the "inside" container, + * and not before it has run to completion. `postTask`/`requestAnimationFrame` are the best way we know to achieve this. * Usually we want click event handlers from parent components to access the latest committed values, * so `mousedown` is used instead of `click`. * @@ -72,7 +72,7 @@ export default function EditCell({ // We need to prevent the `useLayoutEffect` from cleaning up between re-renders, // as `onWindowCaptureMouseDown` might otherwise miss valid mousedown events. - // To that end we instead access the latest props via useEffectEvent. + // To that end, we instead access the latest props via useEffectEvent. const commitOnOutsideMouseDown = useEffectEvent(() => { onClose(true, false); }); @@ -128,7 +128,7 @@ export default function EditCell({ }; }, [commitOnOutsideClick]); - // TODO: report react compiler bug + // TODO: report React Compiler bug // oxlint-disable-next-line react/invariant function cancelTask() { captureEventRef.current = undefined; diff --git a/src/GroupedColumnHeaderRow.tsx b/src/GroupedColumnHeaderRow.tsx index 191664af09..af101e9428 100644 --- a/src/GroupedColumnHeaderRow.tsx +++ b/src/GroupedColumnHeaderRow.tsx @@ -49,7 +49,7 @@ function GroupedColumnHeaderRow({ return (
{cells} diff --git a/src/HeaderCell.tsx b/src/HeaderCell.tsx index a81d2310f1..9b41d5cc7e 100644 --- a/src/HeaderCell.tsx +++ b/src/HeaderCell.tsx @@ -105,7 +105,7 @@ export default function HeaderCell({ const dragImageRef = useRef(null); const isDragging = draggedColumnKey === column.key; const rowSpan = getHeaderCellRowSpan(column, rowIdx); - // set the tabIndex to 0 when there is no active cell so grid can receive focus + // set the tabIndex to 0 when there is no active cell so the grid can receive focus const { tabIndex, childTabIndex, onFocus } = useRovingTabIndex(shouldFocusGrid || isCellActive); const sortIndex = sortColumns?.findIndex((sort) => sort.columnKey === column.key); const sortColumn = @@ -166,7 +166,7 @@ export default function HeaderCell({ function handleFocus(event: React.FocusEvent) { onFocus?.(event); if (shouldFocusGrid) { - // Select the first header cell if there is no active cell + // Activate the first header cell if there is no active cell setPosition({ idx: 0, rowIdx }); } } diff --git a/src/HeaderRow.tsx b/src/HeaderRow.tsx index 79fffb9d8f..ba71ef5dad 100644 --- a/src/HeaderRow.tsx +++ b/src/HeaderRow.tsx @@ -94,7 +94,7 @@ function HeaderRow({ return (
({ if (!isGroupRow(row)) return; if ( idx === -1 && - // Collapse the current group row if it is focused and is in expanded state + // Collapse the current group row if it is focused and expanded ((event.key === leftKey && row.isExpanded) || - // Expand the current group row if it is focused and is in collapsed state + // Expand the current group row if it is focused and collapsed (event.key === rightKey && !row.isExpanded)) ) { // prevent scrolling diff --git a/src/hooks/useActivePosition.ts b/src/hooks/useActivePosition.ts index f02ba4dad1..e814b698dc 100644 --- a/src/hooks/useActivePosition.ts +++ b/src/hooks/useActivePosition.ts @@ -51,7 +51,7 @@ export function useActivePosition({ * Returns whether the given position represents a valid cell or row position in the grid. * Active bounds: any valid position in the grid * Viewport: any valid position in the grid outside of header rows and summary rows - * Row selection is only allowed in TreeDataGrid + * Row positions are only allowed in TreeDataGrid */ function validatePosition({ idx, rowIdx }: Position) { // check column position @@ -135,7 +135,7 @@ export function useActivePosition({ useLayoutEffect(() => { // Layout effects clean up when the component is replaced by a suspense fallback, - // or when under , then re-mounts when the suspense boundary cleans, + // or when under , then re-mount when the suspense boundary resolves, // or when Activity switches back to `mode="visible"`. // So we use a ref to: // 1. avoid re-focusing after the effect re-mounts diff --git a/src/hooks/useCalculatedColumns.ts b/src/hooks/useCalculatedColumns.ts index 34c2910eb2..7f19cd8f3a 100644 --- a/src/hooks/useCalculatedColumns.ts +++ b/src/hooks/useCalculatedColumns.ts @@ -283,7 +283,7 @@ export function useCalculatedColumns({ while (colVisibleEndIdx < lastColIdx) { const { left, width } = columnMetrics.get(columns[colVisibleEndIdx])!; // if the right side of the column is beyond or equal to the right side of the available viewport, - // then it the last column that's at least partially visible, as the previous column's right side is not beyond the viewport. + // then it is the last column that's at least partially visible, as the previous column's right side is not beyond the viewport. if (left + width >= viewportRight) { break; } diff --git a/src/hooks/useGridDimensions.ts b/src/hooks/useGridDimensions.ts index 789dcd4edc..576b3234c9 100644 --- a/src/hooks/useGridDimensions.ts +++ b/src/hooks/useGridDimensions.ts @@ -68,7 +68,7 @@ export function useGridDimensions(gridRef: React.RefObject { // ref.current is null during the initial render, when suspending, or in . - // We use ref as key instead to access stable values regardless of rendering state. + // We use the ref as the key instead to access stable values regardless of the rendering state. return sizeMap.get(gridRef) ?? initialSize; }, [gridRef]); diff --git a/src/hooks/useLatestFunc.ts b/src/hooks/useLatestFunc.ts index 1397202a01..ab98301d07 100644 --- a/src/hooks/useLatestFunc.ts +++ b/src/hooks/useLatestFunc.ts @@ -2,7 +2,7 @@ import { useCallback, useLayoutEffect, useRef } from 'react'; import type { Maybe } from '../types'; -// https://reactjs.org/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often +// https://legacy.reactjs.org/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often // oxlint-disable-next-line typescript/no-explicit-any export function useLatestFunc any>>(fn: T): T { const ref = useRef(fn); diff --git a/src/hooks/useRovingTabIndex.ts b/src/hooks/useRovingTabIndex.ts index 555921c4ce..9e69c73537 100644 --- a/src/hooks/useRovingTabIndex.ts +++ b/src/hooks/useRovingTabIndex.ts @@ -10,7 +10,7 @@ export function useRovingTabIndex(isActive: boolean) { } function onFocus(event: React.FocusEvent) { - // Do not steal focus if event originates from a focusable child + // Do not steal focus if the event originates from a focusable child if (event.target === event.currentTarget) { const elementToFocus = event.currentTarget.querySelector( '[tabindex="0"]' diff --git a/src/hooks/useScrollState.ts b/src/hooks/useScrollState.ts index 8bb48a4f10..d2db5f6171 100644 --- a/src/hooks/useScrollState.ts +++ b/src/hooks/useScrollState.ts @@ -56,9 +56,9 @@ export function useScrollState(gridRef: React.RefObject): ); const getSnapshot = useCallback((): ScrollState => { - // gridRef.current is null during initial render, suspending, or - // to avoid returning a different state in those cases, - // we key the ref object instead of the element itself + // gridRef.current is null during the initial render, when suspending, or in . + // To avoid returning a different state in those cases, + // we key the ref object instead of the element itself. return scrollStateMap.get(gridRef) ?? initialScrollState; }, [gridRef]); diff --git a/src/hooks/useViewportColumns.ts b/src/hooks/useViewportColumns.ts index 6418370934..27ceefda2b 100644 --- a/src/hooks/useViewportColumns.ts +++ b/src/hooks/useViewportColumns.ts @@ -99,7 +99,7 @@ export function useViewportColumns({ ]); // Effective inclusive upper bound for overscan in the unfrozen band. - // When end-frozen columns exist, unfrozen band ends just before them. + // When end-frozen columns exist, the unfrozen band ends just before them. const effectiveOverscanEndIdx = firstEndFrozenColumnIndex > -1 ? min(colOverscanEndIdx, firstEndFrozenColumnIndex - 1) @@ -128,7 +128,7 @@ export function useViewportColumns({ } } - // Always yield end-frozen tail (virtualization must keep these in the DOM) + // Always yield the end-frozen tail (virtualization must keep these in the DOM) if (firstEndFrozenColumnIndex > -1) { for (let colIdx = firstEndFrozenColumnIndex; colIdx < columns.length; colIdx++) { yield columns[colIdx]; diff --git a/src/hooks/useViewportRows.ts b/src/hooks/useViewportRows.ts index 13b8502302..0af33ae1be 100644 --- a/src/hooks/useViewportRows.ts +++ b/src/hooks/useViewportRows.ts @@ -28,8 +28,8 @@ export function useViewportRows({ }; } - // Calcule the height of all the rows upfront. This can cause performance issues - // and we can consider using a similar approach as react-window + // Calculate the height of all the rows upfront. This can cause performance issues, + // and we can consider using a similar approach to react-window // https://github.com/bvaughn/react-window/blob/b0a470cc264e9100afcaa1b78ed59d88f7914ad4/src/VariableSizeList.js#L68 let totalRowHeight = 0; let gridTemplateRows = ''; diff --git a/src/style/core.ts b/src/style/core.ts index e2e0280c31..3f192b0ae3 100644 --- a/src/style/core.ts +++ b/src/style/core.ts @@ -41,7 +41,7 @@ const root = css` accent-color: light-dark(hsl(207deg 100% 29%), hsl(207deg 100% 79%)); - /* https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context */ + /* https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Stacking_context */ /* We set a stacking context so internal elements don't render on top of external elements. */ /* size containment is not used as it could break "width: min-content" for example, and the grid would infinitely resize on Chromium browsers */ contain: content; diff --git a/src/types.ts b/src/types.ts index bfbea5270d..5dcf3e313a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -43,11 +43,11 @@ export interface Column { readonly renderGroupCell?: Maybe<(props: RenderGroupCellProps) => ReactNode>; /** Render function to render the content of edit cells. When set, the column is automatically set to be editable */ readonly renderEditCell?: Maybe<(props: RenderEditCellProps) => ReactNode>; - /** Enables cell editing. If set and no editor property specified, then a textinput will be used as the cell editor */ + /** Control whether cells can be edited with `renderEditCell` */ readonly editable?: Maybe boolean)>; readonly colSpan?: Maybe<(args: ColSpanArgs) => Maybe>; - /** Determines whether column is frozen, and on which edge. - * `true` is an alias for `'start'` for backwards compatibility. */ + /** Determines whether the column is frozen, and on which edge. + * `true` is an alias for `'start'` for backward compatibility. */ readonly frozen?: Maybe; /** Enable resizing of the column */ readonly resizable?: Maybe; @@ -95,7 +95,7 @@ export interface CalculatedColumn extends Column { - /** The name of the column group, it will be displayed in the header cell */ + /** The name of the column group. It will be displayed in the header cell */ readonly name: string | ReactElement; readonly headerCellClass?: Maybe; readonly children: readonly ColumnOrColumnGroup[]; diff --git a/src/utils/frozenColumnUtils.ts b/src/utils/frozenColumnUtils.ts index f3d41767a0..6e88ecb222 100644 --- a/src/utils/frozenColumnUtils.ts +++ b/src/utils/frozenColumnUtils.ts @@ -1,6 +1,6 @@ import type { ColumnFrozen } from '../types'; -// Shared predicate — `frozen: true` is the backwards-compatible alias for `frozen: 'start'`. +// Shared predicate — `frozen: true` is the backward-compatible alias for `frozen: 'start'`. export function isStartFrozen(frozen: ColumnFrozen): boolean { return frozen === true || frozen === 'start'; } diff --git a/src/utils/index.ts b/src/utils/index.ts index a77cc18d90..16b787884c 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -25,7 +25,7 @@ export function clampColumnWidth( ): number { width = max(width, minWidth); - // ignore maxWidth if it less than minWidth + // ignore maxWidth if it is less than minWidth if (typeof maxWidth === 'number' && maxWidth >= minWidth) { return min(width, maxWidth); } diff --git a/src/utils/keyboardUtils.ts b/src/utils/keyboardUtils.ts index a8d5ebf732..9b0683875c 100644 --- a/src/utils/keyboardUtils.ts +++ b/src/utils/keyboardUtils.ts @@ -1,7 +1,7 @@ import type { Direction, Maybe } from '../types'; import { isElement } from './domUtils'; -// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values +// https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values const nonInputKeys = new Set([ // Special keys 'Unidentified', @@ -55,8 +55,8 @@ export function isCtrlKeyHeldDown(e: React.KeyboardEvent): boolean { return (e.ctrlKey || e.metaKey) && e.key !== 'Control'; } -// event.key may differ by keyboard input language, so we use event.keyCode instead -// event.nativeEvent.code cannot be used either as it would break copy/paste for the DVORAK layout +// event.key may differ by keyboard input language, so we use event.keyCode instead. +// event.nativeEvent.code cannot be used either, as it would break copy/paste for the Dvorak layout. const vKey = 86; export function isDefaultCellInput( @@ -72,7 +72,7 @@ export function isDefaultCellInput( * By default, the following navigation keys are enabled while an editor is open, under specific conditions: * - Tab: * - The editor must be an , a