Canvas Grid
The Canvas Grid that renders the spreadsheet
CanvasGrid is a controlled component that accepts a set of props and exposes callbacks for developers to hook into.
import { SpreadsheetProvider, CanvasGrid } from "@rowsncolumns/spreadsheet";
const App = () => {
return (
<SpreadsheetProvider>
<CanvasGrid
rowCount={1000}
columnCount={1000}
sheetId={1}
/>
</SpreadsheetProvider>
);
};
CanvasGrid options
The following options are supported by CanvasGrid component
export type CanvasGridProps<T extends CellData = CellData> = {
licenseKey?: string;
/**
* ID of the selected sheet
*/
sheetId: number;
/**
* Initial active cell of the sheet
*/
activeCell?: CellInterface;
/**
* Initial cell selections of the sheet
*/
selections?: SelectionArea<SelectionAttributes>[];
/**
* Spreadsheet theme
*/
theme?: SpreadsheetTheme;
/**
* Automatically focus on the Spreadsheet
*/
autoFocus?: boolean;
/**
* Frozen row count
*/
frozenRowCount?: number;
/**
* Frozen column count
*/
frozenColumnCount?: number;
/**
* Total no of rows
*/
rowCount?: number;
/**
* Total no of columns
*/
columnCount?: number;
/**
* Scaling factor
*/
scale?: number;
/**
* @deprecated basicFilter. Use tables instead
*/
basicFilter?: FilterView;
/**
* Filter views
*/
tables?: TableView[];
/**
* Named ranges
*/
namedRanges?: NamedRange[];
/**
* Banded ranges
*/
bandedRanges?: BandedRange[];
/**
* Collaborators of the sheetsActivecell + Selections of the
* collaborator will be highlighted. Exclude current user
*/
users?: Collaborator[];
/**
* Current user's userId
*/
userId?: number | string;
/**
* Color of filter view border
*/
tableBorderColor?: string;
/**
* Color of the filter icon
*/
filterIconColor?: string;
/**
* Show filter icon in header cells
*/
showFilterIcon?: boolean;
/**
* Show calculated column icon
*/
showCalculatedColumnIcon?: boolean;
/**
* Conditional formatting
*/
conditionalFormats?: ConditionalFormatRule[];
/**
* Embedded chart
*/
charts?: EmbeddedChart[];
/**
* Embed any object on top of a sheet
*/
embeds?: EmbeddedObject[];
/**
* Default row height
*/
defaultRowHeight?: number;
/**
* Default column width
*/
defaultColumnWidth?: number;
/**
* Default column header height
*/
defaultColumnHeaderHeight?: number;
/**
* Default row header width
*/
defaultRowHeaderWidth?: number;
/**
* Color of the sheet grid lines
*/
gridLineColor?: string;
/**
* Default text color
*/
cellColor?: string;
/**
* Header color of banded cell
*/
bandedHeaderColor?: string;
/**
* Opacity of first band
*/
bandedOpacity?: number;
/**
* Default background color of a cell
*/
cellBackgroundColor?: string;
/**
* Border color of header cell
*/
headerBorderColor?: string;
/**
* Background color of header cells
*/
headerBackgroundColor?: string;
/**
* Header text color
*/
headerColor?: string;
/**
* When a cell is selected
*/
headerActiveBackgroundColor?: string;
/**
* Header background when an entire row or column is selected
*/
headerSelectedBackgroundColor?: string;
/**
* Text color of header when an entire row or column is selected
*/
headerSelectedColor?: string;
/**
* Header background for table cells
*/
headerTableBackgroundColor?: string;
/**
* Header background when table cell is selected
*/
headerTableActiveBackgroundColor?: string;
/**
* When an entire header row or column is selected
*/
headerTableSelectedBackgroundColor?: string;
/**
* Selected border color for charts
*/
chartSelectedColor?: string;
/**
* Background color of chips
*/
chipBackgroundColor?: string;
/**
* Shadow color of frozen row
*/
frozenShadowColor?: string;
/**
* Thickness of frozen shadow
*/
frozenShadowThickness?: number;
/**
* Border color of selections
*/
selectionBorderColor?: string;
/**
* Background selection color
*/
selectionBackgroundColor?: string;
/**
* Border color when selection is dragged
*/
selectionDragBorderColor?: string;
/**
* Merged cells
*/
merges?: GridRange[];
/**
* Protected cell ranges
*/
protectedRanges?: ProtectedRange[];
/**
* Additional bordered areas in the grid
*/
borderStyles?: RangeBorderStyle[];
/**
* Meta data of a row
*/
rowMetadata?: Sheet["columnMetadata"];
/**
* Meta data of a column
*/
columnMetadata?: Sheet["columnMetadata"];
/**
* Enable sticky editor
*/
stickyEditor?: boolean;
/**
* Scrollbar size
*/
scrollbarSize?: number;
/**
* Show grid lines
*/
showGridLines?: boolean;
/**
* Show frozen line separator for row and column
*/
showFrozenSeparator?: boolean;
/**
* Show formulas in cells
*/
showFormulas?: boolean;
/**
* Show spreadsheet row and column headers
*/
showHeaders?: boolean;
/**
* Snaps to row or column while scrolling
* Recommended for 60fps scrolling, Since canvas
* does not need to redraw at each scroll frame
*/
scrollSnap?: boolean;
/**
* How fast scroll should snap to row or column
*/
scrollThrottleTimeout?: number;
/**
* Cell selection policy
*/
selectionPolicy?: UseSelectionOptions["selectionPolicy"];
/**
* Enable enter key to edit a cell
* When false, pressing enter will select the next cell
*/
enableEditOnEnterKey?: boolean;
/**
* Show header menu button that invokes context menu
*/
showHeaderMenuButton?: boolean;
/**
* Enable text overflow to neighbouring empty cells
* Enabling it will have an performance impact
*/
enableTextOverflow?: boolean;
/**
* Number of additional columns to
* render on the left and right
* Useful, when text overflows adjacent cells
*/
overscanCount?: number;
/**
* Header renderer
*/
HeaderCell?: ElementType<HeaderCellProps>;
/**
* Cell renderer
*/
Cell?: ElementType<CellProps>;
/**
* Selection title component
*/
SelectionTitleComponent?: ElementType<SelectionTitleProps>;
/**
* Cell Editor
*/
CellEditor?: ElementType;
/**
* Tooltip
*/
CellTooltip?: ElementType<CellTooltipProps>;
/**
* Custom Context menu component
*/
ContextMenu?: ElementType;
/**
* Filterbox component
*/
FilterBox?: ElementType | ReactElement;
/**
* Chart component
*/
getChartComponent?(props: ChartComponentProps): React.ReactElement;
/**
* Chart component
*/
getEmbedComponent?(props: EmbedComponentProps): React.ReactElement;
/**
* User scrolls the grid
* @param scrollCoords
*/
onScroll?(scrollCoords: ScrollCoords): void;
/**
* View port changes
*/
onViewPortChange?(viewport: ViewPortProps): void;
/**
* Callback when user changes a cell value
* @param sheetId
* @param cell
* @param value
*/
onChange?(
sheetId: number,
cell: CellInterface,
value: string | boolean,
previousValue: string | boolean | undefined,
isDirty?: boolean
): void;
/**
* User is deleting a cell or selections
* @param sheetId
* @param cell
* @param selections
*/
onDelete?(
sheetId: number,
cell: CellInterface,
selections: SelectionArea<SelectionAttributes>[]
): void;
/**
* When user changes editor value
* @param value
* @param sheetId
* @param cell
*/
onChangeEditorValue?(
value: string,
sheetId: number,
cell: CellInterface
): void;
/**
* For result preview panel in cell editor
* @param value
* @param sheetId
* @param cell
*
* @returns FormulaResult
*/
onRequestCalculate?(
value: string,
sheetId: number,
rowIndex: number,
columnIndex: number,
isArray?: boolean
): Promise<
| undefined
| string
| number
| boolean
| Date
| (string | number | boolean | Date)[][]
>;
/**
* Fill
* @param cell
* @param selections
*/
onFill?(
sheetId: number,
cell: CellInterface,
fillSelection: SelectionArea<SelectionAttributes>,
selections: SelectionArea<SelectionAttributes>[]
): void;
/**
* Callback when user moves a selection
* @param from
* @param to
*/
onMoveSelection?(
sheetId: number,
from: SelectionArea<SelectionAttributes>,
to: SelectionArea<SelectionAttributes>
): void;
/**
* Callback when active cell changes
*/
onChangeActiveCell?(cell: CellInterface): void;
/**
* Callback when selections cell changes
*/
onChangeSelections?(
selections: SelectionArea<SelectionAttributes>[],
finishedSelection?: boolean
): void;
/**
* Formulas can trigger sheet change
*/
onChangeActiveSheet?(sheetId: number): void;
/**
* Get data of a specific cell
* @param rowIndex
* @param columnIndex
* @returns CellData
*/
getCellData?(
sheetId: number,
rowIndex: number,
columnIndex: number
): T | null | undefined;
/**
* Callback when user resizes a column or row
* @param dimension
* @param index
* @param axis
* @param autoFit
*/
onResize?(
sheetId: number,
indexes: number[],
dimension: number,
axis: AXIS,
autoFit?: boolean
): void;
/**
* Hide column
* @param columnIndexes
*/
onHideColumn?(sheetId: number, columnIndexes: number[]): void;
/**
* Hide row
* @param rowIndexes
*/
onHideRow?(sheetId: number, rowIndexes: number[]): void;
/**
* Show column
* @param columnIndex
*/
onShowColumn?(sheetId: number, columnIndexes: number[]): void;
/**
* Show row
* @param rowIndex
*/
onShowRow?(sheetId: number, rowIndexes: number[]): void;
/**
* Delete column
* @param columnIndex
*/
onDeleteColumn?(sheetId: number, columnIndexes: number[]): void;
/**
* Delete row
* @param rowIndex
*/
onDeleteRow?(sheetId: number, rowIndexes: number[]): void;
/**
* Insert column
* @param columnIndex
*/
onInsertColumn?(sheetId: number, columnIndex: number): void;
/**
* Insert row
* @param rowIndex
*/
onInsertRow?(sheetId: number, rowIndex: number): void;
/**
* When user inserts cell and shift down
* @param cell
*/
onInsertCellsShiftDown?(sheetId: number, cell: CellInterface): void;
/**
* When user inserts cell and shift right
* @param cell
*/
onInsertCellsShiftRight?(sheetId: number, cell: CellInterface): void;
/**
* Delete cells and shift left
* @param cell
*/
onDeleteCellsShiftLeft?(sheetId: number, cell: CellInterface): void;
/**
* Delete cells and shift up
* @param cell
*/
onDeleteCellsShiftUp?(sheetId: number, cell: CellInterface): void;
/**
* Callback when columns are moved
* @param dims
* @param toColumn
*/
onMoveColumns?(sheetId: number, dims: number[], toColumn: number): void;
/**
* Callback when rows are moved
* @param dims
* @param toRow
*/
onMoveRows?(sheetId: number, dims: number[], toRow: number): void;
/**
* User pressed a key to select previous sheet
*/
onSelectPreviousSheet?(e?: React.KeyboardEvent<HTMLDivElement>): void;
/**
* User pressed a key to select previous sheet
*/
onSelectNextSheet?(e?: React.KeyboardEvent<HTMLDivElement>): void;
/**
* Shift + Fn + F11
* To insert a new sheet
*/
onCreateNewSheet?(): void;
/**
* Keydown handler
*/
onKeyDown?(e: React.KeyboardEvent<HTMLDivElement>): void;
/**
* When user changes formatting, Eg: bold, underline
*/
onChangeFormatting?<T extends FormattingType>(
sheetId: number,
type: T,
value: FormattingValue<T>
): void;
/**
* When user presses F4, we can replay the last formatting
* on a new cell
* @param sheetId
*/
onRepeatFormatting?(sheetId: number): void;
/**
* User is trying to clear all formatting from
* cells
*/
onClearFormatting?(sheetId: number): void;
/**
* Callback when user clears contents
*/
onClearContents?(sheetId: number, activeCell: CellInterface): void;
/**
* Called when user tries to edit a protected cell
* @param cell
*/
onEditProtectedCell?(sheetId: number, cell: CellInterface): void;
/**
* Return sheet name from sheetId
* @param sheetId
*/
getSheetName?(sheetId: number): string;
/**
* Callback when user resizes a chart
* @param width
* @param height
*/
onResizeChart?(
chartId: number,
anchorCell: CellInterface,
offsetXPixels: number,
offsetYPixels: number,
width: number,
height: number
): void;
/**
* User is trying to delete an embed
* @param chartId
*/
onDeleteChart?(chartId: number): void;
/**
* Fired when user moves a chart
* @param anchorCell
* @param offsetXPixels
* @param offsetYPixels
*/
onMoveChart?(
chartId: number,
anchorCell: CellInterface,
offsetXPixels: number,
offsetYPixels: number
): void;
/**
* Callback when user resizes an embed
* @param width
* @param height
*/
onResizeEmbed?(
embedId: number,
anchorCell: CellInterface,
offsetXPixels: number,
offsetYPixels: number,
width: number,
height: number
): void;
/**
* User is trying to delete an embed
* @param embedId
*/
onDeleteEmbed?(embedId: number): void;
/**
* Fired when user moves an embed
* @param anchorCell
* @param offsetXPixels
* @param offsetYPixels
*/
onMoveEmbed?(
embedId: number,
anchorCell: CellInterface,
offsetXPixels: number,
offsetYPixels: number
): void;
/**
* When user tries to fill range
* @param activeCell
* @param selections
* @param direction
*
* Command + Enter => Fill range
* Command + D => Fill down
* Command + R => Fill right
*/
onFillRange?(
sheetId: number,
activeCell: CellInterface,
selections: SelectionArea<SelectionAttributes>[],
direction?: Direction
): void;
/**
* On insert current time
* @param activeCell
* @param selections
*/
onInsertTime?(
sheetId: number,
activeCell: CellInterface,
selections: SelectionArea<SelectionAttributes>[]
): void;
/**
* On insert date
* @param activeCell
* @param selections
*/
onInsertDate?(
sheetId: number,
activeCell: CellInterface,
selections: SelectionArea<SelectionAttributes>[]
): void;
/**
* Freeze columns
* @param sheetId
* @param columnIndex
*/
onFreezeColumn?(sheetId: number, columnIndex: number): void;
/**
* Freeze rows
* @param sheetId
* @param columnIndex
*/
onFreezeRow?(sheetId: number, rowIndex: number): void;
/**
* User tries to undo an action
*/
onUndo?(): void;
/**
* User tries to redo an action
*/
onRedo?(): void;
/**
* Callback when user paste a set of cells
* @param e Browser event
* @param copiedSelections Selection that user copied
* @param activeCell Current active cell
* @param selections Current active selections
* @param shouldDeleteSource If user has cut a selection, we should delete copiedSelections
*/
onPaste?(
e: ClipboardEvent | undefined,
sourceSheetId: number | undefined,
destinationSheetId: number,
copiedSelections: SelectionArea<SelectionAttributes>[] | undefined,
activeCell: CellInterface,
selections: SelectionArea<SelectionAttributes>[] | undefined,
finalSelections: SelectionArea<SelectionAttributes>[] | undefined,
shouldDeleteSource: boolean
): void;
/**
* Callback when user copies a selection
* useful to save copied selection till user
* paste's the selection
* @param e
* @param copiedSelections Selections that user copied
*/
onCopy?(
e: ClipboardEvent | undefined,
sheetId: number,
copiedSelections: SelectionArea<SelectionAttributes>[]
): void;
/**
* Callback when user cuts a selection
* @param e
*/
onCut?(e: ClipboardEvent | undefined, sheetId: number): void;
/**
* Sort sheet by columnIndex
* @param columnIndex
* @param sortOrder
*/
onSortColumn?(
sheetId: number,
columnIndex: number,
sortOrder: SortOrder
): void;
/**
* Callback when user sorts a basicFilter or Table
*/
onSortTable?(
sheetId: number,
filter: FilterView | TableView,
columnIndex: number,
direction: SortOrder
): void;
/**
* Callback when applies a filter
* @param columnIndex
* @param conditionType
* @param conditionValue
* @param hiddenValues
*/
onFilterTable?(
sheetId: number,
filter: FilterView | TableView,
columnIndex: number,
conditionType: ConditionType | undefined,
conditionValue: ConditionValue[] | undefined,
hiddenValues: string[]
): void;
/**
* Callback when user resizes a table
* @param sheetId
* @param tableId
* @param range
*/
onResizeTable?(sheetId: number, table: TableView, range: GridRange): void;
/**
* Callback when user updates or adds a new note
* @param sheetId
* @param cell
* @param notes
*/
onUpdateNote?(sheetId: number, cell: CellInterface, notes?: string): void;
/**
* User wants to protect a range of cells or sheet
* @param sheetId
* @param cell
* @param selections
*/
onProtectRange?(
sheetId: number,
cell: CellInterface,
selections: SelectionArea<SelectionAttributes>[] | undefined
): void;
/**
* Un protect range by Id
* @param sheetId
* @param protectedRangeId
*/
onUnProtectRange?(sheetId: number, protectedRangeId: number): void;
/**
* Sort a selection range
* @param sheetId
* @param selection
*/
onSortRange?(
sheetId: number,
selection: SelectionArea<SelectionAttributes>[],
sortOrder: SortOrder
): void;
/**
* On Request edit a table
* Developers can choose to show a modal dialog
* @param table
*/
onRequestEditTable?(table: TableView): void;
/**
* Handle keyboard shortcut to create a new table
* Option + Command + T
* Ctrl + Option + T
*/
onCreateTable?(
sheetId: number,
activeCell: CellInterface,
selections: SelectionArea<SelectionAttributes>[],
headerRow?: boolean
): void;
/**
* Define a new or edit an existing named range
*/
onRequestDefineNamedRange?(
sheetId: number,
activeCell: CellInterface,
selections: SelectionArea<SelectionAttributes>[]
): void;
/**
* Get text for a row header
* @param rowIndex
*/
getRowHeaderText?(rowIndex: number): string;
/**
* Get text for a column header
* @param columnIndex
*/
getColumnHeaderText?(columnIndex: number): string;
/**
* Parses a text value to return tokens
* @param value
*/
tokenizer?(value: string | undefined, sheetName?: string): ParsedToken[];
/**
* All functions supported by the
* calculator, used for suggestions
* in the formula dropdown
*/
functionDescriptions?: CalculatorFunction[];
};
Last updated