Skip to content

Commit 72395ba

Browse files
committed
new colors system
1 parent bd76df6 commit 72395ba

8 files changed

Lines changed: 223 additions & 13 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ packages/sidebar/script.js
66
packages/sidebar/icon.svg
77
packages/sidebar/preload.js
88
packages/sidebar/export.js
9+
packages/sidebar/colors.js
910
packages/newtab/styles.css
1011
packages/newtab/script.js
1112
packages/newtab/icon.svg
1213
packages/newtab/preload.js
1314
packages/newtab/export.js
15+
packages/newtab/colors.js
1416
web-ext-artifacts

packages/newtab/newtab.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@
5656
<div class="col-right" style="position: relative;">
5757
<!-- Settings Menu Popover -->
5858
<div id="settings-menu" class="settings-menu" hidden>
59+
<div class="setting-row">
60+
<label for="theme-selector">Theme</label>
61+
</div>
62+
<select id="theme-selector">
63+
<option value="default">Default</option>
64+
<option value="catppuccin">Catppuccin</option>
65+
</select>
66+
5967
<div class="setting-row">
6068
<label for="font-slider">Font Size</label>
6169
<span id="font-display">18px</span>
@@ -100,6 +108,7 @@
100108
</footer>
101109

102110
<script type="text/javascript" src="script.js"></script>
111+
<script type="text/javascript" src="colors.js"></script>
103112
<script type="text/javascript" src="export.js"></script>
104113
</body>
105114

packages/sidebar/panel.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@
5656
<div class="col-right" style="position: relative;">
5757
<!-- Settings Menu Popover -->
5858
<div id="settings-menu" class="settings-menu" hidden>
59+
<div class="setting-row">
60+
<label for="theme-selector">Theme</label>
61+
</div>
62+
<select id="theme-selector">
63+
<option value="default">Default</option>
64+
<option value="catppuccin">Catppuccin</option>
65+
</select>
66+
5967
<div class="setting-row">
6068
<label for="font-slider">Font Size</label>
6169
<span id="font-display">18px</span>
@@ -100,6 +108,7 @@
100108
</footer>
101109

102110
<script type="text/javascript" src="script.js"></script>
111+
<script type="text/javascript" src="colors.js"></script>
103112
<script type="text/javascript" src="export.js"></script>
104113
</body>
105114

scripts/copy-shared.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const path = require('path');
66
// Configuration
77
const sharedDir = path.join(__dirname, '../shared');
88
const packagesDir = path.join(__dirname, '../packages');
9-
const sharedFiles = ['script.js', 'styles.css', 'icon.svg', 'preload.js', 'export.js'];
9+
const sharedFiles = ['script.js', 'styles.css', 'icon.svg', 'preload.js', 'export.js', 'colors.js'];
1010
const targets = ['newtab', 'sidebar'];
1111

1212
// Colors for console output

scripts/watch-shared.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const { build } = require('./copy-shared.js');
88

99
// Configuration
1010
const sharedDir = path.join(__dirname, '../shared');
11-
const sharedFiles = ['script.js', 'styles.css', 'icon.svg', 'preload.js', 'export.js'];
11+
const sharedFiles = ['script.js', 'styles.css', 'icon.svg', 'preload.js', 'export.js', 'colors.js'];
1212

