diff --git a/.dumi/pages/index/components/Banner.tsx b/.dumi/pages/index/components/Banner.tsx index ddd842e315..040b0d9566 100644 --- a/.dumi/pages/index/components/Banner.tsx +++ b/.dumi/pages/index/components/Banner.tsx @@ -3,10 +3,10 @@ import { Button, Space, Typography } from 'antd'; import { Link, useLocation } from 'dumi'; import { css } from '@emotion/react'; import useLocale from '../../../hooks/useLocale'; +import SiteContext from '../../../theme/slots/SiteContext'; import useSiteToken from '../../../hooks/useSiteToken'; import { GroupMask } from './Group'; import * as utils from '../../../theme/utils'; -import SiteContext from './SiteContext'; const locales = { cn: { diff --git a/.dumi/pages/index/components/BannerRecommends.tsx b/.dumi/pages/index/components/BannerRecommends.tsx index 32a34b74a9..bac9d312de 100644 --- a/.dumi/pages/index/components/BannerRecommends.tsx +++ b/.dumi/pages/index/components/BannerRecommends.tsx @@ -4,7 +4,7 @@ import type { SerializedStyles } from '@emotion/react'; import { css } from '@emotion/react'; import type { Extra, Icon } from './util'; import useSiteToken from '../../../hooks/useSiteToken'; -import SiteContext from './SiteContext'; +import SiteContext from '../../../theme/slots/SiteContext'; import { useCarouselStyle } from './util'; const useStyle = () => { @@ -65,14 +65,20 @@ const RecommendItem = ({ extra, index, icons, itemCss }: RecommendItemProps) => const icon = icons.find((i) => i.name === extra.source); return ( - + {extra?.title} {extra.description}
{extra.date} - {icon && banner} + {icon && banner}
); @@ -119,4 +125,3 @@ export default function BannerRecommends({ extras = [], icons = [] }: BannerReco ); } - diff --git a/.dumi/pages/index/components/ComponentsList.tsx b/.dumi/pages/index/components/ComponentsList.tsx index 322b565092..a58df73b62 100644 --- a/.dumi/pages/index/components/ComponentsList.tsx +++ b/.dumi/pages/index/components/ComponentsList.tsx @@ -17,7 +17,7 @@ import { CustomerServiceOutlined, QuestionCircleOutlined, SyncOutlined } from '@ import { css } from '@emotion/react'; import useSiteToken from '../../../hooks/useSiteToken'; import useLocale from '../../../hooks/useLocale'; -import SiteContext from './SiteContext'; +import SiteContext from '../../../theme/slots/SiteContext'; import { useCarouselStyle } from './util'; const SAMPLE_CONTENT_EN = diff --git a/.dumi/pages/index/components/DesignFramework.tsx b/.dumi/pages/index/components/DesignFramework.tsx index d4bbad6318..9e044bd531 100644 --- a/.dumi/pages/index/components/DesignFramework.tsx +++ b/.dumi/pages/index/components/DesignFramework.tsx @@ -5,7 +5,7 @@ import { Link, useLocation } from 'dumi'; import useLocale from '../../../hooks/useLocale'; import useSiteToken from '../../../hooks/useSiteToken'; import * as utils from '../../../theme/utils'; -import SiteContext from './SiteContext'; +import SiteContext from '../../../theme/slots/SiteContext'; const SECONDARY_LIST = [ { diff --git a/.dumi/pages/index/components/Group.tsx b/.dumi/pages/index/components/Group.tsx index 2b4587c923..8fa8ce059c 100644 --- a/.dumi/pages/index/components/Group.tsx +++ b/.dumi/pages/index/components/Group.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { useContext } from 'react'; import { Typography } from 'antd'; import useSiteToken from '../../../hooks/useSiteToken'; -import SiteContext from './SiteContext'; +import SiteContext from '../../../theme/slots/SiteContext'; export interface GroupMaskProps { style?: React.CSSProperties; diff --git a/.dumi/pages/index/components/SiteContext.tsx b/.dumi/pages/index/components/SiteContext.tsx deleted file mode 100644 index 9767a89b50..0000000000 --- a/.dumi/pages/index/components/SiteContext.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from 'react'; - -export interface SiteContextProps { - isMobile: boolean; -} - -const SiteContext = React.createContext({ - isMobile: false, -}); - -export default SiteContext; diff --git a/.dumi/pages/index/components/Theme/index.tsx b/.dumi/pages/index/components/Theme/index.tsx index 0f809d7dde..745842b9f5 100644 --- a/.dumi/pages/index/components/Theme/index.tsx +++ b/.dumi/pages/index/components/Theme/index.tsx @@ -30,7 +30,7 @@ import RadiusPicker from './RadiusPicker'; import Group from '../Group'; import BackgroundImage from './BackgroundImage'; import { DEFAULT_COLOR, getAvatarURL, getClosetColor, PINK_COLOR } from './colorUtil'; -import SiteContext from '../SiteContext'; +import SiteContext from '../../../../theme/slots/SiteContext'; import { useCarouselStyle } from '../util'; import MobileCarousel from './MobileCarousel'; diff --git a/.dumi/pages/index/index.tsx b/.dumi/pages/index/index.tsx index ee0992c09d..a64fa9ce83 100644 --- a/.dumi/pages/index/index.tsx +++ b/.dumi/pages/index/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo } from 'react'; +import React from 'react'; import { useLocale as useDumiLocale } from 'dumi'; import { ConfigProvider } from 'antd'; import useLocale from '../../hooks/useLocale'; @@ -9,7 +9,6 @@ import Theme from './components/Theme'; import BannerRecommends from './components/BannerRecommends'; import ComponentsList from './components/ComponentsList'; import DesignFramework from './components/DesignFramework'; -import SiteContext from './components/SiteContext'; const locales = { cn: { @@ -34,61 +33,44 @@ const Homepage: React.FC = () => { const localeStr = localeId === 'zh-CN' ? 'cn' : 'en'; const [siteData] = useSiteData(); - const [isMobile, setIsMobile] = React.useState(false); - - const updateMobileMode = () => { - setIsMobile(window.innerWidth < 768); - }; - - useEffect(() => { - updateMobileMode(); - window.addEventListener('resize', updateMobileMode); - return () => { - window.removeEventListener('resize', updateMobileMode); - }; - }, []); - - const siteValue = useMemo(() => ({ isMobile }), [isMobile]); return ( - -
- - - +
+ + + -
- - - - - - {/* Image Left Top */} - - - } - > - - -
-
- +
+ + + + + + {/* Image Left Top */} + + + } + > + + +
+
); }; diff --git a/.dumi/theme/builtins/ComponentOverview/index.tsx b/.dumi/theme/builtins/ComponentOverview/index.tsx index 9cdaf58dcb..5d35933089 100644 --- a/.dumi/theme/builtins/ComponentOverview/index.tsx +++ b/.dumi/theme/builtins/ComponentOverview/index.tsx @@ -1,5 +1,5 @@ import React, { memo, useMemo, useState } from 'react'; -import { Link, useIntl, useSidebarData } from 'dumi'; +import { Link, useIntl, useSidebarData, useLocation } from 'dumi'; import { css } from '@emotion/react'; import debounce from 'lodash/debounce'; import { Card, Col, Divider, Input, Row, Space, Tag, Typography } from 'antd'; @@ -16,7 +16,6 @@ const useStyle = () => { padding: 0; `, componentsOverviewGroupTitle: css` - font-size: 24px; margin-bottom: 24px !important; `, componentsOverviewTitle: css` @@ -38,22 +37,7 @@ const useStyle = () => { } `, componentsOverviewSearch: css` - &${token.antCls}-input-affix-wrapper { - width: 100%; - padding: 0; - font-size: 20px; - border: 0; - box-shadow: none; - - input { - color: rgba(0, 0, 0, 0.85); - font-size: 20px; - } - - .anticon { - color: #bbb; - } - } + font-size: ${token.fontSizeXL}px; `, }; }; @@ -81,7 +65,7 @@ const { Title } = Typography; const Overview: React.FC = () => { const style = useStyle(); const data = useSidebarData(); - + const { search: urlSearch } = useLocation(); const { locale, formatMessage } = useIntl(); const [search, setSearch] = useState(''); @@ -131,7 +115,8 @@ const Overview: React.FC = () => { reportSearch(e.target.value); }} onKeyDown={onKeyDown} - autoFocus // eslint-disable-line jsx-a11y/no-autofocus + bordered={false} + autoFocus suffix={} /> @@ -154,10 +139,16 @@ const Overview: React.FC = () => { {components.map((component) => { - const url = `${component.link}/`; + /** 是否是外链 */ + const isExternalLink = component.link.startsWith('http'); + let url = `${component.link}`; + + if (!isExternalLink) { + url += urlSearch; + } /** Link 不能跳转到外链 */ - const ComponentLink = !url.startsWith('http') ? Link : 'a'; + const ComponentLink = isExternalLink ? 'a' : Link; return ( diff --git a/.dumi/theme/builtins/Previewer/fromDumiProps.tsx b/.dumi/theme/builtins/Previewer/fromDumiProps.tsx index 588c1451a0..e0eb1151b6 100644 --- a/.dumi/theme/builtins/Previewer/fromDumiProps.tsx +++ b/.dumi/theme/builtins/Previewer/fromDumiProps.tsx @@ -3,7 +3,7 @@ import JsonML from 'jsonml.js/lib/utils'; import toReactComponent from 'jsonml-to-react-element'; import Prism from 'prismjs'; import 'prismjs/components/prism-typescript'; -import { useLocation, useSearchParams, useIntl, type IPreviewerProps } from 'dumi'; +import { useLocation, useIntl, type IPreviewerProps } from 'dumi'; import { ping } from '../../utils'; let pingDeferrer: PromiseLike; @@ -36,7 +36,6 @@ export default function fromDumiProps

( const hoc = function DumiPropsAntdPreviewer(props: IPreviewerProps) { const showRiddleButton = useShowRiddleButton(); const location = useLocation(); - const [searchParams] = useSearchParams(); const { asset, children, demoUrl, expand, description = '', ...meta } = props; const intl = useIntl(); const entryCode = asset.dependencies['index.tsx'].value; @@ -89,7 +88,6 @@ export default function fromDumiProps

( expand, // FIXME: confirm is there has any case? highlightedStyle: '', - theme: searchParams.get('theme'), } as P; return ; diff --git a/.dumi/theme/builtins/Previewer/index.tsx b/.dumi/theme/builtins/Previewer/index.tsx index 0a5aa6b80b..9cc5a642d6 100644 --- a/.dumi/theme/builtins/Previewer/index.tsx +++ b/.dumi/theme/builtins/Previewer/index.tsx @@ -17,6 +17,8 @@ import CodeSandboxIcon from '../../common/CodeSandboxIcon'; import RiddleIcon from '../../common/RiddleIcon'; import ExternalLinkIcon from '../../common/ExternalLinkIcon'; import fromDumiProps from './fromDumiProps'; +import type { SiteContextProps } from '../../slots/SiteContext'; +import SiteContext from '../../slots/SiteContext'; import { version } from '../../../../package.json'; const { ErrorBoundary } = Alert; @@ -38,7 +40,6 @@ interface DemoProps { highlightedStyle: string; expand: boolean; intl: any; - theme: string; sourceCodes: Record<'jsx' | 'tsx', string>; location: Location; showRiddleButton: boolean; @@ -53,6 +54,8 @@ interface DemoState { } class Demo extends React.Component { + static contextType = SiteContext; + liveDemo: any; iframeRef = React.createRef(); @@ -81,13 +84,12 @@ class Demo extends React.Component { shouldComponentUpdate(nextProps: DemoProps, nextState: DemoState) { const { codeExpand, copied, copyTooltipOpen, codeType } = this.state; - const { expand, theme, showRiddleButton } = this.props; + const { expand, showRiddleButton } = this.props; return ( (codeExpand || expand) !== (nextState.codeExpand || nextProps.expand) || copied !== nextState.copied || copyTooltipOpen !== nextState.copyTooltipOpen || codeType !== nextState.copyTooltipOpen || - nextProps.theme !== theme || nextProps.showRiddleButton !== showRiddleButton ); } @@ -129,6 +131,7 @@ class Demo extends React.Component { render() { const { state } = this; const { props } = this; + const site: SiteContextProps = this.context; const { meta, src, @@ -139,7 +142,6 @@ class Demo extends React.Component { highlightedStyle, expand, intl: { locale }, - theme, showRiddleButton, } = props; const { copied, copyTooltipOpen, codeType } = state; @@ -465,7 +467,7 @@ createRoot(document.getElementById('container')).render(); expand code); expand code void; }; -const ThemeSwitch: React.FC = ({ value, onChange }) => { +const ThemeSwitch: React.FC = (props: ThemeSwitchProps) => { + const { value = ['light'], onChange } = props; const { token } = useSiteToken(); const { pathname, search } = useLocation(); return ( diff --git a/.dumi/theme/layouts/DocLayout/index.tsx b/.dumi/theme/layouts/DocLayout/index.tsx index f0a754dac9..a9f5efe9e0 100644 --- a/.dumi/theme/layouts/DocLayout/index.tsx +++ b/.dumi/theme/layouts/DocLayout/index.tsx @@ -1,16 +1,15 @@ -import React, { useEffect, useLayoutEffect, useMemo, useRef } from 'react'; +import React, { useContext, useEffect, useLayoutEffect, useMemo, useRef } from 'react'; import 'dayjs/locale/zh-cn'; import dayjs from 'dayjs'; -import { Helmet, useOutlet, useSearchParams } from 'dumi'; +import { Helmet, useOutlet } from 'dumi'; import '../../static/style'; -import type { DirectionType } from 'antd/es/config-provider'; import ConfigProvider from 'antd/es/config-provider'; import classNames from 'classnames'; import zhCN from 'antd/es/locale/zh_CN'; +import SiteContext from '../../slots/SiteContext'; import Header from '../../slots/Header'; import Footer from '../../slots/Footer'; import useLocale from '../../../hooks/useLocale'; -import SiteContext from '../../slots/SiteContext'; import useLocation from '../../../hooks/useLocation'; import ResourceLayout from '../ResourceLayout'; import GlobalStyles from '../../common/GlobalStyles'; @@ -28,26 +27,13 @@ const locales = { }, }; -const RESPONSIVE_MOBILE = 768; - const DocLayout: React.FC = () => { const outlet = useOutlet(); const location = useLocation(); const { pathname, search } = location; - const [searchParams, setSearchParams] = useSearchParams(); const [locale, lang] = useLocale(locales); - - // TODO: place doc layout here, apply for all docs route paths - // migrate from: https://github.com/ant-design/ant-design/blob/eb9179464b9c4a93c856e1e70ddbdbaaf3f3371f/site/theme/template/Layout/index.tsx - - const [isMobile, setIsMobile] = React.useState(false); - const [direction, setDirection] = React.useState('ltr'); - const timerRef = useRef(null); - - const updateMobileMode = () => { - setIsMobile(window.innerWidth < RESPONSIVE_MOBILE); - }; + const { direction } = useContext(SiteContext); useLayoutEffect(() => { if (lang === 'cn') { @@ -64,20 +50,6 @@ const DocLayout: React.FC = () => { nprogressHiddenStyle.parentNode?.removeChild(nprogressHiddenStyle); }, 0); } - - // Handle direction - const queryDirection = searchParams.get('direction'); - setDirection(queryDirection === 'rtl' ? 'rtl' : 'ltr'); - - // Handle mobile mode - updateMobileMode(); - window.addEventListener('resize', updateMobileMode); - return () => { - window.removeEventListener('resize', updateMobileMode); - if (timerRef.current) { - clearTimeout(timerRef.current); - } - }; }, []); React.useEffect(() => { @@ -89,16 +61,6 @@ const DocLayout: React.FC = () => { } }, [location]); - const changeDirection = (dir: DirectionType): void => { - setDirection(dir); - if (dir === 'ltr') { - searchParams.delete('direction'); - } else { - searchParams.set('direction', 'rtl'); - } - setSearchParams(searchParams); - }; - const content = useMemo(() => { if ( ['', '/'].some((path) => path === pathname) || @@ -120,16 +82,8 @@ const DocLayout: React.FC = () => { return {outlet}; }, [pathname, outlet]); - const siteContextValue = useMemo( - () => ({ - isMobile, - direction, - }), - [isMobile, direction], - ); - return ( - + <> { content="https://gw.alipayobjects.com/zos/rmsportal/rlpTLlbMzTNYuZGGCVYM.png" /> - + -

+
{content} - + ); }; diff --git a/.dumi/theme/layouts/GlobalLayout.tsx b/.dumi/theme/layouts/GlobalLayout.tsx index ca71a4b772..035287fee8 100644 --- a/.dumi/theme/layouts/GlobalLayout.tsx +++ b/.dumi/theme/layouts/GlobalLayout.tsx @@ -1,18 +1,26 @@ -import React from 'react'; -import { useOutlet, useSearchParams } from 'dumi'; +import React, { useCallback, useEffect, useMemo } from 'react'; +import { createSearchParams, useOutlet, useSearchParams } from 'dumi'; import { ConfigProvider, theme as antdTheme } from 'antd'; import { createCache, StyleProvider } from '@ant-design/cssinjs'; +import type { DirectionType } from 'antd/es/config-provider'; import ThemeSwitch from '../common/ThemeSwitch'; import type { ThemeName } from '../common/ThemeSwitch'; import useLocation from '../../hooks/useLocation'; +import type { SiteContextProps } from '../slots/SiteContext'; +import SiteContext from '../slots/SiteContext'; + +type Entries = { [K in keyof T]: [K, T[K]] }[keyof T][]; +type SiteState = Partial>; + +const RESPONSIVE_MOBILE = 768; const styleCache = createCache(); if (typeof global !== 'undefined') { (global as any).styleCache = styleCache; } -const getAlgorithm = (themes: ThemeName[]) => - (themes || []).map((theme) => { +const getAlgorithm = (themes: ThemeName[] = []) => + themes.map((theme) => { if (theme === 'dark') { return antdTheme.darkAlgorithm; } @@ -26,26 +34,87 @@ const GlobalLayout: React.FC = () => { const outlet = useOutlet(); const { pathname } = useLocation(); const [searchParams, setSearchParams] = useSearchParams(); - const theme = searchParams.getAll('theme') as unknown as ThemeName[]; - const handleThemeChange = (value: ThemeName[]) => { - setSearchParams({ - ...searchParams, - theme: value, - }); + const [{ theme, direction, isMobile }, setSiteState] = React.useState({ + isMobile: false, + direction: 'ltr', + theme: ['light'], + }); + + const updateSiteConfig = useCallback( + (props: SiteState) => { + setSiteState((prev) => ({ ...prev, ...props })); + + // updating `searchParams` will clear the hash + const oldSearchStr = searchParams.toString(); + + let nextSearchParams: URLSearchParams = searchParams; + (Object.entries(props) as Entries).forEach(([key, value]) => { + if (key === 'direction') { + if (value === 'rtl') { + nextSearchParams.set('direction', 'rtl'); + } else { + nextSearchParams.delete('direction'); + } + } + if (key === 'theme') { + nextSearchParams = createSearchParams({ + ...nextSearchParams, + theme: value.filter((t) => t !== 'light'), + }); + } + }); + + if (nextSearchParams.toString() !== oldSearchStr) { + setSearchParams(nextSearchParams); + } + }, + [searchParams, setSearchParams], + ); + + const updateMobileMode = () => { + updateSiteConfig({ isMobile: window.innerWidth < RESPONSIVE_MOBILE }); }; + useEffect(() => { + const _theme = searchParams.getAll('theme') as ThemeName[]; + const _direction = searchParams.get('direction') as DirectionType; + setSiteState({ theme: _theme, direction: _direction === 'rtl' ? 'rtl' : 'ltr' }); + + // Handle isMobile + updateMobileMode(); + window.addEventListener('resize', updateMobileMode); + return () => { + window.removeEventListener('resize', updateMobileMode); + }; + }, []); + + const siteContextValue = useMemo( + () => ({ + direction, + updateSiteConfig, + theme: theme!, + isMobile: isMobile!, + }), + [isMobile, direction, updateSiteConfig, theme], + ); + return ( - - {outlet} - {!pathname.startsWith('/~demos') && ( - - )} - + + + {outlet} + {!pathname.startsWith('/~demos') && ( + updateSiteConfig({ theme: nextTheme })} + /> + )} + + ); }; diff --git a/.dumi/theme/slots/Header/SwitchBtn.tsx b/.dumi/theme/slots/Header/SwitchBtn.tsx index b532b03ea4..799392a65a 100644 --- a/.dumi/theme/slots/Header/SwitchBtn.tsx +++ b/.dumi/theme/slots/Header/SwitchBtn.tsx @@ -83,7 +83,7 @@ export default function LangBtn({ top: 0, zIndex: 1, background: token.colorText, - color: token.colorTextLightSolid, + color: token.colorBgContainer, transformOrigin: '0 0', transform: `scale(0.7)`, }; diff --git a/.dumi/theme/slots/Header/index.tsx b/.dumi/theme/slots/Header/index.tsx index 9dc42060fb..95704a4ba8 100644 --- a/.dumi/theme/slots/Header/index.tsx +++ b/.dumi/theme/slots/Header/index.tsx @@ -4,7 +4,6 @@ import DumiSearchBar from 'dumi/theme-default/slots/SearchBar'; import classNames from 'classnames'; import { Col, Modal, Popover, Row, Select, Typography } from 'antd'; import { GithubOutlined, MenuOutlined } from '@ant-design/icons'; -import type { DirectionType } from 'antd/es/config-provider'; import { ClassNames, css } from '@emotion/react'; import * as utils from '../../utils'; import { getThemeConfig, ping } from '../../utils'; @@ -129,10 +128,6 @@ const useStyle = () => { }; }; -export interface HeaderProps { - changeDirection: (direction: DirectionType) => void; -} - const V5_NOTIFICATION = 'antd@4.0.0-notification-sent'; const SHOULD_OPEN_ANT_DESIGN_MIRROR_MODAL = 'ANT_DESIGN_DO_NOT_OPEN_MIRROR_MODAL'; @@ -151,8 +146,7 @@ interface HeaderState { } // ================================= Header ================================= -const Header: React.FC = (props) => { - const { changeDirection } = props; +const Header: React.FC = () => { const [isClient, setIsClient] = React.useState(false); const [locale, lang] = useLocale(locales); const { token } = useSiteToken(); @@ -188,7 +182,7 @@ const Header: React.FC = (props) => { windowWidth: 1400, searching: false, }); - const { direction, isMobile } = useContext(SiteContext); + const { direction, isMobile, updateSiteConfig } = useContext(SiteContext); const pingTimer = useRef(null); const location = useLocation(); const { pathname, search } = location; @@ -208,7 +202,7 @@ const Header: React.FC = (props) => { setHeaderState((prev) => ({ ...prev, menuVisible: visible })); }, []); const onDirectionChange = () => { - changeDirection?.(direction !== 'rtl' ? 'rtl' : 'ltr'); + updateSiteConfig({ direction: direction !== 'rtl' ? 'rtl' : 'ltr' }); }; useEffect(() => { diff --git a/.dumi/theme/slots/Sidebar/index.tsx b/.dumi/theme/slots/Sidebar/index.tsx index d8da6ecfaf..996a77b1cb 100644 --- a/.dumi/theme/slots/Sidebar/index.tsx +++ b/.dumi/theme/slots/Sidebar/index.tsx @@ -126,10 +126,11 @@ const useStyle = () => { const Sidebar: React.FC = () => { const sidebarData = useSidebarData(); - const { isMobile } = useContext(SiteContext); + const { isMobile, theme } = useContext(SiteContext); const styles = useStyle(); const [menuItems, selectedKey] = useMenu(); + const isDark = theme.includes('dark'); const menuChild = ( { inlineIndent={30} css={styles.asideContainer} mode="inline" + theme={isDark ? 'dark' : 'light'} selectedKeys={[selectedKey]} defaultOpenKeys={sidebarData?.map(({ title }) => title).filter((item) => item) as string[]} /> diff --git a/.dumi/theme/slots/SiteContext.tsx b/.dumi/theme/slots/SiteContext.tsx index c002df15cb..179aa6dc33 100644 --- a/.dumi/theme/slots/SiteContext.tsx +++ b/.dumi/theme/slots/SiteContext.tsx @@ -1,14 +1,19 @@ import * as React from 'react'; import type { DirectionType } from 'antd/es/config-provider'; +import type { ThemeName } from '../common/ThemeSwitch'; export interface SiteContextProps { isMobile: boolean; direction: DirectionType; + theme: ThemeName[]; + updateSiteConfig: (props: Partial) => void; } const SiteContext = React.createContext({ isMobile: false, direction: 'ltr', + theme: ['light'], + updateSiteConfig: () => {}, }); export default SiteContext;