# Meeting planner
> Several cities on one time line, one row per city, with each hour drawn as a block of dots: dense for working hours, sparse for the night.
- React: `import { GeoTimezones } from "@/components/lumesec/geo-timezones"`
- 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-timezones.json
- Page: https://elements.lumesec.ai/components/location/timezones



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

Demo source:

```tsx
"use client";

import * as React from "react";

import { GeoTimezones, type TimeZoneCity } from "@/components/lumesec/geo-timezones";

const BUTTON =
  "h-[30px] 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 disabled:cursor-default disabled:opacity-50 disabled:hover:border-border";

const CITIES: readonly TimeZoneCity[] = [
  { id: "london", label: "London", timeZone: "Europe/London" },
  { id: "berlin", label: "Berlin", timeZone: "Europe/Berlin" },
  { id: "new-york", label: "New York", timeZone: "America/New_York" },
  { id: "sao-paulo", label: "São Paulo", timeZone: "America/Sao_Paulo" },
];

const EXTRA_CITIES: readonly TimeZoneCity[] = [
  { id: "singapore", label: "Singapore", timeZone: "Asia/Singapore" },
  { id: "tokyo", label: "Tokyo", timeZone: "Asia/Tokyo" },
];

export default function GeoTimezonesDemo() {
  const [cities, setCities] = React.useState<readonly TimeZoneCity[]>(CITIES);

  return (
    <div className="grid w-full max-w-[660px] justify-items-center gap-3">
      <GeoTimezones cities={cities} onCitiesChange={setCities} removable />
      <div className="flex flex-wrap justify-center gap-2">
        {EXTRA_CITIES.map((city) => (
          <button
            key={city.id}
            type="button"
            disabled={cities.some((entry) => entry.id === city.id)}
            onClick={() => setCities((current) => (current.some((entry) => entry.id === city.id) ? current : [...current, city]))}
            className={BUTTON}
          >
            Add {city.label}
          </button>
        ))}
        <button
          type="button"
          disabled={cities === CITIES}
          onClick={() => setCities(CITIES)}
          className={BUTTON}
        >
          Reset
        </button>
      </div>
    </div>
  );
}
```

## Installation

```bash
npx shadcn@latest add @lumesec/geo-timezones
```

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-timezones.json
```

## Usage

React:

```tsx
"use client";

import * as React from "react";

import { GeoTimezones, type TimeZoneCity } from "@/components/lumesec/geo-timezones";

const team: TimeZoneCity[] = [
  { id: "lon", label: "London", timeZone: "Europe/London" },
  { id: "nyc", label: "New York", timeZone: "America/New_York" },
  { id: "blr", label: "Bengaluru", timeZone: "Asia/Kolkata" },
];

export function Example() {
  const [meeting, setMeeting] = React.useState<Date | null>(null);
  return (
    <div className="grid gap-2">
      <GeoTimezones defaultCities={team} reference="lon" onValueChange={(time) => setMeeting(new Date(time))} />
      <p className="text-sm text-muted-foreground">{meeting ? meeting.toISOString() : "Drag the cursor to pick a time."}</p>
    </div>
  );
}
```

## Behaviour

Several cities on one time line, one row per city, with each hour drawn as a block of dots: dense for working hours, sparse for the night. Drag the cursor across the rows and every city's local time rolls with it.

Hours when every city is at work light up as a band across all rows, and a light runs down the band when the cursor enters it. Offsets come from the time zone database, so daylight saving time is handled.

## 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).


