zkit-ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/README.md +267 -0
  2. package/dist/ComponentLibProvider.d.ts +15 -0
  3. package/dist/ComponentLibProvider.d.ts.map +1 -0
  4. package/dist/ComponentLibProvider.js +18 -0
  5. package/dist/assets/animations/spinner.json +1 -0
  6. package/dist/assets/icons/check.svg +4 -0
  7. package/dist/assets/icons/toast/error.webp +0 -0
  8. package/dist/assets/icons/toast/success.webp +0 -0
  9. package/dist/assets/icons/toast/warning.webp +0 -0
  10. package/dist/config.d.ts +16 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +42 -0
  13. package/dist/i18n/I18nProvider.d.ts +11 -0
  14. package/dist/i18n/I18nProvider.d.ts.map +1 -0
  15. package/dist/i18n/I18nProvider.js +84 -0
  16. package/dist/i18n/locale.d.ts +7 -0
  17. package/dist/i18n/locale.d.ts.map +1 -0
  18. package/dist/i18n/locale.js +87 -0
  19. package/dist/i18n/locales/de.d.ts +51 -0
  20. package/dist/i18n/locales/de.d.ts.map +1 -0
  21. package/dist/i18n/locales/de.js +62 -0
  22. package/dist/i18n/locales/en-US.d.ts +51 -0
  23. package/dist/i18n/locales/en-US.d.ts.map +1 -0
  24. package/dist/i18n/locales/en-US.js +62 -0
  25. package/dist/i18n/locales/index.d.ts +9 -0
  26. package/dist/i18n/locales/index.d.ts.map +1 -0
  27. package/dist/i18n/locales/index.js +23 -0
  28. package/dist/i18n/locales/ja.d.ts +51 -0
  29. package/dist/i18n/locales/ja.d.ts.map +1 -0
  30. package/dist/i18n/locales/ja.js +62 -0
  31. package/dist/i18n/locales/zh-CN.d.ts +51 -0
  32. package/dist/i18n/locales/zh-CN.d.ts.map +1 -0
  33. package/dist/i18n/locales/zh-CN.js +62 -0
  34. package/dist/i18n/locales/zh-TW.d.ts +51 -0
  35. package/dist/i18n/locales/zh-TW.d.ts.map +1 -0
  36. package/dist/i18n/locales/zh-TW.js +62 -0
  37. package/dist/i18n/types.d.ts +11 -0
  38. package/dist/i18n/types.d.ts.map +1 -0
  39. package/dist/i18n/types.js +2 -0
  40. package/dist/i18n/useI18n.d.ts +2 -0
  41. package/dist/i18n/useI18n.d.ts.map +1 -0
  42. package/dist/i18n/useI18n.js +41 -0
  43. package/dist/index.d.ts +57 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +90 -0
  46. package/dist/services/ActionDialogService/ActionDialog.d.ts +4 -0
  47. package/dist/services/ActionDialogService/ActionDialog.d.ts.map +1 -0
  48. package/dist/services/ActionDialogService/ActionDialog.js +531 -0
  49. package/dist/services/ActionDialogService/index.d.ts +4 -0
  50. package/dist/services/ActionDialogService/index.d.ts.map +1 -0
  51. package/dist/services/ActionDialogService/index.js +8 -0
  52. package/dist/services/ActionDialogService/service.d.ts +7 -0
  53. package/dist/services/ActionDialogService/service.d.ts.map +1 -0
  54. package/dist/services/ActionDialogService/service.js +309 -0
  55. package/dist/services/ActionDialogService/shared.d.ts +17 -0
  56. package/dist/services/ActionDialogService/shared.d.ts.map +1 -0
  57. package/dist/services/ActionDialogService/shared.js +167 -0
  58. package/dist/services/ActionDialogService/types.d.ts +160 -0
  59. package/dist/services/ActionDialogService/types.d.ts.map +1 -0
  60. package/dist/services/ActionDialogService/types.js +2 -0
  61. package/dist/services/CardToastService/index.d.ts +115 -0
  62. package/dist/services/CardToastService/index.d.ts.map +1 -0
  63. package/dist/services/CardToastService/index.js +899 -0
  64. package/dist/services/ImagePreviewService/index.d.ts +179 -0
  65. package/dist/services/ImagePreviewService/index.d.ts.map +1 -0
  66. package/dist/services/ImagePreviewService/index.js +1383 -0
  67. package/dist/services/LoadingService/index.d.ts +146 -0
  68. package/dist/services/LoadingService/index.d.ts.map +1 -0
  69. package/dist/services/LoadingService/index.js +827 -0
  70. package/dist/services/PermissionPurposeDialogService/index.d.ts +99 -0
  71. package/dist/services/PermissionPurposeDialogService/index.d.ts.map +1 -0
  72. package/dist/services/PermissionPurposeDialogService/index.js +360 -0
  73. package/dist/services/PickerService/index.d.ts +128 -0
  74. package/dist/services/PickerService/index.d.ts.map +1 -0
  75. package/dist/services/PickerService/index.js +250 -0
  76. package/dist/theme/ThemeProvider.d.ts +15 -0
  77. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  78. package/dist/theme/ThemeProvider.js +61 -0
  79. package/dist/theme/defaultTheme.d.ts +3 -0
  80. package/dist/theme/defaultTheme.d.ts.map +1 -0
  81. package/dist/theme/defaultTheme.js +28 -0
  82. package/dist/theme/mergeTheme.d.ts +3 -0
  83. package/dist/theme/mergeTheme.d.ts.map +1 -0
  84. package/dist/theme/mergeTheme.js +19 -0
  85. package/dist/theme/types.d.ts +17 -0
  86. package/dist/theme/types.d.ts.map +1 -0
  87. package/dist/theme/types.js +2 -0
  88. package/dist/theme/useTheme.d.ts +2 -0
  89. package/dist/theme/useTheme.d.ts.map +1 -0
  90. package/dist/theme/useTheme.js +46 -0
  91. package/dist/ui/Accordion/index.d.ts +99 -0
  92. package/dist/ui/Accordion/index.d.ts.map +1 -0
  93. package/dist/ui/Accordion/index.js +777 -0
  94. package/dist/ui/AddressCascader/index.d.ts +58 -0
  95. package/dist/ui/AddressCascader/index.d.ts.map +1 -0
  96. package/dist/ui/AddressCascader/index.js +710 -0
  97. package/dist/ui/BetweenTime/index.d.ts +82 -0
  98. package/dist/ui/BetweenTime/index.d.ts.map +1 -0
  99. package/dist/ui/BetweenTime/index.js +702 -0
  100. package/dist/ui/Button/index.d.ts +93 -0
  101. package/dist/ui/Button/index.d.ts.map +1 -0
  102. package/dist/ui/Button/index.js +832 -0
  103. package/dist/ui/Checkbox/index.d.ts +103 -0
  104. package/dist/ui/Checkbox/index.d.ts.map +1 -0
  105. package/dist/ui/Checkbox/index.js +694 -0
  106. package/dist/ui/DatePicker/index.d.ts +5 -0
  107. package/dist/ui/DatePicker/index.d.ts.map +1 -0
  108. package/dist/ui/DatePicker/index.js +157 -0
  109. package/dist/ui/DatePicker/types.d.ts +99 -0
  110. package/dist/ui/DatePicker/types.d.ts.map +1 -0
  111. package/dist/ui/DatePicker/types.js +2 -0
  112. package/dist/ui/DatePicker/utils.d.ts +32 -0
  113. package/dist/ui/DatePicker/utils.d.ts.map +1 -0
  114. package/dist/ui/DatePicker/utils.js +316 -0
  115. package/dist/ui/LinkedScroll/index.d.ts +78 -0
  116. package/dist/ui/LinkedScroll/index.d.ts.map +1 -0
  117. package/dist/ui/LinkedScroll/index.js +470 -0
  118. package/dist/ui/LoadingSpinner/index.d.ts +8 -0
  119. package/dist/ui/LoadingSpinner/index.d.ts.map +1 -0
  120. package/dist/ui/LoadingSpinner/index.js +122 -0
  121. package/dist/ui/Picker/actionBar.d.ts +14 -0
  122. package/dist/ui/Picker/actionBar.d.ts.map +1 -0
  123. package/dist/ui/Picker/actionBar.js +28 -0
  124. package/dist/ui/Picker/index.d.ts +5 -0
  125. package/dist/ui/Picker/index.d.ts.map +1 -0
  126. package/dist/ui/Picker/index.js +412 -0
  127. package/dist/ui/Picker/types.d.ts +80 -0
  128. package/dist/ui/Picker/types.d.ts.map +1 -0
  129. package/dist/ui/Picker/types.js +2 -0
  130. package/dist/ui/Picker/utils.d.ts +27 -0
  131. package/dist/ui/Picker/utils.d.ts.map +1 -0
  132. package/dist/ui/Picker/utils.js +182 -0
  133. package/dist/ui/Radio/index.d.ts +95 -0
  134. package/dist/ui/Radio/index.d.ts.map +1 -0
  135. package/dist/ui/Radio/index.js +633 -0
  136. package/dist/ui/Sheet/index.d.ts +12 -0
  137. package/dist/ui/Sheet/index.d.ts.map +1 -0
  138. package/dist/ui/Sheet/index.js +832 -0
  139. package/dist/ui/Sheet/nativeBottom.d.ts +52 -0
  140. package/dist/ui/Sheet/nativeBottom.d.ts.map +1 -0
  141. package/dist/ui/Sheet/nativeBottom.js +442 -0
  142. package/dist/ui/Sheet/nativeBottom.web.d.ts +18 -0
  143. package/dist/ui/Sheet/nativeBottom.web.d.ts.map +1 -0
  144. package/dist/ui/Sheet/nativeBottom.web.js +46 -0
  145. package/dist/ui/Sheet/slots.d.ts +5 -0
  146. package/dist/ui/Sheet/slots.d.ts.map +1 -0
  147. package/dist/ui/Sheet/slots.js +40 -0
  148. package/dist/ui/Sheet/types.d.ts +131 -0
  149. package/dist/ui/Sheet/types.d.ts.map +1 -0
  150. package/dist/ui/Sheet/types.js +2 -0
  151. package/dist/ui/SliderCaptcha/index.d.ts +57 -0
  152. package/dist/ui/SliderCaptcha/index.d.ts.map +1 -0
  153. package/dist/ui/SliderCaptcha/index.js +586 -0
  154. package/dist/ui/Switch/index.d.ts +72 -0
  155. package/dist/ui/Switch/index.d.ts.map +1 -0
  156. package/dist/ui/Switch/index.js +671 -0
  157. package/dist/ui/Text/index.d.ts +41 -0
  158. package/dist/ui/Text/index.d.ts.map +1 -0
  159. package/dist/ui/Text/index.js +325 -0
  160. package/dist/ui/TextInput/TextInputPrimitive.d.ts +8 -0
  161. package/dist/ui/TextInput/TextInputPrimitive.d.ts.map +1 -0
  162. package/dist/ui/TextInput/TextInputPrimitive.js +54 -0
  163. package/dist/ui/TextInput/index.d.ts +89 -0
  164. package/dist/ui/TextInput/index.d.ts.map +1 -0
  165. package/dist/ui/TextInput/index.js +545 -0
  166. package/dist/ui/WheelColumn/ZKitWheelPickerNativeComponent.d.ts +39 -0
  167. package/dist/ui/WheelColumn/ZKitWheelPickerNativeComponent.d.ts.map +1 -0
  168. package/dist/ui/WheelColumn/ZKitWheelPickerNativeComponent.js +60 -0
  169. package/dist/ui/WheelColumn/constants.d.ts +2 -0
  170. package/dist/ui/WheelColumn/constants.d.ts.map +1 -0
  171. package/dist/ui/WheelColumn/constants.js +4 -0
  172. package/dist/ui/WheelColumn/index.d.ts +59 -0
  173. package/dist/ui/WheelColumn/index.d.ts.map +1 -0
  174. package/dist/ui/WheelColumn/index.js +547 -0
  175. package/ios/ZKitWheelPicker.h +18 -0
  176. package/ios/ZKitWheelPicker.mm +230 -0
  177. package/ios/ZKitWheelPickerLabel.h +10 -0
  178. package/ios/ZKitWheelPickerLabel.mm +31 -0
  179. package/ios/ZKitWheelPickerManager.h +5 -0
  180. package/ios/ZKitWheelPickerManager.mm +53 -0
  181. package/package.json +75 -0
  182. package/react-native.config.js +10 -0
  183. package/src/ComponentLibProvider.tsx +56 -0
  184. package/src/assets/animations/spinner.json +1 -0
  185. package/src/assets/icons/check.svg +4 -0
  186. package/src/assets/icons/toast/error.webp +0 -0
  187. package/src/assets/icons/toast/success.webp +0 -0
  188. package/src/assets/icons/toast/warning.webp +0 -0
  189. package/src/config.ts +65 -0
  190. package/src/i18n/I18nProvider.tsx +69 -0
  191. package/src/i18n/locale.ts +108 -0
  192. package/src/i18n/locales/de.ts +67 -0
  193. package/src/i18n/locales/en-US.ts +67 -0
  194. package/src/i18n/locales/index.ts +19 -0
  195. package/src/i18n/locales/ja.ts +67 -0
  196. package/src/i18n/locales/zh-CN.ts +67 -0
  197. package/src/i18n/locales/zh-TW.ts +67 -0
  198. package/src/i18n/types.ts +21 -0
  199. package/src/i18n/useI18n.ts +7 -0
  200. package/src/index.ts +395 -0
  201. package/src/services/ActionDialogService/ActionDialog.tsx +756 -0
  202. package/src/services/ActionDialogService/README.md +146 -0
  203. package/src/services/ActionDialogService/index.tsx +39 -0
  204. package/src/services/ActionDialogService/service.tsx +355 -0
  205. package/src/services/ActionDialogService/shared.ts +204 -0
  206. package/src/services/ActionDialogService/types.ts +197 -0
  207. package/src/services/CardToastService/README.md +128 -0
  208. package/src/services/CardToastService/index.tsx +1284 -0
  209. package/src/services/ImagePreviewService/README.md +67 -0
  210. package/src/services/ImagePreviewService/index.tsx +2148 -0
  211. package/src/services/LoadingService/README.md +128 -0
  212. package/src/services/LoadingService/index.tsx +1113 -0
  213. package/src/services/PermissionPurposeDialogService/README.md +80 -0
  214. package/src/services/PermissionPurposeDialogService/index.tsx +449 -0
  215. package/src/services/PickerService/README.md +154 -0
  216. package/src/services/PickerService/index.tsx +410 -0
  217. package/src/theme/ThemeProvider.tsx +40 -0
  218. package/src/theme/defaultTheme.ts +30 -0
  219. package/src/theme/mergeTheme.ts +16 -0
  220. package/src/theme/types.ts +36 -0
  221. package/src/theme/useTheme.ts +10 -0
  222. package/src/types/svg.d.ts +9 -0
  223. package/src/types/vant-area-data.d.ts +19 -0
  224. package/src/ui/Accordion/README.md +67 -0
  225. package/src/ui/Accordion/index.tsx +1221 -0
  226. package/src/ui/AddressCascader/README.md +144 -0
  227. package/src/ui/AddressCascader/index.tsx +1084 -0
  228. package/src/ui/BetweenTime/README.md +490 -0
  229. package/src/ui/BetweenTime/index.tsx +1001 -0
  230. package/src/ui/Button/README.md +186 -0
  231. package/src/ui/Button/index.tsx +1356 -0
  232. package/src/ui/Checkbox/README.md +211 -0
  233. package/src/ui/Checkbox/index.tsx +1231 -0
  234. package/src/ui/DatePicker/README.md +117 -0
  235. package/src/ui/DatePicker/index.tsx +295 -0
  236. package/src/ui/DatePicker/types.ts +115 -0
  237. package/src/ui/DatePicker/utils.ts +405 -0
  238. package/src/ui/LinkedScroll/README.md +55 -0
  239. package/src/ui/LinkedScroll/index.tsx +809 -0
  240. package/src/ui/LoadingSpinner/index.tsx +104 -0
  241. package/src/ui/Picker/README.md +190 -0
  242. package/src/ui/Picker/actionBar.tsx +70 -0
  243. package/src/ui/Picker/index.tsx +694 -0
  244. package/src/ui/Picker/types.ts +94 -0
  245. package/src/ui/Picker/utils.ts +239 -0
  246. package/src/ui/Radio/README.md +207 -0
  247. package/src/ui/Radio/index.tsx +1117 -0
  248. package/src/ui/Sheet/README.md +82 -0
  249. package/src/ui/Sheet/index.tsx +1163 -0
  250. package/src/ui/Sheet/nativeBottom.tsx +683 -0
  251. package/src/ui/Sheet/nativeBottom.web.tsx +40 -0
  252. package/src/ui/Sheet/slots.tsx +75 -0
  253. package/src/ui/Sheet/types.ts +195 -0
  254. package/src/ui/SliderCaptcha/README.md +61 -0
  255. package/src/ui/SliderCaptcha/index.tsx +816 -0
  256. package/src/ui/Switch/README.md +143 -0
  257. package/src/ui/Switch/index.tsx +1092 -0
  258. package/src/ui/Text/README.md +157 -0
  259. package/src/ui/Text/index.tsx +450 -0
  260. package/src/ui/TextInput/README.md +197 -0
  261. package/src/ui/TextInput/TextInputPrimitive.tsx +44 -0
  262. package/src/ui/TextInput/index.tsx +942 -0
  263. package/src/ui/WheelColumn/README.md +104 -0
  264. package/src/ui/WheelColumn/ZKitWheelPickerNativeComponent.tsx +68 -0
  265. package/src/ui/WheelColumn/constants.ts +1 -0
  266. package/src/ui/WheelColumn/index.tsx +826 -0
  267. package/zkit-ui.podspec +19 -0
