From ced1b6dc4d0ea909cc0d5c56707ad9a9f2b83547 Mon Sep 17 00:00:00 2001 From: Daniel Imfeld Date: Wed, 3 Jan 2024 15:59:58 -1000 Subject: [PATCH 1/5] add ThemeInit component that place script inside tag --- .changeset/friendly-pets-reflect.md | 5 +++++ .../src/lib/components/ThemeInit.svelte | 12 +++++++++++ .../svelte-ux/src/lib/components/index.ts | 1 + packages/svelte-ux/src/lib/styles/theme.ts | 20 +++++++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 .changeset/friendly-pets-reflect.md create mode 100644 packages/svelte-ux/src/lib/components/ThemeInit.svelte diff --git a/.changeset/friendly-pets-reflect.md b/.changeset/friendly-pets-reflect.md new file mode 100644 index 000000000..e86611b37 --- /dev/null +++ b/.changeset/friendly-pets-reflect.md @@ -0,0 +1,5 @@ +--- +"svelte-ux": patch +--- + +Add ThemeInit component to prevent flash of unstyled content when SSR is enabled diff --git a/packages/svelte-ux/src/lib/components/ThemeInit.svelte b/packages/svelte-ux/src/lib/components/ThemeInit.svelte new file mode 100644 index 000000000..6daffa81e --- /dev/null +++ b/packages/svelte-ux/src/lib/components/ThemeInit.svelte @@ -0,0 +1,12 @@ + + + + {@html headSnippet} + diff --git a/packages/svelte-ux/src/lib/components/index.ts b/packages/svelte-ux/src/lib/components/index.ts index acf035412..92b281cc7 100644 --- a/packages/svelte-ux/src/lib/components/index.ts +++ b/packages/svelte-ux/src/lib/components/index.ts @@ -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'; diff --git a/packages/svelte-ux/src/lib/styles/theme.ts b/packages/svelte-ux/src/lib/styles/theme.ts index aac38dadf..48edc90f5 100644 --- a/packages/svelte-ux/src/lib/styles/theme.ts +++ b/packages/svelte-ux/src/lib/styles/theme.ts @@ -20,3 +20,23 @@ export const colorNames = [ 'surface-300', 'surface-content', ]; + +/** Return a script tag that will set the initial theme from localStorage. This allows setting +* the theme before anything starts rendering, even when SSR is in use. */ +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 ``; +} From 30d8b29eb03fb32537d2a4d61b77b28c440ca842 Mon Sep 17 00:00:00 2001 From: Daniel Imfeld Date: Wed, 3 Jan 2024 17:02:21 -1000 Subject: [PATCH 2/5] Fix bug --- packages/svelte-ux/src/lib/styles/theme.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/svelte-ux/src/lib/styles/theme.ts b/packages/svelte-ux/src/lib/styles/theme.ts index 48edc90f5..b303f62aa 100644 --- a/packages/svelte-ux/src/lib/styles/theme.ts +++ b/packages/svelte-ux/src/lib/styles/theme.ts @@ -22,9 +22,9 @@ export const colorNames = [ ]; /** Return a script tag that will set the initial theme from localStorage. This allows setting -* the theme before anything starts rendering, even when SSR is in use. */ + * the theme before anything starts rendering, even when SSR is in use. */ export function createHeadSnippet(darkThemes: string[]) { - function _applyInitialStyle() { + function _applyInitialStyle(darkThemes) { let theme = localStorage.getItem('theme'); if (theme) { document.documentElement.dataset.theme = theme; From 4538b2737003324a309cfe918738357e72612083 Mon Sep 17 00:00:00 2001 From: Daniel Imfeld Date: Wed, 3 Jan 2024 17:11:39 -1000 Subject: [PATCH 3/5] proper sorting --- packages/svelte-ux/src/lib/components/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/svelte-ux/src/lib/components/index.ts b/packages/svelte-ux/src/lib/components/index.ts index 92b281cc7..50e84ea25 100644 --- a/packages/svelte-ux/src/lib/components/index.ts +++ b/packages/svelte-ux/src/lib/components/index.ts @@ -82,8 +82,8 @@ 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 ThemeInit } from './ThemeInit.svelte'; export { default as Tilt } from './Tilt.svelte'; export { default as Toggle } from './Toggle.svelte'; export { default as ToggleButton } from './ToggleButton.svelte'; From 61554e738296ea05a34e69d6265731fc0cdae633 Mon Sep 17 00:00:00 2001 From: Daniel Imfeld Date: Wed, 3 Jan 2024 17:13:24 -1000 Subject: [PATCH 4/5] instantiate ThemeInit inside Settings component --- packages/svelte-ux/src/lib/components/Settings.svelte | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/svelte-ux/src/lib/components/Settings.svelte b/packages/svelte-ux/src/lib/components/Settings.svelte index bae5e3e24..a2c0952e9 100644 --- a/packages/svelte-ux/src/lib/components/Settings.svelte +++ b/packages/svelte-ux/src/lib/components/Settings.svelte @@ -1,9 +1,15 @@ +{#if themeInit} + +{/if} From e07535e41134ddbafebf7374613e7977ddf68a6c Mon Sep 17 00:00:00 2001 From: Daniel Imfeld Date: Wed, 3 Jan 2024 17:25:05 -1000 Subject: [PATCH 5/5] add comment about stringified function --- packages/svelte-ux/src/lib/styles/theme.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/svelte-ux/src/lib/styles/theme.ts b/packages/svelte-ux/src/lib/styles/theme.ts index b303f62aa..edb9d0872 100644 --- a/packages/svelte-ux/src/lib/styles/theme.ts +++ b/packages/svelte-ux/src/lib/styles/theme.ts @@ -22,7 +22,11 @@ export const colorNames = [ ]; /** Return a script tag that will set the initial theme from localStorage. This allows setting - * the theme before anything starts rendering, even when SSR is in use. */ + * the theme before anything starts rendering, even when SSR is in use. + * + * This feels a bit weird compared to just placing the function directly in svelte:head, + * but it's the only way to inject the `darkThemes` array into the function. + **/ export function createHeadSnippet(darkThemes: string[]) { function _applyInitialStyle(darkThemes) { let theme = localStorage.getItem('theme');