@@ -10,6 +10,7 @@ import type {
1010 SignInCreateParams ,
1111 SignInResource ,
1212} from '@clerk/shared/types' ;
13+ import type { CountryIso } from '@/ui/elements/PhoneInput/countryCodeData' ;
1314import { isWebAuthnAutofillSupported , isWebAuthnSupported } from '@clerk/shared/webauthn' ;
1415import { useEffect , useLayoutEffect , useMemo , useRef , useState } from 'react' ;
1516
@@ -33,7 +34,7 @@ import {
3334 withRedirectToSignInTask ,
3435} from '../../common' ;
3536import { useCoreSignIn , useEnvironment , useSignInContext } from '../../contexts' ;
36- import { Col , descriptors , Flow , localizationKeys } from '../../customizables' ;
37+ import { Col , descriptors , Flow , localizationKeys , useAppearance } from '../../customizables' ;
3738import { CaptchaElement } from '../../elements/CaptchaElement' ;
3839import { useLoadingStatus } from '../../hooks' ;
3940import { useSupportEmail } from '../../hooks/useSupportEmail' ;
@@ -88,6 +89,7 @@ function SignInStartInternal(): JSX.Element {
8889 const ctx = useSignInContext ( ) ;
8990 const { afterSignInUrl, signUpUrl, waitlistUrl, isCombinedFlow, navigateOnSetActive } = ctx ;
9091 const supportEmail = useSupportEmail ( ) ;
92+ const { parsedOptions } = useAppearance ( ) ;
9193 const totalEnabledAuthMethods = useTotalEnabledAuthMethods ( ) ;
9294 const identifierAttributes = useMemo < SignInStartIdentifier [ ] > (
9395 ( ) => groupIdentifiers ( userSettings . enabledFirstFactorIdentifiers ) ,
@@ -103,13 +105,46 @@ function SignInStartInternal(): JSX.Element {
103105 const authenticateWithPasskey = useHandleAuthenticateWithPasskey ( onSecondFactor ) ;
104106 const isWebSupported = isWebAuthnSupported ( ) ;
105107
106- const onlyPhoneNumberInitialValueExists =
107- ! ! ctx . initialValues ?. phoneNumber && ! ( ctx . initialValues . emailAddress || ctx . initialValues . username ) ;
108- const shouldStartWithPhoneNumberIdentifier =
109- onlyPhoneNumberInitialValueExists && identifierAttributes . includes ( 'phone_number' ) ;
110- const [ identifierAttribute , setIdentifierAttribute ] = useState < SignInStartIdentifier > (
111- shouldStartWithPhoneNumberIdentifier ? 'phone_number' : identifierAttributes [ 0 ] || '' ,
112- ) ;
108+ const resolveInitialIdentifier = ( ) : SignInStartIdentifier => {
109+ const iv = ctx . initialValues ;
110+
111+ const mapToIdentifierAttribute = ( key : string ) : SignInStartIdentifier | undefined => {
112+ if ( key === 'phoneNumber' ) {
113+ return identifierAttributes . includes ( 'phone_number' ) ? 'phone_number' : undefined ;
114+ }
115+ if ( key === 'emailAddress' ) {
116+ if ( identifierAttributes . includes ( 'email_address' ) ) return 'email_address' ;
117+ if ( identifierAttributes . includes ( 'email_address_username' ) ) return 'email_address_username' ;
118+ return undefined ;
119+ }
120+ if ( key === 'username' ) {
121+ if ( identifierAttributes . includes ( 'email_address_username' ) ) return 'email_address_username' ;
122+ if ( identifierAttributes . includes ( 'username' ) ) return 'username' ;
123+ return undefined ;
124+ }
125+ return undefined ;
126+ } ;
127+
128+ const filledValues = [
129+ iv ?. emailAddress && 'emailAddress' ,
130+ iv ?. phoneNumber && 'phoneNumber' ,
131+ iv ?. username && 'username' ,
132+ ] . filter ( Boolean ) as string [ ] ;
133+
134+ if ( filledValues . length === 1 ) {
135+ const mapped = mapToIdentifierAttribute ( filledValues [ 0 ] ) ;
136+ if ( mapped ) return mapped ;
137+ }
138+
139+ if ( parsedOptions . preferredSignInIdentifier ) {
140+ const mapped = mapToIdentifierAttribute ( parsedOptions . preferredSignInIdentifier ) ;
141+ if ( mapped ) return mapped ;
142+ }
143+
144+ return identifierAttributes [ 0 ] || '' ;
145+ } ;
146+
147+ const [ identifierAttribute , setIdentifierAttribute ] = useState < SignInStartIdentifier > ( resolveInitialIdentifier ) ;
113148 const [ hasSwitchedByAutofill , setHasSwitchedByAutofill ] = useState ( false ) ;
114149
115150 const organizationTicket = getClerkQueryParam ( '__clerk_ticket' ) || '' ;
@@ -596,6 +631,9 @@ function SignInStartInternal(): JSX.Element {
596631 actionLabel = { nextIdentifier ?. action }
597632 onActionClicked = { switchToNextIdentifier }
598633 { ...identifierFieldProps }
634+ defaultCountryIso = {
635+ ctx . initialValues ?. phoneNumberCountryCode ?. toLowerCase ( ) as CountryIso | undefined
636+ }
599637 autoFocus = { shouldAutofocus }
600638 autoComplete = { isWebAuthnAutofillSupported ? 'webauthn' : undefined }
601639 isLastAuthenticationStrategy = { isIdentifierLastAuthenticationStrategy }
@@ -650,6 +688,7 @@ function SignInStartInternal(): JSX.Element {
650688 phoneNumberFormState = { phoneIdentifierField }
651689 onUseAnotherMethod = { onAlternativePhoneCodeUseAnotherMethod }
652690 phoneCodeProvider = { alternativePhoneCodeProvider }
691+ defaultCountryIso = { ctx . initialValues ?. phoneNumberCountryCode ?. toLowerCase ( ) as CountryIso | undefined }
653692 />
654693 ) }
655694 </ Flow . Part >
0 commit comments