mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
## Problem Primary colour serves readable text and selected controls, but those uses need different shades. Light mode needs darker text, while dark mode needs a deeper button fill. Fixed brand green on interactive chrome also prevents a custom primary hue from carrying through the interface. Some slider tracks and selected text are hard to read. ## Solution - Keep `--primary` for accessible text and small selected indicators. Use `--primary-solid` for button fills, which need a deeper shade in dark mode. - Add `--primary-bright` for focus rings, selected control chrome, chart accents, and other interactive highlights. It follows `--primary-hue`; `brand-*` stays fixed for Supabase identity. - Make slider troughs clearer and text selection translucent with theme foreground text. - Document the split in the design-system colour guide. | Before | After | | --- | --- | | <img width="980" height="244" alt="Before: light mode primary controls" src="https://github.com/user-attachments/assets/dfae325d-0dfe-4231-8bcd-3f89c4b9d793" /> | <img width="982" height="204" alt="After: light mode primary controls" src="https://github.com/user-attachments/assets/5fdcb531-a6e3-4549-8a13-9d9a5ebe6e20" /> | | <img width="610" height="120" alt="Before: slider track" src="https://github.com/user-attachments/assets/04f768e0-51e8-4d06-9b97-c52f4a34f122" /> | <img width="622" height="126" alt="After: slider track" src="https://github.com/user-attachments/assets/95127f4e-13dc-4f0f-b63c-cf5d70a28b42" /> | | <img width="652" height="512" alt="Before: dark mode controls" src="https://github.com/user-attachments/assets/3f88de66-90cc-40ee-8cf1-b5f4eb87b09a" /> | <img width="658" height="498" alt="After: dark mode controls" src="https://github.com/user-attachments/assets/906bec30-6ca1-4614-9fb3-6cf5e5feec22" /> | ## Review instructions 1. Compare light and dark mode in the [colour usage guide](https://design-system-git-dnywh-fix-bright-brand-chrome-supabase.vercel.app/design-system/docs/color-usage#primary-and-brand-colors). Check primary ink, primary-solid, primary-bright, and fixed brand swatches. 2. In Studio, open the ‘new table’ sheet in [Table Editor](https://studio-staging-git-dnywh-fix-bright-brand-chrome-supabase.vercel.app/dashboard/project/_/editor). Tab through the new table sheet's fields and toggles. Check the focus rings, selected controls, and the sheet's edges in both themes. You do not need to save a table. 3. Select text in Studio in both themes, including a link or primary-coloured label. The selection and text should remain legible. 4. Check the [Field](https://design-system-git-dnywh-fix-bright-brand-chrome-supabase.vercel.app/design-system/docs/components/field) Price Range slider: the unused track should remain visible in both themes. The selected field card border should follow primary-bright. 5. Check the [Button](https://design-system-git-dnywh-fix-bright-brand-chrome-supabase.vercel.app/design-system/docs/components/button) and [Radio Group](https://design-system-git-dnywh-fix-bright-brand-chrome-supabase.vercel.app/design-system/docs/components/radio-group) previews. In dark mode, `primary` button fill should be deeper than primary [text](https://design-system-git-dnywh-fix-bright-brand-chrome-supabase.vercel.app/design-system/docs/color-usage#text); selected radios should remain readable.
305 lines
23 KiB
Plaintext
305 lines
23 KiB
Plaintext
---
|
|
title: Charts
|
|
description: Composable charts for Reports, Dashboards and other visualizations.
|
|
links:
|
|
doc: https://recharts.github.io/en-US/
|
|
source:
|
|
recharts: true
|
|
---
|
|
|
|
<ComponentPreview name="chart-composed-demo" peekCode wide />
|
|
|
|
## About
|
|
|
|
Charts are an integral part of Observability at Supabase. Charts aim to be composable and reusable for frictionless setup.
|
|
|
|
Our charts use a combination of our own presentational components and [Recharts](https://recharts.github.io/en-US/) for extensibility.
|
|
|
|
## Best Practices
|
|
|
|
1. **Use provided chart types first**: Always try to use the default provided charts first, otherwise passing Recharts compoennts to `<ChartContent>` is possible but not recommended to avoid complexity.
|
|
|
|
2. **Use the `useChart` context to show loading and disabled states**: The `useChart` context provides boolean flags for child components to show `isLoading` and `isDisabled` states.
|
|
|
|
3. **Keep it simple**: Try to avoid abstracting the chart content too much. These components should cover most of your presentational needs.
|
|
|
|
## Color
|
|
|
|
Series colors come from eight categorical slots, `--chart-1` through `--chart-8`, defined in
|
|
`packages/config/css/charts.css`. Assign them in order and never cycle: a ninth series folds
|
|
into "Other" or becomes small multiples. Each slot has a matching `-fill` token. Slots resolve
|
|
per theme, so pass `var(--chart-n)` and never branch on light/dark in code. Adjacent slots
|
|
alternate hue families and clear colorblind separation in both themes.
|
|
|
|
Reference lines use `--chart-reference`. Headroom, idle and unused capacity use `--chart-muted`.
|
|
Directional pairs use `--chart-in` / `--chart-out` so read and write keep the same hue across
|
|
charts.
|
|
|
|
Status colors (`--chart-status-success`, `-warning`, `-destructive`, each with a `-muted` tier)
|
|
are reserved for state and always ship with an icon or label. Never use one as a series color:
|
|
amber on a neutral metric reads as a problem. Warm hues are otherwise limited to tomato, slot 5,
|
|
because no amber or yellow step is legible on the dark surface.
|
|
|
|
<ComponentPreview name="chart-palette" wide />
|
|
|
|
Every slot stacked together, to check adjacent segments stay separable in both themes.
|
|
|
|
<ComponentPreview name="chart-palette-stress" wide />
|
|
|
|
## Examples
|
|
|
|
### Basic Chart Types
|
|
|
|
<ComponentPreview name="chart-composed-basic" wide />
|
|
|
|
### Chart States
|
|
|
|
<ComponentPreview name="chart-composed-states" wide />
|
|
|
|
### Charts as Standalone Metrics
|
|
|
|
<ComponentPreview name="chart-composed-metrics" wide />
|
|
|
|
### Charts with Actions
|
|
|
|
<ComponentPreview name="chart-composed-actions" wide />
|
|
|
|
### Chart with Table
|
|
|
|
<ComponentPreview name="chart-composed-table" wide />
|
|
|
|
You can pass through our [Table](/docs/components/table) component to the `ChartFooter` and expect it to be styled correctly. There is no additional need to style the table, `ChartFooter` will handle the styling for you.
|
|
|
|
## API
|
|
|
|
### Chart
|
|
|
|
The root container component that provides chart context to all child components.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ------------ | -------------------------------------- | ------- | ------------------------------------------------------------------ |
|
|
| `children` | `React.ReactNode` | - | Chart child components |
|
|
| `isLoading` | `boolean` | `false` | Shows loading state in child components via the `useChart` context |
|
|
| `isDisabled` | `boolean` | `false` | Disables chart interactions via the `useChart` context |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
|
|
|
### ChartCard
|
|
|
|
A card wrapper for the chart. Can be used as a Card component or as a slot.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | -------------------------------------- | ------- | ----------------------------------------------------------------------------- |
|
|
| `children` | `React.ReactNode` | - | Chart content |
|
|
| `asChild` | `boolean` | - | Render as child component (uses Slot) - ideal for removing the `Card` wrapper |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
|
|
|
### ChartHeader
|
|
|
|
Container for chart header content like title and actions.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | -------------------------------------- | ---------- | ------------------------------------------------------------------- |
|
|
| `children` | `React.ReactNode` | - | Header content (typically ChartTitle, ChartActions, or ChartMetric) |
|
|
| `align` | `'start' \| 'center'` | `'center'` | Alignment of header content |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
|
|
|
### ChartTitle
|
|
|
|
Displays the chart title with optional tooltip.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | -------------------------------------- | ------- | ------------------------------------- |
|
|
| `children` | `React.ReactNode` | - | Title text |
|
|
| `tooltip` | `string` | - | Tooltip text shown on help icon hover |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
|
|
|
### ChartActions
|
|
|
|
Renders action buttons or links in the chart header.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | -------------------------------------- | ------- | ---------------------------------------------------------- |
|
|
| `actions` | `ChartAction[]` | - | Array of action objects (see ChartAction type below) |
|
|
| `children` | `React.ReactNode` | - | Custom action content (takes precedence over actions prop) |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
|
|
|
#### ChartAction Type
|
|
|
|
| Property | Type | Description |
|
|
| ----------- | -------------------- | ----------------------------------------------- |
|
|
| `label` | `string` | Accessible label for the action |
|
|
| `icon` | `React.ReactNode` | Icon component to display |
|
|
| `onClick` | `() => void` | Click handler for button actions |
|
|
| `href` | `string` | URL for link actions |
|
|
| `type` | `'button' \| 'link'` | Action type (auto-detected if href is provided) |
|
|
| `className` | `string` | Additional CSS classes |
|
|
|
|
### ChartMetric
|
|
|
|
Displays a metric value with optional status indicator.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | ---------------------------------------------------- | --------- | --------------------------------------------------- |
|
|
| `label` | `string` | - | Metric label text |
|
|
| `value` | `string \| number \| null \| undefined` | - | Metric value to display |
|
|
| `diffValue` | `string \| number \| null \| undefined` | - | Differential value to display (shown as +/- change) |
|
|
| `status` | `'positive' \| 'negative' \| 'warning' \| 'default'` | - | Status indicator color |
|
|
| `align` | `'start' \| 'end'` | `'start'` | Alignment of the metric |
|
|
| `tooltip` | `string` | - | Tooltip text shown on help icon hover |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
|
|
|
### ChartContent
|
|
|
|
Container for the main chart visualization. Handles loading and empty states.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------------- | -------------------------------------- | ------- | -------------------------------------- |
|
|
| `children` | `React.ReactNode` | - | Chart visualization content |
|
|
| `isEmpty` | `boolean` | `false` | Whether to show empty state |
|
|
| `emptyState` | `React.ReactNode` | - | Custom empty state component |
|
|
| `loadingState` | `React.ReactNode` | - | Custom loading state component |
|
|
| `disabledState` | `React.ReactNode` | - | Custom disabled state component |
|
|
| `disabledActions` | `ChartAction[]` | - | Actions to show when chart is disabled |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
|
|
|
### ChartEmptyState
|
|
|
|
Pre-built empty state component for charts.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ------------- | -------------------------------------- | ------- | ------------------------ |
|
|
| `title` | `string` | - | Empty state title |
|
|
| `description` | `string` | - | Empty state description |
|
|
| `icon` | `React.ReactNode` | - | Optional icon to display |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
|
|
|
### ChartLoadingState
|
|
|
|
Pre-built loading state component. Takes no props.
|
|
|
|
### ChartFooter
|
|
|
|
Container for footer content below the chart.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | -------------------------------------- | ------- | ---------------------- |
|
|
| `children` | `React.ReactNode` | - | Footer content |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
|
|
|
### ChartConfig
|
|
|
|
Type definition for chart configuration used with Recharts components.
|
|
|
|
```tsx
|
|
type ChartConfig = {
|
|
[key: string]: {
|
|
label?: React.ReactNode
|
|
icon?: React.ComponentType
|
|
} & (
|
|
| { color?: string; theme?: never }
|
|
| { color?: never; theme: Record<'light' | 'dark', string> }
|
|
)
|
|
}
|
|
```
|
|
|
|
| Property | Type | Description |
|
|
| -------- | ----------------------------------- | -------------------------------------------------------- |
|
|
| `label` | `React.ReactNode` | Label for the data series |
|
|
| `icon` | `React.ComponentType` | Icon component for the data series |
|
|
| `color` | `string` | Single color value (mutually exclusive with theme) |
|
|
| `theme` | `Record<'light' \| 'dark', string>` | Theme-aware color values (mutually exclusive with color) |
|
|
|
|
### ChartLine
|
|
|
|
Line chart component for displaying time-series data.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ------------------- | --------------------------------------------------------------------- | ------------------------- | ----------------------------------------------------------------- |
|
|
| `data` | `ChartLineTick[]` | - | Array of data points with timestamp |
|
|
| `dataKey` | `string` | - | Key in data object to plot |
|
|
| `config` | `ChartConfig?` | - | Chart configuration for styling |
|
|
| `onLineClick` | `(datum: ChartLineTick, tooltipData?: CategoricalChartState) => void` | - | Click handler for line points |
|
|
| `DateTimeFormat` | `string` | `'MMM D, YYYY, hh:mma'` | Date format for tooltips and labels |
|
|
| `isFullHeight` | `boolean` | `false` | Whether chart should take full height |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `color` | `string` | `'var(--primary-bright)'` | Line color |
|
|
| `hoverColor` | `string` | `'hsl(var(--brand-500))'` | Line color on hover |
|
|
| `chartHighlight` | `ChartHighlight` | - | Highlight selection configuration |
|
|
| `updateDateRange` | `(from: string, to: string) => void` | - | Callback when date range is updated via highlight |
|
|
| `highlightActions` | `ChartHighlightAction[]` | - | Actions to show when area is highlighted |
|
|
| `syncId` | `string` | - | ID to sync multiple charts |
|
|
| `showHighlightArea` | `boolean` | `true` | Whether to show highlight area |
|
|
| `cursor` | `string` | - | Cursor style (defaults to 'crosshair' if chartHighlight provided) |
|
|
| `showGrid` | `boolean` | `false` | Whether to show grid lines |
|
|
| `showYAxis` | `boolean` | `false` | Whether to show Y-axis |
|
|
| `YAxisProps` | `object` | - | Additional Y-axis props (tick, tickFormatter, width, etc.) |
|
|
| `strokeWidth` | `number` | `1.5` | Line stroke width |
|
|
|
|
#### ChartLineTick Type
|
|
|
|
| Property | Type | Description |
|
|
| --------------- | ------------------ | ---------------------------- |
|
|
| `timestamp` | `string` | Timestamp for the data point |
|
|
| `[key: string]` | `string \| number` | Additional data fields |
|
|
|
|
#### ChartHighlight Type
|
|
|
|
| Property | Type | Description |
|
|
| ----------------- | ------------------------------------------------------------- | ------------------------------------ |
|
|
| `handleMouseDown` | `(e: { activeLabel?: string; coordinates?: string }) => void` | Mouse down handler |
|
|
| `handleMouseMove` | `(e: { activeLabel?: string; coordinates?: string }) => void` | Mouse move handler |
|
|
| `handleMouseUp` | `(e: { chartX?: number; chartY?: number }) => void` | Mouse up handler |
|
|
| `coordinates` | `{ left?: string; right?: string }` | Highlight area coordinates |
|
|
| `clearHighlight` | `() => void?` | Optional function to clear highlight |
|
|
|
|
#### ChartHighlightAction Type
|
|
|
|
| Property | Type | Description |
|
|
| ------------ | -------------------------------------------------------------------------------- | ---------------------------------------------------- |
|
|
| `id` | `string` | Unique identifier for the action |
|
|
| `label` | `string \| ((ctx: { start: string; end: string; clear: () => void }) => string)` | Action label or function that returns label |
|
|
| `icon` | `ReactNode?` | Optional icon component |
|
|
| `isDisabled` | `(ctx: { start: string; end: string; clear: () => void }) => boolean?` | Optional function to determine if action is disabled |
|
|
| `onSelect` | `(ctx: { start: string; end: string; clear: () => void }) => void` | Action selection handler |
|
|
|
|
### ChartBar
|
|
|
|
Bar chart component for displaying time-series data.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ------------------- | -------------------------------------------------------------------- | ------------------------------- | ----------------------------------------------------------------- |
|
|
| `data` | `ChartBarTick[]` | - | Array of data points with timestamp |
|
|
| `dataKey` | `string` | - | Key in data object to plot |
|
|
| `config` | `ChartConfig?` | - | Chart configuration for styling |
|
|
| `onBarClick` | `(datum: ChartBarTick, tooltipData?: CategoricalChartState) => void` | - | Click handler for bars |
|
|
| `DateTimeFormat` | `string` | `'MMM D, YYYY, hh:mma'` | Date format for tooltips and labels |
|
|
| `isFullHeight` | `boolean` | `false` | Whether chart should take full height |
|
|
| `className` | `string` | - | Additional CSS classes |
|
|
| `color` | `string` | `'var(--primary-bright)'` | Bar color |
|
|
| `hoverColor` | `string` | `'var(--primary-bright-hover)'` | Bar color on hover |
|
|
| `chartHighlight` | `ChartHighlight` | - | Highlight selection configuration |
|
|
| `updateDateRange` | `(from: string, to: string) => void` | - | Callback when date range is updated via highlight |
|
|
| `highlightActions` | `ChartHighlightAction[]` | - | Actions to show when area is highlighted |
|
|
| `syncId` | `string` | - | ID to sync multiple charts |
|
|
| `showHighlightArea` | `boolean` | `true` | Whether to show highlight area |
|
|
| `cursor` | `string` | - | Cursor style (defaults to 'crosshair' if chartHighlight provided) |
|
|
| `showGrid` | `boolean` | `false` | Whether to show grid lines |
|
|
| `showYAxis` | `boolean` | `false` | Whether to show Y-axis |
|
|
| `YAxisProps` | `object` | - | Additional Y-axis props (tick, tickFormatter, width, etc.) |
|
|
|
|
#### ChartBarTick Type
|
|
|
|
| Property | Type | Description |
|
|
| --------------- | ------------------ | ---------------------------- |
|
|
| `timestamp` | `string` | Timestamp for the data point |
|
|
| `[key: string]` | `string \| number` | Additional data fields |
|