-
Notifications
You must be signed in to change notification settings - Fork 341
Add dark theme and theme switcher #540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 41 commits
07e416b
932844e
2469f07
f0cccbe
9850073
338a1b5
a1d9865
6f50e5a
df23c55
84338de
5e3f3a5
81a2117
bf6044b
c59735c
25a8e1e
03a84ee
951a316
7342f64
06ab359
3b36764
9ecd5e4
31f7c5e
5b1452d
ecdf638
8eb2c1e
36445bc
3e07469
a474db1
c822508
2c28826
e107a14
5bb58c3
fec703b
06c7e13
34b3934
17409bf
9b13e31
8413144
1406d1f
ba3e59a
82c2e79
a2aaf68
0f9f477
80cb20e
e4c68a4
43ceb27
4b6f568
1bff226
5220fb9
ba04a68
48d3d6b
1a45cc7
02f185c
df22fc2
27e7bd6
5ef0ac3
45860d7
decac66
45d65c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,89 @@ import "bootstrap"; | |
|
||
import "../styles/index.scss"; | ||
|
||
/******************************************************************************* | ||
* Theme interaction | ||
*/ | ||
|
||
var prefersDark = window.matchMedia("(prefers-color-scheme: dark)"); | ||
|
||
/** | ||
* set the the body theme to the one specified by the user browser | ||
* @param {event} e | ||
*/ | ||
function autoTheme(e) { | ||
document.documentElement.dataset.theme = prefersDark.matches | ||
? "dark" | ||
: "light"; | ||
} | ||
|
||
/** | ||
* Set the theme using the specified mode. | ||
* It can be one of ["auto", "dark", "light"] | ||
* @param {str} mode | ||
*/ | ||
function setTheme(mode) { | ||
if (mode !== "light" && mode !== "dark" && mode !== "auto") { | ||
console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the future, how do you envision new light and dark modes using new themes? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think no more than 2 themes at the time should be used in documentation. |
||
mode = "auto"; | ||
} | ||
|
||
// get the theme | ||
var colorScheme = prefersDark.matches ? "dark" : "light"; | ||
document.documentElement.dataset.mode = mode; | ||
var theme = mode == "auto" ? colorScheme : mode; | ||
document.documentElement.dataset.theme = theme; | ||
|
||
// save mode and theme | ||
localStorage.setItem("mode", mode); | ||
localStorage.setItem("theme", theme); | ||
console.log(`Changed to ${mode} mode using the ${theme} theme.`); | ||
|
||
// add a listener if set on auto | ||
prefersDark.onchange = mode == "auto" ? autoTheme : ""; | ||
} | ||
|
||
/** | ||
* Change the theme option order so that clicking on the btn is always a change | ||
* from "auto" | ||
*/ | ||
function cycleMode() { | ||
const defaultMode = document.documentElement.dataset.defaultMode || "auto"; | ||
const currentMode = localStorage.getItem("mode") || defaultMode; | ||
|
||
var loopArray = (arr, current) => { | ||
var nextPosition = arr.indexOf(current) + 1; | ||
if (nextPosition === arr.length) { | ||
nextPosition = 0; | ||
} | ||
return arr[nextPosition]; | ||
}; | ||
|
||
// make sure the next theme after auto is always a change | ||
var modeList = prefersDark.matches | ||
? ["auto", "light", "dark"] | ||
: ["auto", "dark", "light"]; | ||
var newMode = loopArray(modeList, currentMode); | ||
setTheme(newMode); | ||
} | ||
|
||
/** | ||
* add the theme listener on the btns of the navbar | ||
*/ | ||
function addModeListener() { | ||
// the theme was set a first time using the initial mini-script | ||
// running setMode will ensure the use of the dark mode if auto is selected | ||
setTheme(document.documentElement.dataset.mode); | ||
|
||
// Attach event handlers for toggling themes colors | ||
const btn = document.getElementById("theme-switch"); | ||
btn.addEventListener("click", cycleMode); | ||
} | ||
|
||
/******************************************************************************* | ||
* TOC interactivity | ||
*/ | ||
|
||
function addTOCInteractivity() { | ||
// TOC sidebar - add "active" class to parent list | ||
// | ||
|
@@ -31,6 +114,10 @@ function addTOCInteractivity() { | |
}); | ||
} | ||
|
||
/******************************************************************************* | ||
* Scroll | ||
*/ | ||
|
||
// Navigation sidebar scrolling to active page | ||
function scrollToActive() { | ||
var sidebar = document.querySelector("div.bd-sidebar"); | ||
|
@@ -73,5 +160,6 @@ function scrollToActive() { | |
|
||
// This is equivalent to the .ready() function as described in | ||
// https://api.jquery.com/ready/ | ||
$(addModeListener); | ||
$(scrollToActive); | ||
$(addTOCInteractivity); |
Uh oh!
There was an error while loading. Please reload this page.