# MapLegend

## Overview

`MapLegend` reads the color and size encodings of a map. It renders two independent keys: a **color key** (one entry per series or choropleth class) and a **size key** (what the radius of a proportional symbol means). Both derive from the same sources as the map itself, so the legend cannot drift out of step with the symbols it describes.

---

## Import

```tsx
import { MapLegend, type MapLegendItem, type MapLegendSizeKey } from 'xertica-ui/ui';
```

---

## Prerequisites

- Import `xertica-ui/style.css` once at the app root.
- For `variant="overlay"`, wrap the map and the legend in a container with `position: relative`.
- For a size key, keep a single `MapScale` object and pass it to both `markers[].scale` and `sizeKey.scale`.

---

## Props

| Prop        | Type                    | Default         | Description                                                     |
| ----------- | ----------------------- | --------------- | --------------------------------------------------------------- |
| `variant`   | `'inline' \| 'overlay'` | `'inline'`      | `overlay` floats over the map; `inline` flows in normal layout. |
| `position`  | `MapOverlayPosition`    | `'bottom-left'` | Anchor for `variant="overlay"`. One of nine.                    |
| `items`     | `MapLegendItem[]`       | `[]`            | Color key entries.                                              |
| `sizeKey`   | `MapLegendSizeKey`      | -               | Size key for proportional symbols.                              |
| `title`     | `string`                | -               | Heading, also used as the accessible name.                      |
| `ariaLabel` | `string`                | `"Map legend"`  | Accessible name when no `title` is shown.                       |

### `MapLegendItem`

| Field         | Type                                      | Description                                        |
| ------------- | ----------------------------------------- | -------------------------------------------------- |
| `colorToken`  | `ColorToken`                              | CSS custom property name, e.g. `'--chart-1'`.      |
| `label`       | `string`                                  | Required.                                          |
| `shape`       | `'circle' \| 'square' \| 'line' \| 'pin'` | Glyph. Default `'circle'`.                         |
| `fillOpacity` | `number`                                  | Match the feature being described. Default `0.85`. |

### `MapLegendSizeKey`

| Field         | Type         | Description                                               |
| ------------- | ------------ | --------------------------------------------------------- |
| `values`      | `number[]`   | Representative values to draw, smallest first.            |
| `scale`       | `MapScale`   | The same scale the markers use. `scale.value` is ignored. |
| `unit`        | `string`     | Appended after each value.                                |
| `colorToken`  | `ColorToken` | Color of the sample discs. Default `'--primary'`.         |
| `fillOpacity` | `number`     | Default `0.45`.                                           |

---

## Example

```tsx
import { Map, MapLegend, type MapScale } from 'xertica-ui/ui';

const scale: MapScale = { value: 0, domain: [0, 900], range: [6, 24], method: 'sqrt' };

<div className="relative">
  <Map
    height="520px"
    fitTo="markers"
    markers={data.map(d => ({
      id: d.id,
      position: d.position,
      shape: 'circle',
      scale: { ...scale, value: d.total },
      colorToken: '--chart-1',
      fillOpacity: 0.45,
    }))}
  />
  <MapLegend
    variant="overlay"
    position="bottom-left"
    title="Atendimentos no mês"
    items={[
      { colorToken: '--chart-2', label: 'Regular' },
      { colorToken: '--destructive', label: 'Irregular' },
    ]}
    sizeKey={{ values: [41, 233, 874], scale, unit: 'un.', colorToken: '--chart-1' }}
  />
</div>;
```

---

## AI Rules

- **Always** build `sizeKey.scale` from the same `MapScale` object passed to `markers[].scale`. A legend built from a different scale silently misreports every symbol on the map.
- **Always** use `colorToken`, never a hex literal — the legend must follow the theme along with the map it describes.
- **Always** wrap the map and the legend in a `relative` container when using `variant="overlay"`.
- **Never** ship a proportional-symbol map without a size key. A disc twice as wide means nothing until the scale is stated.
- **Never** hand-roll a legend as a row of `<span>`s with colored dots — that is exactly the duplication this component exists to remove.
- Common mistake: passing `items` whose labels describe sizes rather than colors. Sizes belong in `sizeKey`; `items` is the color key.
