🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

react-native-form-container

Package Overview
Dependencies
Maintainers
0
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-native-form-container - npm Package Compare versions

Comparing version
1.0.39
to
1.0.40
+168
src/components/ValidationFields.ts
export const ValidationFields = {
email: {
pattern: {
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
},
},
minPassword: {
pattern: {
value: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/,
},
},
speacialCharacter: {
pattern: {
value: /[^a-zA-Z0-9]/,
},
},
upperCaseCharacter: {
pattern: {
value: /[A-Z]/,
},
},
lowerCaseCharacter: {
pattern: {
value: /[a-z]/,
},
},
number: {
pattern: {
value: /[0-9]/,
},
},
text: {
pattern: {
value: /^[a-zA-Z]*$/,
},
},
phone: {
pattern: {
value: /^[0-9]*$/,
},
},
};
export default interface ValidationFields {
email?: boolean;
password?: boolean;
text?: boolean;
phone?: boolean;
number?: boolean;
}
export interface ValidationPasswordOptions {
minLength?: number;
speacial?: boolean;
upperCase?: boolean;
lowerCase?: boolean;
number?: boolean;
}
export type ValidationFieldsKeys = typeof ValidationFields;
export const isValidation = (
validation: ValidationFieldsKeys,
value: any,
passwordOptions?: ValidationPasswordOptions,
) => {
if (value === undefined || value === null || value === '') {
return false;
}
if (validation === 'email') {
if (!ValidationFields.email.pattern.value.test(value)) {
return false;
}
}
if (validation === 'password') {
if (passwordOptions?.lowerCase) {
if (!ValidationFields.lowerCaseCharacter.pattern.value.test(value)) {
return false;
}
}
if (passwordOptions?.upperCase) {
if (!ValidationFields.upperCaseCharacter.pattern.value.test(value)) {
return false;
}
}
if (passwordOptions?.number) {
if (!ValidationFields.number.pattern.value.test(value)) {
return false;
}
}
if (passwordOptions?.speacial) {
if (!ValidationFields.speacialCharacter.pattern.value.test(value)) {
return false;
}
}
if (passwordOptions?.minLength) {
return value.length >= passwordOptions.minLength;
}
}
if (validation === 'text') {
if (!ValidationFields.text.pattern.value.test(value)) {
return false;
}
}
if (validation === 'phone') {
if (!ValidationFields.phone.pattern.value.test(value)) {
return false;
}
}
if (validation === 'number') {
if (!ValidationFields.number.pattern.value.test(value)) {
return false;
}
}
return true;
};
export const checkPasswordOptions = (
options: ValidationPasswordOptions,
value: string,
inputId: string,
): {
password?: boolean;
lowerCase?: boolean;
upperCase?: boolean;
number?: boolean;
speacial?: boolean;
minLength?: boolean;
} => {
let result = {};
if (value === undefined || value.length === 0) {
result = {
[inputId]: true,
};
}
if (options?.lowerCase) {
if (ValidationFields.lowerCaseCharacter.pattern.value.test(value)) {
result = {
lowerCase: true,
};
}
}
if (options?.upperCase) {
if (ValidationFields.upperCaseCharacter.pattern.value.test(value)) {
result = {
upperCase: true,
};
}
}
if (options?.number) {
if (ValidationFields.number.pattern.value.test(value)) {
result = {
number: true,
};
}
}
if (options?.speacial) {
if (ValidationFields.speacialCharacter.pattern.value.test(value)) {
result = {
speacial: true,
};
}
}
if (options?.minLength) {
if (ValidationFields.minPassword.pattern.value.test(value)) {
result = {
minLength: true,
};
}
}
return result;
};
+20
-8

@@ -1,4 +0,4 @@

