Skip to content

Commit

Permalink
add ThemeInit component that place script inside <head> tag
Browse files Browse the repository at this point in the history
  • Loading branch information
dimfeld committed Jan 4, 2024
1 parent 2e0ad12 commit 29f7081
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/friendly-pets-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte-ux": patch
---

Add ThemeInit component to prevent flash of unstyled content when SSR is enabled
12 changes: 12 additions & 0 deletions packages/svelte-ux/src/lib/components/ThemeInit.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script>
import { createHeadSnippet } from '../styles/theme';
import { getSettings } from './settings';
const darkThemes = getSettings().themes?.dark ?? [];
let headSnippet = createHeadSnippet(darkThemes);
</script>
<svelte:head>
{@html headSnippet}
</svelte:head>
1 change: 1 addition & 0 deletions packages/svelte-ux/src/lib/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export { default as TableOrderIcon } from './TableOrderIcon.svelte';
export { default as Tab } from './Tab.svelte';
export { default as Tabs } from './Tabs.svelte';
export { default as TextField } from './TextField.svelte';
export { default as ThemeInit } from './ThemeInit.svelte';
export { default as ThemeButton } from './ThemeButton.svelte';
export { default as Tilt } from './Tilt.svelte';
export { default as Toggle } from './Toggle.svelte';
Expand Down
19 changes: 19 additions & 0 deletions packages/svelte-ux/src/lib/styles/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,22 @@ export const colorNames = [
'surface-300',
'surface-content',
];

/** Return a script tag that will set the initial theme from localStorage. This is suitable */
export function createHeadSnippet(darkThemes: string[]) {
function _applyInitialStyle() {
let theme = localStorage.getItem('theme');
if (theme) {
document.documentElement.dataset.theme = theme;
if (darkThemes.includes(theme)) {
document.documentElement.classList.add('dark');
}
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark');
}
}

let darkThemeList = darkThemes.map((theme) => `'${theme}'`).join(', ');

return `<script>(${_applyInitialStyle.toString()})([${darkThemeList}])</script>`;
}

0 comments on commit 29f7081

Please sign in to comment.