diff --git a/packages/docusaurus-theme-classic/src/index.ts b/packages/docusaurus-theme-classic/src/index.ts index 9fd370a2e5..ad0e4f09d6 100644 --- a/packages/docusaurus-theme-classic/src/index.ts +++ b/packages/docusaurus-theme-classic/src/index.ts @@ -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(' '), + }, ], }; }, diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Container/index.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Container/index.tsx index 293d700dad..335ed92b9c 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Container/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Container/index.tsx @@ -7,24 +7,17 @@ import React, {type ComponentProps} from 'react'; import clsx from 'clsx'; -import { - usePrismTheme, - getPrismCssVariables, - ThemeClassNames, -} from '@docusaurus/theme-common'; +import {ThemeClassNames} from '@docusaurus/theme-common'; import styles from './styles.module.css'; export default function CodeBlockContainer({ as: As, ...props }: {as: T} & ComponentProps): JSX.Element { - const prismTheme = usePrismTheme(); - const prismCssVariables = getPrismCssVariables(prismTheme); return ( ( - + )); return ( - + {showLineNumbers ? ( <> diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx index 9565932faf..8df9a52bb2 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx @@ -6,7 +6,6 @@ */ import React, {isValidElement, type ReactNode} from 'react'; -import useIsBrowser from '@docusaurus/useIsBrowser'; import type {Props} from '@theme/CodeBlock'; import ElementContent from '@theme/CodeBlock/Content/Element'; import StringContent from '@theme/CodeBlock/Content/String'; @@ -29,17 +28,8 @@ export default function CodeBlock({ children: rawChildren, ...props }: Props): JSX.Element { - // The Prism theme on SSR is always the default theme but the site theme can - // be in a different mode. React hydration doesn't update DOM styles that come - // from SSR. Hence force a re-render after mounting to apply the current - // relevant styles. - const isBrowser = useIsBrowser(); const children = maybeStringifyChildren(rawChildren); const CodeBlockComp = typeof children === 'string' ? StringContent : ElementContent; - return ( - - {children as string} - - ); + return {children as string}; } diff --git a/packages/docusaurus-theme-classic/src/validateThemeConfig.ts b/packages/docusaurus-theme-classic/src/validateThemeConfig.ts index 9bdf1a8d9d..7369288ab5 100644 --- a/packages/docusaurus-theme-classic/src/validateThemeConfig.ts +++ b/packages/docusaurus-theme-classic/src/validateThemeConfig.ts @@ -44,6 +44,7 @@ export const DEFAULT_CONFIG = { prism: { additionalLanguages: [], theme: defaultPrismTheme, + darkTheme: defaultPrismTheme, magicComments: [ { className: 'theme-code-block-highlighted-line', diff --git a/packages/docusaurus-theme-common/src/hooks/usePrismTheme.ts b/packages/docusaurus-theme-common/src/hooks/usePrismTheme.ts index b791d31194..f25b68af71 100644 --- a/packages/docusaurus-theme-common/src/hooks/usePrismTheme.ts +++ b/packages/docusaurus-theme-common/src/hooks/usePrismTheme.ts @@ -16,9 +16,7 @@ import {useThemeConfig} from '../utils/useThemeConfig'; export function usePrismTheme(): PrismTheme { const {prism} = useThemeConfig(); const {colorMode} = useColorMode(); - const lightModeTheme = prism.theme; - const darkModeTheme = prism.darkTheme || lightModeTheme; - const prismTheme = colorMode === 'dark' ? darkModeTheme : lightModeTheme; + const prismTheme = colorMode === 'dark' ? prism.darkTheme : prism.theme; return prismTheme; } diff --git a/packages/docusaurus-theme-common/src/index.ts b/packages/docusaurus-theme-common/src/index.ts index 424aff10b0..f285381469 100644 --- a/packages/docusaurus-theme-common/src/index.ts +++ b/packages/docusaurus-theme-common/src/index.ts @@ -35,7 +35,6 @@ export { parseLanguage, parseLines, containsLineNumbers, - getPrismCssVariables, } from './utils/codeBlockUtils'; export { diff --git a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts index fa091fe7a1..9baa9c4288 100644 --- a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts @@ -6,8 +6,6 @@ */ import rangeParser from 'parse-numeric-range'; -import type {PrismTheme} from 'prism-react-renderer'; -import type {CSSProperties} from 'react'; const codeBlockTitleRegex = /title=(?["'])(?.*?)\1/; const metastringLinesRangeRegex = /\{(?<range>[\d,-]+)\}/; @@ -231,19 +229,3 @@ export function parseLines( }); return {lineClassNames, code}; } - -export function 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; -} diff --git a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts index 03cf74d4ff..3bdf459def 100644 --- a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts +++ b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts @@ -55,7 +55,7 @@ export type AnnouncementBarConfig = { export type PrismConfig = { theme: PrismTheme; - darkTheme?: PrismTheme; + darkTheme: PrismTheme; defaultLanguage?: string; additionalLanguages: string[]; magicComments: MagicCommentConfig[];