Skip to content

Commit

Permalink
Merge pull request #144 from goveo/fix/skip-focus-on-country-set
Browse files Browse the repository at this point in the history
Allow disable focus on country change
  • Loading branch information
goveo authored Jan 11, 2024
2 parents 2bac4df + e714101 commit b62f3d0
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 11 deletions.
10 changes: 9 additions & 1 deletion packages/docs/docs/02-Usage/01-PhoneInput.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ description={<span>Show prefix and dial code between country selector and phone
defaultValue="false"
/>

### `disableFocusAfterCountrySelect`

<PropDescription
type="boolean"
description="Disable auto focus on input field after country select."
defaultValue="false"
/>

### `disableFormatting`

<PropDescription
Expand Down Expand Up @@ -237,7 +245,7 @@ In addition to the [HTMLInputElement API](https://developer.mozilla.org/en-US/do
#### `setCountry`

<PropDescription
type="(iso2: CountryIso2) => void"
type="(iso2: CountryIso2, options?: { focusOnInput: boolean }) => void"
description="Set some country value (works same as country selector country item click handler)"
/>

Expand Down
2 changes: 1 addition & 1 deletion packages/docs/docs/04-Advanced Usage/01-usePhoneInput.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,6 @@ description="Current country object."
### `setCountry`

<PropDescription
type="(country: CountryIso2) => void"
type="(country: CountryIso2, options?: { focusOnInput: boolean })) => void"
description="Country setter."
/>
44 changes: 44 additions & 0 deletions src/components/PhoneInput/PhoneInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1259,4 +1259,48 @@ describe('PhoneInput', () => {
});
});
});

describe('disableFocusAfterCountrySelect', () => {
test('should focus on input if disableFocusAfterCountrySelect is not provided', async () => {
render(<PhoneInput />);

expect(getInput().value).toBe('+1 ');

getInput().focus();
expect(getInput()).toHaveFocus();

// remove focus from input
(document.activeElement as HTMLElement).blur();

act(() => {
fireEvent.click(getCountrySelector());
fireEvent.click(getDropdownOption('ua'));
});

await Promise.resolve();

expect(getInput()).toHaveFocus();
});

test('should not focus on input if disableFocusAfterCountrySelect is true', async () => {
render(<PhoneInput disableFocusAfterCountrySelect />);

expect(getInput().value).toBe('+1 ');

getInput().focus();
expect(getInput()).toHaveFocus();

// remove focus from input
(document.activeElement as HTMLElement)?.blur();

act(() => {
fireEvent.click(getCountrySelector());
fireEvent.click(getDropdownOption('ua'));
});

await Promise.resolve();

expect(getInput()).not.toHaveFocus();
});
});
});
17 changes: 14 additions & 3 deletions src/components/PhoneInput/PhoneInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import React, { forwardRef, useImperativeHandle } from 'react';
import { defaultCountries } from '../../data/countryData';
import { usePhoneInput, UsePhoneInputConfig } from '../../hooks/usePhoneInput';
import { buildClassNames } from '../../style/buildClassNames';
import { CountryIso2, ParsedCountry } from '../../types';
import { ParsedCountry } from '../../types';
import {
CountrySelector,
CountrySelectorProps,
Expand Down Expand Up @@ -46,6 +46,12 @@ export interface PhoneInputProps
*/
showDisabledDialCodeAndPrefix?: boolean;

/**
* @description Disable auto focus on input field after country select.
* @default false
*/
disableFocusAfterCountrySelect?: boolean;

/**
* @description Custom flag URLs array
* @default undefined
Expand Down Expand Up @@ -87,7 +93,7 @@ export interface PhoneInputProps
export type PhoneInputRefType =
| null
| (HTMLInputElement & {
setCountry: (iso2: CountryIso2) => void;
setCountry: ReturnType<typeof usePhoneInput>['setCountry'];
state: {
phone: string;
inputValue: string;
Expand All @@ -103,6 +109,7 @@ export const PhoneInput = forwardRef<PhoneInputRefType, PhoneInputProps>(
countries = defaultCountries,
hideDropdown,
showDisabledDialCodeAndPrefix,
disableFocusAfterCountrySelect,
flags,

style,
Expand Down Expand Up @@ -177,7 +184,11 @@ export const PhoneInput = forwardRef<PhoneInputRefType, PhoneInputProps>(
style={style}
>
<CountrySelector
onSelect={(country) => setCountry(country.iso2)}
onSelect={(country) =>
setCountry(country.iso2, {
focusOnInput: !disableFocusAfterCountrySelect,
})
}
flags={flags}
selectedCountry={country.iso2}
countries={countries}
Expand Down
17 changes: 11 additions & 6 deletions src/hooks/usePhoneInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,10 @@ export const usePhoneInput = ({
return value;
};

const setNewCountry = (countryIso2: CountryIso2) => {
const setCountry = (
countryIso2: CountryIso2,
options = { focusOnInput: false },
) => {
const newCountry = getCountry({
value: countryIso2,
field: 'iso2',
Expand All @@ -335,10 +338,12 @@ export const usePhoneInput = ({
country: newCountry.iso2,
});

// Next tick is used to support UI libraries (had an issue with MUI)
Promise.resolve().then(() => {
inputRef.current?.focus();
});
if (options.focusOnInput) {
// Next tick is used to support UI libraries (had an issue with MUI)
Promise.resolve().then(() => {
inputRef.current?.focus();
});
}
};

const [initialized, setInitialized] = useState(false);
Expand Down Expand Up @@ -388,7 +393,7 @@ export const usePhoneInput = ({
phone, // Phone in E164 format
inputValue, // Formatted phone string. Value that should be rendered inside input element.
country: fullCountry, // Current country object.
setCountry: setNewCountry, // Country setter.
setCountry, // Country setter.
handlePhoneValueChange, // Change handler for input component
inputRef, // Ref object for input component (handles caret position, focus and undo/redo).
};
Expand Down

2 comments on commit b62f3d0

@vercel
Copy link

@vercel vercel bot commented on b62f3d0 Jan 11, 2024

Choose a reason for hiding this comment

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

@vercel
Copy link

@vercel vercel bot commented on b62f3d0 Jan 11, 2024

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.