Skip to content

Commit 45f04b6

Browse files
feat: Add support for dark mode (#246)
Resolves #197 --------- Signed-off-by: lennartrommeiss <[email protected]> Co-authored-by: Lennart Rommeiss <[email protected]>
1 parent 985909d commit 45f04b6

File tree

20 files changed

+208
-83
lines changed

20 files changed

+208
-83
lines changed

assets/js/aside.js

Lines changed: 0 additions & 41 deletions
This file was deleted.

assets/js/countrySelector.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
function initCountrySelector() {
2-
32
const expandButton = document.querySelector('.o-header__expand-button');
43
const countryContainer = document.querySelector('.o-header__item-countries');
54

assets/js/darkmode.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
(function() {
2+
const THEME_KEY = 'fipguide-theme';
3+
const DARK_THEME = 'dark';
4+
const LIGHT_THEME = 'light';
5+
const AUTO_THEME = 'auto';
6+
7+
function getSavedTheme() {
8+
return localStorage.getItem(THEME_KEY) || AUTO_THEME;
9+
}
10+
11+
function saveTheme(theme) {
12+
localStorage.setItem(THEME_KEY, theme);
13+
}
14+
15+
function getSystemTheme() {
16+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? DARK_THEME : LIGHT_THEME;
17+
}
18+
19+
function getEffectiveTheme(theme) {
20+
return theme === AUTO_THEME ? getSystemTheme() : theme;
21+
}
22+
23+
function applyTheme(theme) {
24+
const effectiveTheme = getEffectiveTheme(theme);
25+
if (effectiveTheme === DARK_THEME) {
26+
document.documentElement.setAttribute('data-theme', DARK_THEME);
27+
} else {
28+
document.documentElement.removeAttribute('data-theme');
29+
}
30+
}
31+
32+
function toggleTheme() {
33+
const currentTheme = getSavedTheme();
34+
let newTheme;
35+
36+
if (currentTheme === LIGHT_THEME) {
37+
newTheme = DARK_THEME;
38+
} else if (currentTheme === DARK_THEME) {
39+
newTheme = AUTO_THEME;
40+
} else {
41+
newTheme = LIGHT_THEME;
42+
}
43+
44+
saveTheme(newTheme);
45+
applyTheme(newTheme);
46+
updateToggleButtons(newTheme);
47+
}
48+
49+
function updateToggleButtons(theme) {
50+
const toggleButtons = document.querySelectorAll('.a-theme-toggle');
51+
52+
toggleButtons.forEach(button => {
53+
let icon;
54+
let label;
55+
if (theme === AUTO_THEME) {
56+
icon = 'brightness_auto';
57+
label = button.dataset.switchToLight;
58+
} else if (theme === LIGHT_THEME) {
59+
icon = 'light_mode';
60+
label = button.dataset.switchToDark;
61+
} else if (theme === DARK_THEME) {
62+
icon = 'dark_mode';
63+
label = button.dataset.switchToAuto;
64+
}
65+
66+
const iconElement = button.querySelector('.material-symbols-rounded');
67+
if(iconElement) {
68+
iconElement.textContent = icon;
69+
}
70+
button.setAttribute('title', label);
71+
button.setAttribute('aria-label', label);
72+
});
73+
}
74+
75+
function initializeButtons() {
76+
const savedTheme = getSavedTheme();
77+
updateToggleButtons(savedTheme);
78+
79+
const toggleButtons = document.querySelectorAll('.a-theme-toggle');
80+
toggleButtons.forEach(button => {
81+
button.addEventListener('click', toggleTheme);
82+
});
83+
84+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
85+
if (getSavedTheme() === AUTO_THEME) {
86+
applyTheme(AUTO_THEME);
87+
}
88+
});
89+
}
90+
91+
applyTheme(getSavedTheme());
92+
93+
if (document.readyState === 'loading') {
94+
document.addEventListener('DOMContentLoaded', initializeButtons);
95+
} else {
96+
initializeButtons();
97+
}
98+
})();

assets/js/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ import './resizeObserver.js';
44
import './mediaqueries.js';
55
import './highlightHeadline.js';
66
import './anchorlinks.js';
7+
import './darkmode.js';
78
import './interactiveMap.js';

assets/sass/_variables.scss

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ $bg-neutral: #EBE9E1;
1212
$bg-accent: #FFD900;
1313
$bg-accent2: #DABA00;
1414
$bg-accent3: #fff284;
15-
$color-onDark: #FFFFFF;
1615
$color-onLight: #000000;
1716
$color-table-border: #5B5B5B;
1817

