studio-ui-patterns
Design system UI patterns for Supabase Studio. Use when building or updating
Works with
--- name: studio-ui-patterns description: Design system UI patterns for Supabase Studio. Use when building or updating license: Apache-2.0 --- # 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 type | `size` | | ----------------- | ----------- | | 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: | 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: - 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` | 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 | - 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` | 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` ## 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.
More Design Systems skills
stitch-design-taste
leonxlnx/taste-skill
Semantic Design System Skill for Google Stitch. Generates agent-friendly DESIGN.md files that enforce premium, anti-generic UI standards — strict typography, calibrated color, asymmetric layouts, perpetual micro-motion, and hardware-accelerated performance.
figma
heygen-com/hyperframes
Import Figma content into a HyperFrames composition — rendered assets, brand tokens, components, storyboard sections → reconstructed motion (frames read as states, not slides) (REST/CLI), connector-assisted motion when available, and shaders from a connector or native export. Use when the user pastes a figma.com link or asks to bring a Figma design, frame, logo, brand, or animation into a video/composition.
image
coreyhaines31/marketingskills
When the user wants to create, generate, edit, or optimize images for marketing — blog heroes, social graphics, product mockups, profile banners, listing visuals, or brand assets. Also use when the user mentions 'AI image generation,' 'generate an image,' 'create a graphic,' 'product mockup,' 'hero image,' 'social media graphic,' 'banner image,' 'cover photo,' 'profile banner,' 'listing screenshot,' 'Flux,' 'Flux Kontext,' 'Midjourney,' 'DALL-E,' 'GPT Image,' 'ChatGPT Images,' 'Ideogram,' 'Gemini image,' 'Nano Banana,' 'Recraft,' 'Stable Diffusion,' 'Canva,' 'Figma,' 'image optimization,' 'compress images,' 'WebP,' or 'OG image.' Use this for general-purpose marketing image creation and optimization. For paid ad image creative and platform-specific ad specs, see ad-creative. For video production, see video.

