# Canvas Grid

CanvasGrid is a controlled component that accepts a set of props and exposes callbacks for developers to hook into.

```tsx
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

```typescript
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[];
  /**
   * Pivot tables
   */
  pivotTables?: PivotTable[];
  /**
   * 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;
  /**
   * Request to edit a pivot table configuration
   * @param pivotId
   */
  onRequestEditPivotTable?(pivotId: string): void;
  /**
   * Request to delete a pivot table
   * @param pivotId
   */
  onRequestDeletePivotTable?(pivotId: string): 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[];
};
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rowsncolumns.app/configuration/components/canvas-grid.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
