@neo4j-ndl/react
Version:
React implementation of Neo4j Design System
497 lines (423 loc) • 14.6 kB
Markdown
# 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: "UTC Offsets" and
"City-Based Timezones"
</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;
```