Skip to content
GRID Editor

Changelog

  • selectCells, focus(ref) and highlightRefs scroll only as far as needed to show the cells, and not at all when they are already in view. selectCells(ref, "center") centers them as before.

    The last row and column can scroll fully into view.

    In core, setSelection takes reveal: "minimal" next to "center", and reveal_selection carries the mode.

  • Require @grid-is/apiary 18.1.0 or newer as a peer dependency

  • Add controller.overlays for host-owned DOM on cells

  • Bump lucide-react from 1.48.0 to 1.52.0
  • Use light style for Editor scroll bars in dark mode
  • Bump dependencies: @grid-is/fontstack 3.0.2, lucide-react 1.48.0
  • Bump postcss-modules from 6.0.1 to 9.0.1
  • Require @grid-is/apiary 18 as a peer dependency
  • Move the editor’s controller type into editor-types as SpreadsheetController, so the viewer can implement the same interface. SpreadsheetEditorController is renamed to SpreadsheetController and is no longer marked experimental.
  • Bump postcss-import from 16.1.1 to 17.0.0
  • Only load fonts when fontConfig.baseUrl is set

    The editor used to default to loading fonts when no fontConfig was given. The editor now makes no attempt to load fonts unless explicitly asked to do so.

  • Bump Mondrian sheet renderer to v2.3.0. This renders drawing placeholders and row styles in the editor.

  • Rewrite the npm package description to say what the editor does.
  • Load Calibri only when fontFilter allows it
  • SelectionNavigator now moves and resizes a selection on its own: move, moveToEdge, extend, extendToEdge, moveActiveCell and collapse, within the bounds and edges provided.
  • Declare @grid-is/apiary as a peer dependency with the range ^17.1.0. Consumers that also depend on Apiary now resolve a single engine copy and own its version.
  • Move the merged-cells index into editor core. The engine bridge owns an engine-backed index exposed as Editor.getMergedCells() and the MergedCells class is exported from core; the React package reads the index from the editor instead of building and threading its own copy through props.
  • Show scroll arrows in the sheet tab bar when there are more sheets than fit the available space
  • Use shareable keyboard shortcuts library from @grid-is/editor-kit
  • Fix cell menu submenus opening far above their menu item when the editor is embedded lower on the page
  • Merge-aware selection navigation (SelectionNavigator and MergedCells) now lives in @grid-is/editor-kit.
  • Update dependencies: lucide-react 1.21.0 → 1.26.0, react/react-dom 19.2.6 → 19.2.8, and the build/test toolchain (vite, vitest, tsdown, @tsdown/css, sass, postcss, @playwright/test, @vitejs/plugin-react, @testing-library/jest-dom, @biomejs/biome, @changesets/cli).
  • Read cell formatting straight from the engine instead of through the legacy cell proxy
  • Centralize merged-cell selection handling in editor core. The editor now normalizes every selection and a new SelectionNavigator provides merge-aware keyboard navigation. The react layer no longer carries any merged-cell logic.
  • Add merge / unmerge cell action to the formatting panel.
  • Surface engine refusals as interventions instead of silent failures or crashes. Headless callers can observe refusals via editor.onIntervention() or the return value of the move methods.
  • Selections no longer depend on the spreadsheet engine. Their ranges are now SelectionRange instances, which keep a subset of the Apiary Range properties.
  • Bump dependencies: @borgar/fx 5.1.1, @grid-is/mondrian 2.1.0, @jsfkit/types 2.6.0, lucide-react 1.34.0
  • Trap focus in the modal while it is open, close it on Escape even when the grid has focus, and refresh its visual style
  • 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 _v field) 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 autoFocus option to focus the spreadsheet when it mounts, plus a focus() 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.
  • 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.scss used color.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.

  • 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
  • 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
  • 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.
  • Include documentation on the @grid-is/editor-react public API (auto-generated from JSDoc)
  • Fix formula references merging when dragging one over another
  • Add showErrorTooltips prop to display an error tooltip when a cell containing a formula error is selected
  • CSS is now auto-injected into the ESM bundle — ESM consumers no longer need to import @grid-is/editor-react/editor-styles.css separately. CJS consumers should continue importing it manually.
  • Remove Roboto Mono from the editor. The robotoMonoUrl prop has been removed from FontConfig. The formula bar and cell inputs fall back to the system monospace font stack.
  • Fix function docs and picker staying visible after committing a formula edit
  • Add initialSelection prop to SpreadsheetEditor and scroll it into view
  • Replace config prop with direct fontConfig prop on SpreadsheetEditor
  • Add formula reference highlighting on cell selection
  • Remove useApiaryEditor hook and accept Model directly on SpreadsheetEditor
  • Replace boundsConfig hook option with a size prop on SpreadsheetEditor.
  • 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.quote to fix Sass deprecation warning for global quote() 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.