feat: support non-singleton darkmode
| | |
| | | // @ts-ignore: this is safe, we don't want to actually make darkmode.inline.ts a module as |
| | | // modules are automatically deferred and we don't want that to happen for critical beforeDOMLoads |
| | | // see: https://v8.dev/features/modules#defer |
| | | // @ts-ignore |
| | | import darkmodeScript from "./scripts/darkmode.inline" |
| | | import styles from "./styles/darkmode.scss" |
| | | import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" |
| | |
| | | |
| | | const Darkmode: QuartzComponent = ({ displayClass, cfg }: QuartzComponentProps) => { |
| | | return ( |
| | | <button class={classNames(displayClass, "darkmode")} id="darkmode"> |
| | | <button class={classNames(displayClass, "darkmode")}> |
| | | <svg |
| | | xmlns="http://www.w3.org/2000/svg" |
| | | xmlnsXlink="http://www.w3.org/1999/xlink" |
| | | version="1.1" |
| | | id="dayIcon" |
| | | class="dayIcon" |
| | | x="0px" |
| | | y="0px" |
| | | viewBox="0 0 35 35" |
| | |
| | | xmlns="http://www.w3.org/2000/svg" |
| | | xmlnsXlink="http://www.w3.org/1999/xlink" |
| | | version="1.1" |
| | | id="nightIcon" |
| | | class="nightIcon" |
| | | x="0px" |
| | | y="0px" |
| | | viewBox="0 0 100 100" |
| | |
| | | emitThemeChangeEvent(newTheme) |
| | | } |
| | | |
| | | // Darkmode toggle |
| | | const themeButton = document.querySelector("#darkmode") as HTMLButtonElement |
| | | if (themeButton) { |
| | | themeButton.addEventListener("click", switchTheme) |
| | | window.addCleanup(() => themeButton.removeEventListener("click", switchTheme)) |
| | | for (const darkmodeButton of document.getElementsByClassName("darkmode")) { |
| | | darkmodeButton.addEventListener("click", switchTheme) |
| | | window.addCleanup(() => darkmodeButton.removeEventListener("click", switchTheme)) |
| | | } |
| | | |
| | | // Listen for changes in prefers-color-scheme |
| | | const colorSchemeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)") |
| | | colorSchemeMediaQuery.addEventListener("change", themeChange) |
| | |
| | | } |
| | | |
| | | :root[saved-theme="dark"] .darkmode { |
| | | & > #dayIcon { |
| | | & > .dayIcon { |
| | | display: none; |
| | | } |
| | | & > #nightIcon { |
| | | & > .nightIcon { |
| | | display: inline; |
| | | } |
| | | } |
| | | |
| | | :root .darkmode { |
| | | & > #dayIcon { |
| | | & > .dayIcon { |
| | | display: inline; |
| | | } |
| | | & > #nightIcon { |
| | | & > .nightIcon { |
| | | display: none; |
| | | } |
| | | } |