Skip to content

Commit 5c54ebe

Browse files
authored
Add random themes (#55)
1 parent f530c8d commit 5c54ebe

File tree

2 files changed

+151
-16
lines changed

2 files changed

+151
-16
lines changed

doc/source/_static/custom.css

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,65 @@
1+
/* Custom properties for colors (default light theme values) */
2+
:root {
3+
--bg-color: #ffffff;
4+
--text-color: #2c2c2c;
5+
--link-color: #337ab7;
6+
--caption-color: #666;
7+
--header-color: #000000;
8+
--body-bg-color: #ffffff;
9+
--body-text-color: #2c2c2c;
10+
}
11+
12+
/* Light theme (default) */
13+
body.light, body {
14+
background-color: var(--bg-color);
15+
color: var(--text-color);
16+
}
17+
18+
body.light a, a {
19+
color: var(--link-color);
20+
}
21+
22+
body.light a:hover, a:hover {
23+
color: #23527c;
24+
}
25+
26+
body.light p.caption, p.caption {
27+
color: var(--caption-color);
28+
}
29+
30+
body.light h1, body.light h2, body.light h3, body.light h4, body.light h5, body.light h6,
31+
h1, h2, h3, h4, h5, h6 {
32+
color: var(--header-color);
33+
}
34+
35+
body.light div.body, div.body {
36+
background-color: var(--body-bg-color);
37+
}
38+
39+
body.light div.body p, div.body p {
40+
color: var(--body-text-color);
41+
}
42+
43+
/* Dark theme */
44+
body.dark {
45+
--bg-color: #2c2c2c;
46+
--text-color: #e0e0e0;
47+
--link-color: #58a6ff;
48+
--caption-color: #f3e5ab;
49+
--header-color: #ffffff;
50+
--body-bg-color: #2c2c2c;
51+
--body-text-color: #f3e5ab;
52+
}
53+
54+
/* Random theme */
55+
/* The JavaScript sets the color properties directly on the body element. */
56+
body.random {
57+
/* No CSS required here; the JS handles the styles */
58+
}
59+
60+
/* Other existing CSS for lists and icons */
61+
/* ... (existing styles for lists and icons are unchanged) */
62+
163
.green {
264
color: green;
365
}
Lines changed: 89 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,110 @@
11
document.addEventListener('DOMContentLoaded', () => {
2+
// Define a set of random color palettes
3+
const randomPalettes = [
4+
// Palette 1
5+
{
6+
'--bg-color': '#f0e6f2',
7+
'--text-color': '#4a235a',
8+
'--link-color': '#8e44ad',
9+
'--caption-color': '#c0392b',
10+
'--header-color': '#4a235a',
11+
'--body-bg-color': '#f0e6f2',
12+
'--body-text-color': '#4a235a'
13+
},
14+
// Palette 2
15+
{
16+
'--bg-color': '#e8f8f5',
17+
'--text-color': '#117a65',
18+
'--link-color': '#1abc9c',
19+
'--caption-color': '#d35400',
20+
'--header-color': '#117a65',
21+
'--body-bg-color': '#e8f8f5',
22+
'--body-text-color': '#117a65'
23+
},
24+
// Palette 3
25+
{
26+
'--bg-color': '#fef9e7',
27+
'--text-color': '#b07e0c',
28+
'--link-color': '#f39c12',
29+
'--caption-color': '#2c3e50',
30+
'--header-color': '#b07e0c',
31+
'--body-bg-color': '#fef9e7',
32+
'--body-text-color': '#b07e0c'
33+
}
34+
];
35+
236
const themeToggle = document.getElementById('theme-toggle');
3-
if (themeToggle) { // Add this check to prevent errors if the element isn't found
37+
if (themeToggle) {
438
const body = document.body;
5-
6-
// Check for a saved theme preference in local storage
739
const savedTheme = localStorage.getItem('theme');
40+
let currentTheme = 'light'; // Default
41+
842
if (savedTheme) {
9-
body.classList.add(savedTheme);
43+
currentTheme = savedTheme;
44+
if (currentTheme === 'random') {
45+
applyRandomTheme(body, randomPalettes);
46+
} else {
47+
body.classList.add(currentTheme);
48+
}
1049
} else {
1150
// Fallback to the user's system preference
1251
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
13-
body.classList.add('dark');
52+
currentTheme = 'dark';
53+
body.classList.add(currentTheme);
1454
} else {
15-
body.classList.add('light');
55+
body.classList.add(currentTheme);
1656
}
1757
}
1858

19-
// Set the initial state of the toggle button
20-
themeToggle.textContent = body.classList.contains('dark') ? '☀️' : '🌙';
59+
updateToggleText(themeToggle, currentTheme);
2160

22-
// Add click event listener to the toggle button
2361
themeToggle.addEventListener('click', () => {
24-
if (body.classList.contains('dark')) {
62+
if (currentTheme === 'dark') {
63+
currentTheme = 'light';
2564
body.classList.remove('dark');
2665
body.classList.add('light');
27-
localStorage.setItem('theme', 'light');
28-
themeToggle.textContent = '🌙';
29-
} else {
66+
removeRandomTheme(body);
67+
} else if (currentTheme === 'light') {
68+
currentTheme = 'random';
3069
body.classList.remove('light');
70+
applyRandomTheme(body, randomPalettes);
71+
} else { // It's 'random'
72+
currentTheme = 'dark';
73+
body.classList.remove('random');
3174
body.classList.add('dark');
32-
localStorage.setItem('theme', 'dark');
33-
themeToggle.textContent = '☀️';
75+
removeRandomTheme(body);
3476
}
77+
localStorage.setItem('theme', currentTheme);
78+
updateToggleText(themeToggle, currentTheme);
3579
});
3680
}
37-
});
81+
82+
// Helper function to update button text
83+
function updateToggleText(button, theme) {
84+
if (theme === 'dark') {
85+
button.textContent = '☀️';
86+
} else if (theme === 'light') {
87+
button.textContent = '🎨'; // Paint palette for random
88+
} else {
89+
button.textContent = '🌙';
90+
}
91+
}
92+
93+
// Helper function to apply random theme colors
94+
function applyRandomTheme(body, palettes) {
95+
body.classList.add('random');
96+
const randomPalette = palettes[Math.floor(Math.random() * palettes.length)];
97+
for (const [property, value] of Object.entries(randomPalette)) {
98+
body.style.setProperty(property, value);
99+
}
100+
}
101+
102+
// Helper function to remove random theme styles
103+
function removeRandomTheme(body) {
104+
body.classList.remove('random');
105+
const randomPalette = randomPalettes[0]; // Use any palette to get property keys
106+
for (const property of Object.keys(randomPalette)) {
107+
body.style.removeProperty(property);
108+
}
109+
}
110+
});

0 commit comments

Comments
 (0)