studio-shortcuts

v2026.09.24

Keyboard shortcut conventions for Supabase Studio. Use when adding a repeated user action, toolbar action, list/table operation, or sub-page navigation that should have shortcut coverage, when registering or changing a shortcut, or when adding a search/filter Input (which needs the staged-Escape handler). Covers the shortcut registry, useShortcut, ShortcutTooltip/ShortcutBadge, the reference sheet, and collision rules.

GitHub
Install command
npx skhub add supabase/studio-shortcuts
Markdown
SKILL.md

Studio Keyboard Shortcuts

When Studio UI changes introduce or materially alter repeated user actions, consider whether keyboard shortcut coverage should be added or updated. Shortcuts use the shared Studio shortcut system and must be discoverable from the visible UI.

Rules

  • Never add a one-off keydown listener for a normal Studio action — register it through the shortcut registry and useShortcut.
  • Every registered shortcut is exposed where the action is visible, via ShortcutTooltip, ShortcutBadge, or a command-menu badge.
  • G then … chords are reserved for navigation.
  • Avoid broad Mod+letter shortcuts that overlap common browser, editor, system, copy/save/search, or devtools behavior.
  • Before adding a shortcut, check the registry and any remaining non-registry listeners for collisions.
  • Every search/filter <Input> gets onKeyDown={onSearchInputEscape(...)} — see Search inputs.

Preferred pattern

  • Add definitions in apps/studio/state/shortcuts/registry.ts or apps/studio/state/shortcuts/registry/*.
  • Register with useShortcut.
  • Gate availability with enabled.
  • Surface visible actions with ShortcutTooltip or ShortcutBadge.
  • Prefer scoped, mnemonic sequential chords over global modifier chords.
  • Set showInSettings: false on contextual shortcuts (scoped to a specific page state, sheet, or panel).
  • When a shortcut group should appear in the reference sheet (Shift+?), add the group key to SHORTCUT_REFERENCE_GROUP_ORDER in apps/studio/state/shortcuts/referenceGroups.ts and a human label to GROUP_LABELS in ShortcutsReferenceSheet.tsx.
  • For sheet-scoped shortcuts (active only while a <Sheet> is open), mount useShortcut inside the sheet component gated by the open prop ({ enabled: open }) — apps/studio/components/interfaces/Platform/Webhooks/PlatformWebhooksDeliveryDetailsSheet.tsx is the canonical example. A shortcut that opens a sheet from anywhere is global instead, gated by whatever makes the action valid (e.g. useConnectSheetShortcut checks project health).

Search inputs

Every <Input> used as a search or filter field must include the staged-Escape handler from apps/studio/lib/keyboard.ts:

import { onSearchInputEscape } from '@/lib/keyboard'

;<Input
  value={query}
  onChange={(e) => setQuery(e.target.value)}
  onKeyDown={onSearchInputEscape(query, setQuery)}
/>

Behavior:

  • Escape while the input has a value → clears the value, keeps focus (so a second Escape then blurs)
  • Escape while the input is empty → blurs the input
  • Stops propagation on Escape so the keystroke does not accidentally close a parent dialog or sheet

When pairing with useShortcut(LIST_PAGE_FOCUS_SEARCH, ...) to focus a search input via keyboard, always also add onSearchInputEscape on the same input — focus and escape-to-blur are always a pair.

Key files

apps/studio/state/shortcuts/registry.ts, apps/studio/state/shortcuts/useShortcut.tsx, apps/studio/components/ui/Shortcut*.tsx, apps/studio/lib/keyboard.ts.

Tests

E2E tests for a feature with shortcuts cover both click interactions and the keyboard path — see studio-e2e-tests.

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

Apache-2.0

Source path

.agents/skills/studio-shortcuts

Default branch

master

Latest commit

ad5c4bb

Tree SHA

ad08565