Style the colour picker

This commit is contained in:
Lewis Dale 2023-09-26 17:06:52 +01:00
parent 47a657a36c
commit f213a499e2
2 changed files with 77 additions and 48 deletions

View File

@ -34,15 +34,7 @@
<li><a href="/links">Links</a></li> <li><a href="/links">Links</a></li>
</ul> </ul>
</nav> </nav>
<color-scheme-toggle></color-scheme-toggle> <fieldset class="color-scheme">
</header>
{{ content | safe }}
<footer>
<div class="wrapper-lg">Copyright &copy; {{ today.year }} {{ metadata.author.name }}</div>
</footer>
<template id="color-scheme-toggle">
<fieldset>
<legend>Change your colour scheme</legend> <legend>Change your colour scheme</legend>
<label> <label>
<input type="radio" name="color-scheme" value="dark" /> <input type="radio" name="color-scheme" value="dark" />
@ -53,55 +45,50 @@
Light Light
</label> </label>
</fieldset> </fieldset>
</template> </header>
{{ content | safe }}
<footer>
<div class="wrapper-lg">Copyright &copy; {{ today.year }} {{ metadata.author.name }}</div>
</footer>
<script type="text/javascript"> <script type="text/javascript">
window.customElements.define("color-scheme-toggle", class extends HTMLElement { const defaultColourScheme = () => {
constructor() { if (localStorage.getItem('color-scheme')) {
super(); return localStorage.getItem('color-scheme');
const template = document.getElementById("color-scheme-toggle");
const templateNode = template.content.cloneNode(true);
this.appendChild(templateNode);
} }
getColourScheme = () => { if (window.matchMedia('(prefers-color-scheme: dark)')?.matches) {
const colourScheme = localStorage.getItem('color-scheme'); return "dark";
if (colourScheme) {
return colourScheme;
}
if (window.matchMedia('(prefers-color-scheme: dark)')?.matches) {
return "dark";
}
return "light";
} }
onColourSchemeChange = (e) => { return "light";
localStorage.setItem('color-scheme', e.target.value); };
this.updateComponents();
}
updateComponents = () => { const data = new Proxy({
this.querySelectorAll('[name="color-scheme"]').forEach(radio => { 'color-scheme': defaultColourScheme(),
radio.checked = this.getColourScheme() === radio.value; }, {
set: (obj, key, value) => {
obj[key] = value;
localStorage.setItem(key, value);
document.querySelectorAll(`[type="radio"][name="${key}"]`).forEach(radio => {
radio.checked = radio.value === value;
}); });
document.body.setAttribute(`data-${key}`, value);
if (localStorage.getItem('color-scheme')) { return true;
document.body.setAttribute('data-color-scheme', this.getColourScheme());
}
}
connectedCallback() {
this.querySelectorAll('[name="color-scheme"]').forEach(radio => {
radio.addEventListener('change', this.onColourSchemeChange);
});
this.updateComponents();
} }
}); });
const onRadioChange = e => {
data[e.target.name] = e.target.value;
}
document.querySelectorAll('[name="color-scheme"]').forEach(radio => {
radio.addEventListener('change', onRadioChange);
radio.checked = data[radio.name] == radio.value;
});
document.body.setAttribute(`data-color-scheme`, data['color-scheme']);
</script> </script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,42 @@
.color-scheme {
border: 0;
display: flex;
gap: var(--space-size-xs);
legend {
position:absolute;
clip:rect(0 0 0 0);
}
input[name="color-scheme"] {
position:absolute;
clip:rect(0 0 0 0);
}
label:has(:not(:checked)) {
color: var(--color-subtle);
}
label:has(:focus-visible) {
outline: 1px solid var(--color-primary);
outline-offset: 2px;
}
label:has([name="color-scheme"])::before {
font-family: "font awesome 6 free";
font-style: normal;
font-variant: normal;
text-rendering: auto;
font-weight: 900;
-webkit-font-smoothing: antialiased;
font-size: var(--text-size-s);
}
label:has([name="color-scheme"][value="dark"])::before {
content: "\f186";
}
label:has([name="color-scheme"][value="light"])::before {
content: "\f185";
}
}