Files
supabase/apps/studio/components/interfaces/UserDropdown/TimezoneDropdown.tsx
Gildas Garcia 243e079a2c chore: remove _Shadcn_ suffix from Command components (#46153)
## Problem

The `_Shadcn_` suffix isn't needed anymore on `Command` components

## Solution

- Remove the `_Shadcn_` suffix
- Simplify UI package exports
- Apply prettier

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Simplified command component imports and exports across the UI library
by removing internal naming aliases and adopting direct component
references. Updated the public UI package barrel export to use wildcard
re-exports for cleaner API surface.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46153?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-20 15:45:32 +02:00

114 lines
4.0 KiB
TypeScript

import { CheckIcon } from 'lucide-react'
import { useMemo, useState } from 'react'
import {
cn,
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
DropdownMenuPortal,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
ScrollArea,
} from 'ui'
import { findTimezoneByIana, TIMEZONES_BY_IANA } from '@/lib/constants/timezones'
import { useTimezone } from '@/lib/datetime'
import { guessLocalTimezone } from '@/lib/dayjs'
import { useTrack } from '@/lib/telemetry/track'
const AUTO_OPTION_VALUE = '__auto__'
export const TimezoneDropdown = () => {
const { timezone, storedTimezone, setTimezone, isAutoDetected } = useTimezone()
const track = useTrack()
const [open, setOpen] = useState(false)
// The "Auto detect" row always advertises the browser's own timezone, even
// when the user is currently overriding it with a manual pick.
const browserTimezone = useMemo(() => guessLocalTimezone(), [])
const triggerLabel = useMemo(() => {
return findTimezoneByIana(timezone)?.text ?? timezone
}, [timezone])
const handleSelect = (nextStored: string) => {
setTimezone(nextStored)
const resolvedNext = nextStored || guessLocalTimezone()
track('timezone_picker_clicked', {
previousTimezone: timezone,
nextTimezone: resolvedNext,
isAutoDetected: nextStored === '',
source: 'user_dropdown',
})
setOpen(false)
}
return (
<DropdownMenuSub open={open} onOpenChange={setOpen}>
<DropdownMenuSubTrigger className="flex gap-2 cursor-pointer">
<div className="flex flex-col min-w-0">
<span>Timezone</span>
<span className="text-xs text-foreground-lighter truncate" title={triggerLabel}>
{isAutoDetected ? `Auto (${timezone})` : triggerLabel}
</span>
</div>
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent className="p-0 w-[320px]" sideOffset={4}>
<Command>
<CommandInput placeholder="Search timezone..." className="h-9" />
<CommandList>
<CommandEmpty>No timezones found</CommandEmpty>
<CommandGroup>
<ScrollArea className="h-72">
<CommandItem
key={AUTO_OPTION_VALUE}
value={`Auto detect ${browserTimezone}`}
onSelect={() => handleSelect('')}
>
<div className="flex flex-col">
<span>Auto detect</span>
<span className="text-xs text-foreground-lighter">{browserTimezone}</span>
</div>
<CheckIcon
className={cn(
'ml-auto h-4 w-4',
isAutoDetected ? 'opacity-100' : 'opacity-0'
)}
/>
</CommandItem>
{TIMEZONES_BY_IANA.map((entry) => {
const ianaName = entry.utc[0]
const isSelected = !isAutoDetected && storedTimezone === ianaName
return (
<CommandItem
key={ianaName}
// CommandItem matches against the `value` prop for the input filter — include
// both the human label and the IANA name so search works for either.
value={`${entry.text} ${ianaName}`}
onSelect={() => handleSelect(ianaName)}
>
{entry.text}
<CheckIcon
className={cn(
'ml-auto h-4 w-4',
isSelected ? 'opacity-100' : 'opacity-0'
)}
/>
</CommandItem>
)
})}
</ScrollArea>
</CommandGroup>
</CommandList>
</Command>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
)
}