mirror of
https://github.com/supabase/supabase.git
synced 2026-10-18 23:59:08 +03:00
55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
import { Moon, Sun } from 'lucide-react'
|
|
import { useTheme } from 'next-themes'
|
|
import { useEffect, useState } from 'react'
|
|
|
|
import Panel from 'components/ui/Panel'
|
|
import { Listbox, Theme, themes } from 'ui'
|
|
|
|
const ThemeSettings = () => {
|
|
const [mounted, setMounted] = useState(false)
|
|
const { theme, resolvedTheme, setTheme } = useTheme()
|
|
|
|
/**
|
|
* Avoid Hydration Mismatch
|
|
* https://github.com/pacocoursey/next-themes?tab=readme-ov-file#avoid-hydration-mismatch
|
|
*/
|
|
// useEffect only runs on the client, so now we can safely show the UI
|
|
useEffect(() => {
|
|
setMounted(true)
|
|
}, [])
|
|
|
|
if (!mounted) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<Panel title={<h5 key="panel-title">Theme</h5>}>
|
|
<Panel.Content>
|
|
<Listbox
|
|
value={theme}
|
|
label="Interface theme"
|
|
descriptionText="Choose a theme preference"
|
|
layout="horizontal"
|
|
style={{ width: '50%' }}
|
|
icon={resolvedTheme === 'dark' ? <Moon /> : <Sun />}
|
|
onChange={(value: string) => setTheme(value)}
|
|
>
|
|
{themes
|
|
.filter(
|
|
(theme: Theme) =>
|
|
// temporary fix to exclude new themes
|
|
theme.value === 'light' || theme.value === 'dark' || theme.value === 'system'
|
|
)
|
|
.map((theme: Theme) => (
|
|
<Listbox.Option key={theme.value} label={theme.name} value={theme.value}>
|
|
{theme.name}
|
|
</Listbox.Option>
|
|
))}
|
|
</Listbox>
|
|
</Panel.Content>
|
|
</Panel>
|
|
)
|
|
}
|
|
|
|
export default ThemeSettings
|