topiray-auth-react 1.1.3 → 1.1.4
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.
- package/README.md +194 -1
- package/dist/i18n/I18nProvider.d.ts +13 -0
- package/dist/i18n/en.json.d.ts +93 -0
- package/dist/i18n/index.d.ts +3 -0
- package/dist/i18n/types.d.ts +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.es.js +3486 -2224
- package/dist/index.umd.js +55 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ A comprehensive, themeable React component library for authentication flows. Bui
|
|
|
14
14
|
- 🔐 **Complete Auth Flow** - Sign in/up, 2FA, email verification, password reset
|
|
15
15
|
- ⚡ **TypeScript** - Full type safety and IntelliSense support
|
|
16
16
|
- 🎯 **Tree Shakeable** - Import only what you need
|
|
17
|
+
- 🌐 **i18n Support** - Built-in internationalization with customizable translations
|
|
17
18
|
|
|
18
19
|
<img width="1910" height="892" alt="image" src="https://github.com/user-attachments/assets/1eb04b72-be57-477a-96de-2879d2fc9191" />
|
|
19
20
|
<img width="1910" height="892" alt="image" src="https://github.com/user-attachments/assets/089695f9-9558-4cea-af24-fec94ecd2ebb" />
|
|
@@ -750,6 +751,195 @@ const handleSocialLogin = (provider: 'google' | 'apple' | 'facebook') => {
|
|
|
750
751
|
- **High Contrast**: Colors meet WCAG contrast requirements
|
|
751
752
|
- **Reduced Motion**: Respects user's motion preferences
|
|
752
753
|
|
|
754
|
+
## Internationalization (i18n)
|
|
755
|
+
|
|
756
|
+
All auth components support internationalization out of the box. English is the default language. You can provide custom translations for any language by wrapping your app with the `I18nProvider`.
|
|
757
|
+
|
|
758
|
+
### Default Behavior (English)
|
|
759
|
+
|
|
760
|
+
Without any i18n configuration, all components render in English. No setup is required.
|
|
761
|
+
|
|
762
|
+
### Adding a New Language
|
|
763
|
+
|
|
764
|
+
1. Create a translation JSON file following the same structure as the built-in English translations. All keys live under the `topiray.auth` namespace:
|
|
765
|
+
|
|
766
|
+
```json
|
|
767
|
+
// fr.json
|
|
768
|
+
{
|
|
769
|
+
"topiray": {
|
|
770
|
+
"auth": {
|
|
771
|
+
"signIn": {
|
|
772
|
+
"title": "Se connecter",
|
|
773
|
+
"emailPlaceholder": "E-mail",
|
|
774
|
+
"passwordPlaceholder": "Mot de passe",
|
|
775
|
+
"submitButton": "Continuer",
|
|
776
|
+
"submittingButton": "Connexion en cours...",
|
|
777
|
+
"dividerText": "ou se connecter avec",
|
|
778
|
+
"forgotPassword": "Mot de passe oublié ?",
|
|
779
|
+
"noAccount": "Vous n'avez pas de compte ?",
|
|
780
|
+
"signUpLink": "S'inscrire"
|
|
781
|
+
},
|
|
782
|
+
"signUp": {
|
|
783
|
+
"title": "Créez votre compte",
|
|
784
|
+
"emailPlaceholder": "E-mail",
|
|
785
|
+
"passwordPlaceholder": "Mot de passe",
|
|
786
|
+
"submitButton": "Créer un compte",
|
|
787
|
+
"submittingButton": "Création du compte...",
|
|
788
|
+
"dividerText": "ou s'inscrire avec",
|
|
789
|
+
"hasAccount": "Vous avez déjà un compte ?",
|
|
790
|
+
"signInLink": "Se connecter"
|
|
791
|
+
},
|
|
792
|
+
"forgottenPassword": {
|
|
793
|
+
"title": "Mot de passe oublié ?",
|
|
794
|
+
"description": "Entrez l'adresse e-mail associée à votre compte et nous vous enverrons un lien unique pour réinitialiser votre mot de passe.",
|
|
795
|
+
"emailPlaceholder": "E-mail",
|
|
796
|
+
"submitButton": "Réinitialiser le mot de passe",
|
|
797
|
+
"submittingButton": "Envoi en cours..."
|
|
798
|
+
},
|
|
799
|
+
"resetPassword": {
|
|
800
|
+
"title": "Réinitialiser votre mot de passe",
|
|
801
|
+
"description": "Entrez votre nouveau mot de passe ci-dessous. Assurez-vous qu'il est sécurisé et comporte au moins 8 caractères.",
|
|
802
|
+
"newPasswordPlaceholder": "Nouveau mot de passe",
|
|
803
|
+
"confirmPasswordPlaceholder": "Confirmer le mot de passe",
|
|
804
|
+
"submitButton": "Réinitialiser le mot de passe",
|
|
805
|
+
"submittingButton": "Réinitialisation...",
|
|
806
|
+
"errors": {
|
|
807
|
+
"passwordRequired": "Le mot de passe est requis",
|
|
808
|
+
"confirmPasswordRequired": "La confirmation du mot de passe est requise",
|
|
809
|
+
"passwordsMismatch": "Les mots de passe ne correspondent pas"
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
"verifyEmail": {
|
|
813
|
+
"title": "Vérifiez votre e-mail",
|
|
814
|
+
"imageAlt": "Vérification de l'e-mail",
|
|
815
|
+
"descriptionPrefix": "Nous avons envoyé un e-mail de vérification à",
|
|
816
|
+
"descriptionSuffix": ". Veuillez cliquer sur le lien dans cet e-mail pour continuer.",
|
|
817
|
+
"emailFallback": "[votre e-mail]",
|
|
818
|
+
"checkInbox": "Vérifier ma boîte de réception",
|
|
819
|
+
"resendEmail": "Renvoyer l'e-mail",
|
|
820
|
+
"resendingEmail": "Envoi en cours..."
|
|
821
|
+
},
|
|
822
|
+
"twoFactor": {
|
|
823
|
+
"setup": {
|
|
824
|
+
"title": "Authentification multi-facteurs",
|
|
825
|
+
"description": "Utilisez votre application d'authentification pour scanner ce code QR. Si vous n'avez pas d'application d'authentification sur votre appareil, vous devrez en installer une maintenant.",
|
|
826
|
+
"learnMore": "En savoir plus",
|
|
827
|
+
"cantScanQr": "Impossible de scanner le code QR ?",
|
|
828
|
+
"qrPlaceholder": "Le code QR apparaîtra ici",
|
|
829
|
+
"manualEntryKey": "Clé de saisie manuelle :",
|
|
830
|
+
"cancelButton": "Annuler",
|
|
831
|
+
"nextButton": "Suivant",
|
|
832
|
+
"loadingButton": "Chargement..."
|
|
833
|
+
},
|
|
834
|
+
"verify": {
|
|
835
|
+
"title": "Entrez votre code de vérification",
|
|
836
|
+
"description": "Entrez le code que vous voyez dans votre application d'authentification",
|
|
837
|
+
"verifyButton": "Vérifier",
|
|
838
|
+
"verifyingButton": "Vérification...",
|
|
839
|
+
"helpText": "Vous pouvez aussi coller votre code à 6 chiffres"
|
|
840
|
+
},
|
|
841
|
+
"complete": {
|
|
842
|
+
"title": "Vous êtes prêt",
|
|
843
|
+
"descriptionLine1": "Vous pouvez maintenant utiliser l'application d'authentification mobile pour obtenir un code d'authentification chaque fois que vous vous connectez.",
|
|
844
|
+
"descriptionLine2": "Enregistrez ces codes de secours à usage unique dans un endroit sûr.",
|
|
845
|
+
"copyButton": "Copier",
|
|
846
|
+
"copiedButton": "Copié !",
|
|
847
|
+
"downloadButton": "Télécharger",
|
|
848
|
+
"footerText": "Ces codes de secours vous permettent de vous connecter si vous ne pouvez pas recevoir de SMS ou si vous n'avez pas accès à vos autres méthodes d'authentification à deux facteurs.",
|
|
849
|
+
"doneButton": "Terminé",
|
|
850
|
+
"loadingButton": "Chargement...",
|
|
851
|
+
"copyCodesButton": "Copier les codes",
|
|
852
|
+
"copiedCodesButton": "Copié !"
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
2. Wrap your app with the `I18nProvider` and pass your translations:
|
|
861
|
+
|
|
862
|
+
```tsx
|
|
863
|
+
import { ThemeProvider, I18nProvider, defaultTheme } from 'topiray-auth-react'
|
|
864
|
+
import fr from './i18n/fr.json'
|
|
865
|
+
|
|
866
|
+
function App() {
|
|
867
|
+
return (
|
|
868
|
+
<ThemeProvider theme={defaultTheme}>
|
|
869
|
+
<I18nProvider translations={fr}>
|
|
870
|
+
{/* Your auth components */}
|
|
871
|
+
</I18nProvider>
|
|
872
|
+
</ThemeProvider>
|
|
873
|
+
)
|
|
874
|
+
}
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
### Partial Translations
|
|
878
|
+
|
|
879
|
+
You only need to provide the keys you want to override. Any missing keys will automatically fall back to the default English translations:
|
|
880
|
+
|
|
881
|
+
```tsx
|
|
882
|
+
import { I18nProvider } from 'topiray-auth-react'
|
|
883
|
+
|
|
884
|
+
const customTranslations = {
|
|
885
|
+
topiray: {
|
|
886
|
+
auth: {
|
|
887
|
+
signIn: {
|
|
888
|
+
title: "Welcome back",
|
|
889
|
+
submitButton: "Log in"
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
<I18nProvider translations={customTranslations}>
|
|
896
|
+
{/* SignInForm will show "Welcome back" and "Log in",
|
|
897
|
+
all other strings fall back to English */}
|
|
898
|
+
</I18nProvider>
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
### Dynamic Language Switching
|
|
902
|
+
|
|
903
|
+
Switch languages at runtime by updating the translations passed to `I18nProvider`:
|
|
904
|
+
|
|
905
|
+
```tsx
|
|
906
|
+
import { I18nProvider, en } from 'topiray-auth-react'
|
|
907
|
+
import fr from './i18n/fr.json'
|
|
908
|
+
import de from './i18n/de.json'
|
|
909
|
+
|
|
910
|
+
const languages = { en, fr, de }
|
|
911
|
+
|
|
912
|
+
function App() {
|
|
913
|
+
const [locale, setLocale] = useState('en')
|
|
914
|
+
|
|
915
|
+
return (
|
|
916
|
+
<I18nProvider translations={languages[locale]}>
|
|
917
|
+
<select onChange={(e) => setLocale(e.target.value)} value={locale}>
|
|
918
|
+
<option value="en">English</option>
|
|
919
|
+
<option value="fr">Français</option>
|
|
920
|
+
<option value="de">Deutsch</option>
|
|
921
|
+
</select>
|
|
922
|
+
{/* Your auth components */}
|
|
923
|
+
</I18nProvider>
|
|
924
|
+
)
|
|
925
|
+
}
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
### Translation Keys Reference
|
|
929
|
+
|
|
930
|
+
All translation keys are nested under `topiray.auth`. Here is the full key structure:
|
|
931
|
+
|
|
932
|
+
| Namespace | Keys |
|
|
933
|
+
|-----------|------|
|
|
934
|
+
| `topiray.auth.signIn` | `title`, `emailPlaceholder`, `passwordPlaceholder`, `submitButton`, `submittingButton`, `dividerText`, `forgotPassword`, `noAccount`, `signUpLink` |
|
|
935
|
+
| `topiray.auth.signUp` | `title`, `emailPlaceholder`, `passwordPlaceholder`, `submitButton`, `submittingButton`, `dividerText`, `hasAccount`, `signInLink` |
|
|
936
|
+
| `topiray.auth.forgottenPassword` | `title`, `description`, `emailPlaceholder`, `submitButton`, `submittingButton` |
|
|
937
|
+
| `topiray.auth.resetPassword` | `title`, `description`, `newPasswordPlaceholder`, `confirmPasswordPlaceholder`, `submitButton`, `submittingButton`, `errors.passwordRequired`, `errors.confirmPasswordRequired`, `errors.passwordsMismatch` |
|
|
938
|
+
| `topiray.auth.verifyEmail` | `title`, `imageAlt`, `descriptionPrefix`, `descriptionSuffix`, `emailFallback`, `checkInbox`, `resendEmail`, `resendingEmail` |
|
|
939
|
+
| `topiray.auth.twoFactor.setup` | `title`, `description`, `learnMore`, `cantScanQr`, `qrPlaceholder`, `manualEntryKey`, `cancelButton`, `nextButton`, `loadingButton` |
|
|
940
|
+
| `topiray.auth.twoFactor.verify` | `title`, `description`, `verifyButton`, `verifyingButton`, `helpText` |
|
|
941
|
+
| `topiray.auth.twoFactor.complete` | `title`, `descriptionLine1`, `descriptionLine2`, `copyButton`, `copiedButton`, `downloadButton`, `footerText`, `doneButton`, `loadingButton`, `copyCodesButton`, `copiedCodesButton` |
|
|
942
|
+
|
|
753
943
|
## Browser Support
|
|
754
944
|
|
|
755
945
|
- Chrome 90+
|
|
@@ -757,6 +947,10 @@ const handleSocialLogin = (provider: 'google' | 'apple' | 'facebook') => {
|
|
|
757
947
|
- Safari 14+
|
|
758
948
|
- Edge 90+
|
|
759
949
|
|
|
950
|
+
## Authors
|
|
951
|
+
|
|
952
|
+
JayArrowz
|
|
953
|
+
|
|
760
954
|
## Contributing
|
|
761
955
|
|
|
762
956
|
1. Fork the repository
|
|
@@ -765,7 +959,6 @@ const handleSocialLogin = (provider: 'google' | 'apple' | 'facebook') => {
|
|
|
765
959
|
4. Add tests for new functionality
|
|
766
960
|
5. Submit a pull request
|
|
767
961
|
|
|
768
|
-
|
|
769
962
|
## Support
|
|
770
963
|
|
|
771
964
|
For questions and support:
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { TranslationDictionary } from './types';
|
|
3
|
+
interface I18nContextType {
|
|
4
|
+
t: (key: string) => string;
|
|
5
|
+
translations: TranslationDictionary;
|
|
6
|
+
}
|
|
7
|
+
export declare const useTranslation: () => I18nContextType;
|
|
8
|
+
interface I18nProviderProps {
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
translations: TranslationDictionary;
|
|
11
|
+
}
|
|
12
|
+
export declare const I18nProvider: React.FC<I18nProviderProps>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
"topiray": {
|
|
3
|
+
"auth": {
|
|
4
|
+
"signIn": {
|
|
5
|
+
"title": "Sign in",
|
|
6
|
+
"emailPlaceholder": "Email",
|
|
7
|
+
"passwordPlaceholder": "Password",
|
|
8
|
+
"submitButton": "Continue",
|
|
9
|
+
"submittingButton": "Signing in...",
|
|
10
|
+
"dividerText": "or sign in with",
|
|
11
|
+
"forgotPassword": "Forgot Password?",
|
|
12
|
+
"noAccount": "Don't have an account?",
|
|
13
|
+
"signUpLink": "Sign up"
|
|
14
|
+
},
|
|
15
|
+
"signUp": {
|
|
16
|
+
"title": "Create your account",
|
|
17
|
+
"emailPlaceholder": "Email",
|
|
18
|
+
"passwordPlaceholder": "Password",
|
|
19
|
+
"submitButton": "Create Account",
|
|
20
|
+
"submittingButton": "Creating account...",
|
|
21
|
+
"dividerText": "or sign up with",
|
|
22
|
+
"hasAccount": "Already have an account?",
|
|
23
|
+
"signInLink": "Sign in"
|
|
24
|
+
},
|
|
25
|
+
"forgottenPassword": {
|
|
26
|
+
"title": "Forgot your password?",
|
|
27
|
+
"description": "Enter your email address associated to your account and we will send you a one time link to reset your password.",
|
|
28
|
+
"emailPlaceholder": "Email",
|
|
29
|
+
"submitButton": "Reset Password",
|
|
30
|
+
"submittingButton": "Sending..."
|
|
31
|
+
},
|
|
32
|
+
"resetPassword": {
|
|
33
|
+
"title": "Reset your password",
|
|
34
|
+
"description": "Enter your new password below. Make sure it's secure and at least 8 characters long.",
|
|
35
|
+
"newPasswordPlaceholder": "New Password",
|
|
36
|
+
"confirmPasswordPlaceholder": "Confirm Password",
|
|
37
|
+
"submitButton": "Reset Password",
|
|
38
|
+
"submittingButton": "Resetting...",
|
|
39
|
+
"errors": {
|
|
40
|
+
"passwordRequired": "Password is required",
|
|
41
|
+
"confirmPasswordRequired": "Confirm password is required",
|
|
42
|
+
"passwordsMismatch": "Passwords do not match"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"verifyEmail": {
|
|
46
|
+
"title": "Verify your email",
|
|
47
|
+
"imageAlt": "Email verification",
|
|
48
|
+
"descriptionPrefix": "We sent a verification email to",
|
|
49
|
+
"descriptionSuffix": ". Please tap the link inside that email to continue.",
|
|
50
|
+
"emailFallback": "[your email]",
|
|
51
|
+
"checkInbox": "Check my inbox",
|
|
52
|
+
"resendEmail": "Resend Email",
|
|
53
|
+
"resendingEmail": "Sending..."
|
|
54
|
+
},
|
|
55
|
+
"twoFactor": {
|
|
56
|
+
"setup": {
|
|
57
|
+
"title": "Multi-Factor Authentication",
|
|
58
|
+
"description": "Use your authentication app to scan this QR code. If you don't have an authentication app on your device, you'll need to install one now.",
|
|
59
|
+
"learnMore": "Learn more",
|
|
60
|
+
"cantScanQr": "Can't scan the QR code?",
|
|
61
|
+
"qrPlaceholder": "QR Code will appear here",
|
|
62
|
+
"manualEntryKey": "Manual entry key:",
|
|
63
|
+
"cancelButton": "Cancel",
|
|
64
|
+
"nextButton": "Next",
|
|
65
|
+
"loadingButton": "Loading..."
|
|
66
|
+
},
|
|
67
|
+
"verify": {
|
|
68
|
+
"title": "Enter your verification code",
|
|
69
|
+
"description": "Enter the code that you see in your authenticator app",
|
|
70
|
+
"verifyButton": "Verify",
|
|
71
|
+
"verifyingButton": "Verifying...",
|
|
72
|
+
"helpText": "You can also paste your 6-digit code"
|
|
73
|
+
},
|
|
74
|
+
"complete": {
|
|
75
|
+
"title": "You're all set",
|
|
76
|
+
"descriptionLine1": "Now you can use the mobile authenticator app to get an authentication code any time you log in.",
|
|
77
|
+
"descriptionLine2": "Save these single-use backup codes in a safe place.",
|
|
78
|
+
"copyButton": "Copy",
|
|
79
|
+
"copiedButton": "Copied!",
|
|
80
|
+
"downloadButton": "Download",
|
|
81
|
+
"footerText": "These backup codes let you log in if you can't receive a text message or don't have access to any of your other two-factor authentication methods.",
|
|
82
|
+
"doneButton": "Done",
|
|
83
|
+
"loadingButton": "Loading...",
|
|
84
|
+
"copyCodesButton": "Copy Codes",
|
|
85
|
+
"copiedCodesButton": "Copied!"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
;
|
|
92
|
+
|
|
93
|
+
export default _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TranslationDictionary = Record<string, unknown>;
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,9 @@ export { AlertMessage } from './components/common/AlertMessage';
|
|
|
9
9
|
export { BackArrow } from './components/common/BackArrow';
|
|
10
10
|
export { SocialLoginButtons } from './components/common/SocialLoginButtons';
|
|
11
11
|
export type { ButtonProps, AlertMessageProps, BackArrowProps, SocialLoginButtonsProps } from './components/common/types';
|
|
12
|
+
export { I18nProvider, useTranslation } from './i18n/I18nProvider';
|
|
13
|
+
export type { TranslationDictionary } from './i18n/types';
|
|
14
|
+
export { default as en } from './i18n/en.json';
|
|
12
15
|
export { AuthCard } from './components/auth/AuthCard';
|
|
13
16
|
export { SignInForm } from './components/auth/SignInForm';
|
|
14
17
|
export { SignUpForm } from './components/auth/SignUpForm';
|