mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-01 18:32:52 +02:00
fix(v2): Fix announcementBar layout shifts (#5040)
* Fix announcementBar layout shift * useAnnouncementBar should return correct state after hydration * refactor announcementBar => move utils to theme-common * restore previous announcementBar * typo
This commit is contained in:
parent
814455f88e
commit
9916a0b4a4
11 changed files with 179 additions and 110 deletions
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import {DocusaurusContext, Plugin} from '@docusaurus/types';
|
||||
import {ThemeConfig} from '@docusaurus/theme-common';
|
||||
import type {ThemeConfig} from '@docusaurus/theme-common';
|
||||
import {getTranslationFiles, translateThemeConfig} from './translations';
|
||||
import path from 'path';
|
||||
import Module from 'module';
|
||||
|
@ -24,7 +24,7 @@ const ContextReplacementPlugin = requireFromDocusaurusCore(
|
|||
|
||||
// Need to be inlined to prevent dark mode FOUC
|
||||
// Make sure that the 'storageKey' is the same as the one in `/theme/hooks/useTheme.js`
|
||||
const storageKey = 'theme';
|
||||
const ThemeStorageKey = 'theme';
|
||||
const noFlashColorMode = ({defaultMode, respectPrefersColorScheme}) => {
|
||||
return `(function() {
|
||||
var defaultMode = '${defaultMode}';
|
||||
|
@ -37,7 +37,7 @@ const noFlashColorMode = ({defaultMode, respectPrefersColorScheme}) => {
|
|||
function getStoredTheme() {
|
||||
var theme = null;
|
||||
try {
|
||||
theme = localStorage.getItem('${storageKey}');
|
||||
theme = localStorage.getItem('${ThemeStorageKey}');
|
||||
} catch (err) {}
|
||||
return theme;
|
||||
}
|
||||
|
@ -63,6 +63,26 @@ const noFlashColorMode = ({defaultMode, respectPrefersColorScheme}) => {
|
|||
})();`;
|
||||
};
|
||||
|
||||
// Duplicated constant. Unfortunately we can't import it from theme-common, as we need to support older nodejs versions without ESM support
|
||||
// TODO: import from theme-common once we only support Node.js with ESM support
|
||||
// + move all those announcementBar stuff there too
|
||||
export const AnnouncementBarDismissStorageKey =
|
||||
'docusaurus.announcement.dismiss';
|
||||
const AnnouncementBarDismissDataAttribute =
|
||||
'data-announcement-bar-initially-dismissed';
|
||||
// We always render the announcement bar html on the server, to prevent layout shifts on React hydration
|
||||
// The theme can use CSS + the data attribute to hide the announcement bar asap (before React hydration)
|
||||
const AnnouncementBarInlineJavaScript = `
|
||||
(function() {
|
||||
function isDismissed() {
|
||||
try {
|
||||
return localStorage.getItem('${AnnouncementBarDismissStorageKey}') === 'true';
|
||||
} catch (err) {}
|
||||
return false;
|
||||
}
|
||||
document.documentElement.setAttribute('${AnnouncementBarDismissDataAttribute}', isDismissed());
|
||||
})();`;
|
||||
|
||||
function getInfimaCSSFile(direction) {
|
||||
return `infima/dist/css/default/default${
|
||||
direction === 'rtl' ? '-rtl' : ''
|
||||
|
@ -82,7 +102,11 @@ export default function docusaurusThemeClassic(
|
|||
i18n: {currentLocale, localeConfigs},
|
||||
} = context;
|
||||
const themeConfig = (roughlyTypedThemeConfig || {}) as ThemeConfig;
|
||||
const {colorMode, prism: {additionalLanguages = []} = {}} = themeConfig;
|
||||
const {
|
||||
announcementBar,
|
||||
colorMode,
|
||||
prism: {additionalLanguages = []} = {},
|
||||
} = themeConfig;
|
||||
const {customCss} = options || {};
|
||||
const {direction} = localeConfigs[currentLocale];
|
||||
|
||||
|
@ -178,7 +202,10 @@ export default function docusaurusThemeClassic(
|
|||
preBodyTags: [
|
||||
{
|
||||
tagName: 'script',
|
||||
innerHTML: noFlashColorMode(colorMode),
|
||||
innerHTML: `
|
||||
${noFlashColorMode(colorMode)}
|
||||
${announcementBar ? AnnouncementBarInlineJavaScript : ''}
|
||||
`,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue