Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pnpm typecheck # typecheck all packages

**Language** — Use U.S. English everywhere.

**Studio shortcuts** — when adding or changing repeated Studio UI actions, use the shared shortcut registry and primitives in `apps/studio/state/shortcuts/` and `apps/studio/components/ui/Shortcut*.tsx`. Prefer registered, discoverable shortcuts over one-off keyboard listeners; keep `G then ...` chords for navigation.

## Studio

Pages router. Co-locate sub-components with parent. Avoid barrel re-export files.
Expand Down
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ Path-specific rules in `.github/instructions/`:
- **E2E Tests**: `studio-e2e-tests.instructions.md` — selector priority, anti-patterns (`waitForTimeout`, `force: true`)
- **Composition Patterns**: `studio-composition-patterns.instructions.md` — avoid boolean props, use compound components
- **shadcn/Radix Components**: `studio-shadcn-components.instructions.md` — accessibility handled by primitives, do not flag
- **Keyboard Shortcuts**: `studio-shortcuts.instructions.md` — shared registry usage, discovery, collision checks

These files are scoped to `apps/studio/` and applied automatically during reviews.
37 changes: 37 additions & 0 deletions .github/instructions/studio-shortcuts.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
applyTo: 'apps/studio/**'
---

# Studio Shortcut Review Rules

All comments are **advisory**.

## Core Principle

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

## When to Flag

- PR adds a primary repeated action, toolbar action, list/table operation, or sub-page navigation without considering shortcut coverage.
- PR adds a one-off `keydown` listener for a normal Studio action instead of using the shortcut registry and `useShortcut`.
- PR registers a shortcut but does not expose it via `ShortcutTooltip`, `ShortcutBadge`, or command-menu badge where the action is visible.
- PR wires `useShortcut` and `ShortcutTooltip` separately for a single visible element instead of using the `<Shortcut>` wrapper.
- PR uses `G then ...` for a non-navigation action.
- PR adds a broad `Mod+letter` shortcut that overlaps common browser, editor, system, copy/save/search, or devtools behavior.
- PR adds a shortcut without checking existing registry and non-registry listeners for collisions.
- PR adds a search or filter input with custom Escape handling instead of `onSearchInputEscape` from `@/lib/keyboard`.

## Preferred Pattern

- Add definitions in `apps/studio/state/shortcuts/registry.ts` or `apps/studio/state/shortcuts/registry/*`.
- Add or reuse a cheatsheet group in `apps/studio/state/shortcuts/referenceGroups.ts` when a shortcut belongs to a new surface; prefer existing groups for global actions, navigation, and established feature surfaces.
- Register with `useShortcut`.
- For a single visible element that owns the action (button, icon button, menu trigger), prefer the `<Shortcut>` wrapper in `apps/studio/components/ui/Shortcut.tsx` — it binds `useShortcut` and `ShortcutTooltip` from one `id` so the hotkey and tooltip can't drift. Drop down to `useShortcut` + `ShortcutTooltip`/`ShortcutBadge` separately only when the trigger and the visible affordance live on different elements.
- Gate availability with `enabled`.
- Use `showInSettings: false` for contextual shortcuts that only work inside a page state, panel, sheet, or selected-row mode.
- Surface visible actions with `ShortcutTooltip` or `ShortcutBadge`.
- For sheet-owned actions, mount the shortcut from the sheet or a sheet-owned hook; gate with `enabled` when the action only applies while the sheet is open. See `apps/studio/components/interfaces/ConnectSheet/useConnectSheetShortcut.ts`.
- For search/filter inputs, wire `onKeyDown` to `onSearchInputEscape(value, setValue)` from `@/lib/keyboard` so Escape clears the value, then blurs on a second press, and doesn't bubble to a parent dialog/popover. Don't re-implement this with a local `keydown` listener.
- Prefer scoped, mnemonic sequential chords over global modifier chords.

Canonical implementation context: `apps/studio/state/shortcuts/registry.ts`, `apps/studio/state/shortcuts/useShortcut.tsx`, and `apps/studio/components/ui/Shortcut*.tsx`
5 changes: 0 additions & 5 deletions apps/design-system/config/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,6 @@ export const docsConfig: DocsConfig = {
href: '/docs/fragments/empty-state-presentational',
items: [],
},
{
title: 'Modal',
href: '/docs/fragments/modal',
items: [],
},
{
title: 'Page Container',
href: '/docs/fragments/page-container',
Expand Down

This file was deleted.

This file was deleted.

43 changes: 0 additions & 43 deletions apps/design-system/registry/default/example/modal-hide-footer.tsx

This file was deleted.

This file was deleted.

15 changes: 7 additions & 8 deletions apps/docs/components/Feedback/Feedback.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
'use client'

import { createClient } from '@supabase/supabase-js'
import { IS_PLATFORM } from '~/lib/constants'
import { useSendFeedbackMutation } from '~/lib/fetch/feedback'
import { useSendTelemetryEvent } from '~/lib/telemetry'
import { useConstant, useIsLoggedIn, type Database } from 'common'
import { Check, MessageSquareQuote, X } from 'lucide-react'
import { usePathname } from 'next/navigation'
import {
type CSSProperties,
type MouseEventHandler,
forwardRef,
useReducer,
useRef,
useState,
type CSSProperties,
type MouseEventHandler,
} from 'react'

import { type Database, useConstant, useIsLoggedIn } from 'common'
import { Button, cn } from 'ui'

import { IS_PLATFORM } from '~/lib/constants'
import { useSendFeedbackMutation } from '~/lib/fetch/feedback'
import { useSendTelemetryEvent } from '~/lib/telemetry'
import { getLinearTeam, getSanitizedTabParams } from './Feedback.utils'
import { type FeedbackFields, FeedbackModal } from './FeedbackModal'
import { FeedbackModal, type FeedbackFields } from './FeedbackModal'

const FeedbackButton = forwardRef<
HTMLButtonElement,
Expand Down
Loading
Loading