From fce9d475ee22ddfd7c8e0616a5600eac24db3370 Mon Sep 17 00:00:00 2001
From: Danny White <3104761+dnywh@users.noreply.github.com>
Date: Wed, 9 Sep 2026 17:36:35 +1000
Subject: [PATCH] chore(studio): migrate combobox triggers (#50157)
## What kind of change does this PR introduce?
Studio UI consistency refactor.
## What is the current behaviour?
Several Studio comboboxes still build their triggers from `Button` and
supply their own double-chevron icon. This duplicates trigger styling
and allows these controls to drift from selects and other comboboxes.
## What is the new behaviour?
- Migrates the PITR timezone, AWS region, and account timezone controls
to `ComboboxTrigger`
- Migrates the shared `SchemaSelector` and `FunctionSelector`, updating
their Studio callsites together
- Preserves the globe icon in both timezone controls
- Exposes the correct combobox role and open state through the shared
trigger
- Tightens the tiny schema selector end padding so its chevron aligns
with adjacent controls
- Leaves organisation and project context switchers unchanged
| Before | After |
| --- | --- |
| | |
| | |
## To test
On the [Studio
preview](https://studio-staging-git-dnywh-choremigrate-combobox-680102-supabase.vercel.app):
1. Open **Database > Tables** and use the schema selector above the
table. It should use a single down chevron, open normally, and update
the selected schema.
2. Open **Authentication > Hooks > Add hook**, then select **Postgres**
as the hook type. The **Postgres schema** and **Postgres function**
selectors should use a single down chevron and continue to open and
select normally.
The PITR, AWS region, and account timezone callsites require the
relevant plan, integration, or feature flag. When available, their
triggers should use the same single down chevron, and both timezone
controls should retain the globe icon.
## Summary by CodeRabbit
* **UI Improvements**
* Standardized timezone, AWS region, database backup, function, and
schema selectors with a consistent combobox interface.
* Added clear visual feedback for open and closed selector states.
* Preserved contextual icons and labels, including globe icons for
timezone selections.
* Improved accessibility with appropriate combobox semantics, accessible
names, and state information.
* Timezone settings are now available without an optional feature flag.
* **Tests**
* Updated end-to-end coverage for the standardized combobox controls.
* Added coverage confirming schema selectors expose the selected schema
as an accessible name.
---------
Co-authored-by: Joshen Lim
---
.../Account/Preferences/TimezoneSettings.tsx | 29 +++++++---------
.../ThirdPartyAuthForm/AwsRegionSelector.tsx | 16 ++++-----
.../Backups/PITR/TimezoneSelection.tsx | 26 +++++++-------
.../studio/components/ui/FunctionSelector.tsx | 27 +++++++--------
.../components/ui/SchemaSelector.test.tsx | 8 +++++
apps/studio/components/ui/SchemaSelector.tsx | 34 +++++++++++--------
e2e/studio/features/rls-policies.spec.ts | 6 ++--
7 files changed, 74 insertions(+), 72 deletions(-)
diff --git a/apps/studio/components/interfaces/Account/Preferences/TimezoneSettings.tsx b/apps/studio/components/interfaces/Account/Preferences/TimezoneSettings.tsx
index bc21899f4ab..e7be5ec816a 100644
--- a/apps/studio/components/interfaces/Account/Preferences/TimezoneSettings.tsx
+++ b/apps/studio/components/interfaces/Account/Preferences/TimezoneSettings.tsx
@@ -1,11 +1,10 @@
-import { useFlag } from 'common'
-import { CheckIcon, ChevronsUpDown, Globe } from 'lucide-react'
+import { CheckIcon, Globe } from 'lucide-react'
import { useId, useMemo, useState } from 'react'
import {
- Button,
Card,
CardContent,
cn,
+ ComboboxTrigger,
Command,
CommandEmpty,
CommandGroup,
@@ -35,11 +34,10 @@ 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()
+ const [open, setOpen] = useState(false)
+ const { timezone, storedTimezone, setTimezone, isAutoDetected } = useTimezone()
// Browser timezone is captured once and stays stable even when the user has
// overridden the dashboard timezone — that's the value the "Auto detect"
@@ -48,8 +46,6 @@ export const TimezoneSettings = () => {
const triggerLabel = useMemo(() => findTimezoneByIana(timezone)?.text ?? timezone, [timezone])
- if (!timezonePickerEnabled) return null
-
const handleSelect = (nextStored: string) => {
setTimezone(nextStored)
const resolvedNext = nextStored || guessLocalTimezone()
@@ -87,20 +83,19 @@ export const TimezoneSettings = () => {
>
- }
- iconRight={}
>
-
- {isAutoDetected ? `Auto detect (${timezone})` : triggerLabel}
+
+
+
+ {isAutoDetected ? `Auto detect (${timezone})` : triggerLabel}
+
-
+
diff --git a/apps/studio/components/interfaces/Auth/ThirdPartyAuthForm/AwsRegionSelector.tsx b/apps/studio/components/interfaces/Auth/ThirdPartyAuthForm/AwsRegionSelector.tsx
index c957e302795..3f2a22231ee 100644
--- a/apps/studio/components/interfaces/Auth/ThirdPartyAuthForm/AwsRegionSelector.tsx
+++ b/apps/studio/components/interfaces/Auth/ThirdPartyAuthForm/AwsRegionSelector.tsx
@@ -1,8 +1,8 @@
-import { Check, ChevronsUpDown } from 'lucide-react'
+import { Check } from 'lucide-react'
import { useId, useState } from 'react'
import {
- Button,
cn,
+ ComboboxTrigger,
Command,
CommandEmpty,
CommandGroup,
@@ -62,19 +62,15 @@ export const AwsRegionSelector = ({
-
- }
>
{value ?? 'Select a region'}
-
+
diff --git a/apps/studio/components/interfaces/Database/Backups/PITR/TimezoneSelection.tsx b/apps/studio/components/interfaces/Database/Backups/PITR/TimezoneSelection.tsx
index 6a40d086032..935cb9478d9 100644
--- a/apps/studio/components/interfaces/Database/Backups/PITR/TimezoneSelection.tsx
+++ b/apps/studio/components/interfaces/Database/Backups/PITR/TimezoneSelection.tsx
@@ -1,8 +1,8 @@
-import { CheckIcon, ChevronsUpDown, Globe } from 'lucide-react'
+import { CheckIcon, Globe } from 'lucide-react'
import { useId, useState } from 'react'
import {
- Button,
cn,
+ ComboboxTrigger,
Command,
CommandEmpty,
CommandGroup,
@@ -36,20 +36,22 @@ export const TimezoneSelection = ({