feat: store locale in localStorage to persist across page loads
This commit is contained in:
parent
4852f2d5d1
commit
59674292be
3 changed files with 70 additions and 69 deletions
|
|
@ -11,9 +11,10 @@
|
|||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.6",
|
||||
"@types/node": "^22.15.17",
|
||||
"axios": "^1.11.0",
|
||||
"@vueuse/components": "^13.3.0",
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"arktype": "^2.1.29",
|
||||
"axios": "^1.11.0",
|
||||
"bulma": "^1.0.4",
|
||||
"tailwindcss": "^4.1.6",
|
||||
"vue": "^3.5.13",
|
||||
|
|
|
|||
|
|
@ -1,20 +1,50 @@
|
|||
import en_US from "../locales/en_US";
|
||||
import vp_VL from "../locales/vp_VL";
|
||||
import wp_VL from "../locales/wp_VL";
|
||||
import { computed, readonly, ref, type DeepReadonly } from "vue";
|
||||
import { computed, readonly, type DeepReadonly } from "vue";
|
||||
import type { Locale } from "./locale";
|
||||
import type { DeepPartial } from "@/utils/deep-partial";
|
||||
import { useLocalStorage } from "@vueuse/core";
|
||||
import { type } from "arktype";
|
||||
|
||||
export const LOCALE_IDS = ["en_US", "vp_VL", "wp_VL"] as const;
|
||||
export type LocaleId = (typeof LOCALE_IDS)[number];
|
||||
|
||||
export type LocaleId = typeof LocaleId.infer;
|
||||
export const LocaleId = type.enumerated(...LOCALE_IDS);
|
||||
|
||||
export const DEFAULT_LOCALE_ID = "en_US" satisfies LocaleId;
|
||||
|
||||
const locales = { en_US, vp_VL, wp_VL } as const satisfies {
|
||||
en_US: Locale;
|
||||
} & Record<Exclude<LocaleId, "en_US">, DeepPartial<Locale>>;
|
||||
} & Record<Exclude<LocaleId, typeof DEFAULT_LOCALE_ID>, DeepPartial<Locale>>;
|
||||
|
||||
export const localeId = ref<LocaleId>("en_US");
|
||||
// users could manually edit localStorage to make this value anything, so we need to validate it
|
||||
const localStorageLocaleId = useLocalStorage<unknown>(
|
||||
"localeId",
|
||||
DEFAULT_LOCALE_ID,
|
||||
);
|
||||
|
||||
export function useLocale(opt: UseLocaleOptions = {}) {
|
||||
export const localeId = computed({
|
||||
get: (): LocaleId => {
|
||||
const localeIdRes = LocaleId(localStorageLocaleId.value);
|
||||
if (localeIdRes instanceof type.errors) {
|
||||
// if invalid LocaleId, reset to default
|
||||
localStorageLocaleId.value = DEFAULT_LOCALE_ID;
|
||||
return DEFAULT_LOCALE_ID;
|
||||
}
|
||||
|
||||
// else return user's selection
|
||||
const localeId = localeIdRes;
|
||||
return localeId;
|
||||
},
|
||||
// custom setter to ensure it is only set to a valid LocaleId by our code
|
||||
// (since the localStorage ref is typed as `unknown`, it can be set to any value)
|
||||
set: (id: LocaleId) => {
|
||||
localStorageLocaleId.value = id;
|
||||
},
|
||||
});
|
||||
|
||||
export const useLocale = (opt: UseLocaleOptions = {}) => {
|
||||
const locale = computed<DeepReadonly<Locale>>(() => {
|
||||
return fallbackProxy<Locale>(
|
||||
locales[opt.locale ?? localeId.value],
|
||||
|
|
@ -23,7 +53,7 @@ export function useLocale(opt: UseLocaleOptions = {}) {
|
|||
});
|
||||
|
||||
return readonly(locale);
|
||||
}
|
||||
};
|
||||
|
||||
export interface UseLocaleOptions {
|
||||
locale?: LocaleId;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue