Repository: mapbox/mr-ui
Pull request #78 (2019-04-10 18:02:33)

create `zIndex` option for Popover
I'd like to propose a `zIndex` option for Popover so that we can change the z-index of the popover body when needed.

I'm currently blocked by adding a popover on an element that has a z-index of 3. I'm can't change the other element's z-index as it's incremented just enough to clear the z-index of the Mapbox attribution logo.


Patch:
diff --git a/src/components/popover/popover-positioner.js b/src/components/popover/popover-positioner.js
index 58fcf07..4e99e1b 100644
--- a/src/components/popover/popover-positioner.js
+++ b/src/components/popover/popover-positioner.js
@@ -26,6 +26,7 @@ let popoverPositionerList = [];
  * @param {boolean} [containWithinViewport] - See options for calculatePosition.
  * @param {Function} [getContainingElement] - See options for calculatePosition.
  * @param {Function} [onElement] - A function that receives the containing element.
+ * @param {number} [zIndex] - z-index for body element.
  */
 class PopoverPositioner extends React.PureComponent {
   static propTypes = {
@@ -43,6 +44,7 @@ class PopoverPositioner extends React.PureComponent {
     containWithinViewport: PropTypes.bool,
     getContainingElement: PropTypes.func,
     onElement: PropTypes.func,
+    zIndex: PropTypes.number,
     // For mockery
     calculatePosition: PropTypes.func,
     getScrollableParents: PropTypes.func,
@@ -157,7 +159,7 @@ class PopoverPositioner extends React.PureComponent {
   render() {
     const basicStyle = {
       position: 'absolute',
-      zIndex: 1,
+      zIndex: this.props.zIndex,
       top: 0,
       left: 0,
       visibility: 'hidden'
diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js
index 40bed92..7a5a04a 100644
--- a/src/components/popover/popover.js
+++ b/src/components/popover/popover.js
@@ -208,6 +208,7 @@ export default class Popover extends React.Component {
         getContainingElement={props.getContainingElement}
         offsetFromAnchor={props.offsetFromAnchor}
         onElement={this.setPopoverElement}
+        zIndex={props.zIndex}
       >
         <div
           key="body"
@@ -333,7 +334,11 @@ Popover.propTypes = {
   /**
    * Props to pass directly to the `<div>` that will wrap your popover content.
    */
-  passthroughProps: PropTypes.object
+  passthroughProps: PropTypes.object,
+  /**
+   * CSS z-index number to order popover over content.
+   */
+  zIndex: PropTypes.number
 };
 
 Popover.defaultProps = {
@@ -348,7 +353,8 @@ Popover.defaultProps = {
   clickOutsideCloses: true,
   escapeCloses: true,
   receiveFocus: true,
-  trapFocus: false
+  trapFocus: false,
+  zIndex: 1
 };
 
 Popover.repositionPopovers = PopoverPositioner.recalculatePositions;


Test patch:
diff --git a/src/components/copiable/__tests__/__snapshots__/copiable.test.js.snap b/src/components/copiable/__tests__/__snapshots__/copiable.test.js.snap
index 9779836..b3d6e6f 100644
--- a/src/components/copiable/__tests__/__snapshots__/copiable.test.js.snap
+++ b/src/components/copiable/__tests__/__snapshots__/copiable.test.js.snap
@@ -82,6 +82,7 @@ exports[`basic shows copy hint when focused 1`] = `
     placement="top"
     receiveFocus={true}
     trapFocus={false}
+    zIndex={1}
   >
     <div
       className="txt-s"
diff --git a/src/components/copy-button/__tests__/__snapshots__/copy-button.test.js.snap b/src/components/copy-button/__tests__/__snapshots__/copy-button.test.js.snap
index ecfdd9e..95af4df 100644
--- a/src/components/copy-button/__tests__/__snapshots__/copy-button.test.js.snap
+++ b/src/components/copy-button/__tests__/__snapshots__/copy-button.test.js.snap
@@ -40,6 +40,7 @@ exports[`CopyButton Defaults changes state on click 1`] = `
       placement="top"
       receiveFocus={true}
       trapFocus={false}
+      zIndex={1}
     >
       <div
         className="txt-s"
@@ -150,6 +151,7 @@ exports[`CopyButton all props changes state on click 1`] = `
       placement="top"
       receiveFocus={true}
       trapFocus={false}
+      zIndex={1}
     >
       <div
         className="txt-s"
diff --git a/src/components/popover/__tests__/__snapshots__/popover-positioner.test.js.snap b/src/components/popover/__tests__/__snapshots__/popover-positioner.test.js.snap
index 4366f51..7894584 100644
--- a/src/components/popover/__tests__/__snapshots__/popover-positioner.test.js.snap
+++ b/src/components/popover/__tests__/__snapshots__/popover-positioner.test.js.snap
@@ -10,7 +10,7 @@ exports[`PopoverPositioner renders initially with everything hidden 1`] = `
         "position": "absolute",
         "top": 0,
         "visibility": "hidden",
-        "zIndex": 1,
+        "zIndex": 3,
       }
     }
   >
@@ -26,7 +26,7 @@ exports[`PopoverPositioner renders initially with everything hidden 1`] = `
         "position": "absolute",
         "top": 0,
         "visibility": "hidden",
-        "zIndex": 1,
+        "zIndex": 3,
       }
     }
   />
diff --git a/src/components/popover/__tests__/__snapshots__/popover.test.js.snap b/src/components/popover/__tests__/__snapshots__/popover.test.js.snap
index d34145b..0d017d6 100644
--- a/src/components/popover/__tests__/__snapshots__/popover.test.js.snap
+++ b/src/components/popover/__tests__/__snapshots__/popover.test.js.snap
@@ -13,6 +13,7 @@ exports[`Popover all props renders 1`] = `
   onElement={[Function]}
   placement="left"
   pointerColor="#fff"
+  zIndex={1}
 >
   <div
     className="color-text shadow-darken25 round"
@@ -50,6 +51,7 @@ exports[`Popover basic renders 1`] = `
   onElement={[Function]}
   placement="right"
   pointerColor="#fff"
+  zIndex={1}
 >
   <div
     className="color-text shadow-darken25 round px12 py12"
@@ -86,6 +88,7 @@ exports[`Popover dark renders 1`] = `
   onElement={[Function]}
   placement="right"
   pointerColor="#273d56"
+  zIndex={1}
 >
   <div
     className="color-white shadow-darken25 round px12 py12"
@@ -122,6 +125,7 @@ exports[`Popover no pointer renders 1`] = `
   onElement={[Function]}
   placement="right"
   pointerColor="#fff"
+  zIndex={1}
 >
   <div
     className="color-text shadow-darken25 round px12 py12"
@@ -158,6 +162,7 @@ exports[`Popover warning renders 1`] = `
   onElement={[Function]}
   placement="right"
   pointerColor="#FFF5A0"
+  zIndex={1}
 >
   <div
     className="color-text shadow-darken25 round px12 py12"
diff --git a/src/components/popover/__tests__/popover-positioner.test.js b/src/components/popover/__tests__/popover-positioner.test.js
index 8343de9..8bf5dba 100644
--- a/src/components/popover/__tests__/popover-positioner.test.js
+++ b/src/components/popover/__tests__/popover-positioner.test.js
@@ -49,6 +49,7 @@ describe('PopoverPositioner', () => {
       calculatePosition: mockCalculatePosition,
       getScrollableParents: mockGetScrollableParents,
       createScrollListener: mockCreateScrollListener,
+      zIndex: 3,
       getWindow: mockGetWindow
     };
   });
@@ -203,6 +204,7 @@ describe('PopoverPositioner', () => {
     const wrapper = mount(<PopoverPositioner.WrappedComponent {...props} />);
     expect(mockCalculatePosition).toHaveBeenCalledTimes(1);
     wrapper.setProps({ children: <span>horses</span> });
+    expect(wrapper.instance().bodyElement.style.zIndex).toBe('3');
     expect(mockCalculatePosition).toHaveBeenCalledTimes(2);
   });