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:
parent
0a9da5245b
commit
a84389da13
1 changed files with 25 additions and 24 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Should listen to the value prop to update the hasValue state.
|
||||
*/
|
||||
const checkAutoFillTimeout = setTimeout(() => {
|
||||
setHasValue(inputDom.matches('*:-webkit-autofill'));
|
||||
}, 200);
|
||||
setHasValue(Boolean(value));
|
||||
}, [value]);
|
||||
|
||||
return () => {
|
||||
clearTimeout(checkAutoFillTimeout);
|
||||
};
|
||||
}, [innerRef]);
|
||||
/**
|
||||
* Fix the issue that the input field doesn't have the active style when the autofill value is set.
|
||||
* Modern browsers will trigger an animation event when the input field is autofilled.
|
||||
*/
|
||||
const handleAnimationStart = useCallback((event: AnimationEvent<HTMLInputElement>) => {
|
||||
if (event.animationName === 'onautofillstart') {
|
||||
setHasValue(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue