Skip to content

Commit 97abf10

Browse files
authored
Merge pull request #3 from anigenero/localization
Localization
2 parents 7858e79 + 2182c02 commit 97abf10

6 files changed

Lines changed: 48 additions & 7 deletions

File tree

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.idea/
12
src/
23
node_modules/
34

README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@ Easy-to-use React hook for validating forms with the [class-validator](https://g
1111
npm install --save react-class-validator
1212
```
1313

14+
```typescript
15+
16+
const validatorOptions: ValidatorContextOptions = {
17+
onErrorMessage: (error): string => {
18+
// custom error message handling (localization, etc)
19+
}
20+
}
21+
22+
render((
23+
<ValidatorContext options={validatorOptions}>
24+
<MyComponent />
25+
</ValidatorContext>
26+
), document.getElementById('root'))
27+
```
28+
1429
## Usage
1530

1631
```typescript
@@ -32,7 +47,7 @@ class LoginValidation {
3247
```
3348

3449
```typescript jsx
35-
const LoginForm = () => {
50+
const MyComponent = () => {
3651

3752
const [username, setUsername] = useState('');
3853
const [password, setPassword] = useState('');
@@ -58,7 +73,7 @@ const LoginForm = () => {
5873
{/* show error */}
5974
{errors.username && (
6075
<div className="error">
61-
{errors.username}
76+
{errors.username.map((message) => <strong>message</strong>)}
6277
</div>
6378
)}
6479

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/context.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import {ValidationError} from "class-validator";
2+
import React, {createContext, FunctionComponent} from "react";
3+
4+
export type OnErrorMessageHandler = (error: ValidationError) => string[];
5+
export type ValidatorContextOptions = {
6+
onErrorMessage: OnErrorMessageHandler;
7+
};
8+
9+
const _getDefaultContextOptions = (): ValidatorContextOptions => ({
10+
onErrorMessage: (error) => Object.keys(error.constraints).map((key) => error.constraints[key])
11+
});
12+
13+
export const ValidatorContext = createContext<ValidatorContextOptions>(null);
14+
15+
export const ValidatorProvider: FunctionComponent<{ options?: ValidatorContextOptions }> =
16+
({options = _getDefaultContextOptions(), children}) => (
17+
<ValidatorContext.Provider value={options}>
18+
{children}
19+
</ValidatorContext.Provider>
20+
);

src/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import {validate} from 'class-validator';
2-
import {useState} from 'react';
2+
import {useContext, useState} from 'react';
3+
import {ValidatorContext} from "./context";
4+
5+
export {ValidatorProvider, ValidatorContextOptions, OnErrorMessageHandler} from './context';
36

47
type Newable<T> = {
58
new(): T;
69
} | Function;
710

8-
type ValidationErrorMap<T, K extends keyof T> = { [key in K]?: string };
11+
type ValidationErrorMap<T, K extends keyof T> = { [key in K]?: string[] };
912
type ValidationPayload<T, K extends keyof T> = { [key in K]?: T[K] };
1013
type ValidationFunction<T, K extends keyof T> = (payload: ValidationPayload<T, K>, filter?: K[]) => Promise<boolean>;
1114
type UseValidationResult<T, K extends keyof T> = [ValidationFunction<T, K>, ValidationErrorMap<T, K>];
1215

1316
export const useValidation = <T, K extends keyof T>(validationClass: Newable<T>): UseValidationResult<T, K> => {
1417

18+
const {onErrorMessage} = useContext(ValidatorContext);
19+
1520
const [validationErrors, setErrors] = useState<ValidationErrorMap<T, K>>({});
1621

1722
const validateCallback: ValidationFunction<T, K> = async (payload, filter: K[] = []) => {
@@ -34,7 +39,7 @@ export const useValidation = <T, K extends keyof T>(validationClass: Newable<T>)
3439
const validation: ValidationErrorMap<T, K> = errors.reduce(
3540
(acc, value) => ({
3641
...acc,
37-
[value.property as K]: Object.keys(value.constraints).map((key) => value.constraints[key])[0]
42+
[value.property as K]: onErrorMessage(value)
3843
}),
3944
{} as ValidationErrorMap<T, K>
4045
);

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"/**/*.spec.tsx"
2727
],
2828
"include": [
29-
"./src/**/*"
29+
"./src/index.ts"
3030
]
3131
}
3232

0 commit comments

Comments
 (0)