refactor: mitigate FOUC when applying Prism theme

This commit is contained in:
Alexey Pyltsyn 2022-05-08 13:59:39 +03:00
parent 7c9892888d
commit 3094b9f4fa
No known key found for this signature in database
GPG key ID: 43C3EEBF02122A7A
9 changed files with 48 additions and 45 deletions

View file

@ -15,6 +15,8 @@ import rtlcss from 'rtlcss';
import {readDefaultCodeTranslationMessages} from '@docusaurus/theme-translations';
import type {Options} from '@docusaurus/theme-classic';
import type webpack from 'webpack';
import type {PrismTheme} from 'prism-react-renderer';
import type {CSSProperties} from 'react';
const requireFromDocusaurusCore = createRequire(
require.resolve('@docusaurus/core/package.json'),
@ -22,6 +24,22 @@ const requireFromDocusaurusCore = createRequire(
const ContextReplacementPlugin: typeof webpack.ContextReplacementPlugin =
requireFromDocusaurusCore('webpack/lib/ContextReplacementPlugin');
const getPrismCssVariables = (prismTheme: PrismTheme): CSSProperties => {
const mapping: {[name: keyof PrismTheme['plain']]: string} = {
color: '--prism-color',
backgroundColor: '--prism-background-color',
};
const properties: {[key: string]: string} = {};
Object.entries(prismTheme.plain).forEach(([key, value]) => {
const varName = mapping[key];
if (varName && typeof value === 'string') {
properties[varName] = value;
}
});
return properties;
};
// Need to be inlined to prevent dark mode FOUC
// Make sure the key is the same as the one in `/theme/hooks/useTheme.js`
const ThemeStorageKey = 'theme';
@ -103,10 +121,14 @@ export default function themeClassic(
const {
announcementBar,
colorMode,
prism: {additionalLanguages},
prism: {additionalLanguages, theme, darkTheme},
} = themeConfig;
const {customCss} = options ?? {};
const {direction} = localeConfigs[currentLocale]!;
const prismBaseStyles = {
':root': getPrismCssVariables(theme),
'[data-theme="dark"]': getPrismCssVariables(darkTheme),
};
return {
name: 'docusaurus-theme-classic',
@ -201,6 +223,17 @@ ${noFlashColorMode(colorMode)}
${announcementBar ? AnnouncementBarInlineJavaScript : ''}
`,
},
{
tagName: 'style',
innerHTML: Object.entries(prismBaseStyles)
.map(
([selector, properties]) =>
`${selector} {${Object.entries(properties)
.map(([name, value]) => `${name}:${value};`)
.join('')}}`,
)
.join(' '),
},
],
};
},