# Location picker
> Choose a point on a map.
- React: `import { GeoLocationPicker } from "@/components/lumesec/geo-location-picker"`
- Collection: Location (https://elements.lumesec.ai/components/location)
- Data: takes your data (`data`); shows demo data until you pass it
- Registry item: https://elements.lumesec.ai/r/geo-location-picker.json
- Page: https://elements.lumesec.ai/components/location/location-picker



Live preview: https://elements.lumesec.ai/view/geo-location-picker

Demo source:

```tsx
"use client";

import * as React from "react";

import { GeoLocationPicker } from "@/components/lumesec/geo-location-picker";

/** New York, one of the demo places, so the picker opens with a pin and its name under the map. */
const START = { lat: 40.7128, lon: -74.006 };

const BUTTON =
  "h-[30px] shrink-0 cursor-pointer rounded-lg border border-border bg-card px-[11px] font-[inherit] text-[12.5px] font-medium text-foreground outline-none hover:border-[color-mix(in_srgb,var(--lumesec)_50%,var(--border))] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid focus-visible:outline-lumesec";

export default function GeoLocationPickerDemo() {
  const [submitted, setSubmitted] = React.useState<string | null>(null);

  function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const data = new FormData(event.currentTarget);
    const fields = ["site-lat", "site-lon"].flatMap((key) => {
      const entry = data.get(key);
      return typeof entry === "string" ? [`${key}=${entry}`] : [];
    });
    setSubmitted(fields.join("  "));
  }

  return (
    <form onSubmit={handleSubmit} className="grid w-full max-w-[400px] gap-3">
      <GeoLocationPicker name="site" snap={25} defaultValue={START} label="Site location" />
      <div className="flex min-w-0 items-center gap-3">
        <button type="submit" className={BUTTON}>
          Submit
        </button>
        <output className="min-w-0 truncate text-[12.5px] leading-5 text-muted-foreground">
          {submitted === null ? (
            "Not submitted yet"
          ) : submitted ? (
            <>
              Submitted <span className="font-mono text-foreground tabular-nums">{submitted}</span>
            </>
          ) : (
            "Submitted without a pin"
          )}
        </output>
      </div>
    </form>
  );
}
```

## Installation

```bash
npx shadcn@latest add @lumesec/geo-location-picker
```

First time with the @lumesec registry? Register it once, or install by URL:

```bash
npx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json
npx shadcn@latest add https://elements.lumesec.ai/r/geo-location-picker.json
```

## Usage

React:

```tsx
import { GeoLocationPicker } from "@/components/lumesec/geo-location-picker";

export function Example() {
  return (
    <form>
      <GeoLocationPicker name="site" snap={25} defaultValue={{ lat: 6.5244, lon: 3.3792 }} required />
    </form>
  );
}
```

## Behaviour

Choose a point on a map. Click or tap to drop the pin, search for a place, or type exact coordinates into the latitude and longitude fields.

The pin drops on a bouncy spring and lands with a splash: the dots around it are pushed outward in a ring like water, and the coordinates roll to the new values. Picking a search result flies the map there and zooms in so you can place the pin precisely.

## API reference

### Ref

`ref` points at the root `HTMLDivElement`.

## Theming

Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from `--lumesec`. See [Theming](/docs/theming).


