()
+
+ return {
+ ...actual,
+ Slider: (props: SliderProps) => (
+ props.onValueChange?.([100])}
+ onKeyUp={() => props.onValueCommit?.([100])}
+ onLostPointerCapture={props.onLostPointerCapture}
+ />
+ ),
+ }
+})
+
+describe('ThemeColorSettings', () => {
+ beforeEach(() => {
+ resetOverrides.mockReset()
+ setOverride.mockReset()
+ document.documentElement.style.removeProperty('--chroma')
+ document.documentElement.dataset.theme = 'dark'
+ })
+
+ it('persists a rapid pointer change for the active mode', () => {
+ customRender()
+
+ const slider = screen.getByRole('slider', { name: 'Color intensity' })
+ fireEvent.click(slider)
+ fireEvent.lostPointerCapture(slider)
+
+ expect(setOverride).toHaveBeenCalledWith('chroma', 0.04)
+ })
+
+ it('persists an ordinary committed change', () => {
+ customRender()
+
+ const slider = screen.getByRole('slider', { name: 'Color intensity' })
+ fireEvent.click(slider)
+ fireEvent.keyUp(slider)
+
+ expect(setOverride).toHaveBeenCalledWith('chroma', 0.04)
+ })
+
+ it('resets the active mode', () => {
+ customRender()
+
+ fireEvent.click(screen.getByRole('button', { name: 'Reset' }))
+
+ expect(resetOverrides).toHaveBeenCalledOnce()
+ })
+
+ it('restores persisted values when an active preview unmounts', () => {
+ const { unmount } = customRender()
+
+ fireEvent.click(screen.getByRole('slider', { name: 'Color intensity' }))
+ expect(document.documentElement.style.getPropertyValue('--chroma')).toBe('0.04')
+
+ unmount()
+
+ expect(document.documentElement.style.getPropertyValue('--chroma')).toBe('0.02')
+ })
+
+ it('does not restore persisted Dark values when switching to Classic Dark', () => {
+ const { rerender } = customRender()
+
+ fireEvent.click(screen.getByRole('slider', { name: 'Color intensity' }))
+ applyResolvedThemeOverrides(document.documentElement, 'classic-dark', 'dark', { chroma: 0.02 })
+ rerender()
+
+ expect(document.documentElement.style.getPropertyValue('--chroma')).toBe('')
+ })
+})
diff --git a/apps/studio/vite.config.ts b/apps/studio/vite.config.ts
index 1b860d0e2fa..9ac9552668a 100644
--- a/apps/studio/vite.config.ts
+++ b/apps/studio/vite.config.ts
@@ -629,6 +629,11 @@ export default defineConfig(({ command, mode }) => {
// whichever page/feature chunk happens to be its only non-barrel
// importer (a form page, `components/interfaces/Sidebar.tsx`)
// while `ui`'s barrel re-exports them too.
+ //
+ // `packages/ui/src/components/shadcn/ui/slider.tsx` — same shape
+ // again: its only non-barrel importer is the Appearance settings'
+ // `ThemeColorSettings`, so Rolldown pools it into the `/account/me`
+ // page chunk while `ui`'s barrel re-exports it too.
build: {
rollupOptions: {
output: {
@@ -665,6 +670,9 @@ export default defineConfig(({ command, mode }) => {
) {
return 'ui-sidebar'
}
+ if (id.includes('packages/ui/src/components/shadcn/ui/slider.tsx')) {
+ return 'ui-slider'
+ }
return undefined
},
},
diff --git a/packages/common/constants/local-storage.ts b/packages/common/constants/local-storage.ts
index 23808138393..d713fbe3026 100644
--- a/packages/common/constants/local-storage.ts
+++ b/packages/common/constants/local-storage.ts
@@ -17,6 +17,7 @@ export const LOCAL_STORAGE_KEYS = {
UNIFIED_LOGS_DOCK: 'unified-logs-dock',
UI_TIMEZONE: 'supabase-ui-timezone',
+ UI_THEME_OVERRIDES: 'supabase-ui-theme-overrides',
UI_PREVIEW_CLS: 'supabase-ui-cls',
UI_PREVIEW_INLINE_EDITOR: 'supabase-ui-preview-inline-editor',
UI_PREVIEW_UNIFIED_LOGS: 'supabase-ui-preview-unified-logs',
@@ -180,6 +181,7 @@ const LOCAL_STORAGE_KEYS_ALLOWLIST = [
LOCAL_STORAGE_KEYS.LINTER_SHOW_FOOTER,
LOCAL_STORAGE_KEYS.SIDEBAR_BEHAVIOR,
LOCAL_STORAGE_KEYS.UI_TIMEZONE,
+ LOCAL_STORAGE_KEYS.UI_THEME_OVERRIDES,
]
export function clearLocalStorage() {