topiray-auth-react 1.0.0 → 1.0.1

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