# Paint Format

The Paint Format feature, also known as Format Painter, allows users to copy formatting from one cell or range and apply it to another location. This is useful for quickly applying consistent formatting across your spreadsheet.

## Overview

Paint Format copies all visual formatting from the source cells (colors, borders, fonts, alignment, number formats, etc.) and applies it to target cells, without affecting the cell values.

## Basic Usage

### Using the Toolbar Button

The easiest way to use Paint Format is through the `ButtonPaintFormat` toolbar button:

```tsx
import {
  SpreadsheetProvider,
  CanvasGrid,
  Toolbar,
  ButtonPaintFormat,
} from "@rowsncolumns/spreadsheet";
import { useSpreadsheetState } from "@rowsncolumns/spreadsheet-state";

function MySpreadsheet() {
  const {
    activeCell,
    activeSheetId,
    selections,
    onSavePaintFormat,
    isPaintFormatActive,
    // ... other hook values
  } = useSpreadsheetState({
    sheets,
    sheetData,
    onChangeSheets,
    onChangeSheetData,
  });

  return (
    <SpreadsheetProvider>
      <Toolbar>
        <ButtonPaintFormat
          isActive={isPaintFormatActive}
          onClick={() =>
            onSavePaintFormat(activeSheetId, activeCell, selections)
          }
        />
      </Toolbar>
      <CanvasGrid
        sheetId={activeSheetId}
        activeCell={activeCell}
        selections={selections}
        // ... other props
      />
    </SpreadsheetProvider>
  );
}
```

## How It Works

### 1. Copy Format (Activate Paint Format)

Click the Paint Format button or call `onSavePaintFormat` to copy formatting from the currently selected cells:

```tsx
// Save formatting from current selection
onSavePaintFormat(activeSheetId, activeCell, selections);
```

When paint format is active, `isPaintFormatActive` returns `true`, which can be used to show visual feedback.

### 2. Apply Format

Once activated, simply select the target cells where you want to apply the formatting. The spreadsheet automatically applies the copied formatting to the new selection.

### 3. Deactivate

Paint format automatically deactivates after applying to one selection. To cancel without applying, click the Paint Format button again.

## Programmatic Usage

You can also use paint format programmatically:

```tsx
import { useSpreadsheetState } from "@rowsncolumns/spreadsheet-state";

const {
  onSavePaintFormat,
  onApplyPaintFormat,
  isPaintFormatActive,
  paintFormat, // Direct function to paint from one range to another
} = useSpreadsheetState({
  // ... configuration
});

// Copy formatting from range A1:B2
onSavePaintFormat(
  1, // sheetId
  { rowIndex: 1, columnIndex: 1 }, // activeCell
  [{
    range: {
      startRowIndex: 1,
      endRowIndex: 2,
      startColumnIndex: 1,
      endColumnIndex: 2,
    }
  }]
);

// Or paint directly from one range to another
paintFormat(
  {
    startRowIndex: 1,
    endRowIndex: 2,
    startColumnIndex: 1,
    endColumnIndex: 2,
    sheetId: 1,
  },
  {
    startRowIndex: 5,
    endRowIndex: 6,
    startColumnIndex: 3,
    endColumnIndex: 4,
    sheetId: 1,
  }
);
```

## What Gets Copied

Paint Format copies the following formatting properties:

* **Text formatting**: Font family, font size, bold, italic, underline, strikethrough
* **Colors**: Text color, background color
* **Borders**: All border styles and colors
* **Alignment**: Horizontal and vertical alignment
* **Number formats**: Currency, percentage, date, custom formats
* **Text wrapping**: Wrap, overflow, or clip
* **Indentation**: Text indentation levels

## What Does NOT Get Copied

Paint Format does NOT copy:

* Cell values or formulas
* Cell comments/notes
* Data validation rules
* Conditional formatting rules
* Protected range settings
* Merged cell configuration

## Complete Example

