0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-30 20:33:54 -05:00

fix(experience): smart input field should have correct initial type (#6477)

This commit is contained in:
Xiao Yijun 2024-08-20 17:24:30 +08:00 committed by GitHub
parent d4674833c8
commit 818e2c61f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 61 additions and 38 deletions

View file

@ -7,6 +7,8 @@ import useUpdateEffect from '@/hooks/use-update-effect';
import { getDefaultCountryCallingCode } from '@/utils/country-code';
import { parseIdentifierValue } from '@/utils/form';
import { detectIdentifierType } from './utils';
export type IdentifierInputType =
| SignInIdentifier.Email
| SignInIdentifier.Phone
@ -24,8 +26,6 @@ export type IdentifierInputValue = {
value: string;
};
const digitsRegex = /^\d*$/;
type Props = {
defaultValue?: string;
_defaultType?: IdentifierInputType;
@ -56,7 +56,14 @@ const useSmartInputField = ({ _defaultType, defaultValue, enabledTypes }: Props)
[defaultType, defaultValue]
);
const [currentType, setCurrentType] = useState(defaultType);
const [currentType, setCurrentType] = useState(
detectIdentifierType({
value: defaultValue ?? '',
enabledTypeSet,
defaultType,
currentType: defaultType,
})
);
const [countryCode, setCountryCode] = useState<string>(
defaultCountryCode ?? getDefaultCountryCallingCode()
@ -65,41 +72,7 @@ const useSmartInputField = ({ _defaultType, defaultValue, enabledTypes }: Props)
const [inputValue, setInputValue] = useState<string>(defaultInputValue ?? '');
const detectInputType = useCallback(
(value: string) => {
// Reset InputType
if (!value && enabledTypeSet.size > 1) {
return;
}
if (enabledTypeSet.size === 1) {
return defaultType;
}
const hasAtSymbol = value.includes('@');
const isAllDigits = digitsRegex.test(value);
if (enabledTypeSet.has(SignInIdentifier.Phone) && value.length >= 3 && isAllDigits) {
return SignInIdentifier.Phone;
}
if (enabledTypeSet.has(SignInIdentifier.Email) && hasAtSymbol) {
return SignInIdentifier.Email;
}
if (currentType === SignInIdentifier.Phone && isAllDigits) {
return SignInIdentifier.Phone;
}
if (enabledTypeSet.has(SignInIdentifier.Username)) {
return SignInIdentifier.Username;
}
if (enabledTypeSet.has(SignInIdentifier.Email)) {
return SignInIdentifier.Email;
}
return currentType;
},
(value: string) => detectIdentifierType({ value, enabledTypeSet, defaultType, currentType }),
[defaultType, currentType, enabledTypeSet]
);

View file

@ -40,3 +40,53 @@ export const getInputHtmlProps = (
label: enabledTypes.map((type) => i18next.t(identifierInputPlaceholderMap[type])).join(' / '),
};
};
const digitsRegex = /^\d*$/;
type DetectIdentifierTypeParams = {
value: string;
enabledTypeSet: Set<IdentifierInputType>;
defaultType?: IdentifierInputType;
currentType?: IdentifierInputType;
};
export const detectIdentifierType = ({
value,
enabledTypeSet,
defaultType,
currentType,
}: DetectIdentifierTypeParams) => {
// Reset InputType
if (!value && enabledTypeSet.size > 1) {
return;
}
if (enabledTypeSet.size === 1) {
return defaultType;
}
const hasAtSymbol = value.includes('@');
const isAllDigits = digitsRegex.test(value);
if (enabledTypeSet.has(SignInIdentifier.Phone) && value.length >= 3 && isAllDigits) {
return SignInIdentifier.Phone;
}
if (enabledTypeSet.has(SignInIdentifier.Email) && hasAtSymbol) {
return SignInIdentifier.Email;
}
if (currentType === SignInIdentifier.Phone && isAllDigits) {
return SignInIdentifier.Phone;
}
if (enabledTypeSet.has(SignInIdentifier.Username)) {
return SignInIdentifier.Username;
}
if (enabledTypeSet.has(SignInIdentifier.Email)) {
return SignInIdentifier.Email;
}
return currentType;
};