Feat/resize columns - #350
Draft
mir4a wants to merge 48 commits into
Draft
Conversation
if it's being resized too much (below it's min width which is 40px)
✅ Deploy Preview for react-datasheet-grid canceled.
|
apparently shifted by 2px resize handles to the right caused horizontal scroll in outerRef to appear
tdonkena
approved these changes
May 15, 2024
maxkuzmin
reviewed
May 16, 2024
|
|
||
| .dsg-resize-handle:hover { | ||
| cursor: col-resize; | ||
| background: rgba(0, 0, 250, 0.75); |
There was a problem hiding this comment.
it should use --dsg-selection-border-color var instead of hardcoded color
maxkuzmin
reviewed
May 16, 2024
| > Type: `({ widths: Array<number | undefined>) => void`<br /> | ||
| > Default: `void` | ||
|
|
||
| If provided, the grid will became resizable. This callback is called when the user resizes a column. |
There was a problem hiding this comment.
I think we need to have additional boolean flag which enables resizing. One would use resizing without need for handling it.
maxkuzmin
reviewed
May 16, 2024
| Called when the selection changes. Called with null when the grid is blurred. | ||
|
|
||
| ### onColumnsResize | ||
| > Type: `({ widths: Array<number | undefined>) => void`<br /> |
|
@nick-keller Can this get reviewed and merged please, this has been open for 2 months |
chinonso-opti
approved these changes
Jul 30, 2024
abubakir1997
approved these changes
Jan 13, 2026
rodrigoescandon
added a commit
to rodrigoescandon/react-datasheet-grid
that referenced
this pull request
Aug 5, 2026
Root cause of the earlier JS-driven approaches (98f4543, f3168a2): any scroll-event-driven positioning -- even one that bypasses React and writes a CSS var straight to the DOM -- still runs on the main thread in response to a dispatched 'scroll' event. On macOS momentum/fast-wheel scrolling the compositor paints frames faster than the main thread can dispatch and handle those events, so the sticky-left cells' visual position could render a frame (or several) behind the actual scrollLeft, producing visible drift/vanish/snap-back under fast scrolling. Fix: make sticky-left cells (gutter + pinned data columns) real in-flow `position: sticky` elements again, pinned by the browser's compositor with no JS involved in the scroll path at all -- categorically immune to the main-thread-lag failure mode, not just less prone to it. This requires solving the original blocker from PR nick-keller#386: .dsg-row is a plain block container, and in-flow sticky cells (unlike ordinary cells, which are position: absolute and therefore out of flow) stack vertically under block layout -- one row-height per sticky cell -- which is what broke PR nick-keller#386 for N > 1 pinned columns in the first place. Fix layout instead of abandoning sticky: 1. src/style.css: `.dsg-row { display: flex }`. Ordinary cells are position: absolute and therefore not flex items at all -- completely unaffected. The in-flow sticky cells (gutter, sticky-left, sticky-right) become flex items on one horizontal line instead of stacking. 2. src/components/Grid.tsx: fixed a latent DOM-order bug in the column virtualizer's rangeExtractor. It force-includes sticky column indices via repeated `result.unshift(stickyCol)` in an ascending loop, which builds the array in DESCENDING order (each unshift lands in front of the last) whenever those columns fall outside the naturally-virtualized range (i.e. once scrolled past them). That was harmless when sticky-left cells were position: absolute (DOM order didn't affect visual position, see f3168a2) but would render pinned columns in reverse visual order under flex. Now collects the missing indices and unshifts them together to preserate ascending order. 3. src/style.css: sticky cells get `left: col.start` (unchanged, still set inline per-cell in Cell.tsx) plus `flex: none` to keep their exact measured width regardless of available flex-line space. col.start for a sticky column is the cumulative width of columns 0..i-1, which -- since the sticky set is always the contiguous range starting at 0 -- is exactly the cumulative width of the *prior sticky columns*, precisely what `position: sticky`'s `left` needs. 4. src/style.css: removed `.dsg-cell-sticky-right`'s `transform: translateY(-100%)`. That hack compensated for exactly two in-flow children (gutter, sticky-right) stacking vertically under block layout; under flex, in-flow children lay out horizontally on one line, so the vertical stacking it compensated for no longer happens and the transform would now be actively wrong. 5. src/components/Grid.tsx, src/style.css: removed the --dsg-sticky-x custom-property/transform mechanism (and the onScroll handler that drove it) entirely -- no longer needed now that positioning is native CSS sticky. 6. src/style.css: gave `.dsg-cell-sticky-left` its own border-right/border-bottom (using --dsg-border-color) instead of relying on the shared box-shadow trick ordinary cells use to draw grid lines -- that trick depends on the two cells' edges staying pixel- aligned as the grid scrolls, which doesn't hold for a sticky cell with an opaque background sitting over a non-sticky neighbor. This was previously patched only in the consumer app's CSS (base-de-datos-grid/packages/payload-grid-view); folded the same fix into the fork so the engine is correct standalone. Verified in the consumer app (base-de-datos-grid, Directorio, 5391 rows, stickyLeftColumnNumber={2}): gutter + open-record arrow + Nombre stay rock-solid pinned and opaque through rapid back-and-forth horizontal scrolling, scrolling to the far right, and vertical scrolling while horizontally offset (rows 51-74 checked) -- both light and dark themes. Column resize (PR nick-keller#350) still works and correctly reflows the sticky layout. npm test: 100/100 (one paste.test.tsx case flaked once under full- suite timing pressure -- an act()-wrapping warning unrelated to this change -- and passed both in isolation and on a full-suite rerun). - src/components/Grid.tsx: rangeExtractor DOM-order fix; dropped handleScroll/--dsg-sticky-x wiring, onScroll passed through directly. - src/style.css: .dsg-row display: flex; .dsg-cell-sticky-left/-right/ -gutter position: sticky with flex: none; sticky-left border-right/ -bottom; removed --dsg-sticky-x var and sticky-right's translateY hack. - dist/: rebuilt (npm run build). - package.json: version -> 4.11.6-grid.4. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds possibility to resize columns with with two callbacks: for tracking resize (dragging) and resize end useful for storing which columns were resized. Stored values then can be passed as a property so that after reloading the page the table will restore touched column widths.
What is done:
If you would like to test it out right away, you can try my fork published on npm:
npm i @mir4a/react-datasheet-grid@4.12.0-alpha.15 --save-exact.