Files
supabase/apps/studio/components/interfaces/SQLEditor/SQLEditorLayout.tsx
Danny White ec53175b8a refactor(ui): rename text-brand to text-primary (#50564)
## What kind of change does this PR introduce?

Refactor. Follow-up to #49871.

## What is the current behavior?

Branded (green) text still uses the `text-brand` classname while the
colour comes from `--primary`.

## What is the new behavior?

**Rename-only:** `text-brand` → `text-primary` across callsites and
docs. Leftover `bg-brand` / `border-brand` alias to `brand-default`. No
intentional colour changes in this PR.

This better matches how we treat our green in other components and
props, like `variant="primary"` for green buttons.

## To test

On light mode: smoke-test that branded text still looks like #49871
(readable green, not the bright fill).

-
[Homepage](https://zone-www-dot-com-git-dnywh-depr-316-text-brand-de2380-supabase.vercel.app/):
“Scale to millions” uses `text-primary`
- [Docs
homepage](https://docs-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/docs):
branded links like “More on self-hosting” are still readable
- [Typography
docs](https://design-system-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/design-system/docs/typography):
documents `text-primary`
- [Colour
usage](https://design-system-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/design-system/docs/color-usage):
`text-primary` is visibly darker than `bg-brand-default` _on light mode_
- [Studio auth
providers](https://studio-staging-git-dnywh-depr-316-text-brand-to-60fa6c-supabase.vercel.app/dashboard/project/_/auth/providers):
enabled provider badge text readable; status dot stays bright green

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Style**
* Updated branded text, link hover states, icons, badges, indicators,
and highlighted content across the Design System, Docs, Studio, Learn,
UI Library, and marketing experiences to use the primary theme color.
* Updated syntax highlighting and table-of-contents styling for
consistent primary-color presentation.
  * Refined brand color fallback behavior for bright fills and borders.

* **Documentation**
* Updated color-usage and typography guidance to recommend the primary
text utility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-22 16:19:03 +10:00

160 lines
5.1 KiB
TypeScript

import { acceptUntrustedSql, untrustedSql } from '@supabase/pg-meta'
import { LOCAL_STORAGE_KEYS } from 'common'
import { Loader2 } from 'lucide-react'
import { useCallback } from 'react'
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from 'ui'
import { RunQueryWarningModal } from './RunQueryWarningModal'
import type { UtilityTab } from './SQLEditor.types'
import { appendEnableRLSStatements } from './SQLEditor.utils'
import { useSQLEditorContext } from './SQLEditorContext'
import {
useSqlEditorAssistant,
useSqlEditorRun,
useSqlEditorSnippet,
useSqlEditorUi,
} from './SQLEditorControllers'
import { SQLEditorEditorPanel } from './SQLEditorEditorPanel'
import { UtilityActions } from './UtilityPanel/UtilityActions'
import { UtilityPanel } from './UtilityPanel/UtilityPanel'
import { acceptUntrustedLogsSql } from '@/data/logs/safe-analytics-sql'
const SQLEditorRunWarningModal = () => {
const { refocusEditor, clearPendingRunRefocus, markRefocusAfterRun } = useSQLEditorContext()
const { potentialIssues, resetPotentialIssues, executeQuery, readEditorSql } = useSqlEditorRun()
return (
<RunQueryWarningModal
visible={!!potentialIssues}
potentialIssues={potentialIssues}
onCancel={() => {
clearPendingRunRefocus()
resetPotentialIssues()
refocusEditor()
}}
onConfirm={() => {
markRefocusAfterRun()
resetPotentialIssues()
const sql = readEditorSql()
if (sql === undefined) return clearPendingRunRefocus()
// The user has reviewed the warning and confirmed — promote here.
void executeQuery(acceptUntrustedSql(sql), true)
}}
onConfirmWithRLS={() => {
const tables = potentialIssues?.createTablesMissingRLS ?? []
if (tables.length === 0) return
const baseSql = readEditorSql() ?? untrustedSql('')
const rewrittenSql = appendEnableRLSStatements(baseSql, tables)
markRefocusAfterRun()
resetPotentialIssues()
// The user has reviewed the warning and confirmed — promote here.
void executeQuery(acceptUntrustedSql(untrustedSql(rewrittenSql)), true)
}}
/>
)
}
/** The top-bar controls (run / prettify / etc.). */
const SQLEditorToolbar = () => {
const { clearPendingRunRefocus, markRefocusAfterRun } = useSQLEditorContext()
const { id } = useSqlEditorSnippet()
const { diff } = useSqlEditorAssistant()
const {
executeQuery,
readEditorSql,
isExecuting,
prettifyQuery,
runSource,
executeLogsQuery,
readEditorLogsSql,
} = useSqlEditorRun()
const { hasSelection } = useSqlEditorUi()
// Run gesture from the toolbar button — promote here, at the user action.
const runQuery = useCallback(() => {
markRefocusAfterRun()
if (runSource._tag === 'logs') {
const sql = readEditorLogsSql()
if (sql === undefined) return clearPendingRunRefocus()
void executeLogsQuery(acceptUntrustedLogsSql(sql))
} else {
const sql = readEditorSql()
if (sql === undefined) return clearPendingRunRefocus()
void executeQuery(acceptUntrustedSql(sql))
}
}, [
clearPendingRunRefocus,
executeLogsQuery,
executeQuery,
markRefocusAfterRun,
readEditorLogsSql,
readEditorSql,
runSource._tag,
])
return (
<UtilityActions
id={id}
runSource={runSource}
isExecuting={isExecuting}
isDisabled={diff.isDiffOpen}
hasSelection={hasSelection}
prettifyQuery={prettifyQuery}
executeQuery={runQuery}
className="px-4 min-h-[42px] border-b shrink-0"
/>
)
}
/** The bottom (results) resizable panel: loading state + utility panel. */
const SQLEditorResultsPanel = () => {
const { id, isLoading } = useSqlEditorSnippet()
const { diff, ai } = useSqlEditorAssistant()
const { isExecuting } = useSqlEditorRun()
const { activeUtilityTab, setActiveUtilityTab } = useSqlEditorUi()
return isLoading ? (
<div className="flex h-full w-full items-center justify-center">
<Loader2 className="animate-spin text-primary" />
</div>
) : (
<UtilityPanel
id={id}
isExecuting={isExecuting}
isDisabled={diff.isDiffOpen}
onDebug={ai.onDebug}
buildDebugPrompt={ai.buildDebugPrompt}
activeTab={activeUtilityTab}
onActiveTabChange={(tab) => setActiveUtilityTab(tab as UtilityTab)}
/>
)
}
/** The SQL editor shell: warning modal, toolbar, and the editor/results split. */
export const SQLEditorLayout = () => {
return (
<>
<SQLEditorRunWarningModal />
<div className="flex flex-col h-full">
<SQLEditorToolbar />
<ResizablePanelGroup
className="relative flex-1 min-h-0"
orientation="vertical"
autoSaveId={LOCAL_STORAGE_KEYS.SQL_EDITOR_SPLIT_SIZE}
>
<ResizablePanel defaultSize="50" maxSize="70">
<SQLEditorEditorPanel />
</ResizablePanel>
<ResizableHandle withHandle />
<ResizablePanel defaultSize="50" maxSize="70">
<SQLEditorResultsPanel />
</ResizablePanel>
</ResizablePanelGroup>
</div>
</>
)
}