dumi-theme-antd
Version:
Ant Design 5.0 官网风格类似的 dumi2 主题插件
187 lines (186 loc) • 6.82 kB
JavaScript
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;