mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-11-30 11:08:45 +08:00
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:
parent
bcd32305bb
commit
e65a18899b
@ -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}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user