Просмотр исходного кода

Create a portal and use it with our popper component (tooltip and popover) to avoid potential overflow-/zindex-bugs

Johannes Schill 7 лет назад
Родитель
Сommit
1bbe48e9c5

+ 28 - 0
public/app/core/components/Portal/BodyPortal.tsx

@@ -0,0 +1,28 @@
+import { PureComponent } from 'react';
+import ReactDOM from 'react-dom';
+
+interface Props {
+  className?: string;
+}
+
+export default class BodyPortal extends PureComponent<Props> {
+  node: HTMLElement = document.createElement('div');
+  portalRoot = document.body;
+
+  constructor(props) {
+    super(props);
+    const { className } = this.props;
+    if (className) {
+      this.node.classList.add();
+    }
+    this.portalRoot.appendChild(this.node);
+  }
+
+  componentWillUnmount() {
+    this.portalRoot.removeChild(this.node);
+  }
+
+  render() {
+    return ReactDOM.createPortal(this.props.children, this.node);
+  }
+}

+ 23 - 20
public/app/core/components/Tooltip/Popper.tsx

@@ -1,4 +1,5 @@
 import React, { PureComponent } from 'react';
+import BodyPortal from 'app/core/components/Portal/BodyPortal';
 import { Manager, Popper as ReactPopper, Reference } from 'react-popper';
 import Transition from 'react-transition-group/Transition';
 
@@ -38,27 +39,29 @@ class Popper extends PureComponent<Props> {
         </Reference>
         <Transition in={show} timeout={100} mountOnEnter={true} unmountOnExit={true}>
           {transitionState => (
-            <ReactPopper placement={placement}>
-              {({ ref, style, placement, arrowProps }) => {
-                return (
-                  <div
-                    ref={ref}
-                    style={{
-                      ...style,
-                      ...defaultTransitionStyles,
-                      ...transitionStyles[transitionState],
-                    }}
-                    data-placement={placement}
-                    className="popper"
-                  >
-                    <div className="popper__background">
-                      {renderContent(content)}
-                      <div ref={arrowProps.ref} data-placement={placement} className="popper__arrow" />
+            <BodyPortal className="hej">
+              <ReactPopper placement={placement}>
+                {({ ref, style, placement, arrowProps }) => {
+                  return (
+                    <div
+                      ref={ref}
+                      style={{
+                        ...style,
+                        ...defaultTransitionStyles,
+                        ...transitionStyles[transitionState],
+                      }}
+                      data-placement={placement}
+                      className="popper"
+                    >
+                      <div className="popper__background">
+                        {renderContent(content)}
+                        <div ref={arrowProps.ref} data-placement={placement} className="popper__arrow" />
+                      </div>
                     </div>
-                  </div>
-                );
-              }}
-            </ReactPopper>
+                  );
+                }}
+              </ReactPopper>
+            </BodyPortal>
           )}
         </Transition>
       </Manager>