UNPKG

dumi-theme-antd

Version:

Ant Design 5.0 官网风格类似的 dumi2 主题插件

187 lines (186 loc) 6.82 kB
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import { createCache, legacyNotSelectorLinter, logicalPropertiesLinter, parentSelectorLinter, StyleProvider, extractStyle } from '@ant-design/cssinjs'; import { ConfigProvider, theme as antdTheme } from 'antd'; import { Outlet, useServerInsertedHTML, usePrefersColor } from 'dumi'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import useAdditionalThemeConfig from "../hooks/useAdditionalThemeConfig"; import ThemeSwitch from "../common/ThemeSwitch"; import SiteContext from "dumi/theme/slots/SiteContext"; import { jsx as ___EmotionJSX } from "@emotion/react"; var RESPONSIVE_MOBILE = 768; var SITE_STATE_LOCALSTORAGE_KEY = 'dumi-theme-antd-site-state'; var defaultSiteState = { theme: ['light'], isMobile: false, direction: 'ltr' }; var getAlgorithm = function getAlgorithm() { var themes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; return themes.map(function (theme) { if (theme === 'dark') { return antdTheme.darkAlgorithm; } if (theme === 'compact') { return antdTheme.compactAlgorithm; } return antdTheme.defaultAlgorithm; }); }; var isThemeDark = function isThemeDark() { if (typeof window !== 'undefined') { var _window$matchMedia; return (_window$matchMedia = window.matchMedia('(prefers-color-scheme: dark)')) === null || _window$matchMedia === void 0 ? void 0 : _window$matchMedia.matches; } return false; }; var getSiteState = function getSiteState(siteState) { var localSiteState = siteState; var isDark = isThemeDark(); // 系统默认主题 var theme = (localSiteState === null || localSiteState === void 0 ? void 0 : localSiteState.theme) || []; var isAutoTheme = theme.filter(function (item) { return item === 'auto'; }).length > 0; if (isAutoTheme) { var nextTheme = theme.filter(function (item) { return item !== 'auto'; }); nextTheme.push(isDark ? 'dark' : 'light'); localSiteState.theme = nextTheme; } return Object.assign(defaultSiteState, localSiteState); }; var GlobalLayout = function GlobalLayout() { var _usePrefersColor = usePrefersColor(), _usePrefersColor2 = _slicedToArray(_usePrefersColor, 3), setPrefersColor = _usePrefersColor2[2]; var _useAdditionalThemeCo = useAdditionalThemeConfig(), configTheme = _useAdditionalThemeCo.theme, ssr = _useAdditionalThemeCo.ssr, prefersColor = _useAdditionalThemeCo.prefersColor; var _useState = useState(defaultSiteState), _useState2 = _slicedToArray(_useState, 2), _useState2$ = _useState2[0], theme = _useState2$.theme, isMobile = _useState2$.isMobile, direction = _useState2$.direction, setSiteState = _useState2[1]; // 基于 localStorage 实现 var updateSiteConfig = useCallback(function (props) { if (typeof window === 'undefined') { return; } try { var localSiteState = JSON.parse(window.localStorage.getItem(SITE_STATE_LOCALSTORAGE_KEY) || '{}'); var nextLocalSiteState = Object.assign(localSiteState, props); window.localStorage.setItem(SITE_STATE_LOCALSTORAGE_KEY, JSON.stringify(nextLocalSiteState)); setSiteState(function (prev) { return _objectSpread(_objectSpread({}, prev), props); }); } catch (error) { // eslint-disable-next-line no-console console.error(error); } }, []); var updateMobileMode = useCallback(function () { if (typeof window === 'undefined') { return; } updateSiteConfig({ isMobile: window.innerWidth < RESPONSIVE_MOBILE }); }, [updateSiteConfig]); useEffect(function () { if (typeof window === 'undefined') { return; } try { var _window$localStorage; var localSiteState = JSON.parse(((_window$localStorage = window.localStorage) === null || _window$localStorage === void 0 ? void 0 : _window$localStorage.getItem(SITE_STATE_LOCALSTORAGE_KEY)) || '{}'); // 首次设置主题样式 if (!(localSiteState !== null && localSiteState !== void 0 && localSiteState.theme)) { localSiteState.theme = [prefersColor.default]; } var siteConfig = getSiteState(localSiteState); updateSiteConfig(siteConfig); } catch (error) { // eslint-disable-next-line no-console console.error(error); } }, [prefersColor, updateSiteConfig]); useEffect(function () { if (typeof window === 'undefined') { return function () {}; } updateMobileMode(); // set data-prefers-color setPrefersColor((theme !== null && theme !== void 0 ? theme : []).indexOf('dark') > -1 ? 'dark' : 'light'); window.addEventListener('resize', updateMobileMode); return function () { window.removeEventListener('resize', updateMobileMode); }; }, [theme, updateMobileMode, setPrefersColor]); var siteContextValue = useMemo(function () { return { direction: direction, isMobile: isMobile, theme: theme, updateSiteConfig: updateSiteConfig }; }, [isMobile, theme, direction, updateSiteConfig]); var _React$useState = React.useState(function () { return createCache(); }), _React$useState2 = _slicedToArray(_React$useState, 1), styleCache = _React$useState2[0]; useServerInsertedHTML(function () { var styleText = extractStyle(styleCache, { plain: true, types: 'style' }); return ___EmotionJSX("style", { "data-type": "antd-cssinjs", dangerouslySetInnerHTML: { __html: styleText } }); }); useServerInsertedHTML(function () { var styleText = extractStyle(styleCache, { plain: true, types: ['cssVar', 'token'] }); return ___EmotionJSX("style", { "data-type": "antd-css-var", "data-rc-order": "prepend", "data-rc-priority": "-9999", dangerouslySetInnerHTML: { __html: styleText } }); }); var BaseGlobalLayoutJSX = ___EmotionJSX(SiteContext.Provider, { value: siteContextValue }, ___EmotionJSX(ConfigProvider, { theme: _objectSpread(_objectSpread({}, configTheme), {}, { algorithm: getAlgorithm(theme) }) }, ___EmotionJSX(Outlet, null), prefersColor.switch && ___EmotionJSX(ThemeSwitch, { value: theme, onChange: function onChange(nextTheme) { return updateSiteConfig({ theme: nextTheme }); } }))); var SSRGlobalLayoutJSX = ___EmotionJSX(StyleProvider, { cache: styleCache, linters: [logicalPropertiesLinter, legacyNotSelectorLinter, parentSelectorLinter] }, BaseGlobalLayoutJSX); if (ssr) { global.styleCache = styleCache; return SSRGlobalLayoutJSX; } return BaseGlobalLayoutJSX; }; export default GlobalLayout;