Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bootstrap-dark-5

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bootstrap-dark-5 - npm Package Compare versions

Comparing version 0.1.1 to 0.1.2

dist/css/bootstrap-blackbox.css

210

dist/js/darkmode.js
"use strict";
class DarkMode {
constructor() {
this.isInDarkMode = false;
this.hasGDPRConsent = false;
this._hasGDPRConsent = false;
this.cookieExpiry = 365;
this.documentRoot = document.getElementsByTagName("html")[0];
document.addEventListener("DOMContentLoaded", function () {
if (document.readyState === 'loading') {
document.addEventListener("DOMContentLoaded", function () {
DarkMode.onDOMContentLoaded();
});
}
else {
DarkMode.onDOMContentLoaded();
});
}
}
saveValue(name, value, days = this.cookieExpiry) {
if (this.hasGDPRConsent) {
let exp;
if (days) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
exp = "; expires=" + date.toUTCString();
get inDarkMode() {
return DarkMode.getColorScheme() == DarkMode.VALUE_DARK;
}
set inDarkMode(val) {
this.setDarkMode(val, false);
}
get hasGDPRConsent() {
return this._hasGDPRConsent;
}
set hasGDPRConsent(val) {
this._hasGDPRConsent = val;
if (val) {
const prior = DarkMode.readCookie(DarkMode.DATA_KEY);
if (prior) {
DarkMode.saveCookie(DarkMode.DATA_KEY, "", -1);
localStorage.setItem(DarkMode.DATA_KEY, prior);
}
else {
exp = "";
}
else {
const prior = localStorage.getItem(DarkMode.DATA_KEY);
if (prior) {
localStorage.removeItem(DarkMode.DATA_KEY);
DarkMode.saveCookie(DarkMode.DATA_KEY, prior);
}
document.cookie = name + "=" + value + exp + "; SameSite=Strict; path=/";
}
}
get documentRoot() {
return document.getElementsByTagName("html")[0];
}
static saveCookie(name, value = "", days = 365) {
let exp = "";
if (days) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
exp = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + value + exp + "; SameSite=Strict; path=/";
}
saveValue(name, value, days = this.cookieExpiry) {
if (this.hasGDPRConsent) {
DarkMode.saveCookie(name, value, days);
}
else {

@@ -30,13 +62,16 @@ localStorage.setItem(name, value);

}
static readCookie(name) {
const n = name + "=";
const parts = document.cookie.split(";");
for (let i = 0; i < parts.length; i++) {
const part = parts[i].trim();
if (part.startsWith(n)) {
return part.substring(n.length);
}
}
return "";
}
readValue(name) {
if (this.hasGDPRConsent) {
const n = name + "=";
const parts = document.cookie.split(";");
for (let i = 0; i < parts.length; i++) {
const part = parts[i].trim();
if (part.startsWith(n)) {
return part.substring(n.length);
}
}
return "";
return DarkMode.readCookie(name);
}

@@ -57,16 +92,11 @@ else {

getSavedColorScheme() {
const val = this.readValue(DarkMode.DATA_NAME);
if (val) {
return val;
}
else {
return "";
}
const val = this.readValue(DarkMode.DATA_KEY);
return val ? val : "";
}
getPreferedColorScheme() {
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: " + DarkMode.DARK + ")").matches) {
return DarkMode.DARK;
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
return DarkMode.VALUE_DARK;
}
else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: " + DarkMode.LIGHT + ")").matches) {
return DarkMode.LIGHT;
else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches) {
return DarkMode.VALUE_LIGHT;
}

@@ -78,56 +108,89 @@ else {

setDarkMode(darkMode, doSave = true) {
if (!darkMode) {
this.documentRoot.classList.remove(DarkMode.DARK);
this.documentRoot.classList.add(DarkMode.LIGHT);
this.isInDarkMode = false;
if (doSave)
this.saveValue(DarkMode.DATA_NAME, DarkMode.LIGHT);
const nodeList = document.querySelectorAll("[data-" + DarkMode.DATA_SELECTOR + "]");
if (nodeList.length == 0) {
if (!darkMode) {
this.documentRoot.classList.remove(DarkMode.CLASS_NAME_DARK);
this.documentRoot.classList.add(DarkMode.CLASS_NAME_LIGHT);
}
else {
this.documentRoot.classList.remove(DarkMode.CLASS_NAME_LIGHT);
this.documentRoot.classList.add(DarkMode.CLASS_NAME_DARK);
}
}
else {
this.documentRoot.classList.remove(DarkMode.LIGHT);
this.documentRoot.classList.add(DarkMode.DARK);
this.isInDarkMode = true;
if (doSave)
this.saveValue(DarkMode.DATA_NAME, DarkMode.DARK);
for (let i = 0; i < nodeList.length; i++) {
nodeList[i].setAttribute("data-" + DarkMode.DATA_SELECTOR, darkMode ? DarkMode.VALUE_DARK : DarkMode.VALUE_LIGHT);
}
}
if (doSave)
this.saveValue(DarkMode.DATA_KEY, darkMode ? DarkMode.VALUE_DARK : DarkMode.VALUE_LIGHT);
}
toggleDarkMode(doSave = true) {
this.setDarkMode(!this.documentRoot.classList.contains(DarkMode.DARK), doSave);
let dm;
const node = document.querySelector("[data-" + DarkMode.DATA_SELECTOR + "]");
if (!node) {
dm = this.documentRoot.classList.contains(DarkMode.CLASS_NAME_DARK);
}
else {
dm = node.getAttribute("data-" + DarkMode.DATA_SELECTOR) == DarkMode.VALUE_DARK;
}
this.setDarkMode(!dm, doSave);
}
resetDarkMode() {
this.eraseValue(DarkMode.DATA_NAME);
const darkMode = this.getPreferedColorScheme();
if (darkMode) {
this.setDarkMode(darkMode == DarkMode.DARK, false);
this.eraseValue(DarkMode.DATA_KEY);
const dm = this.getPreferedColorScheme();
if (dm) {
this.setDarkMode(dm == DarkMode.VALUE_DARK, false);
}
else {
this.documentRoot.classList.remove(DarkMode.LIGHT);
this.documentRoot.classList.remove(DarkMode.DARK);
const nodeList = document.querySelectorAll("[data-" + DarkMode.DATA_SELECTOR + "]");
if (nodeList.length == 0) {
this.documentRoot.classList.remove(DarkMode.CLASS_NAME_LIGHT);
this.documentRoot.classList.remove(DarkMode.CLASS_NAME_DARK);
}
else {
for (let i = 0; i < nodeList.length; i++) {
nodeList[i].setAttribute("data-" + DarkMode.DATA_SELECTOR, "");
}
}
}
}
static getColorScheme() {
const node = document.querySelector("[data-" + DarkMode.DATA_SELECTOR + "]");
if (!node) {
if (darkmode.documentRoot.classList.contains(DarkMode.CLASS_NAME_DARK)) {
return DarkMode.VALUE_DARK;
}
else if (darkmode.documentRoot.classList.contains(DarkMode.CLASS_NAME_LIGHT)) {
return DarkMode.VALUE_LIGHT;
}
else {
return "";
}
}
else {
const data = node.getAttribute("data-" + DarkMode.DATA_SELECTOR);
return ((data == DarkMode.VALUE_DARK) || (data == DarkMode.VALUE_LIGHT)) ? data : "";
}
}
static updatePreferedColorSchemeEvent() {
let darkMode = darkmode.getSavedColorScheme();
if (!darkMode) {
darkMode = darkmode.getPreferedColorScheme();
if (darkMode)
darkmode.setDarkMode(darkMode == DarkMode.DARK, false);
let dm = darkmode.getSavedColorScheme();
if (!dm) {
dm = darkmode.getPreferedColorScheme();
if (dm)
darkmode.setDarkMode(dm == DarkMode.VALUE_DARK, false);
}
}
static onDOMContentLoaded() {
let pref = darkmode.readValue(DarkMode.DATA_NAME);
let pref = darkmode.readValue(DarkMode.DATA_KEY);
if (!pref) {
if (darkmode.documentRoot.classList.contains(DarkMode.DARK)) {
pref = DarkMode.DARK;
}
else if (darkmode.documentRoot.classList.contains(DarkMode.LIGHT)) {
pref = DarkMode.LIGHT;
}
else {
pref = DarkMode.getColorScheme();
if (!pref) {
pref = darkmode.getPreferedColorScheme();
}
}
darkmode.isInDarkMode = pref == DarkMode.DARK;
darkmode.setDarkMode(darkmode.isInDarkMode, false);
const dm = (pref == DarkMode.VALUE_DARK);
darkmode.setDarkMode(dm, false);
if (window.matchMedia) {
window.matchMedia("(prefers-color-scheme: " + DarkMode.DARK + ")").addEventListener("change", function () {
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
DarkMode.updatePreferedColorSchemeEvent();

@@ -138,6 +201,9 @@ });

}
DarkMode.DATA_NAME = "bs_prefers_color_scheme";
DarkMode.LIGHT = "light";
DarkMode.DARK = "dark";
DarkMode.DATA_KEY = "bs.prefers-color-scheme";
DarkMode.DATA_SELECTOR = "bs-color-scheme";
DarkMode.VALUE_LIGHT = "light";
DarkMode.VALUE_DARK = "dark";
DarkMode.CLASS_NAME_LIGHT = "light";
DarkMode.CLASS_NAME_DARK = "dark";
const darkmode = new DarkMode();
//# sourceMappingURL=darkmode.js.map

@@ -1,1 +0,1 @@

"use strict";class DarkMode{constructor(){this.isInDarkMode=!1,this.hasGDPRConsent=!1,this.cookieExpiry=365,this.documentRoot=document.getElementsByTagName("html")[0],document.addEventListener("DOMContentLoaded",(function(){DarkMode.onDOMContentLoaded()}))}saveValue(e,o,t=this.cookieExpiry){if(this.hasGDPRConsent){let a;if(t){const e=new Date;e.setTime(e.getTime()+24*t*60*60*1e3),a="; expires="+e.toUTCString()}else a="";document.cookie=e+"="+o+a+"; SameSite=Strict; path=/"}else localStorage.setItem(e,o)}readValue(e){if(this.hasGDPRConsent){const o=e+"=",t=document.cookie.split(";");for(let e=0;e<t.length;e++){const a=t[e].trim();if(a.startsWith(o))return a.substring(o.length)}return""}{const o=localStorage.getItem(e);return o||""}}eraseValue(e){this.hasGDPRConsent?this.saveValue(e,"",-1):localStorage.removeItem(e)}getSavedColorScheme(){const e=this.readValue(DarkMode.DATA_NAME);return e||""}getPreferedColorScheme(){return window.matchMedia&&window.matchMedia("(prefers-color-scheme: "+DarkMode.DARK+")").matches?DarkMode.DARK:window.matchMedia&&window.matchMedia("(prefers-color-scheme: "+DarkMode.LIGHT+")").matches?DarkMode.LIGHT:""}setDarkMode(e,o=!0){e?(this.documentRoot.classList.remove(DarkMode.LIGHT),this.documentRoot.classList.add(DarkMode.DARK),this.isInDarkMode=!0,o&&this.saveValue(DarkMode.DATA_NAME,DarkMode.DARK)):(this.documentRoot.classList.remove(DarkMode.DARK),this.documentRoot.classList.add(DarkMode.LIGHT),this.isInDarkMode=!1,o&&this.saveValue(DarkMode.DATA_NAME,DarkMode.LIGHT))}toggleDarkMode(e=!0){this.setDarkMode(!this.documentRoot.classList.contains(DarkMode.DARK),e)}resetDarkMode(){this.eraseValue(DarkMode.DATA_NAME);const e=this.getPreferedColorScheme();e?this.setDarkMode(e==DarkMode.DARK,!1):(this.documentRoot.classList.remove(DarkMode.LIGHT),this.documentRoot.classList.remove(DarkMode.DARK))}static updatePreferedColorSchemeEvent(){let e=darkmode.getSavedColorScheme();e||(e=darkmode.getPreferedColorScheme(),e&&darkmode.setDarkMode(e==DarkMode.DARK,!1))}static onDOMContentLoaded(){let e=darkmode.readValue(DarkMode.DATA_NAME);e||(e=darkmode.documentRoot.classList.contains(DarkMode.DARK)?DarkMode.DARK:darkmode.documentRoot.classList.contains(DarkMode.LIGHT)?DarkMode.LIGHT:darkmode.getPreferedColorScheme()),darkmode.isInDarkMode=e==DarkMode.DARK,darkmode.setDarkMode(darkmode.isInDarkMode,!1),window.matchMedia&&window.matchMedia("(prefers-color-scheme: "+DarkMode.DARK+")").addEventListener("change",(function(){DarkMode.updatePreferedColorSchemeEvent()}))}}DarkMode.DATA_NAME="bs_prefers_color_scheme",DarkMode.LIGHT="light",DarkMode.DARK="dark";const darkmode=new DarkMode;
"use strict";class DarkMode{constructor(){this._hasGDPRConsent=!1,this.cookieExpiry=365,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(function(){DarkMode.onDOMContentLoaded()})):DarkMode.onDOMContentLoaded()}get inDarkMode(){return DarkMode.getColorScheme()==DarkMode.VALUE_DARK}set inDarkMode(e){this.setDarkMode(e,!1)}get hasGDPRConsent(){return this._hasGDPRConsent}set hasGDPRConsent(e){if(this._hasGDPRConsent=e,e){const e=DarkMode.readCookie(DarkMode.DATA_KEY);e&&(DarkMode.saveCookie(DarkMode.DATA_KEY,"",-1),localStorage.setItem(DarkMode.DATA_KEY,e))}else{const e=localStorage.getItem(DarkMode.DATA_KEY);e&&(localStorage.removeItem(DarkMode.DATA_KEY),DarkMode.saveCookie(DarkMode.DATA_KEY,e))}}get documentRoot(){return document.getElementsByTagName("html")[0]}static saveCookie(e,o="",t=365){let a="";if(t){const e=new Date;e.setTime(e.getTime()+24*t*60*60*1e3),a="; expires="+e.toUTCString()}document.cookie=e+"="+o+a+"; SameSite=Strict; path=/"}saveValue(e,o,t=this.cookieExpiry){this.hasGDPRConsent?DarkMode.saveCookie(e,o,t):localStorage.setItem(e,o)}static readCookie(e){const o=e+"=",t=document.cookie.split(";");for(let e=0;e<t.length;e++){const a=t[e].trim();if(a.startsWith(o))return a.substring(o.length)}return""}readValue(e){if(this.hasGDPRConsent)return DarkMode.readCookie(e);{const o=localStorage.getItem(e);return o||""}}eraseValue(e){this.hasGDPRConsent?this.saveValue(e,"",-1):localStorage.removeItem(e)}getSavedColorScheme(){const e=this.readValue(DarkMode.DATA_KEY);return e||""}getPreferedColorScheme(){return window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?DarkMode.VALUE_DARK:window.matchMedia&&window.matchMedia("(prefers-color-scheme: light)").matches?DarkMode.VALUE_LIGHT:""}setDarkMode(e,o=!0){const t=document.querySelectorAll("[data-"+DarkMode.DATA_SELECTOR+"]");if(0==t.length)e?(this.documentRoot.classList.remove(DarkMode.CLASS_NAME_LIGHT),this.documentRoot.classList.add(DarkMode.CLASS_NAME_DARK)):(this.documentRoot.classList.remove(DarkMode.CLASS_NAME_DARK),this.documentRoot.classList.add(DarkMode.CLASS_NAME_LIGHT));else for(let o=0;o<t.length;o++)t[o].setAttribute("data-"+DarkMode.DATA_SELECTOR,e?DarkMode.VALUE_DARK:DarkMode.VALUE_LIGHT);o&&this.saveValue(DarkMode.DATA_KEY,e?DarkMode.VALUE_DARK:DarkMode.VALUE_LIGHT)}toggleDarkMode(e=!0){let o;const t=document.querySelector("[data-"+DarkMode.DATA_SELECTOR+"]");o=t?t.getAttribute("data-"+DarkMode.DATA_SELECTOR)==DarkMode.VALUE_DARK:this.documentRoot.classList.contains(DarkMode.CLASS_NAME_DARK),this.setDarkMode(!o,e)}resetDarkMode(){this.eraseValue(DarkMode.DATA_KEY);const e=this.getPreferedColorScheme();if(e)this.setDarkMode(e==DarkMode.VALUE_DARK,!1);else{const e=document.querySelectorAll("[data-"+DarkMode.DATA_SELECTOR+"]");if(0==e.length)this.documentRoot.classList.remove(DarkMode.CLASS_NAME_LIGHT),this.documentRoot.classList.remove(DarkMode.CLASS_NAME_DARK);else for(let o=0;o<e.length;o++)e[o].setAttribute("data-"+DarkMode.DATA_SELECTOR,"")}}static getColorScheme(){const e=document.querySelector("[data-"+DarkMode.DATA_SELECTOR+"]");if(e){const o=e.getAttribute("data-"+DarkMode.DATA_SELECTOR);return o==DarkMode.VALUE_DARK||o==DarkMode.VALUE_LIGHT?o:""}return darkmode.documentRoot.classList.contains(DarkMode.CLASS_NAME_DARK)?DarkMode.VALUE_DARK:darkmode.documentRoot.classList.contains(DarkMode.CLASS_NAME_LIGHT)?DarkMode.VALUE_LIGHT:""}static updatePreferedColorSchemeEvent(){let e=darkmode.getSavedColorScheme();e||(e=darkmode.getPreferedColorScheme(),e&&darkmode.setDarkMode(e==DarkMode.VALUE_DARK,!1))}static onDOMContentLoaded(){let e=darkmode.readValue(DarkMode.DATA_KEY);e||(e=DarkMode.getColorScheme(),e||(e=darkmode.getPreferedColorScheme()));const o=e==DarkMode.VALUE_DARK;darkmode.setDarkMode(o,!1),window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",(function(){DarkMode.updatePreferedColorSchemeEvent()}))}}DarkMode.DATA_KEY="bs.prefers-color-scheme",DarkMode.DATA_SELECTOR="bs-color-scheme",DarkMode.VALUE_LIGHT="light",DarkMode.VALUE_DARK="dark",DarkMode.CLASS_NAME_LIGHT="light",DarkMode.CLASS_NAME_DARK="dark";const darkmode=new DarkMode;
/**
* `darkmode.js`, the JavaScript module.
* *boostrap-dark-5* `darkmode.js` -- the JavaScript module.
*
* Use this JS file, and it's `darkmode` object, in your HTML to automatically capture `prefers-color-scheme` media query
* events and also initialize the document root (`<HTML>` tag) with the user prefered color scheme.
* ***class*** **DarkMode**
*
* Use this JS file, and its `darkmode` object, in your HTML to automatically capture `prefers-color-scheme` media query
* events and also initialize tags with the `data-bs-color-scheme` attribute, or the document root (`<HTML>` tag) with the
* user preferred color scheme.
*
* The `darkmode` object can also be used to drive a dark mode toggle event, with optional persistance
* storage in either a cookie (if GDPR consent is given) or the browsers `localStorage` object.
* @module bootstrap-dark-5
* @author Vino Rodrigues
*
* The module can be loaded into a html page using a standard script command.
* ```html
* <script src="darkmode.js"></script>
* ```
*
* This will create a variable `darkmode` that is an instance of the DarkMode class.
*
* Once the DOM is loaded the script will then look for any html tag with a `data-bs-color-scheme` attribute, and, if found
* will use these tags to populate the current mode. If this data attribute is not found then the script will use the document
* root (`<HTML>` tag) with the class `dark` or `light`.
*
* For example, the `bootstrap-blackbox.css` variant requires the `<HTML>` to be initialized:
*
* ```html
* <!doctype html>
* <html lang="en" data-bs-color-scheme>
* <head>
* <!-- ... -->
* ```
* You can also pre-initialize the mode by populating the data attribute:
*
* ```html
* <html lang="en" data-bs-color-scheme="dark">
* ```
*
* @module DarkMode
* @_author Vino Rodrigues
*/
/**
* @class
* @classdesc The `darkmode` object is an instace of the class `DarkMode`
*/
class DarkMode {
/** ***const*** -- Name of the cookie or localStorage->name when saving */
static readonly DATA_NAME = "bs_prefers_color_scheme"
static readonly DATA_KEY = "bs.prefers-color-scheme"
/** ***const*** -- String used to identify light mode (do not change), @see https://www.w3.org/TR/mediaqueries-5/#prefers-color-scheme */
static readonly LIGHT = "light"
//** ***const*** -- Data selector, when present in HTML will populate with `dark` or `light` as appropriate */
static readonly DATA_SELECTOR = "bs-color-scheme";
/** ***const*** -- String used to identify dark mode (do not change), @see https://www.w3.org/TR/mediaqueries-5/#prefers-color-scheme */
static readonly DARK = "dark"
/** ***const*** -- String used to identify light mode *(do not change)*, @see https://www.w3.org/TR/mediaqueries-5/#prefers-color-scheme */
static readonly VALUE_LIGHT = "light"
/** ***const*** -- String used to identify dark mode *(do not change)*, @see https://www.w3.org/TR/mediaqueries-5/#prefers-color-scheme */
static readonly VALUE_DARK = "dark"
/** ***const*** -- String used to identify light mode as a class in the `<HTML>` tag */
static readonly CLASS_NAME_LIGHT = "light"
/** ***const*** -- String used to identify dark mode as a class in the `<HTML>` tag */
static readonly CLASS_NAME_DARK = "dark"
/**
* Used to store the current state, `true` when in dark mode, `false` when in light mode
* @type {bool}
* ***property***
*
* Used to get the current state, `true` when in dark mode, `false` when in light mode or when mode not set
*
* Can also be used to set the current mode *(with no persistance saving)*
*
* @example <caption>Get if page is in "Dark" mode</caption>
* var myVal = darkmode.inDarkMode;
*
* @example <caption>Set the page to the "Dark" mode</caption>
* darkmode.inDarkMode = true;
*
* @public
* @type {boolean}
*/
isInDarkMode = false;
get inDarkMode() {
return DarkMode.getColorScheme() == DarkMode.VALUE_DARK
}
set inDarkMode(val: boolean) {
this.setDarkMode(val, false)
}
/** @private */
private _hasGDPRConsent = false
/**
* Variable to store GDPR Consent
* Variable to store GDPR Consent. This setting drives the persistance mechanism.
*
* Used in {@link #saveValue} to determin if a cookie or the `localStorage` object should be used.
* * Set to `true` when GDPR Consent has been given to enable storage to cookie *(useful in Server-Side knowlage of user preference)*
* Used in {@link #saveValue} to determine if a cookie or the `localStorage` object should be used.
* * Set to `true` when GDPR Consent has been given to enable storage to cookie *(useful in Server-Side knowledge of user preference)*
* * The setter takes care of swapping the cookie and localStorage if appropriate
* * Default is `false`, thus storage will use the browsers localStorage object *(Note: No expiry is set)*
*
* @example <caption>Set once GDPR consent is given by the user</caption>
* darkmode.hasGDPRConsent = true;
*/
hasGDPRConsent = false;
get hasGDPRConsent() {
return this._hasGDPRConsent
}
set hasGDPRConsent(val: boolean) {
this._hasGDPRConsent = val
if (val) {
// delete cookie if it exists
const prior = DarkMode.readCookie(DarkMode.DATA_KEY)
if (prior) {
DarkMode.saveCookie(DarkMode.DATA_KEY, "", -1)
localStorage.setItem(DarkMode.DATA_KEY, prior)
}
} else {
// delete localStorage if it exists
const prior = localStorage.getItem(DarkMode.DATA_KEY)
if (prior) {
localStorage.removeItem(DarkMode.DATA_KEY)
DarkMode.saveCookie(DarkMode.DATA_KEY, prior)
}
}
}
/** Expiry time in days when saving and GDPR consent is give */

@@ -48,15 +127,40 @@ cookieExpiry = 365;

*/
documentRoot: HTMLHtmlElement = document.getElementsByTagName("html")[0]
get documentRoot(): HTMLHtmlElement {
return document.getElementsByTagName("html")[0]
}
/**
* @constructor
* The constructor intializes the `darkmode` object (that should be used as a singleton).
* The constructor initializes the `darkmode` object (that should be used as a singleton).
*/
constructor() {
document.addEventListener("DOMContentLoaded", function() {
if (document.readyState === 'loading') {
document.addEventListener("DOMContentLoaded", function() {
DarkMode.onDOMContentLoaded()
})
} else {
DarkMode.onDOMContentLoaded()
})
}
}
/**
* Writes a cookie, assumes SameSite = Strict & path = /
*
* @private
* @param name -- Name of the cookie
* @param value -- Value to be saved
* @param days -- Number of days to expire the cookie
* @returns {void}
*/
static saveCookie(name: string, value = "", days = 365): void {
let exp = ""
if (days) {
const date = new Date()
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000))
exp = "; expires=" + date.toUTCString()
}
document.cookie = name + "=" + value + exp + "; SameSite=Strict; path=/"
}
/**
* Save the current color-scheme mode

@@ -66,17 +170,9 @@ *

* @param {string} value -- Should be one of `light` or `dark`
* @param {number} days -- Number of days to expire the cookie when the cookie is used
* @param {number} days -- Number of days to expire the cookie when the cookie is used, ignored for `localStorage`
* @returns {void}
*/
saveValue(name: string, value: string, days = this.cookieExpiry): void {
private saveValue(name: string, value: string, days = this.cookieExpiry): void {
if (this.hasGDPRConsent) {
// use cookies
let exp
if (days) {
const date = new Date()
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000))
exp = "; expires=" + date.toUTCString()
} else {
exp = ""
}
document.cookie = name + "=" + value + exp + "; SameSite=Strict; path=/"
DarkMode.saveCookie(name, value, days)
} else {

@@ -90,23 +186,30 @@ // use local storage

/**
* Reads a cookie
* @private
*/
static readCookie(name: string): string {
const n = name + "="
const parts = document.cookie.split(";")
for(let i=0; i < parts.length; i++) {
const part = parts[i].trim()
if (part.startsWith(n)) {
// found it
return part.substring(n.length)
}
}
return ""
}
/**
* Retrieves the color-scheme last saved
*
* NOTE: is dependant on {@link #hasGDPRConsent}
* **NOTE:** is dependant on {@link #hasGDPRConsent}
*
* @param {string} name -- Name of the cookie or localStorage->name
* @returns {string} -- The saved value, iether `light` or `dark`, or an empty string if not saved prior
* @returns {string} -- The saved value, either `light` or `dark`, or an empty string if not saved prior
*/
readValue(name: string): string {
if (this.hasGDPRConsent) {
const n = name + "="
const parts = document.cookie.split(";")
for(let i=0; i < parts.length; i++) {
const part = parts[i].trim()
if (part.startsWith(n)) {
// found it
return part.substring(n.length)
}
}
return ""
return DarkMode.readCookie(name)
} else {

@@ -121,3 +224,3 @@ const ret = localStorage.getItem(name)

*
* NOTE: is dependant on {@link #hasGDPRConsent}
* **NOTE:** is dependant on {@link #hasGDPRConsent}
*

@@ -138,13 +241,9 @@ * @param {string} name

*
* (This value is set prior via the {@link #setDarkMode}) function.)
* *(This value is set prior via the {@link #setDarkMode}) function.)*
*
* @returns {string} -- The current value, iether `light` or `dark`, or an empty string if not saved prior
* @returns {string} -- The current value, either `light` or `dark`, or an empty string if not saved prior
*/
getSavedColorScheme(): string {
const val = this.readValue(DarkMode.DATA_NAME)
if (val) {
return val
} else {
return ""
}
const val = this.readValue(DarkMode.DATA_KEY)
return val ? val : ""
}

@@ -155,11 +254,11 @@

*
* (This value is set prior via the {@link #setDarkMode}) function.)
* *(This value is set prior via the {@link #setDarkMode}) function.)*
*
* @returns {string} -- The current value, iether `light` or `dark`, or an empty string if the media query is not supported
* @returns {string} -- The current value, either `light` or `dark`, or an empty string if the media query is not supported
*/
getPreferedColorScheme(): string {
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: "+DarkMode.DARK+")").matches) {
return DarkMode.DARK
} else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: "+DarkMode.LIGHT+")").matches) {
return DarkMode.LIGHT
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
return DarkMode.VALUE_DARK
} else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches) {
return DarkMode.VALUE_LIGHT
} else {

@@ -173,40 +272,96 @@ return ""

*
* @example
* `<html lang="en" class="dark">`
* @example
* `<html lang="en" class="light">`
* **Note:** This function will modify your document root element, i.e. the `<HTML>` tag
*
* @param {bool} darkMode -- `true` for "dark", `false` for 'light'
* @param {bool} doSave -- If `true`, then will also call {@link #saveValue} to save that state
* Default behavior when setting dark mode `true`
*
* ```html
* <html lang="en" class="other-classes dark">
* <!-- Note: the "light" class is removed -->
* ```
*
* Default behavior when setting dark mode `false`
*
* ```html
* <html lang="en" class="other-classes light">
* <!-- Note: the "dark" class is removed -->
* ```
*
* Behavior when setting dark mode `true`, and `dataSelector = "data-bs-color-scheme"`
*
* ```html
* <html lang="en" data-bs-color-scheme="dark">
* ```
*
* Behavior when setting dark mode `false`, and `dataSelector = "data-bs-color-scheme"`
*
* ```html
* <html lang="en" data-bs-color-scheme="light">
* ```
*
* @example <caption>Set the color scheme to ***dark***, saving the state to the persistance mechanism</caption>
* document.querySelector("#darkmode-on-button").onclick = function(e){
* darkmode.setDarkMode(true); // save=true is default
* }
*
* @example <caption>Set the color scheme to ***light***, but not saving the state</caption>
* document.querySelector("#darkmode-off-button-no-save").onclick = function(e){
* darkmode.setDarkMode(false, false);
* }
*
* @param {boolean} darkMode -- `true` for "dark", `false` for 'light'
* @param {boolean} doSave -- If `true`, then will also call {@link #saveValue} to save that state
* @returns {void} -- Nothing, assumes saved
*/
setDarkMode(darkMode: boolean, doSave = true): void {
if (!darkMode) {
// DarkMode.LIGHT
this.documentRoot.classList.remove(DarkMode.DARK)
this.documentRoot.classList.add(DarkMode.LIGHT)
this.isInDarkMode = false
if (doSave) this.saveValue(DarkMode.DATA_NAME, DarkMode.LIGHT)
const nodeList = document.querySelectorAll("[data-"+DarkMode.DATA_SELECTOR+"]")
if (nodeList.length == 0) {
if (!darkMode) {
// light
this.documentRoot.classList.remove(DarkMode.CLASS_NAME_DARK)
this.documentRoot.classList.add(DarkMode.CLASS_NAME_LIGHT)
} else {
// dark
this.documentRoot.classList.remove(DarkMode.CLASS_NAME_LIGHT)
this.documentRoot.classList.add(DarkMode.CLASS_NAME_DARK)
}
} else {
// dark
this.documentRoot.classList.remove(DarkMode.LIGHT)
this.documentRoot.classList.add(DarkMode.DARK)
this.isInDarkMode = true
if (doSave) this.saveValue(DarkMode.DATA_NAME, DarkMode.DARK)
for (let i = 0; i < nodeList.length; i++) {
nodeList[i].setAttribute("data-"+DarkMode.DATA_SELECTOR, darkMode ? DarkMode.VALUE_DARK : DarkMode.VALUE_LIGHT)
}
}
if (doSave) this.saveValue(DarkMode.DATA_KEY, darkMode ? DarkMode.VALUE_DARK : DarkMode.VALUE_LIGHT)
}
/**
* Toggles the color-scheme in the `<HTML>` tag as a class called either `light` or `dark`
* Toggles the color scheme in the `<HTML>` tag as a class called either `light` or `dark`
* based on the inverse of it's prior state.
*
* See {@link #setDarkMode}
* When {@link #dataSelector} is set, this is set in the given data selector as the data value.
*
* *(See {@link #setDarkMode})*
*
* @example <caption>Bind an UI Element `click` event to toggle dark mode</caption>
* document.querySelector("#darkmode-button").onclick = function(e){
* darkmode.toggleDarkMode();
* }
*
* @returns {void} - Nothing, assumes success
*/
toggleDarkMode(doSave = true): void {
this.setDarkMode( !this.documentRoot.classList.contains(DarkMode.DARK), doSave )
let dm
const node = document.querySelector("[data-"+DarkMode.DATA_SELECTOR+"]") // only get first one
if (!node) {
dm = this.documentRoot.classList.contains(DarkMode.CLASS_NAME_DARK)
} else {
dm = node.getAttribute("data-"+DarkMode.DATA_SELECTOR) == DarkMode.VALUE_DARK
}
this.setDarkMode( !dm, doSave )
}
/**
* Clears the persistance state of the module and resets the document to the default mode.
*
* Calls {@link #eraseValue} to erase any saved value, and then

@@ -216,13 +371,25 @@ * calls {@link #getPreferedColorScheme} to retrieve the `prefers-color-scheme` media query,

*
* @example <caption>Bind a reset UI Element `click` event to reset the dark mode </caption>
* document.querySelector("#darkmode-forget").onclick = function(e){
* darkmode.resetDarkMode();
* }
*
* @returns {void} - Nothing, no error handling is performed.
*/
resetDarkMode(): void {
this.eraseValue(DarkMode.DATA_NAME)
const darkMode = this.getPreferedColorScheme()
if (darkMode) {
this.setDarkMode( darkMode == DarkMode.DARK, false )
this.eraseValue(DarkMode.DATA_KEY)
const dm = this.getPreferedColorScheme()
if (dm) {
this.setDarkMode( dm == DarkMode.VALUE_DARK, false )
} else {
// make good when `prefers-color-scheme` not supported
this.documentRoot.classList.remove(DarkMode.LIGHT)
this.documentRoot.classList.remove(DarkMode.DARK)
const nodeList = document.querySelectorAll("[data-"+DarkMode.DATA_SELECTOR+"]")
if (nodeList.length == 0) {
this.documentRoot.classList.remove(DarkMode.CLASS_NAME_LIGHT)
this.documentRoot.classList.remove(DarkMode.CLASS_NAME_DARK)
} else {
for (let i = 0; i < nodeList.length; i++) {
nodeList[i].setAttribute("data-"+DarkMode.DATA_SELECTOR, "")
}
}
}

@@ -232,6 +399,28 @@ }

/**
* Gets the current color-scheme from the document `<HTML>` tag
*
* @returns {string} -- The current value, either `light` or `dark`, or an empty string if not present
*/
static getColorScheme(): string {
const node = document.querySelector("[data-"+DarkMode.DATA_SELECTOR+"]")
if (!node) {
if (darkmode.documentRoot.classList.contains(DarkMode.CLASS_NAME_DARK)) {
return DarkMode.VALUE_DARK
} else if (darkmode.documentRoot.classList.contains(DarkMode.CLASS_NAME_LIGHT)) {
return DarkMode.VALUE_LIGHT
} else {
return ""
}
} else {
const data = node.getAttribute("data-"+DarkMode.DATA_SELECTOR)
// exact match only
return ((data == DarkMode.VALUE_DARK) || (data == DarkMode.VALUE_LIGHT)) ? data : ""
}
}
/**
* ***static*** -- function called by the media query on change event.
*
* First retrieves any saved value, and if present ignores the event, but
* if not set then triggers the {@link #setDarkMode} function to chnage the current mode.
* First retrieves any persistent/saved value, and if present ignores the event, but
* if not set then triggers the {@link #setDarkMode} function to change the current mode.
*

@@ -241,6 +430,6 @@ * @returns {void} -- Nothing, assumes success

static updatePreferedColorSchemeEvent(): void {
let darkMode = darkmode.getSavedColorScheme()
if (!darkMode) {
darkMode = darkmode.getPreferedColorScheme()
if (darkMode) darkmode.setDarkMode( darkMode == DarkMode.DARK, false )
let dm = darkmode.getSavedColorScheme()
if (!dm) {
dm = darkmode.getPreferedColorScheme()
if (dm) darkmode.setDarkMode( dm == DarkMode.VALUE_DARK, false )
}

@@ -258,15 +447,14 @@ }

*
* Followd by setting up the media query on change event
* Followed by setting up the media query on change event
*
* ***Warning:*** This function is automatically called when loading this module.
*
* @returns {void}
*/
static onDOMContentLoaded(): void {
let pref = darkmode.readValue(DarkMode.DATA_NAME)
let pref = darkmode.readValue(DarkMode.DATA_KEY)
if (!pref) {
// user has not set pref. so get from `<HTML>` tag incase developer has set pref.
if (darkmode.documentRoot.classList.contains(DarkMode.DARK)) {
pref = DarkMode.DARK
} else if (darkmode.documentRoot.classList.contains(DarkMode.LIGHT)) {
pref = DarkMode.LIGHT
} else {
// user has not set pref. so get from `<HTML>` tag in case developer has set pref.
pref = DarkMode.getColorScheme()
if (!pref) {
// when all else fails, get pref. from OS/browser

@@ -276,10 +464,10 @@ pref = darkmode.getPreferedColorScheme()

}
darkmode.isInDarkMode = pref == DarkMode.DARK
const dm = (pref == DarkMode.VALUE_DARK)
// initalize the `HTML` tag
darkmode.setDarkMode(darkmode.isInDarkMode, false)
// initialize the `HTML` tag
darkmode.setDarkMode(dm, false)
// update every time it changes
if (window.matchMedia) {
window.matchMedia("(prefers-color-scheme: "+DarkMode.DARK+")").addEventListener( "change", function() {
window.matchMedia("(prefers-color-scheme: dark)").addEventListener( "change", function() {
DarkMode.updatePreferedColorSchemeEvent()

@@ -286,0 +474,0 @@ })

{
"name": "bootstrap-dark-5",
"version": "0.1.1",
"version": "0.1.2",
"description": "The Ancillary Guide to Dark Mode and Bootstrap 5 - A continuation of the v4 Dark Mode POC",

@@ -19,7 +19,2 @@ "main": "",

"css-minify": "npm-run-all --parallel css-minify-*",
"DISABLED_css-minify-main": "cleancss -O1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap.min.css dist/css/bootstrap.css",
"DISABLED_css-minify-night": "cleancss -O1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap-night.min.css dist/css/bootstrap-night.css",
"DISABLED_css-minify-nightfall": "cleancss -O1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap-nightfall.min.css dist/css/bootstrap-nightfall.css",
"DISABLED_css-minify-nightshade": "cleancss -O1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap-nightshade.min.css dist/css/bootstrap-nightshade.css",
"DISABLED_css-minify-dark": "cleancss -O1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap-dark.min.css dist/css/bootstrap-dark.css",
"css-minify-main": "cleancss -O1 --format breakWith=lf --output dist/css/bootstrap.min.css dist/css/bootstrap.css",

@@ -30,2 +25,4 @@ "css-minify-night": "cleancss -O1 --format breakWith=lf --output dist/css/bootstrap-night.min.css dist/css/bootstrap-night.css",

"css-minify-dark": "cleancss -O1 --format breakWith=lf --output dist/css/bootstrap-dark.min.css dist/css/bootstrap-dark.css",
"css-minify-unlit": "cleancss -O1 --format breakWith=lf --output dist/css/bootstrap-unlit.min.css dist/css/bootstrap-unlit.css",
"css-minify-blackbox": "cleancss -O1 --format breakWith=lf --output dist/css/bootstrap-blackbox.min.css dist/css/bootstrap-blackbox.css",
"css-lint": "npm-run-all --continue-on-error --parallel css-lint-*",

@@ -37,3 +34,2 @@ "css-lint-stylelint": "stylelint \"**/*.scss\" --cache --cache-location .cache/.stylelintcache --rd",

"js-compile": "tsc -p build",
"DISABLED_js-minify": "terser -c -m -o ./dist/js/darkmode.min.js ./dist/js/darkmode.js --source-map \"content='./dist/js/darkmode.js.map'\"",
"js-minify": "terser -c -m -o ./dist/js/darkmode.min.js ./dist/js/darkmode.js",

@@ -46,6 +42,12 @@ "js-lint": "eslint --cache --cache-location .cache/.eslintcache --report-unused-disable-directives . --ext .ts",

"watch-root": "nodemon --watch . --ext html --exec \"browser-sync reload\"",
"docs": "npm-run-all --parallel docs-js-*",
"docs-js-darkmode": "documentation build js/src/darkmode.ts --parse-extension ts -f md -o docs/darkmode.js.md --markdown-toc true --shallow false",
"map-dark-vars": "npm-run-all --parallel map-dark-vars-*",
"docs": "npm-run-all --parallel docs-js-*",
"docs-js-darkmode": "documentation build js/src/darkmode.ts --parse-extension ts -f md -o docs/darkmode.js.md --markdown-toc false --shallow true",
"map-dark-vars-alt-to-core": "node ./build/make-dark-map.js ./build/dark-map-list.json '-alt' '' > ./scss/dark/_variables-map-alt-to-core.scss"
"map-dark-vars-alt-to-core": "node ./build/make-dark-map.js ./build/dark-map-list.json '-alt' '' > ./scss/dark/_variables-map-alt-to-core.scss",
"map-dark-vars-core-to-temp": "node ./build/make-dark-map.js ./build/dark-map-list.json '' '-temp-dnu' > ./scss/dark/_variables-map-core-to-temp.scss",
"map-dark-vars-temp-to-alt": "node ./build/make-dark-map.js ./build/dark-map-list.json '-temp-dnu' '-alt' > ./scss/dark/_variables-map-temp-to-alt.scss",
"bump": "echo \"Use bump-major, bump-minor, bump-patch\" && echo \"\" && exit 0",
"bump-major": "npm version major",
"bump-minor": "npm version minor",
"bump-patch": "npm version patch"
},

@@ -112,4 +114,4 @@ "author": "Vino Rodrigues",

"dependencies": {
"bootstrap": "5.0.0-beta1"
"bootstrap": "5.0.0-beta2"
}
}

@@ -10,6 +10,8 @@ # The Ancillary Guide to Dark Mode and Bootstrap 5

> <u style="text-decoration:none;color:red">***NOTE:***</u> This is a 'Work In Progress' and is specifically based on Bootstrap 5 - Beta 1 - https://github.com/twbs/bootstrap/tree/v5.0.0-beta1
> ![NOTE:](https://img.shields.io/badge/NOTE%3A-069?style=for-the-badge) This is a 'Work In Progress' and is specifically based on Bootstrap 5 - Beta 2 - https://github.com/twbs/bootstrap/tree/v5.0.0-beta2
> <u style="text-decoration:none;color:red">***NOTE:***</u> The recomendation is to ***not*** use this in a production environment.
> ![NOTE:](https://img.shields.io/badge/NOTE%3A-069?style=for-the-badge) The recommendation is to ***not*** use this in a production environment.
> ![NOTE: on Bootstrap core](https://img.shields.io/badge/NOTE-on%20Bootstrap%20core%3A-069?style=for-the-badge) I have tried to merge this project in to Bootstrap core *(see [pull request #32936](https://github.com/twbs/bootstrap/pull/32936))*, but while that's being considered I will continue to work on this project. If you wish this to be added to Bootstrap core then let the authors know by adding a comment to the [pull request](https://github.com/twbs/bootstrap/pull/32936).
## About

@@ -23,18 +25,35 @@

The code only compiles the [Method 1](https://github.com/vinorodrigues/bootstrap-dark/blob/master/README.md#method-1), [Method 3](https://github.com/vinorodrigues/bootstrap-dark/blob/master/README.md#method-3) and [Method 4](https://github.com/vinorodrigues/bootstrap-dark/blob/master/README.md#method-4) variants (for BS5) of the topics discussed in the original body of work.
The code compiles the four methods *(and variants - **six in total**)* of the original body of work, but compiled for and sourcing **Bootstrap 5**. These are:
i.e.:
* [Method 1](https://github.com/vinorodrigues/bootstrap-dark/blob/master/README.md#method-1) <small>*(link to original)*</small>
* `bootstrap-night`,
* [Quick Start Guide](docs/bootstrap-night.md)
* `bootstrap-nightshade`,
* [Quick Start Guide](docs/bootstrap-nightshade.md)
* [`darkmode.js` Reference](docs/darkmode.js.md)
* `bootstrap-dark`.
* [Quick Start Guide](docs/bootstrap-dark.md)
* **`bootstrap-night`**: This is simply a dark bootstrap theme. I can however be used with the Bootstrap core CSS to deliver a 2-file dark mode functionality.
* [Method 2](https://github.com/vinorodrigues/bootstrap-dark/blob/master/README.md#method-2) <small>*(link to original)*</small>
* **`bootstrap-nightfall`**: This is simply the "color only" CSS of all the components of Bootstrap core CSS, but dark, and is intended to be used as a add-on. It can however with a simple media query drive automatic dark mode switching.
* [Method 3](https://github.com/vinorodrigues/bootstrap-dark/blob/master/README.md#method-3) <small>*(link to original)*</small>
* **`bootstrap-nightshade`**: This a modification of the Bootstrap core and adds dark color CSS for all the components, but dark, nested in a `html.dark` class wrapper. By itself it cannot offer dark mode switching, but add the included `darkmode.js` library and you have an interactive dark mode switching variant of Bootstrap with built in ***"toggle"*** button support.
* **`bootstrap-blackbox`**: ![New](https://img.shields.io/badge/NEW-red) This variant is essentially the same as the "nightshade" variant, but instead of using a HTML tag class, it uses a HTML tag data attribute; `data-bs-color-scheme`. The same `darkmode.js` library drives this one, all you need to do is add the data attribute to your HTML tag.
* [Method 4](https://github.com/vinorodrigues/bootstrap-dark/blob/master/README.md#method-4) <small>*(link to original)*</small>
* **`bootstrap-dark`**: This is the recommended method; one CSS with both light and dark themes, toggle-able only with the OS or browser `prefers-color-scheme` media query.
* **`bootstrap-unlit`**: This variant is essentially the same as the "dark" variant, but with "dark" scheme as the primary/fallback and "light" as optioned in color scheme.
## Get started
| **1.** `bootstrap-night` | **2.** `bootstrap-nightfall` | **3.** `bootstrap-nightshade` | **3b.** `bootstrap-blackbox` | **4.** `bootstrap-dark` | **4b.** `bootstrap-unlit` |
|:---:|:---:|:---:|:---:|:---:|:---:|
| [Quick Start Guide](docs/bootstrap-night.md) | [Quick Start Guide](docs/bootstrap-nightfall.md) | [Quick Start Guide](docs/bootstrap-nightshade.md) | [Quick Start Guide](docs/bootstrap-blackbox.md) | [Quick Start Guide](docs/bootstrap-dark.md) | [Quick Start Guide](docs/bootstrap-unlit.md) |
| | | [`darkmode.js` Reference](docs/darkmode.js.md) | [`darkmode.js` Reference](docs/darkmode.js.md) | | |
| [See Example](https://vinorodrigues.github.io/bootstrap-dark-5/examples/cheatsheet-night.html) | | [See Example](https://vinorodrigues.github.io/bootstrap-dark-5/examples/cheatsheet-nightshade.html) | | [See Example](https://vinorodrigues.github.io/bootstrap-dark-5/examples/cheatsheet-dark.html) | |
## The Proof Is in the Pudding
Test pages have been set up at [vinorodrigues.github.io/bootstrap-dark-5](https://vinorodrigues.github.io/bootstrap-dark-5/)
Some of the test pages have been set up at [vinorodrigues.github.io/bootstrap-dark-5](https://vinorodrigues.github.io/bootstrap-dark-5/)

@@ -48,3 +67,4 @@

If you're a theme builder or want to use its principles in your own project you'll need to have [Git](https://help.github.com/articles/set-up-git) and [Node](https://nodejs.org/) installed.
If you're a theme builder or want to use its principles in your own project you'll need to have
[Git](https://help.github.com/articles/set-up-git) and [Node](https://nodejs.org/) installed.

@@ -57,3 +77,3 @@ 1. Fork or download the repository: `git clone https://github.com/vinorodrigues/bootstrap-dark-5.git`

> <u style="text-decoration:none;color:red">***NOTE:***</u> The build system is based on [NPM Scripts](https://docs.npmjs.com/cli/v6/using-npm/scripts). Most of the build tools _(NPM modules)_ will need to be installed as *"global"* to ensure the scripts are executable from the command line.
> ![NOTE:](https://img.shields.io/badge/NOTE%3A-069?style=for-the-badge) The build system is based on [NPM Scripts](https://docs.npmjs.com/cli/v6/using-npm/scripts). Most of the build tools _(NPM modules)_ will need to be installed as *"global"* to ensure the scripts are executable from the command line.

@@ -89,3 +109,3 @@ ```bash

* **`bootstrap-nightshade`** - the `html.body` css class + JS library variant
* **`bootstrap-nightshade`** - the `html.dark` css class + JS library variant
* Production / minified variants:

@@ -113,2 +133,4 @@ * [`https://cdn.jsdelivr.net/npm/bootstrap-dark-5@0.1/dist/css/bootstrap-nightshade.min.css`](https://cdn.jsdelivr.net/npm/bootstrap-dark-5@0.1/dist/css/bootstrap-nightshade.min.css)

* ...obviously, the original content: [The Definitive Guide to Dark Mode and Bootstrap 4](http://vinorodrigues.github.io/bootstrap-dark#readme)
* web.dev, Thomas Steiner ([@tomayac](https://github.com/tomayac)), Jun 27, 2019 *(updated Jun 9, 2020)*, "[prefers-color-scheme: Hello darkness, my old friend](https://web.dev/prefers-color-scheme/)"

@@ -115,0 +137,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc