From 892b64a28ea8a857d81587635777be980aa3cc04 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 9 Dec 2025 10:15:51 +0530 Subject: [PATCH 01/12] svg for theme toggle --- client/assets/icon-moon.svg | 3 +++ client/assets/icon-sun.svg | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 client/assets/icon-moon.svg create mode 100644 client/assets/icon-sun.svg diff --git a/client/assets/icon-moon.svg b/client/assets/icon-moon.svg new file mode 100644 index 00000000..6d6762cc --- /dev/null +++ b/client/assets/icon-moon.svg @@ -0,0 +1,3 @@ + + + diff --git a/client/assets/icon-sun.svg b/client/assets/icon-sun.svg new file mode 100644 index 00000000..c41a0594 --- /dev/null +++ b/client/assets/icon-sun.svg @@ -0,0 +1,4 @@ + + + + From 6f374280188cd77f4a708b43e0451b1b5371acfc Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 9 Dec 2025 10:17:38 +0530 Subject: [PATCH 02/12] feat: add dark mode state management and CSS variables --- client/store.js | 15 +++++++++++++++ client/viewer.css | 22 ++++++++++++++++++++++ client/viewer.jsx | 1 + 3 files changed, 38 insertions(+) diff --git a/client/store.js b/client/store.js index 1695db11..cf3e417e 100644 --- a/client/store.js +++ b/client/store.js @@ -12,6 +12,7 @@ export class Store { @observable defaultSize; @observable selectedSize; @observable showConcatenatedModulesContent = (localStorage.getItem('showConcatenatedModulesContent') === true); + @observable darkMode = (localStorage.getItem('darkMode') === true); setModules(modules) { walkModules(modules, module => { @@ -179,6 +180,20 @@ export class Store { return filteredModules; }, []); } + + toggleDarkMode() { + this.darkMode = !this.darkMode; + localStorage.setItem('darkMode', this.darkMode); + this.updateTheme(); + } + + updateTheme() { + if (this.darkMode) { + document.documentElement.setAttribute('data-theme', 'dark'); + } else { + document.documentElement.removeAttribute('data-theme'); + } + } } export const store = new Store(); diff --git a/client/viewer.css b/client/viewer.css index f10404d8..7f9876a2 100644 --- a/client/viewer.css +++ b/client/viewer.css @@ -1,5 +1,24 @@ :root { --main-font: normal 11px Verdana, sans-serif; + --bg-primary: #fff; + --bg-secondary: #f5f5f5; + --text-primary: #000; + --text-secondary: #666; + --border-color: #aaa; + --border-light: #ddd; + --shadow: rgba(0, 0, 0, 0.1); + --hover-bg: rgba(0, 0, 0, 0.05); +} + +[data-theme="dark"] { + --bg-primary: #1e1e1e; + --bg-secondary: #252525; + --text-primary: #e0e0e0; + --text-secondary: #a0a0a0; + --border-color: #404040; + --border-light: #333; + --shadow: rgba(0, 0, 0, 0.3); + --hover-bg: rgba(255, 255, 255, 0.05); } :global html, @@ -10,6 +29,9 @@ overflow: hidden; padding: 0; width: 100%; + background: var(--bg-primary); + color: var(--text-primary); + transition: background-color 0.3s ease, color 0.3s ease; } :global body.resizing { diff --git a/client/viewer.jsx b/client/viewer.jsx index 19f32c4e..5fa8ea95 100644 --- a/client/viewer.jsx +++ b/client/viewer.jsx @@ -21,6 +21,7 @@ window.addEventListener('load', () => { store.defaultSize = `${window.defaultSizes}Size`; store.setModules(window.chartData); store.setEntrypoints(window.entrypoints); + store.updateTheme(); render( , document.getElementById('app') From fb031aee2b1f5df4553e533986a2898750f8fef2 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 9 Dec 2025 10:17:55 +0530 Subject: [PATCH 03/12] feat: add ThemeToggle component with moon/sun icons --- client/components/ThemeToggle.css | 19 +++++++++++++++++++ client/components/ThemeToggle.jsx | 28 ++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 client/components/ThemeToggle.css create mode 100644 client/components/ThemeToggle.jsx diff --git a/client/components/ThemeToggle.css b/client/components/ThemeToggle.css new file mode 100644 index 00000000..bd63493e --- /dev/null +++ b/client/components/ThemeToggle.css @@ -0,0 +1,19 @@ +.themeToggle { + background: transparent; + border: none; + cursor: pointer; + padding: 8px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + transition: background-color 0.2s ease; +} + +.themeToggle:hover { + background: rgba(0, 0, 0, 0.1); +} + +[data-theme="dark"] .themeToggle:hover { + background: rgba(255, 255, 255, 0.1); +} diff --git a/client/components/ThemeToggle.jsx b/client/components/ThemeToggle.jsx new file mode 100644 index 00000000..520f2eeb --- /dev/null +++ b/client/components/ThemeToggle.jsx @@ -0,0 +1,28 @@ +import {Component} from 'preact'; +import {observer} from 'mobx-react'; + +import s from './ThemeToggle.css'; +import Button from './Button'; +import Icon from './Icon'; +import {store} from '../store'; + +@observer +export default class ThemeToggle extends Component { + render() { + const {darkMode} = store; + + return ( + + ); + } + + handleToggle = () => { + store.toggleDarkMode(); + } +} From e653185df29f9a06e5c3829ef22eecce62b0ccc7 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 9 Dec 2025 10:18:23 +0530 Subject: [PATCH 04/12] feat: integrate ThemeToggle into sidebar with proper positioning --- client/components/Sidebar.css | 15 +++++++++++++-- client/components/Sidebar.jsx | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/client/components/Sidebar.css b/client/components/Sidebar.css index 54241e06..956460a6 100644 --- a/client/components/Sidebar.css +++ b/client/components/Sidebar.css @@ -1,13 +1,14 @@ @value toggleTime: 200ms; .container { - background: #fff; + background: var(--bg-primary); border: none; - border-right: 1px solid #aaa; + border-right: 1px solid var(--border-color); box-sizing: border-box; max-width: calc(50% - 10px); opacity: 0.95; z-index: 1; + transition: background-color 0.3s ease, border-color 0.3s ease; } .container:not(.hidden) { @@ -45,6 +46,16 @@ padding: 0; } +.container :global(.themeToggle) { + position: absolute; + top: 10px; + left: 15px; + z-index: 10; + height: 26px; + width: 27px; + padding: 0; +} + .pinButton, .toggleButton { cursor: pointer; diff --git a/client/components/Sidebar.jsx b/client/components/Sidebar.jsx index 66ac044b..82ffd70a 100644 --- a/client/components/Sidebar.jsx +++ b/client/components/Sidebar.jsx @@ -4,6 +4,7 @@ import cls from 'classnames'; import s from './Sidebar.css'; import Button from './Button'; import Icon from './Icon'; +import ThemeToggle from './ThemeToggle'; const toggleTime = parseInt(s.toggleTime); @@ -48,6 +49,7 @@ export default class Sidebar extends Component { className={className} onClick={this.handleClick} onMouseLeave={this.handleMouseLeave}> + {visible &&