@@ -0,0 +1,69 @@
1
+ import * as React from 'react';
2
+ import { getDefaultI18nConfig } from '../config';
3
+ import { resolveBuiltinLocale } from './locale';
4
+ import { locales } from './locales';
5
+ import type {
6
+ I18nContextValue,
7
+ I18nMessages,
8
+ I18nMissingKeyPolicy,
9
+ I18nTranslate,
10
+ I18nTranslateParams,
11
+ } from './types';
12
+
13
+ function interpolate(template: string, params?: I18nTranslateParams) {
14
+ if (!params) return template;
15
+ return template.replace(/\{(\w+)\}/g, (full, key: string) => {
16
+ const value = params[key];
17
+ if (value === undefined || value === null) return full;
18
+ return String(value);
19
+ });
20
+ }
21
+
22
+ function createTranslator(messages: I18nMessages, missingKeyPolicy: I18nMissingKeyPolicy): I18nTranslate {
23
+ return (key, params) => {
24
+ const raw = messages[key];
25
+ if (raw == null) {
26
+ if (missingKeyPolicy === 'throw') {
27
+ throw new Error(`[zkit-ui] Missing i18n key: ${key}`);
28
+ }
29
+ return key;
30
+ }
31
+ return interpolate(raw, params);
32
+ };
33
+ }
34
+
35
+ function resolveI18nValue(
36
+ base: Required<ReturnType<typeof getDefaultI18nConfig>>,
37
+ override?: {
38
+ locale?: string;
39
+ messages?: I18nMessages;
40
+ missingKeyPolicy?: I18nMissingKeyPolicy;
41
+ }
42
+ ): I18nContextValue {
43
+ const locale = override?.locale ?? base.locale;
44
+ // 优先级:override.messages > base.messages > 内置语言包
45
+ const builtinMessages = locales[resolveBuiltinLocale(locale)] ?? {};
46
+ const messages = { ...builtinMessages, ...base.messages, ...(override?.messages ?? {}) };
47
+ const missingKeyPolicy = override?.missingKeyPolicy ?? base.missingKeyPolicy;
48
+ const t = createTranslator(messages, missingKeyPolicy);
49
+ return { locale, messages, missingKeyPolicy, t };
50
+ }
51
+
52
+ export const I18nContext = React.createContext<I18nContextValue>({
53
+ ...resolveI18nValue(getDefaultI18nConfig()),
54
+ });
55
+
56
+ export type I18nProviderProps = {
57
+ locale?: string;
58
+ messages?: I18nMessages;
59
+ missingKeyPolicy?: I18nMissingKeyPolicy;
60
+ children: React.ReactNode;
61
+ };
62
+
63
+ export function I18nProvider({ locale, messages, missingKeyPolicy, children }: I18nProviderProps) {
64
+ const value = React.useMemo(() => {
65
+ const base = getDefaultI18nConfig();
66
+ return resolveI18nValue(base, { locale, messages, missingKeyPolicy });
67
+ }, [locale, messages, missingKeyPolicy]);
68
+ return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>;
69
+ }
@@ -0,0 +1,108 @@
1
+ import { NativeModules } from 'react-native';
2
+
3
+ export const DEFAULT_I18N_LOCALE = 'zh-CN';
4
+
5
+ export const BUILTIN_I18N_LOCALES = ['zh-CN', 'zh-TW', 'ja', 'en-US', 'de'] as const;
6
+ const TRADITIONAL_CHINESE_REGIONS = new Set(['HK', 'MO', 'TW']);
7
+
8
+ export type BuiltinI18nLocale = (typeof BUILTIN_I18N_LOCALES)[number];
9
+ type NavigatorLike = {
10
+ language?: string;
11
+ languages?: readonly string[];
12
+ userLanguage?: string;
13
+ };
14
+ type NativeSettings = Record<string, unknown>;
15
+ type NativeModulesWithLocale = typeof NativeModules & {
16
+ I18nManager?: {
17
+ localeIdentifier?: unknown;
18
+ };
19
+ SettingsManager?: {
20
+ settings?: NativeSettings;
21
+ };
22
+ };
23
+
24
+ function getString(value: unknown) {
25
+ const next = typeof value === 'string' ? value.trim() : '';
26
+ return next.length > 0 ? next : undefined;
27
+ }
28
+
29
+ function getStringArray(value: unknown) {
30
+ if (!Array.isArray(value)) return [];
31
+ return value.flatMap((item) => {
32
+ const next = getString(item);
33
+ return next ? [next] : [];
34
+ });
35
+ }
36
+
37
+ function normalizeLocaleParts(locale: string) {
38
+ const parts = locale
39
+ .replace(/_/g, '-')
40
+ .split('-')
41
+ .map((part) => part.trim())
42
+ .filter(Boolean);
43
+
44
+ if (parts.length === 0) return null;
45
+
46
+ return {
47
+ language: parts[0].toLowerCase(),
48
+ subtags: parts.slice(1).map((part) => part.toUpperCase()),
49
+ };
50
+ }
51
+
52
+ function matchBuiltinLocale(locale?: string | null): BuiltinI18nLocale | undefined {
53
+ const rawLocale = getString(locale);
54
+ if (!rawLocale) return undefined;
55
+
56
+ const exactLocale = BUILTIN_I18N_LOCALES.find(
57
+ (supportedLocale) => supportedLocale.toLowerCase() === rawLocale.toLowerCase()
58
+ );
59
+ if (exactLocale) return exactLocale;
60
+
61
+ const normalized = normalizeLocaleParts(rawLocale);
62
+ if (!normalized) return undefined;
63
+
64
+ if (normalized.language === 'zh') {
65
+ const usesTraditionalChinese =
66
+ normalized.subtags.includes('HANT') ||
67
+ normalized.subtags.some((subtag) => TRADITIONAL_CHINESE_REGIONS.has(subtag));
68
+ return usesTraditionalChinese ? 'zh-TW' : 'zh-CN';
69
+ }
70
+
71
+ if (normalized.language === 'ja') return 'ja';
72
+ if (normalized.language === 'en') return 'en-US';
73
+ if (normalized.language === 'de') return 'de';
74
+
75
+ return undefined;
76
+ }
77
+
78
+ export function resolveBuiltinLocale(locale?: string | null): BuiltinI18nLocale {
79
+ return matchBuiltinLocale(locale) ?? DEFAULT_I18N_LOCALE;
80
+ }
81
+
82
+ function getSystemLocaleCandidates() {
83
+ const nativeModules = (NativeModules ?? {}) as NativeModulesWithLocale;
84
+ const settings = nativeModules.SettingsManager?.settings;
85
+ const navigator = (globalThis as { navigator?: NavigatorLike }).navigator;
86
+
87
+ return [
88
+ getString(settings?.AppleLocale),
89
+ ...getStringArray(settings?.AppleLanguages),
90
+ getString(nativeModules.I18nManager?.localeIdentifier),
91
+ ...(navigator?.languages ?? []),
92
+ getString(navigator?.language),
93
+ getString(navigator?.userLanguage),
94
+ ];
95
+ }
96
+
97
+ export function getSystemLocale() {
98
+ return getSystemLocaleCandidates().find((candidate) => getString(candidate));
99
+ }
100
+
101
+ export function resolveSystemBuiltinLocale() {
102
+ for (const candidate of getSystemLocaleCandidates()) {
103
+ const locale = matchBuiltinLocale(candidate);
104
+ if (locale) return locale;
105
+ }
106
+
107
+ return DEFAULT_I18N_LOCALE;
108
+ }
@@ -0,0 +1,67 @@
1
+ export const de = {
2
+ // Picker
3
+ 'picker.title': 'Bitte auswählen',
4
+ 'picker.cancel': 'Abbrechen',
5
+ 'picker.confirm': 'Bestätigen',
6
+ 'picker.empty': 'Keine Optionen verfügbar',
7
+
8
+ // DatePicker
9
+ 'datePicker.title': 'Datum auswählen',
10
+ 'datePicker.placeholder': 'Datum wählen',
11
+ 'datePicker.year': 'Jahr',
12
+ 'datePicker.month': 'Monat',
13
+ 'datePicker.day': 'Tag',
14
+
15
+ // AddressCascader
16
+ 'addressCascader.title': 'Adresse auswählen',
17
+ 'addressCascader.province': 'Provinz',
18
+ 'addressCascader.city': 'Stadt',
19
+ 'addressCascader.district': 'Bezirk',
20
+ 'addressCascader.empty': 'Keine Adressen verfügbar',
21
+
22
+ // BetweenTime
23
+ 'betweenTime.title': 'Zeitraum auswählen',
24
+ 'betweenTime.clear': 'Leeren',
25
+ 'betweenTime.startTime': 'Startzeit',
26
+ 'betweenTime.endTime': 'Endzeit',
27
+ 'betweenTime.to': 'bis',
28
+ 'betweenTime.cancel': 'Abbrechen',
29
+ 'betweenTime.confirm': 'Bestätigen',
30
+ 'betweenTime.unit.year': 'Jahr',
31
+ 'betweenTime.unit.month': 'Monat',
32
+ 'betweenTime.unit.day': 'Tag',
33
+ 'betweenTime.unit.hour': 'Std.',
34
+ 'betweenTime.unit.minute': 'Min.',
35
+ 'betweenTime.unit.second': 'Sek.',
36
+ 'betweenTime.quick.today': 'Heute',
37
+ 'betweenTime.quick.thisWeek': 'Diese Woche',
38
+ 'betweenTime.quick.thisMonth': 'Dieser Monat',
39
+ 'betweenTime.quick.thisYear': 'Dieses Jahr',
40
+ 'betweenTime.quick.thisQuarter': 'Dieses Quartal',
41
+ 'betweenTime.quick.recentDays': 'Letzte {n} Tage',
42
+
43
+ // ImagePreview
44
+ 'imagePreview.preview': 'Bildvorschau',
45
+ 'imagePreview.close': 'Bildvorschau schließen',
46
+ 'imagePreview.loadFailed': 'Bild konnte nicht geladen werden',
47
+ 'imagePreview.counter': 'Bild {current} von {total}',
48
+ 'imagePreview.image': 'Bild {current} von {total}',
49
+
50
+ // ActionDialog
51
+ 'actionDialog.confirm': 'Bestätigen',
52
+ 'actionDialog.cancel': 'Abbrechen',
53
+ 'actionDialog.close': 'Dialog schließen',
54
+
55
+ // Loading
56
+ 'loading.loading': 'Wird geladen',
57
+ 'loading.success': 'Fertig',
58
+ 'loading.error': 'Fehlgeschlagen',
59
+
60
+ // SliderCaptcha
61
+ 'sliderCaptcha.title': 'Schieber ziehen, um das Puzzle zu lösen',
62
+ 'sliderCaptcha.verifyFailed': 'Verifizierung fehlgeschlagen, bitte erneut versuchen',
63
+ 'sliderCaptcha.verifySuccess': 'Verifiziert',
64
+
65
+ // TextInput
66
+ 'textInput.clear': 'Eingabe löschen',
67
+ };
@@ -0,0 +1,67 @@
1
+ export const enUS = {
2
+ // Picker
3
+ 'picker.title': 'Please Select',
4
+ 'picker.cancel': 'Cancel',
5
+ 'picker.confirm': 'Confirm',
6
+ 'picker.empty': 'No options available',
7
+
8
+ // DatePicker
9
+ 'datePicker.title': 'Select Date',
10
+ 'datePicker.placeholder': 'Select date',
11
+ 'datePicker.year': 'Year',
12
+ 'datePicker.month': 'Month',
13
+ 'datePicker.day': 'Day',
14
+
15
+ // AddressCascader
16
+ 'addressCascader.title': 'Select Address',
17
+ 'addressCascader.province': 'Province',
18
+ 'addressCascader.city': 'City',
19
+ 'addressCascader.district': 'District',
20
+ 'addressCascader.empty': 'No addresses available',
21
+
22
+ // BetweenTime
23
+ 'betweenTime.title': 'Select Time Range',
24
+ 'betweenTime.clear': 'Clear',
25
+ 'betweenTime.startTime': 'Start Time',
26
+ 'betweenTime.endTime': 'End Time',
27
+ 'betweenTime.to': 'to',
28
+ 'betweenTime.cancel': 'Cancel',
29
+ 'betweenTime.confirm': 'Confirm',
30
+ 'betweenTime.unit.year': 'Year',
31
+ 'betweenTime.unit.month': 'Month',
32
+ 'betweenTime.unit.day': 'Day',
33
+ 'betweenTime.unit.hour': 'Hour',
34
+ 'betweenTime.unit.minute': 'Min',
35
+ 'betweenTime.unit.second': 'Sec',
36
+ 'betweenTime.quick.today': 'Today',
37
+ 'betweenTime.quick.thisWeek': 'This Week',
38
+ 'betweenTime.quick.thisMonth': 'This Month',
39
+ 'betweenTime.quick.thisYear': 'This Year',
40
+ 'betweenTime.quick.thisQuarter': 'This Quarter',
41
+ 'betweenTime.quick.recentDays': 'Last {n} Days',
42
+
43
+ // ImagePreview
44
+ 'imagePreview.preview': 'Image preview',
45
+ 'imagePreview.close': 'Close image preview',
46
+ 'imagePreview.loadFailed': 'Failed to load image',
47
+ 'imagePreview.counter': 'Image {current} of {total}',
48
+ 'imagePreview.image': 'Image {current} of {total}',
49
+
50
+ // ActionDialog
51
+ 'actionDialog.confirm': 'Confirm',
52
+ 'actionDialog.cancel': 'Cancel',
53
+ 'actionDialog.close': 'Close dialog',
54
+
55
+ // Loading
56
+ 'loading.loading': 'Loading',
57
+ 'loading.success': 'Done',
58
+ 'loading.error': 'Failed',
59
+
60
+ // SliderCaptcha
61
+ 'sliderCaptcha.title': 'Drag slider to finish puzzle',
62
+ 'sliderCaptcha.verifyFailed': 'Verification failed',
63
+ 'sliderCaptcha.verifySuccess': 'Verified',
64
+
65
+ // TextInput
66
+ 'textInput.clear': 'Clear input',
67
+ };
@@ -0,0 +1,19 @@
1
+ import { zhCN } from './zh-CN';
2
+ import { zhTW } from './zh-TW';
3
+ import { ja } from './ja';
4
+ import { enUS } from './en-US';
5
+ import { de } from './de';
6
+ import type { I18nMessages } from '../types';
7
+
8
+ export const locales: Record<string, I18nMessages> = {
9
+ 'zh-CN': zhCN,
10
+ 'zh-TW': zhTW,
11
+ ja,
12
+ 'en-US': enUS,
13
+ de,
14
+ // 别名
15
+ zh: zhCN,
16
+ en: enUS,
17
+ };
18
+
19
+ export { zhCN, zhTW, ja, enUS, de };
@@ -0,0 +1,67 @@
1
+ export const ja = {
2
+ // Picker
3
+ 'picker.title': '選択',
4
+ 'picker.cancel': 'キャンセル',
5
+ 'picker.confirm': '確認',
6
+ 'picker.empty': '選択できる項目がありません',
7
+
8
+ // DatePicker
9
+ 'datePicker.title': '日付を選択',
10
+ 'datePicker.placeholder': '日付を選択',
11
+ 'datePicker.year': '年',
12
+ 'datePicker.month': '月',
13
+ 'datePicker.day': '日',
14
+
15
+ // AddressCascader
16
+ 'addressCascader.title': '住所を選択',
17
+ 'addressCascader.province': '都道府県',
18
+ 'addressCascader.city': '市区町村',
19
+ 'addressCascader.district': '町域',
20
+ 'addressCascader.empty': '選択できる住所がありません',
21
+
22
+ // BetweenTime
23
+ 'betweenTime.title': '期間を選択',
24
+ 'betweenTime.clear': 'クリア',
25
+ 'betweenTime.startTime': '開始',
26
+ 'betweenTime.endTime': '終了',
27
+ 'betweenTime.to': '〜',
28
+ 'betweenTime.cancel': 'キャンセル',
29
+ 'betweenTime.confirm': '確認',
30
+ 'betweenTime.unit.year': '年',
31
+ 'betweenTime.unit.month': '月',
32
+ 'betweenTime.unit.day': '日',
33
+ 'betweenTime.unit.hour': '時',
34
+ 'betweenTime.unit.minute': '分',
35
+ 'betweenTime.unit.second': '秒',
36
+ 'betweenTime.quick.today': '今日',
37
+ 'betweenTime.quick.thisWeek': '今週',
38
+ 'betweenTime.quick.thisMonth': '今月',
39
+ 'betweenTime.quick.thisYear': '今年',
40
+ 'betweenTime.quick.thisQuarter': '今四半期',
41
+ 'betweenTime.quick.recentDays': '過去{n}日間',
42
+
43
+ // ImagePreview
44
+ 'imagePreview.preview': '画像プレビュー',
45
+ 'imagePreview.close': '画像プレビューを閉じる',
46
+ 'imagePreview.loadFailed': '画像の読み込みに失敗しました',
47
+ 'imagePreview.counter': '{total}枚中{current}枚目',
48
+ 'imagePreview.image': '{total}枚中{current}枚目の画像',
49
+
50
+ // ActionDialog
51
+ 'actionDialog.confirm': '確認',
52
+ 'actionDialog.cancel': 'キャンセル',
53
+ 'actionDialog.close': 'ダイアログを閉じる',
54
+
55
+ // Loading
56
+ 'loading.loading': '読み込み中',
57
+ 'loading.success': '完了',
58
+ 'loading.error': '失敗しました',
59
+
60
+ // SliderCaptcha
61
+ 'sliderCaptcha.title': 'スライドで認証',
62
+ 'sliderCaptcha.verifyFailed': '認証失敗',
63
+ 'sliderCaptcha.verifySuccess': '認証成功',
64
+
65
+ // TextInput
66
+ 'textInput.clear': '入力をクリア',
67
+ };
@@ -0,0 +1,67 @@
1
+ export const zhCN = {
2
+ // Picker
3
+ 'picker.title': '请选择',
4
+ 'picker.cancel': '取消',
5
+ 'picker.confirm': '确认',
6
+ 'picker.empty': '暂无可选项',
7
+
8
+ // DatePicker
9
+ 'datePicker.title': '请选择日期',
10
+ 'datePicker.placeholder': '选择日期',
11
+ 'datePicker.year': '年',
12
+ 'datePicker.month': '月',
13
+ 'datePicker.day': '日',
14
+
15
+ // AddressCascader
16
+ 'addressCascader.title': '请选择地址',
17
+ 'addressCascader.province': '省份',
18
+ 'addressCascader.city': '城市',
19
+ 'addressCascader.district': '区县',
20
+ 'addressCascader.empty': '暂无可选地址',
21
+
22
+ // BetweenTime
23
+ 'betweenTime.title': '请选择时间',
24
+ 'betweenTime.clear': '清空',
25
+ 'betweenTime.startTime': '开始时间',
26
+ 'betweenTime.endTime': '结束时间',
27
+ 'betweenTime.to': '至',
28
+ 'betweenTime.cancel': '取消',
29
+ 'betweenTime.confirm': '确认',
30
+ 'betweenTime.unit.year': '年',
31
+ 'betweenTime.unit.month': '月',
32
+ 'betweenTime.unit.day': '日',
33
+ 'betweenTime.unit.hour': '时',
34
+ 'betweenTime.unit.minute': '分',
35
+ 'betweenTime.unit.second': '秒',
36
+ 'betweenTime.quick.today': '今天',
37
+ 'betweenTime.quick.thisWeek': '本周',
38
+ 'betweenTime.quick.thisMonth': '本月',
39
+ 'betweenTime.quick.thisYear': '本年',
40
+ 'betweenTime.quick.thisQuarter': '本季度',
41
+ 'betweenTime.quick.recentDays': '最近{n}天',
42
+
43
+ // ImagePreview
44
+ 'imagePreview.preview': '图片预览',
45
+ 'imagePreview.close': '关闭图片预览',
46
+ 'imagePreview.loadFailed': '图片加载失败',
47
+ 'imagePreview.counter': '第{current}张,共{total}张',
48
+ 'imagePreview.image': '第{current}张图片,共{total}张',
49
+
50
+ // ActionDialog
51
+ 'actionDialog.confirm': '确认',
52
+ 'actionDialog.cancel': '取消',
53
+ 'actionDialog.close': '关闭弹窗',
54
+
55
+ // Loading
56
+ 'loading.loading': '正在加载',
57
+ 'loading.success': '已完成',
58
+ 'loading.error': '操作失败',
59
+
60
+ // SliderCaptcha
61
+ 'sliderCaptcha.title': '请拖动滑块完成拼图',
62
+ 'sliderCaptcha.verifyFailed': '验证失败,请重试',
63
+ 'sliderCaptcha.verifySuccess': '验证成功',
64
+
65
+ // TextInput
66
+ 'textInput.clear': '清空输入',
67
+ };
@@ -0,0 +1,67 @@
1
+ export const zhTW = {
2
+ // Picker
3
+ 'picker.title': '請選擇',
4
+ 'picker.cancel': '取消',
5
+ 'picker.confirm': '確認',
6
+ 'picker.empty': '暫無可選項',
7
+
8
+ // DatePicker
9
+ 'datePicker.title': '請選擇日期',
10
+ 'datePicker.placeholder': '選擇日期',
11
+ 'datePicker.year': '年',
12
+ 'datePicker.month': '月',
13
+ 'datePicker.day': '日',
14
+
15
+ // AddressCascader
16
+ 'addressCascader.title': '請選擇地址',
17
+ 'addressCascader.province': '省份',
18
+ 'addressCascader.city': '城市',
19
+ 'addressCascader.district': '區縣',
20
+ 'addressCascader.empty': '暫無可選地址',
21
+
22
+ // BetweenTime
23
+ 'betweenTime.title': '請選擇時間',
24
+ 'betweenTime.clear': '清空',
25
+ 'betweenTime.startTime': '開始時間',
26
+ 'betweenTime.endTime': '結束時間',
27
+ 'betweenTime.to': '至',
28
+ 'betweenTime.cancel': '取消',
29
+ 'betweenTime.confirm': '確認',
30
+ 'betweenTime.unit.year': '年',
31
+ 'betweenTime.unit.month': '月',
32
+ 'betweenTime.unit.day': '日',
33
+ 'betweenTime.unit.hour': '時',
34
+ 'betweenTime.unit.minute': '分',
35
+ 'betweenTime.unit.second': '秒',
36
+ 'betweenTime.quick.today': '今天',
37
+ 'betweenTime.quick.thisWeek': '本週',
38
+ 'betweenTime.quick.thisMonth': '本月',
39
+ 'betweenTime.quick.thisYear': '本年',
40
+ 'betweenTime.quick.thisQuarter': '本季度',
41
+ 'betweenTime.quick.recentDays': '最近{n}天',
42
+
43
+ // ImagePreview
44
+ 'imagePreview.preview': '圖片預覽',
45
+ 'imagePreview.close': '關閉圖片預覽',
46
+ 'imagePreview.loadFailed': '圖片載入失敗',
47
+ 'imagePreview.counter': '第{current}張,共{total}張',
48
+ 'imagePreview.image': '第{current}張圖片,共{total}張',
49
+
50
+ // ActionDialog
51
+ 'actionDialog.confirm': '確認',
52
+ 'actionDialog.cancel': '取消',
53
+ 'actionDialog.close': '關閉彈窗',
54
+
55
+ // Loading
56
+ 'loading.loading': '正在載入',
57
+ 'loading.success': '已完成',
58
+ 'loading.error': '操作失敗',
59
+
60
+ // SliderCaptcha
61
+ 'sliderCaptcha.title': '請拖動滑塊完成拼圖',
62
+ 'sliderCaptcha.verifyFailed': '驗證失敗,請重試',
63
+ 'sliderCaptcha.verifySuccess': '驗證成功',
64
+
65
+ // TextInput
66
+ 'textInput.clear': '清空輸入',
67
+ };
@@ -0,0 +1,21 @@
1
+ // I18nMessages 使用扁平字典,便于:
2
+ // - 接入现有业务多语言系统(通常也是 key-value)
3
+ // - 做静态分析/漏 key 校验(后续可扩展)
4
+ export type I18nMessages = Record<string, string>;
5
+
6
+ // missingKeyPolicy:
7
+ // - key:找不到 key 时回显 key(避免线上崩溃)
8
+ // - throw:找不到 key 时抛错(更适合开发/测试的 fail-fast)
9
+ export type I18nMissingKeyPolicy = 'key' | 'throw';
10
+
11
+ export type I18nTranslateParams = Record<string, string | number>;
12
+
13
+ export type I18nTranslate = (key: string, params?: I18nTranslateParams) => string;
14
+
15
+ export type I18nContextValue = {
16
+ // locale 目前主要用于透传;未来可扩展数字/日期格式化等能力
17
+ locale: string;
18
+ messages: I18nMessages;
19
+ missingKeyPolicy: I18nMissingKeyPolicy;
20
+ t: I18nTranslate;
21
+ };
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ import { I18nContext } from './I18nProvider';
3
+
4
+ export function useI18n() {
5
+ return React.useContext(I18nContext);
6
+ }
7
+