## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
This is a first draft at introducing semantic colours to our
Observability charts. This moves away from just random colours being
assigned to prop after prop. They're only scoped to the Database reports
right now, but if it flows nice, we can open it up to the other reports
too.
This also aims to tone down some of the harsher colours in our charts,
such as the orange which sometimes can look like a warning metric/prop.
| Before | After |
|--------|--------|
| <img width="839" height="336" alt="Screenshot 2026-06-10 at 09 14 56"
src="https://github.com/user-attachments/assets/222747c5-973b-4165-aa53-df7b93412ad3"
/> | <img width="950" height="341" alt="Screenshot 2026-09-14 at 18 14
47"
src="https://github.com/user-attachments/assets/836f3ddd-4a97-4064-b8cf-3a3b435417ac"
/> |
cc @supabase/design for additional thoughts.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added semantic chart color roles with light and dark theme variants
for consistent visualizations.
* Standardized colors and fills across database, networking, storage,
and connection charts.
* Maximum-value lines now use configured chart colors when available.
* Added chart palette reference and stress-test examples.
* Added stacked bar charts, customizable margins, and gradient-filled
line charts.
* Improved multi-series bar chart focus and date-range footer alignment.
* **Documentation**
* Documented the chart palette, theme variants, accessibility guidance,
and usage recommendations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
Line-style report charts (auth processing time, percentiles, edge
functions, realtime, etc.) hardcoded `stackId="1"` on every `<Area>`, so
recharts summed the series additively instead of overlaying them.
When multiple series share a value (e.g. Max/Min/Avg all `153.98`), they
rendered as three stacked bands at 1x/2x/3x the value, even though the
tooltip showed the true identical values.
## Fix
Default each area to its own `stackId` (its attribute name) so series
overlay, while still honoring an explicit per-attribute `stackId` from
config — matching the existing bar-chart path directly above it.
`normalizeVisibleStackToPercent`, the only flag that would make stacked
areas intentional, is never enabled anywhere.
## Before / after
Before: three equal values drawn at `0→153.98`, `153.98→307.96`,
`307.96→461.94`.
After: all three overlay at `153.98`.
Affects every line-style multi-series report, not just auth.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Bug Fixes**
- Improved stacked chart behavior by consistently applying configured
series stacking settings.
- Ensured area charts can overlay correctly when no explicit stacking
configuration is provided.
- Added safeguards for missing or invalid chart attribute data.
- **Tests**
- Added coverage for configured stack IDs, fallback behavior, empty
values, and invalid inputs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What kind of change does this PR introduce?
A11y cleanup follow-up to #47984 /
[DEPR-626](https://linear.app/supabase/issue/DEPR-626).
## What is the current behavior?
Studio had 82 ratcheted `supabase/require-explicit-tabindex` violations
(raw `<button>` / `role="button"` without explicit `tabIndex`).
## What is the new behavior?
- Explicit `tabIndex={0}` (or disabled → `-1`) on those Studio call
sites across nav, `components/ui`, Database, Storage, and the remainder
- Ratchet baseline cleared (**82 → 0**) and the rule **removed from the
Studio ratchet** (debt is gone; ratchet is temporary)
- Rule remains a shared **`warn`** for now — promoting to `error` (and
sweeping www/docs/design-system) is a follow-up
- Also fixed the learn/ui-library call sites that surfaced while
experimenting with error promotion
- Small follow-ups where making controls focusable exposed gaps:
accessible names, disabled/focus consistency, focus-ring polish on
To-test surfaces, home section `KeyboardSensor`, and an E2E locator
tightened after `aria-label="Remove column"`
Prefer migrating to `Button` from `ui` in future touch-ups; this PR
takes the minimal path so Studio debt can stay at zero.
## Additional context
Batches landed together so baseline conflicts stayed simple while
chipping away:
- Hotspots / nav (FirstLevelNav, Marketplace, AttachmentUpload, Column,
Tabs, …)
- `components/ui` shared
- Database + Storage
- Remainder
**Out of scope / intentional deferrals**
- Promoting `supabase/require-explicit-tabindex` to a lint **error**
(follow-up after www/docs/design-system sweeps)
- Tabs/Radio roving, tooltips, context menus, in-menu items
- Full keyboard-accessible tab-close UX (close stays hover +
`tabIndex={-1}`; context menu still closes tabs)
- Data API docs links (`/project/<ref>/api` redirect)
**Reviewer notes**
- Rule only flags raw `<button>` / `role="button"` without a `tabIndex`
prop. `Button` from `ui` already bakes this in
- `tabIndex={-1}` is intentional for disabled controls, in-menu /
roving-focus children, and hover-only tab close
- For dnd-kit grips, put `tabIndex` **after** `{...attributes}` so it
isn’t overwritten (TS2783)
### To test
Use **Safari** with macOS Keyboard navigation **off** (System Settings →
Keyboard). Chrome once for a sanity pass. For each surface below: Tab
until the control is focused, then activate with Enter/Space where
relevant.
1. **API Docs side panel** (Table Editor → open a table → **API docs**)
- Floating API Docs panel — **not** `/project/<ref>/api` (that redirects
to Data API docs; language ToggleGroup uses arrow keys; links are out of
scope)
- Left nav buttons — Tab through several and activate one; active
highlight / navigation still works
2. **Integrations → Marketplace**
- Enable **Integrations layout** feature preview first (avatar menu →
Feature previews)
- `/org/<slug>/integrations` or project integrations marketplace
- “Clear all”, grid/list toggles — Tab + activate
3. **Table Editor → create a table → Columns**
- Drag handles only appear while **creating** (not when editing an
existing table)
- Tab to grip / remove (X) / sensitive-data eye if shown
4. **Project Home** — section drag handles
- Tab to a grip (visible focus ring)
- Optional: Space to pick up, arrows to move, Space/Esc to drop
(KeyboardSensor added)
- Mouse dnd still works
5. **Storage → Policies** — expand/collapse bucket list chevron
(design-system focus ring, no stuck grey open bg)
6. **Support form** (Help → Support) — attachment remove (×) and
add-attachment control when visible
Disabled controls should be **skipped** by Tab.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Accessibility Improvements**
* Improved keyboard navigation throughout Studio by explicitly managing
focus (`tabIndex`) across many interactive controls (menus, tabs,
tables, charts, dialogs, navigation, and form actions).
* Disabled or non-interactive controls are now removed from the tab
order (or made unfocusable), while available actions remain reachable.
* Ensured `type="button"` on relevant controls to prevent unintended
submissions, and refined keyboard focus behavior for various toggles and
copy/remove actions.
* **Chores**
* Updated the ESLint rule baseline configuration to match the new focus
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixes [DEBUG-94](https://linear.app/supabase/issue/DEBUG-94)
## Summary
- **Min MB units**: Added \`formatBytesMinMB\` helper that always
formats byte values in at least MB. Applied to RAM and swap y-axis tick
formatters, tooltips, and chart headers.
- **Swap chart scale**: Every Supabase compute instance is provisioned
with **1 GB of swap regardless of size** (per
[docs](https://supabase.com/docs/guides/troubleshooting/memory-and-swap-usage-explained-aPNgm0)),
so the swap y-axis always shows at least 0 to 1 GB. Low swap usage no
longer fills the full chart height. Removed the show/hide limit toggle
since the limit is implicit in the y-axis scale.
- **Swap units in header/tooltip**: Fixed all three formatters (initial
header, hover-sync header, tooltip) to use \`formatBytesMinMB\` for swap
so the value always shows a unit like "2.00 MB".
- **Reference-line defensive fix**: Added a \`customValue\` fallback in
\`useAttributeQueries\` so future reference-line attributes that use
\`customValue\` instead of \`value\` are not silently overwritten to 0.
## Test plan
- [ ] Open DB Reports and verify RAM/Swap y-axis labels show MB (or GB
for large values), never KB or bytes
- [ ] Hover a bar in the swap chart and verify tooltip and header show
the same value with a unit (e.g. "2.00 MB")
- [ ] With low or zero swap usage, the chart bars are flat and the
y-axis goes 0 to 1 GB
- [ ] CPU chart limit toggle still renders at 100% (regression check on
the \`useAttributeQueries\` fallback change)
🤖 Generated with [Claude Code](https://claude.ai/claude-code)
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
## Problem
The dashboard's timezone picker (#45517) propagates to log timestamps
and the shared TimestampInfo component, but observability and reports
charts still render their X-axis labels, range labels, and tooltip
headers in the browser's local timezone. The result is jarring once a
user picks a non-local timezone: hover a chart and you get one tz, hover
a log row and you get another.
## Fix
Routes all display-side timestamp formatting in the chart layer through
the existing picker-aware helpers (\`useFormatDateTime\` /
\`formatDateTime\`) so chart UI matches the rest of the dashboard.
- **ComposedChart.utils** \`CustomTooltip\` (the hotspot — drives every
observability dashboard tooltip): reads the active timezone via
\`useTimezone\` for both the header label and the formatted timestamp.
- **AreaChart** / **BarChart**: introduce a \`formatChartDate\` helper
that honours each component's existing \`displayDateInUtc\` prop,
otherwise routes through the picker.
- **ChartBlock**: the two recharts \`labelFormatter\` arrows now close
over \`useFormatDateTime\`.
- **ChartHighlightActions**: range labels in the zoom dropdown migrated
to the same hook.
Intentionally untouched (must stay UTC):
- \`ChartHandler\` / \`ChartBlock\` \`startDate\`/\`endDate\` (API range
params, day boundary).
- \`ChartBlock.tsx:166\` explicit \`.utc()\` data-key normalisation.
- \`useFillTimeseriesSorted\` and friends (range math, no display).
## How to test
- Sign in. Open the avatar dropdown, pick a timezone different from your
browser local (e.g. Asia/Tokyo).
- Visit any project, then \`/project/<ref>/reports/database\` (or any
\`/observability/...\` page).
- Hover any chart series — the tooltip header should display the chosen
IANA name and times in that timezone.
- Click-drag a range on a chart to open the zoom dropdown — start/end
labels in the menu should also be in the chosen timezone.
- Switch back to "Auto detect" and confirm everything reverts to
browser-local.
- For an AreaChart/BarChart that uses \`displayDateInUtc\` (e.g. some
legacy reports), confirm those still render in UTC regardless of picker.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Standardized date/time formatting across charts, tooltips, axis
labels, header/footer labels, and highlight range labels in Reports and
chart components.
* Switched to a shared, timezone-aware formatter that respects UTC
display mode or the selected picker/timezone, ensuring consistent,
human-readable timestamps throughout the UI.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR migrates the whole monorepo to use Tailwind v4:
- Removed `@tailwindcss/container-queries` plugin since it's included by
default in v4,
- Bump all instances of Tailwind to v4. Made minimal changes to the
shared config to remove non-supported features (`alpha` mentions),
- Migrate all apps to be compatible with v4 configs,
- Fix the `typography.css` import in 3 apps,
- Add missing rules which were included by default in v3,
- Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot
of classes
- Rename all misnamed classes according to
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all
apps.
---------
Co-authored-by: Jordi Enric <jordi.err@gmail.com>
This PR preps the monorepo for a migration to Tailwind v4:
- Bump all Tailwind dependencies and libraries to the latest possible
version, while still compatible with Tailwind 3.
- Cleans up obsolete Tailwind 3 specific options and configs.
- Cleans up unused CSS files and fixes the CSS imports.
- Migrates all `important` uses in `@apply` lines to using the `!`
prefix.
- Move `typography.css` to the `config` package and import it from the
apps.
- Migrated all occurrences of `flex-grow`, `flex-shrink`,
`overflow-clip` and `overflow-ellipsis` since they're deprecated and
will be removed in Tailwind 4.
- Make the default theme object typesafe in the `ui` package.
- Migrate all `bg-opacity`, `border-opacity`, `ring-opacity` and
`divider-opacity` to the new format where they're declared as part of
the property color.
- Bump and unify all imports of `postcss` dependency.
## Summary
Fixes several high-impact Sentry errors reported in production.
### Fixed Issues
- **[SUPABASE-APP-EJ3](https://supabase.sentry.io/issues/7356937474/)**
— `TypeError: Cannot read properties of undefined (reading 'direct')`.
`connectionStringPooler` could be `undefined` when the connection source
doesn't match any key in the connection strings map. Added an early
return guard in `resolveConnectionString`.
- **[SUPABASE-APP-B17](https://supabase.sentry.io/issues/7117468199/)**
— `RangeError: Invalid time zone specified: Etc/Unknown`.
`dayjs.tz.guess()` returns `"Etc/Unknown"` for some users with
misconfigured browser/OS timezones. Added a shared
`guessLocalTimezone()` helper that validates the guessed timezone via
`Intl.DateTimeFormat` and falls back to UTC. Applied across all 4 call
sites.
- **[SUPABASE-APP-BCM](https://supabase.sentry.io/issues/7192934901/)**
— `TypeError: Cannot convert undefined or null to object`.
`Object.entries(definition.properties)` crashed when a JSON schema
definition existed but had no `properties` field. Updated the guard to
check `definition?.properties` instead of just `definition`.
- https://supabase.sentry.io/issues/7357780302/?project=5459134
- https://supabase.sentry.io/issues/7358344652/?project=5459134
- https://supabase.sentry.io/issues/7096737077/?project=5459134
## Test plan
- [ ] Verify connect dialog renders without errors when connection data
is still loading
- [ ] Verify API docs Entity view handles schema definitions without
properties
- [ ] Verify charts/tooltips display correct timezone labels
---------
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
This PR fixes some prettier issues:
- Bump and unify all prettier versions to 3.7.3 across teh whole repo
- Bump the SQL prettier plugin
- When running `test:prettier`, check `mdx` files also
- Run the new prettier format on all files
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Changes
- Replaces plan ID-based chart gating with entitlement-based checks
across all observability pages (database, auth, realtime,
edge-functions)
- Adds requiredPlan display field so the upsell shows the correct target
plan (e.g. "Upgrade to Team" for disk throughput, not just "Upgrade")
- Decouples database-charts.ts from Organization Plan, now accepts
pre-computed entitlement flags instead
### Note on `requiredPlan`
The entitlement system currently tells us whether a user has access, but
not what plan they need to get access. `requiredPlan` is a frontend-only
display hint. Ideally the backend entitlement response would include a
minimumPlan field so we can remove this hardcoded mapping. For now, this
is a pragmatic workaround to avoid misleading upsell copy (e.g. a Free
user seeing "Upgrade" for a Team-only feature and landing on Pro).
## Testing
### Database
- Head to `/project/_/observability/database` with an Org on the Free
Plan and assert that the Disk throughput is gated.
<img width="1402" height="682" alt="image"
src="https://github.com/user-attachments/assets/b783d866-774d-44dc-88d1-797d26502f02"
/>
### Auth
- Head to `/project/_/observability/auth` with an Org on the Free Plan
and assert that the following metrics are gated:
<img width="1402" height="682" alt="image"
src="https://github.com/user-attachments/assets/cb062dd7-5864-4e40-a11f-ad6be1f7fd41"
/>
### Edge Functions
- Head to `/project/_/observability/edge-functions` with an Org on the
Free Plan and assert that the following metrics are gated:
<img width="1402" height="320" alt="image"
src="https://github.com/user-attachments/assets/517b5483-4575-493c-9401-2c67ac9e684c"
/>
### Realtime
- Head to `/project/_/observability/realtime` with an Org on the Free
Plan and assert that the following metrics are gated:
<img width="1402" height="722" alt="image"
src="https://github.com/user-attachments/assets/0c2757a2-8482-43f4-a65c-c0dde3d878c7"
/>
* support total percentage normalization and show idle time in cpu usage chart
* pretier
* improve test
* clarify in comment why new prop is necessary
* fix type error int est
* refactor to use max value instead of idle property, add more tests
* cleanup composed chart
* prettier
* fix tests
* react improvements
* remove unused stacking properties
* remove rest property references as it wont be used
* fix comment and max cpu desc
* test the resolvehighlightedvalue function
* undo unnecessary composedcharthandler change
* remove unnecessary comment
* minor db charts percentage formatting fixes
* move format check
* fix issue with conflict resolution
* wip
* add formatTimestamp for reports
* add tests for formatTimestamp
* fix type err
* rm old chart logic
* do not retry replication sources
* update report config schema
* use report config
* fix charts, simplify config
* sync charts
* rm comment
* usefilltimeseries
* move chart upsell to its own component
* cleanup v2 chart component
* fix chartheader function format bug
* make attributes dynamic
* move types to its own file
* update reportv2chart types
* update reportv2 chart type
* use new edgefn report
* rm mock
* rm old code
* fix type err
* fix type err
* rename hook
* return sql in dataprovider
* add button to open in log explorer in chart header
* fix type
* fix chart type toggle
* fix type error
* export data transformation for testing
* add tests for data transformation
* rm dupped code
* add report settings to edge fn report
* rm mocked data
* rename
* fix type err
* Apply suggestion from @joshenlim
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
* rm unnecessary div
* rm unnecessary props from report upsell
* cleaner query keys
* move loadin/error/empty states to inside panel content to prevent layout shift
* use card instead of panel
* use buttontooltip in chartheader
* use buttontooltips in buttons with tooltips
* rm export default
* rm export defualt
* rm i from key
* fix status code transformation
* fix filltimeseries
* add tests for filltimeseries
* fix data transform
* pass xaxis key to chart
* refactor hover state to use timestamp not index
* fix tests
* fix areachart
* fix barchart
* fix chartheader
* fix composedchart
* fix stacked
* fix type missing xaxiskey
* type fix
* Revert "refactor hover state to use timestamp not index"
This reverts commit cfd7886460.
* undo charthover changes, fix data aggregation
* Revert "fix tests"
This reverts commit e5200a2035.
* move transforms to testable functions, add tests
* nit refactors and clean up
* feat: add aws nimbus cloud provider (#38312)
* feat: add aws nimbus cloud provider
* Fix return type of useCustomContent hook
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
* add utc plugin to dayjs
* move plugins to vitest setup
* rm customparser plugin
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
Co-authored-by: Alaister Young <alaister@users.noreply.github.com>
* release charts to Teams and Enterprise
* update db charts
* clean up chart types and add disk_fs_used_system
* show update data for Disk Size chart
* remove feature flag release
* update PostgREST connections tooltip
* show percentage in tooltip only if value is not percentage itself
* show percentage in tooltip only if value is not percentage itself
* insert disk_fs_used_system
* update db disk size chart
* reorder admin connection
* improve legend items hover
* show yAxis label
* open range in logs explorer
* add provisioned disk size to Memory Usage chart
* temp new charts
* Network Traffic chart
* sync charts marker
* update api types
* fix layout
* add max memory
* add db size
* chore: remove unused properties
* disk_io_usage
* add max db and pooler connections
* chart header tooltip
* clean charts
* add cpu max
* refactor charts and change max color
* reference line on Database Size chart
* reference line text
* reference lines on Database Size chart
* fix aggregation
* legend spacing
* reference line
* add docsUrl