Users drag header boundaries to resize, merge a range into one cell, and drag the fill handle to repeat cells; code can do the first two through the Grid.
Result: A1:B1 is merged and shows 10, the value from A1. B1's 30 is hidden. This static illustration shows the merge, not the grid's pixel widths.
Full setup
import "@sheetwrite/core/styles.css" ;
const host = document . querySelector < HTMLElement >( "#grid" ); if ( host === null ) throw new Error ( "Missing #grid host" );
columns : { a : new Float64Array ([ 10 , 20 , 0 , 0 ]), b : new Float64Array ([ 30 , 40 , 0 , 0 ]) }, // Later, make A1 and B1 separate again:
// grid.actions.unmerge();
Column A is 160 px wide. After merge(), A1's value spans both columns and B1 is hidden. Call grid.actions.unmerge() to separate them again.
Try it live → Spreadsheet showcase
Resizing
Drag a column-header boundary or a row-header boundary to preview its size. The preview changes geometry only: the document and undo history stay the same until release. Release submits one undoable size change. Cancellation, capture loss, or a rejected change restores the document's size. Turning read-only on ends an active resize without committing.
Merged cells
Merging combines the selected range into one cell. The top-left value shows, and the covered cells are hidden. A per-sheet merge registry tracks them. Unmerge reverses it.
Drag-to-fill
A small fill handle sits at the bottom-right corner of the selection. Drag it down, up, left, or right to fill the source block across the new region. The dominant axis wins. The grid tiles (repeats) the source to cover the target.
For example, after unmerging, select A1:B2 from Full setup and drag the fill handle down through row 4. The source repeats; it does not become a numeric series:
Result: filling A1:B2 down through row 4 repeats 10, 30 and 20, 40. Rows 3 and 4 are the new copies; this static illustration has no draggable handle.
When the filled cells contain formulas, the grid rewrites references as it copies them: relative A1 parts shift by the fill offset, and absolute parts (prefixed with $) stay fixed.
Source formula Fill direction Filled formula =A1 + $B$1One column right =B1 + $B$1
See Formulas → Point mode and reference rewriting .
Options
API Effect grid.setColumnWidth(col, width)Set one column's width with an undoable setColumn patch. grid.setRowHeight(row, height)Set one row's persistent display height through document history. grid.actions.merge() / grid.actions.unmerge()Merge or unmerge the selection. grid.actions.mergeAndCenter()Merge the selection and center its text, as one undoable step. readOnly: trueTurns off drag-to-fill and resizing, including double-click autofit. Turning it on ends an active resize without committing.
Edge cases and limits
Merges are not drawn while a sort or filter view is active , because the display order no longer maps cleanly to the merged region. Clear the view to see them again. See Data operations .
Drag-to-fill is unavailable while a sort or filter view is active (the handle is hidden). When readOnly is on, the handle still shows, but a fill changes nothing.
A resize preview does not change the document. Only the release commits.
See also
const grid: Grid const grid : Grid const grid : Grid The imperative core grid this controller owns. API reference → Grid.setColumnWidth(col: number, width: number): void Grid. setColumnWidth (col: number, width: number): void Grid. setColumnWidth (col: number, width: number): void Set one column's width via an undoable setColumn patch. API reference → Grid.setSelection(sel: Selection | null): void Grid. setSelection (sel: Selection | null ): void Grid. setSelection (sel: Selection | null ): void kind: "range" let kind : "range" let kind : "range" Selects one inclusive rectangular range. range: Range let range : Range let range : Range Data-space bounds of the selected rectangle. API reference → Range.sheet: string interface Range {
sheet : string ;
} interface Range {
sheet : string ;
} Sheet identity used by the simple data-first adapter. Defaults to sheet1. API reference → Range.start: {
row: number;
col: number;
} interface Range {
start : {
row : number ;
col : number ;
};
} interface Range {
start : {
row : number ;
col : number ;
};
} Zero-based workbook column index of the first key. API reference → row: number let row : number let row : number 0-based row of the cell that holds the top-left corner. API reference → col: number let col : number let col : number 0-based column of the cell that holds the top-left corner. API reference → Range.end: {
row: number;
col: number;
} interface Range {
end : {
row : number ;
col : number ;
};
} interface Range {
end : {
row : number ;
col : number ;
};
} Exclusive workbook column index after the last key. API reference → Grid.actions: GridActions interface Grid {
actions : GridActions ;
} interface Grid {
actions : GridActions ;
} Imperative action surface for binding custom toolbars/menus. API reference → GridActions.merge(): void GridActions. merge (): void GridActions. merge (): void Show merge and unmerge controls in the default toolbar (default true). API reference → function createGrid(host: HTMLElement, opts: GridOptions): Grid function createGrid (
host : HTMLElement ,
opts : GridOptions ,
) : Grid function createGrid (
host : HTMLElement ,
opts : GridOptions ,
) : Grid Creates and mounts an imperative Grid in the supplied host element. Example import { createGrid, initSheetwrite } from "@sheetwrite/core" ;
await initSheetwrite ();
const host = document. createElement ( "div" );
host.style.height = "400px" ;
document.body. append (host);
const grid = createGrid (host, {
workbook: {
activeSheet: "sales" ,
sheets: [{ id: "sales" , name: "Sales" , rowCount: 2 ,
columns: [{ key: "amount" , header: "Amount" , type: "number" , width: 120 }] }],
},
data: { rowCount: 2 , columns: { amount: [ 12 , 18 ] } },
});
grid. scrollToCell ({ sheet: "sales" , row: 1 , col: 0 });
// Call when the host view is removed.
grid. destroy (); See also Grid * See also GridOptions API reference → function initSheetwrite(source?: BufferSource | URL | string | Request | WebAssembly.Module, engine?: SheetwriteEngine): Promise<void> function initSheetwrite (
source ?:
BufferSource | URL | string | Request | WebAssembly . Module ,
engine ?: SheetwriteEngine ,
) : Promise < void > function initSheetwrite (
source ?:
| BufferSource
| URL
| string
| Request
| WebAssembly . Module ,
engine ?: SheetwriteEngine ,
) : Promise < void > Load one WASM engine before createGrid. The default is @sheetwrite/wasm. Pass the @sheetwrite/formulas module as the second argument to select the full engine. Example import { initSheetwrite } from "@sheetwrite/core" ;
import * as formulas from "@sheetwrite/formulas" ;
await initSheetwrite ( undefined , formulas); See also /docs/start/choose-an-engine/ See also createGrid API reference → interface ColumnarData interface ColumnarData interface ColumnarData Eager column-oriented values used to initialize a sheet. API reference → interface Workbook interface Workbook interface Workbook Live workbook schema containing ordered sheets and the active sheet ID. API reference → const host: HTMLElement | null const host : HTMLElement | null const host : HTMLElement | null var document: Document var document : Document var document : Document window.document returns a reference to the document contained in the window. MDN Reference API reference → ParentNode.querySelector<HTMLElement>(selectors: string): HTMLElement | null (+4 overloads) ParentNode. querySelector < HTMLElement >(selectors: string): HTMLElement | null ( + 4 overloads) ParentNode. querySelector < HTMLElement >(selectors: string): HTMLElement | null ( + 4 overloads) Returns the first element that is a descendant of node that matches selectors. MDN Reference interface HTMLElement interface HTMLElement interface HTMLElement The HTMLElement interface represents any HTML element. MDN Reference var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+2 overloads) var Error : ErrorConstructor
new ( message ?: string , options ?: ErrorOptions ) => Error ( + 2 overloads) var Error : ErrorConstructor
new ( message ?: string , options ?: ErrorOptions ) => Error ( + 2 overloads) const host: HTMLElement const host : HTMLElement const host : HTMLElement ElementCSSInlineStyle.style: CSSStyleDeclaration interface ElementCSSInlineStyle {
style : CSSStyleDeclaration ;
} interface ElementCSSInlineStyle {
style : CSSStyleDeclaration ;
} MDN Reference API reference → CSSStyleDeclaration.height: string interface CSSStyleDeclaration {
height : string ;
} interface CSSStyleDeclaration {
height : string ;
} MDN Reference API reference → const workbook: Workbook const workbook : Workbook const workbook : Workbook Live workbook schema adopted by the store and updated by document operations. API reference → Workbook.activeSheet: string interface Workbook {
activeSheet : string ;
} interface Workbook {
activeSheet : string ;
} Active sheet ID and initial tab presented when the grid is created. API reference → Workbook.sheets: Sheet[] interface Workbook {
sheets : Sheet [];
} interface Workbook {
sheets : Sheet [];
} Sheets in display/tab order. API reference → Sheet.id: string interface Sheet {
id : string ;
} interface Sheet {
id : string ;
} Stable identifier, unique within the workbook and used by every cell address. API reference → Sheet.name: string interface Sheet {
name : string ;
} interface Sheet {
name : string ;
} User-facing sheet name shown in tabs and workbook exports. API reference → Sheet.rowCount: number interface Sheet {
rowCount : number ;
} interface Sheet {
rowCount : number ;
} Row count for both in-memory and datasource-backed sheets. API reference → Sheet.columns: Column[] interface Sheet {
columns : Column [];
} interface Sheet {
columns : Column [];
} Ordered schema; array positions are the zero-based column coordinates. API reference → Column.key: string interface Column {
key : string ;
} interface Column {
key : string ;
} Non-empty key, unique within the sheet, used to map input and datasource values. API reference → Column.header: string interface Column {
header : string ;
} interface Column {
header : string ;
} Schema label used by table exports and data-grid presentation headers. API reference → Column.type: CellFormat interface Column {
type : CellFormat ;
} interface Column {
type : CellFormat ;
} Controls cell input parsing and default value formatting for this column. API reference → Column.width: number interface Column {
width : number ;
} interface Column {
width : number ;
} Unzoomed column width in CSS pixels. API reference → const data: ColumnarData const data : ColumnarData const data : ColumnarData Eager column-major values loaded into workbook.activeSheet; use instead of datasource. API reference → ColumnarData.rowCount: number interface ColumnarData {
rowCount : number ;
} interface ColumnarData {
rowCount : number ;
} Row count for both in-memory and datasource-backed sheets. API reference → ColumnarData.columns: Record<string, ArrayLike<CellScalar | CellValue>> interface ColumnarData {
columns : Record < string , ArrayLike < CellScalar | CellValue >>;
} interface ColumnarData {
columns : Record <
string ,
ArrayLike <
CellScalar | CellValue
>
>;
} Exact column runs represented by every returned row. API reference → a: Float64Array<ArrayBuffer> let a : Float64Array < ArrayBuffer > let a : Float64Array < ArrayBuffer > var Float64Array: Float64ArrayConstructor
new (elements: Iterable<number>) => Float64Array<ArrayBuffer> (+6 overloads) var Float64Array : Float64ArrayConstructor
new ( elements : Iterable < number >) => Float64Array < ArrayBuffer > ( + 6 overloads) var Float64Array : Float64ArrayConstructor
new ( elements : Iterable < number >) => Float64Array < ArrayBuffer > ( + 6 overloads) b: Float64Array<ArrayBuffer> let b : Float64Array < ArrayBuffer > let b : Float64Array < ArrayBuffer > GridOptions.workbook: Workbook interface GridOptions {
workbook : Workbook ;
} interface GridOptions {
workbook : Workbook ;
} Live workbook schema adopted by the store and updated by document operations. API reference → GridOptions.data?: ColumnarData | undefined interface GridOptions {
data ?: ColumnarData | undefined ;
} interface GridOptions {
data ?: ColumnarData | undefined ;
} Eager column-major values loaded into workbook.activeSheet; use instead of datasource. API reference →