# Grid Footer

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

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

| Prop               | Type                                                | Description                             |
| ------------------ | --------------------------------------------------- | --------------------------------------- |
| `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)

| Prop              | Type              | Description                         |
| ----------------- | ----------------- | ----------------------------------- |
| `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

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

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

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

```tsx
// The default GridFooter styling includes:
// - Responsive padding
// - Border styling
// - Background color from theme
// - Proper alignment with row headers
```

## Layout Considerations

### Footer Height

The `footerHeight` prop determines the height of the footer area:

```tsx
<CanvasGrid
  footerHeight={80}  // 80 pixels for footer
  footerComponent={<GridFooter {...props} />}
/>
```

### Row Header Alignment

GridFooter automatically aligns with the row header column, ensuring consistent layout:

```tsx
// Internal padding matches ROW_HEADER_WIDTH constant
// Scrollbar space is automatically accounted for
```

## Complete Example

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

1. **Set appropriate footer height**: The default 80px works well for most cases, but adjust based on your content
2. **Validate row additions**: Consider limits on total row count to prevent performance issues
3. **Provide feedback**: Show loading states or success messages when adding rows
4. **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.


---

# 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/grid-footer.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.