```tsx
import React, { useState } from "react";
import {
  SpreadsheetProvider,
  CanvasGrid,
  Toolbar,
  ButtonPaintFormat,
  ToolbarSeparator,
  ButtonBold,
  ButtonItalic,
  BackgroundColorSelector,
} from "@rowsncolumns/spreadsheet";
import {
  useSpreadsheetState,
  type SheetData,
} from "@rowsncolumns/spreadsheet-state";

function SpreadsheetWithPaintFormat() {
  const [sheets, setSheets] = useState([
    { sheetId: 1, rowCount: 100, columnCount: 26, title: "Sheet 1" }
  ]);
  const [sheetData, setSheetData] = useState<SheetData>({});

  const {
    activeCell,
    activeSheetId,
    selections,
    getCellData,
    getEffectiveFormat,
    onChangeActiveCell,
    onChangeSelections,
    onChangeFormatting,
    onSavePaintFormat,
    isPaintFormatActive,
  } = useSpreadsheetState({
    sheets,
    sheetData,
    onChangeSheets: setSheets,
    onChangeSheetData: setSheetData,
  });

  const currentCellFormat = getEffectiveFormat(
    activeSheetId,
    activeCell.rowIndex,
    activeCell.columnIndex
  );

  return (
    <SpreadsheetProvider>
      <Toolbar>
        <ButtonBold
          isActive={currentCellFormat?.textFormat?.bold}
          onClick={() =>
            onChangeFormatting(
              activeSheetId,
              activeCell,
              selections,
              "textFormat",
              { bold: !currentCellFormat?.textFormat?.bold }
            )
          }
        />
        <ButtonItalic
          isActive={currentCellFormat?.textFormat?.italic}
          onClick={() =>
            onChangeFormatting(
              activeSheetId,
              activeCell,
              selections,
              "textFormat",
              { italic: !currentCellFormat?.textFormat?.italic }
            )
          }
        />
        <BackgroundColorSelector
          color={currentCellFormat?.backgroundColor}
          onChange={(color) =>
            onChangeFormatting(
              activeSheetId,
              activeCell,
              selections,
              "backgroundColor",
              color
            )
          }
        />
        <ToolbarSeparator />
        <ButtonPaintFormat
          isActive={isPaintFormatActive}
          onClick={() =>
            onSavePaintFormat(activeSheetId, activeCell, selections)
          }
        />
      </Toolbar>
      <CanvasGrid
        sheetId={activeSheetId}
        activeCell={activeCell}
        selections={selections}
        getCellData={getCellData}
        onChangeActiveCell={onChangeActiveCell}
        onChangeSelections={onChangeSelections}
      />
    </SpreadsheetProvider>
  );
}
```

## Keyboard Shortcut

Paint Format can also be activated via keyboard shortcuts (implementation dependent on your configuration):

```tsx
// Example: Activate paint format with Ctrl+Shift+C (copy format)
// Then apply with Ctrl+Shift+V (paste format)
```

## Use Cases

### Consistent Table Headers

Apply the same header formatting to multiple tables:

1. Format one header cell (bold, background color, borders)
2. Click Paint Format
3. Select other header cells to apply the same style

### Standardizing Reports

Quickly apply consistent formatting across similar data sections:

1. Format one complete section
2. Use Paint Format to copy it
3. Apply to other sections

### Color Coding

Apply color coding patterns to categorize data:

1. Set up one cell with specific colors
2. Paint format to similar categories

## Best Practices

1. **Format once, apply many**: Create template cells with desired formatting, then use Paint Format to replicate
2. **Visual feedback**: The `isPaintFormatActive` state should be used to provide visual indication that paint format mode is active
3. **Undo support**: Paint format operations are tracked in undo history
4. **Performance**: Paint format is efficient even for large ranges

## API Reference

### useSpreadsheetState Returns

| Property              | Type                                        | Description                                  |
| --------------------- | ------------------------------------------- | -------------------------------------------- |
| `onSavePaintFormat`   | `(sheetId, activeCell, selections) => void` | Saves formatting from selection for painting |
| `onApplyPaintFormat`  | `(sheetId, activeCell, selections) => void` | Applies saved formatting to new selection    |
| `isPaintFormatActive` | `boolean`                                   | Whether paint format mode is active          |
| `paintFormat`         | `(sourceRange, targetRange) => void`        | Directly paint from one range to another     |

## Limitations

* Paint format is a client-side operation and works with the current spreadsheet state
* Very large ranges may take a moment to process
* Formatting from merged cells requires special handling

## Troubleshooting

### Paint Format Not Working

Ensure you have the necessary callbacks:

```tsx
const {
  onSavePaintFormat,
  isPaintFormatActive,
  // These are required for paint format to work
  onChangeFormatting,
  getEffectiveFormat,
} = useSpreadsheetState({
  // configuration
});
```

### Visual Feedback Not Showing

Use `isPaintFormatActive` to style the button:

```tsx
<ButtonPaintFormat
  isActive={isPaintFormatActive}  // This provides visual feedback
  onClick={handlePaintFormat}
/>
```
