studio-ui-patterns

작성자: supabase

Supabase Studio를 위한 디자인 시스템 UI 패턴입니다. 빌드하거나 업데이트할 때 사용하세요.

npx skills add https://github.com/supabase/supabase --skill studio-ui-patterns

Studio UI Patterns

The Design System docs and demos are the source of truth. Always check the relevant demo file before composing new UI.

Layout

Docs: apps/design-system/content/docs/ui-patterns/layout.mdx

Build pages with PageContainer, PageHeader, and PageSection.

Content typesize
Settings / config"default"
Lists / tables"large"
Full-screen views"full"
  • If filters/search exist on a list page, align table actions with the filters (don't use PageHeaderAside/PageSectionAside for those actions)
  • If no filters, actions can go in PageHeaderAside or PageSectionAside

Demos: page-layout-settings.tsx, page-layout-list.tsx, page-layout-list-simple.tsx, page-layout-detail.tsx (all in apps/design-system/registry/default/example/)

Forms

Docs: apps/design-system/content/docs/ui-patterns/forms.mdx

  • Use react-hook-form + zod
  • Use FormItemLayout instead of manually composing FormItem/FormLabel/FormMessage/FormDescription
  • Wrap inputs with FormControl; import primitives from ui

Layout selection:

ContextLayoutContainer
Page (settings/config)FormItemLayout layout="flex-row-reverse"Card (CardContent per field; CardFooter for actions)
Side panel — wideFormItemLayout layout="horizontal"SheetSection
Side panel — narrow (size="sm" or below)FormItemLayout layout="vertical"SheetSection

Dirty state / submit:

  • Destructure isDirty from form.formState to show Cancel and disable Save
  • Show loading on submit button via loading prop
  • If submit button is outside <form>, set a stable formId and use form prop on the button

Demos: form-patterns-pagelayout.tsx, form-patterns-sidepanel.tsx

Tables

Docs: apps/design-system/content/docs/ui-patterns/tables.mdx

PatternUse when
TableSimple, static, semantic display
Data TableTanStack-powered; sorting, filtering, pagination; composed per use-case
Data GridVirtualization, column resizing, or complex cell editing
  • Actions: above the table, aligned right
  • Search/filters: above the table, aligned left
  • If table is primary content with no filters, actions can live in the page's primary/secondary actions area

Demos: table-demo.tsx, data-table-demo.tsx, data-grid-demo.tsx

Charts

Docs: apps/design-system/content/docs/ui-patterns/charts.mdx

  • Use provided chart building blocks; avoid passing raw Recharts components to ChartContent
  • Use useChart context flags for loading/disabled states
  • Keep composition straightforward — avoid over-abstraction

Demos (in apps/design-system/__registry__/default/block/): chart-composed-demo.tsx, chart-composed-basic.tsx, chart-composed-states.tsx, chart-composed-metrics.tsx, chart-composed-actions.tsx, chart-composed-table.tsx

Empty States

Docs: apps/design-system/content/docs/ui-patterns/empty-states.mdx

ScenarioPattern
Initial / onboardingPresentational empty state with value prop + clear next action
Data-heavy listsInformational empty state matching the list/table layout
Zero results from searchKeep layout consistent with data state to avoid jarring transitions
Missing routeCentered Admonition

Demos: empty-state-presentational-icon.tsx, empty-state-initial-state-informational.tsx, empty-state-zero-items-table.tsx, data-grid-empty-state.tsx, empty-state-missing-route.tsx

Navigation

Docs: apps/design-system/content/docs/ui-patterns/navigation.mdx

  • Use NavMenu for a horizontal list of related views within a consistent page layout
  • Activating an item must trigger a URL change — no local-only tab state

Cards

  • Group related information in cards
  • CardContent for sections, CardFooter for actions
  • Only use CardHeader/CardTitle when context isn't already provided by surrounding content
  • Use headers/titles when multiple cards represent distinct groups (e.g. multiple settings sections)

Alerts

  • Use Admonition to call out important actions, restrictions, or critical context
  • Place at the top of a page's content (below page title) or top of the relevant section (below section title)
  • Use sparingly

Sheets (Side Panels)

Use a Sheet when switching pages would be disruptive and the user needs to maintain context (e.g. selecting a row from a list to edit).

Structure:

  • SheetContent with size="lg" for forms needing horizontal layout
  • Use SheetHeader, SheetTitle, SheetSection, SheetFooter
  • Submit/cancel actions go in SheetFooter

Forms in sheets:

  • layout="horizontal" for wider sheets
  • layout="vertical" for narrow sheets (size="sm" or below)
  • When the sheet contains a form, wire dirty dismissal with useConfirmOnClose + DiscardChangesConfirmationDialog (Cancel, Escape, and backdrop). Source of truth: apps/design-system/content/docs/ui-patterns/modality.mdx (Dirty form dismissal). Also see the react-hook-form skill for isDirty destructuring.

Copy

Source of truth: apps/design-system/content/docs/copywriting.mdx — sentence case, title case, proper nouns, voice and tone.

When changing visible copy, grep e2e/studio/ for the old string.

supabase의 다른 스킬

studio-e2e-tests
supabase
Supabase Studio용 Playwright E2E 테스트를 작성하고 실행합니다. 요청 시 사용하세요.
pm-the-docs
supabase
Docs-PM 의사결정 지원 도구로, "Write the docs" 작성 프로세스에서 Frame 및 Shape 단계 중 대상 독자, 단계, 교차 범위 결정을 지원합니다…
studio-best-practices
supabase
Supabase Studio를 위한 React 및 TypeScript 모범 사례. Studio 컴포넌트 작성 또는 검토 시 사용 — boolean 명명, 컴포넌트 구조 등을 다룹니다.
docs-content
supabase
Supabase 콘텐츠를 apps/docs 어디에서든 작성, 편집, 구성, 검토하세요 — 가이드, 설명 자료, 튜토리얼, 문제 해결 항목, 참조 문서 등…
studio-mock-api-tests
supabase
Supabase Studio의 컴포넌트 테스트로, MSW를 사용하여 네트워크 계층에서 API 요청을 모킹합니다. React…를 실행하는 컴포넌트 테스트를 작성하거나 검토할 때 사용하세요.
studio-ui-patterns
supabase
Supabase Studio용 디자인 시스템 UI 패턴. 페이지, 양식, 테이블, 차트, 빈 상태, 네비게이션, 카드, 알림 또는 사이드…를 구축하거나 업데이트할 때 사용하세요.
react-hook-form
supabase
모노레포 어디서든 올바른 React Hook Form 사용법 — 데이터 흐름, 구독, 리셋, 더티 상태, 숫자 입력, 제어 입력 규칙. 이것을 로드하세요…
studio-queries
supabase
Supabase Studio에서 데이터 페칭을 위한 React Query 컨벤션. apps/studio/data/에서 쿼리 훅, 뮤테이션 훅, 또는 쿼리 키를 작성하거나 리뷰할 때 사용하세요—…