From d370d83b2eced8882e09494597d088edca6622e9 Mon Sep 17 00:00:00 2001 From: MoritzWeber Date: Tue, 15 Jul 2025 22:32:28 +0200 Subject: [PATCH 1/6] feat: Add language switcher --- assets/js/languageSwitcher.js | 28 +++++++++++++ assets/js/main.js | 1 + assets/sass/footer.scss | 75 ++++++++++++++++++++++++++++++++++- i18n/de.yaml | 3 ++ i18n/en.yaml | 3 ++ layouts/partials/footer.html | 23 +++++++++-- layouts/partials/menu.html | 2 +- 7 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 assets/js/languageSwitcher.js diff --git a/assets/js/languageSwitcher.js b/assets/js/languageSwitcher.js new file mode 100644 index 00000000..9e36509b --- /dev/null +++ b/assets/js/languageSwitcher.js @@ -0,0 +1,28 @@ +document.addEventListener('DOMContentLoaded', function() { + const languageSwitcher = document.querySelector('.o-language-switcher'); + + if (!languageSwitcher) return; + + const button = languageSwitcher.querySelector('.o-language-switcher__button'); + const dropdown = languageSwitcher.querySelector('.o-language-switcher__dropdown'); + + button.addEventListener('click', function() { + const expanded = button.getAttribute('aria-expanded') === 'true'; + button.setAttribute('aria-expanded', !expanded); + dropdown.setAttribute('aria-hidden', expanded); + }); + + document.addEventListener('click', function(event) { + if (!languageSwitcher.contains(event.target)) { + button.setAttribute('aria-expanded', 'false'); + dropdown.setAttribute('aria-hidden', 'true'); + } + }); + + document.addEventListener('keydown', function(event) { + if (event.key === 'Escape' && button.getAttribute('aria-expanded') === 'true') { + button.setAttribute('aria-expanded', 'false'); + dropdown.setAttribute('aria-hidden', 'true'); + } + }); +}); diff --git a/assets/js/main.js b/assets/js/main.js index 09dcb987..fb118887 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -4,3 +4,4 @@ import './resizeObserver.js'; import './mediaqueries.js'; import './highlightHeadline.js'; import './anchorlinks.js'; +import './languageSwitcher.js'; diff --git a/assets/sass/footer.scss b/assets/sass/footer.scss index 0f6c44a4..751262d5 100644 --- a/assets/sass/footer.scss +++ b/assets/sass/footer.scss @@ -1,6 +1,9 @@ .o-footer { margin-top: 2rem; margin-bottom: 2rem; + display: flex; + flex-direction: column; + gap: 0.8rem; } .o-footer__links { @@ -31,8 +34,78 @@ } } -.o-footer__firstline { +.o-footer__line { display: flex; justify-content: space-between; + align-items: center; flex-wrap: wrap; + gap: 1rem; +} + +.o-language-switcher { + position: relative; +} + +.o-language-switcher__button { + border: 0; + background-color: var(--bg-neutral); + display: flex; + font-weight: 500; + padding: 1rem 1rem 1rem 0; +} + +.o-language-switcher__current { + margin-right: 0.5rem; +} + +.o-language-switcher__icon { + font-size: 0.7rem; + transition: transform 0.2s; +} + +.o-language-switcher__button[aria-expanded="true"] .o-language-switcher__icon { + transform: rotate(180deg); + + @media (max-width: #{$breakpoint-lg}) { + transform: rotate(0deg); + } +} + +.o-language-switcher__dropdown { + display: none; + position: absolute; + bottom: 100%; + right: 0; + background: var(--bg-neutral); + border-top-left-radius: 4px; + border-top-right-radius: 4px; + list-style: none; + width: min-content; + margin-bottom: 0; + padding-left: 0; + box-shadow: var(--box-shadow); +} + +.o-language-switcher__button[aria-expanded="true"] + .o-language-switcher__dropdown { + display: block; +} + +.o-language-switcher__item { + margin: 1.6rem; +} + +.o-language-switcher__link { + text-decoration: none; + font-weight: 400; + white-space: nowrap; + + &:hover, + &:focus { + color: var(--link-hovered); + } + + &--active { + color: var(--link-default); + font-weight: 700; + } } diff --git a/i18n/de.yaml b/i18n/de.yaml index e6d5f75e..c71ceb01 100644 --- a/i18n/de.yaml +++ b/i18n/de.yaml @@ -32,6 +32,9 @@ home-page-text: FIP Guide Startseite information-disclaimer-short: >- Diese Informationen sind inoffiziell und ohne Gewähr. Es besteht keine rechtliche Verbindung zu FIP oder Bahngesellschaften. +language-switcher: + aria-label: Sprache wechseln + label: Sprache menu-close: Schließen menu-open: Menü navigate-to-country: Gehe zu Land diff --git a/i18n/en.yaml b/i18n/en.yaml index e1638ee7..e9308029 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -31,6 +31,9 @@ home-page-text: FIP Guide Home Page information-disclaimer-short: >- The information provided is unofficial and without guarantee. There is no legal connection to FIP or railway companies. +language-switcher: + aria-label: Switch language + label: Language menu-close: Close menu-open: Menu navigate-to-country: Navigate to country diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html index e2f7572f..3ee721e2 100644 --- a/layouts/partials/footer.html +++ b/layouts/partials/footer.html @@ -1,5 +1,5 @@