Files
supabase/apps/studio/components/interfaces/Account/Preferences/TimezoneSettings.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

164 lines
6.1 KiB
TypeScript

import { useFlag } from 'common'
import { CheckIcon, ChevronsUpDown, Globe } from 'lucide-react'
import { useId, useMemo, useState } from 'react'
import {
Button,
Card,
CardContent,
cn,
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
Popover,
PopoverContent,
PopoverTrigger,
ScrollArea,
} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import {
PageSection,
PageSectionContent,
PageSectionDescription,
PageSectionMeta,
PageSectionSummary,
PageSectionTitle,
} from 'ui-patterns/PageSection'
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 TimezoneSettings = () => {
const timezonePickerEnabled = useFlag('timezonePicker')
const { timezone, storedTimezone, setTimezone, isAutoDetected } = useTimezone()
const track = useTrack()
const [open, setOpen] = useState(false)
const listboxId = useId()
// Browser timezone is captured once and stays stable even when the user has
// overridden the dashboard timezone — that's the value the "Auto detect"
// option will revert to.
const browserTimezone = useMemo(() => guessLocalTimezone(), [])
const triggerLabel = useMemo(() => findTimezoneByIana(timezone)?.text ?? timezone, [timezone])
if (!timezonePickerEnabled) return null
const handleSelect = (nextStored: string) => {
setTimezone(nextStored)
const resolvedNext = nextStored || guessLocalTimezone()
track('timezone_picker_clicked', {
previousTimezone: timezone,
nextTimezone: resolvedNext,
isAutoDetected: nextStored === '',
source: 'account_preferences',
})
setOpen(false)
}
return (
<PageSection>
<PageSectionMeta>
<PageSectionSummary>
<PageSectionTitle>Timezone</PageSectionTitle>
<PageSectionDescription>
Choose how dates and times in logs and other dashboard surfaces are displayed.
</PageSectionDescription>
</PageSectionSummary>
</PageSectionMeta>
<PageSectionContent>
<Card>
<CardContent>
<FormItemLayout
isReactForm={false}
label="Display timezone"
layout="flex-row-reverse"
description={
isAutoDetected
? `Auto detected from your browser (${browserTimezone}).`
: 'Pick "Auto detect" to follow your browser timezone again.'
}
>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
role="combobox"
aria-expanded={open}
aria-controls={listboxId}
className="w-full justify-between"
type="default"
size="small"
icon={<Globe />}
iconRight={<ChevronsUpDown size={14} strokeWidth={1.5} />}
>
<span className="truncate text-left">
{isAutoDetected ? `Auto detect (${timezone})` : triggerLabel}
</span>
</Button>
</PopoverTrigger>
<PopoverContent id={listboxId} className="w-[--radix-popover-trigger-width] p-0">
<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>
</PopoverContent>
</Popover>
</FormItemLayout>
</CardContent>
</Card>
</PageSectionContent>
</PageSection>
)
}