JSPM

  • Created
  • Published
  • Downloads 43
  • Score
    100M100P100Q64346F
  • License MIT

Package Exports

  • recaptz
  • recaptz/dist/recaptz.es.js
  • recaptz/dist/recaptz.umd.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (recaptz) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

ReCAPTZ

A modern, customizable CAPTCHA component for React applications with TypeScript support. This package provides multiple CAPTCHA types, validation rules, and a beautiful UI out of the box.

Features

  • 🎨 Beautiful Design: Modern, clean UI with dark mode support and gradient effects
  • 🔒 Multiple CAPTCHA Types: Numbers, letters, mixed, or custom characters
  • 🎯 Validation Rules: Extensive validation options including custom validators
  • Accessibility: Screen reader support and keyboard navigation
  • 🌙 Dark Mode: Built-in dark mode support with automatic theme detection
  • 🎵 Audio Support: Text-to-speech for visually impaired users
  • 🔄 Refreshable: Easy CAPTCHA refresh with animation
  • Customizable: Extensive styling and validation options
  • 📱 Responsive: Works on all screen sizes
  • 🎯 Form Integration: Works with React Hook Form, Formik, and other form libraries
  • 🔍 TypeScript: Full TypeScript support with type definitions
  • 📦 Zero Dependencies: Minimal bundle size with no external dependencies
  • 🌐 Browser Support: Works in all modern browsers
  • 🔧 Easy Integration: Simple API with comprehensive documentation

Installation

npm install recaptz

React Compatibility

ReCAPTZ supports React 19.0.0+ and is fully compatible with the latest React features:

  • React 19.1.0: Full compatibility with latest React internals
  • Next.js 15.4.4: Works seamlessly with latest Next.js
  • Concurrent Features: Compatible with React's concurrent rendering
  • Strict Mode: Works correctly in React Strict Mode

Minimum Requirements:

  • React ≥ 19.0.0
  • React DOM ≥ 19.0.0

Peer Dependencies:

{
  "react": ">=19.0.0",
  "react-dom": ">=19.0.0"
}

Quick Start

import { Captcha } from "recaptz";

function App() {
  const handleValidate = (isValid: boolean) => {
    if (isValid) {
      console.log("CAPTCHA validated successfully");
    }
  };

  return <Captcha type="mixed" length={6} onValidate={handleValidate} />;
}

Localization (i18n)

You can localize all user-facing strings by passing the i18n prop to the Captcha component. Provide only the keys you want to override; all others will use English defaults.

Example: Arabic (RTL)

<Captcha
  rtl
  i18n={{
    securityCheck: "التحقق الأمني",
    listenToCaptcha: "استمع إلى كابتشا",
    refreshCaptcha: "تحديث كابتشا",
    inputPlaceholder: "أدخل الرمز أعلاه",
    pressSpaceToHearCode: "اضغط المسافة لسماع الرمز",
    enterToValidate: "إنتر: تحقق",
    escToClear: "إسك: مسح",
    verifyButton: "تحقق",
    verificationSuccessful: "تم التحقق!",
    attemptsRemaining: (n) => `المحاولات المتبقية: ${n}`,
    captchaRequired: "يرجى إدخال كابتشا",
    minLength: (min) => `الحد الأدنى ${min} أحرف`,
    maxLength: (max) => `الحد الأقصى ${max} أحرف`,
    invalidCharacters: (chars) => `أحرف غير صالحة: ${chars}`,
    customValidationFailed: "فشل التحقق المخصص",
    captchaDoesNotMatch: "كابتشا غير متطابقة",
  }}
/>

Note: The rtl prop is only needed for right-to-left languages. The package includes built-in CSS for RTL support.

Example: German (LTR)

<Captcha
  i18n={{
    securityCheck: "Sicherheitsüberprüfung",
    listenToCaptcha: "CAPTCHA anhören",
    refreshCaptcha: "CAPTCHA neu laden",
    inputPlaceholder: "Code eingeben",
    pressSpaceToHearCode: "Leertaste: Code anhören",
    enterToValidate: "Enter: Prüfen",
    escToClear: "Esc: Löschen",
    verifyButton: "Prüfen",
    verificationSuccessful: "Erfolg!",
    attemptsRemaining: (n) => `${n} Versuche übrig`,
    captchaRequired: "Bitte CAPTCHA eingeben",
    minLength: (min) => `Mindestens ${min} Zeichen`,
    maxLength: (max) => `Maximal ${max} Zeichen`,
    invalidCharacters: (chars) => `Ungültige Zeichen: ${chars}`,
    customValidationFailed: "Benutzerdefinierte Validierung fehlgeschlagen",
    captchaDoesNotMatch: "CAPTCHA stimmt nicht überein",
  }}
/>

i18n Keys

Key Type Default (English) Description
securityCheck string "Security Check" Section label
listenToCaptcha string "Listen to CAPTCHA" Audio button aria-label
refreshCaptcha string "Refresh CAPTCHA" Refresh button aria-label
inputPlaceholder string "Enter the code above" Input placeholder
pressSpaceToHearCode string "Press Space to hear the code" Keyboard shortcut hint
enterToValidate string "Enter to validate" Keyboard shortcut hint
escToClear string "Esc to clear" Keyboard shortcut hint
verifyButton string "Verify" Button text
verificationSuccessful string "Verification successful" Success message
attemptsRemaining (n: number) => string "{n} attempts remaining" Attempts left message
captchaRequired string "CAPTCHA response is required" Required error
minLength (min: number) => string "Input must be at least {min} characters long" Min length error
maxLength (max: number) => string "Input cannot be longer than {max} characters" Max length error
invalidCharacters (chars: string) => string "Invalid characters found: {chars}" Invalid chars error
customValidationFailed string "Custom validation failed" Custom validation error
captchaDoesNotMatch string "CAPTCHA does not match" Mismatch error

Examples

Basic Types

Numbers Only

<Captcha
  type="numbers"
  length={4}
  onValidate={(isValid) => console.log("Valid:", isValid)}
  validationRules={{
    required: true,
    allowedCharacters: "0123456789",
    minLength: 4,
    maxLength: 4,
  }}
/>

Letters Only

<Captcha
  type="letters"
  length={6}
  onValidate={(isValid) => console.log("Valid:", isValid)}
  validationRules={{
    required: true,
    customValidator: (value) =>
      /^[a-zA-Z]+$/.test(value) || "Only letters are allowed",
  }}
/>

Mixed Characters

<Captcha
  type="mixed"
  length={8}
  onValidate={(isValid) => console.log("Valid:", isValid)}
  validationRules={{
    required: true,
    minLength: 8,
    maxLength: 8,
  }}
/>

Advanced Features

Timed CAPTCHA

<Captcha
  type="mixed"
  length={5}
  refreshInterval={30} // Refreshes every 30 seconds
  onValidate={(isValid) => console.log("Valid:", isValid)}
  validationRules={{
    required: true,
    minLength: 5,
  }}
/>

Accessible CAPTCHA

<Captcha
  type="letters"
  length={4}
  autoFocus
  showSuccessAnimation
  onValidate={(isValid) => console.log("Valid:", isValid)}
  validationRules={{
    required: true,
  }}
/>

Dark Mode

<Captcha
  type="mixed"
  length={6}
  darkMode
  onValidate={(isValid) => console.log("Valid:", isValid)}
  validationRules={{
    required: true,
  }}
/>

Audio Mode

<Captcha
  type="mixed"
  length={6}
  enableAudio
  onValidate={(isValid) => console.log("Valid:", isValid)}
  validationRules={{
    required: true,
  }}
/>

Max Attempts

<Captcha
  type="mixed"
  length={6}
  maxAttempts={3}
  onValidate={(isValid) => console.log("Valid:", isValid)}
  validationRules={{
    required: true,
  }}
/>

Analytics / Telemetry Hooks

You can track user interactions and events for analytics or logging by using the following props:

  • onFail: Called whenever the user fails validation.
  • onRefresh: Called whenever the CAPTCHA is refreshed.
  • onAudioPlay: Called whenever the audio is played.

Example

<Captcha
  onFail={() => console.log("CAPTCHA failed")}
  onRefresh={() => console.log("CAPTCHA refreshed")}
  onAudioPlay={() => console.log("CAPTCHA audio played")}
/>

Prop Signatures

Prop Type Description
onFail () => void Called when the user fails validation
onRefresh () => void Called when the CAPTCHA is refreshed
onAudioPlay () => void Called when the audio is played

Complex Validation

<Captcha
  customCharacters="ABCDEF123456"
  length={6}
  caseSensitive={true}
  onValidate={(isValid) => console.log("Valid:", isValid)}
  validationRules={{
    required: true,
    allowedCharacters: "ABCDEF123456",
    customValidator: (value) => {
      const hasLetter = /[A-F]/.test(value);
      const hasNumber = /[1-6]/.test(value);
      const hasMinLength = value.length >= 6;
      if (!hasLetter) return "Must contain at least one letter";
      if (!hasNumber) return "Must contain at least one number";
      if (!hasMinLength) return "Must be 6 characters long";
      return true;
    },
  }}
/>

Styling

Custom Classes and Styles

<Captcha
  className="my-custom-class"
  customStyles={{
    backgroundColor: "#f8f9fa",
    borderRadius: "8px",
    padding: "20px",
  }}
  darkMode={true}
/>

Form Integration

React Hook Form

import { useForm } from "react-hook-form";
import { Captcha } from "recaptz";

function LoginForm() {
  const { handleSubmit, setError, clearErrors } = useForm();
  const [isCaptchaValid, setIsCaptchaValid] = useState(false);

  const onSubmit = (data) => {
    if (!isCaptchaValid) {
      setError("captcha", {
        type: "manual",
        message: "Please complete the CAPTCHA",
      });
      return;
    }
    // Handle form submission
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* Form fields */}
      <Captcha
        type="mixed"
        length={6}
        onValidate={(isValid) => {
          setIsCaptchaValid(isValid);
          if (isValid) clearErrors("captcha");
        }}
      />
      <button type="submit">Submit</button>
    </form>
  );
}

Formik

import { Formik, Form } from "formik";
import { Captcha } from "recaptz";

function LoginForm() {
  return (
    <Formik
      initialValues={{ captchaValid: false }}
      onSubmit={(values) => {
        if (values.captchaValid) {
          // Handle form submission
        }
      }}
    >
      {({ setFieldValue }) => (
        <Form>
          {/* Form fields */}
          <Captcha
            type="mixed"
            length={6}
            onValidate={(isValid) => {
              setFieldValue("captchaValid", isValid);
            }}
          />
          <button type="submit">Submit</button>
        </Form>
      )}
    </Formik>
  );
}

Props

Prop Type Default Description
type 'numbers' | 'letters' | 'mixed' 'mixed' Type of CAPTCHA to generate
length number 6 Length of CAPTCHA text
onChange (value: string) => void - Callback when input changes
onValidate (isValid: boolean) => void - Callback when validation occurs
className string '' Additional CSS classes
refreshable boolean true Whether CAPTCHA can be refreshed
caseSensitive boolean false Case-sensitive validation
customCharacters string - Custom character set
customStyles React.CSSProperties - Custom inline styles
validationRules ValidationRules - Custom validation rules
darkMode boolean false Enable dark mode
autoFocus boolean false Auto-focus the input field
showSuccessAnimation boolean false Show success animation
refreshInterval number - Auto-refresh interval in seconds
maxAttempts number - Maximum validation attempts
inputButtonStyle string - Custom class for input button styles
enableAudio boolean - Enable or disable audio support
rtl boolean false Enable right-to-left layout for RTL languages

Validation Rules

interface ValidationRules {
  minLength?: number;
  maxLength?: number;
  allowedCharacters?: string;
  required?: boolean;
  caseSensitive?: boolean;
  customValidator?: (value: string) => boolean | string;
}

Keyboard Shortcuts

  • Space: Hear the CAPTCHA code
  • Enter: Validate the input
  • Escape: Clear the input

Accessibility Features

  • Screen reader support with ARIA labels
  • Keyboard navigation
  • High contrast mode support
  • Audio feedback
  • Focus management
  • Clear error messages
  • Responsive design

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)
  • Opera (latest)

Contributing

We welcome contributions! Please feel free to submit a Pull Request.

License

MIT © Shejan Mahamud