1313
// Colors for console output
1414
const colors = {

shared/colors.js

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Color Management System for NoteKeeper
2+
const colorManager = {
3+
// Default themes (original)
4+
defaults: {
5+
light: {
6+
name: 'Default Light',
7+
bg: '#ffffff',
8+
fg: '#1a1a1a',
9+
accent: '#27ae60',
10+
border: '#e0e0e0',
11+
subtle: '#666',
12+
shadow: 'rgba(0, 0, 0, 0.1)'
13+
},
14+
dark: {
15+
name: 'Default Dark',
16+
bg: '#111111',
17+
fg: '#f0f0f0',
18+
accent: '#27ae60',
19+
border: '#333333',
20+
subtle: '#888',
21+
shadow: 'rgba(0, 0, 0, 0.5)'
22+
}
23+
},
24+
25+
// Catppuccin-inspired color presets
26+
catppuccin: {
27+
latte: {
28+
name: 'Catppuccin Latte',
29+
bg: '#eff1f5',
30+
fg: '#4c4f69',
31+
accent: '#1e66f5',
32+
border: '#dce0e8',
33+
subtle: '#8c8fa1',
34+
shadow: 'rgba(220, 224, 232, 0.5)'
35+
},
36+
frappe: {
37+
name: 'Catppuccin Frappé',
38+
bg: '#303446',
39+
fg: '#c6d0f5',
40+
accent: '#8caaee',
41+
border: '#51576d',
42+
subtle: '#838ba7',
43+
shadow: 'rgba(30, 32, 48, 0.5)'
44+
}
45+
},
46+
47+
// Initialize color system
48+
init() {
49+
const savedTheme = localStorage.getItem('notekeeper-theme') || 'default';
50+
this.applyTheme(savedTheme);
51+
},
52+
53+
// Apply theme colors
54+
applyTheme(themeName) {
55+
let theme;
56+
let isDarkMode = false;
57+
58+
// Handle theme selection
59+
if (themeName === 'default') {
60+
// Use original light/dark toggle behavior
61+
const currentMode = localStorage.getItem('theme') || 'light';
62+
theme = this.defaults[currentMode];
63+
isDarkMode = currentMode === 'dark';
64+
} else if (themeName === 'catppuccin') {
65+
// Use Catppuccin behavior
66+
const currentVariant = localStorage.getItem('catppuccin-variant') || 'latte';
67+
theme = this.catppuccin[currentVariant];
68+
isDarkMode = currentVariant === 'frappe';
69+
} else {
70+
// Direct theme selection
71+
if (themeName.startsWith('catppuccin-')) {
72+
const catppuccinVariant = themeName.replace('catppuccin-', '');
73+
theme = this.catppuccin[catppuccinVariant];
74+
isDarkMode = catppuccinVariant === 'frappe';
75+
} else {
76+
theme = this.defaults[themeName];
77+
isDarkMode = themeName === 'dark';
78+
}
79+
}
80+
81+
if (!theme) return;
82+
83+
// Apply colors to CSS custom properties
84+
Object.entries(theme).forEach(([key, value]) => {
85+
if (key !== 'name') {
86+
document.documentElement.style.setProperty(`--user-${key}`, value);
87+
}
88+
});
89+
90+
// Update theme attribute for existing CSS
91+
document.documentElement.setAttribute('data-theme', isDarkMode ? 'dark' : 'light');
92+
93+
// Save preference
94+
localStorage.setItem('notekeeper-theme', themeName);
95+
96+
// Update theme toggle aria-label
97+
const themeToggle = document.getElementById('theme-toggle');
98+
if (themeToggle) {
99+
const nextTheme = this.getNextTheme(themeName);
100+
const isNextDark = nextTheme === 'dark' || nextTheme === 'frappe';
101+
themeToggle.setAttribute('aria-label', `Switch to ${isNextDark ? 'light' : 'dark'} theme`);
102+
}
103+
},
104+
105+
// Toggle between themes
106+
toggleTheme() {
107+
const currentTheme = localStorage.getItem('notekeeper-theme') || 'default';
108+
109+
if (currentTheme === 'default') {
110+
// Toggle light/dark in default mode
111+
const currentMode = localStorage.getItem('theme') || 'light';
112+
const nextMode = currentMode === 'light' ? 'dark' : 'light';
113+
localStorage.setItem('theme', nextMode);
114+
this.applyTheme('default');
115+
} else if (currentTheme === 'catppuccin') {
116+
// Toggle latte/frappe in catppuccin mode
117+
const currentVariant = localStorage.getItem('catppuccin-variant') || 'latte';
118+
const nextVariant = currentVariant === 'latte' ? 'frappe' : 'latte';
119+
localStorage.setItem('catppuccin-variant', nextVariant);
120+
this.applyTheme('catppuccin');
121+
} else {
122+
// Direct theme selection - toggle between default themes
123+
const nextTheme = currentTheme === 'light' ? 'dark' : 'light';
124+
localStorage.setItem('notekeeper-theme', nextTheme);
125+
localStorage.setItem('theme', nextTheme);
126+
this.applyTheme('default');
127+
}
128+
},
129+
130+
// Get next theme for aria-label (informational only)
131+
getNextTheme(currentTheme) {
132+
if (currentTheme === 'default') {
133+
const currentMode = localStorage.getItem('theme') || 'light';
134+
return currentMode === 'light' ? 'dark' : 'light';
135+
} else if (currentTheme === 'catppuccin') {
136+
const currentVariant = localStorage.getItem('catppuccin-variant') || 'latte';
137+
return currentVariant === 'latte' ? 'frappe' : 'latte';
138+
}
139+
return currentTheme === 'light' ? 'dark' : 'light';
140+
},
141+
142+
// Get current theme
143+
getCurrentTheme() {
144+
return localStorage.getItem('notekeeper-theme') || 'default';
145+
}
146+
};
147+
148+
// Initialize on DOM load
149+
document.addEventListener('DOMContentLoaded', () => {
150+
colorManager.init();
151+
});

shared/preload.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
11
// Prevent FOUC by setting theme and font size before page renders
2-
const savedTheme = localStorage.getItem("theme");
2+
const savedTheme = localStorage.getItem("notekeeper-theme") || localStorage.getItem("theme");
33
const sysTheme = window.matchMedia("(prefers-color-scheme: dark)").matches;
4-
document.documentElement.setAttribute("data-theme", savedTheme || (sysTheme ? "dark" : "light"));
4+
5+
// Determine actual theme to apply
6+
let actualTheme = savedTheme;
7+
if (savedTheme === 'default') {
8+
// For default theme, check the legacy theme storage
9+
const legacyTheme = localStorage.getItem("theme");
10+
actualTheme = legacyTheme || (sysTheme ? "dark" : "light");
11+
} else if (savedTheme === 'catppuccin') {
12+
// For catppuccin theme, check the variant storage
13+
const catppuccinVariant = localStorage.getItem("catppuccin-variant") || "latte";
14+
actualTheme = catppuccinVariant === "frappe" ? "dark" : "light";
15+
}
16+
17+
document.documentElement.setAttribute("data-theme", actualTheme || (sysTheme ? "dark" : "light"));
518

619
// Pre-load font size
720
const savedSize = localStorage.getItem("fontsize");

shared/script.js

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const els = {
77
slider: document.getElementById("font-slider"),
88
fontDisplay: document.getElementById("font-display"),
99
fontFamily: document.getElementById("font-family"),
10+
themeSelector: document.getElementById("theme-selector"),
1011
words: document.getElementById("word-count"),
1112
status: document.getElementById("save-status"),
1213
};
@@ -82,16 +83,9 @@ const localStore = {
8283
},
8384
};
8485

