Repository navigation
Releases: arpitarya/sheetpane
Release list
v0.5.1 — contributing, security and conduct docs; no change to the packages
The package code is the same as 0.5.0. The repository is ready for outside
contributors.
npm i @sheetpane/grid@0.5.1Before you upgrade from 0.5.0: nothing to change.
Added
- The repository:
CONTRIBUTING.md,SECURITY.mdandCODE_OF_CONDUCT.md. The README gains a plain-words section, who sheetpane is for, a roadmap and an FAQ, and says that 0.5.0 is on npm.
v0.5.0 — the grid edits like Excel: in the cell, fill handle, drop to open
@sheetpane/grid now edits in the cell, has a fill handle, and opens a file
dropped on the sheet. Menus and pop-up cards are never cut off. Every other
package is unchanged apart from the version.
npm i @sheetpane/grid@0.5.0Before you upgrade from 0.4.x: Enter, F2 and typing now open an editor
in the cell instead of focusing the cell bar. A test that expected the cell
bar's input to take focus should look for [data-sp="cell-editor"].
Added
@sheetpane/grid: editing in the cell. Typing, Enter, F2 or a double press opens an editor on the cell that grows with its text, and the cell bar keeps the same draft. Enter after a run of Tabs returns to the first column. Arrows commit when you started by typing. Ctrl/⌘+Enter fills the whole range.@sheetpane/grid: the fill handle. Drag the selection's corner to continue a series (numbers, text ending in a number, formulas with shifted references), with the last value shown while dragging; Ctrl/⌘ swaps series and copy. Double-click it to fill down beside the data. Ctrl+D / Ctrl+R copy down and right. Each fill is one undo step throughsheetpane-beforechange.@sheetpane/grid: drop a file on the sheet to open it, with an overlay that names the changes it would replace.
Fixed
@sheetpane/grid: menus and pop-up cards are never cut off or covered (law L13). Every one is shown on top of the page (a popover), inside the viewport. It moves in from the edges, opens above its cell near the bottom, and scrolls inside when it is too tall. Esc now closes the keyboard help.- The demos: All plugins now turns on every plugin (law L12), including visibility, tables, compare and review. A test fails when a new plugin is missing from either demo.
@sheetpane/grid: an insert right of the last column or below the last row did nothing visible. The grid now grows by what was inserted, so the new column appears and you can type in it.
Changed
@sheetpane/grid: Enter, F2 and typing now edit in the cell instead of moving focus to the cell bar. A test that expected the cell bar's input to take focus should look for[data-sp="cell-editor"]; the bar's value is the same draft. A right-click inside a range keeps it. The grid's focus ring shows after Tab only.
v0.4.2 — every package published by CI with provenance; no change to the packages
The package code is the same as 0.4.0 and 0.4.1. All 20 packages now trust
the release workflow, so this version of each — @sheetpane/tables,
review and compare included, whose 0.4.0 was published by hand — comes
from CI with signed provenance.
npm i @sheetpane/grid@0.4.2Before you upgrade from 0.4.1: nothing to change.
v0.4.1 — the playground deploys with each release; no change to the packages
The package code is the same as 0.4.0. This release puts all 20 packages on
one version again through CI alone, and is the first whose release tag also
deploys the live playground.
npm i @sheetpane/grid@0.4.1Before you upgrade from 0.4.0: nothing to change.
Release and tooling
- The live playground (https://arpitarya.github.io/sheetpane/) deploys on a release tag again: the
github-pagesenvironment allowed the branchmainonly, so every tag's deploy had been refused; it now allowsv*(SR-BUILD decision 8). RELEASING.mdcounts 20 packages and describes a new package's first publish as it is done:pnpm publishin its folder, approved in the browser, then the release's publish job re-run.- For contributors: the fux docs index (
fux.toml,.fux/) over the records,work/anddocs/(SR-BUILD decision 1a).
v0.4.0 — results, review layers, insert and delete rows, Excel tables and three new plugins
The features a host's review flow needs from a spreadsheet, built together
(W-50–W-69): results as well as faults, several sets of errors in one pane,
errors about a whole sheet or workbook, accepted deviations, an Edits view,
host data in an error card; insert and delete rows and columns with every
reference shifted; rich text, Excel tables, dependent dropdowns, locked cells
and protection; dropdowns and conditional formats written into downloads; the
pane's checks and a static HTML render in Node; and three new plugins —
@sheetpane/tables, @sheetpane/review (the review as its own sheet)
and @sheetpane/compare (what changed between two versions). Law L11 is
new: the workbook never leaves the browser.
npm i @sheetpane/grid@0.4.0
npm i @sheetpane/tables@0.4.0 @sheetpane/review@0.4.0 @sheetpane/compare@0.4.0 # the new plugins, as neededBefore you upgrade from 0.3.0:
Severityhas two more values,passandskipped: code that switches
exhaustively onseveritymust handle them (isResult(e)tells a result
from a problem).SheetpaneError.rangemay be""(the whole sheet), andsheettoo (the
workbook): code that readsrangeas A1 should useerrorScope(e).statusmay beaccepted: count open errors asstatus === 'open', not
!== 'resolved'.WorkbookStore.setErrors(list, options?, origin?):originmoved from the
second argument to the third. The elements'setErrorsare unchanged.- A plugin's
derivereceives a third input kind,restructure: a provider
that narrowed onloadalone must also handle it (return the whole derived
set). - The
sheetpane-errorsdetail is now the envelopev: 2
({ v, errors, plugins, layers, changed }); a review saved before still
restores. - In Edit mode
<sheetpane-errors>always shows its Problems · Edits switch.
Added
- Law L11 — the workbook never leaves the browser (SR-LAW-11). sheetpane reads, edits, checks and exports a file inside the page and sends nothing to any server: no file bytes, cells, edits, errors, exports or telemetry. Its only network calls are the GETs for the
srcandrules-srcthe host sets. A test intest/packages.test.tsfails if any package adds another. Thesheetpane-backend,sheetpane-load-exportandsheetpane-securityskills now say that a server save is the host's own code and choice. - Two new severities:
passandskipped(not checked) — results as well as faults (W-50; SR-ERRORS, SR-GRID). A host or a plugin'svalidatecan report a passed cell and a cell it did not check; av: 1review without them loads as before. A host that switches exhaustively onseveritymeets two more values —isResult(e)tells a result from a problem. Results stay quiet: the newresultsattribute (on either element, pane-wide) issummaryby default — one line of counts in<sheetpane-errors>(1 problem · ✓ 180 passed · — 28 not checked · On sheet), Passed / Not checked chips, passes grouped by check and not-checked cells by reason, nothing on the sheet and 186 of 214 checked in the status line;marks(or the panel's On sheet switch) adds a 9 px ✓ or — in each result cell's bottom-left corner (new token--sp-skip);offdrops results on arrival. Tab counts, the toolbar counts, n open and the severity filters count problems only.@sheetpane/commentswrites results into a download only withexport({ includeResults: true }). @sheetpane/grid: review layers (W-51). Every error has alayer(reviewunless named).setErrors(list, { layer })replaces that layer only, keeping the others and the undo stack;getErrors({ layer })reads one. Alayersattribute and property on either element chooses the layers shown — the pane's one setting — and<sheetpane-errors>shows a switch (All, then each layer with its open count; names fromlayerNames) when the pane has two or more. The sheet's pins, marks, counts and tab counts, the list and the comments export follow what is shown; a person's new error goes into the layer shown. Avalidatedraft may name alayer. New:sheetpane-layers {visible, layers},setVisibleLayers(),snapshot.layers,visibleLayersandvisibleErrors,layerOf(),isLayerName(),DEFAULT_LAYER, theErrorsEnvelopetype and SP-3021 (a name that is not one).@sheetpane/comments: an export writes the errors of the layers shown;export({ layers: [...] })names another set (W-51).sheetpane-errorscarries the review envelopev: 2(W-51):{ v, errors, plugins, layers, changed }, and every error in it has alayer. Save the wholedetailand give it back withsetErrors(saved); a review saved before ({ errors, plugins }, or a bare list) restores into thereviewlayer as before.@sheetpane/grid: errors with no cell (W-55).range: ""is an error about the whole sheet;sheet: ""withrange: "", about the whole workbook.<sheetpane-errors>lists them first, in a Workbook group and then one group per sheet, above the cell errors. A whole-sheet error counts on its tab, and Show in sheet opens that tab. For a workbook-level error the button is disabled and says why. Neither kind is placed on A1, gets a pin or marks a cell. New:errorScope(e)(cell,sheetorworkbook) and theErrorScopetype.@sheetpane/comments: an error with no cell is not written as an Excel comment, because a comment needs a cell.lastExport.skippedlists it withreason: 'no-cell'and the new code SP-5804.@sheetpane/grid: room for the host in an error (W-68).SheetpaneError.metaholds any JSON of the host's, up to 64 KiB (ERROR_META_MAX). It is saved and restored with the error and never written into the file.renderDetail(error), a new property on<sheetpane-excel>(the error card) and<sheetpane-errors>(the open row), returns a string, a Node ornull. The result is drawn after the message in::part(detail), and the hook runs again only when that error changes. A string is shown as text, never as HTML. New: theErrorMetaandRenderDetailtypes, and the codes SP-3016 (ametathat is not JSON or is over the cap is dropped; the error is kept) and SP-3017 (renderDetailthrew; nothing is shown).@sheetpane/grid: accepted deviations (W-69). An error'sstatusmay now beaccepted, withacceptedBy,acceptedAtand a requiredreason: a known, approved difference that stays in the review and the download but is not counted as open. Accept… in an open row of<sheetpane-errors>asks why and records the element'sauthoras who; an Accepted n chip lists them, and the severity chips, "n open" and the sheet's counts leave them out. In the sheet the pin reads A and the error card shows who, when and why, with Reopen. Undo and Reopen take an acceptance back. New:workbook.acceptError(id, reason, { by }), theErrorStatustype, and the code SP-3018 (a blank reason, or an error the workbook itself wrote, is not accepted; restored without a reason, it comes back open). Code that counted open errors asstatus !== 'resolved'should usestatus === 'open'.@sheetpane/comments: an accepted error gets one more reply in its thread, Accepted: , written by who accepted it, and its thread is marked done (W-69).@sheetpane/grid: the Edits view (W-64).<sheetpane-errors>gets an Edits n chip beside Problems: every change in the pane, newest first — the cell or range and kind, was → now, the time, and links to the errors that edit cleared or raised. Picking a row selects its cell. Revert on a row and Revert all are each one undo step. It shows in Edit mode, and in View mode while the pane holds edits; in Edit mode the panel now always shows the Problems · Edits switch. New on the store:edits(),editEffects(key)({ cleared, raised, matched }) andrevertEdits(keys?); new exportseditRef,EditandEditEffects.- Insert and delete rows and columns, with every reference shifted (W-52; SR-GRID decision 21d, SR-EXPORT decision 11, SR-IMPORT decision 14).
@sheetpane/grid: in Edit, the cell menu, the ⋯ menu and the header menu insert rows above or below and columns left or right, and delete them; Ctrl/⌘+Shift+= and Ctrl/⌘+− do it from the keyboard. The store gainsinsertRows,deleteRows,insertCols,deleteCols,structureRefusal(op)andstructureOps(): one change of kindstructureand one undo step each, andsheetpane-changecarries{ kind: 'structure', op, at, count }. Cell changes, errors (an error whose cells were deleted is resolved, "row deleted"), derived values, merges, freeze, hidden and outline state, the selection, sizes and highlights move with their rows. Refused, as Excel refuses: a delete that splits a merged range (SP-3022), anything that moves a pivot table or its source (SP-3023), cells pushed off the sheet (SP-3024), a table cut (SP-3025). A plugin'sderiveis told{ kind: 'restructure', sheet, op, at, count }— a thirdDeriveInputkind: a provider that narrowed onloadalone must now also handle it (it returns the whole derived set, as on a load).@sheetpane/import:restructureWorkbook(book, op)moves every table of the imported workbook, the chart partspart()serves included;PivotTable.sourcenames a pivot's worksheet source.@sheetpane/export:patchXlsx(…, { structure })replays the operations on the upload first — rows and cells, formulas on every sheet, merges, column spans, the autofilter, validations, conditional formats, hyperlinks, the sheet view, tables, drawing anchors, notes and their VML, threaded comments, chart series and defined names — and refuses (SP-2016) to move a pivot or cut a table or array formula.restructureFormula,shiftRefText,shiftSqrefand the other shifts are exported for plu...
v0.3.0 — CI in about two minutes; no change to the packages
The package code is the same as 0.1.0 and 0.2.0; this release changes how
sheetpane is checked and published. It is the first version meant to
reach npm from CI, through publish.yml with signed provenance.
npm i @sheetpane/grid@0.3.0Before you upgrade from 0.1.0: sheetpane needs Node 22 or later
wherever it runs in Node (0.2.0's change). Browsers are unaffected.
Release and tooling
- CI runs its jobs in parallel: typecheck, coverage, the pack check
and demos, the three-OS matrix, the templates, and the test suite in
four shards balanced by measured time. The pnpm store and Chromium are
cached. publish.ymlasks npm about every package before uploading any. It
prints npm's reason for each refusal, so a release is never left half on
npm.- Release titles say what the release is (
v0.3.0 — …), taken from
the CHANGELOG heading. - A test helper that took 117 s now takes 0.3 s: the TSDoc check reads
each declaration file once. - Every GitHub Action moved to its current major.
v0.2.0 — the release pipeline and Node 22+, never on npm
Released on GitHub only. Its publish run stopped before uploading
anything: no package on npm trusted publish.yml yet. Install
0.3.0, which
has the same package code, or 0.1.0.
Before you upgrade: sheetpane now needs Node 22 or later wherever it
runs in Node: SSR imports, tests, the MCP server, the CLIs. Node 20 is past
end of life. Browsers are unaffected.
Release and tooling
- Published from CI only, with provenance. A GitHub Release runs
publish.yml, which publishes nothing unless CI is green on that commit,
every version site agrees, and the tag matches the packages. It builds once,
checks each tarball (nosrc/, no tests, README and LICENSE present) and
publishes over npm trusted publishing (OIDC): no token, with signed
provenance. SeeRELEASING.md. - CI on Linux, macOS and Windows × Node 22 and the current LTS. Each run
installs the built tarballs into an empty folder and imports every package
from plain Node. @sheetpane/mcpon Windows:explain_codereturns the full entry
(cause, meaning, fix) whenERRORS.mdhas CRLF line endings.- MIT
LICENSEin every package.
The package code is 0.1.0's; its Changed and Added lists are under
0.1.0.
v0.1.0 — the first cut, published to npm by hand
On npm. Published from the v0.1.0 tag by hand, the one version that
did not come from CI. CI at the tag passed every test and all six
templates; the only failure was a stale generated llms-full.txt.
The first complete cut of sheetpane, 17 packages at one version:
<sheetpane-excel>and<sheetpane-errors>(@sheetpane/grid): open,
edit and review.xlsxand.csvin the page. The sheet and its error
list stay in sync through one in-memory workbook. Download hands back the
original file with only your changes written in.- Review: column rules, a JSON rules file and the workbook's own
validation, with errors flagged on cells and listed beside the sheet. - Editing basics: range selection, copy and paste, undo and redo, find,
zoom, freeze panes, resize, and hidden rows, columns and sheets, with a
dark theme. - Nine plugins:
numfmt,formulas,styles,validation,condfmt,
images,charts,comments,visibility. - For hosts and agents:
@sheetpane/testing,@sheetpane/fixtures,
@sheetpane/skillsand@sheetpane/mcp; typings for React, Vue, Svelte
and Solid; the custom-elements manifest. - Requirements: browsers with
DecompressionStream; Node 20+ for
imports in Node (0.2.0 raises this to 22+). MIT licence.
Changed in detail
-
Hidden rows, columns and sheets are honoured and marked (W-49): the
grid no longer draws what the file hides as ordinary rows and tabs. A
◂▸ / ▴▾ marker shows each hidden span (with its errors), Show hidden and
a marker click show it for viewing, hidden sheets are listed by a
⊘ n hidden button, outline groups get a gutter with +/− and levels, and
an error in a hidden place is shown when selected. Keys, copy, Delete and
totals skip hidden cells. Deprecated:ImportedSheet.hidden— use
state(visible·hidden·veryHidden). -
Resize columns and rows (W-47): drag a header edge (a guide and the
size while you drag), double-click to fit the text, several selected at
once, or right-click a header for Fit · width… · Reset. Rows keep the
file's custom heights and wrapped text wraps in them. Sizes are a view
setting — not a change, not in the download — withsizesand
sheetpane-resizefor a host to keep them. -
Range selection is smooth and does more (W-46). The selection is one
layer — a fill, one border, the active cell left clear — so a drag no longer
redraws the cells (on 250,000 rows: no dropped frame dragging with
autoscroll). Drag past an edge to scroll; click column or row headers or
the corner; Ctrl/⌘+arrows, Ctrl+Space, Shift+Space, Ctrl/⌘+A,
Shift+Backspace; Enter / Tab inside a range. A range copies as a grid
(TSV + HTML), clears with Delete, fills from one pasted value, and shows
Count · Sum · Average.sheetpane-selectgainsrangeand fires once per
drag, on release. Touch: two handles. Removed: the cells' internal
.inrange/.selclasses (in the shadow root, never host-facing). -
<sheetpane-excel>: one Download button (W-31). "Download .xlsx" /
"Download .csv", in View and Edit, replaces Export and Download the
original: with no change it hands back the file as opened, byte for
byte; with changes it downloadsexport()'s copy, the change count on the
button.sheetpane-exportkeeps its name and gainsoriginal: truefor
the untouched file. Removed: the separate download-original button. -
The selection bar no longer floats over the cells (W-31). Flag issue,
theselbarplugin buttons and ⋯ (Copy ref, Copy value) are docked at the
right end of the cell bar; right-click, Shift+F10 or the Menu key opens
the same actions under the cell. Theselbarslot keeps its id. -
Download is a neutral split button (W-34), not the accent colour: the
main part downloads in the upload's format; ▾ offers Download as .xlsx
or .csv (converting: one sheet, latest values) and each plugin's export
options (comments: "Write review as Excel comments").sheetpane-export
gainsformatandconverted.
Added in detail
-
@sheetpane/visibility(W-49): hide and unhide rows, columns and
sheets, and group outlines, in Edit — the selection bar, the cell, header
and tab menus, Google Sheets' keys, a marker click — written into the
download (patchXlsx's newhiddenoption).sheetpane-visibilityevent;
store.setHidden,setSheetState,setOutline. -
custom-elements.jsonand typings (W-37):@sheetpane/gridships the
Custom Elements Manifest, VS Code and JetBrains editor data, and type-only
entries@sheetpane/grid/jsx,/vue,/svelte,/solid— no host writes
its own element typings. Angular:CUSTOM_ELEMENTS_SCHEMA(README). -
@sheetpane/mcp(W-39):npx -y @sheetpane/mcp— an MCP server
(2026-07-28, stateless; 2025 clients too) with deterministic, read-only
tools: inspect a workbook, draft and check a rules file, explain an SP
code, find a skill, describe the API.sheetpane-skills installregisters
it for Claude Code, Kiro and Codex (--no-mcpto skip). Codes SP-7001…7007. -
@sheetpane/importreads.xlsxin Node (W-39): a built-in XML reader
stands in whenDOMParseris absent. Removed: theneeds-domrefusal
(SP-1008, retired).@sheetpane/testing'sreadFileuses it everywhere
and drops its own Node reader and its@sheetpane/exportdependency. -
TSDoc on the whole public API (W-36): every export's
.d.tscarries a
summary, parameters, returns, the elements' attributes and events, an example
and a link to its record. -
llms.txt/llms-full.txt(W-38): sheetpane's public contract for AI
agents, at the repository root and in@sheetpane/grid(dist/). -
@sheetpane/testing(W-41):sheetpane(page)for Playwright and
sheetpane(element)for Vitest browser mode — edit, flag, resolve, Download
read back,toHaveCell/toHaveError— on committeddata-sp-*hooks. -
Agent skills (W-35):
npx sheetpane-skills installcopies 23 skills for
Claude Code, Kiro and Codex into a repository, plus a short block in
CLAUDE.md/AGENTS.md;uninstallremoves exactly what it wrote. -
Stable error codes (W-40): every thrown error, console warning, rules
note, refused load and blocked edit carries anSP-xxxxcode with an entry
indocs/ERRORS.md;spCode/codeOf()read it. Messages keep their old
text after the code. -
A rules file (W-33):
rules-src="./sheetpane.rules.json"or
excel.rules = object— rules per sheet ("*"for all), by column title
and by cell or range, withequals,noneOfandnote; a JSON Schema
ships as@sheetpane/grid/rules.schema.json.flagging="off"hides
Flag issue and every pop-up: errors are read in the panel. -
Dark theme:
theme="light" | "dark" | "auto"on both elements (W-29). -
Column rules by title —
columns,validate,onInvalid(W-27). -
Plugins:
@sheetpane/numfmt,formulas,styles,validation,
condfmt,images,charts,comments(W-15–W-22). -
React hook recipes in
examples/react(W-28). -
A plugin gallery in both demos: Vanilla, a tab per plugin and All plugins on
one showcase workbook (W-32).