## Context
Part of consolidating all our code editors - removes all direct renders
of the `Editor` component and use `CodeEditor` instead
## UIs affected
- [ ] Query performance advisor -> query block
- [ ] Table Editor -> Table definition
- [ ] Table Editor -> Text + JSON editor (From RowEditorSidePanel,
expand input field)
- [ ] Auth -> RLS -> Create/edit policy code sections
- [ ] Storage policies -> Anywhere that has a code section
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Rolled out a consistent PostgreSQL code editor experience across
policy, storage policy, trigger function, table definitions, and query
performance screens.
* Updated policy/template previews to use the shared editor for cleaner
read-only viewing.
* **Bug Fixes**
* Removed extra left padding in the query performance editor wrapper.
* Improved the JSON editor action control with clearer icon behavior.
* **Refactor**
* Standardized editor usage by replacing legacy SQL/Monaco-based editors
with the shared CodeEditor and simplifying related editor components.
* Updated CodeEditor capabilities (read-only handling, wrapper styling,
markdown support) and tightened editor prop contracts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Context
Storage settings "Global file size limit" field goes off the card on
smaller viewports
<img width="1592" height="1258" alt="image"
src="https://github.com/user-attachments/assets/bdc58ff1-f54a-4e09-adc8-79c8a1a0b3f1"
/>
Just removes a className on the FormItemLayout that's causing it - have
verified that doesn't cause other issues
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Updated the layout configuration of the Global file size limit field
in Storage Settings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
Our `<Button>` component breaks the default `button` contract by
redefining the `type` prop to set its variant (`primary`, `default`,
etc) instead of the button type (`submit`, `button`, etc).
This is confusing and forces to write more code when using it with
shadcn components that expect/inject the standard button props.
## Solution
- rename the `type` prop to `variant`
- rename the `htmlType` prop to `type`
- propagate the changes where necessary
- format code
## How to test
As this is just prop renaming, if it builds it's ok
---------
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
## Context
Just some clean up as I was going through stuff
- `useExecuteSqlQuery` is deprecated and not used at all
- As such `execute-sql-query` is technically irrelevant, the more
relevant file is `execute-sql-mutation`
- Hence opting to consolidate `execute-sql-query` into
`execute-sql-mutation`
- Also removing `ExecuteSqlError` since its just re-exporting the
`ResponseError` type
There's a lot of file changes but its essentially just updating the
importing statements across the files
## Problem
- API may return a non-array shape that can crash `getKeys` because of
an hard coded cast
- getting API keys is cumbersome as consumers have to call two functions
## Solution
- consolidate `useAPIKeysQuery` + `getKeys` into a single `useAPIKeys`
hook
- guard `getKeys` so that it doesn't crash if passed a non array value
- update usages
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Unified how project API keys are retrieved across the studio,
resulting in more consistent loading/error handling and slight
responsiveness improvements when showing keys and related command
snippets. UI and permissions behavior remain unchanged for end users.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
- Noticing our code we have many patterns of calling localstorage and
handling those errors
- We should add those in a single well tested file
- Handle those errors in the singleton which makes it easier for us to
debug customer issues. Logger is outputing local storage warnings for
feature we expose
- Side effect of this is random crashes on studio when local storage
isn't available or handled correctly
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Improved browser storage handling across the app for more reliable
persistence and graceful behavior in restricted or non-browser
environments (settings, previews, charts, tabs, sign-in/session flows,
integrations, and UI state).
* **New Features**
* Introduced a safe storage layer to standardize and harden
local/session persistence.
* **Tests**
* Added comprehensive tests covering the new safe storage behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What changed
Updated the S3 Vectors wrapper docs links in Studio to use the canonical
`s3_vectors` docs slug instead of `s3-vectors`.
## Why
The docs route on current `master` uses
`/guides/database/extensions/wrappers/s3_vectors`, so these Studio links
should point to the existing page.
## Validation
Skipped local checks at request: this is a two-line URL-only update.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Fixed documentation links for S3 Vectors integration to direct users
to the correct reference guides.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Ali Waseem <waseema393@gmail.com>
## Context
> [!IMPORTANT]
> Will open up for review once CLI PR is merged and deployed so that
it's easier to test
Related PR: https://github.com/supabase/cli/pull/5230
Adding support for vector buckets for local CLI - will need to be tested
locally via `pnpm run dev:studio-local`
## To test
There's a bit of testing instructions in the linear ticket
[here](https://linear.app/supabase/issue/FE-3474/show-vector-buckets-in-local-admin-studio)
as it involves using a branch of CLI - otherwise do reach out to
Fabrizio if any help might be needed, but generally:
### Local CLI
You might need to manually set `isCli` to `true` in `StorageMenuV2` if
the "Vectors" nav item isn't showing up on the storage UI given we're
testing via `pnpm run dev:studio-local`
- [x] Can create bucket
- [x] Can delete bucket
- [x] Can create indexes
- [x] Can insert data into indexes (via FDW)
- [x] Can delete indexes
Known issues (that aren't directly solvable from FE end)
Reach out to Fabrizio for context as we were both investigating this
- PG database needs to be on 17.6 (otherwise there's no S3 vectors FDW)
- Storage version needs to be on 1.59.0
### Self-hosted (This might be tricky to actually test, but just ensure
that the code satisfies this)
- [x] Cannot see vector buckets
### Hosted
- [x] Everything works status quo
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Vector bucket management UI and platform APIs (create/list/delete
buckets & indexes)
* Local S3 credentials endpoint and client-side hook for self‑hosted/CLI
use
* **Bug Fixes**
* Improved S3 vector setup notifications and clearer error guidance for
manual installation
* **Refactor**
* Deployment-mode gating: platform vs CLI/self‑hosted now controls
feature visibility and page behavior
* **Tests**
* Added suites covering deployment-mode gates and vector bucket
error/usage scenarios
* **Chores**
* Build env updated to expose local S3 credential vars
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46381?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 -->
---------
Co-authored-by: Ali Waseem <waseema393@gmail.com>
Studio is on `react@^19.2.6`, and `useEffectEvent` shipped stable in
React 19.2 with the same signature as the userland polyfill. This drops
the local hook in `apps/studio` and `apps/www` in favor of the built-in.
**Removed:**
- `apps/studio/hooks/useStaticEffectEvent.ts`
- `apps/www/hooks/useStaticEffectEvent.ts`
- `.claude/skills/use-static-effect-event/` — skill is obsolete
**Changed:**
- 26 call sites: dropped the `useStaticEffectEvent` import, added
`useEffectEvent` to the existing `react` import, renamed call sites
- `.claude/CLAUDE.md`: `apps/studio` row updated React 18 → React 19
- `.claude/skills/vercel-composition-patterns/SKILL.md`: removed stale
"Studio uses React 18, skip these patterns" warning
## To test
- `pnpm typecheck --filter=studio` — passes locally
- `pnpm typecheck --filter=www` — passes locally
- `grep -rn "useStaticEffectEvent"` returns nothing outside
`node_modules`
- Smoke-test areas that use the hook: schema visualizer edges
(intersection check), spreadsheet import, sign-in/CLI login flows, side
panels with unsaved-changes prompts
**Out of scope:** pre-existing Tailwind lint warning on
`DefaultEdge.tsx:141` (`outline` + `outline-1` conflict) — unrelated to
this migration
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Internal event handling migrated to React’s built-in event hooks
across the Studio app; no user-facing changes.
* **Documentation**
* Clarified React 19 compatibility and noted Studio now targets React
19.
* Removed obsolete documentation for a deprecated internal hook.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46415?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 -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
## Summary
I migrated every `useSendEventMutation` call site in `apps/studio` to
`useTrack`, deleted the legacy hook, and added a lint guardrail so it
can't return. `useTrack` is the type-safe replacement: it auto-injects
`groups: { project, organization }` from the selected project/org and
types `action` + `properties` against `TelemetryEvent`. Existing call
sites built groups manually and were not type-checked at the action
level. The migration covers 81 files (60 trivial swaps, 9 org-only, 3
pre-auth, 5 bespoke, 4 test mocks).
## Changes
- Migrated trivial call sites across `pages/project/[ref]`,
`components/interfaces/*` (Reports, Storage, Realtime/Inspector,
SQLEditor, Functions, EdgeFunctions, Integrations, ProjectAPIDocs,
Branching/BranchManagement, TableGridEditor, Connect, Docs, Auth,
Support, Home, ProjectHome, App), `components/layouts/*`, and
`components/ui/*`.
- Migrated org-only sites (`Organization/Documents/*`,
`Organization/BillingSettings/Subscription/*`,
`Organization/SecuritySettings.tsx`,
`Account/Preferences/DashboardSettingsToggles.tsx`) by dropping the
manual `groups: { organization: ... }` and letting `useTrack`
auto-inject. Verified `useSelectedProjectQuery` is disabled on org
routes (gates on URL `[ref]`).
- Migrated pre-auth sites (`SignInForm.tsx`, `sign-in-mfa.tsx`,
`profile.tsx`) where neither project nor org is resolved.
- Bespoke handling:
- `execute-sql-mutation.ts` and `table-row-create-mutation.ts`: pass `{
project: projectRef }` via `groupOverrides` since the mutation can
target a non-selected project ref.
- `useStudioCommandMenuTelemetry.ts`: kept a direct `sendTelemetryEvent`
call because studio groups must override pre-built event groups
(opposite of `useTrack`'s override direction).
- `AIAssistantOption.tsx`: passes sentinel-aware `groupOverrides` so
`NO_PROJECT_MARKER`/`NO_ORG_MARKER` continue to suppress group emission.
- `SidePanelEditor.utils.tsx`: utility functions `createTable` and
`updateTable` now take a `track: Track` parameter (threaded from
`SidePanelEditor.tsx`); dropped the `organizationSlug` arg since groups
are no longer assembled manually.
- Branch-event attribution: preserved `parentProjectRef` overrides on
`branch_updated`, `branch_merge_completed`, `branch_merge_failed`,
`branch_merge_submitted`, `branch_delete_button_clicked`,
`branch_review_with_assistant_clicked`, and
`branch_*_merge_request_button_clicked`. Original code grouped these
under the parent (production) project, not the branch ref;
auto-injection would have shifted them onto the branch.
- Switched 4 test mocks from `@/data/telemetry/send-event-mutation` to
`@/lib/telemetry/track`. Removed obsolete tests around manual groups and
`try/catch` on telemetry rejection.
- Deleted `apps/studio/data/telemetry/send-event-mutation.ts`. The
deleted module is its own guardrail: any reintroduction of the import
fails at TypeScript module resolution before lint runs.
## Testing
Tested on preview deploy:
- [x] SQL editor `CREATE TABLE` fires `table_created` with method
`sql_editor` and `groups.project` set to the mutation's `projectRef`.
- [x] Table editor creates a table from the side panel; `table_created`
fires from `SidePanelEditor.utils` via threaded `track`.
- [x] Help button (`/project/[ref]/...`) fires `help_button_clicked`
with auto-injected project + org groups.
- [x] Sign-in form fires `sign_in` with empty groups (pre-auth,
expected).
- [x] Org documents page (`/org/[slug]/documents`) fires
`document_view_button_clicked` with org group only, no stale project
ref.
- [x] Command menu (`Cmd+K`) inside a project still fires
`command_menu_opened` with studio's project/org overriding any
event-supplied groups.
- [x] Support form "Ask the Assistant" without selected org fires
`ai_assistant_in_support_form_clicked` with no project/org groups
(sentinels suppress).
- [x] On a branch, "Update branch" / "Merge branch" / "Close merge
request" events fire with `groups.project` set to the parent project
ref, not the branch ref.
Local checks:
- [x] 22/22 tests pass across the 4 updated test files
(`SidePanelEditor.utils.createTable`, `EdgeFunctionRenderer`,
`LayoutSidebar`, `PlanUpdateSidePanel`).
- [x] `rg useSendEventMutation apps/studio` returns 0 hits.
## Linear
- fixes GROWTH-860
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Standardized telemetry across the Studio to a unified tracking system;
events now send simplified payloads with less contextual/grouping data.
* No user-facing flows changed; UI behavior, permissions, and
interactions remain the same.
* **Tests**
* Updated telemetry mocks and tests to align with the new tracking
approach.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46140?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 -->
<img width="1285" height="654" alt="image"
src="https://github.com/user-attachments/assets/10074f07-3ac0-4f1f-b920-4255c67968d6"
/>
Updates file storage buckets to make use of new page components and
follow more standard full width pages as recommended in our design
system.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Search input now always visible with dynamic placeholder and cancel
control.
* “Go up one level” navigation button shown in list view when not at
bucket root.
* **Style**
* Thinner icon strokes and smaller button/icon sizing across the Storage
Explorer and preview.
* Header, breadcrumbs, and page container spacing/layout refined;
explorer outer container simplified.
* Selection count UI made compact/monospaced; new layout tokens for
header and bulk-action rows.
* **Tests**
* Unit and e2e tests updated; added e2e helper for rename/create inputs.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46184?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 -->
## 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 -->
[](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 -->
## Summary
Vector and analytics bucket access is gated by both the org's plan tier
and the project's compute size, but the storage config API only returns
a single `enabled: false` flag. The empty state always told users to
"Upgrade to Pro" — including users who were already on Pro with Nano
compute, leaving them no obvious path forward.
`BucketsUpgradePlan` now reads the org plan and the project's
`infra_compute_size`. When the user is on a paid plan but still on Nano
compute, the message becomes "Upgrade your project's compute size to
Micro or larger…" and the button is wired through `UpgradePlanButton`'s
existing `addon='computeSize'` route to `/settings/compute-and-disk`.
Free plan users keep the existing copy and upgrade flow.
Closes FE-3383.
## Test plan
- [ ] Free org, Nano compute, navigate to `/storage/vectors`: still
shows "Upgrade to Pro" with the billing link
- [ ] Pro org, Nano compute, navigate to `/storage/vectors`: shows the
compute-size message and the button navigates to compute-and-disk
settings
- [ ] Pro org, Micro+ compute: page renders the actual Vector buckets UI
(unchanged)
- [ ] Same flows on `/storage/analytics`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a regional limitation notice for Vector Buckets with an
informational "Coming soon" empty state and tooltip listing available
regions.
* **Bug Fixes**
* Storage bucket upgrade prompts now show context-aware messaging based
on organization plan and project settings, guiding users to the correct
upgrade path.
* **Refactor**
* Region-gating UI logic consolidated into a shared component for
clearer messaging and maintenance.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46008?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 -->
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Summary
Part 4 of the SafeSql migration stack
([#45897](https://github.com/supabase/supabase/pull/45897),
[#45903](https://github.com/supabase/supabase/pull/45903),
[#45990](https://github.com/supabase/supabase/pull/45990), this PR, …).
Converts the remaining reports, query performance, observability, index
advisor, and privileges call sites of `executeSql` to produce
`SafeSqlFragment` values. The `ReportQuery.sql` field flips from
`string` to `SafeSqlFragment`, which cascades into every consumer —
landed here atomically so each branch typechecks cleanly.
Touched areas:
- `interfaces/Reports/*` — `ReportQuery.sql: SafeSqlFragment`, plus all
report definitions/utilities updated
- `interfaces/QueryPerformance/useQueryPerformanceQuery.ts`
- `interfaces/Database/IndexAdvisor/*` and
`data/database/{table-index-advisor,retrieve-index-advisor-result}-query.ts`
-
`data/privileges/{table-api-access,update-exposed-entities}-mutation.ts`
- `interfaces/Storage/StoragePolicies/StoragePolicies.tsx`
- `hooks/analytics/useDbQuery.tsx`
- `Observability/useSlowQueriesCount.ts` +
`useQueryInsightsIssues.utils.test.ts`
## Test plan
- [x] `pnpm typecheck` passes
- [x] `useQueryInsightsIssues.utils.test.ts` passes
- [x] Dev-server smoke test: reports pages, query performance, index
advisor, storage policies
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Reworked SQL construction and typings across reporting, query
performance, index advisor, and privilege features to use safer SQL
fragments, improving reliability and preventing query composition
issues.
* **Types**
* Reporting query types were split to distinguish database vs. logs
queries, enabling correct handling and validation.
* **Docs/Utils**
* Added a helper to consistently generate logs SQL for report hooks.
* **Tests**
* Updated tests to exercise the new SQL-building API.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45998)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
The `_Shadcn_` suffix isn't needed anymore on `Select` components
## Solution
Remove it. No other changes
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Updated internal component architecture to standardize and simplify
the codebase. These changes improve code maintainability and consistency
across the application without affecting existing functionality or user
experience.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45988)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Most changes are related to either types or `useRef` usages (it now
requires an initial value).
- also updated `vaul` to its latest version and haven't noticed any
change ([design-system
demo](https://design-system-git-react-19-supabase.vercel.app/design-system/docs/components/drawer))
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Upgraded workspace to React 19.
* **Bug Fixes**
* Improved null-safety and ref handling across editors, UI components,
shortcuts, and markdown/image rendering to reduce runtime errors.
* Safer event/timeout/interval cleanup and more robust command/context
handling.
* **Chores**
* Bumped vaul dependency versions.
* **Documentation**
* Type and TypeScript accuracy improvements for clearer developer
feedback.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45886)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
The `_Shadcn_` suffix isn't needed anymore on label component
## Solution
Remove it. No other changes
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Standardized Label usage across the codebase by removing the legacy
alias and using the direct Label export from the UI package
consistently.
* **Documentation**
* Updated component examples and docs to use the standardized Label
component in usage snippets and demos.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45986)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## TL;DR
fixes a few storage shortcut edge cases
## ref:
- closes https://github.com/supabase/supabase/issues/45977
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* The storage bucket creation shortcut now respects user permissions and
will only be available when allowed.
* Storage file deletion shortcut now requires appropriate write
permission before it can be used on selections.
* Refresh shortcut in the storage explorer is always available
regardless of selection state.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45978)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
We have multiple Popover components
## Solution
- [x] migrate Popover usages to Shadcn components
- Migrated JSON and text editor in the `TableEditor` (inline row
edition)
- Migrated the template popover in the logs explorer templates page
- [x] remove `_Shadcn_` suffix from Popover components (renaming +
prettier)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Unified popover implementation across the app and design system;
dropdowns, calendars, menus and tooltips now use a consistent popover
API with no visual or interaction changes.
* **Chores**
* Minor prop typing update for the logs date-picker to align with the
consolidated popover content type.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45980)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
The `_Shadcn_` suffix isn't needed anymore on `<ContextMenu_Shadcn_>`
and related components
## Solution
Remove it. No other changes
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Replaced legacy context-menu component variants with the unified UI
context-menu components across the app for consistent rendering and
imports; behavior and menu content remain unchanged.
* **Tests**
* Updated a test mock to track the unified context-menu component mount
count.
* **Chores**
* Simplified UI package re-exports to expose the canonical context-menu
symbols.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45971)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
The `_Shadcn_` suffix isn't needed anymore on fields components
## Solution
Remove it. No other changes
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Refactor**
* Streamlined internal component export patterns and standardized import
references to improve code organization and maintainability.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45972)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What kind of change does this PR introduce?
Bug fix.
## What is the current behavior?
The Storage public bucket warning confirmation modal can render
`SELECTpolicy` without a space. The source relied on implicit JSX
whitespace after an inline `<code>` element, and that whitespace can be
normalised away when React renders the sentence.
## What is the new behavior?
The modal now renders an explicit JSX space after the `SELECT` code
element, so the sentence reads `SELECT policy`.
| Before | After |
| --- | --- |
| <img width="860" height="666" alt="CleanShot 2026-05-14 at 14 31
36@2x-2B492E39-5CB4-4D4D-A409-0F0AF268E108"
src="https://github.com/user-attachments/assets/683cc8c7-c112-411e-9569-de3be2a1d906"
/> | <img width="858" height="668" alt="CleanShot 2026-05-14 at 15 08
08@2x"
src="https://github.com/user-attachments/assets/e9a28bb0-9977-4da9-aecb-d4fa56dff368"
/> |
## Additional context
Testing instructions:
1. Open the staging link.
2. Open the SQL Editor and run:
```sql
insert into storage.buckets (id, name, public)
values ('public-warning-repro', 'public-warning-repro', true)
on conflict (id) do update set public = true;
drop policy if exists "public warning broad select repro" on storage.objects;
create policy "public warning broad select repro"
on storage.objects
for select
to anon, authenticated
using (bucket_id = 'public-warning-repro');
```
3. Navigate to Storage > `public-warning-repro`.
4. Click `Remove policy` on the warning banner.
5. Confirm the modal says `This will drop the SELECT policy...`, not
`SELECTpolicy`.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Improved wording and inline code styling in the public bucket
destructive confirmation modal for clearer, more readable messaging;
visual presentation updated without changing behavior or confirmation
logic.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45910)
<!-- review_stack_entry_end -->
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45910)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Adds keyboard shortcuts to the Storage section, mirroring the
conventions already established for Auth Users and Database pages:
- **Storage navigation chords** (`S, F` / `S, A` / `S, V` / `S, 3`)
active only inside `StorageLayout`.
- **Files (bucket list) page** shortcuts for search, create, refresh,
reset filters, reset sort.
- **Storage Explorer** shortcuts for upload, new folder, view toggle,
refresh, search, multi-select download/move/delete, and an Escape
ladder.
- `ShortcutTooltip` wired into the relevant buttons so users can
discover keybinds on hover.
- Reload spinner is now driven by a shared store flag, so it shows
whether you click the button or fire the shortcut.
## Test plan
### Storage navigation chords
Active anywhere under `/project/<ref>/storage/*`.
| Keybind | Action |
|---------|--------|
| `S` then `F` | Go to Files |
| `S` then `A` | Go to Analytics buckets (platform + feature-flagged) |
| `S` then `V` | Go to Vector buckets (platform + feature-flagged) |
| `S` then `3` | Go to S3 settings (platform only) |
### Files (bucket list) page
At `/project/<ref>/storage/files`.
| Keybind | Action | Notes |
|---------|--------|-------|
| `Shift+F` | Focus search ("Search buckets") | Selects existing text |
| `Shift+N` | Create new bucket | Opens the create-bucket modal |
| `F` then `C` | Reset filters | Clears the search string |
| `Shift+R` | Refresh buckets | Refetches the bucket list |
| `S` then `C` | Reset bucket sort | Only fires when sort ≠ default
(Created at) |
### Storage Explorer (inside a bucket)
At `/project/<ref>/storage/files/buckets/<bucketId>`.
| Keybind | Action | Notes |
|---------|--------|-------|
| `Shift+F` | Focus search ("Search files") | Opens the search input if
hidden, then focuses |
| `Shift+R` | Refresh | Refetches all opened folders; spinner reflects
state |
| `I` then `F` | Upload files | Disabled w/o ` STORAGE_WRITE ` or at
bucket root with no folder |
| `I` then `N` | Create folder | Same permission gates as Upload |
| `V` then `C` | View as columns | |
| `V` then `L` | View as list | |
| `Shift+D` | Download selected | Only fires when ≥1 item selected;
single vs many handled |
| `Shift+M` | Move selected | Only fires when ≥1 item selected AND `
STORAGE_WRITE ` granted |
| `Mod+Backspace` | Delete selected | Only fires when ≥1 item selected
(` Mod ` = ⌘ on macOS / ` Ctrl ` on Win/Linux) |
| `Escape` | Clear selection | If ≥1 item selected |
| `Escape` | Close file preview | If no selection and preview pane open
|
| `Escape` | Close search | If no selection, no preview, and search is
open |
### Tips while testing
- [x] Chords (two-key sequences): press the first key, release, then
press the second key within ~1s
- [x] Hover any wired button (search, Refresh, Upload, Create folder,
View, Download, Move, Delete, the bucket Create button, sidebar items)
to see the keybind in a tooltip
- [x] Most actions also appear under "Shortcuts" in `Cmd+P`
- [x] Chords starting with a plain letter (` S, F ` / ` I, F ` / ` V, C
` / ` F, C ` / ` S, C `) won't fire while typing in an input — click out
first
- [x] `Escape` does fire from inside the search field (closes the
search)
- [x] `Cmd+/` opens the full shortcuts reference
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Keyboard shortcuts added across Storage: buckets (refresh, clear sort,
create, search), explorer (upload, create folder, refresh, download,
move, delete, clear search), and navigation shortcuts for
Files/Analytics/Vectors/S3.
* **UI**
* Shortcut keytips/tooltips added to relevant buttons and menu items for
discoverability.
* **Documentation/Tests**
* Shortcut reference sheet labels updated and covered by a new test.
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45837)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Logo field now accepts/editable logo URL, plus a new storage-based
Logo Picker to select or remove images from project storage.
* Full storage picker: browse buckets, columns/list views, search,
drag‑and‑drop uploads, file previews (image/audio/video), and
single-file selection with responsive mobile/desktop layouts.
* **Refactor**
* Logo submission streamlined to send the provided URL directly (legacy
file-read/upload flow removed).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Refactor / security improvement
## What is the current behavior?
SQL fragments across Studio are built from plain `string` values with no
type-level distinction between developer-authored SQL, DB-sourced
identifiers, and user-typed or externally-influenced content.
## What is the new behavior?
Extends the safe SQL model to additional Studio interfaces, using
`SafeSqlFragment`, `safeSql`, `ident()`, `literal()`, `untrustedSql()`,
and `acceptUntrustedSql()` from `@supabase/pg-meta/src/pg-format`:
- **Policy editor**: template constants typed as `SafeSqlFragment` via
`safeSql` tagged literals; Monaco editor `onInputChange` emits
`untrustedSql()`; `acceptUntrustedSql()` called only at the Save
gesture; roles selector emits a composed `SafeSqlFragment` via `ident()`
+ `joinSqlFragments()`
- **Auth hooks**: grant/revoke SQL statements use `ident()` for schema
and function names
- **Docs description editor**: `COMMENT ON` queries use `ident()` and
`literal()` for table/column/function names and values
- **Cron jobs**: `cron.schedule()` call and HTTP request builder use
`literal()` for all user-provided values
- **GraphQL linter CTA**: `REVOKE` statement uses `ident()` for schema,
table, and role
- **Storage public bucket warning**: `DROP POLICY` uses `ident()` for
policy name
- **View security autofix modal**: `ALTER VIEW` uses `ident()` for
schema and view name
- **API settings**: `CREATE SCHEMA` mutation uses `safeSql` tagged
literal
- **Database event trigger delete**: `DROP EVENT TRIGGER` uses `ident()`
for trigger name
- **Database queues query**: queue list query uses `safeSql` tagged
literal
- **Role impersonation**: function invocation SQL uses `ident()` and
`literal()`
## Manual testing checklist
- Authentication > Policies
- Authentication > Hooks
- Integrations > Queues
- Database > Event Triggers
- Integrations > Cron Jobs
- Table Editor > View entity security autofix
- API Settings > expose schema
- Linter > GraphQL exposure CTA
- Docs > table/column description editor
- Role impersonation (user impersonation panel)
## Additional context
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Replaced ad-hoc SQL string building with a safer, fragment-based SQL
construction across auth, policies, integrations, storage, and DB
operations to improve SQL safety while preserving behavior.
* **Bug Fixes / UX**
* Policy editor and code editor now propagate role and input changes
more reliably, improving editor responsiveness and policy handling
without UI changes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Mark provenance of SQL via the branded types SafeSqlFragment and
UntrustedSqlFragment. Only SafeSqlFragment should be executed;
UntrustedSqlFragments require some kind of implicit user approval (show
on screen + user has to click something) before they are promoted to
SafeSqlFragment.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Editor and RLS tester show loading states for inferred/generated SQL
and include a dedicated user SQL editor for safer edits.
* **Refactor**
* Platform-wide SQL handling tightened: snippets and AI-generated SQL
are treated as untrusted/display-only until promoted, improving safety
and consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR migrates the whole monorepo to use Tailwind v4:
- Removed `@tailwindcss/container-queries` plugin since it's included by
default in v4,
- Bump all instances of Tailwind to v4. Made minimal changes to the
shared config to remove non-supported features (`alpha` mentions),
- Migrate all apps to be compatible with v4 configs,
- Fix the `typography.css` import in 3 apps,
- Add missing rules which were included by default in v3,
- Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot
of classes
- Rename all misnamed classes according to
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all
apps.
---------
Co-authored-by: Jordi Enric <jordi.err@gmail.com>
This PR preps the monorepo for a migration to Tailwind v4:
- Bump all Tailwind dependencies and libraries to the latest possible
version, while still compatible with Tailwind 3.
- Cleans up obsolete Tailwind 3 specific options and configs.
- Cleans up unused CSS files and fixes the CSS imports.
- Migrates all `important` uses in `@apply` lines to using the `!`
prefix.
- Move `typography.css` to the `config` package and import it from the
apps.
- Migrated all occurrences of `flex-grow`, `flex-shrink`,
`overflow-clip` and `overflow-ellipsis` since they're deprecated and
will be removed in Tailwind 4.
- Make the default theme object typesafe in the `ui` package.
- Migrate all `bg-opacity`, `border-opacity`, `ring-opacity` and
`divider-opacity` to the new format where they're declared as part of
the property color.
- Bump and unify all imports of `postcss` dependency.
## Problem
With #45211 and #45218 merged, we don't need the `_Shadcn_` suffix
anymore
## Solution
- [x] Remove the `_Shadcn_` suffix
- [x] Update exports and imports
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Standardized UI component exports by removing legacy naming
conventions and providing direct imports for checkbox and radio group
components throughout the design system.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
We want to reduce the code we ship and maintain.
## Solution
Migrate old `<Checkbox />` usage to the new Shadcn component.
There's one visual change: no more green background or outline.
## Screenshots
### On `apps/www`
Before:
<img width="1095" height="772" alt="image"
src="https://github.com/user-attachments/assets/b14a0477-d8ac-4ae5-a1c3-63657609e4e5"
/>
After:
<img width="1085" height="766" alt="image"
src="https://github.com/user-attachments/assets/f4c2156c-38e1-4834-b013-e39b8c3dd76e"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Unified checkbox appearance and behavior across the app for consistent
toggles, labels, and interactions.
* **Bug Fixes**
* Fixed selection issues including shift-select edge cases and
click-propagation in lists; added ARIA labels for improved
accessibility.
* **Chores**
* Removed legacy checkbox implementation, associated styles, tests, and
deprecated theme entries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
We used to have a `_Shadcn_` suffix for all the shadcn form components
because we also had `formik` form components.
This is not needed anymore.
## Solution
- Remove the suffix
- Update all usages
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved SQL query handling for vector bucket creation and Foreign
Data Wrapper operations
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
This connects the Advisor from the splinter repo. Below are the list of
changes:
- Register advisor which should appear in both the legacy Advisors and
Advisors sidebar.
- Adds a "Dismiss" button to the admonition inside the bucket view.
- Makes the check for select policy on public buckets tiny bit
stricter/truer.
This is awaiting the [PR](https://github.com/supabase/splinter/pull/152)
in splinter going in!
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a security lint that flags public storage buckets allowing
listing, with a direct "View bucket" link.
* Users can dismiss public-bucket warnings per project+bucket for 14
days via a Dismiss button.
* **Improvements**
* Tightened policy detection to better target bucket-scoped select
policies and avoid unrelated matches.
* **Telemetry**
* Added events for policy removal and dismiss-button clicks.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
## TL;DR
fixes an inconsistent UI state where the image transformations toggle
could appear enabled + blur
even when the feature is unavailable for that account
## ex:
| Before | After |
| --- | --- |
| enabled and blurred | disabled and blurred |
| <img width="1295" height="389" alt="Before: image transformations
toggle appears enabled while blurred"
src="https://github.com/user-attachments/assets/2f9617b3-9f45-4cdd-8ba7-a360e1ba9754"
/> | <img width="1316" height="386" alt="After: image transformations
toggle appears disabled and blurred"
src="https://github.com/user-attachments/assets/f6be26fd-1390-49c9-b30c-880344eaeca8"
/> | |
## ref:
- closes https://github.com/supabase/supabase/issues/44844
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed the image transformation toggle so it visually reflects both the
user's entitlement and the saved setting, ensuring the control
accurately shows when the feature is available and enabled.
* Preserved the existing disabled behavior for users without access or
update rights so functionality remains unchanged.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Remove `@headlessui/react` as a direct dependency from both
`apps/studio` and `packages/ui`. It's incompatible with React 19 (at the
pinned v1 version) and overlaps with our existing Radix/shadcn
primitives.
The only usage was the `<Transition>` component in 3 files + a dead
`Overlay` component in `packages/ui`.
**Removed:**
- `@headlessui/react` from `apps/studio/package.json` and
`packages/ui/package.json`
- Dead `packages/ui/src/lib/Overlay/` directory (not exported or
imported anywhere)
**Changed:**
- `ChooseFunctionForm.tsx` — replaced `Transition` with a shadcn
`Accordion` for the "View definition" toggle
- `FileExplorerColumn.tsx` — replaced `Transition` with `framer-motion`
`AnimatePresence` for drag-over overlay
- `PreviewPane.tsx` — removed `Transition` wrapper entirely (wasn't
visually animating on prod), replaced with simple conditional render
Note: `@headlessui/react` will remain in `pnpm-lock.yaml` as a
transitive dependency of `@graphiql/react` and
`@graphiql/plugin-doc-explorer` — that's expected and not something we
control.
## To test
- **Triggers page** (`/dashboard/project/_/database/triggers`): Create
or edit a trigger, click "Choose a function" to open the side panel.
Click "View definition" on a function row — the SQL definition should
expand/collapse with a smooth height animation. Clicking the row itself
should still select the function.
- **Storage explorer**
(`/dashboard/project/_/storage/buckets/<bucket>`): Navigate into a
folder, drag a file over the column — the drag overlay should fade
in/out smoothly.
- **Storage file preview**
(`/dashboard/project/_/storage/buckets/<bucket>`): Click on a file — the
preview pane should appear on the right (no animation, same as current
prod behaviour).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Replaced several transition wrappers with new animation/mounting
behavior for overlays, preview panes, and drag-over UI to improve
consistency and responsiveness.
* Swapped the function-definition toggle for an Accordion and updated
click handling to prevent accidental row selection.
* Removed the legacy overlay component, its context, and associated
overlay styling.
* **Chores**
* Removed HeadlessUI dependency from project packages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
## Problem
The input groups components introduced in #44282 don't have the
validation attributes when invalid. This hurts accessibility and also
break the design:
<img width="1730" height="324" alt="image"
src="https://github.com/user-attachments/assets/a3fb8d86-f3a8-46bb-aa53-d0599c11f056"
/>
## Solution
This is because the wrapper `<FormControl_Shadcn_>` passes the
validation props to its direct child.
The solution is to avoid applying them on the `<InputGroup>` and to
apply them manually on the inputs.
I also fixed a small accessibility issue by moving the addon texts after
the input so that screen readers announce them in the correct order. No
visual change for this
<img width="587" height="158" alt="image"
src="https://github.com/user-attachments/assets/1f8858ea-6659-45f9-964e-8c43a7fe14ba"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Unified numeric input layout by moving unit labels/suffixes (e.g.,
"seconds", "GB", "%", "connections", "digits", "IOPS", "MB/s", "rows")
to appear after their inputs for a consistent, predictable form
appearance.
* **Accessibility**
* Form controls now expose IDs and ARIA attributes from form context
when available, improving screen-reader descriptions and error
association.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
## Summary
- Removes the "API Docs" navigation item from the sidebar and mobile
menu
- Removes the `UI_PREVIEW_API_SIDE_PANEL` feature preview flag since the
feature is fully rolled out
- Makes API docs buttons unconditionally visible across Auth Users,
Storage, Edge Functions, and SecondLevelNav
## Test plan
- [x] `NavigationBar.utils` tests pass (26 tests)
- [x] `FileExplorerHeader` tests pass (6 tests)
- [x] TypeScript compiles with no errors
- [ ] Verify sidebar no longer shows "API Docs" nav item
- [ ] Verify API docs buttons still appear in Auth Users, Storage, and
Edge Functions pages
- [ ] Verify feature preview modal no longer lists "Project API
documentation"
Resolves FE-2759
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* APIDocs button can optionally display a label and use a custom
tooltip.
* **Chores**
* Removed the API docs side-panel feature flag and its localStorage key.
* “API Docs” navigation entry removed; sidebar no longer special-cases
that route.
* Back links and API Docs buttons now render consistently across the app
(no flag gating).
* **Tests**
* Tests updated to stop depending on the removed feature-flag behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Similar to the Advisor, this adds an admonition enabling the user to
disable a public RLS select via dashboard.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Detect public buckets that have removable SELECT policies and show a
contextual warning on the bucket page.
* Let users remove the policy via a confirmation dialog that previews
the removal action.
* Show success/error feedback and automatically refresh storage views
after removal.
* Adjust page layout to surface the warning above the storage explorer.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Charis Lam <26616127+charislam@users.noreply.github.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Refactor
## What is the current behavior?
Studio uses `react-contexify` (an imperative, ID-based context menu
library) for right-click menus in the Table Editor grid, Log Table, and
Storage file explorer. This requires `createPortal` workarounds, a
separate CSS file, and has known bugs with fragment rendering.
## What is the new behavior?
All context menus now use the declarative `ContextMenu_Shadcn_`
(Radix-based) component that is already the standard across Studio. Each
context menu wraps its trigger element directly, removing the need for
imperative `show()` calls, portal hacks, and menu ID constants. The
`react-contexify` dependency and all associated styles are removed.
**Changes by area:**
- **Grid row context menu**: `RowRenderer` wraps each `<Row>` with
`ContextMenu_Shadcn_`. `RowContextMenu` refactored to accept `row`
directly as a prop instead of looking it up by index.
- **Log table**: Row renderer wraps each row with a context menu for
"Copy event message". Removes `cellPosition` state and `createPortal`.
- **Storage**: `FileExplorerRow` reuses its existing `rowOptions` array
for both the dropdown and context menu. `FileExplorerColumn` inlines the
column menu (new folder, select all, view/sort submenus). Three
standalone context menu files deleted.
- **Cleanup**: Removed `react-contexify` from `package.json`, deleted
`contextMenu.scss`, removed styles from `grid.scss`.
## Additional context
Net -370 lines. Follows the TODO comment in `CellContextMenuWrapper.tsx`
and the existing eslint ban on `react-contexify` imports.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Replaced legacy right-click menus with a unified shadcn-style context
menu across grids, logs, and the storage explorer.
* Simplified row/column/item context menu behavior and copy actions;
menus now mount and trigger more reliably.
* **New Features**
* Added row-level context menu providers to ensure consistent triggering
and positioning for row actions.
* **Chores**
* Removed legacy context-menu styles and deprecated menu components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Refactor
## What is the current behavior?
Storage explorer preferences (`view`, `sortBy`, `sortByOrder`,
`sortBucket`) are managed inline within the Valtio proxy state in
`storage-explorer.tsx`, which reads/writes localStorage directly.
## What is the new behavior?
Preferences are extracted into a dedicated `useStoragePreference` hook
backed by `useLocalStorage`. A companion `getStoragePreference` function
allows the Valtio state to read sort options imperatively for API calls
without holding preference data itself. Consumers import the hook
directly instead of reading preferences from the snapshot.
## Additional context
No behavioral or visual changes — localStorage key and data shape are
unchanged.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Storage view and sorting preferences now persist per project and drive
the explorer UI.
* Changing view or sort preferences refreshes folder contents and clears
the open file preview.
* **Chores**
* Centralized preference handling for consistent behavior across the
storage explorer.
* **Tests**
* Updated tests to exercise the new preference-backed behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>