declare module "react-native-form-container" {
import { MutableRefObject, ReactNode } from "react";
import { ViewProps, TextInputProps } from "react-native";
declare module 'react-native-form-container' {
import {MutableRefObject, ReactNode} from 'react';
import {ViewProps, TextInputProps} from 'react-native';

@@ -9,2 +9,3 @@ export interface FormContainerProps extends ViewProps {

formContainerRef?: MutableRefObject<FormContainerRef | null>;
errorMessageField?: string;
}

@@ -19,7 +20,6 @@

export interface FormInputProps extends TextInputProps {
id: string;
iconPosition?: "left" | "right";
interface InputProps extends TextInputProps {
iconPosition?: 'left' | 'right';
icon?: any;
inputSize?: "sm" | "md";
inputSize?: 'sm' | 'md';
enableFocusBorder?: boolean;

@@ -35,5 +35,17 @@ errorMessage?: string;

errorMessageContainerStyle?: StyleProp<ViewStyle>;
validation?: keyof ValidationFields;
}
interface PasswordInputProps extends InputProps {
passwordOptions: ValidationPasswordOptions;
validation: 'password';
}
interface NonPasswordFormInputProps extends InputProps {
validation?: Exclude<keyof ValidationFields, 'password'>;
passwordOptions?: never;
}
export type FormInputProps = PasswordInputProps | NonPasswordFormInputProps;
const FormInput: (props: FormInputProps) => JSX.Element;
export { FormInput };
export {FormInput};
}
{
"name": "react-native-form-container",
"version": "1.0.39",
"version": "1.0.40",
"description": "A form container component for React Native",

@@ -25,8 +25,5 @@ "main": "src/index.js",

"devDependencies": {
"@types/react-i18next": "^8.1.0",
"@types/react-native": "^0.60.0"
},
"dependencies": {
"react-i18next": "^14.1.2"
}
"dependencies": {}
}

@@ -5,2 +5,4 @@ # React Native Form Container

📝 [Medium Article](https://medium.com/@ozkankocakaplan07/simple-form-validation-with-react-native-form-container-a198f5fd8597)
## Support the Project

@@ -22,2 +24,6 @@

<img src="https://miro.medium.com/v2/resize:fit:592/format:webp/1*VWxjZQFQ1UP40jEzVH0UIw.gif" alt="react-native basic form validate" width="250">
## Installation

@@ -24,0 +30,0 @@

@@ -1,2 +0,2 @@

import React, { useState } from "react";
import React, {useState} from 'react';
import {

@@ -14,7 +14,9 @@ View,

Text,
} from "react-native";
} from 'react-native';
import ValidationFields, {ValidationPasswordOptions} from './ValidationFields';
interface InputProps extends TextInputProps {
iconPosition?: "left" | "right";
iconPosition?: 'left' | 'right';
icon?: any;
inputSize?: "sm" | "md";
inputSize?: 'sm' | 'md';
enableFocusBorder?: boolean;

@@ -30,7 +32,19 @@ errorMessage?: string;

errorMessageContainerStyle?: StyleProp<ViewStyle>;
validation?: keyof ValidationFields;
}
interface PasswordInputProps extends InputProps {
passwordOptions: ValidationPasswordOptions;
validation: 'password';
}
interface NonPasswordFormInputProps extends InputProps {
validation?: Exclude<keyof ValidationFields, 'password'>;
passwordOptions?: never;
}
export type FormInputProps = PasswordInputProps | NonPasswordFormInputProps;
export default function FormInput({
iconPosition = "left",
iconPosition = 'left',
icon = undefined,
inputSize = "md",
inputSize = 'md',
enableFocusBorder = true,

@@ -41,9 +55,9 @@ errorMessage,

passwordShowIcon,
activeBorder = "green",
inputBorder = "#143722",
activeBorder = 'green',
inputBorder = '#143722',
errorMessageComponent,
errorMessageTextStyle = { color: "red", marginTop: 5 },
errorMessageTextStyle = {color: 'red', marginTop: 5},
errorMessageContainerStyle,
...props
}: InputProps) {
}: FormInputProps) {
const [passwordShow, setPasswordShow] = useState(false);

@@ -63,14 +77,13 @@ const [isFocused, setIsFocused] = useState(false);

const size = inputSize === "sm" ? 10 : 15;
const iconSize = inputSize === "sm" ? 17 : 20;
const size = inputSize === 'sm' ? 10 : 15;
const iconSize = inputSize === 'sm' ? 17 : 20;
const iconSmTop = inputSize === "sm" ? (Platform.OS === "ios" ? 10 : 15) : 20;
const iconMdTop = inputSize === "md" ? 15 : 20;
const iconTop = inputSize === "sm" ? iconSmTop : iconMdTop;
const iconSmTop = inputSize === 'sm' ? (Platform.OS === 'ios' ? 10 : 15) : 20;
const iconMdTop = inputSize === 'md' ? 15 : 20;
const iconTop = inputSize === 'sm' ? iconSmTop : iconMdTop;
const inputPaddingHorizontal = inputSize === "sm" ? 33 : 40;
const inputPaddingHorizontal = inputSize === 'sm' ? 33 : 40;
return (
<View>
{iconPosition === "left" && icon && icon()}
{iconPosition === 'left' && icon && icon()}
<TextInput

@@ -87,7 +100,7 @@ autoFocus={false}

paddingLeft:
iconPosition === "left" && icon !== undefined
iconPosition === 'left' && icon !== undefined
? inputPaddingHorizontal
: size,
paddingRight:
iconPosition === "right" && icon !== undefined
iconPosition === 'right' && icon !== undefined
? inputPaddingHorizontal

@@ -101,5 +114,4 @@ : size,

<TouchableOpacity
style={[styles.passwordIcon, { top: iconTop, right: 10 }]}
onPress={() => setPasswordShow(!passwordShow)}
>
style={[styles.passwordIcon, {top: iconTop, right: 10}]}
onPress={() => setPasswordShow(!passwordShow)}>
{passwordShow ? passwordShowIcon() : passwordHideIcon()}

@@ -109,4 +121,4 @@ </TouchableOpacity>

{iconPosition === "right" && icon !== undefined && (
<View style={[styles.icon, { top: iconTop, right: 10 }]}>{icon()}</View>
{iconPosition === 'right' && icon !== undefined && (
<View style={[styles.icon, {top: iconTop, right: 10}]}>{icon()}</View>
)}

@@ -128,16 +140,16 @@ {errorMessage && (

input: {
width: "100%",
width: '100%',
borderRadius: 10,
backgroundColor: "#fff",
color: "#143722",
backgroundColor: '#fff',
color: '#143722',
borderWidth: 1,
},
icon: {
position: "absolute",
position: 'absolute',
zIndex: 1,
},
passwordIcon: {
position: "absolute",
position: 'absolute',
zIndex: 1,
},
});

@@ -7,9 +7,11 @@ import React, {

useState,
} from "react";
import { LogBox, View, ViewProps } from "react-native";
import { useTranslation } from "react-i18next";
} from 'react';
import {View, ViewProps} from 'react-native';
import {
isValidation,
checkPasswordOptions,
} from './components/ValidationFields';
export interface FormContainerProps extends ViewProps {
children: ReactNode;
formId?: string;
errorMessageField?: string;

@@ -22,3 +24,3 @@ formContainerRef?: MutableRefObject<FormContainerRef | null>;

}
LogBox.ignoreLogs([/react-i18next::/]);
export default function FormContainer(props: FormContainerProps) {

@@ -28,12 +30,8 @@ const {

formContainerRef,
formId,
errorMessageField = "errorMessage",
errorMessageField = 'errorMessage',
} = props;
const { t } = useTranslation(formId);
const [children, setChildren] = useState<ReactNode[] | any>(
React.Children.toArray(initialChildren)
React.Children.toArray(initialChildren),
);
const [errors, setErrors] = useState<{ [key: string]: string | undefined }>(
{}
);
const [errors, setErrors] = useState<{[key: string]: string | undefined}>({});
const checkValidation = useCallback((errorData: any) => {

@@ -45,11 +43,23 @@ handleErrorMessage(errorData);

let isEmpty = true;
React.Children.forEach(initialChildren, (child) => {
React.Children.forEach(initialChildren, child => {
if (React.isValidElement(child)) {
const childProps = { ...child.props };
const childProps = {...child.props};
if (childProps.id) {
if (
(childProps.required && childProps?.value === "") ||
childProps.value === undefined
) {
isEmpty = false;
let checkValidation = childProps?.validation;
if (checkValidation) {
let result = isValidation(
childProps?.validation,
childProps?.value,
childProps?.passwordOptions,
);
if (!result) {
isEmpty = false;
}
} else {
if (
(childProps.required && childProps?.value === '') ||
childProps.value === undefined
) {
isEmpty = false;
}
}

@@ -79,22 +89,9 @@ }

const handleErrorMessage = useCallback((errorData?: any) => {
let errorFields = {} as any;
if (props.formId && !errorData) {
React.Children.forEach(initialChildren, (child) => {
if (React.isValidElement(child)) {
const childProps = { ...child.props };
if (childProps.required && childProps?.id) {
errorFields[childProps.id] = t(childProps.id);
}
}
});
setErrors(errorFields);
} else {
setErrors(errorData);
}
setErrors(errorData);
}, []);
useEffect(() => {
setChildren(
React.Children.map(initialChildren, (child) => {
React.Children.map(initialChildren, child => {
if (React.isValidElement(child)) {
const childProps = { ...child.props };
var childProps = {...child.props};

@@ -104,26 +101,38 @@ if (childProps.id) {

let error = errors?.[childProps.id];
if (
(childProps?.value === "" || childProps?.value === undefined) &&
error
) {
if (props.formId) {
childProps[errorMessageField] = t(childProps?.id);
} else {
let validationCheck = childProps?.validation;
if (validationCheck) {
let result = isValidation(
childProps?.validation,
childProps?.value,
childProps?.passwordOptions,
);
if (!result) {
let errorOptions = checkPasswordOptions(
childProps?.passwordOptions,
childProps?.value,
childProps?.id,
);
let findKeyErrorOptions = Object.keys(errorOptions)[0];
childProps[errorMessageField] = errors?.[findKeyErrorOptions];
}
} else {
if (
(childProps?.value === '' ||
childProps?.value === undefined) &&
error
) {
if (error) {
childProps[errorMessageField] = error;
}
} else {
delete childProps[errorMessageField];
}
} else {
delete childProps[errorMessageField];
}
}
if (childProps.type === "checkbox") {
if (childProps.type === 'checkbox') {
if (!childProps.checked) {
if (props.formId) {
childProps[errorMessageField] = t(childProps.id);
} else {
let error = errors[childProps.id];
if (error) {
childProps[errorMessageField] = error;
}
let error = errors[childProps.id];
if (error) {
childProps[errorMessageField] = error;
}

@@ -140,3 +149,3 @@ } else {

return child;
})
}),
);

@@ -143,0 +152,0 @@ }, [initialChildren, errors]);