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 { type Nullable } from '@silverhand/essentials';
import classNames from 'classnames'; import classNames from 'classnames';
import type { HTMLProps, ReactElement, Ref } from 'react'; import type { HTMLProps, ReactElement, Ref, AnimationEvent } from 'react';
import { forwardRef, cloneElement, useState, useImperativeHandle, useRef, useEffect } from 'react'; import {
forwardRef,
cloneElement,
useState,
useImperativeHandle,
useRef,
useEffect,
useCallback,
} from 'react';
import ErrorMessage from '@/components/ErrorMessage'; import ErrorMessage from '@/components/ErrorMessage';
@ -47,33 +55,25 @@ const InputField = (
const [isFocused, setIsFocused] = useState(false); const [isFocused, setIsFocused] = useState(false);
const [hasValue, setHasValue] = 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(() => { useEffect(() => {
const inputDom = innerRef.current; /**
if (!inputDom) { * Should listen to the value prop to update the hasValue state.
return; */
} 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. * 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(() => { const handleAnimationStart = useCallback((event: AnimationEvent<HTMLInputElement>) => {
setHasValue(inputDom.matches('*:-webkit-autofill')); if (event.animationName === 'onautofillstart') {
}, 200); setHasValue(true);
}
}, []);
return () => { const isActive = Boolean(isPrefixVisible) || hasValue || isFocused;
clearTimeout(checkAutoFillTimeout);
};
}, [innerRef]);
return ( return (
<div className={className}> <div className={className}>
@ -97,6 +97,7 @@ const InputField = (
{...props} {...props}
ref={innerRef} ref={innerRef}
value={value} value={value}
onAnimationStart={handleAnimationStart}
onFocus={(event) => { onFocus={(event) => {
setIsFocused(true); setIsFocused(true);
return onFocus?.(event); return onFocus?.(event);