# `PhiaUi.Components.PivotTable`
[🔗](https://github.com/charlenopires/PhiaUI/blob/v0.1.17/lib/phia_ui/components/data/pivot_table.ex#L1)

Cross-tabulation (pivot) table — rows × columns matrix display.

Renders a data matrix where row headers and column headers define the axes,
and `data` provides the values at each intersection. Supports optional
heatmap coloring, value formatting, and row/column totals.

## Sub-components

| Function           | HTML element | Purpose                                    |
|--------------------|--------------|---------------------------------------------|
| `pivot_table/1`    | `<table>`    | Full matrix table with optional totals      |
| `pivot_cell/1`     | `<td>`       | Data cell with optional heatmap background  |
| `pivot_row_header/1`| `<th>`      | Sticky first-column row label               |

## Data format

The `data` attr accepts either:

- **Map** keyed by `{row_key, col_key}` tuples:
  ```elixir
  %{
    {"north", "q1"} => 1200,
    {"north", "q2"} => 1450,
    {"south", "q1"} => 980,
  }
  ```

- **Function** `fn row_key, col_key -> value end`:
  ```elixir
  fn region, quarter -> Stats.revenue(region, quarter) end
  ```

Missing keys return `0` for maps or `nil` for functions.

## Example

    <.pivot_table
      row_headers={[
        %{key: "north", label: "North"},
        %{key: "south", label: "South"},
        %{key: "east", label: "East"},
      ]}
      col_headers={[
        %{key: "q1", label: "Q1"},
        %{key: "q2", label: "Q2"},
        %{key: "q3", label: "Q3"},
        %{key: "q4", label: "Q4"},
      ]}
      data={@revenue_map}
      format={:currency}
      heatmap
      row_totals
      col_totals
    />

# `pivot_cell`

Renders a single pivot table data cell.

Uses `tabular-nums` font variant for aligned numeric values. Accepts an
optional `heatmap_class` for background intensity colouring.

## Example

    <.pivot_cell
      value={1450}
      formatted="$1,450"
      heatmap_class="bg-primary/40"
    />

## Attributes

* `value` (`:any`) (required) - Raw cell value (number, string, or nil).
* `formatted` (`:string`) - Pre-formatted display string. If `nil`, falls back to `to_string(@value)`. Defaults to `nil`.
* `heatmap_class` (`:any`) - Optional Tailwind background class for heatmap intensity (e.g. `"bg-primary/40"`). Defaults to `nil`.
* `align` (`:atom`) - Text alignment — defaults to `:right` for numeric data. Defaults to `:right`. Must be one of `:left`, `:right`, or `:center`.
* `class` (`:string`) - Additional CSS classes for the `<td>`. Defaults to `nil`.

# `pivot_row_header`

Renders the sticky first-column row header cell.

Uses `position: sticky; left: 0` via Tailwind's `sticky left-0` utilities,
with `bg-background` to cover scrolled content. `whitespace-nowrap` prevents
label wrapping that would grow the column unpredictably.

## Example

    <.pivot_row_header label="North America" />

## Attributes

* `label` (`:string`) (required) - Row label text for the sticky first column.
* `class` (`:string`) - Additional CSS classes for the `<th>`. Defaults to `nil`.

# `pivot_table`

Renders a full cross-tabulation matrix table.

The first column (`pivot_row_header/1`) is `position: sticky; left: 0` so
it stays visible when the table scrolls horizontally. All cells use
`tabular-nums` for aligned numeric values.

## Example

    <.pivot_table
      row_headers={@regions}
      col_headers={@quarters}
      data={@revenue_map}
      format={:currency}
      heatmap
      row_totals
    />

## Attributes

* `row_headers` (`:list`) (required) - List of `%{key: any, label: string}` maps defining the row axis.
* `col_headers` (`:list`) (required) - List of `%{key: any, label: string}` maps defining the column axis.
* `data` (`:any`) (required) - Data source. Either a map keyed by `{row_key, col_key}` tuples, or a
  function `fn row_key, col_key -> value end`.

* `heatmap` (`:boolean`) - When `true`, cells are coloured with a `primary` intensity scale based on
  their relative value within the min–max range of all cells.

  Defaults to `false`.
* `format` (`:atom`) - Value formatting:
  - `:default` — `to_string/1`
  - `:number` — plain numeric string
  - `:percent` — appends `%` with one decimal place
  - `:currency` — prepends `$` with two decimal places

  Defaults to `:default`. Must be one of `:default`, `:percent`, `:currency`, or `:number`.
* `row_totals` (`:boolean`) - When `true`, appends a totals column on the right. Defaults to `false`.
* `col_totals` (`:boolean`) - When `true`, appends a totals row at the bottom. Defaults to `false`.
* `class` (`:string`) - Additional CSS classes for the outer wrapper div. Defaults to `nil`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
