Files
supabase/apps/studio/components
Ali Waseem be56096ea7 fix(studio): prevent SQL editor TreeView crash when an expanded folder leaves the tree (#46595)
## Problem

Sentry [SUPABASE-APP-J7C](https://supabase.sentry.io/issues/7492405004)
— `Error: Node with id=new-folder doesn't exist in the tree.` (328
events / 280 users). Crashes the SQL editor.

## Root cause

`react-accessible-treeview` throws when an id is dropped from the
controlled `expandedIds` prop in the same render its node leaves the
tree data — its collapse effect calls `getTreeNode(data, id)` on a node
that's already gone. The prior fix (`8bcb878a01`) reactively filtered
`expandedIds` against the live tree, which is exactly what produces that
simultaneous drop when a `new-folder` placeholder (or any expanded
folder) is removed.

## Fix

- Guard additions: only expand folder ids that exist in the tree.
- Tolerate stale ids: pass `expandedFolderIds` as-is instead of the
reactively filtered list, so we never create a "removed" delta for a
node that's already gone. Stale ids are harmless — the library only
inspects the add/remove delta.

## Reproduction (to verify the fix)

1. Open the SQL Editor for a project.
2. Create a folder and add a snippet into it.
3. **Expand** the folder.
4. Right-click the folder → **Delete folder** (confirm).
5. Before: the editor crashes with `Node with id=... doesn't exist in
the tree.` After: no crash.

Fixes SUPABASE-APP-J7C

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

## Summary by CodeRabbit

* **Bug Fixes**
* Improved stability of private snippet folder expansion in the SQL
editor: auto-expansion now respects the current snippet tree state to
avoid unexpected collapses or visual glitches in the folder tree.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-03 10:39:28 -06:00
..

Writing components

Where to create your components

  • For components that declare the general structure and layout of a page:
    • /components/layouts/xxx
  • For components that are tightly coupled to a specific interface:
    • /components/interfaces/xxx
  • For components that are meant to be reusable across multiple pages:
    • /components/ui/xxx
  • Note: We're gradually moving files out of the to-be-cleaned folder into the respective folders as we refactor

Component structure

  • If a component has constants and utility methods that are tightly coupled to itself, keep them close to the component and enclose them in a folder with an index.tsx as an entry point
  • Otherwise it can just be a file on its own
  • For example:
    • components/ui
      - SampleComponentA
        - SampleComponentA.tsx
        - SampleComponentA.constants.ts
        - SampleComponentA.utils.ts
        - SampleComponentA.types.ts
        - index.ts
      - SampleComponentB.tsx
      

Template for building components


// Declare the prop types of your component
interface ComponentAProps {
  sampleProp: string
}

// Name your component accordingly
const ComponentA = ({ sampleProp }: ComponentAProps) => {
  return <div>ComponentA: {sampleProp}</div>
}

export default ComponentA