# Formula Bar

The Formula Bar is a compound component that displays the active cell reference and allows users to view and edit cell values and formulas. It consists of three main sub-components: `FormulaBar`, `FormulaBarLabel`, and `FormulaBarInput`.

## Overview

The Formula Bar provides:

* **Cell reference display**: Shows the active cell address (e.g., "A1", "Sheet2!B5")
* **Formula editing**: Edit cell formulas and values in a larger input area
* **Formula preview**: View complete formulas without cell width constraints
* **Function hints**: Display function syntax and autocomplete

## Components

### FormulaBar

The parent container that wraps the formula bar components.

```tsx
import { FormulaBar, FormulaBarLabel, FormulaBarInput } from "@rowsncolumns/spreadsheet";

<FormulaBar>
  <FormulaBarLabel>A1</FormulaBarLabel>
  <FormulaBarInput
    value="=SUM(A1:A10)"
    onChange={handleChange}
  />
</FormulaBar>
```

### FormulaBarLabel

Displays the active cell reference or range.

```tsx
import { FormulaBarLabel } from "@rowsncolumns/spreadsheet";
import { cellToAddress } from "@rowsncolumns/utils";

function MyFormulaBar() {
  const { activeCell, activeSheetId, selections } = useSpreadsheetState({});

  const label = selections.length > 1
    ? selectionToAddress(selections[0])
    : cellToAddress(activeCell);

  return (
    <FormulaBarLabel>
      {label}
    </FormulaBarLabel>
  );
}
```

### FormulaBarInput

Input field for editing cell values and formulas.

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

<FormulaBarInput
  value={cellValue}
  onChange={(value) => onChange(activeSheetId, activeCell, value)}
  onKeyDown={handleKeyDown}
  functionDescriptions={functionDescriptions}
/>
```

## Complete Example

```tsx
import React, { useState } from "react";
import {
  SpreadsheetProvider,
  CanvasGrid,
  FormulaBar,
  FormulaBarLabel,
  FormulaBarInput,
  Sheet,
} from "@rowsncolumns/spreadsheet";
import {
  useSpreadsheetState,
  SheetData,
  CellData,
} from "@rowsncolumns/spreadsheet-state";
import { cellToAddress, selectionToAddress } from "@rowsncolumns/utils";
import { functionDescriptions } from "@rowsncolumns/functions";

