-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(theme): fix announcement bar layout shift due to missing storage …
…key namespace (#10144)
- Loading branch information
Showing
3 changed files
with
126 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import type {SiteStorage} from '@docusaurus/types'; | ||
import type {ThemeConfig} from '@docusaurus/theme-common'; | ||
|
||
// Support for ?docusaurus-theme=dark | ||
const ThemeQueryStringKey = 'docusaurus-theme'; | ||
|
||
// Support for ?docusaurus-data-mode=embed&docusaurus-data-myAttr=42 | ||
const DataQueryStringPrefixKey = 'docusaurus-data-'; | ||
|
||
export function getThemeInlineScript({ | ||
colorMode: {defaultMode, respectPrefersColorScheme}, | ||
siteStorage, | ||
}: { | ||
colorMode: ThemeConfig['colorMode']; | ||
siteStorage: SiteStorage; | ||
}): string { | ||
// Need to be inlined to prevent dark mode FOUC | ||
// Make sure the key is the same as the one in the color mode React context | ||
// Currently defined in: `docusaurus-theme-common/src/contexts/colorMode.tsx` | ||
const themeStorageKey = `theme${siteStorage.namespace}`; | ||
|
||
/* language=js */ | ||
return `(function() { | ||
var defaultMode = '${defaultMode}'; | ||
var respectPrefersColorScheme = ${respectPrefersColorScheme}; | ||
function setDataThemeAttribute(theme) { | ||
document.documentElement.setAttribute('data-theme', theme); | ||
} | ||
function getQueryStringTheme() { | ||
try { | ||
return new URLSearchParams(window.location.search).get('${ThemeQueryStringKey}') | ||
} catch (e) { | ||
} | ||
} | ||
function getStoredTheme() { | ||
try { | ||
return window['${siteStorage.type}'].getItem('${themeStorageKey}'); | ||
} catch (err) { | ||
} | ||
} | ||
var initialTheme = getQueryStringTheme() || getStoredTheme(); | ||
if (initialTheme !== null) { | ||
setDataThemeAttribute(initialTheme); | ||
} else { | ||
if ( | ||
respectPrefersColorScheme && | ||
window.matchMedia('(prefers-color-scheme: dark)').matches | ||
) { | ||
setDataThemeAttribute('dark'); | ||
} else if ( | ||
respectPrefersColorScheme && | ||
window.matchMedia('(prefers-color-scheme: light)').matches | ||
) { | ||
setDataThemeAttribute('light'); | ||
} else { | ||
setDataThemeAttribute(defaultMode === 'dark' ? 'dark' : 'light'); | ||
} | ||
} | ||
})();`; | ||
} | ||
|
||
/* language=js */ | ||
export const DataAttributeQueryStringInlineJavaScript = ` | ||
(function() { | ||
try { | ||
const entries = new URLSearchParams(window.location.search).entries(); | ||
for (var [searchKey, value] of entries) { | ||
if (searchKey.startsWith('${DataQueryStringPrefixKey}')) { | ||
var key = searchKey.replace('${DataQueryStringPrefixKey}',"data-") | ||
document.documentElement.setAttribute(key, value); | ||
} | ||
} | ||
} catch(e) {} | ||
})(); | ||
`; | ||
|
||
// 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) | ||
export function getAnnouncementBarInlineScript({ | ||
siteStorage, | ||
}: { | ||
siteStorage: SiteStorage; | ||
}): string { | ||
// 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 support Node.js with ESM support | ||
// + move all those announcementBar stuff there too | ||
const AnnouncementBarDismissStorageKey = `docusaurus.announcement.dismiss${siteStorage.namespace}`; | ||
const AnnouncementBarDismissDataAttribute = | ||
'data-announcement-bar-initially-dismissed'; | ||
|
||
/* language=js */ | ||
return `(function() { | ||
function isDismissed() { | ||
try { | ||
return localStorage.getItem('${AnnouncementBarDismissStorageKey}') === 'true'; | ||
} catch (err) {} | ||
return false; | ||
} | ||
document.documentElement.setAttribute('${AnnouncementBarDismissDataAttribute}', isDismissed()); | ||
})();`; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters