# MapLocateControl

## Overview

`MapLocateControl` centres the map on the device's position and reports the accuracy alongside it. Every failure mode is classified rather than swallowed: a denied permission, a timeout and an absent provider are three different situations for the user.

---

## Import

```tsx
import { Map, MapLocateControl, useDeviceLocation } from 'xertica-ui/ui';
```

---

## Props

| Prop                 | Type                                              | Default                        | Description                        |
| -------------------- | ------------------------------------------------- | ------------------------------ | ---------------------------------- |
| `onLocate`           | `(position, meta: DeviceLocationReading) => void` | required                       | Fires on a successful reading.     |
| `onError`            | `(status: DeviceLocationStatus, message) => void` | -                              | Fires on every failure.            |
| `label`              | `string`                                          | `"Use my location"`            | Accessible name.                   |
| `deniedLabel`        | `string`                                          | `"Location permission denied"` | Shown when permission was refused. |
| `variant`            | `'overlay' \| 'inline'`                           | `'overlay'`                    | `inline` flows in normal layout.   |
| `position`           | `MapOverlayPosition`                              | `'bottom-right'`               | Anchor for `variant="overlay"`.    |
| `enableHighAccuracy` | `boolean`                                         | `true`                         | Passed to the Geolocation API.     |

On `<Map>`: `deviceLocation={{ position, accuracyMeters, mocked }}`.

`useDeviceLocation(options)` returns `{ locate, status, reading, error }` for callers who want the reading without this button.

---

## Example

```tsx
const [device, setDevice] = useState<MapProps['deviceLocation']>(null);

<Map height="480px" deviceLocation={device} markers={markers}>
  <MapLocateControl
    onLocate={(position, meta) =>
      setDevice({ position, accuracyMeters: meta.accuracyMeters, mocked: meta.mocked })
    }
    onError={status => toast.error(t(`location.${status}`))}
  />
</Map>;
```

---

## AI Rules

- **Always** feed the reading into `<Map deviceLocation>` so the accuracy halo is drawn.
- **Always** handle `onError`. A silent failure leaves the user tapping a dead button.
- **Always** show `accuracyMeters`. A coordinate without its accuracy overstates precision.
- **Never** treat `mocked === false` as proof the coordinate is genuine — only some platforms report the flag. Deployments that must reject simulated coordinates need server-side corroboration as well.
- When `mocked` is true, `<Map>` renders the marker in a destructive state with a permanent caption. That is intentional: a simulated coordinate must be visible in the interface, not merely caught by a silent validation.
