Skip to content

Commit 7c9001f

Browse files
Implement a way to check the validation (GH-25)
2 parents 8369c2a + 29153d6 commit 7c9001f

File tree

5 files changed

+59
-13
lines changed

5 files changed

+59
-13
lines changed

README.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ const Demo = () => {
3636
}
3737
```
3838

39-
For including the styles, you should import them in the main `less` file after importing either the `antd/dist/antd.less` or `antd/dist/antd.dark.less` styles.
39+
For including the styles, you should import them in the main `less` file after importing either
40+
the `antd/dist/antd.less` or `antd/dist/antd.dark.less` styles.
4041

4142
```diff
4243
@import "~antd/dist/antd";
@@ -63,10 +64,31 @@ number into a single string.
6364
"countryCode": 1,
6465
"areaCode": 702,
6566
"phoneNumber": "1234567",
66-
"isoCode": "us"
67+
"isoCode": "us",
68+
"valid": true
6769
}
6870
```
6971

72+
## Validation
73+
74+
The `valid` property of the value object shows the real-time validity of the phone number depending on the country. So
75+
this can be used in a `validator` like this:
76+
77+
```javascript
78+
const validator = (_, {valid}) => {
79+
if (valid) {
80+
return Promise.resolve();
81+
}
82+
return Promise.reject("Invalid phone number");
83+
}
84+
85+
return (
86+
<FormItem rules={[{validator}]}>
87+
<PhoneInput/>
88+
</FormItem>
89+
)
90+
```
91+
7092
## Props
7193

7294
| Property | Description | Type |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "0.1.1",
2+
"version": "0.1.2",
33
"name": "antd-phone-input",
44
"description": "Advanced Phone Number Input for Ant Design",
55
"keywords": [

src/index.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {ParsePhoneNumber, PhoneInputProps, ReactPhoneOnChange, ReactPhoneOnMount
55

66
import masks from "./phoneMasks.json";
77
import timezones from "./timezones.json";
8+
import validations from "./validations.json";
89

910
import "react-phone-input-2/lib/style.css";
1011

@@ -35,7 +36,14 @@ const parsePhoneNumber: ParsePhoneNumber = (value, data, formattedNumber) => {
3536
const phoneNumberMatch = value ? (value.match(phoneNumberPattern) || []) : [];
3637
const phoneNumber = phoneNumberMatch.length > 1 ? phoneNumberMatch[1] : null;
3738

38-
return {countryCode, areaCode, phoneNumber, isoCode};
39+
/** Checks if both the area code and phone number length satisfy the validation rules */
40+
const rules = validations[isoCode as ISO2Code] || {areaCode: [], phoneNumber: []};
41+
const valid = [
42+
rules.areaCode.includes((areaCode || "").toString().length),
43+
rules.phoneNumber.includes((phoneNumber || "").toString().length),
44+
].every(Boolean);
45+
46+
return {countryCode, areaCode, phoneNumber, isoCode, valid};
3947
}
4048

4149
const PhoneInput = ({
@@ -79,8 +87,8 @@ const PhoneInput = ({
7987

8088
const onMount: ReactPhoneOnMount = (rawValue, {countryCode, ...event}, formattedNumber) => {
8189
const metadata = parsePhoneNumber(rawValue, {countryCode}, formattedNumber);
82-
/** Initiates the existing value when Antd FormItem is used */
83-
if (value === undefined) handleChange(metadata, event);
90+
/** Initializes the existing value */
91+
handleChange(metadata, event);
8492
handleMount(metadata);
8593
}
8694

src/types.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface PhoneNumber {
99
areaCode?: number | null,
1010
phoneNumber?: string | null,
1111
isoCode?: string,
12+
valid?: boolean,
1213
}
1314

1415
export interface AntInputProps {
@@ -17,9 +18,7 @@ export interface AntInputProps {
1718
style?: CSSProperties,
1819
className?: string,
1920
disabled?: boolean,
20-
}
2121

22-
export interface AntInputEventsProps {
2322
onChange?(value: PhoneNumber, event: ChangeEvent<HTMLInputElement>): void;
2423

2524
onPressEnter?(event: KeyboardEvent<HTMLInputElement>): void;
@@ -37,9 +36,7 @@ export interface ReactPhoneInputProps {
3736
onlyCountries?: string[],
3837
excludeCountries?: string[],
3938
preferredCountries?: string[],
40-
}
4139

42-
export interface ReactPhoneEventsProps {
4340
onFocus?(event: FocusEvent<HTMLInputElement>, value: PhoneNumber): void;
4441

4542
onClick?(event: MouseEvent<HTMLInputElement>, value: PhoneNumber): void;
@@ -63,7 +60,9 @@ export interface ParsePhoneNumber {
6360
(value: string, data: CountryData, formattedNumber: string): PhoneNumber;
6461
}
6562

66-
export interface PhoneInputProps extends AntInputProps, AntInputEventsProps, ReactPhoneInputProps, ReactPhoneEventsProps {
67-
// TODO add onValidate: https://github.com/ArtyomVancyan/antd-phone-input/issues/19
68-
// onValidate?: (value: PhoneNumber) => boolean;
63+
export interface PhoneInputProps extends AntInputProps, ReactPhoneInputProps {
64+
/**
65+
* NOTE: Interfaces of events may differ from the original interfaces
66+
* of dependencies, so be careful and follow the linked documentation.
67+
*/
6968
}

tests/common.test.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ describe("Checks the basic rendering and functionality", () => {
3333
assert(value.areaCode === 702);
3434
assert(value.phoneNumber === "1234567");
3535
assert(value.isoCode === "us");
36+
assert(value.valid === true);
3637
}}
3738
value={{countryCode: 1, areaCode: 702, phoneNumber: "1234567"}}
3839
/>);
40+
assert(screen.getByDisplayValue("+1 (702) 123 4567"));
3941
})
4042

4143
it("Checks the component on user input", async () => {
@@ -67,4 +69,19 @@ describe("Checks the basic rendering and functionality", () => {
6769
assert(input.getAttribute("value") === "+1 (702) 123 4567");
6870
screen.getByTestId("button").click();
6971
})
72+
73+
it("Checks input validation with FormItem", async () => {
74+
render(<Form initialValues={{phone: {countryCode: 1, areaCode: 702, phoneNumber: "1234567"}}}>
75+
<FormItem name="phone" rules={[{
76+
validator: (_, {valid}) => {
77+
assert(valid === true);
78+
return Promise.resolve();
79+
}
80+
}]}>
81+
<PhoneInput/>
82+
</FormItem>
83+
<Button data-testid="button" htmlType="submit">Submit</Button>
84+
</Form>);
85+
await userEvent.click(screen.getByTestId("button"));
86+
})
7087
})

0 commit comments

Comments
 (0)