Skip to content

Commit

Permalink
fix: ensure that the number of digits is the same as in the mask (#392)
Browse files Browse the repository at this point in the history
* chore(deps): bump

* fix: ensure that the number of digits is the same as in the mask

* chore(deps): bump example
  • Loading branch information
jorisre authored Dec 21, 2022
1 parent e94630b commit 8bee58d
Show file tree
Hide file tree
Showing 9 changed files with 3,116 additions and 2,638 deletions.
1 change: 0 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
},
"plugins": ["react", "@typescript-eslint"],
"rules": {
"quotes": ["error", "single"],
"semi": ["error", "always"],
"react/react-in-jsx-scope": 0,
"react/jsx-uses-react": 0,
Expand Down
30 changes: 15 additions & 15 deletions examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@
"preview": "vite preview"
},
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-hook-form": "^7.29.0",
"react-telephone": "^1.3.0",
"styled-components": "^5.3.5"
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.41.0",
"react-telephone": "^1.3.1",
"styled-components": "^5.3.6"
},
"devDependencies": {
"@types/node": "^17.0.23",
"@types/react": "^17.0.43",
"@types/react-dom": "^17.0.14",
"@types/styled-components": "^5.1.24",
"@vitejs/plugin-react": "^1.3.0",
"autoprefixer": "^10.4.4",
"postcss": "^8.4.12",
"tailwindcss": "^3.0.23",
"typescript": "^4.6.3",
"vite": "^2.9.1"
"@types/node": "^18.11.17",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"@types/styled-components": "^5.1.26",
"@vitejs/plugin-react": "^3.0.0",
"autoprefixer": "^10.4.13",
"postcss": "^8.4.20",
"tailwindcss": "^3.2.4",
"typescript": "^4.9.4",
"vite": "^4.0.2"
}
}
1,321 changes: 612 additions & 709 deletions examples/yarn.lock

Large diffs are not rendered by default.

