Skip to content

Commit

Permalink
Add PostDelay component
Browse files Browse the repository at this point in the history
Remove Form component. Use FormProvider instead
Rename rulesForm to regex
  • Loading branch information
ngocle2497 committed Mar 25, 2021
1 parent 7891668 commit a6df3fe
Show file tree
Hide file tree
Showing 25 changed files with 248 additions and 390 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rn-boiler-template",
"version": "1.64.1",
"version": "1.64.2",
"description": "Clean and minimalist React Native template for a quick start with TypeScript and components",
"scripts": {
"test": "exit 0"
Expand Down
1 change: 1 addition & 0 deletions template/_babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@components": "./src/app/library/components",
"@networking": "./src/app/library/networking",
"@utils": "./src/app/library/utils",
"@model": "./src/app/model",
"@navigation": "./src/app/navigation",
"@store": "./src/app/store",
"@theme": "./src/app/themes",
Expand Down
2 changes: 1 addition & 1 deletion template/src/app/common/handleError/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {ERROR_NETWORK_CODE} from '@config';
import {ERROR_NETWORK_CODE} from '@config/api';
import {translate} from '@utils';
import {ResponseBase} from '@config/type';

Expand Down
File renamed without changes.
2 changes: 2 additions & 0 deletions template/src/app/config/regex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const rxEmail = /^[a-z][a-z0-9%_\.]{3,32}@[a-z0-9]{3,}(\.[a-z]{3,4}){1,2}$/;
export const rxPassword = /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[\W])(?!.*['"]).{8,}$/;
80 changes: 0 additions & 80 deletions template/src/app/config/ruleForm.ts

This file was deleted.

9 changes: 9 additions & 0 deletions template/src/app/config/type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-shadow */
import {Theme} from '@react-navigation/native';
import {RegisterOptions} from 'react-hook-form';
export interface ResponseBase<T = any> {
code: number;

Expand Down Expand Up @@ -113,6 +114,14 @@ export interface Spacing {
}
export type AppTheme = Theme & {colors: Partial<Colors>};

export type HookFormRules = Exclude<
RegisterOptions,
'valueAsNumber' | 'valueAsDate' | 'setValueAs'
>;
export type ValidationMap<T = any, Keys extends keyof T = keyof T> = {
[K in Keys]-?: RegisterOptions;
};

export enum SLICE_NAME {
APP = 'APP',
LOGIN = 'LOGIN',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,67 +1,62 @@
/* eslint-disable import/extensions */
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, {memo, useMemo} from 'react';
import {Button} from 'react-native';
import {ValidationMap} from '@config/type';
import {FormLoginType} from '@model/login';
import React, {memo, useCallback, useMemo} from 'react';
import isEqual from 'react-fast-compare';
import {Form} from '@components';
import {ValidationMap} from '@library/components/Form/Form.props';
import {useForm} from 'react-hook-form';
import {FormProvider, useForm} from 'react-hook-form';
import {Button} from 'react-native';

import {Input} from './Input';

export type FormValue = {
name: string;
password: string;
repassword: string;
};

interface FormLoginProps {
onSubmit: (data: FormValue) => void;
onSubmit: (data: FormLoginType) => void;
}

const FormLoginComponent = ({onSubmit}: FormLoginProps) => {
const {
register,
setValue,
trigger,
getValues,
errors,
handleSubmit,
} = useForm<FormValue>();
// state
const formMethod = useForm<FormLoginType>({mode: 'all'});
const {password} = formMethod.watch();
const isDirty = formMethod.formState.dirtyFields.rePassword;

const rules = useMemo(
() =>
({
name: {required: {value: true, message: 'Name is required'}},
password: {required: {value: true, message: 'Password is required'}},
repassword: {
required: {value: true, message: 'Confirm is required'},
validate: (val: any) =>
val === getValues().password || 'Passwords do not match',
rePassword: {
required: {value: true, message: 'Password is required'},
validate: (val: string | undefined) => {
return !isDirty || val === password
? undefined
: 'Passwords do not match';
},
},
} as ValidationMap<FormValue>),
[getValues],
} as ValidationMap<FormLoginType>),
[isDirty, password],
);
const onSubmitKey = () => {
handleSubmit(onSubmit)();
};

// function
const onSubmitKey = useCallback(() => {
formMethod.handleSubmit(onSubmit)();
}, [formMethod, onSubmit]);

// render
return (
<>
<Form {...{register, getValues, setValue, trigger, rules, errors}}>
<Input name={'name'} label={'Name'} />
<Input
nameTrigger={'repassword'}
name={'password'}
label={'Password'}
/>
<Input
onSubmit={onSubmitKey}
nameTrigger={'password'}
name={'repassword'}
label={'Confirm Password'}
/>
<Button title={'Submit'} onPress={handleSubmit(onSubmit)} />
</Form>
</>
<FormProvider {...formMethod}>
<Input rules={rules.name} name={'name'} label={'Name'} />
<Input
rules={rules.password}
nameTrigger={'rePassword'}
name={'password'}
label={'Password'}
/>
<Input
rules={rules.rePassword}
onSubmit={onSubmitKey}
name={'rePassword'}
label={'Confirm Password'}
/>
<Button title={'Submit'} onPress={onSubmitKey} />
</FormProvider>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,53 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, {memo, forwardRef} from 'react';
import {TextField} from '@components';
import {HookFormRules} from '@config/type';
import {FormLoginType} from '@model/login';
import React, {memo} from 'react';
import isEqual from 'react-fast-compare';
import {FieldError} from 'react-hook-form';
import {useController, useFormContext} from 'react-hook-form';
import {TextInputProps} from 'react-native';

import {FormValue} from './FormLogin';

interface InputProps {
name: keyof FormValue;
interface InputProps extends TextInputProps {
name: keyof FormLoginType;
label: string;
error?: FieldError | undefined;
onSubmit?: () => void;
nameTrigger?: keyof FormValue;
nameTrigger?: keyof FormLoginType;
rules?: HookFormRules;
}

const InputComponent = forwardRef<any, InputProps>(
({onSubmit, label, name, nameTrigger, error, ...rest}, ref) => {
return (
<TextField
onSubmit={onSubmit}
ref={ref}
nameTrigger={nameTrigger}
error={error?.message !== undefined}
label={label}
name={name}
typeInput={'flat'}
{...rest}
/>
);
},
);
const InputComponent = ({
onSubmit,
label,
name,
rules,
nameTrigger,
defaultValue = '',
...rest
}: InputProps) => {
// state
const {errors, control, trigger, getValues} = useFormContext<FormLoginType>();
const {field} = useController({
name,
control,
rules,
defaultValue,
});
// render
return (
<TextField
onSubmit={onSubmit}
ref={field.ref}
nameTrigger={nameTrigger}
trigger={trigger}
error={errors[name]?.message !== undefined}
label={label}
name={name}
onChangeText={field.onChange}
onBlur={field.onBlur}
defaultValue={getValues()[name]}
typeInput={'flat'}
{...rest}
/>
);
};

export const Input = memo(InputComponent, isEqual);

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ import {
TouchableScale,
Wallpaper,
} from '@components';
import {FormLoginType} from '@model/login';
import React, {memo, useCallback, useRef, useState} from 'react';
import isEqual from 'react-fast-compare';

import {FormLogin} from './components/FormLogin';

const LoginComponent = () => {
const _modalMode = useRef<ModalAppModeRef>();
const _refAction = useRef<ActionSheetRef>();
Expand All @@ -38,6 +41,9 @@ const LoginComponent = () => {
lower: number;
upper: number;
}>({lower: 0, upper: 0});
const onSubmit = useCallback((data: FormLoginType) => {
alert(JSON.stringify(data));
}, []);
const _onShowAction = useCallback(() => {
if (_refAction.current) {
_refAction.current.show();
Expand All @@ -52,6 +58,7 @@ const LoginComponent = () => {
style={{paddingVertical: 0, paddingHorizontal: 10}}
scroll={true}
backgroundColor={'transparent'}>
<FormLogin onSubmit={onSubmit} />
<Block width={150} height={150}>
<LightBox source={{uri: 'https://picsum.photos/id/11/400/400'}} />
</Block>
Expand Down Expand Up @@ -175,7 +182,6 @@ const LoginComponent = () => {
<Spacer width={10} />
<Switch type={'android'} />
</Block>
{/* <FormLogin onSubmit={_onSubmit} /> */}
</Screen>
<FAB
label="Float"
Expand Down
2 changes: 1 addition & 1 deletion template/src/app/library/components/AppMode/AppMode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, {memo} from 'react';
import {StyleSheet, Text, View} from 'react-native';
import {AppModeType} from '@networking';
import isEqual from 'react-fast-compare';
import {APP_MODE} from '@config';
import {APP_MODE} from '@config/api';

const modeToString = (mode: AppModeType): string => {
switch (mode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import isEqual from 'react-fast-compare';
import Modal from 'react-native-modal';
import {FontSizeDefault} from '@theme/fontSize';
import {AppModeType} from '@networking';
import {APP_MODE} from '@config';
import {APP_MODE} from '@config/api';
import {dispatch, useSelector} from '@common';
import {onSetAppMode} from '@store/app_redux/reducer';
import {saveString} from '@utils';
Expand Down
Loading

0 comments on commit a6df3fe

Please sign in to comment.