Replace native <select> language picker with styled dropdown
Build and Deploy Verso / deploy (push) Successful in 13m43s
Build and Deploy Verso / deploy (push) Successful in 13m43s
The native <select> looked like a form control ("cheap"). Replace it with
the same HTML+CSS pattern as the React LanguagePicker: btn-inline-link
toggle with a translate icon, Bootstrap dropdown-menu for the list, active
item highlighted in green.
A tiny self-contained inline script handles the toggle since Bootstrap JS
is not loaded on React-layout pages. It builds the return_to URL from
window.location.pathname at click time (same as the old select approach).
Added top: auto / bottom: 100% to .language-picker .dropdown-menu so the
list always opens upward regardless of whether Popper.js is present.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,54 @@
|
||||
li.language-picker
|
||||
select.language-picker-select(
|
||||
name='lng'
|
||||
translate='no'
|
||||
onchange='window.location.href="/set-language?lng="+encodeURIComponent(this.value)+"&return_to="+encodeURIComponent(window.location.pathname)'
|
||||
aria-label=translate('select_a_language')
|
||||
)
|
||||
each lngCode in availableLanguages
|
||||
if settings.translatedLanguages[lngCode]
|
||||
option(value=lngCode selected=lngCode === currentLngCode)= settings.translatedLanguages[lngCode]
|
||||
.dropdown
|
||||
button#language-picker-toggle.btn-inline-link(
|
||||
type='button'
|
||||
aria-haspopup='true'
|
||||
aria-expanded='false'
|
||||
aria-label=translate('select_a_language')
|
||||
translate='no'
|
||||
)
|
||||
span.material-symbols translate
|
||||
|
|
||||
span.language-picker-text= settings.translatedLanguages[currentLngCode] || currentLngCode
|
||||
ul.dropdown-menu.dropdown-menu-sm-width(
|
||||
role='menu'
|
||||
aria-labelledby='language-picker-toggle'
|
||||
translate='no'
|
||||
)
|
||||
each lngCode in availableLanguages
|
||||
if settings.translatedLanguages[lngCode]
|
||||
li(role='none')
|
||||
a.dropdown-item(
|
||||
role='menuitem'
|
||||
data-lng=lngCode
|
||||
class=lngCode === currentLngCode ? 'active' : ''
|
||||
)= settings.translatedLanguages[lngCode]
|
||||
script.
|
||||
(function () {
|
||||
var toggle = document.getElementById('language-picker-toggle')
|
||||
var menu = toggle && toggle.parentElement.querySelector('.dropdown-menu')
|
||||
if (!toggle || !menu) return
|
||||
// Build return_to at runtime so the href reflects the actual current path
|
||||
menu.querySelectorAll('a[data-lng]').forEach(function (a) {
|
||||
var lng = a.getAttribute('data-lng')
|
||||
a.href =
|
||||
'/set-language?lng=' +
|
||||
encodeURIComponent(lng) +
|
||||
'&return_to=' +
|
||||
encodeURIComponent(window.location.pathname)
|
||||
})
|
||||
function close() {
|
||||
menu.classList.remove('show')
|
||||
toggle.setAttribute('aria-expanded', 'false')
|
||||
}
|
||||
toggle.addEventListener('click', function (e) {
|
||||
e.stopPropagation()
|
||||
var opening = !menu.classList.contains('show')
|
||||
menu.classList.toggle('show', opening)
|
||||
toggle.setAttribute('aria-expanded', String(opening))
|
||||
})
|
||||
document.addEventListener('click', close)
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Escape') { close(); toggle.focus() }
|
||||
})
|
||||
})()
|
||||
|
||||
@@ -218,6 +218,11 @@ footer.site-footer {
|
||||
}
|
||||
|
||||
.language-picker .dropdown-menu {
|
||||
// Open upward — Popper.js isn't available on all page layouts
|
||||
top: auto;
|
||||
bottom: 100%;
|
||||
margin-bottom: var(--spacing-02);
|
||||
|
||||
.dropdown-item {
|
||||
&.active {
|
||||
color: var(--green-70);
|
||||
|
||||
Reference in New Issue
Block a user