1
1
import {
2
2
$ ,
3
3
component$ ,
4
- HTMLAttributes ,
5
4
type QRL ,
6
5
useSignal ,
7
6
useStylesScoped$ ,
@@ -19,11 +18,12 @@ import {
19
18
} from 'libphonenumber-js' ;
20
19
import type { CountryCode } from 'libphonenumber-js' ;
21
20
import { countries , type CountryListItemType } from 'country-list-json' ;
21
+ import { timezoneCityToCountry } from './timezone-city-to-country' ;
22
22
import styles from './input-phone.css?inline' ;
23
23
24
24
export type InputPhoneProps = QwikIntrinsicElements [ 'div' ] & {
25
25
value ?: string ;
26
- countryCode ?: CountryCode ;
26
+ countryCode ?: CountryCode | 'auto' ;
27
27
onCountryChange$ ?: QRL < ( country ?: InputPhoneCountry ) => void > ;
28
28
onNumberChange$ ?: QRL < ( phone : string ) => void > ;
29
29
onValidChange$ ?: QRL < ( validity : InputPhoneValidity ) => void > ;
@@ -83,6 +83,30 @@ export const findBySelectValue = (value: string) => {
83
83
return find ( ( { name, dial_code } ) => value === `${ name } (${ dial_code } )` ) ;
84
84
} ;
85
85
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
+
86
110
export const InputPhone = component$ (
87
111
( {
88
112
countryCode,
@@ -94,7 +118,10 @@ export const InputPhone = component$(
94
118
...props
95
119
} : InputPhoneProps ) => {
96
120
useStylesScoped$ ( styles ) ;
97
- const defaultCountry = find ( countryCode , 'code' ) ;
121
+ const defaultCountry =
122
+ countryCode === 'auto'
123
+ ? findCountryByUserTimezone ( )
124
+ : find ( countryCode , 'code' ) ;
98
125
99
126
const inputRefSignal = useSignal < HTMLInputElement > ( ) ;
100
127
const selectRefSignal = useSignal < HTMLSelectElement > ( ) ;
0 commit comments