44 changes: 22 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,29 +54,29 @@
"react-dom": "^16 || ^17 || ^18"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^14.0.4",
"@types/node": "^17.0.21",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^5.15.0",
"@typescript-eslint/parser": "^5.15.0",
"@vitejs/plugin-react": "^1.0.7",
"c8": "^7.11.0",
"eslint": "^8.10.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3",
"@types/node": "^18.11.17",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"@typescript-eslint/eslint-plugin": "^5.47.0",
"@typescript-eslint/parser": "^5.47.0",
"@vitejs/plugin-react": "^3.0.0",
"c8": "^7.12.0",
"eslint": "^8.30.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-react": "^7.29.3",
"husky": ">=6",
"jsdom": "^19.0.0",
"lint-staged": ">=12.3.7",
"microbundle": "^0.14.2",
"prettier": "2.6.2",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"typescript": "^4.5.4",
"vite": "^2.9.1",
"vitest": "^0.9.0"
"eslint-plugin-react": "^7.31.11",
"husky": ">=8.0.2",
"jsdom": "^20.0.3",
"lint-staged": ">=13.1.0",
"microbundle": "^0.15.1",
"prettier": "2.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^4.9.4",
"vite": "^4.0.2",
"vitest": "^0.26.1"
},
"lint-staged": {
"*.js": "yarn lint --cache --fix",
Expand Down
29 changes: 26 additions & 3 deletions src/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ test('should empty the field', async () => {
expect(screen.getByPlaceholderText('3 33 33 33 33')).toBeEmptyDOMElement();
});

test('should empty the field with phone number that contains `-` or `()`', async () => {
test.only('should empty the field with phone number that contains `-` or `()`', async () => {
const handleChange = vi.fn<[React.ChangeEvent<HTMLInputElement>], void>();
const placeholder = '(33) 33-33-33';

Expand Down Expand Up @@ -251,10 +251,13 @@ test('should empty the field with phone number that contains `-` or `()`', async
await user.type(screen.getByPlaceholderText(placeholder), '{Backspace}');
await user.type(screen.getByPlaceholderText(placeholder), '{Backspace}');

expect(screen.getByPlaceholderText(placeholder)).toBeEmptyDOMElement();
expect(screen.getByPlaceholderText(placeholder)).toHaveValue('');

await user.type(screen.getByPlaceholderText(placeholder), 'AA');
expect(screen.getByPlaceholderText(placeholder)).toHaveValue('');
});

test('should format placeholder if it\'s formatable', async () => {
test("should format placeholder if it's formatable", async () => {
const placeholder = '333333333';

render(
Expand Down Expand Up @@ -287,3 +290,23 @@ test('should not format placeholder', async () => {

expect(screen.getByPlaceholderText(placeholder)).toBeTruthy();
});

test('PhoneInput with default country', async () => {
const placeholder = 'XXXXXXXXX';
const handleChange = vi.fn<[React.ChangeEvent<HTMLInputElement>], void>();

render(
<Phone onChange={handleChange} defaultCountry="fr">
<Phone.Country />
<Phone.Number placeholder={placeholder} />
</Phone>
);

expect(screen.queryByDisplayValue('France (+33)')).toBeVisible();

await user.type(screen.getByPlaceholderText(placeholder), '7878787877');

expect(handleChange).toHaveBeenCalled();

expect(handleChange.mock.calls[0][0].target.value).toEqual('+33787878787');
});
20 changes: 10 additions & 10 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import * as React from 'react';
import countries from './countries';
import type { Country as CountryType } from './utils';
import { Country as CountryType, getMaskDigit } from './utils';
import {
applyMask,
getCountryByIso,
PhoneNumber,
removeMask,
replaceDialCode,
splitPhoneNumber,
} from './utils';
Expand Down Expand Up @@ -144,14 +143,15 @@ const _Number = React.forwardRef<
onChange={(e) => {
props.onChange?.(e);

if (/\d+|^$/.test(e.target.value)) {
setValue(
Object.assign({}, _value, {
raw: '+' + _value.country[3] + removeMask(e.target.value),
formatted: applyMask(e.target.value, _value.country[4]),
})
);
}
setValue(
Object.assign({}, _value, {
raw:
'+' +
_value.country[3] +
getMaskDigit(e.target.value, _value.country[4]),
formatted: applyMask(e.target.value, _value.country[4]),
})
);
}}
/>
);
Expand Down
10 changes: 10 additions & 0 deletions src/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
applyMask,
getCountryByIso,
getMaskDigit,
isE164Compliant,
removeMask,
splitPhoneNumber,
Expand Down Expand Up @@ -118,6 +119,15 @@ test.each([
['(33) 33-33-33', '33333333'],
])('removeMask(%s) -> %s', (p, e) => expect(removeMask(p)).toBe(e));

test.each([
['234567890', '. .. .. .. ..', '234567890'],
['23456789099', '. .. .. .. ..', '234567890'],
['2345678', '. .. .. .. ..', '2345678'],
['(33) 33-33-33', '(..) ..-..-..', '33333333'],
])('getMaskDigit(%s, %s) -> %s', (p, m, e) =>
expect(getMaskDigit(p, m)).toBe(e)
);

test('getCountryByIso', () => {
expect(getCountryByIso('fr')).toEqual([
'France',
Expand Down
13 changes: 12 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,22 @@ export const getCountryByIso = (code: Country[2]) =>
countries.find((c) => c[2] === code) as Country;

export const removeMask = (value: string) => value.replace(/\D/g, '');
export const getMaskDigit = (value: string, mask?: string) => {
const v = removeMask(value);
if (!mask) return v;

const numberOfDigits = mask.match(/\./g)?.length;

return v.substring(0, numberOfDigits);
};

export const applyMask = (value = '', mask?: string) => {
if (!mask || !value) return value;
const flatValue = removeMask(value).split('');
return (/^.*\d/.exec(mask.replace(/\./g, () => flatValue.shift() || '')) || [])[0] || '';
return (
(/^.*\d/.exec(mask.replace(/\./g, () => flatValue.shift() || '')) ||
[])[0] || ''
);
};

export const isE164Compliant = (value: string) =>
Expand Down
Loading

1 comment on commit 8bee58d

@vercel
Copy link

@vercel vercel bot commented on 8bee58d Dec 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.