DEV Community

Discussion on: Using usePopper and styled-components to create a practical dropdown from scratch

Collapse
 
sergeyt profile image
Sergey Todyshev

a bit modified version using "react-outside-click-handler" and "without styled-components":

import React, { useState, useRef } from "react";
import { usePopper } from "react-popper";
import OutsideClickHandler from "react-outside-click-handler";

function DefaultButton(props) {
  return <span className="dots" {...props}>...</span>;
}

export default function Dropdown({ button: Button = DefaultButton, children }) {
  const [visible, setVisible] = useState(false);
  const referenceRef = useRef(null);
  const popperRef = useRef(null);

  const { styles, attributes } = usePopper(
    referenceRef.current,
    popperRef.current,
    {
      placement: "bottom",
      modifiers: [
        {
          name: "offset",
          enabled: true,
          options: {
            offset: [0, 10],
          },
        },
      ],
    }
  );

  const hide = () => setVisible(false);

  function handleDropdownClick(e: any) {
    e.preventDefault();
    setVisible(true);
  }

  const containerStyle: any = {
    ...styles.popper,
    display: visible ? "flex" : "none",
    zIndex: 999,
    flexDirection: "column",
    backgroundColor: "#FFF",
    borderRadius: "4px",
    boxShadow: "0 0 8px 0 rgba(0, 0, 0, 0.14)",
    padding: "10px",
  };

  return (
    <React.Fragment>
      <OutsideClickHandler onOutsideClick={hide}>
        <span ref={referenceRef} onClick={handleDropdownClick}>
          <Button />
        </span>
      </OutsideClickHandler>
      <div ref={popperRef} style={containerStyle} {...attributes.popper}>
        <OutsideClickHandler onOutsideClick={hide}>
          {children}
        </OutsideClickHandler>
      </div>
    </React.Fragment>
  );
}
Enter fullscreen mode Exit fullscreen mode

this snippet might be reused too

Collapse
 
tannerhallman profile image
Tanner Hallman

Ah cool, thanks for sharing!