Changelog
Minor Changes
Section titled “Minor Changes”- Upgrade the underlying spreadsheet engine (Apiary) to 17.0.0, which brings pivot table support and replaces transient writes with explicit value snapshots. As a result of the value-snapshot change,
ProxiedCell.isModifiedState(and its_vfield) can no longer be derived and have been removed. - Add insertCells (shift down / shift right) with a right-click context menu and Ctrl++ keyboard shortcut, complementing delete cells.
- Add a download XLSX button to the editor toolbar
- Render row and column headers on the Mondrian canvas instead of in the DOM. The DOM header strips become invisible interaction shells that keep their geometry, test IDs, and handlers, while the labels, gridlines, and corner are painted as part of Mondrian’s single render pass. This removes a duplicate rendering path and keeps the header labels in sync with the canvas after fast scrolls. Header dimensions now derive from Mondrian’s font size (≈18×25px at font size 11).
- Add an
autoFocusoption to focus the spreadsheet when it mounts, plus afocus()method on the editor controller to focus the spreadsheet programmatically.focus()accepts an optional cell reference (e.g.focus("Sheet1!A4")) to move the selection — switching sheets when the reference names one — before taking focus. - Add deleteCells (shift up / shift left) with a right-click context menu and Ctrl+- keyboard shortcut. Cut / Copy / Paste and row / column delete are also available from the new cell context menu.
Patch Changes
Section titled “Patch Changes”-
Update @biomejs/biome to 2.5.1 and reformat SCSS to match its stricter checks. Also fixes two bugs found along the way:
headerlayer.module.scssusedcolor.adjust(..., vars.$lightness: -5%), an invalid namespaced keyword argument, silently skipping the intended darkened background on hover/read-only-selected column and row headers.- Biome’s automatic property-sort fix moved
@include reset.resetButton();after explicit property overrides in four components (toolbar option buttons, the formatting menu item button, and the modal’s confirm/cancel buttons), so the mixin’s reset styles were clobbering the intended padding/margin. Restored the mixin to run first and pinned that order against future auto-formatting.
-
Simplify scroll handling by removing the scroll-position debounce: the canvas now paints synchronously from scroll events and clicks hit-test against the live scroll position, keeping selection and rendering in sync with scrolling.
-
Pin the cell canvas max/min width so host-page CSS resets can’t shrink it below the painted size, which was misaligning column headers from the cells.
-
Update dependencies: @jsfkit/types 2.4.0 → 2.5.0, lucide-react 1.16.0 → 1.21.0, sass 1.100.0 → 1.101.0, @types/react 19.2.15 → 19.2.17, and the build/test toolchain (vite, vitest, tsdown, @playwright/test, @vitejs/plugin-react).
-
Update dependencies: React 19.2.6 (react and react-dom), lucide-react 1.11.0 → 1.16.0, @jsfkit/types 2.2.0 → 2.4.0, postcss 8.5.14 → 8.5.15, sass 1.98.0 → 1.100.0, and the build/test toolchain (vite, vitest, tsdown, @playwright/test, @vitejs/plugin-react).
-
Keep the selection glued to the grid while scrolling. The selection overlay is translated to follow the synchronously painted canvas between React commits; on commit the translate was blanked to zero, which stranded the overlay a frame behind the cells whenever a newer scroll event had already moved the canvas past the committed position. The commit now re-derives the translate from the live scroll offset, so the selection tracks the grid frame-for-frame. Most visible on full-row/full-column selections, whose viewport-spanning borders made the lag obvious.
Also make the performance cap on full-row/full-column selection boxes symmetric, leaving off-screen slack on every side instead of only the trailing edge.
-
Simplify how the editor handles scrolling. No change to how the editor behaves.
-
Update @grid-is/mondrian to 2.0.1, removing a workaround for a rendering type mismatch that mondrian 2.0.1 fixes upstream.
-
Cell coordinate calculations now share a single source of truth with the canvas renderer, preventing alignment drift between the grid and selection, header, and editing overlays.
-
Clamp the scrollable area to the interactive bounds. The scrollable area was slightly larger than the part of the sheet you can interact with, so a scroll could land past the content. The scrollable area now matches the interactive bounds.
-
Update @tsdown/css to 0.22.3 to match the already-updated tsdown version, and hoist postcss-modules to the workspace root so tsdown can resolve it at build time.
Minor Changes
Section titled “Minor Changes”- Upgrade to @grid-is/apiary 16 and @grid-is/mondrian 2.
- Make keyboard navigation aware of merged cells
- Upgrade to jsfkit/types v2 with structured Color objects, apiary 16, and mondrian 1.14
- Export all editor event interfaces (
WriteCellEvent,PasteEvent, etc.) from the package - Add tab cycling within a selected range
- Add mergeAnchor property to Selection for merged cell anchor rendering
- Handle shift+arrow contraction near merged cells
Patch Changes
Section titled “Patch Changes”- Bump vite from 7.3.1 to 8.0.2
- Update @grid-is/apiary to 16.1.0.
- Bump @jsfkit/types from 2.0.0 to 2.2.0
- Bump tsdown from 0.19.0 to 0.21.10
- Bump @vitejs/plugin-react from 5.2.0 to 6.0.1
- Remove leftover eslint-disable directives (ESLint is not used in this project)
- Bump lucide-react from 0.563.0 to 1.11.0
- Bump sass from 1.97.3 to 1.98.0
- Persist and restore sheet selection when switching between sheets
- Bump jsdom from 27.4.0 to 29.0.1
- Remove prop-types dependency
- Remove unused ts-morph dependency
- Set explicit build target to fix esbuild 0.27.7 compatibility with vite-plugin-top-level-await
- Bump vite from 7.3.1 to 7.3.2
Minor Changes
Section titled “Minor Changes”- Programmatically navigate to any cell or range, including switching sheets, from outside the editor.
- The onChange callback now receives structured editor events, letting embedding apps react to specific user actions like cell edits, formatting changes, sheet additions, and more.
Patch Changes
Section titled “Patch Changes”- Include documentation on the @grid-is/editor-react public API (auto-generated from JSDoc)
- Fix formula references merging when dragging one over another
- Add
showErrorTooltipsprop to display an error tooltip when a cell containing a formula error is selected
Minor Changes
Section titled “Minor Changes”- CSS is now auto-injected into the ESM bundle — ESM consumers no longer need to import
@grid-is/editor-react/editor-styles.cssseparately. CJS consumers should continue importing it manually. - Remove Roboto Mono from the editor. The
robotoMonoUrlprop has been removed fromFontConfig. The formula bar and cell inputs fall back to the system monospace font stack.
Patch Changes
Section titled “Patch Changes”- Fix function docs and picker staying visible after committing a formula edit
Minor Changes
Section titled “Minor Changes”- Add initialSelection prop to SpreadsheetEditor and scroll it into view
- Replace
configprop with directfontConfigprop on SpreadsheetEditor - Add formula reference highlighting on cell selection
- Remove
useApiaryEditorhook and acceptModeldirectly onSpreadsheetEditor - Replace
boundsConfighook option with asizeprop onSpreadsheetEditor.
Patch Changes
Section titled “Patch Changes”-
Isolate editor styles from consumer CSS with defensive resets and scoped class selectors
-
Add documentation site with guides and API reference (https://docs.grid.is/editor/)
-
Fix scroll feedback loop causing jerky scrolling
-
Use modular
string.quoteto fix Sass deprecation warning for globalquote()function -
Upgrade @grid-is/apiary to ^15.3.1 and remove vite-plugin-node-polyfills
-
Remove xlsx-convert as a direct dependency, use apiary’s built-in conversion instead
-
Sheet tab bar redesign to match mondrian-react viewer. Adding a matching fx icon to the formula bar as well as polishing hover states, button alignments, dropdown behavior and documents statistics footer.
-
Fix Editor not reflecting changes made directly to Apiary model outside Editor methods. Consumers can update model directly, but UI stayed stale because Editor never detected external modifications.
Editor now listens to Apiary recalc events and updates internal state when model changes occur outside Editor interface.