Grid Footer
Footer component for adding rows dynamically at the bottom of the spreadsheet
The GridFooter component provides a customizable footer area at the bottom of the spreadsheet grid, allowing users to add additional rows dynamically.
Overview
GridFooter displays at the bottom of the spreadsheet canvas and typically includes controls for adding new rows to the end of the sheet. It's useful for applications where users frequently add data at the bottom of their spreadsheet.
Basic Usage
import { SpreadsheetProvider, CanvasGrid, GridFooter } from "@rowsncolumns/spreadsheet";
import { useSpreadsheetState } from "@rowsncolumns/spreadsheet-state";
function MySpreadsheet() {
const {
activeSheetId,
onRequestAddRows,
// ... other hook values
} = useSpreadsheetState({
// ... configuration
});
return (
<SpreadsheetProvider>
<CanvasGrid
sheetId={activeSheetId}
footerHeight={80}
footerComponent={
<GridFooter
sheetId={activeSheetId}
onRequestAddRows={onRequestAddRows}
/>
}
// ... other props
/>
</SpreadsheetProvider>
);
}Props
GridFooter Props
sheetId
number
The ID of the active sheet
onRequestAddRows
(sheetId: number, additionalRows: number) => void
Callback when user requests to add rows
CanvasGrid Props (for footer)
footerHeight
number
Height of the footer area in pixels
footerComponent
React.ReactNode
The footer component to render
Features
Add Rows Functionality
The GridFooter includes:
An input field for specifying the number of rows to add
An "Add" button to execute the action
Automatic scrolling to the bottom after adding rows
const { onRequestAddRows } = useSpreadsheetState({
sheets,
sheetData,
onChangeSheets: setSheets,
onChangeSheetData: setSheetData,
});
// GridFooter will call this when user clicks "Add"
// It automatically scrolls to the bottom after adding rows
<GridFooter
sheetId={activeSheetId}
onRequestAddRows={(sheetId, numRows) => {
console.log(`Adding ${numRows} rows to sheet ${sheetId}`);
onRequestAddRows?.(sheetId, numRows);
}}
/>Implementing onRequestAddRows
The onRequestAddRows callback is typically provided by useSpreadsheetState, but you can also implement custom logic:
import { useState } from "react";
import type { Sheet } from "@rowsncolumns/spreadsheet";
const [sheets, setSheets] = useState<Sheet[]>([
{ sheetId: 1, rowCount: 100, columnCount: 26, title: "Sheet 1" }
]);
const handleAddRows = (sheetId: number, additionalRows: number) => {
setSheets(prev => prev.map(sheet => {
if (sheet.sheetId === sheetId) {
return {
...sheet,
rowCount: sheet.rowCount + additionalRows,
};
}
return sheet;
}));
};
<GridFooter
sheetId={activeSheetId}
onRequestAddRows={handleAddRows}
/>Custom Footer Component
You can create your own custom footer component instead of using the default GridFooter:
const CustomFooter = ({ sheetId }: { sheetId: number }) => {
return (
<div className="flex items-center justify-between p-4 bg-gray-100">
<span>Sheet {sheetId}</span>
<button onClick={() => console.log("Custom action")}>
Custom Action
</button>
</div>
);
};
<CanvasGrid
footerHeight={60}
footerComponent={<CustomFooter sheetId={activeSheetId} />}
/>Styling
The GridFooter component uses Tailwind CSS classes and can be customized through className props:
// The default GridFooter styling includes:
// - Responsive padding
// - Border styling
// - Background color from theme
// - Proper alignment with row headersLayout Considerations
Footer Height
The footerHeight prop determines the height of the footer area:
<CanvasGrid
footerHeight={80} // 80 pixels for footer
footerComponent={<GridFooter {...props} />}
/>Row Header Alignment
GridFooter automatically aligns with the row header column, ensuring consistent layout:
// Internal padding matches ROW_HEADER_WIDTH constant
// Scrollbar space is automatically accounted forComplete Example
import React, { useState } from "react";
import {
SpreadsheetProvider,
CanvasGrid,
GridFooter,
type Sheet,
} from "@rowsncolumns/spreadsheet";
import {
useSpreadsheetState,
type SheetData,
} from "@rowsncolumns/spreadsheet-state";
function SpreadsheetWithFooter() {
const [sheets, setSheets] = useState<Sheet[]>([
{ sheetId: 1, rowCount: 100, columnCount: 26, title: "Sheet 1" }
]);
const [sheetData, setSheetData] = useState<SheetData>({});
const {
activeCell,
activeSheetId,
selections,
getCellData,
onChangeActiveCell,
onChangeSelections,
onRequestAddRows,
// ... other state values
} = useSpreadsheetState({
sheets,
sheetData,
onChangeSheets: setSheets,
onChangeSheetData: setSheetData,
});
return (
<SpreadsheetProvider>
<CanvasGrid
sheetId={activeSheetId}
activeCell={activeCell}
selections={selections}
getCellData={getCellData}
onChangeActiveCell={onChangeActiveCell}
onChangeSelections={onChangeSelections}
footerHeight={80}
footerComponent={
<GridFooter
sheetId={activeSheetId}
onRequestAddRows={onRequestAddRows}
/>
}
/>
</SpreadsheetProvider>
);
}Best Practices
Set appropriate footer height: The default 80px works well for most cases, but adjust based on your content
Validate row additions: Consider limits on total row count to prevent performance issues
Provide feedback: Show loading states or success messages when adding rows
Handle errors gracefully: Validate the number input and handle edge cases
Use Cases
Data entry applications: Allow users to easily add more rows as they input data
Dynamic spreadsheets: Support growing datasets without manual sheet configuration
Form-like interfaces: Provide a way to add new records at the bottom of a list
Log viewers: Allow users to append new log entries
Performance
GridFooter is lightweight and doesn't impact spreadsheet performance. The component only re-renders when its props change, and adding rows is handled efficiently by the spreadsheet state management.
Last updated
Was this helpful?