fix: pre-hydration navbar color to prevent flash, fix hydration mismatch in color picker
This commit is contained in:
1 parent
d6ccc250f6
commit
5b7bd1ebb0
2 files changed
+10
-11
No files matched your search
+1
-1
@@ -42,7 +42,7 @@ export default async function RootLayout({ children }: { children: ReactNode })
|
||||
{/* Apply the saved/default theme before first paint to avoid a flash. */}
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `try{var s=localStorage.getItem('theme');if(s==='dark'||(!s&&${defaultDark}))document.documentElement.classList.add('dark');}catch(e){}`,
|
||||
__html: `try{var s=localStorage.getItem('theme');if(s==='dark'||(!s&&${defaultDark}))document.documentElement.classList.add('dark');var nc=localStorage.getItem('navbarColor'),nt=localStorage.getItem('navbarTextColor');if(nc)document.documentElement.style.setProperty('--color-navbar',nc);if(nt)document.documentElement.style.setProperty('--color-navbar-text',nt);}catch(e){}`,
|
||||
}}
|
||||
/>
|
||||
</head>
|
||||
|
||||
@@ -22,12 +22,8 @@ const COLORS = [
|
||||
|
||||
export function NavbarColorPicker() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [active, setActive] = useState(() => {
|
||||
if (typeof document === "undefined") return 0;
|
||||
const current = getComputedStyle(document.documentElement).getPropertyValue("--color-navbar").trim();
|
||||
const idx = COLORS.findIndex((c) => c.value === current);
|
||||
return idx >= 0 ? idx : 0;
|
||||
});
|
||||
const [active, setActive] = useState(0);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
function apply(index: number) {
|
||||
const c = COLORS[index];
|
||||
@@ -45,12 +41,15 @@ export function NavbarColorPicker() {
|
||||
useEffect(() => {
|
||||
const saved = localStorage.getItem("navbarColor");
|
||||
const savedText = localStorage.getItem("navbarTextColor");
|
||||
if (saved && savedText) {
|
||||
document.documentElement.style.setProperty("--color-navbar", saved);
|
||||
document.documentElement.style.setProperty("--color-navbar-text", savedText);
|
||||
if (saved) {
|
||||
const idx = COLORS.findIndex((c) => c.value === saved);
|
||||
if (idx >= 0) setActive(idx);
|
||||
document.documentElement.style.setProperty("--color-navbar", saved);
|
||||
}
|
||||
if (savedText) {
|
||||
document.documentElement.style.setProperty("--color-navbar-text", savedText);
|
||||
}
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@@ -71,7 +70,7 @@ export function NavbarColorPicker() {
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{open && (
|
||||
{mounted && open && (
|
||||
<div
|
||||
className="absolute right-0 mt-1 min-w-[200px] rounded-xl shadow-xl z-50 py-3 px-2 border backdrop-blur-md"
|
||||
style={{ backgroundColor: "color-mix(in srgb, var(--color-dropdown) 97%, transparent)", borderColor: "color-mix(in srgb, var(--color-text-muted) 10%, transparent)" }}
|
||||
|
||||
Reference in new issue
Block a user