Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(date): prevent multiple instances of date picker opening at the same time #6937

Merged
merged 2 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 35 additions & 20 deletions src/components/date/date.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import DatePicker, { PickerProps } from "./__internal__/date-picker";
import DateRangeContext, {
InputName,
} from "../date-range/__internal__/date-range.context";
import useClickAwayListener from "../../hooks/__internal__/useClickAwayListener";
import useFormSpacing from "../../hooks/__internal__/useFormSpacing";
import guid from "../../__internal__/utils/helpers/guid";

Expand Down Expand Up @@ -139,6 +138,7 @@ export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(
const alreadyFocused = useRef(false);
const isBlurBlocked = useRef(false);
const focusedViaPicker = useRef(false);
const blockClose = useRef(false);
const locale = useLocale();
const { dateFnsLocale } = locale.date;
const { format, formats } = useMemo(() => getFormatData(dateFnsLocale()), [
Expand Down Expand Up @@ -187,21 +187,30 @@ export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(
return customEvent;
};

const handleClickAway = () => {
if (open) {
alreadyFocused.current = true;
internalInputRef.current?.focus();
isBlurBlocked.current = false;
internalInputRef.current?.blur();
setOpen(false);
alreadyFocused.current = false;
}
};
// Add custom listener to prevent issues with regards to double calls within the Date component
// This is a temporary fix until the Date component is refactored more info can be found:
// TODO: FE-6757
useEffect(() => {
const handleClick = () => {
if (!blockClose.current) {
if (open) {
alreadyFocused.current = true;
internalInputRef.current?.focus();
isBlurBlocked.current = false;
internalInputRef.current?.blur();
setOpen(false);
alreadyFocused.current = false;
}
} else {
blockClose.current = false;
}
};
document.addEventListener("mousedown", handleClick);

const handleClickInside = useClickAwayListener(
handleClickAway,
"mousedown"
);
return function cleanup() {
document.removeEventListener("mousedown", handleClick);
};
}, [open]);

const handleChange = (ev: React.ChangeEvent<HTMLInputElement>) => {
isInitialValue.current = false;
Expand Down Expand Up @@ -284,7 +293,9 @@ export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(
isBlurBlocked.current = false;

if (!open && !alreadyFocused.current) {
setOpen(true);
setTimeout(() => {
setOpen(true);
}, 0);
} else {
alreadyFocused.current = false;
}
Expand Down Expand Up @@ -332,7 +343,7 @@ export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(
};

const handleMouseDown = (ev: React.MouseEvent<HTMLElement>) => {
handleClickInside();
blockClose.current = true;

if (setInputRefMap) {
isBlurBlocked.current = true;
Expand All @@ -342,9 +353,13 @@ export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(

if (type !== "text") {
alreadyFocused.current = true;
setOpen((prev) => !prev);
setTimeout(() => {
setOpen((prev) => !prev);
}, 0);
} else if (!open) {
setOpen(true);
setTimeout(() => {
setOpen(true);
}, 0);
}
};

Expand All @@ -355,7 +370,7 @@ export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(

const handlePickerMouseDown = () => {
isBlurBlocked.current = true;
handleClickInside();
blockClose.current = true;
};

const assignInput = useCallback(
Expand Down
Loading