Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(documentation-website): add language switch on footer (#702) #874

Merged
7 changes: 7 additions & 0 deletions documentation-website/language/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -500,3 +500,10 @@ cookie-consent:
youtube:
title: "YouTube"
description: "We will load videos from www.youtube-nocookie.com to directly play on the site."

language-switch:
aria: "Language switch"

languages:
en: "English"
fr: "Français"
4 changes: 4 additions & 0 deletions documentation-website/src/components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import {
NavLink,
} from 'react-router-dom';
import CookieConsent from './cookie-consent.tsx';
import LanguageSwitch from './language-switch.tsx';

const Footer = () => <footer>
<span>©2020-2024 Björn Büttner and contributors.</span>
<ul>
<li>
<LanguageSwitch />
</li>
<li>
<CookieConsent />
</li>
Expand Down
4 changes: 4 additions & 0 deletions documentation-website/src/components/language-switch.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
select.language-switch {
appearance: auto;
cursor: pointer;
}
57 changes: 57 additions & 0 deletions documentation-website/src/components/language-switch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, {
Idrinth marked this conversation as resolved.
Show resolved Hide resolved
lazy,
Suspense,
useState,
} from 'react';
import Lang from './lang.tsx';
import languages from '../locales/languages';
import languageKey from '../locales/language-key.ts';
import t from './t.ts';
import Window from './window.ts';
import './language-switch.scss';

const LanguageSwitch = () => {
const that: Window = window as unknown as Window;

const [
language,
setLanguage,
] = useState<string>(() => that?.localStorage?.getItem('language',) ?? 'en',);

const changeLanguage = (newLanguage: string,) => {
setLanguage(newLanguage,);
that?.localStorage?.setItem('language', newLanguage,);
// reload page
that?.location?.reload();
Idrinth marked this conversation as resolved.
Show resolved Hide resolved
Idrinth marked this conversation as resolved.
Show resolved Hide resolved
};

const EL = lazy(async() => {
const ariaLabel = await t('language-switch.aria',);
return {
default: () => <select
className='language-switch'
aria-label={ ariaLabel }
value={ language }
onChange={ (event,) => changeLanguage(event.target.value,) }
>{
languages.map((lang,) => <option
key={ lang }
value={ lang }
>
<Lang lnkey={`languages.${ lang }` as languageKey}/>
</option>,)
}
</select>,
};
},);

return <Suspense fallback={
Idrinth marked this conversation as resolved.
Show resolved Hide resolved
<select className='language-switch'>{ languages.map((lang,) => <option
key={ lang }
value={ lang }
>{ lang }</option>,) }</select>}>
<EL/>
</Suspense>;
};

export default LanguageSwitch;
7 changes: 5 additions & 2 deletions documentation-website/src/components/t.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ export default async(lnkey: languageKey, global?: object,): Promise<string> => {
return '';
}
const that: Window = (global ?? window) as Window;
const language = (that?.Navigator?.language ?? 'en')
.replace(/-.*$/u, '',);
const language = (
(that?.localStorage?.getItem('language',) || 'en')
?? that?.Navigator?.language
?? 'en'
).split('-',)[FIRST_ELEMENT];
const main = lnkey.split('.',)[FIRST_ELEMENT];
if (! files.includes(`en-${ main }`,)) {
return lnkey;
Expand Down
3 changes: 3 additions & 0 deletions documentation-website/src/components/window.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
interface Window {
location: {
reload(): void,
},
localStorage: {
getItem(key: string): string,
setItem(key: string, value: string): string
Expand Down
2 changes: 2 additions & 0 deletions documentation-website/src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,9 @@ header #medium img {
header {
grid-template-columns: 30% auto 5%;
}
}

@media only screen and (width >= 950px) {
footer {
flex-direction: row;
justify-content: space-between;
Expand Down
Loading