Design system UI patterns for Supabase Studio. Use when building or updating pages, forms, tables, charts, empty states, navigation, cards, alerts, or side panels (sheets). Covers layout selection, component choice, and placement conventions.
The Design System docs and demos are the source of truth. Always check the relevant demo file before composing new UI.
Docs: apps/design-system/content/docs/ui-patterns/layout.mdx
Build pages with PageContainer, PageHeader, and PageSection.
| Content type | size |
|---|---|
| Settings / config | "default" |
| Lists / tables | "large" |
| Full-screen views | "full" |
PageHeaderAside/PageSectionAside for those actions)PageHeaderAside or PageSectionAsideDemos: page-layout-settings.tsx, page-layout-list.tsx, page-layout-list-simple.tsx,
(all in )
page-layout-detail.tsxapps/design-system/registry/default/example/Docs: apps/design-system/content/docs/ui-patterns/forms.mdx
react-hook-form + zodFormItemLayout instead of manually composing FormItem/FormLabel/FormMessage/FormDescriptionFormControl_Shadcn_; use _Shadcn_ imports from ui for primitivesLayout selection:
| Context | Layout | Container |
|---|---|---|
| Page (settings/config) | FormItemLayout layout="flex-row-reverse" | Card (CardContent per field; CardFooter for actions) |
| Side panel — wide | FormItemLayout layout="horizontal" | SheetSection |
Side panel — narrow (size="sm" or below) | FormItemLayout layout="vertical" | SheetSection |
Dirty state / submit:
isDirty from form.formState to show Cancel and disable Saveloading prop<form>, set a stable formId and use form prop on the buttonDemos: form-patterns-pagelayout.tsx, form-patterns-sidepanel.tsx
Docs: apps/design-system/content/docs/ui-patterns/tables.mdx
| Pattern | Use when |
|---|---|
Table | Simple, static, semantic display |
| Data Table | TanStack-powered; sorting, filtering, pagination; composed per use-case |
| Data Grid | Virtualization, column resizing, or complex cell editing |
Demos: table-demo.tsx, data-table-demo.tsx, data-grid-demo.tsx
Docs: apps/design-system/content/docs/ui-patterns/charts.mdx
ChartContentuseChart context flags for loading/disabled statesDemos (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
Docs: apps/design-system/content/docs/ui-patterns/empty-states.mdx
| Scenario | Pattern |
|---|---|
| Initial / onboarding | Presentational empty state with value prop + clear next action |
| Data-heavy lists | Informational empty state matching the list/table layout |
| Zero results from search | Keep layout consistent with data state to avoid jarring transitions |
| Missing route | Centered 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
Docs: apps/design-system/content/docs/ui-patterns/navigation.mdx
NavMenu for a horizontal list of related views within a consistent page layoutCardContent for sections, CardFooter for actionsCardHeader/CardTitle when context isn't already provided by surrounding contentAdmonition to call out important actions, restrictions, or critical contextUse 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 layoutSheetHeader, SheetTitle, SheetSection, SheetFooterSheetFooterForms in sheets:
layout="horizontal" for wider sheetslayout="vertical" for narrow sheets (size="sm" or below)