85-
// Theme Logic
86+
// Theme Logic - Now uses colorManager
8687
const toggleTheme = () => {
87-
const next =
88-
els.html.getAttribute("data-theme") === "dark" ? "light" : "dark";
89-
els.html.setAttribute("data-theme", next);
90-
localStore.set("theme", next);
91-
els.toggleTheme.setAttribute(
92-
"aria-label",
93-
`Switch to ${next === "dark" ? "light" : "dark"}`
94-
);
88+
colorManager.toggleTheme();
9589
};
9690

9791
els.toggleTheme.addEventListener("click", toggleTheme);
@@ -127,6 +121,10 @@ els.fontFamily.addEventListener("change", (e) => {
127121
updateFontFamily(e.target.value);
128122
});
129123

124+
els.themeSelector.addEventListener("change", (e) => {
125+
colorManager.applyTheme(e.target.value);
126+
});
127+
130128
// Close menu when clicking outside
131129
document.addEventListener("click", (e) => {
132130
if (
@@ -252,6 +250,34 @@ if (storedFontFamily) {
252250
updateFontFamily(storedFontFamily);
253251
}
254252

253+
// Init Theme Selector
254+
const currentTheme = colorManager.getCurrentTheme();
255+
if (els.themeSelector) {
256+
els.themeSelector.value = currentTheme;
257+
}
258+
259+
// Migrate legacy theme storage for backward compatibility
260+
const migrateLegacyTheme = () => {
261+
const legacyTheme = localStore.get("theme");
262+
if (legacyTheme && !localStorage.getItem('notekeeper-theme')) {
263+
// Migrate old theme to new system
264+
if (legacyTheme === 'light' || legacyTheme === 'dark') {
265+
localStorage.setItem('notekeeper-theme', legacyTheme);
266+
localStorage.setItem('theme', legacyTheme);
267+
} else if (legacyTheme === 'latte') {
268+
localStorage.setItem('notekeeper-theme', 'catppuccin');
269+
localStorage.setItem('catppuccin-variant', 'latte');
270+
} else if (legacyTheme === 'frappe') {
271+
localStorage.setItem('notekeeper-theme', 'catppuccin');
272+
localStorage.setItem('catppuccin-variant', 'frappe');
273+
}
274+
// Remove old theme key
275+
localStore.remove("theme");
276+
}
277+
};
278+
279+
migrateLegacyTheme();
280+
255281
els.note.addEventListener("input", (e) => {
256282
updateStats(e.target.value);
257283
save(e.target.value);

0 commit comments

Comments
 (0)