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:
commit
8304cf0f10
5 changed files with 32 additions and 24 deletions
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
})
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>> = {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Reference in a new issue