react-native-localize.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Smart stub for react-native-localize that uses browser locale on web.
  2. // Date *order* must not read `navigator` during SSR/first paint — that is
  3. // handled by `useDateLocaleTag` in packages/app/lib/util/datetime.ts.
  4. const getBrowserLocale = () => {
  5. if (typeof navigator === 'undefined') {
  6. // Server-side fallback
  7. return { languageCode: 'en', countryCode: 'US', languageTag: 'en-US', isRTL: false };
  8. }
  9. // Client-side: get real browser locale
  10. const locale = navigator.language || navigator.userLanguage || 'en-US';
  11. const [languageCode, countryCode] = locale.split('-');
  12. return {
  13. languageCode: languageCode || 'en',
  14. countryCode: countryCode?.toUpperCase() || 'US',
  15. languageTag: locale,
  16. isRTL: false,
  17. };
  18. };
  19. const browserLanguage = typeof navigator === 'undefined'
  20. ? 'en-US'
  21. : navigator.language || 'en-US';
  22. const browserNumberFormatter = typeof Intl === 'undefined'
  23. ? null
  24. : new Intl.NumberFormat(browserLanguage);
  25. const browserDateTimeFormatter = typeof Intl === 'undefined'
  26. ? null
  27. : new Intl.DateTimeFormat(browserLanguage, { hour: 'numeric' });
  28. export const getLocales = () => [getBrowserLocale()];
  29. export const findBestLanguageTag = (languageTags) => {
  30. const browserLocale = getBrowserLocale();
  31. // Try to find matching language tag
  32. const match = languageTags?.find(tag =>
  33. tag.toLowerCase() === browserLocale.languageTag.toLowerCase()
  34. );
  35. return {
  36. languageTag: match || languageTags?.[0] || browserLocale.languageTag,
  37. isRTL: false,
  38. };
  39. };
  40. export const getNumberFormatSettings = () => {
  41. if (typeof navigator === 'undefined' || typeof Intl === 'undefined') {
  42. return { decimalSeparator: '.', groupingSeparator: ',' };
  43. }
  44. // Get real browser number format
  45. const formatter = browserNumberFormatter;
  46. const parts = formatter.formatToParts(1234.5);
  47. return {
  48. decimalSeparator: parts.find(p => p.type === 'decimal')?.value || '.',
  49. groupingSeparator: parts.find(p => p.type === 'group')?.value || ',',
  50. };
  51. };
  52. export const uses24HourClock = () => {
  53. if (!browserDateTimeFormatter) return false;
  54. const formatter = browserDateTimeFormatter;
  55. const parts = formatter.formatToParts(new Date(2020, 0, 1, 13));
  56. return !parts.some(part => part.type === 'dayPeriod');
  57. };
  58. export default {
  59. getLocales,
  60. findBestLanguageTag,
  61. getNumberFormatSettings,
  62. uses24HourClock,
  63. };