TimezoneSelection.tsx91 lines · main
1import { CheckIcon, ChevronsUpDown, Globe } from 'lucide-react'
2import { useId, useState } from 'react'
3import {
4 Button,
5 cn,
6 Command,
7 CommandEmpty,
8 CommandGroup,
9 CommandInput,
10 CommandItem,
11 CommandList,
12 Popover,
13 PopoverContent,
14 PopoverTrigger,
15 ScrollArea,
16} from 'ui'
17
18import { ALL_TIMEZONES } from './PITR.constants'
19import type { Timezone } from './PITR.types'
20
21interface TimezoneSelectionProps {
22 selectedTimezone: Timezone
23 onSelectTimezone: (timezone: Timezone) => void
24}
25
26export const TimezoneSelection = ({
27 selectedTimezone,
28 onSelectTimezone,
29}: TimezoneSelectionProps) => {
30 const [open, setOpen] = useState(false)
31 const listboxId = useId()
32
33 const timezoneOptions = ALL_TIMEZONES.map((option) => option.text)
34
35 return (
36 <div className="w-full">
37 <Popover open={open} onOpenChange={setOpen}>
38 <PopoverTrigger asChild>
39 <Button
40 role="combobox"
41 aria-expanded={open}
42 aria-controls={listboxId}
43 className="w-[350px] justify-between"
44 size="small"
45 icon={<Globe />}
46 iconRight={<ChevronsUpDown size={14} strokeWidth={1.5} />}
47 >
48 {selectedTimezone
49 ? timezoneOptions.find((option) => option === selectedTimezone.text)
50 : 'Select timezone...'}
51 </Button>
52 </PopoverTrigger>
53 <PopoverContent id={listboxId} className="w-[350px] p-0">
54 <Command>
55 <CommandInput placeholder="Search timezone..." className="h-9" />
56 <CommandList>
57 <CommandEmpty>No timezones found...</CommandEmpty>
58 <CommandGroup>
59 <ScrollArea className="h-72">
60 {timezoneOptions.map((option) => (
61 <CommandItem
62 key={option}
63 value={option}
64 onSelect={(text) => {
65 const selectedTimezone = ALL_TIMEZONES.find(
66 (option) => option.text === text
67 )
68 if (selectedTimezone) {
69 onSelectTimezone(selectedTimezone)
70 setOpen(false)
71 }
72 }}
73 >
74 {option}
75 <CheckIcon
76 className={cn(
77 'ml-auto h-4 w-4',
78 selectedTimezone.text === option ? 'opacity-100' : 'opacity-0'
79 )}
80 />
81 </CommandItem>
82 ))}
83 </ScrollArea>
84 </CommandGroup>
85 </CommandList>
86 </Command>
87 </PopoverContent>
88 </Popover>
89 </div>
90 )
91}