Skip to content

Commit a10e150

Browse files
committed
added theme change functionality
1 parent 7cd175f commit a10e150

File tree

9 files changed

+128
-49
lines changed

9 files changed

+128
-49
lines changed

index.html

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ <h3 class="output-placeholder-title" data-translation="output.placeholder.title"
7979
</main>
8080
<footer>
8181
<div class="container">
82-
<nav class="footer-language-nav" aria-labelledby="language-nav-label">
82+
<nav class="footer-nav" aria-labelledby="language-nav-label">
8383
<span id="language-nav-label" hidden aria-hidden="true" data-translation="footer.language.label">Change language</span>
8484
<span id="language-icon-label" hidden aria-hidden="true" data-translation="footer.language.icon">Globe</span>
8585
<svg width="24" height="24" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="language-icon" aria-labelledby="language-icon-label">
@@ -88,13 +88,30 @@ <h3 class="output-placeholder-title" data-translation="output.placeholder.title"
8888
</g>
8989
</svg>
9090
<span id="language-link-en-label" hidden aria-hidden="true">English</span>
91-
<a id="language-link-en" href="#" class="footer-language-link en" aria-labelledby="language-link-en-label">EN<a>
91+
<a id="language-link-en" href="#" class="footer-nav-link en" aria-labelledby="language-link-en-label">EN<a>
9292
<span id="language-link-pt-label" hidden aria-hidden="true">Português</span>
93-
<a id="language-link-pt" href="#" class="footer-language-link pt" aria-labelledby="language-link-pt-label">PT</a>
93+
<a id="language-link-pt" href="#" class="footer-nav-link pt" aria-labelledby="language-link-pt-label">PT</a>
9494
</nav>
9595
<p class="footer-credits">
96-
<span data-translation="footer.credits">made with 💜 by</span> <a href="https://github.com/novcmbro" class="footer-novcmbro-link" target="_blank" rel="noopener noreferrer" aria-label="GitHub">Novcmbro</a>
96+
<span data-translation="footer.credits">made with 💜 by</span> <a href="https://github.com/novcmbro" class="footer-credits-novcmbro-link" target="_blank" rel="noopener noreferrer" aria-label="GitHub">Novcmbro</a>
9797
</p>
98+
<nav class="footer-nav" aria-labelledby="theme-nav-label">
99+
<span id="theme-nav-label" hidden aria-hidden="true" data-translation="footer.theme.label">Change theme</span>
100+
<a id="theme-link-light" href="#" class="footer-nav-link light" aria-labelledby="theme-link-light-label">
101+
<span id="theme-link-light-label" hidden aria-hidden="true" data-translation="footer.theme.light.text">Light theme</span>
102+
<span id="theme-link-light-icon-label" hidden aria-hidden="true" data-translation="footer.theme.light.icon">Sun</span>
103+
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-labelledby="theme-link-light-icon-label">
104+
<path d="M12 4V2M12 20V22M6.41421 6.41421L5 5M17.728 17.728L19.1422 19.1422M4 12H2M20 12H22M17.7285 6.41421L19.1427 5M6.4147 17.728L5.00049 19.1422M12 17C9.23858 17 7 14.7614 7 12C7 9.23858 9.23858 7 12 7C14.7614 7 17 9.23858 17 12C17 14.7614 14.7614 17 12 17Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
105+
</svg>
106+
</a>
107+
<a id="theme-link-dark" href="#" class="footer-nav-link dark" aria-labelledby="theme-link-dark-label">
108+
<span id="theme-link-dark-label" hidden aria-hidden="true" data-translation="footer.theme.dark.text">Dark theme</span>
109+
<span id="theme-link-dark-icon-label" hidden aria-hidden="true" data-translation="footer.theme.dark.icon">Moon</span>
110+
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-labelledby="theme-link-dark-icon-label">
111+
<path d="M3.32031 11.6835C3.32031 16.6541 7.34975 20.6835 12.3203 20.6835C16.1075 20.6835 19.3483 18.3443 20.6768 15.032C19.6402 15.4486 18.5059 15.6834 17.3203 15.6834C12.3497 15.6834 8.32031 11.654 8.32031 6.68342C8.32031 5.50338 8.55165 4.36259 8.96453 3.32996C5.65605 4.66028 3.32031 7.89912 3.32031 11.6835Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
112+
</svg>
113+
</a>
114+
</nav>
98115
</div>
99116
</footer>
100117
</body>

