Skip to content

Commit 91af379

Browse files
authored
feat: auto country code (#249)
* docs: add auto & unset countryCode InputPhone * feat: add auto countryCode based on user timezone
1 parent 8c8b1aa commit 91af379

File tree

3 files changed

+481
-4
lines changed

3 files changed

+481
-4
lines changed

apps/website/src/routes/docs/headless/input-phone/index.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,32 @@ export default component$(() => {
3232

3333
<h2>Input Phone Example</h2>
3434

35+
<h3>countryCode set to FR</h3>
36+
3537
<div class="form-item">
3638
<InputPhone
3739
countryCode="FR"
38-
value="06486254"
40+
value="0645678990"
41+
placeholder="Type your phone number"
42+
/>
43+
</div>
44+
45+
<hr />
46+
47+
<h3>countryCode unset</h3>
48+
49+
<div class="form-item">
50+
<InputPhone value="0645678990" placeholder="Type your phone number" />
51+
</div>
52+
53+
<hr />
54+
55+
<h3>countryCode set to auto</h3>
56+
57+
<div class="form-item">
58+
<InputPhone
59+
countryCode="auto"
60+
value="0481163"
3961
placeholder="Type your phone number"
4062
onCountryChange$={$((value?: InputPhoneCountry) => {
4163
country.value = value;

packages/headless/src/components/input-phone/input-phone.tsx

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
$,
33
component$,
4-
HTMLAttributes,
54
type QRL,
65
useSignal,
76
useStylesScoped$,
@@ -19,11 +18,12 @@ import {
1918
} from 'libphonenumber-js';
2019
import type { CountryCode } from 'libphonenumber-js';
2120
import { countries, type CountryListItemType } from 'country-list-json';
21+
import { timezoneCityToCountry } from './timezone-city-to-country';
2222
import styles from './input-phone.css?inline';
2323

2424
export type InputPhoneProps = QwikIntrinsicElements['div'] & {
2525
value?: string;
26-
countryCode?: CountryCode;
26+
countryCode?: CountryCode | 'auto';
2727
onCountryChange$?: QRL<(country?: InputPhoneCountry) => void>;
2828
onNumberChange$?: QRL<(phone: string) => void>;
2929
onValidChange$?: QRL<(validity: InputPhoneValidity) => void>;
@@ -83,6 +83,30 @@ export const findBySelectValue = (value: string) => {
8383
return find(({ name, dial_code }) => value === `${name} (${dial_code})`);
8484
};
8585

86+
/**
87+
* Retrieve the dial country code in CountryItem by using the user's timezone
88+
* @returns CountryItem | undefined
89+
*/
90+
export const findCountryByUserTimezone = () => {
91+
if (!Intl) {
92+
console.warn(
93+
'We cannot automatically retrieve the country of the user because Intl is not supported.'
94+
);
95+
return;
96+
}
97+
98+
const userTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
99+
const city = userTimeZone.split('/').at(-1) as string;
100+
const country = timezoneCityToCountry[city];
101+
102+
// look into the city and country's name,
103+
// e.g. Reunion (as city) the country's name is Réunion
104+
// but only Reunion exists in country-list-json
105+
return countries.find(({ name }) => name === city || name === country) as
106+
| CountryItem
107+
| undefined;
108+
};
109+
86110
export const InputPhone = component$(
87111
({
88112
countryCode,
@@ -94,7 +118,10 @@ export const InputPhone = component$(
94118
...props
95119
}: InputPhoneProps) => {
96120
useStylesScoped$(styles);
97-
const defaultCountry = find(countryCode, 'code');
121+
const defaultCountry =
122+
countryCode === 'auto'
123+
? findCountryByUserTimezone()
124+
: find(countryCode, 'code');
98125

99126
const inputRefSignal = useSignal<HTMLInputElement>();
100127
const selectRefSignal = useSignal<HTMLSelectElement>();

0 commit comments

Comments
 (0)