Search code examples
reactjsantd

React Indiana drag scroll component interfering with Ant Design popover


I am trying to implement Ant Design popovers inside a react-indiana-drag-scroll component. I need the popovers to dismiss when the user clicks off them.

When the user clicks anywhere on the page, the active popover disappears. However, If they click inside the scroll component to open another popover or try to scroll the div, the active popover does not dissappear.

https://codesandbox.io/s/async-frog-3mxh7

The above Code Sand Box has the whole scenario to play with, I can also paste the code in if necessary.

Steps to make popup dismiss: Click one of the "A" cells in the table - the popover should appear. click on one of the names in the Name column - the popover will dismiss

Steps to make the popover stay: Click one of the "A" cells in the table - the popover should appear. Click one of the "A" cells or try to click and drag the table about. - The popover will not disappear

I think that the problem has something do do with the ScrollContainer handling the click event and not letting the browser or antd do anything else with it.

Thanks for any help you can offer.

Code is as follows:

import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Popover } from "antd";
import ScrollContainer from "react-indiana-drag-scroll";

class GridSquare extends React.Component {
  state = {
    visible: false
  };

  hide = () => {
    this.setState({
      visible: false
    });
  };

  handleVisibleChange = visible => {
    this.setState({ visible });
  };

  render() {
    const content = <div>Popup Window</div>;

    return (
      <div>
        <Popover
          content={content}
          title="Title"
          trigger="click"
          placement="right"
          visible={this.state.visible}
          onVisibleChange={this.handleVisibleChange}
        >
          <a href="none">A</a>
        </Popover>
      </div>
    );
  }
}

class App extends React.Component {
  render() {
    const data = [
      {
        Name: "Vanessa Smith",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      },
      {
        Name: "Alan Benedict",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      },
      {
        Name: "James Borton",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      },
      {
        Name: "Belinda Gong",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      },
      {
        Name: "Barry Homeowner",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      },
      {
        Name: "Cassandra Blanche",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      },
      {
        Name: "Carmel Daniels",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      },
      {
        Name: "Peter Jones",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      },
      {
        Name: "Grimswick Smith",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      },
      {
        Name: "Sanrda Martinez",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      },
      {
        Name: "Ronnie Hotdog",
        Things: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
      }
    ];

    return (
      <div className="outer-div-constrainer">
        <div className="attendance-floater">
          <table className="table-attendance table table-condensed">
            <thead>
              <tr>
                <th colSpan="5">Name</th>
              </tr>
            </thead>
            <tbody>
              {data.map((row, i) => (
                <tr key={i}>
                  <td>{row.Name}</td>
                  <td>0</td>
                  <td>0</td>
                  <td>0</td>
                  <td>0</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        <ScrollContainer
          className="scroll-container attendance-scroller"
          hideScrollbars={false}
          nativeMobileScroll={true}
        >
          <table className="table-attendance table table-condensed">
            <thead>
              <tr>
                {data[0].Things.map((row, i) => (
                  <th key={i}>Thing</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {data.map((row, i) => (
                <tr key={i}>
                  {row.Things.map((i, j) => (
                    <td key={j}>
                      <GridSquare />
                    </td>
                  ))}
                </tr>
              ))}
            </tbody>
          </table>
        </ScrollContainer>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));
.outer-div-constrainer {
  width: 300px;
}

.attendance-scroller {
  overflow-x: scroll;
  direction: rtl;
  cursor: grab;
}
.attendance-floater {
  float: left;
}
<div id="container" style="padding: 24px"></div>

Solution

  • I'm the developer of react-indiana-drag-scroll. The reason of this bug is the unnecessary preventing of the event propagation inside the scroll container event handlers. It's fixed in 1.6.0. Please update to this version to solve your problem (try at this example).

    No additional fixes needed.