0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

fix(experience): correct active state for input field (#6255)

This commit is contained in:
Xiao Yijun 2024-07-16 21:59:39 +08:00 committed by GitHub
parent 0a9da5245b
commit a84389da13
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,7 +1,15 @@
import { type Nullable } from '@silverhand/essentials';
import classNames from 'classnames';
import type { HTMLProps, ReactElement, Ref } from 'react';
import { forwardRef, cloneElement, useState, useImperativeHandle, useRef, useEffect } from 'react';
import type { HTMLProps, ReactElement, Ref, AnimationEvent } from 'react';
import {
forwardRef,
cloneElement,
useState,
useImperativeHandle,
useRef,
useEffect,
useCallback,
} from 'react';
import ErrorMessage from '@/components/ErrorMessage';
@ -47,33 +55,25 @@ const InputField = (
const [isFocused, setIsFocused] = useState(false);
const [hasValue, setHasValue] = useState(false);
const hasContent =
Boolean(isPrefixVisible) ||
hasValue ||
// Handle the case when this filed have a default value
Boolean(value);
const isActive = hasContent || isFocused;
useEffect(() => {
const inputDom = innerRef.current;
if (!inputDom) {
return;
}
/**
* Should listen to the value prop to update the hasValue state.
*/
setHasValue(Boolean(value));
}, [value]);
/**
* Use a timeout to check if the input field has autofill value.
* Fix the issue that the input field doesn't have the active style when the autofill value is set.
* see https://github.com/facebook/react/issues/1159#issuecomment-1025423604
* Modern browsers will trigger an animation event when the input field is autofilled.
*/
const checkAutoFillTimeout = setTimeout(() => {
setHasValue(inputDom.matches('*:-webkit-autofill'));
}, 200);
const handleAnimationStart = useCallback((event: AnimationEvent<HTMLInputElement>) => {
if (event.animationName === 'onautofillstart') {
setHasValue(true);
}
}, []);
return () => {
clearTimeout(checkAutoFillTimeout);
};
}, [innerRef]);
const isActive = Boolean(isPrefixVisible) || hasValue || isFocused;
return (
<div className={className}>
@ -97,6 +97,7 @@ const InputField = (
{...props}
ref={innerRef}
value={value}
onAnimationStart={handleAnimationStart}
onFocus={(event) => {
setIsFocused(true);
return onFocus?.(event);