-
-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: enable mode-watcher to manage the theme-color meta tag #48
Conversation
🦋 Changeset detectedLatest commit: 1b42b67 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Hey @ollema, currently traveling this week but I'll try to find some time to check this out! |
Hey @ollema, hit me up on Discord when you see this! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks great! left some comments for further improvement (for either of us to fix, I can do it if you don't have time)
src/lib/mode-watcher.svelte
Outdated
|
||
elem.classList[light ? 'remove' : 'add']('dark'); | ||
elem.style.colorScheme = light ? 'light' : 'dark'; | ||
rootEl.classList[light ? 'remove' : 'add']('dark'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
elem
and te
was chosen instead of more descriptive names for bundle size reasons. but maybe this was not needed, maybe this code is also minimized. will have to double check!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah man these get minified. Descriptive names > short names (unless you're building a minifier 😉)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could have sworn that this kind of hacky code where you include something that's stringified as a raw html string would not be minified but I am probably mistaken
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you can find rootEl
in the client-side bundle I'll send you some $ 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No you're fine, I should have done a more thorough review before making bold claims like that 😂 It's because we are stringifying it, and then slapping that stringified version directly into the tag, vs calling the setInitialMode.toString()
in there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought so too, so I tried:
{@html `<\u{73}cript nonce="%sveltekit.nonce%">(${setInitialMode.toString()})("dark");</script>`}
similar to skeleton, but that did not work it seems. still did not end up being minimized!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe the function needs to be defined in a .ts
file and exported, let me try that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tried:
<script lang="ts">
import { setInitialMode } from './mode.js';
</script>
...
<svelte:head>
{@html `<\u{73}cript nonce="%sveltekit.nonce%">(${setInitialMode.toString()})("dark", undefined);</script>`}
</svelte:head>
with:
// mode.ts
export function setInitialMode(defaultMode: Mode, themeColors?: ThemeColors) {
const rootEl = document.documentElement;
const mode = localStorage.getItem('mode-watcher-mode') || defaultMode;
const light =
mode === 'light' ||
(mode === 'system' && window.matchMedia('(prefers-color-scheme: light)').matches);
rootEl.classList[light ? 'remove' : 'add']('dark');
rootEl.style.colorScheme = light ? 'light' : 'dark';
if (themeColors) {
const themeMetaEl = document.querySelector('meta[name="theme-color"]');
if (themeMetaEl) {
themeMetaEl.setAttribute('content', mode === 'light' ? themeColors.light : themeColors.dark);
}
}
localStorage.setItem('mode', mode);
}
and that still does not work...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get it.
I copied the exact code from skeleton now, just to verify:
<svelte:head>
<!-- Workaround for a svelte parsing error: https://github.com/sveltejs/eslint-plugin-svelte/issues/492 -->
{@html `<\u{73}cript nonce="%sveltekit.nonce%">(${setInitialClassState.toString()})();</script>`}
</svelte:head>
and
// mode.ts
export function setInitialClassState() {
const elemHtmlClasses = document.documentElement.classList;
// Conditions
const condLocalStorageUserPrefs = localStorage.getItem('modeUserPrefers') === 'false';
const condLocalStorageUserPrefsExists = !('modeUserPrefers' in localStorage);
const condMatchMedia = window.matchMedia('(prefers-color-scheme: dark)').matches;
// Add/remove `.dark` class to HTML element
if (condLocalStorageUserPrefs || (condLocalStorageUserPrefsExists && condMatchMedia)) {
elemHtmlClasses.add('dark');
} else {
elemHtmlClasses.remove('dark');
}
}
still not minified when running pnpm build && pnpm preview
. I have no idea what's going on
Let me know once this is ready for re-review/merge! |
theme-color
propmode-watcher
to manage the theme-color meta tag
mode-watcher
to manage the theme-color meta tag
should be ready now! all questions/concerns have been resolved I think except for the first one included in the original PR description:
I'm tempted to leave as is and solve with better documentation, I think that will be the least surprising option |
I think we can create one if The code in #40 is more pseudo I believe. |
Was able to get the head tag to minify :) merging now! |
There's a typo either in the implementation or docs, since the former use |
thanks! fixed in #58 |
closes #40.
progress:
src/lib/mode-watcher.svelte
. FOUC prevention snippet should work based on my testing - both for existing functionality and for thetheme-color
settingsrc/routes/+page.svelte
by adding derived stores that displays how thehtml
element and the newmeta
element is updatedthemeColors
prop in the demo app:src/routes/+layout.svelte
<meta name="theme-color" content="..." />
insrc/app.html
for the demo app, see belowtodo:
<meta name="theme-color" content="..." />
entry since we check for it's existing before overwriting it. is this intentional or should we always write (create a meta element for theme-color if needed) ifthemeColors
are set?src/lib/stores.ts
. could you help me out here @huntabyte - I'm searching for some pattern where props passed to a component could somehow be read from stores which are initialised somewhere else... do we perhaps need to add some helper function for creating stores/components? usecontext="module"
? I'm not sure, I have not encountered this before