Add language switcher

This commit is contained in:
Kitaiti Makoto 2020-12-20 15:10:53 +09:00
parent fee42c1bce
commit fe5712c080
5 changed files with 139 additions and 1 deletions

34
data/languages.yaml Normal file
View file

@ -0,0 +1,34 @@
---
af: Afrikaans
ar: العربية
ca: Català
cs: Česky
da: Dansk
de: Deutsch
el: Ελληνικά
en: English
eo: Esperanto
es: Español
fa: فارسی
fi: Suomi
fr: Français
gl: Galego
he: עברית
hu: Magyar
it: Italiano
ja: 日本語
ko: 한국어
nl: Nederlands
'no': Norsk (bokmål)
pl: Polski
pt: Português
ro: Română
ru: Русский
sat: ᱥᱟᱱᱛᱟᱲᱤ
si: සිංහල
sr: Српски
sv: Svenska
tr: Türkçe
uk: Українська
vi: Việtnam
zh: 中文

BIN
source/images/LanguageIcon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View file

@ -1,3 +1,23 @@
document.getElementById('menu').addEventListener('click', evt => document.getElementById('menu').addEventListener('click', evt =>
evt.target.parentElement.classList.toggle('show') evt.target.parentElement.classList.toggle('show')
) )
document.addEventListener('DOMContentLoaded', () => {
for (const switcher of document.getElementsByClassName('language-switcher')) {
const control = switcher.querySelector('[aria-haspopup]');
control.addEventListener('click', event => {
const popupId = control.getAttribute('aria-controls');
if (! popupId) return;
const popup = document.getElementById(popupId);
if (! popup) return;
if (control.getAttribute('aria-expanded') === 'true') {
control.setAttribute('aria-expanded', 'false');
popup.setAttribute('aria-hidden', 'true');
} else {
control.setAttribute('aria-expanded', 'true');
popup.setAttribute('aria-hidden', 'false');
}
});
}
});

View file

@ -28,6 +28,14 @@
<header> <header>
<h1><%= current_page.data.title %></h1> <h1><%= current_page.data.title %></h1>
<p><%= current_page.data.summary %></p> <p><%= current_page.data.summary %></p>
<div class="language-switcher">
<button aria-controls="languages" aria-haspopup="true" aria-expanded="false"><img src="/images/LanguageIcon.png" alt="switch language"></button>
<ul id="languages" class="languages" aria-hidden="true">
<% data.languages.each_pair do |code, name| %>
<li lang="<%=h code %>" translate="no" class="language"><%= link_to h(name), code == "en" ? "/" : "/#{code}/", hreflang: h(code), rel: "alternate" %></li>
<% end %>
</ul>
</div>
</header> </header>
<aside> <aside>
<i id="menu" data-feather="menu"></i> <i id="menu" data-feather="menu"></i>

View file

@ -5,6 +5,11 @@ $black: invert($gray);
@import url('https://fonts.googleapis.com/css?family=Playfair+Display'); @import url('https://fonts.googleapis.com/css?family=Playfair+Display');
:root {
--lang-switcher-margin: 2vw;
--lang-switcher-width: 2em;
}
html, body { html, body {
padding: 0px; padding: 0px;
margin: 0px; margin: 0px;
@ -22,6 +27,15 @@ header {
background: linear-gradient(0deg, $plumedark, $plume); background: linear-gradient(0deg, $plumedark, $plume);
color: white; color: white;
font-size: 1.5em; font-size: 1.5em;
.language-switcher {
position: absolute;
top: var(--lang-switcher-margin);
right: var(--lang-switcher-margin);
margin: 0;
padding: 0;
line-height: 1;
}
} }
body { body {
@ -346,3 +360,65 @@ a.action {
"foot foot foot foot foot"; "foot foot foot foot foot";
} }
} }
.language-switcher {
position: relative;
font-size: 1rem;
[aria-haspopup] {
display: block;
width: var(--lang-switcher-width);
padding: 0;
line-height: 1;
border: none;
background: transparent;
&:hover {
opacity: 0.5;
}
&[aria-expanded="true"] {
opacity: 0.5;
}
img {
width: 100%;
height: auto;
}
}
[aria-hidden="true"] {
display: none;
}
.languages {
position: absolute;
right: 0;
list-style: none;
margin: 0;
padding: 0.5em 0;
max-height: calc(90vh - var(--lang-switcher-margin) - var(--lang-switcher-width));
overflow-y: scroll;
overscroll-behavior: contain;
border-radius: 0.1em;
background: #ffffff;
box-shadow: 0 0 16px -6px rgba(0, 0, 0, 0.6);
}
.language {
padding: 0;
a {
display: block;
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 0.5em 1em;
border-left: solid 0.5em transparent;
&:hover, &:focus {
border-left-color: $plume;
}
}
}
}