UNPKG

@frank-auth/react

Version:

Flexible and customizable React UI components for Frank Authentication

207 lines (206 loc) 5.82 kB
import { DEFAULT_LOCALIZATION_CONFIG as h } from "./defaults.js"; import { DEFAULT_LOCALE_MESSAGES as N } from "./defaults.js"; import { LOCALE_INFO as s } from "../locales/index.js"; var g = Object.defineProperty, d = (a, e, t) => e in a ? g(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t, c = (a, e, t) => d(a, typeof e != "symbol" ? e + "" : e, t); class m { constructor(e) { c(this, "config"), c(this, "currentLocale"), c(this, "loadedMessages", /* @__PURE__ */ new Map()), c(this, "listeners", /* @__PURE__ */ new Set()), this.config = { ...h, ...e }, this.currentLocale = this.config.defaultLocale, this.loadedMessages.set(this.currentLocale, { ...s[this.currentLocale], ...this.config.messages }); } /** * Get current locale */ getCurrentLocale() { return this.currentLocale; } /** * Get current locale metadata */ getCurrentLocaleMetadata() { return s[this.currentLocale]; } /** * Set current locale */ async setLocale(e) { this.config.supportedLocales.includes(e) || (console.warn(`Locale ${e} is not supported. Falling back to ${this.config.fallbackLocale}`), e = this.config.fallbackLocale), this.currentLocale = e, this.loadedMessages.has(e) || await this.loadLocaleMessages(e), this.notifyListeners(); } /** * Get translation for a key */ t(e, t) { const r = this.getCurrentMessages(), o = this.getNestedValue(r, e); return typeof o != "string" ? (console.warn(`Translation key "${e}" not found for locale "${this.currentLocale}"`), e) : this.interpolate(o, t); } /** * Get plural translation */ plural(e, t) { const { count: r } = t, i = s[this.currentLocale].pluralRules.select(r); let n; if (r === 0 && t.zero) return this.interpolate(t.zero, { count: r }); switch (i) { case "one": n = t.one || t.other; break; case "two": n = t.two || t.other; break; case "few": n = t.few || t.other; break; case "many": n = t.many || t.other; break; default: n = t.other; } return this.interpolate(n, { count: r }); } /** * Format date according to current locale */ formatDate(e, t) { return s[this.currentLocale], new Intl.DateTimeFormat(this.currentLocale, { ...t, ...t || {} }).format(e); } /** * Format time according to current locale */ formatTime(e, t) { return new Intl.DateTimeFormat(this.currentLocale, { timeStyle: "short", ...t }).format(e); } /** * Format number according to current locale */ formatNumber(e, t) { const r = s[this.currentLocale]; return new Intl.NumberFormat(this.currentLocale, { ...r.numberFormat, ...t }).format(e); } /** * Format currency according to current locale */ formatCurrency(e, t, r) { return new Intl.NumberFormat(this.currentLocale, { style: "currency", currency: t, ...r }).format(e); } /** * Format relative time (e.g., "2 hours ago") */ formatRelativeTime(e, t) { const r = new Intl.RelativeTimeFormat(this.currentLocale, { numeric: "auto", ...t }), o = /* @__PURE__ */ new Date(), i = e.getTime() - o.getTime(), n = Math.round(i / 1e3), l = Math.round(n / 60), u = Math.round(l / 60), f = Math.round(u / 24); return Math.abs(n) < 60 ? r.format(n, "second") : Math.abs(l) < 60 ? r.format(l, "minute") : Math.abs(u) < 24 ? r.format(u, "hour") : r.format(f, "day"); } /** * Get available locales */ getAvailableLocales() { return this.config.supportedLocales.map((e) => ({ code: e, name: s[e].name, nativeName: s[e].nativeName })); } /** * Subscribe to locale changes */ subscribe(e) { return this.listeners.add(e), () => { this.listeners.delete(e); }; } /** * Update localization configuration */ updateConfig(e) { this.config = { ...this.config, ...e }, e.messages && this.loadedMessages.set(this.currentLocale, { ...s[this.currentLocale], ...this.config.messages }); } // Private methods getCurrentMessages() { return this.loadedMessages.get(this.currentLocale) || s[this.currentLocale]; } getNestedValue(e, t) { return t.split(".").reduce((r, o) => r?.[o], e); } interpolate(e, t) { return t ? e.replace(/\{\{(\w+)\}\}/g, (r, o) => { const i = t[o]; return i === void 0 ? r : i instanceof Date ? this.formatDate(i) : String(i); }) : e; } async loadLocaleMessages(e) { try { const t = s[e] || s[this.config.fallbackLocale]; this.loadedMessages.set(e, { ...t, ...this.config.messages }); } catch (t) { console.error(`Failed to load messages for locale ${e}:`, t); const r = s[this.config.fallbackLocale]; this.loadedMessages.set(e, r); } } notifyListeners() { this.listeners.forEach((e) => e(this.currentLocale)); } } function w(a) { return new m(a); } function p(a) { if (typeof navigator > "u") return "en"; const e = [ navigator.language, ...navigator.languages || [] ]; for (const t of e) { const r = t.split("-")[0]; if (a.includes(r)) return r; } return "en"; } function L(a) { return s[a]?.direction || "ltr"; } function y(a) { return L(a) === "rtl"; } function F(a, e) { return { t: (t, r) => a.t(`${e}.${t}`, r), plural: (t, r) => a.plural(`${e}.${t}`, r) }; } export { N as DEFAULT_LOCALE_MESSAGES, h as DEFAULT_LOCALIZATION_CONFIG, m as LocalizationManager, w as createLocalizationManager, F as createTranslationNamespace, p as detectBrowserLocale, L as getLocaleDirection, y as isRTL }; //# sourceMappingURL=localization.js.map