src/css/footer.css

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,45 @@
11
footer .container {
22
display: flex;
3-
flex-direction: column;
3+
flex-wrap: wrap;
4+
justify-content: space-between;
45
align-items: center;
56
gap: var(--spacing-sm) var(--spacing-base);
6-
text-align: center;
77
padding: var(--spacing-base);
88
}
99

10-
.footer-language-nav .language-icon {
11-
vertical-align: text-bottom;
10+
.language-icon {
11+
vertical-align: middle;
1212
margin-right: var(--spacing-sm);
1313
}
1414

15-
.footer-language-link.pt:lang(en),
16-
.footer-language-link.en:lang(pt) {
15+
.footer-nav-link.en:lang(pt),
16+
.footer-nav-link.pt:lang(en),
17+
:root.light .footer-nav-link.dark,
18+
.dark .footer-nav-link.light {
1719
opacity: 0.47;
1820
}
1921

20-
.footer-language-link.pt:lang(en):hover,
21-
.footer-language-link.en:lang(pt):hover {
22+
.footer-nav-link.en:lang(pt):hover,
23+
.footer-nav-link.pt:lang(en):hover,
24+
:root.light .footer-nav-link.dark:hover,
25+
:root.dark .footer-nav-link.light:hover {
2226
opacity: 1;
2327
transition: opacity var(--transition-duration);
2428
}
2529

26-
.footer-novcmbro-link {
30+
.footer-credits-novcmbro-link {
2731
font-weight: var(--font-bold);
2832
}
2933

30-
@media screen and (min-width: 700px) {
31-
footer .container {
32-
flex-direction: row;
33-
justify-content: space-between;
34-
}
34+
.footer-nav-link.light,
35+
.footer-nav-link.dark {
36+
display: inline-block;
37+
}
3538

39+
@media screen and (max-width: 520px) {
3640
.footer-credits {
41+
order: 3;
42+
text-align: center;
3743
margin: 0 auto;
3844
}
3945
}

src/css/index.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
font-size: var(--font-md);
4242
font-weight: var(--font-medium);
4343
scroll-behavior: smooth;
44+
transition: background-color var(--transition-duration), color var(--transition-duration);
4445
}
4546

4647
* {

src/css/output.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
border-radius: var(--shape);
44
flex-grow: 1;
55
padding: var(--spacing-md);
6+
transition: background-color var(--transition-duration);
67
}
78

89
.output-placeholder:not([hidden]) {

src/css/themes.css

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,26 @@
1-
@media (prefers-color-scheme: light) {
2-
:root {
3-
background-color: var(--dark-white);
4-
color: var(--dark-gray);
5-
}
1+
:root.light {
2+
background-color: var(--dark-white);
3+
color: var(--dark-gray);
4+
}
65

7-
.input-section {
8-
outline-color: var(--white);
9-
}
6+
:root.light .input-section:not(.input-field-has-focus, .input-field-is-invalid) {
7+
outline-color: var(--white);
8+
}
109

11-
.output-section {
12-
background-color: var(--white);
13-
}
10+
:root.light .output-section {
11+
background-color: var(--white);
1412
}
1513

16-
@media (prefers-color-scheme: dark) {
17-
:root {
18-
--shadow-opacity: 1;
19-
background-color: var(--black);
20-
color: var(--white);
21-
}
14+
:root.dark {
15+
--shadow-opacity: 1;
16+
background-color: var(--black);
17+
color: var(--white);
18+
}
2219

23-
.input-section {
24-
outline-color: var(--light-black);
25-
}
20+
:root.dark .input-section:not(.input-field-has-focus, .input-field-is-invalid) {
21+
outline-color: var(--light-black);
22+
}
2623

27-
.output-section {
28-
background-color: var(--light-black);
29-
}
24+
:root.dark .output-section {
25+
background-color: var(--light-black);
3026
}

src/js/index.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import theme from "./theme.js"
12
import { changeLanguage, initTranslation, translation } from "./translation.js"
23
import cryptographyEntries from "./cryptographyEntries.js"
34
import copyOutputText from "./copyOutputText.js"
45

56
document.addEventListener("DOMContentLoaded", () => {
7+
theme.init()
68
initTranslation()
79

810
const inputField = document.querySelector("#input-field")
@@ -16,6 +18,8 @@ document.addEventListener("DOMContentLoaded", () => {
1618
const copyButton = document.querySelector("#copy-button")
1719
const languageLinkEN = document.querySelector("#language-link-en")
1820
const languageLinkPT = document.querySelector("#language-link-pt")
21+
const themeLinkLight = document.querySelector("#theme-link-light")
22+
const themeLinkDark = document.querySelector("#theme-link-dark")
1923

2024
const cryptography = (target) => {
2125
const entries = target === encryptButton ? cryptographyEntries : Object.fromEntries(Object.entries(cryptographyEntries).map(([letter, word]) => [word, letter]))
@@ -70,12 +74,8 @@ document.addEventListener("DOMContentLoaded", () => {
7074
}
7175
}
7276

73-
inputField.addEventListener("focus", toggleInputFocusClass)
74-
inputField.addEventListener("blur", toggleInputFocusClass)
75-
inputField.addEventListener("input", clearInputFieldError)
76-
encryptButton.addEventListener("click", handleCryptography)
77-
decryptButton.addEventListener("click", handleCryptography)
78-
copyButton.addEventListener("click", () => copyOutputText(outputField))
77+
themeLinkLight.addEventListener("click", theme.change)
78+
themeLinkDark.addEventListener("click", theme.change)
7979
languageLinkEN.addEventListener("click", (e) => {
8080
changeLanguage(e)
8181
clearInputFieldError()
@@ -84,4 +84,10 @@ document.addEventListener("DOMContentLoaded", () => {
8484
changeLanguage(e)
8585
clearInputFieldError()
8686
})
87+
inputField.addEventListener("focus", toggleInputFocusClass)
88+
inputField.addEventListener("blur", toggleInputFocusClass)
89+
inputField.addEventListener("input", clearInputFieldError)
90+
encryptButton.addEventListener("click", handleCryptography)
91+
decryptButton.addEventListener("click", handleCryptography)
92+
copyButton.addEventListener("click", () => copyOutputText(outputField))
8793
})

src/js/theme.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const localStorageKey = "novcmbro_decoder_theme"
2+
const rootElement = document.documentElement
3+
4+
const theme = {
5+
db: () => localStorage.getItem(localStorageKey),
6+
update: undefined,
7+
init: undefined,
8+
change: undefined
9+
}
10+
11+
theme.update = () => rootElement.classList = theme.db()
12+
13+
theme.init = () => {
14+
const prefersLightTheme = window.matchMedia("(prefers-color-scheme: light)").matches
15+
16+
if (!theme.db()) {
17+
localStorage.setItem(localStorageKey, prefersLightTheme ? "light" : "dark")
18+
}
19+
20+
theme.update()
21+
}
22+
23+
theme.change = ({ currentTarget }) => {
24+
const themeName = currentTarget.classList[1]
25+
localStorage.setItem(localStorageKey, themeName)
26+
theme.update()
27+
}
28+
29+
const { init, change } = theme
30+
export default { init, change }

src/locales/en-us.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,18 @@ const enUS = {
4242
label: "Change language",
4343
icon: "Globe"
4444
},
45-
credits: "made with 💜 by"
45+
credits: "made with 💜 by",
46+
theme: {
47+
label: "Change theme",
48+
light: {
49+
text: "Light theme",
50+
icon: "Sun"
51+
},
52+
dark: {
53+
text: "Dark theme",
54+
icon: "Moon"
55+
}
56+
}
4657
}
4758
}
4859

src/locales/pt-br.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,18 @@ const ptBR = {
4242
label: "Mudar idioma",
4343
icon: "Globo"
4444
},
45-
credits: "feito com 💜 por"
45+
credits: "feito com 💜 por",
46+
theme: {
47+
label: "Mudar tema",
48+
light: {
49+
text: "Tema claro",
50+
icon: "Sol"
51+
},
52+
dark: {
53+
text: "Tema escuro",
54+
icon: "Lua"
55+
}
56+
}
4657
}
4758
}
4859

0 commit comments

Comments
 (0)