From c6d0c627c7bff5141ca60713d36ea9d324ba1e26 Mon Sep 17 00:00:00 2001 From: augmentedmode Date: Mon, 9 Jun 2025 15:15:08 -0400 Subject: [PATCH 1/3] feat: implement dark mode toggle functionality --- src/index.css | 117 +++++++++++++++++++++++++++++++++++++++++++++++-- src/index.html | 6 +++ src/index.js | 52 ++++++++++++++++++++++ 3 files changed, 171 insertions(+), 4 deletions(-) diff --git a/src/index.css b/src/index.css index 6afd3bcb..6ff65a3e 100644 --- a/src/index.css +++ b/src/index.css @@ -1,3 +1,75 @@ +/* CSS Variables for Light/Dark Mode */ +:root { + --bg-color: #ffffff; + --text-color: #212529; + --card-bg: #ffffff; + --border-color: #dee2e6; + --input-bg: #ffffff; + --input-border: #ced4da; + --btn-primary-bg: #007bff; + --btn-primary-border: #007bff; + --alert-primary-bg: #d1ecf1; + --alert-primary-border: #bee5eb; + --alert-secondary-bg: #e2e3e5; + --alert-secondary-border: #d6d8db; + --alert-success-bg: #d4edda; + --alert-success-border: #c3e6cb; +} + +[data-theme="dark"] { + --bg-color: #1a1a1a; + --text-color: #e9ecef; + --card-bg: #2d2d2d; + --border-color: #495057; + --input-bg: #343a40; + --input-border: #495057; + --btn-primary-bg: #0d6efd; + --btn-primary-border: #0d6efd; + --alert-primary-bg: #0c5460; + --alert-primary-border: #086972; + --alert-secondary-bg: #41464b; + --alert-secondary-border: #565e64; + --alert-success-bg: #0f5132; + --alert-success-border: #0a3622; +} + +/* Apply theme variables */ +body { + background-color: var(--bg-color); + color: var(--text-color); + transition: background-color 0.3s ease, color 0.3s ease; +} + +.card { + background-color: var(--card-bg); + border-color: var(--border-color); + margin-bottom: 20px; +} + +.form-control { + background-color: var(--input-bg); + border-color: var(--input-border); + color: var(--text-color); +} + +.alert-primary { + background-color: var(--alert-primary-bg); + border-color: var(--alert-primary-border); + color: var(--text-color); +} + +.alert-secondary { + background-color: var(--alert-secondary-bg); + border-color: var(--alert-secondary-border); + color: var(--text-color); +} + +.alert-success { + background-color: var(--alert-success-bg); + border-color: var(--alert-success-border); + color: var(--text-color); +} + section { margin: 20px 0 20px 0; } @@ -20,16 +92,13 @@ textarea { width: 100%; } -.card { - margin-bottom: 20px; -} - /* Logo & Header */ header { display: flex; justify-content: center; align-items: center; + position: relative; } #logo-container { @@ -46,6 +115,46 @@ header { width: 100%; } +/* Dark Mode Toggle */ +#dark-mode-toggle-container { + position: absolute; + top: 15px; + right: 15px; +} + +.dark-mode-toggle { + background: none; + border: 2px solid var(--border-color); + border-radius: 50px; + padding: 8px 12px; + cursor: pointer; + font-size: 18px; + transition: all 0.3s ease; + background-color: var(--card-bg); + color: var(--text-color); + display: flex; + align-items: center; + gap: 4px; +} + +.dark-mode-toggle:hover { + transform: scale(1.05); + border-color: var(--btn-primary-border); +} + +.dark-mode-toggle:focus { + outline: none; + box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25); +} + +[data-theme="light"] .dark-mode-icon { + display: none; +} + +[data-theme="dark"] .light-mode-icon { + display: none; +} + /* EIP6963 Section */ .eip6963-providers { diff --git a/src/index.html b/src/index.html index 7e7e0d92..35d5aa11 100644 --- a/src/index.html +++ b/src/index.html @@ -28,6 +28,12 @@

+
+ +

diff --git a/src/index.js b/src/index.js index 1d6629cd..49971f25 100644 --- a/src/index.js +++ b/src/index.js @@ -226,6 +226,57 @@ const resolutionsSection = document.createElement('section'); mainContainer.appendChild(resolutionsSection); ensResolutionComponent(resolutionsSection); +/** + * Dark Mode Toggle + */ +const darkModeToggle = document.getElementById('dark-mode-toggle'); + +// Function to set theme +const setTheme = (theme) => { + document.documentElement.setAttribute('data-theme', theme); + localStorage.setItem('theme', theme); +}; + +// Function to get saved theme or default +const getSavedTheme = () => { + const savedTheme = localStorage.getItem('theme'); + if (savedTheme) { + return savedTheme; + } + + // Check system preference + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + return 'dark'; + } + + return 'light'; +}; + +// Initialize theme +const initializeTheme = () => { + const currentTheme = getSavedTheme(); + setTheme(currentTheme); +}; + +// Toggle theme +const toggleTheme = () => { + const currentTheme = document.documentElement.getAttribute('data-theme'); + const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; + setTheme(newTheme); +}; + +// Add event listener +darkModeToggle.addEventListener('click', toggleTheme); + +// Listen for system theme changes +if (window.matchMedia) { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { + if (!localStorage.getItem('theme')) { + setTheme(e.matches ? 'dark' : 'light'); + } + }); +} + /** * Provider */ @@ -722,6 +773,7 @@ const updateContractElements = () => { */ const initialize = async () => { + initializeTheme(); await setActiveProviderDetailWindowEthereum(); detectEip6963(); // We only want to set the activeProviderDetail is there is one instead of From c1ec8dbc4646e9fd9fde61c3b2631c6f8d2e271c Mon Sep 17 00:00:00 2001 From: augmentedmode Date: Mon, 9 Jun 2025 15:23:53 -0400 Subject: [PATCH 2/3] fix: yarn run lint --- src/index.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/index.js b/src/index.js index 49971f25..6189ca5b 100644 --- a/src/index.js +++ b/src/index.js @@ -243,12 +243,15 @@ const getSavedTheme = () => { if (savedTheme) { return savedTheme; } - + // Check system preference - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + if ( + window.matchMedia && + window.matchMedia('(prefers-color-scheme: dark)').matches + ) { return 'dark'; } - + return 'light'; }; @@ -270,11 +273,13 @@ darkModeToggle.addEventListener('click', toggleTheme); // Listen for system theme changes if (window.matchMedia) { - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { - if (!localStorage.getItem('theme')) { - setTheme(e.matches ? 'dark' : 'light'); - } - }); + window + .matchMedia('(prefers-color-scheme: dark)') + .addEventListener('change', (e) => { + if (!localStorage.getItem('theme')) { + setTheme(e.matches ? 'dark' : 'light'); + } + }); } /** From a16726579634bf9024a8561af58828ae85815fde Mon Sep 17 00:00:00 2001 From: augmentedmode Date: Thu, 12 Jun 2025 09:39:49 -0400 Subject: [PATCH 3/3] refactor: improve readability of theme detection logic in index.js --- src/index.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/index.js b/src/index.js index 6189ca5b..e8bcbdff 100644 --- a/src/index.js +++ b/src/index.js @@ -244,14 +244,7 @@ const getSavedTheme = () => { return savedTheme; } - // Check system preference - if ( - window.matchMedia && - window.matchMedia('(prefers-color-scheme: dark)').matches - ) { - return 'dark'; - } - + // Default to light mode return 'light'; }; @@ -271,13 +264,15 @@ const toggleTheme = () => { // Add event listener darkModeToggle.addEventListener('click', toggleTheme); -// Listen for system theme changes +// Listen for system theme changes (only if user hasn't set a preference) if (window.matchMedia) { window .matchMedia('(prefers-color-scheme: dark)') - .addEventListener('change', (e) => { + .addEventListener('change', () => { + // Only follow system preference if user hasn't explicitly set a theme if (!localStorage.getItem('theme')) { - setTheme(e.matches ? 'dark' : 'light'); + // Still default to light mode even when system changes + setTheme('light'); } }); }