npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

topiray-auth-react

v1.0.5

Published

A customizable React authentication component library

Readme

Topiray Auth React Component Library

NPM Version NPM Downloads NPM License

A comprehensive, themeable React component library for authentication flows. Built with TypeScript, CSS Modules, and designed for maximum customization and accessibility.

Features

  • 🎨 Fully Themeable - Customize colors, fonts, spacing, and more
  • 🔧 CSS Modules - Strongly-typed, scoped styling
  • 📱 Responsive Design - Mobile-first approach with breakpoint support
  • Accessible - ARIA labels, keyboard navigation, focus management
  • 🔐 Complete Auth Flow - Sign in/up, 2FA, email verification, password reset
  • TypeScript - Full type safety and IntelliSense support
  • 🎯 Tree Shakeable - Import only what you need

Installation

npm install topiray-auth-react
# or
yarn add topiray-auth-react

Peer Dependencies

npm install react react-dom lucide-react @mui/material

CSS Import

Important: You must import the CSS file for proper styling:

// Import the CSS file in your main App component or index file
import 'topiray-auth-react/dist/topiray-auth-react.css'

Or if you're using a bundler that supports CSS imports:

/* In your main CSS file */
@import 'topiray-auth-react/dist/topiray-auth-react.css';

Quick Start

import React from 'react'
import { 
  ThemeProvider, 
  defaultTheme, 
  TwoPanelLayout, 
  AuthCard, 
  SignInForm 
} from 'topiray-auth-react'

// Import the CSS file
import 'topiray-auth-react/dist/topiray-auth-react.css'

function App() {
  const handleSignIn = (email: string, password: string) => {
    console.log('Sign in:', { email, password })
  }

  return (
    <ThemeProvider theme={defaultTheme}>
      <TwoPanelLayout
        rightContent={
          <AuthCard>
            <SignInForm
              onSubmit={handleSignIn}
              onForgotPassword={() => console.log('Forgot password')}
              onSignUp={() => console.log('Sign up')}
              onSocialLogin={(provider) => console.log('Social:', provider)}
              authProviders={['google', 'apple', 'facebook']}
            />
          </AuthCard>
        }
      />
    </ThemeProvider>
  )
}

Components

Auth Components

AuthCard

Container wrapper for auth forms with consistent styling.

import { AuthCard } from 'topiray-auth-react'

<AuthCard>
  {/* Your auth form content */}
</AuthCard>

SignInForm

Complete sign-in form with email/password and customizable social login options.

import { SignInForm } from 'topiray-auth-react'

<SignInForm
  onSubmit={(email, password) => handleSignIn(email, password)}
  onForgotPassword={() => navigate('/forgot-password')}
  onSignUp={() => navigate('/sign-up')}
  onSocialLogin={(provider) => handleSocialLogin(provider)}
  authProviders={['google', 'apple', 'facebook']}
  isLoading={isSigningIn}
  logoSrc="/your-logo.png"
/>

SignUpForm

Account creation form with business/individual selection and customizable social login.

import { SignUpForm } from 'topiray-auth-react'

<SignUpForm
  onSubmit={(email, password, accountType) => handleSignUp(email, password, accountType)}
  onSignIn={() => navigate('/sign-in')}
  onSocialLogin={(provider) => handleSocialLogin(provider)}
  authProviders={['google', 'apple', 'facebook']}
  isLoading={isSigningUp}
  logoSrc="/your-logo.png"
/>

ForgottenPasswordForm

Password reset request form.

import { ForgottenPasswordForm } from 'topiray-auth-react'

<ForgottenPasswordForm
  onSubmit={(email) => handlePasswordReset(email)}
  isLoading={isLoading}
/>

VerifyEmailForm

Email verification flow with resend functionality.

import { VerifyEmailForm } from 'topiray-auth-react'

<VerifyEmailForm
  onSubmit={() => navigate('/sign-in')}
  onResendEmail={() => handleResendEmail()}
  email="[email protected]"
  isLoading={isLoading}
/>

Two-Factor Authentication

TwoFactorSetupForm

QR code setup for authenticator apps.

import { TwoFactorSetupForm } from 'topiray-auth-react'

<TwoFactorSetupForm
  onNext={() => navigate('/2fa/verify')}
  onCancel={() => navigate('/dashboard')}
  qrCodeUri="otpauth://totp/App:[email protected]?secret=SECRET&issuer=App"
  sharedKey="JBSWY3DPEHPK3PXP"
  isLoading={isLoading}
/>

TwoFactorSetupEnterVerificationForm

6-digit code entry with auto-focus and paste support.

