Skip to content

Commit

Permalink
Implement a way to check the validation (GH-25)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArtyomVancyan authored Mar 7, 2023
2 parents 8369c2a + 29153d6 commit 7c9001f
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 13 deletions.
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ const Demo = () => {
}
```

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.
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.

```diff
@import "~antd/dist/antd";
Expand All @@ -63,10 +64,31 @@ number into a single string.
"countryCode": 1,
"areaCode": 702,
"phoneNumber": "1234567",
"isoCode": "us"
"isoCode": "us",
"valid": true
}
```

## Validation

The `valid` property of the value object shows the real-time validity of the phone number depending on the country. So
this can be used in a `validator` like this:

```javascript
const validator = (_, {valid}) => {
if (valid) {
return Promise.resolve();
}
return Promise.reject("Invalid phone number");
}

return (
<FormItem rules={[{validator}]}>
<PhoneInput/>
</FormItem>
)
```

## Props

| Property | Description | Type |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.1.1",
"version": "0.1.2",
"name": "antd-phone-input",
"description": "Advanced Phone Number Input for Ant Design",
"keywords": [
Expand Down
14 changes: 11 additions & 3 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {ParsePhoneNumber, PhoneInputProps, ReactPhoneOnChange, ReactPhoneOnMount

import masks from "./phoneMasks.json";
import timezones from "./timezones.json";
import validations from "./validations.json";

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

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

return {countryCode, areaCode, phoneNumber, isoCode};
/** Checks if both the area code and phone number length satisfy the validation rules */
const rules = validations[isoCode as ISO2Code] || {areaCode: [], phoneNumber: []};
const valid = [
rules.areaCode.includes((areaCode || "").toString().length),
rules.phoneNumber.includes((phoneNumber || "").toString().length),
].every(Boolean);

return {countryCode, areaCode, phoneNumber, isoCode, valid};
}

const PhoneInput = ({
Expand Down Expand Up @@ -79,8 +87,8 @@ const PhoneInput = ({

const onMount: ReactPhoneOnMount = (rawValue, {countryCode, ...event}, formattedNumber) => {
const metadata = parsePhoneNumber(rawValue, {countryCode}, formattedNumber);
/** Initiates the existing value when Antd FormItem is used */
if (value === undefined) handleChange(metadata, event);
/** Initializes the existing value */
handleChange(metadata, event);
handleMount(metadata);
}

Expand Down
13 changes: 6 additions & 7 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface PhoneNumber {
areaCode?: number | null,
phoneNumber?: string | null,
isoCode?: string,
valid?: boolean,
}

export interface AntInputProps {
Expand All @@ -17,9 +18,7 @@ export interface AntInputProps {
style?: CSSProperties,
className?: string,
disabled?: boolean,
}

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

onPressEnter?(event: KeyboardEvent<HTMLInputElement>): void;
Expand All @@ -37,9 +36,7 @@ export interface ReactPhoneInputProps {
onlyCountries?: string[],
excludeCountries?: string[],
preferredCountries?: string[],
}

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

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

export interface PhoneInputProps extends AntInputProps, AntInputEventsProps, ReactPhoneInputProps, ReactPhoneEventsProps {
// TODO add onValidate: https://github.com/ArtyomVancyan/antd-phone-input/issues/19
// onValidate?: (value: PhoneNumber) => boolean;
export interface PhoneInputProps extends AntInputProps, ReactPhoneInputProps {
/**
* NOTE: Interfaces of events may differ from the original interfaces
* of dependencies, so be careful and follow the linked documentation.
*/
}
17 changes: 17 additions & 0 deletions tests/common.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ describe("Checks the basic rendering and functionality", () => {
assert(value.areaCode === 702);
assert(value.phoneNumber === "1234567");
assert(value.isoCode === "us");
assert(value.valid === true);
}}
value={{countryCode: 1, areaCode: 702, phoneNumber: "1234567"}}
/>);
assert(screen.getByDisplayValue("+1 (702) 123 4567"));
})

it("Checks the component on user input", async () => {
Expand Down Expand Up @@ -67,4 +69,19 @@ describe("Checks the basic rendering and functionality", () => {
assert(input.getAttribute("value") === "+1 (702) 123 4567");
screen.getByTestId("button").click();
})

it("Checks input validation with FormItem", async () => {
render(<Form initialValues={{phone: {countryCode: 1, areaCode: 702, phoneNumber: "1234567"}}}>
<FormItem name="phone" rules={[{
validator: (_, {valid}) => {
assert(valid === true);
return Promise.resolve();
}
}]}>
<PhoneInput/>
</FormItem>
<Button data-testid="button" htmlType="submit">Submit</Button>
</Form>);
await userEvent.click(screen.getByTestId("button"));
})
})

0 comments on commit 7c9001f

Please sign in to comment.