# TimeZonePicker

Import: `import { TimeZonePicker } from '@neo4j-ndl/react'`

## Props

### TimeZonePicker

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `errorText` | `string` |  |  | Manually set the error text |
| `floatingStrategy` | `'absolute' \| 'fixed'` |  |  | Strategy for the dropdown floating element. By default it is absolute, but if the component is inside of a needle Dialog, it is set to fixed. If this prop is set, no auto-detection of Dialog is done. |
| `isDisabled` | `boolean` |  |  | Whether the timezone picker is disabled |
| `isFluid` | `boolean` |  |  | Whether the timezone picker is fluid |
| `isPortaled` | `boolean` |  |  | Whether the dropdown element is rendered in a portal. |
| `isReadOnly` | `boolean` |  |  | Whether the timezone picker is read only |
| `isRequired` | `boolean` |  |  | Whether the timezone picker is required |
| `label` | `string` |  |  | The label of the timezone picker |
| `mode` | `'both' \| 'city' \| 'utc'` |  | `city` | Display mode: 'city', 'utc', or 'both' 'city' - shows city-based timezones, This should be used when the user needs to select a timezone for themselves or if they are selecting a timezone that's related to a date. 'utc' - shows UTC timezones, This should be used when the user needs to select a timezone for a database entry or a technical application. 'both' - shows both city-based and UTC timezones in separate sections, This should be used when the user needs to select a timezone for a database entry or a technical application, but also wants to see the city-based timezones for context for example a zoned date time. @example <TimeZonePicker mode="city" /> <TimeZonePicker mode="utc" /> <TimeZonePicker mode="both" /> |
| `onChange` | `((timezone: string) => void)` |  |  | Callback function triggered when the timezone picker value changes |
| `onError` | `((error: string, timezone: string) => void)` |  |  | Callback function triggered when the timezone picker encounters an error |
| `ref` | `Ref<HTMLInputElement>` |  |  | A ref to apply to the root element. |
| `referenceDate` | `Date` |  |  | Reference date for calculating timezone offsets (useful for DST-aware offset display) |
| `size` | `'large' \| 'medium' \| 'small'` |  | `medium` | The size of the timezone picker |
| `value` | `string` |  |  | The value of the timezone picker (IANA timezone identifier) |

## Examples

### Default

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { TimeZonePicker } from '@neo4j-ndl/react';
import { useState } from 'react';

const Component = () => {
  const [selectedTimeZone, setSelectedTimeZone] = useState<string>('UTC');

  const handleTimeZoneChange = (timezone: string) => {
    setSelectedTimeZone(timezone);
  };

  return (
    <div>
      <TimeZonePicker
        label="Select Timezone"
        value={selectedTimeZone}
        onChange={handleTimeZoneChange}
        htmlAttributes={{ id: 'time-zone-input' }}
      />
      <div style={{ marginTop: '1rem' }}>
        <p>Selected Timezone: {selectedTimeZone}</p>
      </div>
    </div>
  );
};

export default Component;
```

### Both Mode

```tsx
import { useState } from 'react';

import { Typography } from '../../typography';
import { TimeZonePicker } from '../TimeZonePicker';

export const TimeZonePickerBothMode = () => {
  const [selectedTimezone, setSelectedTimezone] =
    useState<string>('America/New_York');

  return (
    <div style={{ maxWidth: '400px', padding: '20px' }}>
      <Typography variant="title-4" style={{ marginBottom: '16px' }}>
        Both Mode - UTC and City-Based Timezones
      </Typography>
      <Typography variant="body-medium" style={{ marginBottom: '24px' }}>
        This mode displays both UTC offsets and city-based timezones in separate
        sections within the dropdown. Perfect for users who need flexibility in
        choosing between precise UTC offsets or familiar city names.
      </Typography>

      <TimeZonePicker
        label="Select Timezone"
        mode="both"
        value={selectedTimezone}
        onChange={(tz) => {
          setSelectedTimezone(tz);
        }}
        htmlAttributes={{ id: 'time-zone-input' }}
      />

      <div
        style={{
          backgroundColor: '#f5f5f5',
          borderRadius: '4px',
          marginTop: '24px',
          padding: '16px',
        }}
      >
        <Typography
          variant="body-small"
          style={{ fontWeight: 600, marginBottom: '8px' }}
        >
          Selected Timezone:
        </Typography>
        <Typography variant="body-medium">
          {selectedTimezone || 'None'}
        </Typography>
      </div>

      <div style={{ marginTop: '16px' }}>
        <Typography variant="body-small" style={{ color: '#666' }}>
          <strong>Features:</strong>
          <ul style={{ marginTop: '8px', paddingLeft: '20px' }}>
            <li>
              Two separate sections: &quot;UTC Offsets&quot; and
              &quot;City-Based Timezones&quot;
            </li>
            <li>Search across both sections simultaneously</li>
            <li>Custom UTC input support (e.g., UTC+5:30)</li>
            <li>All standard UTC offsets from UTC-12 to UTC+14</li>
            <li>All IANA timezone identifiers with city names</li>
          </ul>
        </Typography>
      </div>
    </div>
  );
};

export default TimeZonePickerBothMode;
```

### Disabled

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { TimeZonePicker } from '@neo4j-ndl/react';

const Component = () => {
  return (
    <TimeZonePicker
      isDisabled
      label="Disabled Timezone Picker"
      value="Asia/Tokyo"
      htmlAttributes={{ id: 'time-zone-input' }}
    />
  );
};

export default Component;
```

### Dst Aware

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { TimeZonePicker } from '@neo4j-ndl/react';
import { useState } from 'react';

const Component = () => {
  const [selectedTimeZone, setSelectedTimeZone] =
    useState<string>('Europe/Stockholm');
  const [referenceDate, setReferenceDate] = useState<Date>(
    new Date('2025-01-01'),
  );

  // Create summer and winter dates for DST demonstration
  const summerDate = new Date('2024-07-15T12:00:00'); // July (DST in effect)
  const winterDate = new Date('2024-01-15T12:00:00'); // January (Standard time)

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
      <div>
        <h3 style={{ marginBottom: '1rem' }}>DST-Aware Timezone Picker Demo</h3>
        <p style={{ color: '#666', marginBottom: '1rem' }}>
          The timezone offsets change based on the reference date to account for
          Daylight Saving Time.
        </p>
      </div>

      <div style={{ display: 'flex', gap: '1rem', marginBottom: '1rem' }}>
        <button
          type="button"
          onClick={() => setReferenceDate(summerDate)}
          style={{
            backgroundColor: referenceDate === summerDate ? '#0066cc' : 'white',
            border: '1px solid #ccc',
            borderRadius: '4px',
            color: referenceDate === summerDate ? 'white' : 'black',
            cursor: 'pointer',
            padding: '0.5rem 1rem',
          }}
        >
          Summer Date (July 15, 2024)
        </button>
        <button
          type="button"
          onClick={() => setReferenceDate(winterDate)}
          style={{
            backgroundColor: referenceDate === winterDate ? '#0066cc' : 'white',
            border: '1px solid #ccc',
            borderRadius: '4px',
            color: referenceDate === winterDate ? 'white' : 'black',
            cursor: 'pointer',
            padding: '0.5rem 1rem',
          }}
        >
          Winter Date (January 15, 2024)
        </button>
      </div>

      <TimeZonePicker
        label="Select Timezone"
        value={selectedTimeZone}
        onChange={setSelectedTimeZone}
        referenceDate={referenceDate}
        htmlAttributes={{ id: 'time-zone-input' }}
      />

      <div
        style={{
          backgroundColor: '#f5f5f5',
          borderRadius: '4px',

          padding: '1rem',
        }}
      >
        <p>
          <strong>Selected Timezone:</strong> {selectedTimeZone}
        </p>
        <p>
          <strong>Reference Date:</strong> {referenceDate.toLocaleDateString()}
        </p>
        <p>
          <strong>Example:</strong> New York shows GMT-4 in summer (EDT) and
          GMT-5 in winter (EST)
        </p>
      </div>
    </div>
  );
};

export default Component;
```

### Error

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { TimeZonePicker } from '@neo4j-ndl/react';
import { useState } from 'react';

const Component = () => {
  const [selectedTimeZone, setSelectedTimeZone] = useState<string>('UTC');

  const handleTimeZoneChange = (timezone: string) => {
    setSelectedTimeZone(timezone);
  };

  return (
    <div>
      <TimeZonePicker
        label="Select Timezone"
        value={selectedTimeZone}
        onChange={handleTimeZoneChange}
        errorText="Please select a valid timezone"
        htmlAttributes={{ id: 'time-zone-input' }}
      />
    </div>
  );
};

export default Component;
```

### Fluid

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { TimeZonePicker } from '@neo4j-ndl/react';

const Component = () => {
  return (
    <div style={{ maxWidth: '400px', width: '100%' }}>
      <TimeZonePicker
        isFluid
        label="Select Timezone"
        htmlAttributes={{ id: 'time-zone-input' }}
      />
    </div>
  );
};