function SpreadsheetWithFormulaBar() {
  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,
    getSheetName,
    onChangeActiveCell,
    onChangeSelections,
    onChange,
  } = useSpreadsheetState({
    sheets,
    sheetData,
    onChangeSheets: setSheets,
    onChangeSheetData: setSheetData,
  });

  // Get current cell data
  const cellData = getCellData(
    activeSheetId,
    activeCell.rowIndex,
    activeCell.columnIndex
  );

  // Determine label (cell reference or range)
  const formulaBarLabel = selections.length > 0 && selections[0]
    ? selectionToAddress(selections[0])
    : cellToAddress(activeCell);

  // Get cell value (formula or formatted value)
  const cellValue = cellData?.userEnteredValue?.formulaValue
    || cellData?.formattedValue
    || "";

  return (
    <SpreadsheetProvider>
      <div className="flex flex-col h-screen">
        {/* Formula Bar */}
        <FormulaBar>
          <FormulaBarLabel>{formulaBarLabel}</FormulaBarLabel>
          <FormulaBarInput
            value={cellValue}
            onChange={(value) => {
              onChange?.(
                activeSheetId,
                activeCell,
                value,
                cellData?.formattedValue
              );
            }}
            functionDescriptions={functionDescriptions}
            getSheetName={getSheetName}
          />
        </FormulaBar>

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

export default SpreadsheetWithFormulaBar;
```

## Props

### FormulaBar

| Prop        | Type              | Description                                         |
| ----------- | ----------------- | --------------------------------------------------- |
| `children`  | `React.ReactNode` | Child components (FormulaBarLabel, FormulaBarInput) |
| `className` | `string`          | Optional CSS class name                             |

### FormulaBarLabel

| Prop        | Type              | Description                               |
| ----------- | ----------------- | ----------------------------------------- |
| `children`  | `React.ReactNode` | Cell reference text (e.g., "A1", "B2:D5") |
| `className` | `string`          | Optional CSS class name                   |

### FormulaBarInput

| Prop                   | Type                               | Description                           |
| ---------------------- | ---------------------------------- | ------------------------------------- |
| `value`                | `string`                           | Current cell value or formula         |
| `onChange`             | `(value: string) => void`          | Callback when value changes           |
| `onKeyDown`            | `(e: React.KeyboardEvent) => void` | Optional keyboard handler             |
| `functionDescriptions` | `CalculatorFunction[]`             | Function definitions for autocomplete |
| `getSheetName`         | `(sheetId: number) => string`      | Get sheet name by ID                  |
| `className`            | `string`                           | Optional CSS class name               |

## Features

### Formula Autocomplete

The FormulaBarInput supports autocomplete for functions when `functionDescriptions` is provided:

```tsx
import { functionDescriptions, functions } from "@rowsncolumns/functions";

<FormulaBarInput
  value={cellValue}
  onChange={onChange}
  functionDescriptions={functionDescriptions}
/>
```

When users type `=SUM(`, the input shows function hints and parameter information.

### Multi-Cell Selection Display

When multiple cells are selected, the label shows the range:

```tsx
const label = selections.length > 0 && selections[0]
  ? selectionToAddress(selections[0])  // "A1:E10"
  : cellToAddress(activeCell);         // "A1"

<FormulaBarLabel>{label}</FormulaBarLabel>
```

### Named Range Display

Show named range when applicable:

```tsx
const getFormulaBarLabel = () => {
  // Check if selection is a named range
  const selection = selections[0];
  const namedRange = namedRanges.find(nr =>
    rangesEqual(nr.range, selection?.range)
  );

  if (namedRange) {
    return namedRange.name; // "SalesData"
  }

  return selectionToAddress(selection) || cellToAddress(activeCell);
};
```

### Cross-Sheet References

Display sheet names in cross-sheet references:

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

const label = activeSheetId !== 1
  ? `${getSheetName(activeSheetId)}!${cellToAddress(activeCell)}`
  : cellToAddress(activeCell);

<FormulaBarLabel>{label}</FormulaBarLabel>
```

## Keyboard Shortcuts

The Formula Bar supports standard keyboard shortcuts:

* **Enter**: Confirm and move to next cell
* **Escape**: Cancel editing
* **Tab**: Autocomplete function name
* **F2**: Edit cell in formula bar
* **Ctrl/Cmd + A**: Select all text

## Styling

The Formula Bar can be styled using CSS classes:

```tsx
<FormulaBar className="border-b bg-white">
  <FormulaBarLabel className="font-mono text-sm px-3 py-2 border-r bg-gray-50" />
  <FormulaBarInput className="flex-1 px-3 py-2 font-mono text-sm" />
</FormulaBar>
```

## Integration with Toolbar

Combine with toolbar for a complete spreadsheet interface:

```tsx
import { Toolbar, FormulaBar } from "@rowsncolumns/spreadsheet";

<div className="flex flex-col h-screen">
  <Toolbar>
    {/* Toolbar buttons */}
  </Toolbar>

  <FormulaBar>
    <FormulaBarLabel>{label}</FormulaBarLabel>
    <FormulaBarInput value={value} onChange={onChange} />
  </FormulaBar>

  <div className="flex-1">
    <CanvasGrid {...props} />
  </div>
</div>
```

## Advanced Usage

### Custom Formula Validation

Validate formulas before applying:

```tsx
const handleFormulaChange = (value: string) => {
  if (value.startsWith("=")) {
    // Validate formula syntax
    try {
      validateFormula(value);
      onChange(activeSheetId, activeCell, value);
    } catch (error) {
      console.error("Invalid formula:", error);
    }
  } else {
    onChange(activeSheetId, activeCell, value);
  }
};

<FormulaBarInput
  value={cellValue}
  onChange={handleFormulaChange}
/>
```

### Formula Highlighting

Highlight cell references in formulas:

```tsx
const highlightedFormula = useMemo(() => {
  if (!cellValue.startsWith("=")) return cellValue;

  // Highlight cell references (A1, B2:C5, etc.)
  return cellValue.replace(
    /([A-Z]+[0-9]+)(:[A-Z]+[0-9]+)?/g,
    '<span class="text-blue-600 font-semibold">$&</span>'
  );
}, [cellValue]);
```

### Read-Only Mode

Disable editing in read-only mode:

```tsx
<FormulaBarInput
  value={cellValue}
  onChange={readonly ? undefined : onChange}
  readOnly={readonly}
/>
```

## Best Practices

1. **Always Show Cell Reference**: Display the current cell or range reference in FormulaBarLabel
2. **Sync with Active Cell**: Update formula bar when active cell changes
3. **Handle Long Formulas**: Ensure the input can scroll for long formulas
4. **Provide Function Hints**: Include functionDescriptions for better UX
5. **Validate Input**: Check for formula errors before applying changes
6. **Support Keyboard Navigation**: Implement standard spreadsheet keyboard shortcuts

## Troubleshooting

### Formula Bar Not Updating

* Verify activeCell and selections are properly synced
* Check that getCellData returns the correct cell data
* Ensure onChange is called when cell values change

### Autocomplete Not Working

* Confirm functionDescriptions prop is provided
* Check that function definitions are properly formatted
* Verify the formula starts with "="

### Performance Issues

* Memoize cellValue calculation for large spreadsheets
* Use debouncing for onChange handler
* Consider lazy loading function descriptions

## See Also

* [Formula Input](https://docs.rowsncolumns.app/configuration/components/formula-input) - Standalone formula input component
* [Toolbar](https://docs.rowsncolumns.app/configuration/components/toolbar) - Toolbar component with formatting buttons
* [Canvas Grid](https://docs.rowsncolumns.app/configuration/components/canvas-grid) - Main spreadsheet grid component
