topiray-auth-react 1.0.3-alpha.13 → 1.0.3

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 CHANGED
@@ -1,778 +1,778 @@
1
- # Topiray Auth React Component Library
2
- ![NPM Version](https://img.shields.io/npm/v/topiray-auth-react)
3
- ![NPM Downloads](https://img.shields.io/npm/dm/topiray-auth-react)
4
- ![NPM License](https://img.shields.io/npm/l/topiray-auth-react)
5
-
6
- A comprehensive, themeable React component library for authentication flows. Built with TypeScript, CSS Modules, and designed for maximum customization and accessibility.
7
-
8
- ## Features
9
-
10
- - 🎨 **Fully Themeable** - Customize colors, fonts, spacing, and more
11
- - 🔧 **CSS Modules** - Strongly-typed, scoped styling
12
- - 📱 **Responsive Design** - Mobile-first approach with breakpoint support
13
- - ♿ **Accessible** - ARIA labels, keyboard navigation, focus management
14
- - 🔐 **Complete Auth Flow** - Sign in/up, 2FA, email verification, password reset
15
- - ⚡ **TypeScript** - Full type safety and IntelliSense support
16
- - 🎯 **Tree Shakeable** - Import only what you need
17
-
18
- <img width="1910" height="892" alt="image" src="https://github.com/user-attachments/assets/1eb04b72-be57-477a-96de-2879d2fc9191" />
19
- <img width="1910" height="892" alt="image" src="https://github.com/user-attachments/assets/089695f9-9558-4cea-af24-fec94ecd2ebb" />
20
- <img width="1910" height="892" alt="image" src="https://github.com/user-attachments/assets/dfc87f46-eb1d-4247-9404-6ab136fc5055" />
21
-
22
-
23
- ## Installation
24
-
25
- ```bash
26
- npm install topiray-auth-react
27
- # or
28
- yarn add topiray-auth-react
29
- ```
30
-
31
- ### Peer Dependencies
32
-
33
- ```bash
34
- npm install react react-dom lucide-react @mui/material
35
- ```
36
-
37
- ### CSS Import
38
-
39
- **Important**: You must import the CSS file for proper styling:
40
-
41
- ```tsx
42
- // Import the CSS file in your main App component or index file
43
- import 'topiray-auth-react/dist/topiray-auth-react.css'
44
- ```
45
-
46
- Or if you're using a bundler that supports CSS imports:
47
-
48
- ```css
49
- /* In your main CSS file */
50
- @import 'topiray-auth-react/dist/topiray-auth-react.css';
51
- ```
52
-
53
- ## Quick Start
54
-
55
- ```tsx
56
- import React from 'react'
57
- import {
58
- ThemeProvider,
59
- defaultTheme,
60
- TwoPanelLayout,
61
- AuthCard,
62
- SignInForm
63
- } from 'topiray-auth-react'
64
-
65
- // Import the CSS file
66
- import 'topiray-auth-react/dist/topiray-auth-react.css'
67
-
68
- function App() {
69
- const handleSignIn = (email: string, password: string) => {
70
- console.log('Sign in:', { email, password })
71
- }
72
-
73
- return (
74
- <ThemeProvider theme={defaultTheme}>
75
- <TwoPanelLayout
76
- rightContent={
77
- <AuthCard>
78
- <SignInForm
79
- onSubmit={handleSignIn}
80
- onForgotPassword={() => console.log('Forgot password')}
81
- onSignUp={() => console.log('Sign up')}
82
- onSocialLogin={(provider) => console.log('Social:', provider)}
83
- authProviders={['google', 'apple', 'facebook']}
84
- />
85
- </AuthCard>
86
- }
87
- />
88
- </ThemeProvider>
89
- )
90
- }
91
- ```
92
-
93
- ## Components
94
-
95
- ### Auth Components
96
-
97
- #### AuthCard
98
- Container wrapper for auth forms with consistent styling.
99
-
100
- ```tsx
101
- import { AuthCard } from 'topiray-auth-react'
102
-
103
- <AuthCard>
104
- {/* Your auth form content */}
105
- </AuthCard>
106
- ```
107
-
108
- #### SignInForm
109
- Complete sign-in form with email/password and customizable social login options.
110
-
111
- ```tsx
112
- import { SignInForm } from 'topiray-auth-react'
113
-
114
- <SignInForm
115
- onSubmit={(email, password) => handleSignIn(email, password)}
116
- onForgotPassword={() => navigate('/forgot-password')}
117
- onSignUp={() => navigate('/sign-up')}
118
- onSocialLogin={(provider) => handleSocialLogin(provider)}
119
- authProviders={['google', 'apple', 'facebook']}
120
- isLoading={isSigningIn}
121
- logoSrc="/your-logo.png"
122
- />
123
- ```
124
-
125
- #### SignUpForm
126
- Account creation form with business/individual selection and customizable social login.
127
-
128
- ```tsx
129
- import { SignUpForm } from 'topiray-auth-react'
130
-
131
- <SignUpForm
132
- onSubmit={(email, password, accountType) => handleSignUp(email, password, accountType)}
133
- onSignIn={() => navigate('/sign-in')}
134
- onSocialLogin={(provider) => handleSocialLogin(provider)}
135
- authProviders={['google', 'apple', 'facebook']}
136
- isLoading={isSigningUp}
137
- logoSrc="/your-logo.png"
138
- />
139
- ```
140
-
141
- #### ForgottenPasswordForm
142
- Password reset request form.
143
-
144
- ```tsx
145
- import { ForgottenPasswordForm } from 'topiray-auth-react'
146
-
147
- <ForgottenPasswordForm
148
- onSubmit={(email) => handlePasswordReset(email)}
149
- isLoading={isLoading}
150
- />
151
- ```
152
-
153
- #### VerifyEmailForm
154
- Email verification flow with resend functionality.
155
-
156
- ```tsx
157
- import { VerifyEmailForm } from 'topiray-auth-react'
158
-
159
- <VerifyEmailForm
160
- onSubmit={() => navigate('/sign-in')}
161
- onResendEmail={() => handleResendEmail()}
162
- email="user@example.com"
163
- isLoading={isLoading}
164
- />
165
- ```
166
-
167
- ### Two-Factor Authentication
168
-
169
- #### TwoFactorSetupForm
170
- QR code setup for authenticator apps.
171
-
172
- ```tsx
173
- import { TwoFactorSetupForm } from 'topiray-auth-react'
174
-
175
- <TwoFactorSetupForm
176
- onNext={() => navigate('/2fa/verify')}
177
- onCancel={() => navigate('/dashboard')}
178
- qrCodeUri="otpauth://totp/App:user@example.com?secret=SECRET&issuer=App"
179
- sharedKey="JBSWY3DPEHPK3PXP"
180
- isLoading={isLoading}
181
- />
182
- ```
183
-
184
- #### TwoFactorSetupEnterVerificationForm
185
- 6-digit code entry with auto-focus and paste support.
186
-
187
- ```tsx
188
- import { TwoFactorSetupEnterVerificationForm } from 'topiray-auth-react'
189
-
190
- <TwoFactorSetupEnterVerificationForm
191
- onVerify={(code) => handleVerification(code)}
192
- isLoading={isVerifying}
193
- error={error}
194
- backRoute="/2fa/setup"
195
- />
196
- ```
197
-
198
- #### TwoFactorSetupCompleteForm
199
- Backup codes display with copy/download functionality.
200
-
201
- ```tsx
202
- import { TwoFactorSetupCompleteForm } from 'topiray-auth-react'
203
-
204
- <TwoFactorSetupCompleteForm
205
- onDone={() => navigate('/dashboard')}
206
- backupCodes={recoveryCodes}
207
- isLoading={isLoading}
208
- />
209
- ```
210
-
211
- ### Layout Components
212
-
213
- #### TwoPanelLayout
214
- Responsive layout with left branding panel and right content area.
215
-
216
- ```tsx
217
- import { TwoPanelLayout } from 'topiray-auth-react'
218
-
219
- <TwoPanelLayout
220
- leftContent={<YourBrandingContent />}
221
- rightContent={<YourAuthForm />}
222
- leftBackgroundImage="/background.jpg"
223
- logoSrc="/logo.png"
224
- />
225
- ```
226
-
227
- #### NavLinksLayout
228
- Flexible content layout for pages with navigation.
229
-
230
- ```tsx
231
- import { NavLinksLayout } from 'topiray-auth-react'
232
-
233
- <NavLinksLayout
234
- middle={<MainContent />}
235
- right={<SidebarContent />}
236
- />
237
- ```
238
-
239
- ### Common Components
240
-
241
- #### Button
242
- Versatile button with loading states and variants.
243
-
244
- ```tsx
245
- import { Button } from 'topiray-auth-react'
246
-
247
- <Button variant="primary" isLoading={isLoading} fullWidth>
248
- Sign In
249
- </Button>
250
-
251
- <Button variant="secondary" icon="google">
252
- Sign in with Google
253
- </Button>
254
- ```
255
-
256
- #### AlertMessage
257
- Dismissible alert messages for different states.
258
-
259
- ```tsx
260
- import { AlertMessage } from 'topiray-auth-react'
261
-
262
- <AlertMessage
263
- type="error"
264
- message="Invalid credentials"
265
- dismissible
266
- onDismiss={() => setError(null)}
267
- />
268
- ```
269
-
270
- #### SocialLoginButtons
271
- Pre-configured social login buttons.
272
-
273
- ```tsx
274
- import { SocialLoginButtons } from 'topiray-auth-react'
275
-
276
- <SocialLoginButtons
277
- onSocialLogin={(provider) => handleSocialLogin(provider)}
278
- providers={['google', 'apple', 'facebook']}
279
- orientation="vertical"
280
- isLoading={isLoading}
281
- />
282
- ```
283
-
284
- ### Customizing Social Login Providers
285
-
286
- You can customize which social login providers are displayed using the `authProviders` prop on both `SignInForm` and `SignUpForm`:
287
-
288
- ```tsx
289
- // Show only Google and Apple
290
- <SignInForm
291
- authProviders={['google', 'apple']}
292
- onSocialLogin={(provider) => handleSocialLogin(provider)}
293
- // ... other props
294
- />
295
-
296
- // Show all available providers (default)
297
- <SignUpForm
298
- authProviders={['apple', 'google', 'facebook']}
299
- onSocialLogin={(provider) => handleSocialLogin(provider)}
300
- // ... other props
301
- />
302
-
303
- // Show only Google
304
- <SignInForm
305
- authProviders={['google']}
306
- onSocialLogin={(provider) => handleSocialLogin(provider)}
307
- // ... other props
308
- />
309
-
310
- // Hide social login entirely by setting empty array or omitting the prop
311
- <SignInForm
312
- authProviders={[]}
313
- // ... other props (onSocialLogin not needed if no providers)
314
- />
315
- ```
316
-
317
- **Available providers:**
318
- - `'apple'` - Apple Sign In
319
- - `'google'` - Google Sign In
320
- - `'facebook'` - Facebook Login
321
-
322
- **Default behavior:** If `authProviders` is not specified, it defaults to `['apple', 'google', 'facebook']`.
323
-
324
- ## Real-World Usage Examples
325
-
326
- ### Complete Sign-In Page
327
-
328
- ```tsx
329
- import React, { useState, useEffect } from 'react'
330
- import { useNavigate, useLocation } from 'react-router-dom'
331
- import {
332
- ThemeProvider,
333
- defaultTheme,
334
- TwoPanelLayout,
335
- AuthCard,
336
- SignInForm,
337
- AlertMessage
338
- } from 'topiray-auth-react'
339
-
340
- // Import the CSS file
341
- import 'topiray-auth-react/dist/topiray-auth-react.css'
342
-
343
- function SignInPage() {
344
- const navigate = useNavigate()
345
- const location = useLocation()
346
- const [error, setError] = useState<string | null>(null)
347
- const [isLoading, setIsLoading] = useState(false)
348
-
349
- // Get success message from registration
350
- const successMessage = location.state?.message
351
-
352
- const handleSignIn = async (email: string, password: string) => {
353
- try {
354
- setError(null)
355
- setIsLoading(true)
356
-
357
- const result = await signInAPI(email, password)
358
-
359
- if (result.succeeded) {
360
- navigate('/dashboard')
361
- } else if (result.requiresTwoFactor) {
362
- navigate('/2fa/signin', { state: { userId: result.userId } })
363
- } else if (result.isNotAllowed) {
364
- navigate(`/verify-email?email=${encodeURIComponent(email)}`)
365
- } else {
366
- setError('Invalid email or password.')
367
- }
368
- } catch (error) {
369
- setError('An error occurred during sign in.')
370
- } finally {
371
- setIsLoading(false)
372
- }
373
- }
374
-
375
- const handleSocialLogin = async (provider: 'google' | 'apple' | 'facebook') => {
376
- try {
377
- setError(null)
378
- setIsLoading(true)
379
-
380
- // Initiate social login flow
381
- await socialSignInAPI(provider)
382
- } catch (error) {
383
- setError(`Failed to sign in with ${provider}`)
384
- } finally {
385
- setIsLoading(false)
386
- }
387
- }
388
-
389
- return (
390
- <ThemeProvider theme={defaultTheme}>
391
- <TwoPanelLayout
392
- rightContent={
393
- <AuthCard>
394
- {successMessage && (
395
- <AlertMessage message={successMessage} type="success" />
396
- )}
397
- {error && (
398
- <AlertMessage message={error} type="error" />
399
- )}
400
- <SignInForm
401
- onSubmit={handleSignIn}
402
- onForgotPassword={() => navigate('/forgot-password')}
403
- onSignUp={() => navigate('/sign-up')}
404
- onSocialLogin={handleSocialLogin}
405
- authProviders={['google', 'apple']} // Only show Google and Apple
406
- isLoading={isLoading}
407
- />
408
- </AuthCard>
409
- }
410
- />
411
- </ThemeProvider>
412
- )
413
- }
414
- ```
415
-
416
- ### Two-Factor Setup with QR Code
417
-
418
- ```tsx
419
- import React, { useEffect, useState } from 'react'
420
- import { useNavigate } from 'react-router-dom'
421
- import QRCode from 'qrcode'
422
- import {
423
- TwoPanelLayout,
424
- AuthCard,
425
- TwoFactorSetupForm,
426
- AlertMessage
427
- } from 'topiray-auth-react'
428
-
429
- function TwoFactorSetupPage() {
430
- const navigate = useNavigate()
431
- const [qrCodeDataUrl, setQrCodeDataUrl] = useState<string | null>(null)
432
- const [sharedKey, setSharedKey] = useState<string | null>(null)
433
- const [error, setError] = useState<string | null>(null)
434
- const [isLoading, setIsLoading] = useState(false)
435
-
436
- useEffect(() => {
437
- generateQRCode()
438
- }, [])
439
-
440
- const generateQRCode = async () => {
441
- try {
442
- setIsLoading(true)
443
- const result = await createAuthenticatorKeyAPI()
444
-
445
- if (result.authenticatorUri && result.sharedKey) {
446
- const qrDataUrl = await QRCode.toDataURL(result.authenticatorUri, {
447
- width: 200,
448
- margin: 2
449
- })
450
-
451
- setQrCodeDataUrl(qrDataUrl)
452
- setSharedKey(result.sharedKey)
453
-
454
- // Render QR code
455
- setTimeout(() => {
456
- const container = document.getElementById('qr-code-container')
457
- if (container && qrDataUrl) {
458
- container.innerHTML = `<img src="${qrDataUrl}" alt="QR Code" />`
459
- }
460
- }, 100)
461
- } else {
462
- setError('Failed to generate QR code.')
463
- }
464
- } catch (error) {
465
- setError('Failed to generate QR code.')
466
- } finally {
467
- setIsLoading(false)
468
- }
469
- }
470
-
471
- return (
472
- <TwoPanelLayout
473
- rightContent={
474
- <AuthCard>
475
- {error && <AlertMessage message={error} type="error" />}
476
- <TwoFactorSetupForm
477
- onNext={() => navigate('/2fa/verify')}
478
- onCancel={() => navigate('/dashboard')}
479
- qrCodeUri={qrCodeDataUrl}
480
- sharedKey={sharedKey}
481
- isLoading={isLoading}
482
- />
483
- </AuthCard>
484
- }
485
- />
486
- )
487
- }
488
- ```
489
-
490
- ## Theming
491
-
492
- ### Using Built-in Themes
493
-
494
- ```tsx
495
- import { ThemeProvider, defaultTheme, darkTheme } from 'topiray-auth-react'
496
-
497
- // Light theme
498
- <ThemeProvider theme={defaultTheme}>
499
- <App />
500
- </ThemeProvider>
501
-
502
- // Dark theme
503
- <ThemeProvider theme={darkTheme}>
504
- <App />
505
- </ThemeProvider>
506
- ```
507
-
508
- ### Creating Custom Themes
509
-
510
- ```tsx
511
- import { createCustomTheme } from 'topiray-auth-react'
512
-
513
- const corporateTheme = createCustomTheme({
514
- colors: {
515
- primary: '#0066cc',
516
- secondary: '#6b7280',
517
- tertiary: "#f3f4f6",
518
- background: '#ffffff',
519
- surface: '#f9fafb',
520
- text: '#111827',
521
- textSecondary: '#6b7280',
522
- border: '#d1d5db',
523
- success: '#10b981',
524
- warning: '#f59e0b',
525
- error: '#ef4444',
526
- info: '#3b82f6',
527
- hover: '#f3f4f6',
528
- active: '#e5e7eb',
529
- disabled: '#9ca3af',
530
- inputBackground: '#ffffff',
531
- inputBorder: '#d1d5db',
532
- inputText: '#111827',
533
- inputPlaceholder: '#9ca3af',
534
- buttonPrimary: '#0066cc',
535
- buttonPrimaryText: '#ffffff',
536
- buttonSecondary: '#6b7280',
537
- buttonSecondaryText: '#ffffff',
538
- buttonSocial: '#374151',
539
- buttonSocialText: '#ffffff'
540
- },
541
- brand: {
542
- logo: '/corporate-logo.png',
543
- logoAlt: 'Corporate Logo'
544
- },
545
- customization: {
546
- showFormHeader: true,
547
- showSocialLogin: true,
548
- showBackArrow: true,
549
- showLogo: true,
550
- roundedCorners: true,
551
- animations: true
552
- }
553
- })
554
-
555
- <ThemeProvider theme={corporateTheme}>
556
- <App />
557
- </ThemeProvider>
558
- ```
559
-
560
- ### Advanced Theme Customization
561
-
562
- ```tsx
563
- const advancedTheme = createCustomTheme({
564
- colors: {
565
- // Custom color palette
566
- primary: '#7c3aed',
567
- secondary: '#64748b',
568
- // ... other colors
569
- },
570
- components: {
571
- spacing: {
572
- xs: '0.25rem',
573
- sm: '0.5rem',
574
- md: '1rem',
575
- lg: '1.5rem',
576
- xl: '2rem'
577
- },
578
- borderRadius: {
579
- sm: '0.25rem',
580
- md: '0.5rem',
581
- lg: '0.75rem',
582
- xl: '1rem'
583
- },
584
- typography: {
585
- fontFamily: '"Inter", system-ui, sans-serif',
586
- fontSize: {
587
- xs: '0.75rem',
588
- sm: '0.875rem',
589
- md: '1rem',
590
- lg: '1.125rem',
591
- xl: '1.25rem',
592
- xxl: '1.5rem'
593
- }
594
- }
595
- },
596
- customization: {
597
- backgroundImage: '/custom-background.jpg',
598
- leftPanelContent: <CustomBrandingComponent />
599
- }
600
- })
601
- ```
602
-
603
- ## CSS Custom Properties
604
-
605
- The library uses CSS custom properties for theming. Make sure to import the CSS file first, then you can override these properties:
606
-
607
- ```tsx
608
- // First, import the CSS file
609
- import 'topiray-auth-react/dist/topiray-auth-react.css'
610
- ```
611
-
612
- ```css
613
- /* Then override custom properties in your CSS */
614
- :root {
615
- --topiray-color-primary: #your-brand-color;
616
- --topiray-color-surface: #your-surface-color;
617
- --topiray-font-family: 'Your Font', sans-serif;
618
- --topiray-radius-md: 12px;
619
- --topiray-spacing-lg: 24px;
620
- }
621
- ```
622
-
623
- ## Integration Patterns
624
-
625
- ### With React Router
626
-
627
- ```tsx
628
- import { BrowserRouter, Routes, Route } from 'react-router-dom'
629
-
630
- // Import the CSS file once at the app level
631
- import 'topiray-auth-react/dist/topiray-auth-react.css'
632
-
633
- function App() {
634
- return (
635
- <ThemeProvider theme={defaultTheme}>
636
- <BrowserRouter>
637
- <Routes>
638
- <Route path="/signin" element={<SignInPage />} />
639
- <Route path="/signup" element={<SignUpPage />} />
640
- <Route path="/forgot-password" element={<ForgotPasswordPage />} />
641
- <Route path="/verify-email" element={<VerifyEmailPage />} />
642
- <Route path="/2fa/setup" element={<TwoFactorSetupPage />} />
643
- <Route path="/2fa/verify" element={<TwoFactorVerifyPage />} />
644
- <Route path="/2fa/complete" element={<TwoFactorCompletePage />} />
645
- </Routes>
646
- </BrowserRouter>
647
- </ThemeProvider>
648
- )
649
- }
650
- ```
651
-
652
- ### With State Management
653
-
654
- ```tsx
655
- // Using React Context
656
- const AuthContext = createContext()
657
-
658
- function AuthProvider({ children }) {
659
- const [user, setUser] = useState(null)
660
- const [isLoading, setIsLoading] = useState(false)
661
-
662
- const login = async (email, password) => {
663
- setIsLoading(true)
664
- try {
665
- const result = await signInAPI(email, password)
666
- setUser(result.user)
667
- return result
668
- } finally {
669
- setIsLoading(false)
670
- }
671
- }
672
-
673
- return (
674
- <AuthContext.Provider value={{ user, isLoading, login }}>
675
- {children}
676
- </AuthContext.Provider>
677
- )
678
- }
679
- ```
680
-
681
- ### With Form Validation
682
-
683
- ```tsx
684
- import { z } from 'zod'
685
-
686
- const signInSchema = z.object({
687
- email: z.string().email('Invalid email address'),
688
- password: z.string().min(8, 'Password must be at least 8 characters')
689
- })
690
-
691
- function SignInPage() {
692
- const [errors, setErrors] = useState({})
693
-
694
- const handleSignIn = (email, password) => {
695
- try {
696
- signInSchema.parse({ email, password })
697
- setErrors({})
698
- // Proceed with sign in
699
- } catch (error) {
700
- setErrors(error.flatten().fieldErrors)
701
- }
702
- }
703
-
704
- return (
705
- <SignInForm
706
- onSubmit={handleSignIn}
707
- authProviders={['google', 'apple']}
708
- // Pass validation errors to form
709
- />
710
- )
711
- }
712
- ```
713
-
714
- ## TypeScript Support
715
-
716
- Full TypeScript support with comprehensive type definitions:
717
-
718
- ```tsx
719
- import type {
720
- ThemeConfig,
721
- SignInFormProps,
722
- AuthCardProps
723
- } from 'topiray-auth-react'
724
-
725
- // Custom theme with full type safety
726
- const myTheme: ThemeConfig = {
727
- colors: {
728
- primary: '#0066cc',
729
- // ... TypeScript will validate all required properties
730
- },
731
- // ... rest of theme configuration
732
- }
733
-
734
- // Component props are fully typed
735
- const handleSignIn: SignInFormProps['onSubmit'] = (email, password) => {
736
- // email and password are properly typed as strings
737
- }
738
-
739
- // Social login providers are strictly typed
740
- const handleSocialLogin = (provider: 'google' | 'apple' | 'facebook') => {
741
- // provider parameter is type-safe
742
- }
743
- ```
744
-
745
- ## Accessibility Features
746
-
747
- - **Keyboard Navigation**: Full keyboard support for all interactive elements
748
- - **Screen Reader Support**: Proper ARIA labels and descriptions
749
- - **Focus Management**: Logical focus flow and focus trapping in modals
750
- - **High Contrast**: Colors meet WCAG contrast requirements
751
- - **Reduced Motion**: Respects user's motion preferences
752
-
753
- ## Browser Support
754
-
755
- - Chrome 90+
756
- - Firefox 88+
757
- - Safari 14+
758
- - Edge 90+
759
-
760
- ## Contributing
761
-
762
- 1. Fork the repository
763
- 2. Create a feature branch
764
- 3. Make your changes
765
- 4. Add tests for new functionality
766
- 5. Submit a pull request
767
-
768
-
769
- ## Support
770
-
771
- For questions and support:
772
- - Create an issue on GitHub
773
- - Check the documentation
774
- - Review the demo application
775
-
776
- ---
777
-
778
- Built with ❤️ for the React community
1
+ # Topiray Auth React Component Library
2
+ ![NPM Version](https://img.shields.io/npm/v/topiray-auth-react)
3
+ ![NPM Downloads](https://img.shields.io/npm/dm/topiray-auth-react)
4
+ ![NPM License](https://img.shields.io/npm/l/topiray-auth-react)
5
+
6
+ A comprehensive, themeable React component library for authentication flows. Built with TypeScript, CSS Modules, and designed for maximum customization and accessibility.
7
+
8
+ ## Features
9
+
10
+ - 🎨 **Fully Themeable** - Customize colors, fonts, spacing, and more
11
+ - 🔧 **CSS Modules** - Strongly-typed, scoped styling
12
+ - 📱 **Responsive Design** - Mobile-first approach with breakpoint support
13
+ - ♿ **Accessible** - ARIA labels, keyboard navigation, focus management
14
+ - 🔐 **Complete Auth Flow** - Sign in/up, 2FA, email verification, password reset
15
+ - ⚡ **TypeScript** - Full type safety and IntelliSense support
16
+ - 🎯 **Tree Shakeable** - Import only what you need
17
+
18
+ <img width="1910" height="892" alt="image" src="https://github.com/user-attachments/assets/1eb04b72-be57-477a-96de-2879d2fc9191" />
19
+ <img width="1910" height="892" alt="image" src="https://github.com/user-attachments/assets/089695f9-9558-4cea-af24-fec94ecd2ebb" />
20
+ <img width="1910" height="892" alt="image" src="https://github.com/user-attachments/assets/dfc87f46-eb1d-4247-9404-6ab136fc5055" />
21
+
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ npm install topiray-auth-react
27
+ # or
28
+ yarn add topiray-auth-react
29
+ ```
30
+
31
+ ### Peer Dependencies
32
+
33
+ ```bash
34
+ npm install react react-dom lucide-react @mui/material
35
+ ```
36
+
37
+ ### CSS Import
38
+
39
+ **Important**: You must import the CSS file for proper styling:
40
+
41
+ ```tsx
42
+ // Import the CSS file in your main App component or index file
43
+ import 'topiray-auth-react/dist/topiray-auth-react.css'
44
+ ```
45
+
46
+ Or if you're using a bundler that supports CSS imports:
47
+
48
+ ```css
49
+ /* In your main CSS file */
50
+ @import 'topiray-auth-react/dist/topiray-auth-react.css';
51
+ ```
52
+
53
+ ## Quick Start
54
+
55
+ ```tsx
56
+ import React from 'react'
57
+ import {
58
+ ThemeProvider,
59
+ defaultTheme,
60
+ TwoPanelLayout,
61
+ AuthCard,
62
+ SignInForm
63
+ } from 'topiray-auth-react'
64
+
65
+ // Import the CSS file
66
+ import 'topiray-auth-react/dist/topiray-auth-react.css'
67
+
68
+ function App() {
69
+ const handleSignIn = (email: string, password: string) => {
70
+ console.log('Sign in:', { email, password })
71
+ }
72
+
73
+ return (
74
+ <ThemeProvider theme={defaultTheme}>
75
+ <TwoPanelLayout
76
+ rightContent={
77
+ <AuthCard>
78
+ <SignInForm
79
+ onSubmit={handleSignIn}
80
+ onForgotPassword={() => console.log('Forgot password')}
81
+ onSignUp={() => console.log('Sign up')}
82
+ onSocialLogin={(provider) => console.log('Social:', provider)}
83
+ authProviders={['google', 'apple', 'facebook']}
84
+ />
85
+ </AuthCard>
86
+ }
87
+ />
88
+ </ThemeProvider>
89
+ )
90
+ }
91
+ ```
92
+
93
+ ## Components
94
+
95
+ ### Auth Components
96
+
97
+ #### AuthCard
98
+ Container wrapper for auth forms with consistent styling.
99
+
100
+ ```tsx
101
+ import { AuthCard } from 'topiray-auth-react'
102
+
103
+ <AuthCard>
104
+ {/* Your auth form content */}
105
+ </AuthCard>
106
+ ```
107
+
108
+ #### SignInForm
109
+ Complete sign-in form with email/password and customizable social login options.
110
+
111
+ ```tsx
112
+ import { SignInForm } from 'topiray-auth-react'
113
+
114
+ <SignInForm
115
+ onSubmit={(email, password) => handleSignIn(email, password)}
116
+ onForgotPassword={() => navigate('/forgot-password')}
117
+ onSignUp={() => navigate('/sign-up')}
118
+ onSocialLogin={(provider) => handleSocialLogin(provider)}
119
+ authProviders={['google', 'apple', 'facebook']}
120
+ isLoading={isSigningIn}
121
+ logoSrc="/your-logo.png"
122
+ />
123
+ ```
124
+
125
+ #### SignUpForm
126
+ Account creation form with business/individual selection and customizable social login.
127
+
128
+ ```tsx
129
+ import { SignUpForm } from 'topiray-auth-react'
130
+
131
+ <SignUpForm
132
+ onSubmit={(email, password, accountType) => handleSignUp(email, password, accountType)}
133
+ onSignIn={() => navigate('/sign-in')}
134
+ onSocialLogin={(provider) => handleSocialLogin(provider)}
135
+ authProviders={['google', 'apple', 'facebook']}
136
+ isLoading={isSigningUp}
137
+ logoSrc="/your-logo.png"
138
+ />
139
+ ```
140
+
141
+ #### ForgottenPasswordForm
142
+ Password reset request form.
143
+
144
+ ```tsx
145
+ import { ForgottenPasswordForm } from 'topiray-auth-react'
146
+
147
+ <ForgottenPasswordForm
148
+ onSubmit={(email) => handlePasswordReset(email)}
149
+ isLoading={isLoading}
150
+ />
151
+ ```
152
+
153
+ #### VerifyEmailForm
154
+ Email verification flow with resend functionality.
155
+
156
+ ```tsx
157
+ import { VerifyEmailForm } from 'topiray-auth-react'
158
+
159
+ <VerifyEmailForm
160
+ onSubmit={() => navigate('/sign-in')}
161
+ onResendEmail={() => handleResendEmail()}
162
+ email="user@example.com"
163
+ isLoading={isLoading}
164
+ />
165
+ ```
166
+
167
+ ### Two-Factor Authentication
168
+
169
+ #### TwoFactorSetupForm
170
+ QR code setup for authenticator apps.
171
+
172
+ ```tsx
173
+ import { TwoFactorSetupForm } from 'topiray-auth-react'
174
+
175
+ <TwoFactorSetupForm
176
+ onNext={() => navigate('/2fa/verify')}
177
+ onCancel={() => navigate('/dashboard')}
178
+ qrCodeUri="otpauth://totp/App:user@example.com?secret=SECRET&issuer=App"
179
+ sharedKey="JBSWY3DPEHPK3PXP"
180
+ isLoading={isLoading}
181
+ />
182
+ ```
183
+
184
+ #### TwoFactorSetupEnterVerificationForm
185
+ 6-digit code entry with auto-focus and paste support.
186
+
187
+ ```tsx
188
+ import { TwoFactorSetupEnterVerificationForm } from 'topiray-auth-react'
189
+
190
+ <TwoFactorSetupEnterVerificationForm
191
+ onVerify={(code) => handleVerification(code)}
192
+ isLoading={isVerifying}
193
+ error={error}
194
+ backRoute="/2fa/setup"
195
+ />
196
+ ```
197
+
198
+ #### TwoFactorSetupCompleteForm
199
+ Backup codes display with copy/download functionality.
200
+
201
+ ```tsx
202
+ import { TwoFactorSetupCompleteForm } from 'topiray-auth-react'
203
+
204
+ <TwoFactorSetupCompleteForm
205
+ onDone={() => navigate('/dashboard')}
206
+ backupCodes={recoveryCodes}
207
+ isLoading={isLoading}
208
+ />
209
+ ```
210
+
211
+ ### Layout Components
212
+
213
+ #### TwoPanelLayout
214
+ Responsive layout with left branding panel and right content area.
215
+
216
+ ```tsx
217
+ import { TwoPanelLayout } from 'topiray-auth-react'
218
+
219
+ <TwoPanelLayout
220
+ leftContent={<YourBrandingContent />}
221
+ rightContent={<YourAuthForm />}
222
+ leftBackgroundImage="/background.jpg"
223
+ logoSrc="/logo.png"
224
+ />
225
+ ```
226
+
227
+ #### NavLinksLayout
228
+ Flexible content layout for pages with navigation.
229
+
230
+ ```tsx
231
+ import { NavLinksLayout } from 'topiray-auth-react'
232
+
233
+ <NavLinksLayout
234
+ middle={<MainContent />}
235
+ right={<SidebarContent />}
236
+ />
237
+ ```
238
+
239
+ ### Common Components
240
+
241
+ #### Button
242
+ Versatile button with loading states and variants.
243
+
244
+ ```tsx
245
+ import { Button } from 'topiray-auth-react'
246
+
247
+ <Button variant="primary" isLoading={isLoading} fullWidth>
248
+ Sign In
249
+ </Button>
250
+
251
+ <Button variant="secondary" icon="google">
252
+ Sign in with Google
253
+ </Button>
254
+ ```
255
+
256
+ #### AlertMessage
257
+ Dismissible alert messages for different states.
258
+
259
+ ```tsx
260
+ import { AlertMessage } from 'topiray-auth-react'
261
+
262
+ <AlertMessage
263
+ type="error"
264
+ message="Invalid credentials"
265
+ dismissible
266
+ onDismiss={() => setError(null)}
267
+ />
268
+ ```
269
+
270
+ #### SocialLoginButtons
271
+ Pre-configured social login buttons.
272
+
273
+ ```tsx
274
+ import { SocialLoginButtons } from 'topiray-auth-react'
275
+
276
+ <SocialLoginButtons
277
+ onSocialLogin={(provider) => handleSocialLogin(provider)}
278
+ providers={['google', 'apple', 'facebook']}
279
+ orientation="vertical"
280
+ isLoading={isLoading}
281
+ />
282
+ ```
283
+
284
+ ### Customizing Social Login Providers
285
+
286
+ You can customize which social login providers are displayed using the `authProviders` prop on both `SignInForm` and `SignUpForm`:
287
+
288
+ ```tsx
289
+ // Show only Google and Apple
290
+ <SignInForm
291
+ authProviders={['google', 'apple']}
292
+ onSocialLogin={(provider) => handleSocialLogin(provider)}
293
+ // ... other props
294
+ />
295
+
296
+ // Show all available providers (default)
297
+ <SignUpForm
298
+ authProviders={['apple', 'google', 'facebook']}
299
+ onSocialLogin={(provider) => handleSocialLogin(provider)}
300
+ // ... other props
301
+ />
302
+
303
+ // Show only Google
304
+ <SignInForm
305
+ authProviders={['google']}
306
+ onSocialLogin={(provider) => handleSocialLogin(provider)}
307
+ // ... other props
308
+ />
309
+
310
+ // Hide social login entirely by setting empty array or omitting the prop
311
+ <SignInForm
312
+ authProviders={[]}
313
+ // ... other props (onSocialLogin not needed if no providers)
314
+ />
315
+ ```
316
+
317
+ **Available providers:**
318
+ - `'apple'` - Apple Sign In
319
+ - `'google'` - Google Sign In
320
+ - `'facebook'` - Facebook Login
321
+
322
+ **Default behavior:** If `authProviders` is not specified, it defaults to `['apple', 'google', 'facebook']`.
323
+
324
+ ## Real-World Usage Examples
325
+
326
+ ### Complete Sign-In Page
327
+
328
+ ```tsx
329
+ import React, { useState, useEffect } from 'react'
330
+ import { useNavigate, useLocation } from 'react-router-dom'
331
+ import {
332
+ ThemeProvider,
333
+ defaultTheme,
334
+ TwoPanelLayout,
335
+ AuthCard,
336
+ SignInForm,
337
+ AlertMessage
338
+ } from 'topiray-auth-react'
339
+
340
+ // Import the CSS file
341
+ import 'topiray-auth-react/dist/topiray-auth-react.css'
342
+
343
+ function SignInPage() {
344
+ const navigate = useNavigate()
345
+ const location = useLocation()
346
+ const [error, setError] = useState<string | null>(null)
347
+ const [isLoading, setIsLoading] = useState(false)
348
+
349
+ // Get success message from registration
350
+ const successMessage = location.state?.message
351
+
352
+ const handleSignIn = async (email: string, password: string) => {
353
+ try {
354
+ setError(null)
355
+ setIsLoading(true)
356
+
357
+ const result = await signInAPI(email, password)
358
+
359
+ if (result.succeeded) {
360
+ navigate('/dashboard')
361
+ } else if (result.requiresTwoFactor) {
362
+ navigate('/2fa/signin', { state: { userId: result.userId } })
363
+ } else if (result.isNotAllowed) {
364
+ navigate(`/verify-email?email=${encodeURIComponent(email)}`)
365
+ } else {
366
+ setError('Invalid email or password.')
367
+ }
368
+ } catch (error) {
369
+ setError('An error occurred during sign in.')
370
+ } finally {
371
+ setIsLoading(false)
372
+ }
373
+ }
374
+
375
+ const handleSocialLogin = async (provider: 'google' | 'apple' | 'facebook') => {
376
+ try {
377
+ setError(null)
378
+ setIsLoading(true)
379
+
380
+ // Initiate social login flow
381
+ await socialSignInAPI(provider)
382
+ } catch (error) {
383
+ setError(`Failed to sign in with ${provider}`)
384
+ } finally {
385
+ setIsLoading(false)
386
+ }
387
+ }
388
+
389
+ return (
390
+ <ThemeProvider theme={defaultTheme}>
391
+ <TwoPanelLayout
392
+ rightContent={
393
+ <AuthCard>
394
+ {successMessage && (
395
+ <AlertMessage message={successMessage} type="success" />
396
+ )}
397
+ {error && (
398
+ <AlertMessage message={error} type="error" />
399
+ )}
400
+ <SignInForm
401
+ onSubmit={handleSignIn}
402
+ onForgotPassword={() => navigate('/forgot-password')}
403
+ onSignUp={() => navigate('/sign-up')}
404
+ onSocialLogin={handleSocialLogin}
405
+ authProviders={['google', 'apple']} // Only show Google and Apple
406
+ isLoading={isLoading}
407
+ />
408
+ </AuthCard>
409
+ }
410
+ />
411
+ </ThemeProvider>
412
+ )
413
+ }
414
+ ```
415
+
416
+ ### Two-Factor Setup with QR Code
417
+
418
+ ```tsx
419
+ import React, { useEffect, useState } from 'react'
420
+ import { useNavigate } from 'react-router-dom'
421
+ import QRCode from 'qrcode'
422
+ import {
423
+ TwoPanelLayout,
424
+ AuthCard,
425
+ TwoFactorSetupForm,
426
+ AlertMessage
427
+ } from 'topiray-auth-react'
428
+
429
+ function TwoFactorSetupPage() {
430
+ const navigate = useNavigate()
431
+ const [qrCodeDataUrl, setQrCodeDataUrl] = useState<string | null>(null)
432
+ const [sharedKey, setSharedKey] = useState<string | null>(null)
433
+ const [error, setError] = useState<string | null>(null)
434
+ const [isLoading, setIsLoading] = useState(false)
435
+
436
+ useEffect(() => {
437
+ generateQRCode()
438
+ }, [])
439
+
440
+ const generateQRCode = async () => {
441
+ try {
442
+ setIsLoading(true)
443
+ const result = await createAuthenticatorKeyAPI()
444
+
445
+ if (result.authenticatorUri && result.sharedKey) {
446
+ const qrDataUrl = await QRCode.toDataURL(result.authenticatorUri, {
447
+ width: 200,
448
+ margin: 2
449
+ })
450
+
451
+ setQrCodeDataUrl(qrDataUrl)
452
+ setSharedKey(result.sharedKey)
453
+
454
+ // Render QR code
455
+ setTimeout(() => {
456
+ const container = document.getElementById('qr-code-container')
457
+ if (container && qrDataUrl) {
458
+ container.innerHTML = `<img src="${qrDataUrl}" alt="QR Code" />`
459
+ }
460
+ }, 100)
461
+ } else {
462
+ setError('Failed to generate QR code.')
463
+ }
464
+ } catch (error) {
465
+ setError('Failed to generate QR code.')
466
+ } finally {
467
+ setIsLoading(false)
468
+ }
469
+ }
470
+
471
+ return (
472
+ <TwoPanelLayout
473
+ rightContent={
474
+ <AuthCard>
475
+ {error && <AlertMessage message={error} type="error" />}
476
+ <TwoFactorSetupForm
477
+ onNext={() => navigate('/2fa/verify')}
478
+ onCancel={() => navigate('/dashboard')}
479
+ qrCodeUri={qrCodeDataUrl}
480
+ sharedKey={sharedKey}
481
+ isLoading={isLoading}
482
+ />
483
+ </AuthCard>
484
+ }
485
+ />
486
+ )
487
+ }
488
+ ```
489
+
490
+ ## Theming
491
+
492
+ ### Using Built-in Themes
493
+
494
+ ```tsx
495
+ import { ThemeProvider, defaultTheme, darkTheme } from 'topiray-auth-react'
496
+
497
+ // Light theme
498
+ <ThemeProvider theme={defaultTheme}>
499
+ <App />
500
+ </ThemeProvider>
501
+
502
+ // Dark theme
503
+ <ThemeProvider theme={darkTheme}>
504
+ <App />
505
+ </ThemeProvider>
506
+ ```
507
+
508
+ ### Creating Custom Themes
509
+
510
+ ```tsx
511
+ import { createCustomTheme } from 'topiray-auth-react'
512
+
513
+ const corporateTheme = createCustomTheme({
514
+ colors: {
515
+ primary: '#0066cc',
516
+ secondary: '#6b7280',
517
+ tertiary: "#f3f4f6",
518
+ background: '#ffffff',
519
+ surface: '#f9fafb',
520
+ text: '#111827',
521
+ textSecondary: '#6b7280',
522
+ border: '#d1d5db',
523
+ success: '#10b981',
524
+ warning: '#f59e0b',
525
+ error: '#ef4444',
526
+ info: '#3b82f6',
527
+ hover: '#f3f4f6',
528
+ active: '#e5e7eb',
529
+ disabled: '#9ca3af',
530
+ inputBackground: '#ffffff',
531
+ inputBorder: '#d1d5db',
532
+ inputText: '#111827',
533
+ inputPlaceholder: '#9ca3af',
534
+ buttonPrimary: '#0066cc',
535
+ buttonPrimaryText: '#ffffff',
536
+ buttonSecondary: '#6b7280',
537
+ buttonSecondaryText: '#ffffff',
538
+ buttonSocial: '#374151',
539
+ buttonSocialText: '#ffffff'
540
+ },
541
+ brand: {
542
+ logo: '/corporate-logo.png',
543
+ logoAlt: 'Corporate Logo'
544
+ },
545
+ customization: {
546
+ showFormHeader: true,
547
+ showSocialLogin: true,
548
+ showBackArrow: true,
549
+ showLogo: true,
550
+ roundedCorners: true,
551
+ animations: true
552
+ }
553
+ })
554
+
555
+ <ThemeProvider theme={corporateTheme}>
556
+ <App />
557
+ </ThemeProvider>
558
+ ```
559
+
560
+ ### Advanced Theme Customization
561
+
562
+ ```tsx
563
+ const advancedTheme = createCustomTheme({
564
+ colors: {
565
+ // Custom color palette
566
+ primary: '#7c3aed',
567
+ secondary: '#64748b',
568
+ // ... other colors
569
+ },
570
+ components: {
571
+ spacing: {
572
+ xs: '0.25rem',
573
+ sm: '0.5rem',
574
+ md: '1rem',
575
+ lg: '1.5rem',
576
+ xl: '2rem'
577
+ },
578
+ borderRadius: {
579
+ sm: '0.25rem',
580
+ md: '0.5rem',
581
+ lg: '0.75rem',
582
+ xl: '1rem'
583
+ },
584
+ typography: {
585
+ fontFamily: '"Inter", system-ui, sans-serif',
586
+ fontSize: {
587
+ xs: '0.75rem',
588
+ sm: '0.875rem',
589
+ md: '1rem',
590
+ lg: '1.125rem',
591
+ xl: '1.25rem',
592
+ xxl: '1.5rem'
593
+ }
594
+ }
595
+ },
596
+ customization: {
597
+ backgroundImage: '/custom-background.jpg',
598
+ leftPanelContent: <CustomBrandingComponent />
599
+ }
600
+ })
601
+ ```
602
+
603
+ ## CSS Custom Properties
604
+
605
+ The library uses CSS custom properties for theming. Make sure to import the CSS file first, then you can override these properties:
606
+
607
+ ```tsx
608
+ // First, import the CSS file
609
+ import 'topiray-auth-react/dist/topiray-auth-react.css'
610
+ ```
611
+
612
+ ```css
613
+ /* Then override custom properties in your CSS */
614
+ :root {
615
+ --topiray-color-primary: #your-brand-color;
616
+ --topiray-color-surface: #your-surface-color;
617
+ --topiray-font-family: 'Your Font', sans-serif;
618
+ --topiray-radius-md: 12px;
619
+ --topiray-spacing-lg: 24px;
620
+ }
621
+ ```
622
+
623
+ ## Integration Patterns
624
+
625
+ ### With React Router
626
+
627
+ ```tsx
628
+ import { BrowserRouter, Routes, Route } from 'react-router-dom'
629
+
630
+ // Import the CSS file once at the app level
631
+ import 'topiray-auth-react/dist/topiray-auth-react.css'
632
+
633
+ function App() {
634
+ return (
635
+ <ThemeProvider theme={defaultTheme}>
636
+ <BrowserRouter>
637
+ <Routes>
638
+ <Route path="/signin" element={<SignInPage />} />
639
+ <Route path="/signup" element={<SignUpPage />} />
640
+ <Route path="/forgot-password" element={<ForgotPasswordPage />} />
641
+ <Route path="/verify-email" element={<VerifyEmailPage />} />
642
+ <Route path="/2fa/setup" element={<TwoFactorSetupPage />} />
643
+ <Route path="/2fa/verify" element={<TwoFactorVerifyPage />} />
644
+ <Route path="/2fa/complete" element={<TwoFactorCompletePage />} />
645
+ </Routes>
646
+ </BrowserRouter>
647
+ </ThemeProvider>
648
+ )
649
+ }
650
+ ```
651
+
652
+ ### With State Management
653
+
654
+ ```tsx
655
+ // Using React Context
656
+ const AuthContext = createContext()
657
+
658
+ function AuthProvider({ children }) {
659
+ const [user, setUser] = useState(null)
660
+ const [isLoading, setIsLoading] = useState(false)
661
+
662
+ const login = async (email, password) => {
663
+ setIsLoading(true)
664
+ try {
665
+ const result = await signInAPI(email, password)
666
+ setUser(result.user)
667
+ return result
668
+ } finally {
669
+ setIsLoading(false)
670
+ }
671
+ }
672
+
673
+ return (
674
+ <AuthContext.Provider value={{ user, isLoading, login }}>
675
+ {children}
676
+ </AuthContext.Provider>
677
+ )
678
+ }
679
+ ```
680
+
681
+ ### With Form Validation
682
+
683
+ ```tsx
684
+ import { z } from 'zod'
685
+
686
+ const signInSchema = z.object({
687
+ email: z.string().email('Invalid email address'),
688
+ password: z.string().min(8, 'Password must be at least 8 characters')
689
+ })
690
+
691
+ function SignInPage() {
692
+ const [errors, setErrors] = useState({})
693
+
694
+ const handleSignIn = (email, password) => {
695
+ try {
696
+ signInSchema.parse({ email, password })
697
+ setErrors({})
698
+ // Proceed with sign in
699
+ } catch (error) {
700
+ setErrors(error.flatten().fieldErrors)
701
+ }
702
+ }
703
+
704
+ return (
705
+ <SignInForm
706
+ onSubmit={handleSignIn}
707
+ authProviders={['google', 'apple']}
708
+ // Pass validation errors to form
709
+ />
710
+ )
711
+ }
712
+ ```
713
+
714
+ ## TypeScript Support
715
+
716
+ Full TypeScript support with comprehensive type definitions:
717
+
718
+ ```tsx
719
+ import type {
720
+ ThemeConfig,
721
+ SignInFormProps,
722
+ AuthCardProps
723
+ } from 'topiray-auth-react'
724
+
725
+ // Custom theme with full type safety
726
+ const myTheme: ThemeConfig = {
727
+ colors: {
728
+ primary: '#0066cc',
729
+ // ... TypeScript will validate all required properties
730
+ },
731
+ // ... rest of theme configuration
732
+ }
733
+
734
+ // Component props are fully typed
735
+ const handleSignIn: SignInFormProps['onSubmit'] = (email, password) => {
736
+ // email and password are properly typed as strings
737
+ }
738
+
739
+ // Social login providers are strictly typed
740
+ const handleSocialLogin = (provider: 'google' | 'apple' | 'facebook') => {
741
+ // provider parameter is type-safe
742
+ }
743
+ ```
744
+
745
+ ## Accessibility Features
746
+
747
+ - **Keyboard Navigation**: Full keyboard support for all interactive elements
748
+ - **Screen Reader Support**: Proper ARIA labels and descriptions
749
+ - **Focus Management**: Logical focus flow and focus trapping in modals
750
+ - **High Contrast**: Colors meet WCAG contrast requirements
751
+ - **Reduced Motion**: Respects user's motion preferences
752
+
753
+ ## Browser Support
754
+
755
+ - Chrome 90+
756
+ - Firefox 88+
757
+ - Safari 14+
758
+ - Edge 90+
759
+
760
+ ## Contributing
761
+
762
+ 1. Fork the repository
763
+ 2. Create a feature branch
764
+ 3. Make your changes
765
+ 4. Add tests for new functionality
766
+ 5. Submit a pull request
767
+
768
+
769
+ ## Support
770
+
771
+ For questions and support:
772
+ - Create an issue on GitHub
773
+ - Check the documentation
774
+ - Review the demo application
775
+
776
+ ---
777
+
778
+ Built with ❤️ for the React community