Skip to content

Let editable columns be filled and pasted into without renderEditCell - #4269

Draft
nstepien wants to merge 3 commits into
mainfrom
breaking/editable-without-editor
Draft

nstepien wants to merge 3 commits into
mainfrom
breaking/editable-without-editor

Conversation

@nstepien

Copy link
Copy Markdown
Collaborator

Column.editable now means what its name says: it decides whether a cell's value can change through the grid, by drag-filling and pasting, and whether the cell is aria-readonly. renderEditCell only decides whether an editor can open. Until now both required renderEditCell, so a column whose cells change through their own renderCell content, like a checkbox or a dropdown, couldn't be filled or pasted into without a fake editor (#3116). The default doesn't change: without editable, a column is editable when it has renderEditCell.

Supersedes #3862, which made the same change on a smaller scale.

Breaking change

// 7.0: fillable and pasteable with no editor. Before: read-only, `editable` had no effect without `renderEditCell`
{ key: 'available', name: 'Available', renderCell: AvailableCheckbox, editable: true }

editable no longer requires renderEditCell. A column with editable: true and no editor is drag-fillable and pasteable, shows the drag handle when onFill is set, and isn't aria-readonly. Columns without editable behave as before: editable only when renderEditCell is set.

Semantics

"Editor" covers typing, Enter, double-click, and setActivePosition(position, { enableEditor: true }), which all go through the same check. "Fill" covers the drag handle on the active cell and the target cells. "Read-only" covers aria-readonly="true" and RenderCellContentProps.isCellEditable: false. Changes are in bold.

Column Editor Fill Paste Read-only
no editable, renderEditCell opens yes yes no
no editable, no renderEditCell no no no yes
editable: true, renderEditCell opens yes yes no
editable: true, no renderEditCell no yes (was no) yes (was no) no (was yes)
editable: false, any renderEditCell no no no yes
function editable, renderEditCell opens on rows where it's true targets where it's true; handle only where it's true (was shown on every row) rows where it's true rows where it's false
function editable, no renderEditCell no rows where it's true (was no) rows where it's true (was no) rows where it's false (was every row)

Tests for each changed row:

  • editable: true, no renderEditCell: dragFill.test.tsx "should allow dragFill on an editable column without renderEditCell", copyPaste.test.tsx "should allow paste on editable cells without renderEditCell", and column/renderEditCell.test.tsx "should not open an editor on an editable column without renderEditCell", which types, presses Enter, double-clicks, and calls setActivePosition with enableEditor, and checks aria-readonly and isCellEditable.
  • Function editable, renderEditCell: dragFill.test.tsx "should not show the drag handle on a cell whose editable function returns false".
  • Function editable, no renderEditCell: dragFill.test.tsx "should only fill the editable cells of a column without renderEditCell", the function column in the paste test above, and column/renderEditCell.test.tsx "should set aria-readonly and isCellEditable from editable without renderEditCell".
  • The unchanged rows without renderEditCell are checked alongside: "should not show the drag handle on a column that is not editable" (no editable, and editable: () => false), and the read-only columns in the paste and aria-readonly tests.

Changes

  • isCellEditableUtil resolves editable for the row when it's set, and falls back to renderEditCell != null otherwise. A new canOpenEditorUtil adds the renderEditCell != null check, and DataGrid routes typing, Enter, double-click, and enableEditor through it, so keyboard input on an editable cell without an editor does nothing. Both are pure and don't allocate. The plan called the helper canOpenEditor; it's canOpenEditorUtil to match isCellEditableUtil, with a canOpenEditor(position) wrapper in DataGrid like isCellEditable(position).
  • The drag handle now uses isCellEditableUtil instead of renderEditCell == null || editable === false, which ignored a function editable. The existing "should allow drag up using mouse" test dragged from a cell whose editable function returns false; it now drags from the editable cell above it.
  • RenderCellContentProps.isCellEditable follows the new semantics, so a column with editable: true and no editor reports true to its content renderer, which can enable its own controls to match.
  • JSDoc and README: editable, renderEditCell, onFill, onCellPaste, onCellDoubleClick, and RenderCellContentProps.isCellEditable, plus a short editable example.
  • Demo: the "Available" checkbox column in CommonFeatures is editable: true. That demo had no onFill, so it gets one too, which also lets its columns with editors be drag-filled.

Verification

vp run ci passes. vp test on dragFill, copyPaste, and column/renderEditCell passes in Chromium, Firefox, and WebKit. With src/ restored to main, the new tests fail; with only the enableEditor path left ungated, the editor test fails at its setActivePosition step. vp pack compiles every component. The public types don't change, only their JSDoc. I didn't check the demo by hand with vp dev.

🤖 Generated with Claude Code

nstepien and others added 2 commits October 27, 2026 19:54
`editable` now decides whether a cell can be filled, pasted into, and is
`aria-readonly`, and defaults to whether `renderEditCell` is set. The
editor only opens on editable cells of columns with `renderEditCell`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…editable`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented Oct 27, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.27%. Comparing base (5e7977b) to head (28a83c0).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4269   +/-   ##
=======================================
  Coverage   99.27%   99.27%           
=======================================
  Files          44       44           
  Lines        2204     2210    +6     
  Branches      965      968    +3     
=======================================
+ Hits         2188     2194    +6     
  Misses         16       16           
Files with missing lines Coverage Δ
src/DataGrid.tsx 99.45% <100.00%> (+<0.01%) ⬆️
src/utils/activePositionUtils.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants