diff --git a/examples/simple.js b/examples/simple.js index 3acd97e6..0bd89d35 100644 --- a/examples/simple.js +++ b/examples/simple.js @@ -31,14 +31,27 @@ const builtinPlacements = { }, }; -function preventDefault(e) { - e.preventDefault(); -} - function getPopupContainer(trigger) { return trigger.parentNode; } +const InnerTarget = React.forwardRef((props, ref) => { + React.useImperativeHandle(ref, () => ({})); + + return ( +
+

This is a example of trigger usage.

+

You can adjust the value above

+

which will also change the behaviour of popup.

+
+ ); +}); + class Test extends React.Component { state = { mask: false, @@ -259,7 +272,7 @@ class Test extends React.Component {
i am a popup
} popupTransitionName={state.transitionName} > - -

This is a example of trigger usage.

-

You can adjust the value above

-

which will also change the behaviour of popup.

-
+ diff --git a/src/index.tsx b/src/index.tsx index 6a00153c..d100aa43 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,4 +1,5 @@ import React, { HTMLAttributes } from 'react'; +import ReactDOM from 'react-dom'; import contains from 'rc-util/lib/Dom/contains'; import findDOMNode from 'rc-util/lib/Dom/findDOMNode'; import { composeRef } from 'rc-util/lib/ref'; @@ -394,12 +395,22 @@ export function generateTrigger(PortalComponent: any): React.ComponentClass { + getRootDomNode = (): HTMLElement => { const { getTriggerDOMNode } = this.props; if (getTriggerDOMNode) { return getTriggerDOMNode(this.triggerRef.current); } - return findDOMNode(this.triggerRef.current); + + try { + const domNode = findDOMNode(this.triggerRef.current); + if (domNode) { + return domNode; + } + } catch (err) { + // Do nothing + } + + return ReactDOM.findDOMNode(this) as HTMLElement; }; getPopupClassNameFromAlign = align => { diff --git a/tests/basic.test.jsx b/tests/basic.test.jsx index 14a0d5dd..befc76c5 100644 --- a/tests/basic.test.jsx +++ b/tests/basic.test.jsx @@ -512,4 +512,31 @@ describe('Trigger.Basic', () => { 'target className-in-trigger-1 className-in-trigger-2', ); }); + + it('support function component', () => { + const NoRef = React.forwardRef((props, ref) => { + React.useImperativeHandle(ref, () => null); + return ( +
+ click +
+ ); + }); + + const wrapper = mount( + tooltip2} + > + + , + ); + + wrapper.trigger(); + expect(wrapper.isHidden()).toBeFalsy(); + + wrapper.trigger(); + expect(wrapper.isHidden()).toBeTruthy(); + }); });