Compare commits

...

2 Commits

Author SHA1 Message Date
suroh dff1fa475b added dark light switch
11ty build and deploy for ${{ gitea.repository }} / build-deploy (push) Successful in 21s Details
2024-02-08 16:56:16 +01:00
suroh 8e99275fcc added dark light switch 2024-02-08 16:56:00 +01:00
3 changed files with 227 additions and 7 deletions

View File

@ -7,7 +7,10 @@
</template>
</div>
<button class="audioToggle"></button>
<div class="controls">
<button class="audioToggle"></button>
<theme-switcher></theme-switcher>
</div>
</nav>
<nav id="sub" slot="subnav">
@ -31,6 +34,12 @@
<script src="nav-primary.js" type="module"></script>
<style webc:scoped>
/*
*
* switch element taken from Andy Bell's article
* which can be found here:
* https://piccalil.li/blog/a-highly-configurable-switch-component-using-modern-css/
*/
/* => HOST */
:host {
display: grid;
@ -64,6 +73,12 @@ nav-link[data-name="<~"] {
gap: 0.25em;
}
/* => CONTROLS */
.controls {
display: flex;
gap: 0.5em;
}
/* => AUDIO TOGGLE */
.audioToggle {
background: none;

View File

@ -0,0 +1,167 @@
<label class="switch-input">
<span class="visually-hidden">Enable setting</span>
<input type="checkbox" role="switch" class="visually-hidden" />
<span class="switch-input__decor" data-switch-input-state="on" aria-hidden="true" style="--switch-input-font-size: 65cqw;--switch-input-decor-space: var(--switch-input-gutter) 0.25ch;line-height: 0.63;">☼</span>
<span class="switch-input__decor" data-switch-input-state="off" aria-hidden="true" style="--switch-input-font-size: 50cqw; line-height: 1.03">☾</span>
<span class="switch-input__thumb" aria-hidden="true"></span>
</label>
<script type="module">
customElements.define('theme-switcher', class extends HTMLElement {
currentTheme
preferDark
constructor() {
super()
this.preferDark = window.matchMedia("(prefers-color-scheme: dark)")
}
connectedCallback() {
const checkbox = this.querySelector('input[type="checkbox"]')
this.currentTheme = localStorage.getItem('theme')
if (this.currentTheme == 'dark') {
checkbox.checked = true
document.body.classList.toggle('dark')
} else if (this.currentTheme == 'light') {
checkbox.checked = false
document.body.classList.toggle('light')
}
checkbox.addEventListener('click', () => {
let theme
if (this.preferDark.matches) {
document.body.classList.toggle("light")
theme = document.body.classList.contains("light")
? "light"
: "dark"
} else {
document.body.classList.toggle("dark")
theme = document.body.classList.contains("dark")
? "dark"
: "light"
}
localStorage.setItem("theme", theme)
})
}
})
</script>
<style webc:scoped>
/* Styles */
:host {
--switch-input-thumb-size: 0.88em;
--switch-input-thumb-bg: var(--bg-colour);
--switch-input-thumb-stroke: 1px solid var(--primary-colour-25);
--switch-input-off-bg: var(--neutral-100);
--switch-input-off-text: var(--neutral-900);
--switch-input-on-bg: var(--neutral-100-25);
--switch-input-on-text: var(--neutral-100);
--switch-input-gutter: 1px;
--switch-input-decor-space: var(--switch-input-gutter) 0.5ch;
--switch-input-focus-stroke: 2px solid #ff6978;
--switch-input-font-weight: bold;
/* --switch-input-font-family: sans-serif; */
--switch-input-font-size: 50cqw;
--switch-input-transition: inset 50ms linear;
display: grid;
}
.visually-hidden {
border: 0;
clip: rect(0 0 0 0);
height: auto;
margin: 0;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
white-space: nowrap;
}
.switch-input {
width: calc(
(var(--switch-input-thumb-size) * 2) + (var(--switch-input-gutter) * 3)
);
height: calc(
var(--switch-input-thumb-size) + (var(--switch-input-gutter) * 2)
);
border-radius: calc(
var(--switch-input-thumb-size) + var(--switch-input-gutter)
);
padding: var(--switch-input-gutter);
background: var(--switch-input-off-bg);
color: var(--switch-input-off-text);
text-align: left;
text-transform: uppercase;
font-family: var(--switch-input-font-family);
font-weight: var(--switch-input-font-weight);
position: relative;
cursor: pointer;
container-type: inline-size;
}
.switch-input__decor {
position: absolute;
inset-block: 0;
inset-inline-start: 0;
padding: var(--switch-input-decor-space);
/* Font size lives here because we wanna use container units */
font-size: var(--switch-input-font-size);
/* Legacy */
display: flex;
width: 100%;
/* align-items: center; */
/* Future */
/* align-content: center; */
/* display: block;
block-size: 100%; */
user-select: none;
}
.switch-input__decor[data-switch-input-state="off"] {
justify-content: flex-end;
}
.switch-input__thumb {
display: block;
width: var(--switch-input-thumb-size);
height: var(--switch-input-thumb-size);
border-radius: var(--switch-input-thumb-size);
background: var(--switch-input-thumb-bg);
border: var(--switch-input-thumb-stroke);
z-index: 1;
position: absolute;
inset-block-start: var(--switch-input-gutter);
inset-inline-start: var(--switch-input-gutter);
transition: var(--switch-input-transition);
}
/* Could do this */
/* .switch-input:has(:focus) .switch-input__thumb {
outline: var(--switch-input-focus-stroke);
} */
/* Better pointer experience. Still uses has because focus visible would have to be put direct on the checkbox */
.switch-input:has(:focus-visible) .switch-input__thumb {
outline: var(--switch-input-focus-stroke);
}
.switch-input:has(:checked) {
background: var(--switch-input-on-bg);
color: var(--switch-input-on-text);
}
.switch-input:has(:checked) .switch-input__thumb {
inset-inline-start: calc(
var(--switch-input-thumb-size) + (var(--switch-input-gutter) * 2)
);
}
</style>

View File

@ -5,6 +5,25 @@
scroll-behavior: smooth;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
input,
button,
textarea,
select {
font: inherit;
}
html {
-moz-text-size-adjust: none;
-webkit-text-size-adjust: none;
text-size-adjust: none;
}
/* --> BASE STYLES <-- */
:root {
--page-margin-inline: 1em;
@ -19,12 +38,6 @@
--bg-colour-25: #fcfcfc33;
}
body {
font-family: 'fira code', monospace;
color: var(--primary-colour);
background-color: var(--bg-colour);
}
@media (prefers-color-scheme: dark) {
body {
--primary-colour: var(--neutral-100);
@ -34,6 +47,31 @@ body {
}
}
body.dark {
--primary-colour: var(--neutral-100);
--primary-colour-25: var(--neutral-100-25);
--bg-colour: var(--neutral-900);
--bg-colour-25: var(--neutral-900-25);
}
body.light {
--primary-colour: var(--neutral-900);
--primary-colour-25: var(--neutral-900-25);
--bg-colour: #fcfcfcff;
--bg-colour-25: #fcfcfc33;
}
body {
font-family: 'fira code', monospace;
color: var(--primary-colour);
background-color: var(--bg-colour);
}
input {
background-color: var(--bg-colour);
color: var(--primary-colour);
}
p {
max-width: 80ch;
}