From 8a621e33487f89ca2fc758b87d141e27969ae111 Mon Sep 17 00:00:00 2001 From: Christian Fehmer Date: Wed, 8 Jul 2026 12:53:41 +0200 Subject: [PATCH] feat: allow languages to set specific fonts (@fehmer) --- docs/LANGUAGES.md | 2 ++ frontend/src/ts/ui.ts | 18 +++++++++++++----- frontend/static/languages/lao.json | 1 + packages/schemas/src/fonts.ts | 2 +- packages/schemas/src/languages.ts | 2 ++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/LANGUAGES.md b/docs/LANGUAGES.md index 6f380d669371..9e4afde83778 100644 --- a/docs/LANGUAGES.md +++ b/docs/LANGUAGES.md @@ -24,6 +24,7 @@ The contents of the file should be as follows: "joiningScript": boolean, "orderedByFrequency": boolean, "bcp47": string, + "fallbackFont":string, "words": string[] } ``` @@ -34,6 +35,7 @@ It is recommended that you familiarize yourselves with JSON before adding a lang For `bcp47` put your languages [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag). If the words you're adding are ordered by frequency (most common words at the top, least at the bottom) set the value of `orderedByFrequency` to `true`, otherwise `false`. Finally, add your list of words to the `words` field. +If the language is not rendered correctly, you can provide a `fallbackFont`. The font needs to be one of monkeytypes fonts. Check the [fonts documentation](./FONTS.md). Then, go to `packages/schemas/src/languages.ts` and add your new language name at the _end_ of the `LanguageSchema` enum. Make sure to end the line with a comma. Make sure to add all your language names if you have created multiple word lists of differing lengths in the same language. diff --git a/frontend/src/ts/ui.ts b/frontend/src/ts/ui.ts index 2283c1870186..535a1c2c5b25 100644 --- a/frontend/src/ts/ui.ts +++ b/frontend/src/ts/ui.ts @@ -17,6 +17,7 @@ import { qs, qsr } from "./utils/dom"; import { createEffect } from "solid-js"; import fileStorage from "./utils/file-storage"; import { convertRemToPixels } from "./utils/numbers"; +import { getLanguage } from "./utils/json-data"; let isPreviewingFont = false; export function previewFontFamily(font: FontName): void { @@ -48,10 +49,17 @@ export async function applyFontFamily(): Promise { }`); } - document.documentElement.style.setProperty( - "--font", - `"${font}", "Roboto Mono", "Vazirharf", monospace`, - ); + const fallbackFont = (await getLanguage(Config.language))?.fallbackFont; + + const fonts = [ + font, + fallbackFont !== undefined ? `"${fallbackFont}"` : undefined, + '"Roboto Mono"', + '"Vazirharf"', + "monospace", + ].filter((it) => it !== undefined); + + document.documentElement.style.setProperty("--font", fonts.join(",")); } export function clearFontPreview(): void { @@ -135,7 +143,7 @@ createEffect(() => { }); configEvent.subscribe(async ({ key }) => { - if (key === "fontFamily") { + if (key === "fontFamily" || key === "language") { await applyFontFamily(); } }); diff --git a/frontend/static/languages/lao.json b/frontend/static/languages/lao.json index e16bf468a60b..5e2e7c296789 100644 --- a/frontend/static/languages/lao.json +++ b/frontend/static/languages/lao.json @@ -4,6 +4,7 @@ "joiningScript": false, "orderedByFrequency": false, "bcp47": "lo", + "fallbackFont": "Noto_Sans_Lao", "words": [ "ຂ້ອຍ", "ເຈົ້າ", diff --git a/packages/schemas/src/fonts.ts b/packages/schemas/src/fonts.ts index ed7f13276c44..472ac8306231 100644 --- a/packages/schemas/src/fonts.ts +++ b/packages/schemas/src/fonts.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { customEnumErrorHandler } from "./util"; -const KnownFontNameSchema = z.enum( +export const KnownFontNameSchema = z.enum( [ "Roboto_Mono", "Noto_Naskh_Arabic", diff --git a/packages/schemas/src/languages.ts b/packages/schemas/src/languages.ts index 6bdef92a348f..e30cc81af84f 100644 --- a/packages/schemas/src/languages.ts +++ b/packages/schemas/src/languages.ts @@ -1,4 +1,5 @@ import { z } from "zod"; +import { KnownFontNameSchema } from "./fonts"; import { customEnumErrorHandler } from "./util"; export const LanguageSchema = z.enum( @@ -469,6 +470,7 @@ export const LanguageObjectSchema = z .array(z.tuple([z.string().min(1), z.string().min(1)])) .optional(), bcp47: z.string().optional(), + fallbackFont: KnownFontNameSchema.optional(), originalPunctuation: z.boolean().optional(), }) .strict();