import { defineComponent, ref, computed, watch, onBeforeUnmount, Transition } from 'vue'; import CloseOutlined from '@ant-design/icons-vue/CloseOutlined'; import FileTextOutlined from '@ant-design/icons-vue/FileTextOutlined'; import classNames from '../_util/classNames'; import { getTransitionProps } from '../_util/transition'; import FloatButton, { floatButtonPrefixCls } from './FloatButton'; import useConfigInject from '../config-provider/hooks/useConfigInject'; import { useProvideFloatButtonGroupContext } from './context'; import { findDOMNode, initDefaultProps } from '../_util/props-util'; import { floatButtonGroupProps } from './interface'; import type { FloatButtonGroupProps } from './interface'; import canUseDom from '../_util/canUseDom'; // CSSINJS import useStyle from './style'; import useMergedState from '../_util/hooks/useMergedState'; const FloatButtonGroup = defineComponent({ compatConfig: { MODE: 3 }, name: 'AFloatButtonGroup', inheritAttrs: false, props: initDefaultProps(floatButtonGroupProps(), { type: 'default', shape: 'circle', } as FloatButtonGroupProps), setup(props, { attrs, slots, emit }) { const { prefixCls, direction } = useConfigInject(floatButtonPrefixCls, props); // style const [wrapSSR, hashId] = useStyle(prefixCls); const [open, setOpen] = useMergedState(false, { value: computed(() => props.open) }); const floatButtonGroupRef = ref(null); const floatButtonRef = ref(null); useProvideFloatButtonGroupContext({ shape: computed(() => props.shape), }); const hoverTypeAction = { onMouseenter() { setOpen(true); emit('update:open', true); props.onOpenChange?.(true); }, onMouseleave() { setOpen(false); emit('update:open', false); props.onOpenChange?.(false); }, }; const hoverAction = computed(() => { return props.trigger === 'hover' ? hoverTypeAction : {}; }); const handleOpenChange = () => { const nextOpen = !open.value; emit('update:open', nextOpen); props.onOpenChange?.(nextOpen); setOpen(nextOpen); }; const onClick = (e: MouseEvent) => { if (floatButtonGroupRef.value?.contains(e.target as Node)) { if (findDOMNode(floatButtonRef.value)?.contains(e.target as Node)) { handleOpenChange(); } return; } setOpen(false); emit('update:open', false); props.onOpenChange?.(false); }; watch( computed(() => props.trigger), value => { if (!canUseDom()) { return; } document.removeEventListener('click', onClick); if (value === 'click') { document.addEventListener('click', onClick); } }, { immediate: true }, ); onBeforeUnmount(() => { document.removeEventListener('click', onClick); }); return () => { const { shape = 'circle', type = 'default', tooltip, description, trigger } = props; const groupPrefixCls = `${prefixCls.value}-group`; const groupCls = classNames(groupPrefixCls, hashId.value, attrs.class, { [`${groupPrefixCls}-rtl`]: direction.value === 'rtl', [`${groupPrefixCls}-${shape}`]: shape, [`${groupPrefixCls}-${shape}-shadow`]: !trigger, }); const wrapperCls = classNames(hashId.value, `${groupPrefixCls}-wrap`); const transitionProps = getTransitionProps(`${groupPrefixCls}-wrap`); return wrapSSR(
{trigger && ['click', 'hover'].includes(trigger) ? ( <>
{slots.default && slots.default()}
open.value ? slots.closeIcon?.() || : slots.icon?.() || , tooltip: slots.tooltip, description: slots.description, }} > ) : ( slots.default?.() )}
, ); }; }, }); export default FloatButtonGroup;