NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
A Flutter data-grid widget with a pluto_grid-shaped API and spreadsheet features: a formula engine, multi-sheet workbooks, charts, pivot tables, and CSV/XLSX/PDF import-export.
Last release 2 months ago
29 Jul 2026
Too new to tell
only 2 release windows
Nearly every release is documented
notes for 6 of 6 stable releases
Nothing withdrawn
no release was ever pulled
2 months old
6 releases · first in 2026
One column per month.
Text-wrap cascade — per-cell and per-row wrap control (additive).
Text-wrap cascade — per-cell and per-row wrap control (additive).
BCellWrapText enum (inherit / wrap / noWrap) with a forced getter.
Wrap now resolves as a three-level cascade, cell → row → column:
BCellValue.wrapText forces one cell, BCellRow.wrapText forces a row, and
inherit (the default at both levels) falls through to the existing
BCellColumn.wrapText bool — so untouched cells inherit from their row,
then the header column. Display-only, wraps inside the row height (pair with
BCellRow.height); XLSX export still writes wrap per column.reference/cells.md) show the cascade.Tier-3 release on top of 1.1.2 — advanced formula, what-if, and import features, all additive.
Tier-3 release on top of 1.1.2 — advanced formula, what-if, and import features, all additive.
LAMBDA(params, calc) produces a callable value; call it
directly (=LAMBDA(x, x+1)(5)) or bind it with LET (=LET(f, LAMBDA(a,b, a*b), f(6,7))). BYROW(array, lambda) and MAP(array, lambda) apply a
lambda over an array's rows / elements and spill. (Self-application is depth-
capped to #CIRC!; no BYCOL/REDUCE/SCAN yet.)stateManager.solve({targetCell, targetValue, byChanging: [...]})
(bcell_solver.dart): a multi-cell what-if solver (coordinate descent over
the Goal Seek bisection) that drives several input cells until a target
formula cell reaches a value; restores all inputs on failure. Unconstrained /
target-value only.stateManager.saveScenario(name, cells) /
applyScenario(name) / scenarios / removeScenario(name)
(bcell_scenario.dart): save and restore named sets of input-cell values.BCellImportTransform(rows) (bcell_import_transform.dart):
a chainable, non-mutating pipeline over List<Map> —
rename/select/drop/where/mapColumn/addColumn/distinct/sortBy —
to reshape a JSON payload to the grid's columns before importJson
(Power-Query "lite").TODAY/NOW) still full-clear — correctness
first, over-invalidate never under. No API change; the 10k-row tripwire stays
green.Excel-parity Tier-2 release on top of 1.1.1. Additive except for the removal of the this-row structured reference (see the Removed note below).
Excel-parity Tier-2 release on top of 1.1.1. Additive except for the removal of the this-row structured reference (see the Removed note below).
stateManager.defineTable({name, totals, bandRows})
(bcell_table.dart): registers the grid as an Excel table and unlocks the
[#Headers] / [#Totals] structured references (headers resolve to the
column titles, totals to the computed per-column aggregate). bandRows
(default true) paints the Excel zebra stripe automatically when the widget
leaves oddRowColor null. table / removeTable.BCellConditionalFormat.duplicates(),
.topN(n, {bottom}), and .formulaRule(formula, style) (the formula engine
evaluates the rule per row), alongside the existing color-scale / data-bar /
icon-set.BCellSlicer(stateManager, field:) companion widget: a chip bar of
the field's distinct values, multi-select filters the grid (sibling of
BCellPagination / BCellAutoSum).BCellValue.locked (default true, Excel semantics): a
protected (readOnly) grid still edits cells explicitly marked
locked: false; unprotected grids ignore it.pivot() gains multi-level row/column fields
(List<String> keys), a percentOfTotal value mode (BCellPivotValueMode),
and an optional key comparator, keeping the single-String call path.stateManager.goalSeek(targetCell:, targetValue:, byChanging:)
(bcell_goal_seek.dart): bisection solver that drives one input cell until a
target formula cell hits a value.TAKE, DROP, HSTACK, VSTACK,
TOCOL, TOROW over the existing dynamic-array (spill) values.[Sales] → the column's data range); use plain relative
A1 refs (=B1-C1) for per-row math. [#Headers]/[#Totals] (via
defineTable) are unaffected.Excel-parity feature release on top of 1.1.0 — all additive, no breaking API changes.
Excel-parity feature release on top of 1.1.0 — all additive, no breaking API changes.
formatter (BCellColumnValueFormatter) and
per-cell BCellValue.formatter override, wrapText (soft-wrap in the fixed
row height), and textAlign (BCellColumnTextAlign auto/left/center/right,
cells and header).BCellColumnType.select([...]) edits via an inline dropdown
of fixed options (Excel data-validation list), mirroring pluto_grid.positive;negative;zero;text, with
accounting-style (1,234) negatives), scientific notation (0.00E+00), and
[Red]/[Blue] colour tokens parsed-and-stripped.BCellValidation.number/date/time/list/formula prebuilt
validator helpers (bcell_data_validation.dart).setFrozenRowCount(n) pins the top N rows below the header
while the rest scroll (freeze panes; composes with frozen columns).replaceAll(query, replacement) (case-insensitive, routes
through the edit path so validator/undo apply; skips formula/non-text cells).BCellAutoFilter controller + BCellColumnFilterButton (Excel
column funnel; multiple columns AND together), backed by
distinctValues(field) / filterByValues(map) on the state manager.BCellAutoSum status-bar widget (live Count / Sum / Average of the
selection).setNote/noteFor now render a corner marker plus a
hover tooltip.BCellValue.style (a BCellStyle override that wins over
the column cellStyle resolver) and per-side cell borders via
BCellStyle.border (Flutter Border).BCellSparkline.line/.bar in-cell mini charts via
.toRenderer() (bcell_sparkline.dart).BCellChartType gains area and stackedBar (line/bar/pie/area/
scatter/radar/stackedBar).$A$1 absolute-ref markers parse (bcell treats all refs as
fixed); XLOOKUP; LET(name, value, …, calc); A1# spill-range refs; array
broadcasting at operator combine points (scalar⊗array and same-shape
array⊗array). Dynamic-array spill (FILTER/SORT/UNIQUE/SEQUENCE) and
SUMPRODUCT/TEXTJOIN remain. First-class function values (LAMBDA) stay
out of scope.toXlsx({styled, formulas, merged}): bold header, per-column
alignment, and cellStyle fill/font colour (default on); =… cells as real
Excel formulas (opt-in); colspan/rowspan as Excel merges with value
round-trip (default on).EdgeInsets / TextStyle / BorderSide / Size).Feature release: charts, pivot tables, workbook security, and styling options on top of 1.0.0 — all additive, no breaking API changes.
Feature release: charts, pivot tables, workbook security, and styling options on top of 1.0.0 — all additive, no breaking API changes.
BCellChart companion widget (line / bar / pie via fl_chart)
that plots the grid's filtered rows through evaluated formula values and
redraws live on edits, sorts, and filters.bcell_pivot.dart aggregation plugin with a toGrid()
helper that renders the pivot result as a regular BCellGrid.bcell_workbook_share.dart collaboration plumbing.toEncryptedBytes / decryptWorkbook /
loadEncryptedBytes (AES-256-GCM, PBKDF2-HMAC-SHA256 with hardened
iteration bounds). Wrong passwords and tampered files fail with
BCellDecryptException, never garbage data.saveVersion / versions / restoreVersion /
removeVersion snapshots on the workbook (in-memory, JSON-based).BCellGridStyleConfig gains cell padding, header sort-icon, and
fill-handle (fillHandleSize / fillHandleColor / fillHandleBorderColor)
options, all theme-resolved like the existing style fields.pointycastle ^4.0.0.First stable release. BCell grows from the minimal 0.0.1 data grid into a spreadsheet-capable widget: a formula engine, a multi-sheet workbook, a full
First stable release. BCell grows from the minimal 0.0.1 data grid into a
spreadsheet-capable widget: a formula engine, a multi-sheet workbook, a full
import/export surface, and a large set of Excel-style cell, column, and
selection features — all still built on the flat BCellGridStateManager and
virtualized rendering, guarded by a 10k-row performance regression test.
BCellColumnType.date({format}) hold a DateTime, display
yyyy-MM-dd (or a custom formatter), edit via a native date picker, and
coerce ISO strings / Excel date serials on import and paste.BCellColumnType.number(format: '#,##0.00' | '0%' | '$#,##0.00' | '000') apply display grouping/decimals/percent/prefix while
cells stay raw numbers, so sort and export are unaffected.BCellColumn(renderer:) draws any widget in place of
the default cell text.BCellColumn(cellStyle:) colors a cell by its
value, plus BCellConditionalFormat.colorScale/dataBar/iconSet(...)
renderers for color scales, data bars, and threshold icon sets.BCellRichText([BCellTextRun(...)]) with
bold/italic/underline/color runs (via BCellRichText.column().toRenderer());
exports flatten to plain text automatically.BCellHyperlink.column(onTap:).toRenderer() renders
styled, tappable, accessible link text (no launcher dependency).setNote/noteFor/hasNote/clearNotes.BCellValue(colspan:, rowspan:) (display-only; colspan stays on
the virtualized path, rowspan switches to a non-virtualized body).BCellGridStyleConfig(oddRowColor:) zebra striping.BCellGridStyleConfig gains defaultColumnTitlePadding,
defaultCellPadding, iconSize, iconColor (pluto_grid names), and
fillHandleSize/fillHandleColor/fillHandleBorderColor for the drag-fill
handle; defaults are unchanged (the handle outline now theme-resolves to
colorScheme.surface instead of hardcoded white).BCellRow(height:) with virtualization preserved.BCellColumn(frozen: BCellColumnFrozen.start | .end) pins
a column left/right with synced vertical scroll across sections.moveColumn(from, to) plus header drag-to-reorder and
accessible "Move left/right" actions.extendSelectionTo/isInRange/selectedCells/rangeAsTsv, range copy /
clear / fill, and a drag-fill handle.fillDown (Ctrl+D), fillRight (Ctrl+R), fillSeriesDown() (series/
auto fill), flashFillDown() (flash fill by inferred transform).setRowChecked/toggleRowChecked/
setAllRowsChecked/checkedRows/isAllChecked/isAnyChecked.copySelectionToClipboard/cutSelectionToClipboard/
pasteFromClipboard (TSV block paste, anchored and clipped).BCellColumn(validator:) enforced centrally in
changeCellValue (also guards paste/fill), with an onInvalid callback.undo/redo/canUndo/canRedo), find (find('q')), and go-to
(goToCell/goToRow).BCellGrid(mode: BCellGridMode.readOnly) /
setGridMode(...) blocks every edit and structural row change.= formulas evaluate on display, sort, and export, with error results
(#DIV/0!/#NAME?/#CIRC!/#NUM!/#REF!/#VALUE!/#N/A) and a cycle
guard; results memoized per notification. Formula cells never leak a live
=... into CSV.A1:B2 ranges; arithmetic, comparison, & concat, string
literals.defineName/removeName/clearNames/namedRange/
definedNames.enableStructuredRefs() for [Column] and
decorative Table[Column] whole-column refs, live over displayed rows.toPdf, dep: pdf;
selectionOnly print area), and XLSX (toXlsx, dep: excel). Markup exports
escape every cell value and title.importTsv/importCsv (RFC 4180)/importHtml/importMarkdown/
importJson/importXlsx, mapping onto visible columns and coercing to each
column type.BCellWorkbook (ordered BCellSheets + active
sheet) with add/remove/rename/select/move, per-sheet tab color,
protect, and hidden flags; BCellSheetTabBar (tab strip with drag-to-reorder
and accessible move actions) and BCellWorkbookView.password: on
BCellWorkbook.setProtected; unprotecting a password-protected sheet
requires the matching password. Only a SHA-256 hash is stored and persisted
in the workbook JSON, never the plaintext.BCellWorkbook.toJson() / BCellWorkbook.fromJson()
round-trip sheets, flags, column definitions (incl. number-format codes),
and row data; loadJson() loads a map into an existing workbook in place.saveVersion() / versions / restoreVersion() /
removeVersion() / clearVersions(): in-memory named, timestamped
workbook snapshots built on the JSON persistence, restorable in place.toEncryptedBytes(password) seals the workbook
JSON into an authenticated AES-256-GCM blob (PBKDF2-HMAC-SHA256 key
derivation, random per-file salt and nonce); decryptWorkbook() /
loadEncryptedBytes() open it, throwing BCellDecryptException on a wrong
password or tampered bytes. Backed by pointycastle.mergeChanges(base:, theirs:) folds another copy's
edits into the workbook via a three-way, cell-level merge over toJson()
snapshots; cells both copies changed differently keep the local value and
are reported as BCellMergeConflicts. BCellWorkbookView now rebuilds its
grid after any in-place load (loadJson/restoreVersion/
loadEncryptedBytes/mergeChanges), fixing stale rows when the active
index was unchanged.BCellGridEventManager (addEvent/listener/stream) on a
broadcast stream, allocated lazily.BCellFontController + BCellFontScope (InheritedNotifier)
re-font every BCell widget under one controller live.BCellChart(stateManager, type: BCellChartType.line/.bar/.pie, categoryField:, valueFields:), a companion widget that plots the grid's
filtered rows (formula-evaluated) and re-draws live. Backed by fl_chart.stateManager.pivot(rowField:, columnField:, valueField:, aggregate: BCellPivotAgg.sum/count/average/min/max) aggregates the filtered
rows into a rows × columns matrix (value/rowTotal/columnTotal/
grandTotal); totals re-aggregate the raw numbers. toGrid() renders the
result into BCellGrid columns+rows. Single row/column field.Your coding agent can read these notes before it upgrades. Set up the MCP server →