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