Last active
March 28, 2021 12:15
-
-
Save gchumillas/58baf61613e5f7deb243eb35c825e40a to your computer and use it in GitHub Desktop.
Revisions
-
gchumillas revised this gist
Mar 28, 2021 . 2 changed files with 41 additions and 51 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,48 +3,41 @@ import _ from 'lodash' export type Validator = (val: any) => string | true const useValidator = ({ defaultValidator = () => true, validators }: { defaultValidator?: Validator validators?: | { [name: string]: Validator[] } | ((defaultValidator: Validator) => { [name: string]: Validator[] }) }) => { const [texts, setTexts] = React.useState<{ [name: string]: string | true }>({}) return { test: (values: { [name: string]: any }, options?: { debug: boolean }) => { const texts = _.mapValues(values, (value, name) => { const v = _.isFunction(validators) ? validators(defaultValidator) : validators const fieldValidators = v?.[name] || [defaultValidator] for (const validator of fieldValidators) { const result = validator(value) if (typeof result == 'string') { options?.debug && console.info(`validator: ${name} is not valid`) return result } } return true }) setTexts(texts) return _.every(texts, x => _.isEmpty(x)) }, text: (name: string) => { const text = texts[name] return typeof text == 'string' ? text : undefined } } } export default useValidator This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,20 +15,17 @@ const TestPage = () => { gender: '' }) const validator = useValidator({ // Default validator (applied when no validator is specified) defaultValidator: val => !!val || 'Required field', // Custom validators validators: defaultValidator => ({ // rePassword is required (defaultValidator) and should be equal to password rePassword: [defaultValidator, val => val == item.password || 'Passwords do not match'], // Gender is not required, but when specified it must be one of the following values: gender: [val => !val || ['male', 'female', 'butterfly'].includes(val) || 'Unknown gender'] }) }) const onFieldChange = name => event => { setItem(item => ({ ...item, [name]: event.target.value })) -
gchumillas revised this gist
Mar 27, 2021 . 1 changed file with 5 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,6 +7,7 @@ const CustomTextField = ({ errorText, ...rest }) => { } const TestPage = () => { const [message, setMessage] = React.useState('') const [item, setItem] = React.useState({ username: '', password: '', @@ -35,8 +36,11 @@ const TestPage = () => { const onSubmit = () => { if (!validator.test(item)) { setMessage('No no no...') return } setMessage('Hooray! you got it!') } return ( @@ -71,6 +75,7 @@ const TestPage = () => { errorText={validator.text('gender')} /> <Button onClick={onSubmit}>Submit</Button> <p>{message}</p> </> ) } -
gchumillas renamed this gist
Mar 27, 2021 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
gchumillas created this gist
Mar 27, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,78 @@ import React from 'react' import { Button, TextField } from '@material-ui/core' import useValidator from 'src/lib/validator' const CustomTextField = ({ errorText, ...rest }) => { return <TextField error={!!errorText} helperText={errorText} {...rest} /> } const TestPage = () => { const [item, setItem] = React.useState({ username: '', password: '', rePassword: '', gender: '' }) const validator = useValidator( () => ({ // Default validator (applied when no validator is specified) defaultValidator: val => !!val || 'Required field', // Custom validators validators: defaultValidator => ({ // rePassword is required (defaultValidator) and should be equal to password rePassword: [defaultValidator, val => val == item.password || 'Passwords do not match'], // Gender is not required, but when specified it must be one of the following values: gender: [val => !val || ['male', 'female', 'butterfly'].includes(val) || 'Unknown gender'] }) }), [item.password] ) const onFieldChange = name => event => { setItem(item => ({ ...item, [name]: event.target.value })) } const onSubmit = () => { if (!validator.test(item)) { return } } return ( <> <CustomTextField required label="Username" value={item.username} onChange={onFieldChange('username')} errorText={validator.text('username')} /> <CustomTextField required type="password" label="Password" value={item.password} onChange={onFieldChange('password')} errorText={validator.text('password')} /> <CustomTextField required type="password" label="Repeat password" value={item.rePassword} onChange={onFieldChange('rePassword')} errorText={validator.text('rePassword')} /> <CustomTextField label="Gender" value={item.gender} onChange={onFieldChange('gender')} errorText={validator.text('gender')} /> <Button onClick={onSubmit}>Submit</Button> </> ) } export default TestPage This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,50 @@ import React from 'react' import _ from 'lodash' export type Validator = (val: any) => string | true const useValidator = ( callback: () => { defaultValidator?: Validator validators?: | { [name: string]: Validator[] } | ((defaultValidator: Validator) => { [name: string]: Validator[] }) }, deps: React.DependencyList = [] ) => { const [texts, setTexts] = React.useState<{ [name: string]: string | true }>({}) /* eslint-disable react-hooks/exhaustive-deps */ const memoizedCallback = React.useCallback(callback, deps) return React.useMemo( () => ({ test: (values: { [name: string]: any }) => { const res = memoizedCallback() const defaultValidator = res.defaultValidator || (x => true) const validators = res.validators const texts = _.mapValues(values, (value, name) => { const v = _.isFunction(validators) ? validators(defaultValidator) : validators const fieldValidators = v?.[name] || [defaultValidator] for (const validator of fieldValidators) { const result = validator(value) if (typeof result == 'string') { return result } } return true }) setTexts(texts) return _.every(texts, x => _.isEmpty(x)) }, text: (name: string) => { const text = texts[name] return typeof text == 'string' ? text : undefined } }), [memoizedCallback, texts] ) } export default useValidator