split text size into a follow-up

This commit is contained in:
Danny White committed 2026-09-15 12:02:17 +10:00
1 parent ded0d71e5b
commit 8e350c1d11
11 files changed
+1 -177

No files matched your search

@@ -1,39 +0,0 @@
import { CardContent, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { useTextSize } from '@/hooks/misc/useTextSize'
import { applyTextSize, parseTextSize, TEXT_SIZE_OPTIONS } from '@/lib/text-size'
export const TextSizeSettings = () => {
const { textSize, setTextSize } = useTextSize()
return (
<CardContent>
<FormItemLayout
isReactForm={false}
label="Text size"
layout="flex-row-reverse"
description="Adjust the size of interface text without changing layout density."
>
<Select
value={textSize}
onValueChange={(next) => {
const value = parseTextSize(next)
applyTextSize(document.documentElement, value)
setTextSize(value)
}}
>
<SelectTrigger aria-label="Text size">
<SelectValue />
</SelectTrigger>
<SelectContent>
{TEXT_SIZE_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</FormItemLayout>
</CardContent>
)
}
@@ -25,7 +25,6 @@ import {
PageSectionTitle,
} from 'ui-patterns/PageSection'
import { TextSizeSettings } from './TextSizeSettings'
import { ThemeColorSettings } from './ThemeColorSettings'
import { DEFAULT_SIDEBAR_BEHAVIOR } from '@/components/interfaces/Sidebar'
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
@@ -114,7 +113,6 @@ export const ThemeSettings = () => {
</div>
</CardContent>
<ThemeColorSettings />
<TextSizeSettings />
<CardContent>
<FormItemLayout
isReactForm={false}
@@ -1,21 +1,16 @@
import { useTheme } from 'next-themes'
import { useLayoutEffect } from 'react'
import { useTextSize } from '@/hooks/misc/useTextSize'
import { useThemeOverrides } from '@/hooks/misc/useThemeOverrides'
import { applyTextSize } from '@/lib/text-size'
import { applyThemeOverrides } from '@/lib/theme-overrides'
export const AppearanceSettingsProvider = () => {
const { theme, setTheme } = useTheme()
const { mode, overrides } = useThemeOverrides()
const { textSize } = useTextSize()
useLayoutEffect(() => {
if (theme === 'classic-dark') setTheme('dark')
applyThemeOverrides(document.documentElement, mode, overrides)
applyTextSize(document.documentElement, textSize)
}, [mode, overrides, setTheme, textSize, theme])
}, [mode, overrides, setTheme, theme])
return null
}
@@ -1,10 +0,0 @@
import { LOCAL_STORAGE_KEYS } from 'common'
const textSizeKey = JSON.stringify(LOCAL_STORAGE_KEYS.UI_TEXT_SIZE)
const appearanceSettingsScript = `try{const value=JSON.parse(localStorage.getItem(${textSizeKey}));document.documentElement.dataset.textSize=value==='small'||value==='large'?value:'default'}catch{document.documentElement.dataset.textSize='default'}`
/** Applies persisted typography before Studio paints to avoid a layout shift. */
export const AppearanceSettingsScript = () => (
<script dangerouslySetInnerHTML={{ __html: appearanceSettingsScript }} />
)
-31
View File
@@ -1,31 +0,0 @@
import { LOCAL_STORAGE_KEYS, safeLocalStorage } from 'common'
import { useCallback, useMemo } from 'react'
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
import { parseTextSize, TextSize } from '@/lib/text-size'
function readStoredTextSize(): TextSize {
const stored = safeLocalStorage.getItem(LOCAL_STORAGE_KEYS.UI_TEXT_SIZE)
if (stored === null) return 'default'
try {
return parseTextSize(JSON.parse(stored))
} catch {
return 'default'
}
}
export function useTextSize() {
const [storedTextSize, setStoredTextSize] = useLocalStorageQuery<unknown>(
LOCAL_STORAGE_KEYS.UI_TEXT_SIZE,
readStoredTextSize()
)
const textSize = useMemo(() => parseTextSize(storedTextSize), [storedTextSize])
const setTextSize = useCallback(
(value: TextSize) => setStoredTextSize(value),
[setStoredTextSize]
)
return { textSize, setTextSize }
}
@@ -1,29 +0,0 @@
import { describe, expect, it } from 'vitest'
import { applyTextSize, parseTextSize, TEXT_SIZE_OPTIONS } from '@/lib/text-size'
describe('text size', () => {
it('provides the three supported options', () => {
expect(TEXT_SIZE_OPTIONS).toEqual([
{ label: 'Small', value: 'small' },
{ label: 'Default', value: 'default' },
{ label: 'Large', value: 'large' },
])
})
it.each(['small', 'default', 'large'] as const)('parses %s', (textSize) => {
expect(parseTextSize(textSize)).toBe(textSize)
})
it.each([undefined, null, 'compact', 1, {}])('defaults malformed data: %j', (value) => {
expect(parseTextSize(value)).toBe('default')
})
it('applies the root data attribute', () => {
const root = document.createElement('html')
applyTextSize(root, 'large')
expect(root.dataset.textSize).toBe('large')
})
})
-20
View File
@@ -1,20 +0,0 @@
import * as z from 'zod'
export const TEXT_SIZE_OPTIONS = [
{ label: 'Small', value: 'small' },
{ label: 'Default', value: 'default' },
{ label: 'Large', value: 'large' },
] as const
const textSizeSchema = z.enum(['small', 'default', 'large'])
export type TextSize = z.infer<typeof textSizeSchema>
export function parseTextSize(value: unknown): TextSize {
const parsed = textSizeSchema.safeParse(value)
return parsed.success ? parsed.data : 'default'
}
export function applyTextSize(root: HTMLElement, textSize: TextSize) {
root.dataset.textSize = textSize
}
-2
View File
@@ -39,7 +39,6 @@ import { studioThemeValues, TooltipProvider } from 'ui'
import { TimestampInfoProvider } from 'ui-patterns/TimestampInfo'
import { AppearanceSettingsProvider } from '@/components/interfaces/App/AppearanceSettingsProvider'
import { AppearanceSettingsScript } from '@/components/interfaces/App/AppearanceSettingsScript'
import { StudioCommandMenu } from '@/components/interfaces/App/CommandMenu'
import { StudioCommandProvider as CommandProvider } from '@/components/interfaces/App/CommandMenu/StudioCommandProvider'
import { FeaturePreviewContextProvider } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
@@ -184,7 +183,6 @@ function CustomApp({ Component, pageProps }: AppPropsWithLayout) {
<TimestampInfoTimezoneBridge>
<Head>
<title>{appTitle ?? 'Supabase'}</title>
<AppearanceSettingsScript />
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<meta property="og:image" content={`${BASE_PATH}/img/supabase-og.png`} />
<meta name="googlebot" content="notranslate" />
-2
View File
@@ -61,7 +61,6 @@ import { studioThemeValues, TooltipProvider } from 'ui'
import { TimestampInfoProvider } from 'ui-patterns/TimestampInfo'
import { AppearanceSettingsProvider } from '@/components/interfaces/App/AppearanceSettingsProvider'
import { AppearanceSettingsScript } from '@/components/interfaces/App/AppearanceSettingsScript'
import { StudioCommandMenu } from '@/components/interfaces/App/CommandMenu'
import { StudioCommandProvider as CommandProvider } from '@/components/interfaces/App/CommandMenu/StudioCommandProvider'
import { FeaturePreviewContextProvider } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
@@ -431,7 +430,6 @@ function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
// prerendered shell can't know. Scoped to this element only.
<html lang="en" suppressHydrationWarning>
<head>
<AppearanceSettingsScript />
<HeadContent />
</head>
<body>
-34
View File
@@ -68,40 +68,6 @@
--font-weight-normal: 450;
}
:root[data-text-size='small'] {
--text-grid: 12.22px;
--text-xs: 0.705rem;
--text-sm: 0.7638rem;
--text-base: 0.8813rem;
--text-lg: 0.94rem;
--text-xl: 1.0575rem;
--text-2xl: 1.2925rem;
--text-3xl: 1.645rem;
--text-4xl: 1.9975rem;
--text-5xl: 2.7025rem;
--text-6xl: 3.4075rem;
--text-7xl: 4.1125rem;
--text-8xl: 5.5225rem;
--text-9xl: 7.4025rem;
}
:root[data-text-size='large'] {
--text-grid: 13.78px;
--text-xs: 0.795rem;
--text-sm: 0.8613rem;
--text-base: 0.9938rem;
--text-lg: 1.06rem;
--text-xl: 1.1925rem;
--text-2xl: 1.4575rem;
--text-3xl: 1.855rem;
--text-4xl: 2.2525rem;
--text-5xl: 3.0475rem;
--text-6xl: 3.8425rem;
--text-7xl: 4.6375rem;
--text-8xl: 6.2275rem;
--text-9xl: 8.3475rem;
}
@keyframes shimmer {
0% {
background-position: -1000px 0;
@@ -18,7 +18,6 @@ export const LOCAL_STORAGE_KEYS = {
UI_TIMEZONE: 'supabase-ui-timezone',
UI_THEME_OVERRIDES: 'supabase-ui-theme-overrides',
UI_TEXT_SIZE: 'supabase-ui-text-size',
UI_PREVIEW_CLS: 'supabase-ui-cls',
UI_PREVIEW_INLINE_EDITOR: 'supabase-ui-preview-inline-editor',
UI_PREVIEW_UNIFIED_LOGS: 'supabase-ui-preview-unified-logs',
@@ -182,7 +181,6 @@ const LOCAL_STORAGE_KEYS_ALLOWLIST = [
LOCAL_STORAGE_KEYS.SIDEBAR_BEHAVIOR,
LOCAL_STORAGE_KEYS.UI_TIMEZONE,
LOCAL_STORAGE_KEYS.UI_THEME_OVERRIDES,
LOCAL_STORAGE_KEYS.UI_TEXT_SIZE,
]
export function clearLocalStorage() {