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:
parent
d4674833c8
commit
818e2c61f2
2 changed files with 61 additions and 38 deletions
|
@ -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]
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue