# MapLayerPanel

## Overview

`MapLayerPanel` shows and hides the named layers of a map. With four overlays on screen at once — heat underneath, areas, lines, points on top — the stack stops being an implementation detail and becomes the thing the user operates. Each row carries the layer's label, its color swatch and a switch, grouped by `group`.

---

## Import

```tsx
import { MapLayerPanel, type MapDataLayer } from 'xertica-ui/ui';
```

---

## Prerequisites

- Import `xertica-ui/style.css` once at the app root.
- Pass the same `MapDataLayer[]` to `<Map dataLayers>` and to this panel.
- For `variant="overlay"`, wrap the map and the panel in a container with `position: relative`.

> **`dataLayers` is not `layers`.** `<Map layers>` already means Google's native traffic / transit / bicycling overlays and could not change meaning without breaking working code. The two props are unrelated.

---

## Props

| Prop        | Type                                     | Default        | Description                                 |
| ----------- | ---------------------------------------- | -------------- | ------------------------------------------- |
| `layers`    | `MapDataLayer[]`                         | required       | The same array given to `<Map dataLayers>`. |
| `onToggle`  | `(id: string, visible: boolean) => void` | required       | Called with the layer's new state.          |
| `title`     | `string`                                 | -              | Heading, also used as the accessible name.  |
| `variant`   | `'inline' \| 'overlay'`                  | `'inline'`     | `overlay` floats over the map.              |
| `position`  | `MapOverlayPosition`                     | `'top-right'`  | Anchor for `variant="overlay"`.             |
| `ariaLabel` | `string`                                 | `"Map layers"` | Accessible name when no `title` is shown.   |

### `MapDataLayer`

| Field        | Type         | Description                                        |
| ------------ | ------------ | -------------------------------------------------- |
| `id`         | `string`     | Referenced by `layerId` on markers and geometries. |
| `label`      | `string`     | Row text.                                          |
| `group`      | `string`     | Optional heading the layer is filed under.         |
| `colorToken` | `ColorToken` | Swatch beside the label.                           |
| `visible`    | `boolean`    | Defaults to `true` when omitted.                   |
| `zIndex`     | `number`     | Stacking order for everything in the layer.        |
| `opacity`    | `number`     | Multiplied with each feature's own opacity.        |

---

## Example

```tsx
const [layers, setLayers] = useState<MapDataLayer[]>([
  { id: 'alvos', label: 'Alvos', group: 'Investigação', colorToken: '--chart-1', zIndex: 40 },
  {
    id: 'setores',
    label: 'Setores de cobertura',
    group: 'Território',
    colorToken: '--chart-2',
    zIndex: 20,
  },
  {
    id: 'densidade',
    label: 'Densidade',
    group: 'Território',
    colorToken: '--destructive',
    zIndex: 10,
    visible: false,
  },
]);

const toggle = (id: string, visible: boolean) =>
  setLayers(current => current.map(l => (l.id === id ? { ...l, visible } : l)));

<div className="relative">
  <Map height="520px" dataLayers={layers} markers={markers} polygons={sectors} heatmap={heat} />
  <MapLayerPanel
    variant="overlay"
    position="top-right"
    title="Camadas"
    layers={layers}
    onToggle={toggle}
  />
</div>;
```

---

## AI Rules

- **Always** pass the same `layers` array to `<Map dataLayers>` and to the panel.
- **Always** join features to a layer with `layerId` — markers, `polygons` and `circles` all accept it.
- **Always** set `zIndex` per layer when more than two overlays are visible at once.
- **Never** confuse `dataLayers` with `layers`. The latter is Google's native traffic/transit/bicycling toggle.
- **Never** hold visibility state inside the panel — it is controlled, and the map must read the same array.
- Common mistake: hiding a layer by filtering the features out of `markers`. Set `visible: false` on the layer instead, or the fit and the feature list will disagree with the map.