19-
body {
18+
html {
2019
--pagefind-ui-scale: 1;
2120
--pagefind-ui-text: #000;
2221
--link-default: #{$link-default};
@@ -27,7 +26,6 @@ body {
2726
--bg-accent: #{$bg-accent};
2827
--bg-accent2: #{$bg-accent2};
2928
--bg-accent3: #{$bg-accent3};
30-
--color-onDark: #{$color-onDark};
3129
--color-onLight: #{$color-onLight};
3230
--color-table-border: #{$color-table-border};
3331
--color-body: rgb(33, 37, 41);
@@ -38,4 +36,29 @@ body {
3836
--pagefind-ui-border: #000;
3937
--box-shadow: 0 .4rem 1rem rgba(0,0,0,.25);
4038
--box-shadow-light: 0.4rem 0.4rem 0.4rem rgba(0,0,0,.1);
39+
--highlight-color-tip: #C4F2FF;
40+
--highlight-color-inofficial: #F0F3F5;
41+
--highlight-color-important: #FFE3D9;
42+
}
43+
44+
html[data-theme="dark"] {
45+
--pagefind-ui-text: #fff;
46+
--link-default: #FF6B3D;
47+
--link-hovered: #FF8A5B;
48+
--link-special: #FFFFFF;
49+
--bg-default: #1a1a1a;
50+
--bg-neutral: #2d2d2d;
51+
--bg-accent: #86761a;
52+
--bg-accent2: #DABA00;
53+
--bg-accent3: #fff284;
54+
--color-onLight: #FFFFFF;
55+
--color-table-border: #555;
56+
--color-body: #e0e0e0;
57+
--pagefind-ui-border: #555;
58+
--box-shadow: 0 .4rem 1rem rgba(0,0,0,.5);
59+
--box-shadow-light: 0.4rem 0.4rem 0.4rem rgba(0,0,0,.3);
60+
--pagefind-ui-background: var(--bg-default);
61+
--highlight-color-tip: #1A4A5C;
62+
--highlight-color-inofficial: #2A2D30;
63+
--highlight-color-important: #4A2A1A;
4164
}

assets/sass/button.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
a.a-button {
1+
.a-button {
22
padding: 1rem;
33
display: inline-flex;
44
align-items: center;
@@ -9,6 +9,8 @@ a.a-button {
99
cursor: pointer;
1010
text-decoration: none;
1111
transition: background 0.2s, color 0.2s;
12+
background: transparent;
13+
color: var(--body-color);
1214

1315
&:hover,
1416
&:focus {

assets/sass/content.scss

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
code {
1010
font-size: inherit;
1111
font-weight: 700;
12-
color: var(--color-onLight);
12+
color: $color-onLight;
1313
background-color: var(--bg-accent3);
1414
padding: .2rem .8rem;
1515
border-radius: var(--border-radius-s);
@@ -31,8 +31,8 @@ thead {
3131
}
3232

3333
th {
34-
background: $link-hovered;
35-
color: white;
34+
background: var(--link-hovered);
35+
color: var(--bg-neutral);
3636
text-align: left;
3737
}
3838
}
@@ -43,7 +43,7 @@ tbody {
4343
}
4444

4545
tr:nth-of-type(even) {
46-
background-color: $bg-default;
46+
background-color: var(--bg-default);
4747
}
4848

4949
tr:last-of-type {

assets/sass/form.scss

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,17 @@
1515

1616
input[type=text], input[type=email], select, textarea {
1717
margin-bottom: 1.6rem;
18-
border-radius: var(--border-radius-l);
19-
border-width: .2rem;
20-
border-color: var(--color-onLight);
18+
border: .2rem solid var(--link-default);
19+
border-radius: var(--border-radius-m);
2120
padding: 1.2rem;
21+
background-color: var(--bg-neutral);
22+
color: var(--body-color);
23+
resize: vertical;
2224

2325
@media (min-width: #{$breakpoint-md}) {
2426
width: 50%;
2527
}
2628
}
27-
input[type=submit] {
28-
width: auto;
29-
padding: 1.2rem 2.4rem;
30-
background-color: var(--bg-accent);
31-
color: var(--color-onLight);
32-
border: none;
33-
border-radius: var(--border-radius-l);
34-
transition: background-color .3s ease;
35-
font-weight: 700;
36-
cursor: pointer;
37-
38-
&:hover,
39-
&:focus {
40-
background-color: var(--bg-accent2);
41-
}
42-
}
4329
}
4430

4531
#success {

assets/sass/navigation.scss

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
pointer-events: none;
8585
background-color: var(--bg-neutral);
8686
border-radius: var(--border-radius-s);
87-
color: var(--color-onDark);
87+
color: var(--bg-default);
8888

8989
&:focus {
9090
opacity: 1;
@@ -114,7 +114,7 @@
114114
background: none;
115115
width: fit-content;
116116
text-align: right;
117-
color: black;
117+
color: var(--color-body);
118118
font-weight: 700;
119119

120120
&:hover,
@@ -153,7 +153,7 @@
153153
position: absolute;
154154
padding: 1rem;
155155
justify-items: flex-start;
156-
background-color: white;
156+
background-color: var(--bg-default);
157157
box-shadow: 0 .4rem 1rem 0 rgba(0,0,0,.1);
158158
border-radius: var(--border-radius-s);
159159

@@ -194,7 +194,7 @@
194194
width: 70%;
195195
height: 100%;
196196
z-index: 4;
197-
background-color: white;
197+
background-color: var(--bg-default);
198198
padding: 0 1rem;
199199
overflow-y: scroll;
200200

@@ -242,3 +242,33 @@ body:has(.o-header__nav--open) {
242242
display: none;
243243
}
244244
}
245+
246+
.a-theme-toggle {
247+
padding: 1.2rem;
248+
margin: 0.6rem;
249+
border: none;
250+
background: transparent;
251+
width: fit-content;
252+
color: var(--color-body);
253+
transition: color 0.3s ease;
254+
255+
&:hover {
256+
color: var(--link-hovered);
257+
}
258+
259+
&--desktop {
260+
display: none;
261+
262+
@media (min-width: #{$breakpoint-md}) {
263+
display: inline-flex;
264+
}
265+
}
266+
267+
&--mobile {
268+
display: inline-flex;
269+
270+
@media (min-width: #{$breakpoint-md}) {
271+
display: none;
272+
}
273+
}
274+
}

assets/sass/search.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
}
2323

2424
&::placeholder {
25-
color: var(--color-onLight);
2625
opacity: .5;
2726
}
2827
}
@@ -44,7 +43,7 @@
4443
}
4544

4645
.pagefind-ui__drawer {
47-
background-color: white;
46+
background-color: var(--bg-default);
4847
padding: 0 1rem 1rem 1rem;
4948
overscroll-behavior: contain;
5049
height: 35rem;

0 commit comments

Comments
 (0)