diff --git a/.changeset/two-horses-fold.md b/.changeset/two-horses-fold.md
new file mode 100644
index 0000000000..2c4afdb1ff
--- /dev/null
+++ b/.changeset/two-horses-fold.md
@@ -0,0 +1,5 @@
+---
+'@sumup/circuit-ui': minor
+---
+
+Use the country code instead of the phone prefix as the value of the PhoneNumberInput component's country code select. This is an implementation detail, but might require changes to unit tests that query the country code select.
diff --git a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.spec.tsx b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.spec.tsx
index 4fa77700bf..c1f5eb381e 100644
--- a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.spec.tsx
+++ b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.spec.tsx
@@ -25,8 +25,9 @@ import {
} from './PhoneNumberInput.js';
const countryCodeMap: { [key: string]: string } = {
- '+1': 'US',
- '+49': 'DE',
+ CA: '+1',
+ US: '+1',
+ DE: '+49',
};
const defaultProps = {
@@ -35,8 +36,8 @@ const defaultProps = {
label: 'Country code',
defaultValue: '+1',
options: Object.keys(countryCodeMap).map((key) => ({
- country: countryCodeMap[key],
- code: key,
+ country: key,
+ code: countryCodeMap[key],
})),
},
subscriberNumber: {
@@ -85,7 +86,7 @@ describe('PhoneNumberInput', () => {
};
render();
const select = screen.getByRole('combobox');
- await userEvent.selectOptions(select, '+49');
+ await userEvent.selectOptions(select, 'DE');
expect(onChange).toHaveBeenCalledOnce();
});
@@ -100,7 +101,7 @@ describe('PhoneNumberInput', () => {
};
render();
const select = screen.getByRole('combobox');
- await userEvent.selectOptions(select, '+49');
+ await userEvent.selectOptions(select, 'DE');
expect(onChange).toHaveBeenCalledOnce();
});
diff --git a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.stories.tsx b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.stories.tsx
index 966dcc8088..9dd5381c68 100644
--- a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.stories.tsx
+++ b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.stories.tsx
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-import { FlagDe, FlagUs, type IconComponentType } from '@sumup/icons';
+import { FlagCa, FlagDe, FlagUs, type IconComponentType } from '@sumup/icons';
import { useState } from 'react';
import { action } from '@storybook/addon-actions';
@@ -33,13 +33,15 @@ export default {
};
const flagIconMap: { [key: string]: IconComponentType<'16'> } = {
- DE: FlagDe,
+ CA: FlagCa,
US: FlagUs,
+ DE: FlagDe,
};
const countryCodeMap: { [key: string]: string } = {
- '+1': 'US',
- '+49': 'DE',
+ CA: '+1',
+ US: '+1',
+ DE: '+49',
};
export const Base = (args: PhoneNumberInputProps) => (
@@ -52,8 +54,8 @@ Base.args = {
label: 'Country code',
defaultValue: '+1',
options: Object.keys(countryCodeMap).map((key) => ({
- country: countryCodeMap[key],
- code: key,
+ country: key,
+ code: countryCodeMap[key],
})),
},
subscriberNumber: {
@@ -125,14 +127,14 @@ Disabled.args = {
};
export const WithPrefix = (args: PhoneNumberInputProps) => {
- const [selectedCountry, setSelectedCountry] = useState('US');
+ const [selectedCountry, setSelectedCountry] = useState('CA');
return (
{
- setSelectedCountry(countryCodeMap[event.target.value]);
+ setSelectedCountry(event.target.value);
},
renderPrefix: (props) => {
const Icon = flagIconMap[selectedCountry];
diff --git a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.tsx b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.tsx
index 3aa8bcc1c6..caef5886ac 100644
--- a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.tsx
+++ b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInput.tsx
@@ -240,8 +240,20 @@ export const PhoneNumberInput = forwardRef<
) {
return;
}
+
+ const selectedCountry = countryCodeRef?.current?.value;
+ if (!selectedCountry) {
+ return;
+ }
+ const code = countryCode.options.find(
+ ({ country }) => country === selectedCountry,
+ )?.code;
+
+ if (!code) {
+ return;
+ }
const phoneNumber = normalizePhoneNumber(
- countryCodeRef.current.value,
+ code,
subscriberNumberRef.current.value,
);
onChange(phoneNumber);
@@ -273,21 +285,20 @@ export const PhoneNumberInput = forwardRef<
return;
}
- const pastedCountryCode = countryCode.options
- .map((option) => option.code)
+ const pastedOption = countryCode.options
// Match longer, more specific country codes first
- .sort((a, b) => b.length - a.length)
- .find((code) => pastedText.startsWith(code));
+ .sort((a, b) => b.code.length - a.code.length)
+ .find(({ code }) => pastedText.startsWith(code));
- if (!pastedCountryCode) {
+ if (!pastedOption) {
return;
}
event.preventDefault();
- const pastedSubscriberNumber = pastedText.split(pastedCountryCode)[1];
+ const pastedSubscriberNumber = pastedText.split(pastedOption.code)[1];
- countryCodeRef.current.value = pastedCountryCode;
+ countryCodeRef.current.value = pastedOption.country;
// React overwrites the input.value setter. In order to be able to trigger
// a 'change' event on the input, we need to use the native setter.
diff --git a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.spec.ts b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.spec.ts
index acecc17410..58dc62a91e 100644
--- a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.spec.ts
+++ b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.spec.ts
@@ -52,24 +52,28 @@ describe('PhoneNumberInputService', () => {
});
describe('mapCountryCodeOptions', () => {
- it('should use the country code as the option value', () => {
+ it('should use the country as the option value', () => {
const options = [
+ { country: 'CA', code: '+1' },
{ country: 'US', code: '+1' },
{ country: 'DE', code: '+49' },
];
const actual = mapCountryCodeOptions(options);
- expect(actual[0].value).toBe('+49');
- expect(actual[1].value).toBe('+1');
+ expect(actual[0].value).toBe('CA');
+ expect(actual[1].value).toBe('DE');
+ expect(actual[2].value).toBe('US');
});
it('should use the country name and code as the option label', () => {
const options = [
+ { country: 'CA', code: '+1' },
{ country: 'US', code: '+1' },
{ country: 'DE', code: '+49' },
];
const actual = mapCountryCodeOptions(options);
- expect(actual[0].label).toBe('Germany (+49)');
- expect(actual[1].label).toBe('United States (+1)');
+ expect(actual[0].label).toBe('Canada (+1)');
+ expect(actual[1].label).toBe('Germany (+49)');
+ expect(actual[2].label).toBe('United States (+1)');
});
it('should omit the country name when it is not available', () => {
@@ -80,22 +84,24 @@ describe('PhoneNumberInputService', () => {
it('should sort the options alphabetically', () => {
const options = [
+ { country: 'CA', code: '+1' },
{ country: 'US', code: '+1' },
{ country: 'DE', code: '+49' },
];
const actual = mapCountryCodeOptions(options);
- expect(actual[0].label).toBe('Germany (+49)');
- expect(actual[1].label).toBe('United States (+1)');
+ expect(actual[0].label).toBe('Canada (+1)');
+ expect(actual[1].label).toBe('Germany (+49)');
+ expect(actual[2].label).toBe('United States (+1)');
});
it('should use the locale as the default country code', () => {
const options = [
+ { country: 'CA', code: '+1' },
{ country: 'US', code: '+1' },
{ country: 'DE', code: '+49' },
- { country: 'CA', code: '+1' },
];
const actual = mapCountryCodeOptions(options, 'DE');
- expect(actual[0].value).toBe('+49');
+ expect(actual[0].value).toBe('DE');
});
});
});
diff --git a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.ts b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.ts
index e78b011571..8a8f0355f5 100644
--- a/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.ts
+++ b/packages/circuit-ui/components/PhoneNumberInput/PhoneNumberInputService.ts
@@ -49,7 +49,7 @@ export function mapCountryCodeOptions(
const countryName = displayName.of(country);
return {
label: countryName ? `${countryName} (${code})` : code,
- value: code,
+ value: country,
};
})
.sort((a, b) => a.label.localeCompare(b.label));