From 68b5783a287b5b456df62f2f0414e2fadf9e7152 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sat, 11 Nov 2023 11:37:26 +0100 Subject: [PATCH] Add dark theme variant --- public/css/admin.css | 8 ++-- public/css/default.css | 54 ++++++++++++++++++-------- public/js/color-modes.js | 77 ++++++++++++++++++++++++++++++++++++++ templates/MainNavBar.php | 34 +++++++++++++++++ templates/MainTemplate.php | 3 +- 5 files changed, 156 insertions(+), 20 deletions(-) create mode 100644 public/js/color-modes.js diff --git a/public/css/admin.css b/public/css/admin.css index e69e854a..f0b75037 100644 --- a/public/css/admin.css +++ b/public/css/admin.css @@ -4,18 +4,20 @@ position: relative; } .polaroid a.edit { - background: #fff; + background: var(--bs-body-bg); border-radius: 3px; box-shadow: 1px 1px 2px rgba(0,0,0,0.3); - display: none !important; + color: var(--bs-body-color); + opacity: 0; left: 20px; line-height: 1.5; padding: 5px 10px; position: absolute; + transition: 0.25s; top: 20px; } .polaroid:hover > a.edit { - display: block !important; + opacity: 1; } diff --git a/public/css/default.css b/public/css/default.css index 717388a3..fc7d8f7a 100644 --- a/public/css/default.css +++ b/public/css/default.css @@ -18,6 +18,11 @@ body { font-family: "Open Sans", sans-serif; background: #aaa 0 -50% fixed; padding: 0 0 3rem; + transition: 0.5s; +} + +[data-bs-theme=dark] body { + background-color: #444; } #wrapper, header .container { @@ -34,6 +39,14 @@ a:hover { color: #262626; } +[data-bs-theme=dark] .content-box a:not(.btn) { + color: #b94b4b; +} +[data-bs-theme=dark] .content-box a:not(.btn):hover { + color: #963626; +} + + .page-link { color: #b50707; font-family: 'Coda', sans-serif; @@ -182,7 +195,7 @@ i.nyan-cat { /* Content boxes ------------------*/ .content-box { - background-color: #fff; + background-color: var(--bs-body-bg); margin: 0 auto 2rem; padding: 2rem; border-radius: 0.5rem; @@ -203,10 +216,10 @@ i.nyan-cat { } .tiled-header > a { - background: #fff; + background: var(--bs-body-bg); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); border-radius: 0.5rem; - color: #000; + color: var(--bs-body-color); display: inline-block; font: 400 18px/2.2 'Coda', sans-serif; margin: 0 0 1.5% 0; @@ -217,7 +230,7 @@ i.nyan-cat { } div.polaroid { - background: #fff; + background: var(--bs-body-bg); box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.3); line-height: 0; position: relative; @@ -227,7 +240,7 @@ div.polaroid:hover { box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.5); } div.polaroid img.normal-photo { - background: #fff url('../images/nothumb.svg') center no-repeat; + background: var(--bs-body-bg) url('../images/nothumb.svg') center no-repeat; border: none; left: 0; object-fit: cover; @@ -246,13 +259,13 @@ div.polaroid img.blur-photo { z-index: 0; } div.polaroid img.placeholder-image { - background: #fff; + background: var(--bs-body-bg); z-index: 20; } div.polaroid h4 { - background: #fff; + background: var(--bs-body-bg); bottom: 0; - color: #000; + color: var(--bs-body-color); margin: 0; font: 400 18px 'Coda', sans-serif; padding: 15px 5px; @@ -278,7 +291,7 @@ div.polaroid a { width: 100%; } .album_title_box > a { - background: #fff; + background: var(--bs-body-bg); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); border-top-left-radius: 0.5rem; border-bottom-left-radius: 0.5rem; @@ -289,7 +302,7 @@ div.polaroid a { padding: 8px 10px; } .album_title_box > div { - background: #fff; + background: var(--bs-body-bg); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); border-top-right-radius: 0.5rem; border-bottom-right-radius: 0.5rem; @@ -300,7 +313,7 @@ div.polaroid a { margin: 0 0 1.5% 0; } .album_title_box h2 { - color: #262626; + color: var(--bs-body-color); font: 400 18px/2 'Coda', sans-serif !important; margin: 0; } @@ -316,10 +329,18 @@ div.polaroid a { margin-bottom: 3rem; } .album_button_box > a { + background: var(--bs-body-bg); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); + border-color: var( --bs-secondary-bg); + color: var(--bs-body-color); padding: 8px 10px; margin-left: 12px; } +.album_button_box > a:hover { + background: var(--bs-secondary-bg); + border-color: var(--bs-tertiary-bg); + color: var(--bs-secondary-color); +} /* (Tag) autosuggest @@ -329,8 +350,9 @@ div.polaroid a { position: relative; } .autosuggest { - background: #fff; + background: var(--bs-body-bg); border: 1px solid #ccc; + color: var(--bs-body-color); position: absolute; left: 2px; top: 37px; @@ -459,9 +481,9 @@ figure#photo-figure img.blur-photo { } #previous_photo, #next_photo { - background: #fff; + background: var(--bs-body-bg); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); - color: #262626; + color: var(--bs-body-color); font-size: 3rem; line-height: 0.5; padding: 2rem 0.5rem; @@ -473,8 +495,8 @@ span#previous_photo, span#next_photo { opacity: 0.25; } a#previous_photo:hover, a#next_photo:hover { - background: #eee; - color: #000; + background: var(--bs-secondary-bg); + color: var(--bs-secondary-color); } #previous_photo { border-top-right-radius: 0.5rem; diff --git a/public/js/color-modes.js b/public/js/color-modes.js new file mode 100644 index 00000000..b9167809 --- /dev/null +++ b/public/js/color-modes.js @@ -0,0 +1,77 @@ +/*! + * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors + * Licensed under the Creative Commons Attribution 3.0 Unported License. + */ + +(() => { + 'use strict' + + const getStoredTheme = () => localStorage.getItem('theme'); + const setStoredTheme = theme => localStorage.setItem('theme', theme); + + const getPreferredTheme = () => { + const storedTheme = getStoredTheme(); + if (storedTheme) { + return storedTheme; + } + + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; + } + + const setTheme = theme => { + if (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-bs-theme', 'dark'); + } else { + document.documentElement.setAttribute('data-bs-theme', theme); + } + } + + setTheme(getPreferredTheme()); + + const showActiveTheme = (theme, focus = false) => { + const themeSwitcher = document.querySelector('#bd-theme'); + + if (!themeSwitcher) { + return; + } + + const themeSwitcherText = document.querySelector('#bd-theme-text'); + const activeThemeIcon = document.querySelector('#theme-icon-active'); + const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`); + const activeButtonIcon = btnToActive.querySelector('i.bi').className; + + document.querySelectorAll('[data-bs-theme-value]').forEach(element => { + element.classList.remove('active'); + }); + + btnToActive.classList.add('active'); + activeThemeIcon.className = activeButtonIcon; + const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})` + + if (focus) { + themeSwitcher.focus() + } + } + + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { + const storedTheme = getStoredTheme() + if (storedTheme !== 'light' && storedTheme !== 'dark') { + setTheme(getPreferredTheme()) + } + }) + + window.addEventListener('DOMContentLoaded', () => { + showActiveTheme(getPreferredTheme()) + + document.querySelectorAll('[data-bs-theme-value]') + .forEach(toggle => { + toggle.addEventListener('click', () => { + const theme = toggle.getAttribute('data-bs-theme-value') + setStoredTheme(theme) + setTheme(theme) + showActiveTheme(theme, true) + }) + }) + }) +})() diff --git a/templates/MainNavBar.php b/templates/MainNavBar.php index 1616057c..51ae4c1c 100644 --- a/templates/MainNavBar.php +++ b/templates/MainNavBar.php @@ -51,6 +51,8 @@ class MainNavBar extends NavBar $userMenu = new UserMenu(); $this->renderMenuItems($userMenu->getItems()); + $this->darkModeToggle(); + echo ' '; @@ -60,4 +62,36 @@ class MainNavBar extends NavBar '; } + + private function darkModeToggle() + { + echo ' + '; + } } diff --git a/templates/MainTemplate.php b/templates/MainTemplate.php index 8c8a92f6..413c5c41 100644 --- a/templates/MainTemplate.php +++ b/templates/MainTemplate.php @@ -39,7 +39,8 @@ class MainTemplate extends Template - ' + + ' , $this->header_html, ' classes) ? ' class="' . implode(' ', $this->classes) . '"' : '', '>