Code Monkey home page Code Monkey logo

rn-credit-card's Introduction

React Native Credit Card

This is a fully functional and animated credit card form library, and it's ready to use 🚀

horizontal demo


Features

  • Works on iOS and Android.
  • Validations.
  • Card icon animation with Lottie.
  • Card flip animation with react-native-card-flip.
  • Possible to access all react-hook-form methods.
  • TypeScript code base.
  • Works on Expo.

Blog Post

This repository also contains my initial work of building a simple react native form with react-hook-form without any fancy animations. You may read it on my blog: React Native Form Management Tutorial.

Installation

Install the library first:

npm install rn-credit-card
// OR
yarn add rn-credit-card

Install react-hook-form:

npm install react-hook-form
// OR
yarn add react-hook-form

Note: The latest version of this project works with react-hook-form version >7.0.0. Stick with the version 0.2.0 if you'd like to use it with react-hook-form: <7.0.0:

npm install [email protected]

You also need to install lottie-react-native if you want to display card icon animations. Please note that this is optional, and the library will display simple card icons if Lottie is not present:

npm install lottie-react-native
// OR
yarn add lottie-react-native

If you'd like to use the library on Android, make sure you're using a lottie-react-native version greater than 3.0.0. The animations are not working on 2.x.x versions.

Additional steps might be needed depending on your platform. Please check lottie-react-native documentation.

Configuring Fonts

The library uses Roboto Mono font by default. If you'd like to keep it that way, you need to import RobotoMono_400Regular and RobotoMono_700Bold fonts to your project. Please see Expo or this dev.to post for more information.

You may also use custom fonts with this library. Please see #fonts section.

Usage

You need to create a react-hook-form and pass it down to the CreditCardForm through FormProvider context. This structure helps you accessing every propery and method of the form so you can build some features on top of the library.

The library is written in TypeScript, and types are also available out of the box. You may use FormModel to type your form.

Here is a fully functional example with KeyboardAvodingView, which manages the scroll position when keyboard is open.

import React from 'react'
import { FormProvider, useForm } from 'react-hook-form'
import {
  Alert,
  StyleSheet,
  KeyboardAvoidingView,
  Platform,
  SafeAreaView,
} from 'react-native'
import LottieView from 'lottie-react-native'
import CreditCardForm, { Button, FormModel } from 'rn-credit-card'

const App: React.FC = () => {
  const formMethods = useForm<FormModel>({
    // to trigger the validation on the blur event
    mode: 'onBlur',
    defaultValues: {
      holderName: '',
      cardNumber: '',
      expiration: '',
      cvv: '',
    },
  })
  const { handleSubmit, formState } = formMethods

  function onSubmit(model: FormModel) {
    Alert.alert('Success: ' + JSON.stringify(model, null, 2))
  }

  return (
    <FormProvider {...formMethods}>
      <SafeAreaView style={styles.container}>
        <KeyboardAvoidingView
          style={styles.avoider}
          behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
        >
          <CreditCardForm
            LottieView={LottieView}
            horizontalStart
            overrides={{
              labelText: {
                marginTop: 16,
              },
            }}
          />
        </KeyboardAvoidingView>
        {formState.isValid && (
          <Button
            style={styles.button}
            title={'CONFIRM PAYMENT'}
            onPress={handleSubmit(onSubmit)}
          />
        )}
      </SafeAreaView>
    </FormProvider>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  avoider: {
    flex: 1,
    padding: 36,
  },
  button: {
    margin: 36,
    marginTop: 0,
  },
})

export default App

If you are not using TypeScipt on your project, simply remove FormModel references from the example above.

Available Props

LottieView

This prop takes the default exported value of lottie-react-native library. This is optional because Lottie might require additional configuration steps. The library will display simple png card icons if this prop is not provided.

Please remember you need a lottie-react-native version greater than 3.x.x to make it work on Android.

type default required platform
any undefined NO iOS/Android

Example:

import LottieView from 'lottie-react-native'
;<CreditCardForm LottieView={LottieView} />

horizontalStart

This makes the form start with a horizontal scroll. This is the default behaviour.

This feature is not working on Android due to a weird problem happening when the ScrollView is switched from horizontal.