import { TwoFactorSetupEnterVerificationForm } from 'topiray-auth-react'

<TwoFactorSetupEnterVerificationForm
  onVerify={(code) => handleVerification(code)}
  isLoading={isVerifying}
  error={error}
  backRoute="/2fa/setup"
/>

TwoFactorSetupCompleteForm

Backup codes display with copy/download functionality.

import { TwoFactorSetupCompleteForm } from 'topiray-auth-react'

<TwoFactorSetupCompleteForm
  onDone={() => navigate('/dashboard')}
  backupCodes={recoveryCodes}
  isLoading={isLoading}
/>

Layout Components

TwoPanelLayout

Responsive layout with left branding panel and right content area.

import { TwoPanelLayout } from 'topiray-auth-react'

<TwoPanelLayout
  leftContent={<YourBrandingContent />}
  rightContent={<YourAuthForm />}
  leftBackgroundImage="/background.jpg"
  logoSrc="/logo.png"
/>

NavLinksLayout

Flexible content layout for pages with navigation.

import { NavLinksLayout } from 'topiray-auth-react'

<NavLinksLayout
  middle={<MainContent />}
  right={<SidebarContent />}
/>

Common Components

Button

Versatile button with loading states and variants.

import { Button } from 'topiray-auth-react'

<Button variant="primary" isLoading={isLoading} fullWidth>
  Sign In
</Button>

<Button variant="secondary" icon="google">
  Sign in with Google
</Button>

AlertMessage

Dismissible alert messages for different states.

import { AlertMessage } from 'topiray-auth-react'

<AlertMessage 
  type="error" 
  message="Invalid credentials" 
  dismissible
  onDismiss={() => setError(null)}
/>

SocialLoginButtons

Pre-configured social login buttons.

import { SocialLoginButtons } from 'topiray-auth-react'

<SocialLoginButtons
  onSocialLogin={(provider) => handleSocialLogin(provider)}
  providers={['google', 'apple', 'facebook']}
  orientation="vertical"
  isLoading={isLoading}
/>

Customizing Social Login Providers

You can customize which social login providers are displayed using the authProviders prop on both SignInForm and SignUpForm:

// Show only Google and Apple
<SignInForm
  authProviders={['google', 'apple']}
  onSocialLogin={(provider) => handleSocialLogin(provider)}
  // ... other props
/>

// Show all available providers (default)
<SignUpForm
  authProviders={['apple', 'google', 'facebook']}
  onSocialLogin={(provider) => handleSocialLogin(provider)}
  // ... other props
/>

// Show only Google
<SignInForm
  authProviders={['google']}
  onSocialLogin={(provider) => handleSocialLogin(provider)}
  // ... other props
/>

// Hide social login entirely by setting empty array or omitting the prop
<SignInForm
  authProviders={[]}
  // ... other props (onSocialLogin not needed if no providers)
/>

Available providers:

  • 'apple' - Apple Sign In
  • 'google' - Google Sign In
  • 'facebook' - Facebook Login

Default behavior: If authProviders is not specified, it defaults to ['apple', 'google', 'facebook'].

Real-World Usage Examples

Complete Sign-In Page

import React, { useState, useEffect } from 'react'
import { useNavigate, useLocation } from 'react-router-dom'
import {
  ThemeProvider,
  defaultTheme,
  TwoPanelLayout,
  AuthCard,
  SignInForm,
  AlertMessage
} from 'topiray-auth-react'

// Import the CSS file
import 'topiray-auth-react/dist/topiray-auth-react.css'

function SignInPage() {
  const navigate = useNavigate()
  const location = useLocation()
  const [error, setError] = useState<string | null>(null)
  const [isLoading, setIsLoading] = useState(false)

  // Get success message from registration
  const successMessage = location.state?.message

  const handleSignIn = async (email: string, password: string) => {
    try {
      setError(null)
      setIsLoading(true)
      
      const result = await signInAPI(email, password)
      
      if (result.succeeded) {
        navigate('/dashboard')
      } else if (result.requiresTwoFactor) {
        navigate('/2fa/signin', { state: { userId: result.userId } })
      } else if (result.isNotAllowed) {
        navigate(`/verify-email?email=${encodeURIComponent(email)}`)
      } else {
        setError('Invalid email or password.')
      }
    } catch (error) {
      setError('An error occurred during sign in.')
    } finally {
      setIsLoading(false)
    }
  }

  const handleSocialLogin = async (provider: 'google' | 'apple' | 'facebook') => {
    try {
      setError(null)
      setIsLoading(true)
      
      // Initiate social login flow
      await socialSignInAPI(provider)
    } catch (error) {
      setError(`Failed to sign in with ${provider}`)
    } finally {
      setIsLoading(false)
    }
  }

  return (
    <ThemeProvider theme={defaultTheme}>
      <TwoPanelLayout
        rightContent={
          <AuthCard>
            {successMessage && (
              <AlertMessage message={successMessage} type="success" />
            )}
            {error && (
              <AlertMessage message={error} type="error" />
            )}
            <SignInForm
              onSubmit={handleSignIn}
              onForgotPassword={() => navigate('/forgot-password')}
              onSignUp={() => navigate('/sign-up')}
              onSocialLogin={handleSocialLogin}
              authProviders={['google', 'apple']} // Only show Google and Apple
              isLoading={isLoading}
            />
          </AuthCard>
        }
      />
    </ThemeProvider>
  )
}

