fix: PopOver嵌套场景下错误触发hidden事件问题 Close: #9015 (#9022)

This commit is contained in:
RUNZE LU 2023-12-05 18:29:21 +08:00 committed by GitHub
parent 654f7588dc
commit 088431dea1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 43 additions and 1 deletions

View File

@ -20,6 +20,8 @@ import {
RootClose
} from '../utils';
export const SubPopoverDisplayedID = 'data-sub-popover-displayed';
function onScroll(elem: HTMLElement, callback: () => void) {
const handler = () => {
requestAnimationFrame(callback);
@ -35,6 +37,7 @@ class Position extends React.Component<any, any> {
_lastTarget: any;
resizeDispose: Array<() => void>;
watchedTarget: any;
parentPopover: any;
// setState: (state: any) => void;
static defaultProps = {
@ -59,6 +62,16 @@ class Position extends React.Component<any, any> {
updatePosition(target: any) {
this._lastTarget = target;
/** 标记宿主元素的PopOver祖先用于后续判断PopOver 是否可以 root close */
if (target) {
const parentPopover = target?.closest?.('[role=popover]');
if (!this.parentPopover && parentPopover) {
this.parentPopover = parentPopover;
this.parentPopover.setAttribute(SubPopoverDisplayedID, true);
}
}
if (!target) {
return this.setState({
positionLeft: 0,
@ -139,6 +152,14 @@ class Position extends React.Component<any, any> {
};
componentWillUnmount() {
if (
this.parentPopover &&
this.parentPopover.getAttribute(SubPopoverDisplayedID)
) {
this.parentPopover.removeAttribute(SubPopoverDisplayedID);
this.parentPopover = null;
}
this.resizeDispose?.forEach(fn => fn());
}
@ -223,7 +244,7 @@ export default class Overlay extends React.Component<
this.position?.maybeUpdatePosition(true);
}
componentDidUpdate(prevProps: OverlayProps) {
componentDidUpdate(prevProps: OverlayProps, prevState: OverlayState) {
const props = this.props;
if (prevProps.show !== props.show && props.show) {
this.setState({exited: false});

View File

@ -8,6 +8,7 @@ import React from 'react';
import {findDOMNode} from 'react-dom';
import {ClassNamesFn, themeable} from '../theme';
import {autobind, camel, preventDefault} from '../utils';
import {SubPopoverDisplayedID} from './Overlay';
export interface Offset {
x: number;
@ -124,6 +125,7 @@ export class PopOver extends React.PureComponent<PopOverProps, PopOverState> {
closeOnOutside &&
target &&
this.wrapperRef.current &&
!this.wrapperRef.current.getAttribute(SubPopoverDisplayedID) &&
((!this.wrapperRef.current.contains(target) &&
!target.closest('[role=dialog]')) ||
(target.matches(`.${ns}Modal`) && target === this.wrapperRef.current))
@ -212,6 +214,7 @@ export class PopOver extends React.PureComponent<PopOverProps, PopOverState> {
return (
<div
ref={this.wrapperRef}
role="popover"
className={cx(
`PopOver`,
className,

View File

@ -290,6 +290,7 @@ exports[`Renderer:inputCity with searchable: open select 1`] = `
</span>
<div
class="cxd-PopOver cxd-Select-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; width: auto; left: 0px; top: 0px; position: relative;"
theme="cxd"
>

View File

@ -586,6 +586,7 @@ exports[`Renderer:InputTag InputTag with options 1`] = `
</div>
<div
class="cxd-PopOver cxd-TagControl-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; left: 0px; top: 0px; position: relative;"
theme="cxd"
>

View File

@ -208,6 +208,7 @@ exports[`Renderer:repeat 1`] = `
</span>
<div
class="cxd-PopOver cxd-Select-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; width: 0px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>

View File

@ -355,6 +355,7 @@ exports[`Renderer:select associated mode with virtual 1`] = `
</div>
<div
class="cxd-PopOver cxd-TransferDropDown-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; min-width: 100px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>
@ -968,6 +969,7 @@ exports[`Renderer:select chained mode with virtual 1`] = `
</div>
<div
class="cxd-PopOver cxd-TransferDropDown-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; min-width: 100px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>
@ -1513,6 +1515,7 @@ exports[`Renderer:select group mode with virtual 1`] = `
</div>
<div
class="cxd-PopOver cxd-TransferDropDown-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; min-width: 100px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>
@ -2080,6 +2083,7 @@ exports[`Renderer:select table mode with virtual 1`] = `
</div>
<div
class="cxd-PopOver cxd-TransferDropDown-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; min-width: 100px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>
@ -2453,6 +2457,7 @@ exports[`Renderer:select table with labelField & valueField 1`] = `
</div>
<div
class="cxd-PopOver cxd-TransferDropDown-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; min-width: 100px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>
@ -2950,6 +2955,7 @@ exports[`Renderer:select virtual 1`] = `
</span>
<div
class="cxd-PopOver cxd-Select-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; width: auto; left: 0px; top: 0px; position: relative;"
theme="cxd"
>

View File

@ -1578,6 +1578,7 @@ exports[`Renderer:text with options and multiple and delimiter: first option sel
/>
<div
class="cxd-PopOver cxd-TextControl-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; width: 0px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>
@ -1809,6 +1810,7 @@ exports[`Renderer:text with options and multiple and delimiter: options is opene
/>
<div
class="cxd-PopOver cxd-TextControl-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; width: 0px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>
@ -2067,6 +2069,7 @@ exports[`Renderer:text with options and multiple and delimiter: options is opene
/>
<div
class="cxd-PopOver cxd-TextControl-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; width: 0px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>
@ -2324,6 +2327,7 @@ exports[`Renderer:text with options and multiple and delimiter: second option se
/>
<div
class="cxd-PopOver cxd-TextControl-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; width: 0px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>
@ -2694,6 +2698,7 @@ exports[`Renderer:text with options: options is open 1`] = `
/>
<div
class="cxd-PopOver cxd-TextControl-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; width: 0px; left: 0px; top: 0px; position: relative;"
theme="cxd"
>

View File

@ -854,6 +854,7 @@ exports[`Renderer:Pagination with showPerPage & perPageAvailable & showPageInput
</span>
<div
class="cxd-PopOver cxd-Select-popover cxd-PopOver--leftBottomLeftTop cxd-PopOver--v-top"
role="popover"
style="display: block; width: auto; left: 0px; top: 0px; position: relative;"
theme="cxd"
>

View File

@ -124,6 +124,7 @@ exports[`Renderer:PopOver with offset: show popover no offset 1`] = `
</span>
<div
class="cxd-PopOver cxd-PopOverAble-popover cxd-PopOver--right"
role="popover"
style="display: block; left: 0px; top: 0px; position: relative;"
theme="cxd"
>
@ -268,6 +269,7 @@ exports[`Renderer:PopOver with offset: show popover with offset 1`] = `
</span>
<div
class="cxd-PopOver cxd-PopOverAble-popover cxd-PopOver--right"
role="popover"
style="display: block; left: 101px; top: 102px; position: relative;"
theme="cxd"
>

View File

@ -1559,6 +1559,7 @@ exports[`Renderer:tabs with collapseOnExceed: popover show 1`] = `
</div>
<div
class="cxd-PopOver cxd-Tabs-PopOver cxd-PopOver--centerTopCenterBottom cxd-PopOver--v-bottom"
role="popover"
style="display: block; min-width: auto; left: 0px; top: 0px; position: relative;"
theme="cxd"
>