Skip to content

Commit

Permalink
Prototyped cleaned up runtime implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Zaydek Michels-Gualtieri committed Nov 16, 2020
1 parent 55bff93 commit c429a97
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 74 deletions.
1 change: 0 additions & 1 deletion src/duomo/core/border.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
);
}

// TODO: Rename to `generate-opaque-colors-from-map`.
@mixin border-color-from-map($map, $opacity-range) {
// prettier-ignore
@include helpers.generate-opaque-colors-from-map(
Expand Down
14 changes: 7 additions & 7 deletions src/duomo/helpers/index.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@forward "escape"; // TODO
@forward "generators"; // TODO
@forward "get-ampersand"; // TODO
@forward "getters"; // TODO
@forward "range"; // TODO
@forward "resolve"; // TODO
@forward "safe"; // TODO
@forward "escape";
@forward "generators";
@forward "get-ampersand";
@forward "getters";
@forward "range";
@forward "resolve";
@forward "safe"; // TODO: Do we want to forward `safe-abs`, etc.?
122 changes: 56 additions & 66 deletions src/runtime/Duomo.ts
Original file line number Diff line number Diff line change
@@ -1,87 +1,77 @@
const THEME_PREFERENCE_KEY = "duomo-theme-preference"
const THEME_PREFERENCE_KEY = "duomo-theme-preference" as const

export enum Mode {
development = "development",
production = "production",
}

interface IDuomo {
__deferers: (() => void)[]
init(): void
defer(): void
init(mode: Mode): () => void
toggleDebugMode(): void
toggleDarkMode(): void
}

// TODO: Can we refactor Duomo to be a React component?
//
// <Duomo dev? prod?>
// {/* ... */}
// </Duomo>
//
// The problem with this is SSR. This will be run on the server in NextJS.
// We want to trigger mode as-fast-as-possible when the client loads the app.
//
// Currently we use <script src="/scripts/layoutDarkMode.js" />
//
// function themePreferenceDark() {
// const ok = (
// "themePreference" in localStorage &&
// localStorage.themePreference === "dark"
// )
// return ok
// }
// function prefersColorShemeDark() {
// const ok = (
// window.matchMedia &&
// window.matchMedia("(prefers-color-scheme: dark)").matches
// )
// return ok
// }
// ;(() => {
// if (themePreferenceDark() || prefersColorShemeDark()) {
// const html = document.documentElement
// html.classList.add("dark")
// }
// })()
//
function localStorageThemePreference() {
return "themePreference" in localStorage && localStorage[THEME_PREFERENCE_KEY] === "dark"
}
function operatingSystemThemePreference() {
return "matchMedia" in window && window.matchMedia("(prefers-color-scheme: dark)").matches
}

function recoverDarkMode() {
if (!localStorageThemePreference() && !operatingSystemThemePreference()) {
// No-op
return
}
document.body.classList.add("dark")
}

const Duomo: IDuomo = {
__deferers: [],
init(mode: Mode) {
const deferers: Array<() => void> = []

// TODO: Can `init` return a defer closure? Then deprecate the `defer` method.
// TODO: It would be nice if we can init from "development" or "production" for example.
init() {
// TODO: Read `THEME_PREFERENCE_KEY` from localStorage.
const media = "matchMedia" in window && window.matchMedia("(prefers-color-scheme: dark)")
if (media) {
if (media.matches) {
document.body.setAttribute("data-theme", "dark")
}
// NOTE: Prefer `media.addListener`.
recoverDarkMode()
if ("matchMedia" in window) {
// NOTE: Prefer `media.addListener` (vs. `media.addEventListener`).
//
// The addListener() method of the MediaQueryList interface adds a listener to the MediaQueryListener that will
// run a custom callback function in response to the media query status changing.
//
// This is basically an alias of EventTarget.addEventListener(), for backwards compatibility purposes.
// Older browsers should use addListener instead of addEventListener since MediaQueryList only inherits from
// EventTarget in newer browsers.
// > The addListener() method of the MediaQueryList interface adds a listener to the MediaQueryListener that will
// > run a custom callback function in response to the media query status changing.
// >
// > This is basically an alias of EventTarget.addEventListener(), for backwards compatibility purposes.
// > Older browsers should use addListener instead of addEventListener since MediaQueryList only inherits from
// > EventTarget in newer browsers.
//
// https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/addListener
//
const media = window.matchMedia("(prefers-color-scheme: dark)")
const handleMedia = () => {
Duomo.toggleDarkMode()
}
media.addListener(handleMedia)
Duomo.__deferers.push(() => media.removeListener(handleMedia))
deferers.push(() => media.removeListener(handleMedia))
}
const handleKeyDown = (e: KeyboardEvent) => {
if (!e.ctrlKey && e.key.toLowerCase() === "d") {
Duomo.toggleDarkMode()
} else if (e.ctrlKey && e.key.toLowerCase() === "d") {
Duomo.toggleDebugMode()

if (mode === "development") {
// Handler for dark mode:
const handleKeyDownDarkMode = (e: KeyboardEvent) => {
if (e.ctrlKey && (e.key.toLowerCase() === "d" || e.keyCode === 68)) {
Duomo.toggleDarkMode()
}
}
document.addEventListener("keydown", handleKeyDownDarkMode)
deferers.push(() => document.removeEventListener("keydown", handleKeyDownDarkMode))

// Handler for debug mode:
const handleKeyDownDebugMode = (e: KeyboardEvent) => {
if (e.ctrlKey && (e.key.toLowerCase() === "d" || e.keyCode === 68)) {
Duomo.toggleDebugMode()
}
}
document.addEventListener("keydown", handleKeyDownDebugMode)
deferers.push(() => document.removeEventListener("keydown", handleKeyDownDebugMode))
}
document.addEventListener("keydown", handleKeyDown)
Duomo.__deferers.push(() => document.removeEventListener("keydown", handleKeyDown))
},
defer() {
for (let x = 0; x < Duomo.__deferers.length; x++) {
Duomo.__deferers[x]()
}

return () => deferers.reverse().forEach(defer => defer())
},
toggleDebugMode() {
const hasAttribute = document.body.hasAttribute("data-debug")
Expand Down

0 comments on commit c429a97

Please sign in to comment.