From 213b34427c89a289f858d37bf00817b4087ef443 Mon Sep 17 00:00:00 2001 From: Carrotzpc Date: Thu, 15 Aug 2024 11:25:35 +0800 Subject: [PATCH] feat: support specify desktop or mobile when build SSR --- README.md | 1 + example/package.json | 1 + src/components/ApiHeader/index.tsx | 8 ++-- src/components/ApiHeader/style.ts | 40 +++++++++-------- src/hooks/useResponsive.ts | 18 ++++++++ src/index.ts | 1 + src/layouts/DocLayout/DocumentLayout.tsx | 3 +- src/pages/Changelog/index.tsx | 10 ++--- src/pages/Docs/index.tsx | 2 +- src/slots/Content/index.tsx | 7 ++- src/slots/Content/style.ts | 46 +++++++++---------- src/slots/ContentFooter/index.tsx | 2 +- src/slots/Footer/index.tsx | 4 +- src/slots/Footer/style.ts | 6 +-- src/slots/Header/index.tsx | 2 +- src/slots/Logo/index.tsx | 4 +- src/slots/Logo/style.ts | 6 +-- src/slots/Navbar/index.tsx | 56 +++++++++++++----------- src/slots/SearchBar/index.tsx | 4 +- src/slots/SearchBar/style.ts | 11 +++-- src/slots/Toc/index.tsx | 3 +- 21 files changed, 135 insertions(+), 100 deletions(-) create mode 100644 src/hooks/useResponsive.ts diff --git a/README.md b/README.md index 857672f..b70bcb5 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ dumi-theme-yunti is a documentation site theme package designed for `Dumi 2`. - [ ] diff --git a/example/package.json b/example/package.json index a03202e..1edb865 100644 --- a/example/package.json +++ b/example/package.json @@ -7,6 +7,7 @@ "build:no-compress": "COMPRESS=none dumi build", "dev": "dumi dev", "postinstall": "npm run setup", + "mbp": "MOBILE=true npm run bp", "preview": "dumi preview", "setup": "dumi setup" }, diff --git a/src/components/ApiHeader/index.tsx b/src/components/ApiHeader/index.tsx index 6bc446e..5fbded4 100644 --- a/src/components/ApiHeader/index.tsx +++ b/src/components/ApiHeader/index.tsx @@ -1,10 +1,10 @@ import { Icon, Markdown, Snippet } from '@lobehub/ui'; import { Divider, Space, Typography } from 'antd'; -import { useResponsive } from 'antd-style'; import { Edit3, Github } from 'lucide-react'; import { type ReactNode, memo } from 'react'; import { Flexbox } from 'react-layout-kit'; +import { useResponsive } from '@/hooks/useResponsive'; import { ApiHeaderConfig } from '@/types'; import { useStyles } from './style'; @@ -84,8 +84,8 @@ export const ApiHeader = memo( docUrl, serviceList = [], }) => { - const { styles } = useStyles(); const { mobile } = useResponsive(); + const { styles } = useStyles({ mobile }); const isDoc = type === 'doc'; const items = [ @@ -119,7 +119,7 @@ export const ApiHeader = memo( } wrap> - {serviceList.map((item) => ( + {serviceList.map(item => ( ( )} ); - }, + } ); diff --git a/src/components/ApiHeader/style.ts b/src/components/ApiHeader/style.ts index ac8c4e9..b5b7532 100644 --- a/src/components/ApiHeader/style.ts +++ b/src/components/ApiHeader/style.ts @@ -1,21 +1,23 @@ import { createStyles } from 'antd-style'; -export const useStyles = createStyles(({ css, token, responsive: r, stylish }) => ({ - desc: css` - font-size: ${token.fontSizeLG}px; - line-height: ${token.lineHeightLG}px; - `, - label: css` - width: 80px; - `, - meta: css``, - text: css` - ${stylish.resetLinkColor} - `, - title: css` - ${r.mobile} { - margin-block: 0; - font-size: 32px !important; - } - `, -})); +export const useStyles = createStyles( + ({ css, token, stylish }, { mobile }: { mobile?: boolean }) => ({ + desc: css` + font-size: ${token.fontSizeLG}px; + line-height: ${token.lineHeightLG}px; + `, + label: css` + width: 80px; + `, + meta: css``, + text: css` + ${stylish.resetLinkColor} + `, + title: css` + ${mobile} { + margin-block: 0; + font-size: 32px !important; + } + `, + }) +); diff --git a/src/hooks/useResponsive.ts b/src/hooks/useResponsive.ts new file mode 100644 index 0000000..7208bf8 --- /dev/null +++ b/src/hooks/useResponsive.ts @@ -0,0 +1,18 @@ +import { useResponsive as baseUseResponsive } from 'antd-style'; + +import { isBrowser } from '@/utils'; + +export const useResponsive = () => { + const responsive = baseUseResponsive(); + + if (!isBrowser) { + if (process.env.MOBILE) { + responsive.mobile = process.env.MOBILE === 'true'; + } + if (process.env.DESKTOP) { + responsive.desktop = process.env.DESKTOP === 'true'; + } + } + + return responsive; +}; diff --git a/src/index.ts b/src/index.ts index e68e935..28047f8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ export { defineThemeConfig } from './config'; +export * from './hooks/useResponsive'; export { siteSelectors, type SiteStore, useSiteStore } from './store'; export * from './types'; diff --git a/src/layouts/DocLayout/DocumentLayout.tsx b/src/layouts/DocLayout/DocumentLayout.tsx index 34db3ed..733188c 100644 --- a/src/layouts/DocLayout/DocumentLayout.tsx +++ b/src/layouts/DocLayout/DocumentLayout.tsx @@ -1,10 +1,11 @@ import { Layout } from '@lobehub/ui'; -import { useResponsive, useTheme } from 'antd-style'; +import { useTheme } from 'antd-style'; import { Helmet, useIntl, useLocation, useOutlet } from 'dumi'; import isEqual from 'fast-deep-equal'; import { memo, useCallback, useEffect } from 'react'; import { shallow } from 'zustand/shallow'; +import { useResponsive } from '@/hooks/useResponsive'; import Changelog from '@/pages/Changelog'; import Docs from '@/pages/Docs'; import Home from '@/pages/Home'; diff --git a/src/pages/Changelog/index.tsx b/src/pages/Changelog/index.tsx index 2b6cbdf..764c361 100644 --- a/src/pages/Changelog/index.tsx +++ b/src/pages/Changelog/index.tsx @@ -1,4 +1,3 @@ -import { useResponsive } from 'antd-style'; import { useOutlet } from 'dumi'; import isEqual from 'fast-deep-equal'; import { memo, useEffect } from 'react'; @@ -6,6 +5,7 @@ import { Center } from 'react-layout-kit'; import { shallow } from 'zustand/shallow'; import { ApiHeader } from '@/components/ApiHeader'; +import { useResponsive } from '@/hooks/useResponsive'; import { useStyles } from '@/pages/Docs/styles'; import Content from '@/slots/Content'; import { githubSel, useSiteStore } from '@/store'; @@ -14,17 +14,17 @@ const Changelog = memo(() => { const outlet = useOutlet(); const { mobile } = useResponsive(); const { repoBase } = useSiteStore( - (s) => ({ + s => ({ repoBase: githubSel(s), }), - shallow, + shallow ); const { fm } = useSiteStore( - (s) => ({ + s => ({ fm: s.routeMeta.frontmatter, }), - isEqual, + isEqual ); const { styles } = useStyles(); diff --git a/src/pages/Docs/index.tsx b/src/pages/Docs/index.tsx index 72ae402..cf5f7b3 100644 --- a/src/pages/Docs/index.tsx +++ b/src/pages/Docs/index.tsx @@ -1,11 +1,11 @@ import { StyleProvider } from '@ant-design/cssinjs'; import { Giscus } from '@lobehub/ui'; -import { useResponsive } from 'antd-style'; import { useLocation, useOutlet } from 'dumi'; import { memo, useCallback, useEffect } from 'react'; import { Center } from 'react-layout-kit'; import { shallow } from 'zustand/shallow'; +import { useResponsive } from '@/hooks/useResponsive'; import ApiHeader from '@/slots/ApiHeader'; import Content from '@/slots/Content'; import { giscusSel, isApiPageSel, useSiteStore } from '@/store'; diff --git a/src/slots/Content/index.tsx b/src/slots/Content/index.tsx index 769f7b8..a7f20a9 100644 --- a/src/slots/Content/index.tsx +++ b/src/slots/Content/index.tsx @@ -1,9 +1,9 @@ import { Typography } from '@lobehub/ui'; -import { useResponsive } from 'antd-style'; import isEqual from 'fast-deep-equal'; import { memo, useEffect } from 'react'; import { Flexbox } from 'react-layout-kit'; +import { useResponsive } from '@/hooks/useResponsive'; import ContentFooter from '@/slots/ContentFooter'; import { themeConfig, useSiteStore } from '@/store'; import { DivProps } from '@/types'; @@ -13,8 +13,11 @@ import { useStyles } from './style'; const Content = memo(({ children, ...props }) => { const loading = useSiteStore(s => s.siteData.loading); const { docStyle } = useSiteStore(themeConfig, isEqual); - const { styles, cx } = useStyles(docStyle === 'pure'); const { mobile } = useResponsive(); + const { styles, cx } = useStyles({ + isPure: docStyle === 'pure', + mobile, + }); useEffect(() => { document.body.scrollTo(0, 0); diff --git a/src/slots/Content/style.ts b/src/slots/Content/style.ts index d24b754..e16a676 100644 --- a/src/slots/Content/style.ts +++ b/src/slots/Content/style.ts @@ -1,27 +1,29 @@ import { createStyles } from 'antd-style'; -export const useStyles = createStyles(({ cx, token, responsive, css }, isPure: boolean) => ({ - content: cx( - !isPure && +export const useStyles = createStyles( + ({ cx, token, css }, { isPure, mobile }: { isPure: boolean; mobile?: boolean }) => ({ + content: cx( + !isPure && + css` + padding: 24px 48px; + background-color: ${token.colorBgContainer}; + border-radius: 10px; + + ${mobile} { + padding: 8px 16px; + border-radius: 0; + } + `, css` - padding: 24px 48px; - background-color: ${token.colorBgContainer}; - border-radius: 10px; + flex: 1; + box-sizing: border-box; + width: 100%; + min-height: 400px; - ${responsive.mobile} { - padding: 8px 16px; - border-radius: 0; + &:has([data-page-tabs='true']) { + padding-top: 8px; } - `, - css` - flex: 1; - box-sizing: border-box; - width: 100%; - min-height: 400px; - - &:has([data-page-tabs='true']) { - padding-top: 8px; - } - `, - ), -})); + ` + ), + }) +); diff --git a/src/slots/ContentFooter/index.tsx b/src/slots/ContentFooter/index.tsx index c3e9f93..9ad8115 100644 --- a/src/slots/ContentFooter/index.tsx +++ b/src/slots/ContentFooter/index.tsx @@ -1,8 +1,8 @@ -import { useResponsive } from 'antd-style'; import isEqual from 'fast-deep-equal'; import { memo } from 'react'; import { Flexbox } from 'react-layout-kit'; +import { useResponsive } from '@/hooks/useResponsive'; import { contentBottomSel, useSiteStore } from '@/store'; import Linker from './Linker'; diff --git a/src/slots/Footer/index.tsx b/src/slots/Footer/index.tsx index 9ed0f4e..73754cc 100644 --- a/src/slots/Footer/index.tsx +++ b/src/slots/Footer/index.tsx @@ -1,11 +1,11 @@ import { Footer as Foot, FooterProps } from '@lobehub/ui'; import { Divider } from 'antd'; -import { useResponsive } from 'antd-style'; import isEqual from 'fast-deep-equal'; import { memo } from 'react'; import { Center, Flexbox } from 'react-layout-kit'; import { shallow } from 'zustand/shallow'; +import { useResponsive } from '@/hooks/useResponsive'; import { githubSel, useSiteStore } from '@/store'; import { getColumns } from './columns'; @@ -15,8 +15,8 @@ const Footer = memo(() => { const { themeConfig, pkg } = useSiteStore(s => s.siteData, isEqual); const { footerConfig, footer } = themeConfig; const githubUrl = useSiteStore(githubSel, shallow); - const { styles, theme } = useStyles(); const { mobile } = useResponsive(); + const { styles, theme } = useStyles({ mobile }); if (!footer) return; diff --git a/src/slots/Footer/style.ts b/src/slots/Footer/style.ts index f9d679e..c8e4f40 100644 --- a/src/slots/Footer/style.ts +++ b/src/slots/Footer/style.ts @@ -1,6 +1,6 @@ import { createStyles } from 'antd-style'; -export const useStyles = createStyles(({ css, responsive, token }) => { +export const useStyles = createStyles(({ css, token }, { mobile }: { mobile?: boolean }) => { const prefix = `rc-footer`; return { @@ -13,7 +13,7 @@ export const useStyles = createStyles(({ css, responsive, token }) => { border-top: 1px solid ${token.colorSplit}; - ${responsive.mobile} { + ${mobile} { flex-direction: column; border: none; } @@ -144,7 +144,7 @@ export const useStyles = createStyles(({ css, responsive, token }) => { } } - ${responsive.mobile} { + ${mobile} { .${prefix} { text-align: center; diff --git a/src/slots/Header/index.tsx b/src/slots/Header/index.tsx index 2434815..e3ba851 100644 --- a/src/slots/Header/index.tsx +++ b/src/slots/Header/index.tsx @@ -1,8 +1,8 @@ import { Header as Head } from '@lobehub/ui'; import { Flex } from 'antd'; -import { useResponsive } from 'antd-style'; import { memo } from 'react'; +import { useResponsive } from '@/hooks/useResponsive'; import Logo from '@/slots/Logo'; import Navbar from '@/slots/Navbar'; import SearchBar from '@/slots/SearchBar'; diff --git a/src/slots/Logo/index.tsx b/src/slots/Logo/index.tsx index 7f2b027..8de273d 100644 --- a/src/slots/Logo/index.tsx +++ b/src/slots/Logo/index.tsx @@ -1,10 +1,10 @@ import { Avatar } from '@lobehub/ui'; import { Space } from 'antd'; -import { useResponsive } from 'antd-style'; import { Link } from 'dumi'; import isEqual from 'fast-deep-equal'; import { memo } from 'react'; +import { useResponsive } from '@/hooks/useResponsive'; import { themeConfig } from '@/store/selectors/siteBasicInfo'; import { useSiteStore } from '@/store/useSiteStore'; @@ -13,8 +13,8 @@ import { useStyles } from './style'; const Logo = memo(() => { const config = useSiteStore(themeConfig, isEqual); const locale = useSiteStore(s => s.locale, isEqual); - const { styles, cx } = useStyles(); const { mobile } = useResponsive(); + const { styles, cx } = useStyles({ mobile }); return ( config && ( diff --git a/src/slots/Logo/style.ts b/src/slots/Logo/style.ts index 36a8f47..6e3ea94 100644 --- a/src/slots/Logo/style.ts +++ b/src/slots/Logo/style.ts @@ -1,7 +1,7 @@ import { createStyles } from 'antd-style'; export const useStyles = createStyles( - ({ css, responsive, token }) => css` + ({ css, token }, { mobile }: { mobile?: boolean }) => css` display: inline-flex; align-items: center; @@ -11,8 +11,8 @@ export const useStyles = createStyles( color: ${token.colorText}; text-decoration: none; - ${responsive.mobile} { + ${mobile} { font-size: 18px; } - `, + ` ); diff --git a/src/slots/Navbar/index.tsx b/src/slots/Navbar/index.tsx index 63e3c8b..77fae74 100644 --- a/src/slots/Navbar/index.tsx +++ b/src/slots/Navbar/index.tsx @@ -6,41 +6,45 @@ import { ExternalLink } from 'lucide-react'; import { memo } from 'react'; import { shallow } from 'zustand/shallow'; +import { useResponsive } from '@/hooks/useResponsive'; import { useSiteStore } from '@/store'; import { isExternalLinks } from '@/utils'; -const useStyles = createStyles(({ css, stylish, token, responsive, prefixCls }) => { - return { - link: css` - ${stylish.resetLinkColor} - display: inline-flex; - align-items: center; - - & > .lint-text { +const useStyles = createStyles( + ({ css, stylish, token, prefixCls }, { mobile }: { mobile?: boolean }) => { + return { + link: css` ${stylish.resetLinkColor} - } + display: inline-flex; + align-items: center; - & > .anticon { - margin-left: ${token.marginXS}px; - font-size: ${token.fontSizeSM}px; - color: ${token.colorTextTertiary}; - } - `, - tabs: css` - .${prefixCls}-tabs-tab-active a { - color: ${token.colorText} !important; - } - ${responsive.mobile} { - display: none; - } - `, - }; -}); + & > .lint-text { + ${stylish.resetLinkColor} + } + + & > .anticon { + margin-left: ${token.marginXS}px; + font-size: ${token.fontSizeSM}px; + color: ${token.colorTextTertiary}; + } + `, + tabs: css` + .${prefixCls}-tabs-tab-active a { + color: ${token.colorText} !important; + } + ${mobile} { + display: none; + } + `, + }; + } +); const linkToKey = (path?: string) => (path ?? '').split('/').slice(0, 2).join('/'); const Navbar = memo(() => { - const { styles } = useStyles(); + const { mobile } = useResponsive(); + const { styles } = useStyles({ mobile }); const { pathname } = useLocation(); const nav = useSiteStore(s => s.navData, shallow); diff --git a/src/slots/SearchBar/index.tsx b/src/slots/SearchBar/index.tsx index 4c32472..e97b86c 100644 --- a/src/slots/SearchBar/index.tsx +++ b/src/slots/SearchBar/index.tsx @@ -1,4 +1,5 @@ import { SearchBar as Input } from '@lobehub/ui'; +import { useResponsive } from 'antd-style'; import { useIntl, useSiteSearch } from 'dumi'; import SearchResult from 'dumi/theme-default/slots/SearchResult'; import { memo, useState } from 'react'; @@ -6,7 +7,8 @@ import { memo, useState } from 'react'; import { useStyles } from './style'; const SearchBar = memo(() => { - const { styles } = useStyles(); + const { mobile } = useResponsive(); + const { styles } = useStyles({ mobile }); const [focusing, setFocusing] = useState(false); const { keywords, setKeywords, result, loading } = useSiteSearch(); const intl = useIntl(); diff --git a/src/slots/SearchBar/style.ts b/src/slots/SearchBar/style.ts index 18dca41..8a64d77 100644 --- a/src/slots/SearchBar/style.ts +++ b/src/slots/SearchBar/style.ts @@ -1,12 +1,12 @@ import { createStyles } from 'antd-style'; -export const useStyles = createStyles(({ token, responsive, css, cx }) => { +export const useStyles = createStyles(({ token, css, cx }, { mobile }: { mobile?: boolean }) => { return { container: css` position: relative; // TODO: support search for mobile devices - ${responsive.mobile} { + ${mobile} { display: none; } `, @@ -15,8 +15,7 @@ export const useStyles = createStyles(({ token, responsive, css, cx }) => { width: 280px; height: ${token.controlHeightLG}px; padding: 0; - padding-inline-start: 40px; - padding-inline-end: 12px; + padding-inline: 40px 12px; font-size: 14px; color: ${token.colorTextSecondary}; @@ -122,10 +121,10 @@ export const useStyles = createStyles(({ token, responsive, css, cx }) => { transition: all 0.3s; - ${responsive.mobile} { + ${mobile} { display: none; } - `, + ` ), svg: cx(css` position: absolute; diff --git a/src/slots/Toc/index.tsx b/src/slots/Toc/index.tsx index a14f48f..5b6021f 100644 --- a/src/slots/Toc/index.tsx +++ b/src/slots/Toc/index.tsx @@ -1,9 +1,10 @@ import { Toc as T } from '@lobehub/ui'; -import { useResponsive, useTheme } from 'antd-style'; +import { useTheme } from 'antd-style'; import { useLocation } from 'dumi'; import isEqual from 'fast-deep-equal'; import { memo, useEffect, useState } from 'react'; +import { useResponsive } from '@/hooks/useResponsive'; import { tocAnchorItemSel, useSiteStore } from '@/store'; const GAP = 48;