diff --git a/.changeset/phone-number-input-should-display-country-names.md b/.changeset/phone-number-input-should-display-country-names.md new file mode 100644 index 0000000000..8a9f141412 --- /dev/null +++ b/.changeset/phone-number-input-should-display-country-names.md @@ -0,0 +1,5 @@ +--- +'@sumup-oss/circuit-ui': minor +--- + +Added `shouldDisplayCountryNames` prop to `PhoneNumberInput` to opt out of `Intl.DisplayNames` localization and display calling codes from `countryCode.options` directly. diff --git a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.stories.tsx b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.stories.tsx index 1967029c13..5f177f1a8b 100644 --- a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.stories.tsx +++ b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.stories.tsx @@ -168,6 +168,15 @@ export const WithPrefix = (args: PhoneNumberInputProps) => { WithPrefix.args = Base.args; +export const WithoutCountryNames = (args: PhoneNumberInputProps) => ( + +); + +WithoutCountryNames.args = { + ...Base.args, + shouldDisplayCountryNames: false, +}; + export const Sizes = (args: PhoneNumberInputProps) => ( diff --git a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.tsx b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.tsx index c0b0217caa..d2788a27da 100644 --- a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.tsx +++ b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.tsx @@ -117,6 +117,14 @@ export interface PhoneNumberInputProps * preselected country code. Defaults to `navigator.languages`. */ locale?: string | string[]; + /** + * When `true`, localizes country names in the country code selector using + * `Intl.DisplayNames`. When `false`, displays the calling codes from + * `countryCode.options` without localization. + * + * @default true + */ + shouldDisplayCountryNames?: boolean; /** * Choose from 2 sizes. * @default m @@ -232,6 +240,7 @@ export const PhoneNumberInput = forwardRef< readOnly, 'aria-describedby': descriptionId, locale, + shouldDisplayCountryNames = true, size = 'm', className, style, @@ -257,8 +266,13 @@ export const PhoneNumberInput = forwardRef< ); const options = useMemo( - () => mapCountryCodeOptions(countryCode.options, locale), - [countryCode.options, locale], + () => + mapCountryCodeOptions( + countryCode.options, + locale, + shouldDisplayCountryNames, + ), + [countryCode.options, locale, shouldDisplayCountryNames], ); const handleChange = () => { diff --git a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.spec.ts b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.spec.ts index 8ffa95ae0c..8144eedc9d 100644 --- a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.spec.ts +++ b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.spec.ts @@ -182,5 +182,30 @@ describe('PhoneNumberInputService', () => { const actual = mapCountryCodeOptions(options, locale); expect(actual[0].value).toBe('DE'); }); + + it('should use calling codes as labels when shouldDisplayCountryNames is false', () => { + const options = [ + { country: 'CA', code: '+1' }, + { country: 'US', code: '+1' }, + { country: 'DE', code: '+49' }, + ]; + const actual = mapCountryCodeOptions(options, undefined, false); + expect(actual[0].label).toBe('+1'); + expect(actual[0].value).toBe('CA'); + expect(actual[1].label).toBe('+1'); + expect(actual[1].value).toBe('US'); + expect(actual[2].label).toBe('+49'); + expect(actual[2].value).toBe('DE'); + }); + + it('should sort calling code labels when shouldDisplayCountryNames is false', () => { + const options = [ + { country: 'DE', code: '+49' }, + { country: 'CA', code: '+1' }, + { country: 'US', code: '+1' }, + ]; + const actual = mapCountryCodeOptions(options, undefined, false); + expect(actual.map(({ label }) => label)).toEqual(['+1', '+1', '+49']); + }); }); }); diff --git a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.ts b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.ts index 030170c404..3cc48bf950 100644 --- a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.ts +++ b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.ts @@ -132,7 +132,17 @@ export function normalizePhoneNumber( export function mapCountryCodeOptions( countryCodeOptions: CountryCodeOption[], locale: Locale | undefined, + shouldDisplayCountryNames = true, ): Required['options'] { + if (!shouldDisplayCountryNames) { + return countryCodeOptions + .map(({ code, country }) => ({ + label: code, + value: country, + })) + .sort((a, b) => a.label.localeCompare(b.label)); + } + const getCountryName = (country: string) => { // eslint-disable-next-line compat/compat const isIntlDisplayNamesSupported = typeof Intl.DisplayNames === 'function';