From c8ca3f00c0521ac22d95b1ecf1ec98aaa589effd Mon Sep 17 00:00:00 2001 From: ambar Date: Thu, 28 Mar 2024 22:10:38 +0800 Subject: [PATCH] fix: avoid flash of navbar images (logo and theme icon) --- .changeset/thin-houses-flash.md | 5 ++ .../src/components/Nav/NavBarTitle.tsx | 60 +++++++++++-------- .../src/components/SwitchAppearance/index.tsx | 24 ++++---- packages/theme-default/src/logic/utils.ts | 12 ---- 4 files changed, 54 insertions(+), 47 deletions(-) create mode 100644 .changeset/thin-houses-flash.md diff --git a/.changeset/thin-houses-flash.md b/.changeset/thin-houses-flash.md new file mode 100644 index 000000000..f9e4e236c --- /dev/null +++ b/.changeset/thin-houses-flash.md @@ -0,0 +1,5 @@ +--- +"@rspress/theme-default": patch +--- + +fix: avoid flash of navbar images (logo and theme icon) diff --git a/packages/theme-default/src/components/Nav/NavBarTitle.tsx b/packages/theme-default/src/components/Nav/NavBarTitle.tsx index faeeb8ceb..fe5dff1f0 100644 --- a/packages/theme-default/src/components/Nav/NavBarTitle.tsx +++ b/packages/theme-default/src/components/Nav/NavBarTitle.tsx @@ -1,27 +1,44 @@ -import { useContext, useEffect, useState } from 'react'; -import { - ThemeContext, - normalizeImagePath, - usePageData, - withBase, -} from '@rspress/runtime'; +import { useMemo } from 'react'; +import { normalizeImagePath, usePageData, withBase } from '@rspress/runtime'; import styles from './index.module.scss'; -import { getLogoUrl, useLocaleSiteData } from '../../logic'; +import { useLocaleSiteData } from '../../logic'; export const NavBarTitle = () => { const { siteData } = usePageData(); const localeData = useLocaleSiteData(); const { logo: rawLogo, logoText } = siteData; const title = localeData.title ?? siteData.title; - const { theme } = useContext(ThemeContext); - const [logo, setLogo] = useState(getLogoUrl(rawLogo, theme)); - const [logoVisible, setLogoVisible] = useState(false); - - useEffect(() => { - setLogoVisible(true); - const newLogoUrl = getLogoUrl(rawLogo, theme); - setLogo(newLogoUrl); - }, [theme, rawLogo]); + const logo = useMemo(() => { + if (!rawLogo) { + return null; + } + if (typeof rawLogo === 'string') { + return ( + + ); + } + return ( + <> + + + + ); + }, [rawLogo]); return (
@@ -29,14 +46,7 @@ export const NavBarTitle = () => { href={withBase(localeData.langRoutePrefix || '/')} className="flex items-center w-full h-full text-base font-semibold transition-opacity duration-300 hover:opacity-60" > - {logo && logoVisible && ( - - )} + {logo} {logoText && {logoText}} {!logo && !logoText && {title}} diff --git a/packages/theme-default/src/components/SwitchAppearance/index.tsx b/packages/theme-default/src/components/SwitchAppearance/index.tsx index de766d536..b3386873c 100644 --- a/packages/theme-default/src/components/SwitchAppearance/index.tsx +++ b/packages/theme-default/src/components/SwitchAppearance/index.tsx @@ -16,7 +16,6 @@ export function SwitchAppearance({ onClick }: { onClick?: () => void }) { const isDark = updateUserPreferenceFromStorage(); setTheme(isDark ? 'dark' : 'light'); }; - const [iconVisible, setIconVisible] = useState(false); useEffect(() => { if (isDarkMode()) { @@ -25,7 +24,6 @@ export function SwitchAppearance({ onClick }: { onClick?: () => void }) { if (typeof window !== 'undefined') { window.addEventListener('storage', updateAppearanceAndTheme); } - setIconVisible(true); return () => { if (typeof window !== 'undefined') { window.removeEventListener('storage', updateAppearanceAndTheme); @@ -43,14 +41,20 @@ export function SwitchAppearance({ onClick }: { onClick?: () => void }) { className="md:mr-2 rspress-nav-appearance" >
- {iconVisible && ( - - )} + +
); diff --git a/packages/theme-default/src/logic/utils.ts b/packages/theme-default/src/logic/utils.ts index 7c052fd8b..09fa296ba 100644 --- a/packages/theme-default/src/logic/utils.ts +++ b/packages/theme-default/src/logic/utils.ts @@ -22,18 +22,6 @@ export function isActive( ); } -export function getLogoUrl( - rawLogo: string | { dark: string; light: string }, - theme: 'dark' | 'light', -) { - // If logo is a string, use it directly - if (typeof rawLogo === 'string') { - return rawLogo; - } - // If logo is an object, use dark/light mode logo - return theme === 'dark' ? rawLogo.dark : rawLogo.light; -} - export function isMobileDevice() { return window.innerWidth <= 1024; }