Skip to content

Commit

Permalink
fix(list): list cascader-item on Document click error (#1870)
Browse files Browse the repository at this point in the history
  • Loading branch information
berber1016 authored Mar 1, 2022
1 parent 33e3097 commit 2d4bd6f
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 18 deletions.
30 changes: 17 additions & 13 deletions src/list/inner/CascaderItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import List from '../List';
import { convertChildrenToData, generateSelectParent, generateString } from '../util';
import { ListContext } from '../context';
import { BaseItemProps } from '..';
import TriggerContext from '../../popover/context';

const CascaderItem: React.ForwardRefRenderFunction<
HTMLLIElement,
Expand All @@ -23,6 +24,7 @@ const CascaderItem: React.ForwardRefRenderFunction<
const popoverClassName = `${prefixCls}--content`;
/** context */
const context = useContext(ListContext);
const popoverContext = useContext(TriggerContext);
const { disabled: contextDisabled, selectParent, onClick: contextOnClick, setOptions } = context;
/** end */
const childSelectPrent = generateSelectParent(label, value, selectParent);
Expand Down Expand Up @@ -91,19 +93,21 @@ const CascaderItem: React.ForwardRefRenderFunction<
if (!isEmpty(childrens) || React.isValidElement(children)) {
return (
<div className={prefixClsItem}>
<Popover
placement="rightTop"
overlayClassName={popoverClassName}
// document click contains node
getContainer={() => document.body}
content={content()}
strategy={strategy}
distoryOnHide
delay={200}
offset={[0, 12]}
>
{element}
</Popover>
<TriggerContext.Provider value={popoverContext}>
<Popover
placement="rightTop"
overlayClassName={popoverClassName}
// document click contains node
getContainer={() => document.body}
content={content()}
strategy={strategy}
distoryOnHide
delay={200}
offset={[0, 12]}
>
{element}
</Popover>
</TriggerContext.Provider>
</div>
);
}
Expand Down
41 changes: 36 additions & 5 deletions src/popover/Popover.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useMemo, useCallback, useRef, useLayoutEffect, useEffect } from 'react';
import React, { useState, useMemo, useCallback, useRef, useLayoutEffect, useEffect, useContext } from 'react';
import classNames from 'classnames';
import { debounce, isFunction, isNil, omit } from 'lodash';
import ReactDOM from 'react-dom';
Expand All @@ -8,6 +8,7 @@ import { PopoverProps } from './interface';
import { composeRef, supportRef } from '../utils/composeRef';
import useControlledState from '../utils/hooks/useControlledState';
import usePop from './usePop';
import TriggerContext from './context';

const Popover = (props: PopoverProps) => {
const {
Expand Down Expand Up @@ -43,7 +44,10 @@ const Popover = (props: PopoverProps) => {
const [referenceElement, setReferenceELement] = useState<null | HTMLElement>(null);
const [popperElement, setPopperElement] = useState<null | HTMLElement>(null);
const arrowElement = useRef<HTMLDivElement | null>(null);

const context = useContext(TriggerContext);
const hasPopupMouseDown = useRef<boolean>(false);
const mouseDownTimeout = useRef<any>(undefined);
// const
useEffect(() => {
if (!visible) overContentRef.current = false;
}, [visible]);
Expand Down Expand Up @@ -120,11 +124,32 @@ const Popover = (props: PopoverProps) => {
},
[disabled, enterable, setVisible, onVisibleChange, update]
);

// ============ nest popover on Document click close ============
const onPopupMouseDown = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
hasPopupMouseDown.current = true;

clearTimeout(mouseDownTimeout.current);
mouseDownTimeout.current = window.setTimeout(() => {
hasPopupMouseDown.current = false;
}, 0);

if (context) {
context?.onPopupMouseDown(event);
}
};

const triggerContextValue = { onPopupMouseDown };

const onDocumentClick = useCallback(
(event: MouseEvent) => {
const { target } = event;
if (isFunction(referenceElement?.contains) && isFunction(popperElement?.contains)) {
if (!referenceElement?.contains(target as Node) && !popperElement?.contains(target as Node)) {
if (
!referenceElement?.contains(target as Node) &&
!popperElement?.contains(target as Node) &&
!hasPopupMouseDown.current
) {
updateVisible(false);
}
}
Expand All @@ -139,6 +164,8 @@ const Popover = (props: PopoverProps) => {
};
}, [onDocumentClick]);

// ============ end ============

const isClickToShow = useMemo(() => trigger.indexOf('click') !== -1, [trigger]);

const isHoverToShow = useMemo(() => trigger.indexOf('hover') !== -1, [trigger]);
Expand Down Expand Up @@ -224,6 +251,7 @@ const Popover = (props: PopoverProps) => {
style={{ ...(overlayStyle || {}), ...styles.popper }}
onMouseEnter={onContentMouseEnter}
onMouseLeave={onContentMouseLeave}
onMouseDownCapture={(e) => onPopupMouseDown(e)}
onClick={onContentClick}
role="none"
{...omit(rest, 'arrowPointAtCenter')}
Expand Down Expand Up @@ -257,6 +285,7 @@ const Popover = (props: PopoverProps) => {
cloneProps.ref = composeRef(setReferenceELement, (child as any).ref);
triggerNode = React.cloneElement(child as React.ReactElement, cloneProps);
}

const container = useMemo(() => {
if (isFunction(getContainer) && !isNil(referenceElement)) {
return getContainer(referenceElement);
Expand All @@ -277,8 +306,10 @@ const Popover = (props: PopoverProps) => {
);
return (
<>
{triggerNode}
{distoryOnHide ? visible && renderContent : renderContent}
<TriggerContext.Provider value={triggerContextValue}>
{triggerNode}
{distoryOnHide ? visible && renderContent : renderContent}
</TriggerContext.Provider>
</>
);
};
Expand Down
9 changes: 9 additions & 0 deletions src/popover/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from 'react';

interface TriggerContextProps {
onPopupMouseDown: React.MouseEventHandler<HTMLElement>;
}

const TriggerContext = React.createContext<TriggerContextProps | null>(null);

export default TriggerContext;

1 comment on commit 2d4bd6f

@vercel
Copy link

@vercel vercel bot commented on 2d4bd6f Mar 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.