add theme picker

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2026-03-16 02:13:11 +01:00
parent a4337b3514
commit 49f457cda7
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
5 changed files with 122 additions and 21 deletions

63
lib/theme_picker.typ Normal file
View file

@ -0,0 +1,63 @@
#import "./custom_html.typ" as chtml
/// Buttons to chose the theme to use (Light/Dark)
/// label is the aria-label of the html element (for screenreader).
/// label-auto, label-light and label-dark are the content of each button.
#let theme_picker(
label: "Theme Picker",
label-auto: [Auto],
label-light: [Light],
label-dark: [Dark],
) = {
```raw-css
/* Thanks to Lyra Rebane for no-js theme picker implementation: https://lyra.horse/blog/2025/08/you-dont-need-js/ */
theme-picker {
display: flex;
padding: 5px;
label {
transition: background 0.08s;
&:first-child { border-radius: 8px 0 0 8px; }
&:last-child { border-radius: 0 8px 8px 0; }
&:has(input:checked) {
box-shadow: inset 0px 0px 8px 0px var(--color-button-shadow);
}
&:has(input:focus-visible) {
outline: 2px solid var(--color-button-focus);
}
&:hover { background: #0004; }
&:active { background: #0006; }
box-shadow: inset 0px 0px 1.2px 0px #000;
padding: 10px;
cursor: pointer;
background: #0002;
}
input {
/* To allow screen reader to still access these. */
opacity: 0;
position: absolute;
pointer-events: none;
}
/* Typst like to insert unecessary <p> elements */
p {
margin: 0px;
}
}
```
chtml.theme-picker(
label: label,
{
html.label({
html.input(type: "radio", name: "theme", id: "theme-auto", checked: true)
label-auto
})
html.label({
html.input(type: "radio", name: "theme", id: "theme-light")
label-light
})
html.label({
html.input(type: "radio", name: "theme", id: "theme-dark")
label-dark
})
}
)
}