Fix: Embed Theme switching when appearance is using System Theme (#8655)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
co-authored by
Peer Richelsen
parent
2f175eacf5
commit
d3f77bf292
@@ -12,6 +12,9 @@
|
||||
.cell-2 {
|
||||
margin: 10px;
|
||||
}
|
||||
.dark {
|
||||
background-color:rgb(16 16 16);
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
const searchParams = new URL(document.URL).searchParams;
|
||||
@@ -22,8 +25,5 @@
|
||||
<script type="module" src="./src/preview.ts"></script>
|
||||
<body>
|
||||
<div id="my-embed" style="width: 100%; height: 90%; overflow: scroll"></div>
|
||||
<script type="module">
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -90,3 +90,27 @@ previewWindow.addEventListener("message", (e) => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function makePreviewPageUseSystemPreference() {
|
||||
const colorSchemeQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
|
||||
function handleColorSchemeChange(e: MediaQueryListEvent) {
|
||||
if (e.matches) {
|
||||
// Dark color scheme
|
||||
document.body.classList.remove("light");
|
||||
document.body.classList.add("dark");
|
||||
} else {
|
||||
// Light color scheme
|
||||
document.body.classList.add("light");
|
||||
document.body.classList.remove("dark");
|
||||
}
|
||||
}
|
||||
|
||||
colorSchemeQuery.addEventListener("change", handleColorSchemeChange);
|
||||
|
||||
// Initial check
|
||||
handleColorSchemeChange(new MediaQueryListEvent("change", { matches: colorSchemeQuery.matches }));
|
||||
}
|
||||
|
||||
// This makes preview page behave like a website that has system preference enabled. This provides a better experience of preview when user switch their system theme to dark
|
||||
makePreviewPageUseSystemPreference();
|
||||
|
||||
@@ -14,10 +14,14 @@ export default function useTheme(themeToSet?: Maybe<string>) {
|
||||
const embedTheme = useEmbedTheme();
|
||||
|
||||
useEffect(() => {
|
||||
// If themeToSet is not provided the purpose is to just return the current the current values
|
||||
if (!themeToSet) return;
|
||||
// If themeToSet is not provided the app intends to not apply a specific theme
|
||||
if (!themeToSet) {
|
||||
// But if embedTheme is set then the Embed API intends to apply that theme or it wants "system" theme which is the default
|
||||
setTheme(embedTheme || "system");
|
||||
return;
|
||||
}
|
||||
|
||||
// Embed theme takes precedence over theme configured in app. This allows embeds to be themed differently
|
||||
// Embed theme takes precedence over theme configured in app. If embedTheme isn't set that is it's in 'Auto' mode, then it would use the theme configured in appearance.
|
||||
const finalThemeToSet = embedTheme || themeToSet;
|
||||
|
||||
if (!finalThemeToSet || finalThemeToSet === activeTheme) return;
|
||||
@@ -25,6 +29,7 @@ export default function useTheme(themeToSet?: Maybe<string>) {
|
||||
setTheme(finalThemeToSet);
|
||||
// We must not add `activeTheme` to the dependency list as it can cause an infinite loop b/w dark and theme switches
|
||||
// because there might be another booking page with conflicting theme.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [themeToSet, setTheme, embedTheme]);
|
||||
return {
|
||||
resolvedTheme,
|
||||
|
||||
Reference in New Issue
Block a user