type default required platform
boolean true NO iOS only

This is the outcome when horizontalStart is false:

vertical

formOnly

When true, it hides the card view and displays the credit card form only.

type default required platform
boolean false NO iOS/Android

backgroundImage

You may use this prop to replace the background image of the card preview.

type default required platform
React.ReactNode undefined NO iOS/Android

Example:

<CreditCardForm
  backgroundImage={
    <Image
      style={{
        position: 'absolute',
        width: '100%',
        height: '100%',
        borderRadius: 12,
      }}
      source={background}
    />
  }
/>

fonts

fonts props take an object with two fields:

field type default required
fonts.regular string RobotoMono_400Regular NO
fonts.bold string RobotoMono_700Bold NO

Please note that you should use a Monospaced font for the best user experience. The fixed width helps maintaining the same card number width while the user types.

Example:

<CreditCardForm
  fonts={{
    regular: 'RobotoMono_400Regular',
    bold: 'RobotoMono_700Bold',
  }}
/>

inputColors

You may modify the TextInput colors using this. It's an object with three optional fields:

field type default required
focused string #080F9C NO
errored string #B00020 NO
regular string #B9C4CA NO

Example:

<CreditCardForm
  inputColors={{
    focused: '#080F9C',
    errored: '#B00020',
    regular: '#B9C4CA',
  }}
/>

translations

An optional object that takes a string for each displayed text on the library. You may use it to modify any or all of those displayed texts.

type default required platform
Translations undefined NO iOS/Android

Example:

<CreditCardForm
  // those are the default values
  translations={{
    cardNumber: 'Card Number',
    cardHolderName: 'Cardholder Name',
    nameSurname: 'Name Surname',
    mmYY: 'MM/YY',
    expiration: 'Expiration',
    securityCode: 'Security Code',
    next: 'Next',
    done: 'Done',
    cardNumberRequired: 'Card number is required.',
    cardNumberInvalid: 'This card number looks invalid.',
    cardHolderNameRequired: 'Cardholder name is required.',
    cardHolderNameInvalid: 'This cardholder name looks invalid.',
    expirationRequired: 'Expiration date is required.',
    expirationInvalid: 'This expiration date looks invalid.',
    securityCodeRequired: 'Security code is required.',
    securityCodeInvalid: 'This security date looks invalid.',
  }}
/>

overrides

This props might be used to override some component styles within the library. All fields are optional.

field type
cardPreview ViewStyle or TextStyle
labelText TextStyle
cardHolderPreview TextStyle
expirationPreview ViewStyle or TextStyle
outline ViewStyle
input ViewStyle
labelContainer ViewStyle
inputLabel TextStyle
errorText TextStyle

requiresName

An optional prop that allows you to hide the cardholder Name from both the form and the card view. When false, it hides the CardHolder Name field.

type default required platform
boolean true NO iOS/Android

Example

<CreditCardForm
  LottieView={LottieView}
  horizontalStart
  requiresName={false}
/>

Credits

Licence

MIT

rn-credit-card's People

Contributors

halilb avatar placideirandora avatar tons613 avatar victorjordan95 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rn-credit-card's Issues

Include new fields

Very cool

It would be nice if you could include other necessary fields (identity of the cardholder and birthday)

undefined is not an object (evaluating 'errors[name])

I'm trying to use your example on .js
I removed references to FormModel, and I get this error TypeError: undefined is not an object (evaluating 'errors[name]')

Here is my code after removing FormModel

import { FormProvider, useForm } from 'react-hook-form'
import {
    Alert,
    StyleSheet,
    KeyboardAvoidingView,
    Platform,
    SafeAreaView,
} from 'react-native'
import LottieView from 'lottie-react-native'
import CreditCardForm, { Button, FormModel } from 'rn-credit-card'

const App = () => {
    const formMethods = useForm ({
        // to trigger the validation on the blur event
        mode: 'onBlur',
        defaultValues: {
            holderName: '',
            cardNumber: '',
            expiration: '',
            cvv: '',
        },
    })
    const { handleSubmit, formState } = formMethods

    function onSubmit(model) {
        Alert.alert('Success: ' + JSON.stringify(model, null, 2))
    }

    return (
        <FormProvider {...formMethods}>
            <SafeAreaView style={styles.container}>
                <KeyboardAvoidingView
                    style={styles.avoider}
                    behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
                >
                    <CreditCardForm
                        LottieView={LottieView}
                        horizontalStart
                        overrides={{
                            labelText: {
                                marginTop: 16,
                            },
                        }}
                    />
                </KeyboardAvoidingView>
                {formState.isValid && (
                    <Button
                        style={styles.button}
                        title={'CONFIRM PAYMENT'}
                        onPress={handleSubmit(onSubmit)}
                    />
                )}
            </SafeAreaView>
        </FormProvider>
    )
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    avoider: {
        flex: 1,
        padding: 36,
    },
    button: {
        margin: 36,
        marginTop: 0,
    },
})

export default App

Show all Input Fields together

Hi,
This is a lovely repo. Thanks for this!
My project requires me to show all the input fields together (instead of one sliding in after the other) . Is that possible ( Im sure it is, just cant figure out how!) ?

Thanks!

Translation for the cardHolderNameRequired not working as expected

I would like to thank you for working on this productive library!

I have faced an issue while using it though that I would like you to look into and give it a fix:

CURRENT BEHAVIOR
I have the following translation object passed to the credit card form component:

<CreditCardForm
          LottieView={LottieView}
          horizontalStart
          overrides={{
            labelText: {
              marginTop: 16
            }
          }}
          translations={{
            cardNumber: 'Numéro de Carte',
            cardHolderName: 'Titulaire de Carte',
            nameSurname: 'Nom et Prénom',
            mmYY: 'MM/AA',
            expiration: 'Expiration',
            securityCode: 'Code de Sécurité',
            next: 'Suivant',
            done: 'Terminer',
            cardNumberRequired: 'Numéro de Carte est obligatoire.',
            cardNumberInvalid: 'Ce numéro de carte est invalide.',
            cardHolderNameRequired: 'Nom de titulaire de la carte est obligatoire.',
            cardHolderNameInvalid: 'Ce nom de titulaire de la carte est invalide.',
            expirationRequired: "Date d'Expiration est obligatoire",
            expirationInvalid: "Cette date d'expiration est invalide.",


            securityCodeRequired: 'Code de Sécurité est obligatoire.',
            securityCodeInvalid: 'Ce code de Sécurité est invalide.'
          }}
        />

Every field gets translated as expected except the cardHolderNameRequired which displays the cardNumberRequired instead of its own value.

So, I attempt to skip the card number, they tell me that the card number is required. And I provide it, but when I reach the cardholder's name and attempt the skip, they tell me that the cardholder number is required instead of telling me that the cardholder's name is required. That affects the user experience because it confuses the user.

EXPECTED BEHAVIOR
The right corresponding validation message of the cardholder's name should be displayed instead of the incorrect one.

Unable to resolve AccessibilityInfo

Unable to resolve "AccessibilityInfo" from "node_modules\rn-credit-card\node_modules\react-native\Libraries\react-native\react-native-implementation.js"

Prop "requiresName" not working

Hello,

I noticed in the documentation that there should be a prop "requiresName" to exclude the card holder name input, but setting it to false doesn't seem to make any difference. The card holder name is always displayed...

Example:
<CreditCardForm LottieView={LottieView} horizontalStart requiresName={false} />

Screenshot 2023-12-12 at 11 46 37

Also typescript complains that the property "requiresName" does not exist on CreditCardForm:
Screenshot 2023-12-12 at 11 30 36

Any fix or workaround to make this work as expected?

Kind regards,
Tim

Card Number Limit

Please how do I extend the card number limit from 16 to say 19 ? I have a verve card of 19 digits and I was surprised I could not use it on the package.

Thank you for your help.

Back button

Hi, thank for good work.

I want to create back button like next button on the card form. Because some times we need to go back for edit.

formOnly not working

Hey I tried to set the formOnly prop however the editor says it doesn't exist. Where should I add it to activate it?
Captura de ecrã 2021-10-07, às 18 18 11
Captura de ecrã 2021-10-07, às 18 18 13

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.