export default Component;
```

### In Dialog

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import {
  Dialog,
  FilledButton,
  OutlinedButton,
  TimeZonePicker,
} from '@neo4j-ndl/react';
import { useRef, useState } from 'react';

const Component = () => {
  const [isOpen, setIsOpen] = useState<boolean>(false);
  const [selectedTimeZone, setSelectedTimeZone] = useState<string>('UTC');
  const [tempTimeZone, setTempTimeZone] = useState<string>('UTC');
  const ref = useRef<HTMLDivElement | null>(null);

  const handleOpen = () => {
    setTempTimeZone(selectedTimeZone);
    setIsOpen(true);
  };

  const handleClose = () => setIsOpen(false);

  const handleSave = () => {
    setSelectedTimeZone(tempTimeZone);
    setIsOpen(false);
  };

  const handleTimeZoneChange = (timezone: string) => {
    setTempTimeZone(timezone);
  };

  return (
    <div
      ref={ref}
      className="n-flex n-flex-col n-items-center n-justify-center n-relative n-h-[500px] n-w-full"
    >
      <div className="n-flex n-flex-col n-items-center n-gap-4">
        <FilledButton onClick={handleOpen}>Select Timezone</FilledButton>
        <div>
          <p>Selected Timezone: {selectedTimeZone}</p>
        </div>
      </div>
      <Dialog
        onClose={handleClose}
        isOpen={isOpen}
        container={ref?.current || undefined}
        size="medium"
      >
        <Dialog.Header>Select Timezone</Dialog.Header>
        <Dialog.Description>
          Choose a timezone from the list below
        </Dialog.Description>
        <Dialog.Content>
          <TimeZonePicker
            isFluid
            label="Timezone"
            value={tempTimeZone}
            onChange={handleTimeZoneChange}
            htmlAttributes={{ id: 'time-zone-input' }}
          />
        </Dialog.Content>
        <Dialog.Actions>
          <OutlinedButton onClick={handleClose} variant="neutral" size="medium">
            Cancel
          </OutlinedButton>
          <FilledButton onClick={handleSave} size="medium">
            Save
          </FilledButton>
        </Dialog.Actions>
      </Dialog>
    </div>
  );
};

export default Component;
```

### Sizes

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { TimeZonePicker } from '@neo4j-ndl/react';
import { useState } from 'react';

const Component = () => {
  const [selectedTimeZone, setSelectedTimeZone] =
    useState<string>('Europe/Stockholm');

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
      <TimeZonePicker
        label="Small"
        value={selectedTimeZone}
        onChange={setSelectedTimeZone}
        size="small"
        htmlAttributes={{ id: 'time-zone-input-small' }}
      />
      <TimeZonePicker
        label="Medium (default)"
        value={selectedTimeZone}
        onChange={setSelectedTimeZone}
        size="medium"
        htmlAttributes={{ id: 'time-zone-input-medium' }}
      />
      <TimeZonePicker
        label="Large"
        value={selectedTimeZone}
        onChange={setSelectedTimeZone}
        size="large"
        htmlAttributes={{ id: 'time-zone-input-large' }}
      />
    </div>
  );
};

export default Component;
```

### Utc Only

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { TimeZonePicker } from '@neo4j-ndl/react';
import { useState } from 'react';

const Component = () => {
  const [selectedTimeZone, setSelectedTimeZone] = useState<string>('UTC');

  const handleTimeZoneChange = (timezone: string) => {
    setSelectedTimeZone(timezone);
  };

  return (
    <div>
      <TimeZonePicker
        label="Select UTC Timezone"
        value={selectedTimeZone}
        onChange={handleTimeZoneChange}
        mode="utc"
        htmlAttributes={{ id: 'time-zone-input' }}
      />
      <div style={{ marginTop: '1rem' }}>
        <p>
          <strong>Selected Timezone:</strong> {selectedTimeZone}
        </p>
        <div
          style={{
            backgroundColor: '#f5f5f5',
            borderRadius: '4px',

            marginTop: '1rem',
            padding: '1rem',
          }}
        >
          <p>
            <strong>Features:</strong>
          </p>
          <ul
            style={{
              fontSize: '0.9em',
              margin: 0,
              paddingLeft: '1.5rem',
            }}
          >
            <li>Select from common UTC offsets (UTC-12 to UTC+14)</li>
            <li>Includes fractional offsets (UTC+5:30, UTC+9:30, etc.)</li>
            <li>Type custom offsets: UTC+1:05, UTC-3:45, etc.</li>
            <li>Ideal for database entries and technical applications</li>
          </ul>
          <p
            style={{
              color: '#999',
              fontSize: '0.85em',
              marginBottom: 0,
              marginTop: '0.5rem',
            }}
          >
            Try typing: UTC+5:30, UTC-7:15, or UTC+12:45
          </p>
        </div>
      </div>
    </div>
  );
};

export default Component;
```
