# Font and Text Selectors

A collection of toolbar components for font and text formatting including font family selection, font size adjustment, text alignment, and text wrapping options.

## Components Overview

* **FontFamilySelector**: Choose font family (Arial, Times New Roman, etc.)
* **FontSizeSelector**: Select font size in points
* **TextHorizontalAlignSelector**: Horizontal text alignment
* **TextVerticalAlignSelector**: Vertical text alignment
* **TextWrapSelector**: Text wrapping options
* **TextFormatSelector**: Additional text formatting options

## FontFamilySelector

Select the font family for cells.

### Basic Usage

```tsx
import { FontFamilySelector } from "@rowsncolumns/spreadsheet";

<FontFamilySelector
  value={currentCellFormat?.textFormat?.fontFamily}
  onChange={(value) => {
    onChangeFormatting(
      activeSheetId,
      activeCell,
      selections,
      "textFormat",
      { fontFamily: value }
    );
  }}
/>
```

### Complete Example

```tsx
import React, { useState } from "react";
import {
  SpreadsheetProvider,
  CanvasGrid,
  Toolbar,
  FontFamilySelector,
  Sheet,
} from "@rowsncolumns/spreadsheet";
import {
  useSpreadsheetState,
  SheetData,
  CellData,
} from "@rowsncolumns/spreadsheet-state";

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

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

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

  return (
    <SpreadsheetProvider>
      <Toolbar>
        <FontFamilySelector
          value={currentCellFormat?.textFormat?.fontFamily}
          onChange={(value) => {
            onChangeFormatting(
              activeSheetId,
              activeCell,
              selections,
              "textFormat",
              { fontFamily: value }
            );
          }}
        />
      </Toolbar>

      <CanvasGrid
        sheetId={activeSheetId}
        activeCell={activeCell}
        selections={selections}
        // ... other props
      />
    </SpreadsheetProvider>
  );
}
```

### Props

| Prop        | Type                      | Description                                            |
| ----------- | ------------------------- | ------------------------------------------------------ |
| `value`     | `string`                  | Current font family (e.g., "Arial", "Times New Roman") |
| `onChange`  | `(value: string) => void` | Callback when font family changes                      |
| `className` | `string`                  | Optional CSS class name                                |

### Supported Fonts

Default supported fonts include:

* Arial
* Times New Roman
* Courier New
* Georgia
* Verdana
* Comic Sans MS
* Impact
* Trebuchet MS

## FontSizeSelector

Select font size in points.

### Basic Usage

```tsx
import { FontSizeSelector, DEFAULT_FONT_SIZE_PT } from "@rowsncolumns/spreadsheet";

<FontSizeSelector
  value={currentCellFormat?.textFormat?.fontSize ?? DEFAULT_FONT_SIZE_PT}
  onChange={(value) => {
    onChangeFormatting(
      activeSheetId,
      activeCell,
      selections,
      "textFormat",
      { fontSize: value }
    );
  }}
/>
```

### Props

| Prop        | Type                      | Description                               |
| ----------- | ------------------------- | ----------------------------------------- |
| `value`     | `number`                  | Current font size in points (default: 11) |
| `onChange`  | `(value: number) => void` | Callback when font size changes           |
| `className` | `string`                  | Optional CSS class name                   |

### Common Font Sizes

* 8pt (Very Small)
* 10pt (Small)
* 11pt (Default)
* 12pt (Normal)
* 14pt (Large)
* 18pt (Heading)
* 24pt (Large Heading)
* 36pt (Display)

## TextHorizontalAlignSelector

Horizontal text alignment selector.

### Basic Usage

```tsx
import { TextHorizontalAlignSelector } from "@rowsncolumns/spreadsheet";

<TextHorizontalAlignSelector
  value={currentCellFormat?.horizontalAlignment}
  onChange={(value) => {
    onChangeFormatting(
      activeSheetId,
      activeCell,
      selections,
      "horizontalAlignment",
      value
    );
  }}
/>
```

### Props

| Prop        | Type                            | Description                     |
| ----------- | ------------------------------- | ------------------------------- |
| `value`     | `"left" \| "center" \| "right"` | Current horizontal alignment    |
| `onChange`  | `(value) => void`               | Callback when alignment changes |
| `className` | `string`                        | Optional CSS class name         |

### Alignment Options

* **Left**: Align text to the left (default for text)
* **Center**: Center text horizontally
* **Right**: Align text to the right (default for numbers)

## TextVerticalAlignSelector

Vertical text alignment selector.

### Basic Usage

```tsx
import { TextVerticalAlignSelector } from "@rowsncolumns/spreadsheet";

<TextVerticalAlignSelector
  value={currentCellFormat?.verticalAlignment}
  onChange={(value) => {
    onChangeFormatting(
      activeSheetId,
      activeCell,
      selections,
      "verticalAlignment",
      value
    );
  }}
/>
```

### Props

| Prop        | Type                            | Description                     |
| ----------- | ------------------------------- | ------------------------------- |
| `value`     | `"top" \| "middle" \| "bottom"` | Current vertical alignment      |
| `onChange`  | `(value) => void`               | Callback when alignment changes |
| `className` | `string`                        | Optional CSS class name         |

### Alignment Options

* **Top**: Align text to top of cell
* **Middle**: Center text vertically (default)
* **Bottom**: Align text to bottom of cell

## TextWrapSelector

Text wrapping options.

### Basic Usage

```tsx
import { TextWrapSelector } from "@rowsncolumns/spreadsheet";

<TextWrapSelector
  value={currentCellFormat?.wrapStrategy}
  onChange={(value) => {
    onChangeFormatting(
      activeSheetId,
      activeCell,
      selections,
      "wrapStrategy",
      value
    );
  }}
/>
```

### Props

| Prop        | Type                             | Description                         |
| ----------- | -------------------------------- | ----------------------------------- |
| `value`     | `"overflow" \| "clip" \| "wrap"` | Current wrap strategy               |
| `onChange`  | `(value) => void`                | Callback when wrap strategy changes |
| `className` | `string`                         | Optional CSS class name             |

### Wrap Options

* **Overflow**: Text overflows into adjacent cells (default)
* **Clip**: Text is clipped at cell boundary
* **Wrap**: Text wraps within the cell

## TextFormatSelector

Additional text formatting options.

### Basic Usage

```tsx
import { TextFormatSelector } from "@rowsncolumns/spreadsheet";

<TextFormatSelector
  value={currentCellFormat?.textRotation}
  onChange={(value) => {
    onChangeFormatting(
      activeSheetId,
      activeCell,
      selections,
      "textRotation",
      value
    );
  }}
/>
```

### Props

| Prop        | Type                      | Description                             |
| ----------- | ------------------------- | --------------------------------------- |
| `value`     | `number`                  | Text rotation angle (-90 to 90 degrees) |
| `onChange`  | `(value: number) => void` | Callback when rotation changes          |
| `className` | `string`                  | Optional CSS class name                 |

## Complete Toolbar Example

```tsx
import React, { useState } from "react";
import {
  SpreadsheetProvider,
  CanvasGrid,
  Toolbar,
  ToolbarSeparator,
  FontFamilySelector,
  FontSizeSelector,
  TextHorizontalAlignSelector,
  TextVerticalAlignSelector,
  TextWrapSelector,
  ButtonBold,
  ButtonItalic,
  ButtonUnderline,
  DEFAULT_FONT_SIZE_PT,
  Sheet,
} from "@rowsncolumns/spreadsheet";
import {
  useSpreadsheetState,
  SheetData,
  CellData,
} from "@rowsncolumns/spreadsheet-state";

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

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

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

  return (
    <SpreadsheetProvider>
      <div className="flex flex-col h-screen">
        <Toolbar>
          {/* Font Family */}
          <FontFamilySelector
            value={currentCellFormat?.textFormat?.fontFamily}
            onChange={(value) => {
              onChangeFormatting(
                activeSheetId,
                activeCell,
                selections,
                "textFormat",
                { fontFamily: value }
              );
            }}
          />

          {/* Font Size */}
          <FontSizeSelector
            value={currentCellFormat?.textFormat?.fontSize ?? DEFAULT_FONT_SIZE_PT}
            onChange={(value) => {
              onChangeFormatting(
                activeSheetId,
                activeCell,
                selections,
                "textFormat",
                { fontSize: value }
              );
            }}
          />

          <ToolbarSeparator />

          {/* Bold, Italic, Underline */}
          <ButtonBold
            active={currentCellFormat?.textFormat?.bold}
            onClick={() => {
              onChangeFormatting(
                activeSheetId,
                activeCell,
                selections,
                "textFormat",
                { bold: !currentCellFormat?.textFormat?.bold }
              );
            }}
          />

          <ButtonItalic
            active={currentCellFormat?.textFormat?.italic}
            onClick={() => {
              onChangeFormatting(
                activeSheetId,
                activeCell,
                selections,
                "textFormat",
                { italic: !currentCellFormat?.textFormat?.italic }
              );
            }}
          />

          <ButtonUnderline
            active={currentCellFormat?.textFormat?.underline}
            onClick={() => {
              onChangeFormatting(
                activeSheetId,
                activeCell,
                selections,
                "textFormat",
                { underline: !currentCellFormat?.textFormat?.underline }
              );
            }}
          />

          <ToolbarSeparator />

          {/* Text Alignment */}
          <TextHorizontalAlignSelector
            value={currentCellFormat?.horizontalAlignment}
            onChange={(value) => {
              onChangeFormatting(
                activeSheetId,
                activeCell,
                selections,
                "horizontalAlignment",
                value
              );
            }}
          />

          <TextVerticalAlignSelector
            value={currentCellFormat?.verticalAlignment}
            onChange={(value) => {
              onChangeFormatting(
                activeSheetId,
                activeCell,
                selections,
                "verticalAlignment",
                value
              );
            }}
          />

          {/* Text Wrapping */}
          <TextWrapSelector
            value={currentCellFormat?.wrapStrategy}
            onChange={(value) => {
              onChangeFormatting(
                activeSheetId,
                activeCell,
                selections,
                "wrapStrategy",
                value
              );
            }}
          />
        </Toolbar>

        <div className="flex-1">
          <CanvasGrid
            sheetId={activeSheetId}
            activeCell={activeCell}
            selections={selections}
            getCellData={getCellData}
            onChangeActiveCell={onChangeActiveCell}
            onChangeSelections={onChangeSelections}
          />
        </div>
      </div>
    </SpreadsheetProvider>
  );
}

export default SpreadsheetWithTextFormatting;
```

