feat[float-button]: add clickOutAutoClose feature (#39501)

* feat[float-button]: add clickOutAutoClose feature

* feat: change sourcecode

* fix: lint ts error

* test: add clickOutAutoClose test

* chore: function rename

* fix: bug

* fix: add dep

* fix: solve lint

* remove clickOutAutoClose api

* chore:format

* 还原md

* Update group-menu.md

* Update FloatButtonGroup.tsx

Co-authored-by: lijianan <574980606@qq.com>
This commit is contained in:
2022-12-14 13:51:57 +08:00 committed by GitHub
parent bcd32305bb
commit e65a18899b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 20 deletions

View File

@ -1,4 +1,4 @@
import React, { useRef, memo, useContext } from 'react';
import React, { useRef, memo, useContext, useEffect, useCallback, useMemo } from 'react';
import CloseOutlined from '@ant-design/icons/CloseOutlined';
import FileTextOutlined from '@ant-design/icons/FileTextOutlined';
import classNames from 'classnames';
@ -41,23 +41,11 @@ const FloatButtonGroup: React.FC<FloatButtonGroupProps> = (props) => {
const [open, setOpen] = useMergedState(false, { value: props.open });
const clickAction = useRef<React.HTMLAttributes<HTMLAnchorElement | HTMLButtonElement>>({});
const floatButtonGroupRef = useRef<HTMLDivElement>(null);
const floatButtonRef = useRef<HTMLButtonElement| HTMLAnchorElement>(null);
const hoverAction = useRef<React.HTMLAttributes<HTMLDivElement>>({});
if (trigger === 'click') {
clickAction.current = {
onClick() {
setOpen((prevState) => {
onOpenChange?.(!prevState);
return !prevState;
});
},
};
}
if (trigger === 'hover') {
hoverAction.current = {
const hoverAction = useMemo(() => {
const hoverTypeAction = {
onMouseEnter() {
setOpen(true);
onOpenChange?.(true);
@ -67,11 +55,42 @@ const FloatButtonGroup: React.FC<FloatButtonGroupProps> = (props) => {
onOpenChange?.(false);
},
};
}
return trigger === 'hover' ? hoverTypeAction : {};
}, [trigger]);
const handleOpenChange = () => {
setOpen((prevState) => {
onOpenChange?.(!prevState);
return !prevState;
});
};
const onClick = useCallback(
(e: MouseEvent) => {
if (floatButtonGroupRef.current!.contains(e.target as Node)) {
if (floatButtonRef.current!.contains(e.target as Node)) {
handleOpenChange();
}
return;
}
setOpen(false);
onOpenChange?.(false);
},
[trigger],
);
useEffect(() => {
if (trigger === 'click') {
document.addEventListener('click', onClick);
return () => {
document.removeEventListener('click', onClick);
};
}
}, [trigger]);
return wrapSSR(
<FloatButtonGroupProvider value={shape}>
<div className={groupCls} style={style} {...hoverAction.current}>
<div ref={floatButtonGroupRef} className={groupCls} style={style} {...hoverAction}>
{trigger && ['click', 'hover'].includes(trigger) ? (
<>
<CSSMotion visible={open} motionName={`${groupPrefixCls}-wrap`}>
@ -80,11 +99,11 @@ const FloatButtonGroup: React.FC<FloatButtonGroupProps> = (props) => {
)}
</CSSMotion>
<FloatButton
ref={floatButtonRef}
type={type}
shape={shape}
icon={open ? closeIcon : icon}
description={description}
{...clickAction.current}
/>
</>
) : (

View File

@ -58,4 +58,30 @@ describe('FloatButtonGroup', () => {
fireEvent.mouseLeave(container.querySelector('.ant-float-btn-group')!);
expect(onOpenChange).toHaveBeenCalled();
});
it('support click floatButtonGroup not close', () => {
const onOpenChange = jest.fn();
const { container } = render(
<FloatButton.Group trigger="click" onOpenChange={onOpenChange}>
<FloatButton />
<FloatButton />
<FloatButton />
</FloatButton.Group>,
);
fireEvent.click(container.querySelector('.ant-float-btn')!);
fireEvent.click(container.querySelector('.ant-float-btn-group')!);
expect(onOpenChange).toHaveBeenCalledTimes(1);
});
it('support click out auto close', () => {
const onOpenChange = jest.fn();
const { container } = render(
<FloatButton.Group trigger="click" onOpenChange={onOpenChange}>
<FloatButton />
<FloatButton />
<FloatButton />
</FloatButton.Group>,
);
fireEvent.click(container.querySelector('.ant-float-btn')!);
fireEvent.click(container);
expect(onOpenChange).toHaveBeenCalledTimes(2);
});
});