Improve i18n (#61)

- add support for RTL languages
- fix bug with non-existent locale in localStorage
- add globe icon to detect the language field
This commit is contained in:
Nikita Karamov 2024-01-20 16:44:36 +01:00 committed by GitHub
commit 8304cf0f10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 32 additions and 24 deletions

View file

@ -15,7 +15,10 @@ const { instance, errors } = Astro.props;
data-translate="instance"
>
Fediverse instance
<div class="instance-input">
<div
class="instance-input"
dir="ltr"
>
<span id="https-label">https://</span>
<input
type="text"
@ -90,7 +93,7 @@ const { instance, errors } = Astro.props;
}
#saved-instances {
margin-bottom: 1rem;
margin-block-end: 1rem;
> div {
display: inline-block;

View file

@ -11,8 +11,8 @@ import { languages } from "@i18n/translations";
const initialLanguage = "en";
---
<label data-translate="language">
Language:
<label>
🌍 <span data-translate="language">Language:</span>
<select
name="language"
id="language"
@ -24,7 +24,7 @@ const initialLanguage = "en";
selected={k === initialLanguage}
value={k}
>
{v}
{v.autonym}
</option>
);
})

View file

@ -9,9 +9,6 @@
import { strings, defaultLanguage, languages } from "./translations";
export function useTranslations(language: string) {
if (!(language in strings)) {
language = defaultLanguage;
}
return function t(
key: keyof (typeof strings)[typeof defaultLanguage],
): string {
@ -46,6 +43,9 @@ export function findBestLanguage(): string {
}
export function applyTranslations(language: string) {
if (!(language in strings)) {
language = defaultLanguage;
}
const t = useTranslations(language);
for (const node of document.querySelectorAll("[data-translate]")) {
@ -71,4 +71,8 @@ export function applyTranslations(language: string) {
}
}
}
document.documentElement.lang = language;
document.documentElement.dir =
languages[language as keyof typeof languages].dir;
}

View file

@ -14,12 +14,12 @@ import nl from "./translations/nl.json";
import ru from "./translations/ru.json";
export const languages = {
en: "English",
de: "Deutsch",
es: "Español",
fr: "Français",
nl: "Nederlands",
ru: "Русский",
en: { autonym: "English", dir: "ltr" },
de: { autonym: "Deutsch", dir: "ltr" },
es: { autonym: "Español", dir: "ltr" },
fr: { autonym: "Français", dir: "ltr" },
nl: { autonym: "Nederlands", dir: "ltr" },
ru: { autonym: "Русский", dir: "ltr" },
};
export const strings: Record<keyof typeof languages, Record<string, string>> = {

View file

@ -39,7 +39,8 @@ html {
body {
max-width: 60em;
margin: 0 auto;
margin-block: 0;
margin-inline: auto;
display: flex;
flex-flow: row wrap;
@ -55,19 +56,16 @@ header {
display: flex;
align-items: center;
justify-content: space-between;
> div {
text-align: right;
}
}
main {
margin-bottom: 2rem;
margin-block-end: 2rem;
}
main,
aside {
padding: 0 1rem;
padding-block: 0;
padding-inline: 1rem;
}
hr {
@ -110,6 +108,7 @@ textarea {
textarea {
resize: vertical;
resize: block;
}
input[type="text"],
@ -130,7 +129,8 @@ input[type="submit"] {
color: var(--s2f-button-text-color);
font-weight: bolder;
height: 2.5rem;
padding: 0.5rem 1.5rem;
padding-block: 0.5rem;
padding-inline: 1.5rem;
border: 0;
cursor: pointer;
appearance: button;
@ -175,9 +175,10 @@ input[type="submit"] {
p.error {
color: var(--s2f-error-color);
margin: 0 0 1rem;
margin-block: 0 1rem;
margin-inline: 0;
}
.mt1r {
margin-top: 1rem !important;
margin-block-start: 1rem !important;
}