## Keyboard Shortcuts

Common keyboard shortcuts for text formatting:

* **Ctrl/Cmd + B**: Toggle bold
* **Ctrl/Cmd + I**: Toggle italic
* **Ctrl/Cmd + U**: Toggle underline
* **Ctrl/Cmd + L**: Align left
* **Ctrl/Cmd + E**: Align center
* **Ctrl/Cmd + R**: Align right

## Styling

Customize selector appearance with CSS:

```tsx
<FontFamilySelector
  className="min-w-32 border rounded"
  value={fontFamily}
  onChange={onChange}
/>

<FontSizeSelector
  className="w-16"
  value={fontSize}
  onChange={onChange}
/>
```

## Best Practices

1. **Show Current Format**: Always display the current cell's formatting state
2. **Multi-Selection Support**: Apply formatting to all selected cells
3. **Use getEffectiveFormat**: Get the computed format including defaults
4. **Provide Visual Feedback**: Highlight active formatting buttons
5. **Group Related Controls**: Use ToolbarSeparator to organize formatting options

## Use Cases

### Custom Font Lists

Provide custom font families:

```tsx
const customFonts = [
  "Roboto",
  "Open Sans",
  "Lato",
  "Montserrat",
  "Raleway",
];

<FontFamilySelector
  fonts={customFonts}
  value={fontFamily}
  onChange={onChange}
/>
```

### Font Size Presets

Common font size presets:

```tsx
const fontSizePresets = [8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36];

<FontSizeSelector
  presets={fontSizePresets}
  value={fontSize}
  onChange={onChange}
/>
```

### Conditional Formatting

Apply different alignments based on data type:

```tsx
const handleAlignmentChange = (value) => {
  const cellData = getCellData(activeSheetId, activeCell.rowIndex, activeCell.columnIndex);

  // Auto-align numbers to the right
  if (typeof cellData?.ev?.nv === "number") {
    value = "right";
  }

  onChangeFormatting(activeSheetId, activeCell, selections, "horizontalAlignment", value);
};
```

## Troubleshooting

### Selectors Not Showing Current Value

* Ensure getEffectiveFormat returns the correct cell format
* Check that activeCell and selections are properly synced
* Verify formatting data is stored correctly in sheetData

### Font Changes Not Applying

* Confirm onChangeFormatting is called with correct parameters
* Check that the font family name matches exactly
* Ensure the font is loaded (use loadWebFont for custom fonts)

### Performance Issues

* Memoize currentCellFormat calculation
* Debounce onChange handlers for font size input
* Use React.memo for selector components

## See Also

* [Toolbar](/configuration/components/toolbar.md) - Main toolbar component
* [Text Color Selector](/configuration/components/toolbar.md#textcolorselector) - Text color picker
* [Background Color Selector](/configuration/components/toolbar.md#backgroundcolorselector) - Background color picker
* [Border Selector](/configuration/components/toolbar.md#borderselector) - Cell border formatting


---

# 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/font-and-text-selectors.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.
