From 8343886118e54e5b9e05f3abf9d7a99093e98861 Mon Sep 17 00:00:00 2001 From: yangxingyuan Date: Sun, 18 Feb 2024 12:03:42 +0800 Subject: [PATCH] fix: ui switch query --- .changeset/config.json | 2 +- .changeset/spotty-needles-clap.md | 6 ++ packages/document/rspress.config.ts | 7 +- .../src/components/LocalSideBar/index.tsx | 4 + .../src/components/Sidebar/index.tsx | 14 +-- .../src/layout/DocLayout/index.tsx | 69 ++++-------- .../theme-default/src/layout/Layout/index.tsx | 81 ++------------ packages/theme-default/src/logic/index.ts | 3 +- .../theme-default/src/logic/useHiddenNav.ts | 10 +- .../src/logic/useRedirect4FirstVisit.ts | 50 +++++++++ .../theme-default/src/logic/useUISwitch.ts | 101 ++++++++++++++++++ .../src/node/source-build-plugin.ts | 6 +- packages/theme-default/src/styles/index.ts | 2 +- .../styles/{scrollbar.css => scrollbar.scss} | 0 14 files changed, 215 insertions(+), 140 deletions(-) create mode 100644 .changeset/spotty-needles-clap.md create mode 100644 packages/theme-default/src/logic/useRedirect4FirstVisit.ts create mode 100644 packages/theme-default/src/logic/useUISwitch.ts rename packages/theme-default/src/styles/{scrollbar.css => scrollbar.scss} (100%) diff --git a/.changeset/config.json b/.changeset/config.json index 48f69b8c5..1f81af7dd 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -6,7 +6,7 @@ "access": "restricted", "baseBranch": "main", "fixed": [ - ["@rspress/*", "rspress", "create-rspress", "@modern-js/plugin-rspress", "@rspress-fixture/*"] + ["@rspress/*", "rspress", "create-rspress", "@modern-js/plugin-rspress"] ], "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { "onlyUpdatePeerDependentsWhenOutOfRange": true, diff --git a/.changeset/spotty-needles-clap.md b/.changeset/spotty-needles-clap.md new file mode 100644 index 000000000..5d0cf7422 --- /dev/null +++ b/.changeset/spotty-needles-clap.md @@ -0,0 +1,6 @@ +--- +"@rspress/theme-default": patch +"@rspress/docs": patch +--- + +fix: ui switch query diff --git a/packages/document/rspress.config.ts b/packages/document/rspress.config.ts index af15b532a..59f0b3b64 100644 --- a/packages/document/rspress.config.ts +++ b/packages/document/rspress.config.ts @@ -44,9 +44,10 @@ export default defineConfig({ { tag: 'meta', attrs: { - content: 'https://github.com/web-infra-dev/rspress/assets/39261479/999e7946-45ff-45d5-b9cd-594e634e0e5a', - property: "og:image", - } + content: + 'https://github.com/web-infra-dev/rspress/assets/39261479/999e7946-45ff-45d5-b9cd-594e634e0e5a', + property: 'og:image', + }, }, { tag: 'script', diff --git a/packages/theme-default/src/components/LocalSideBar/index.tsx b/packages/theme-default/src/components/LocalSideBar/index.tsx index 95af855a0..695dcd83e 100644 --- a/packages/theme-default/src/components/LocalSideBar/index.tsx +++ b/packages/theme-default/src/components/LocalSideBar/index.tsx @@ -5,13 +5,16 @@ import ArrowRight from '../../assets/arrow-right.svg'; import { SideBar } from '../Sidebar'; import './index.scss'; import { Toc } from '../Toc'; +import { UISwitchResult } from '#theme/logic/useUISwitch'; export function SideMenu({ beforeSidebar, afterSidebar, + uiSwitch, }: { beforeSidebar?: React.ReactNode; afterSidebar?: React.ReactNode; + uiSwitch?: UISwitchResult; }) { const [isSidebarOpen, setSidebarIsOpen] = useState(false); const [isTocOpen, setIsTocOpen] = useState(false); @@ -81,6 +84,7 @@ export function SideMenu({ isSidebarOpen={isSidebarOpen} beforeSidebar={beforeSidebar} afterSidebar={afterSidebar} + uiSwitch={uiSwitch} /> {isSidebarOpen ? (
= new WeakMap(); export function SideBar(props: Props) { - const { isSidebarOpen, beforeSidebar, afterSidebar } = props; + const { isSidebarOpen, beforeSidebar, afterSidebar, uiSwitch } = props; const { items: rawSidebarData } = useSidebarData(); const localesData = useLocaleSiteData(); const { pathname: rawPathname } = useLocation(); const langRoutePrefix = normalizeSlash(localesData.langRoutePrefix || ''); - const [hideNavbar] = useDisableNav(); const [sidebarData, setSidebarData] = useState< (ISidebarDivider | ISidebarItem | NormalizedSidebarGroup)[] >(rawSidebarData.filter(Boolean).flat()); @@ -131,7 +127,7 @@ export function SideBar(props: Props) { isSidebarOpen ? styles.open : '' }`} > - {hideNavbar ? null : ( + {!uiSwitch.showNavbar ? null : (
diff --git a/packages/theme-default/src/layout/DocLayout/index.tsx b/packages/theme-default/src/layout/DocLayout/index.tsx index e68a3a754..54b88bb88 100644 --- a/packages/theme-default/src/layout/DocLayout/index.tsx +++ b/packages/theme-default/src/layout/DocLayout/index.tsx @@ -1,16 +1,16 @@ -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import { MDXProvider } from '@mdx-js/react'; import { getCustomMDXComponent } from '@theme'; -import { Content, useLocation, usePageData, NoSSR } from '@rspress/runtime'; +import { Content, usePageData, NoSSR } from '@rspress/runtime'; import { Aside } from '../../components/Aside'; import { DocFooter } from '../../components/DocFooter'; -import { useDisableNav, useLocaleSiteData } from '../../logic'; +import { useLocaleSiteData } from '../../logic'; import { SideMenu } from '../../components/LocalSideBar'; import { Overview } from '../../components/Overview'; import { TabDataContext } from '../../logic/TabDataContext'; -import { QueryStatus } from '../Layout'; import ScrollToTop from '../../components/ScrollToTop/index'; import styles from './index.module.scss'; +import { UISwitchResult } from '#theme/logic/useUISwitch'; export interface DocLayoutProps { beforeSidebar?: React.ReactNode; @@ -20,6 +20,7 @@ export interface DocLayoutProps { afterDoc?: React.ReactNode; beforeOutline?: React.ReactNode; afterOutline?: React.ReactNode; + uiSwitch?: UISwitchResult; } export function DocLayout(props: DocLayoutProps) { @@ -31,51 +32,19 @@ export function DocLayout(props: DocLayoutProps) { afterOutline, beforeSidebar, afterSidebar, + uiSwitch, } = props; const { siteData, page } = usePageData(); const { toc = [], frontmatter } = page; const [tabData, setTabData] = useState({}); const headers = toc; const { themeConfig } = siteData; - const localesData = useLocaleSiteData(); - const sidebar = localesData.sidebar || {}; - const [disableNavbar] = useDisableNav(); const enableScrollToTop = themeConfig.enableScrollToTop ?? false; - // siderbar Priority - // 1. frontmatter.sidebar - // 2. themeConfig.locales.sidebar - // 3. themeConfig.sidebar - const hasSidebar = - frontmatter?.sidebar !== false && Object.keys(sidebar).length > 0; + const localesData = useLocaleSiteData(); const outlineTitle = localesData?.outlineTitle || themeConfig?.outlineTitle || 'ON THIS PAGE'; const isOverviewPage = frontmatter?.overview ?? false; - const [hasFooter, setHasFooter] = useState(frontmatter?.footer ?? true); - const location = useLocation(); - - const getHasAside = () => { - // if in iframe, default value is false - const defaultHasAside = - typeof window === 'undefined' ? true : window.top === window.self; - return ( - (frontmatter?.outline ?? themeConfig?.outline ?? defaultHasAside) && - !isOverviewPage - ); - }; - const [hasAside, setHasAside] = useState(getHasAside()); - - useEffect(() => { - setHasAside(getHasAside()); - }, [page, siteData]); - - useEffect(() => { - const query = new URLSearchParams(location.search); - const footer = query.get('footer'); - if (footer === QueryStatus.Hide) { - setHasFooter(false); - } - }, []); const docContent = ( @@ -85,16 +54,22 @@ export function DocLayout(props: DocLayoutProps) { ); + console.log('uiSwitch', uiSwitch); + return (
{beforeDoc} - {hasSidebar ? ( - + {uiSwitch.showSidebar ? ( + ) : null}
{docContent}
{beforeDocFooter} - {hasFooter && } + {uiSwitch.showDocFooter && }
)} @@ -117,16 +92,16 @@ export function DocLayout(props: DocLayoutProps) { )} - {hasAside ? ( + {uiSwitch.showAside ? (
diff --git a/packages/theme-default/src/layout/Layout/index.tsx b/packages/theme-default/src/layout/Layout/index.tsx index aade97fd9..ec14a0bd9 100644 --- a/packages/theme-default/src/layout/Layout/index.tsx +++ b/packages/theme-default/src/layout/Layout/index.tsx @@ -1,18 +1,15 @@ import 'nprogress/nprogress.css'; import '../../styles'; -import React, { useEffect } from 'react'; +import React from 'react'; import { Helmet } from 'react-helmet-async'; import Theme, { Nav } from '@theme'; -import { usePageData, Content, removeBase, withBase } from '@rspress/runtime'; +import { usePageData, Content } from '@rspress/runtime'; import { DocLayout, DocLayoutProps } from '../DocLayout'; import { HomeLayoutProps } from '../HomeLayout'; import type { NavProps } from '../../components/Nav'; -import { useDisableNav, useLocaleSiteData } from '#theme/logic'; - -export enum QueryStatus { - Show = '1', - Hide = '0', -} +import { useLocaleSiteData } from '#theme/logic'; +import { useRedirect4FirstVisit } from '#theme/logic/useRedirect4FirstVisit'; +import { useUISwitch } from '#theme/logic/useUISwitch'; export type LayoutProps = { top?: React.ReactNode; @@ -65,14 +62,11 @@ export const Layout: React.FC = props => { frontmatter, } = page; const localesData = useLocaleSiteData(); - const defaultLang = siteData.lang || ''; - const [hideNavbar, setHideNavbar] = useDisableNav(); + useRedirect4FirstVisit(); // Always show sidebar by default // Priority: front matter title > h1 title let title = (frontmatter?.title as string) ?? articleTitle; const mainTitle = siteData.title || localesData.title; - const localeLanguages = Object.values(siteData.themeConfig.locales || {}); - const langs = localeLanguages.map(item => item.lang) || []; if (title && pageType === 'doc') { // append main title as a suffix @@ -84,13 +78,16 @@ export const Layout: React.FC = props => { (frontmatter?.description as string) || siteData.description || localesData.description; + // Control whether to show navbar/sidebar/outline/footer + const uiSwitch = useUISwitch(); + console.log('uiSwitch', uiSwitch); // Use doc layout by default const getContentLayout = () => { switch (pageType) { case 'home': return ; case 'doc': - return ; + return ; case '404': return ; // The custom pageType will have navbar while the blank pageType will not. @@ -102,62 +99,6 @@ export const Layout: React.FC = props => { } }; - useEffect(() => { - if (!defaultLang || process.env.TEST === '1') { - // Check the window.navigator.language to determine the default language - // If the default language is not the same as the current language, redirect to the default language - // The default language will not have a lang prefix in the URL - return; - } - // Normalize current url, to ensure that the home url is always with a trailing slash - const { pathname } = window.location; - const cleanPathname = removeBase(pathname); - // Check if the user is visiting the site for the first time - const FIRST_VISIT_KEY = 'rspress-visited'; - const visited = localStorage.getItem(FIRST_VISIT_KEY); - if (visited) { - return; - } else { - localStorage.setItem(FIRST_VISIT_KEY, '1'); - } - const targetLang = window.navigator.language.split('-')[0]; - if (!langs.includes(targetLang)) { - return; - } - if (targetLang !== currentLang) { - if (targetLang === defaultLang) { - // Redirect to the default language - window.location.replace(pathname.replace(`/${currentLang}`, '')); - } else if (currentLang === defaultLang) { - // Redirect to the current language - window.location.replace(withBase(`/${targetLang}${cleanPathname}`)); - } else { - // Redirect to the current language - window.location.replace( - pathname.replace(`/${currentLang}`, `/${targetLang}`), - ); - } - } - }, []); - - // Control the display of the navbar, sidebar and aside - useEffect(() => { - const query = new URLSearchParams(location.search); - const navbar = query.get('navbar'); - const sidebar = query.get('sidebar'); - const aside = query.get('outline'); - if (navbar === QueryStatus.Hide) { - setHideNavbar(true); - } - - if (sidebar === QueryStatus.Hide) { - document.documentElement.style.setProperty('--rp-sidebar-width', '0'); - } - - if (aside === QueryStatus.Hide) { - document.documentElement.style.setProperty('--rp-aside-width', '0'); - } - }, []); return (
= props => { {top} - {pageType !== 'blank' && !hideNavbar && ( + {pageType !== 'blank' && uiSwitch.showNavbar && (