Two-Factor Setup with QR Code

import React, { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import QRCode from 'qrcode'
import {
  TwoPanelLayout,
  AuthCard,
  TwoFactorSetupForm,
  AlertMessage
} from 'topiray-auth-react'

function TwoFactorSetupPage() {
  const navigate = useNavigate()
  const [qrCodeDataUrl, setQrCodeDataUrl] = useState<string | null>(null)
  const [sharedKey, setSharedKey] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [isLoading, setIsLoading] = useState(false)

  useEffect(() => {
    generateQRCode()
  }, [])

  const generateQRCode = async () => {
    try {
      setIsLoading(true)
      const result = await createAuthenticatorKeyAPI()
      
      if (result.authenticatorUri && result.sharedKey) {
        const qrDataUrl = await QRCode.toDataURL(result.authenticatorUri, {
          width: 200,
          margin: 2
        })
        
        setQrCodeDataUrl(qrDataUrl)
        setSharedKey(result.sharedKey)
        
        // Render QR code
        setTimeout(() => {
          const container = document.getElementById('qr-code-container')
          if (container && qrDataUrl) {
            container.innerHTML = `<img src="${qrDataUrl}" alt="QR Code" />`
          }
        }, 100)
      } else {
        setError('Failed to generate QR code.')
      }
    } catch (error) {
      setError('Failed to generate QR code.')
    } finally {
      setIsLoading(false)
    }
  }

  return (
    <TwoPanelLayout
      rightContent={
        <AuthCard>
          {error && <AlertMessage message={error} type="error" />}
          <TwoFactorSetupForm
            onNext={() => navigate('/2fa/verify')}
            onCancel={() => navigate('/dashboard')}
            qrCodeUri={qrCodeDataUrl}
            sharedKey={sharedKey}
            isLoading={isLoading}
          />
        </AuthCard>
      }
    />
  )
}

Theming

Using Built-in Themes

import { ThemeProvider, defaultTheme, darkTheme } from 'topiray-auth-react'

// Light theme
<ThemeProvider theme={defaultTheme}>
  <App />
</ThemeProvider>

// Dark theme
<ThemeProvider theme={darkTheme}>
  <App />
</ThemeProvider>

Creating Custom Themes

import { createCustomTheme } from 'topiray-auth-react'

const corporateTheme = createCustomTheme({
  colors: {
    primary: '#0066cc',
    secondary: '#6b7280',
    tertiary: "#f3f4f6",
    background: '#ffffff',
    surface: '#f9fafb',
    text: '#111827',
    textSecondary: '#6b7280',
    border: '#d1d5db',
    success: '#10b981',
    warning: '#f59e0b',
    error: '#ef4444',
    info: '#3b82f6',
    hover: '#f3f4f6',
    active: '#e5e7eb',
    disabled: '#9ca3af',
    inputBackground: '#ffffff',
    inputBorder: '#d1d5db',
    inputText: '#111827',
    inputPlaceholder: '#9ca3af',
    buttonPrimary: '#0066cc',
    buttonPrimaryText: '#ffffff',
    buttonSecondary: '#6b7280',
    buttonSecondaryText: '#ffffff',
    buttonSocial: '#374151',
    buttonSocialText: '#ffffff'
  },
  brand: {
    logo: '/corporate-logo.png',
    logoAlt: 'Corporate Logo'
  },
  customization: {
    showFormHeader: true,
    showSocialLogin: true,
    showBackArrow: true,
    showLogo: true,
    roundedCorners: true,
    animations: true
  }
})

<ThemeProvider theme={corporateTheme}>
  <App />
</ThemeProvider>

Advanced Theme Customization

const advancedTheme = createCustomTheme({
  colors: {
    // Custom color palette
    primary: '#7c3aed',
    secondary: '#64748b',
    // ... other colors
  },
  components: {
    spacing: {
      xs: '0.25rem',
      sm: '0.5rem',
      md: '1rem',
      lg: '1.5rem',
      xl: '2rem'
    },
    borderRadius: {
      sm: '0.25rem',
      md: '0.5rem',
      lg: '0.75rem',
      xl: '1rem'
    },
    typography: {
      fontFamily: '"Inter", system-ui, sans-serif',
      fontSize: {
        xs: '0.75rem',
        sm: '0.875rem',
        md: '1rem',
        lg: '1.125rem',
        xl: '1.25rem',
        xxl: '1.5rem'
      }
    }
  },
  customization: {
    backgroundImage: '/custom-background.jpg',
    leftPanelContent: <CustomBrandingComponent />
  }
})

CSS Custom Properties

The library uses CSS custom properties for theming. Make sure to import the CSS file first, then you can override these properties:

// First, import the CSS file
import 'topiray-auth-react/dist/topiray-auth-react.css'
/* Then override custom properties in your CSS */
:root {
  --topiray-color-primary: #your-brand-color;
  --topiray-color-surface: #your-surface-color;
  --topiray-font-family: 'Your Font', sans-serif;
  --topiray-radius-md: 12px;
  --topiray-spacing-lg: 24px;
}

Integration Patterns

With React Router

import { BrowserRouter, Routes, Route } from 'react-router-dom'

// Import the CSS file once at the app level
import 'topiray-auth-react/dist/topiray-auth-react.css'

function App() {
  return (
    <ThemeProvider theme={defaultTheme}>
      <BrowserRouter>
        <Routes>
          <Route path="/signin" element={<SignInPage />} />
          <Route path="/signup" element={<SignUpPage />} />
          <Route path="/forgot-password" element={<ForgotPasswordPage />} />
          <Route path="/verify-email" element={<VerifyEmailPage />} />
          <Route path="/2fa/setup" element={<TwoFactorSetupPage />} />
          <Route path="/2fa/verify" element={<TwoFactorVerifyPage />} />
          <Route path="/2fa/complete" element={<TwoFactorCompletePage />} />
        </Routes>
      </BrowserRouter>
    </ThemeProvider>
  )
}

With State Management

// Using React Context
const AuthContext = createContext()

function AuthProvider({ children }) {
  const [user, setUser] = useState(null)
  const [isLoading, setIsLoading] = useState(false)

  const login = async (email, password) => {
    setIsLoading(true)
    try {
      const result = await signInAPI(email, password)
      setUser(result.user)
      return result
    } finally {
      setIsLoading(false)
    }
  }

  return (
    <AuthContext.Provider value={{ user, isLoading, login }}>
      {children}
    </AuthContext.Provider>
  )
}

With Form Validation

import { z } from 'zod'

const signInSchema = z.object({
  email: z.string().email('Invalid email address'),
  password: z.string().min(8, 'Password must be at least 8 characters')
})

function SignInPage() {
  const [errors, setErrors] = useState({})

  const handleSignIn = (email, password) => {
    try {
      signInSchema.parse({ email, password })
      setErrors({})
      // Proceed with sign in
    } catch (error) {
      setErrors(error.flatten().fieldErrors)
    }
  }

  return (
    <SignInForm
      onSubmit={handleSignIn}
      authProviders={['google', 'apple']}
      // Pass validation errors to form
    />
  )
}

TypeScript Support

Full TypeScript support with comprehensive type definitions:

import type { 
  ThemeConfig, 
  SignInFormProps, 
  AuthCardProps 
} from 'topiray-auth-react'

// Custom theme with full type safety
const myTheme: ThemeConfig = {
  colors: {
    primary: '#0066cc',
    // ... TypeScript will validate all required properties
  },
  // ... rest of theme configuration
}

// Component props are fully typed
const handleSignIn: SignInFormProps['onSubmit'] = (email, password) => {
  // email and password are properly typed as strings
}

// Social login providers are strictly typed
const handleSocialLogin = (provider: 'google' | 'apple' | 'facebook') => {
  // provider parameter is type-safe
}

Accessibility Features

  • Keyboard Navigation: Full keyboard support for all interactive elements
  • Screen Reader Support: Proper ARIA labels and descriptions
  • Focus Management: Logical focus flow and focus trapping in modals
  • High Contrast: Colors meet WCAG contrast requirements
  • Reduced Motion: Respects user's motion preferences

Browser Support

  • Chrome 90+
  • Firefox 88+
  • Safari 14+
  • Edge 90+

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Submit a pull request

Support

For questions and support:

  • Create an issue on GitHub
  • Check the documentation
  • Review the demo application

Built with ❤️ for the React community