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..e8bcbdff 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; + } + + // Default to light mode + 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 (only if user hasn't set a preference) +if (window.matchMedia) { + window + .matchMedia('(prefers-color-scheme: dark)') + .addEventListener('change', () => { + // Only follow system preference if user hasn't explicitly set a theme + if (!localStorage.getItem('theme')) { + // Still default to light mode even when system changes + setTheme('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