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

Replace overlay by checking if event is inside of ref.

Added an useOutsideAlerter hook that will check if the event triggered is inside the reference passed to it and implemented
this hook to check if the user is clicking outside of the multi save button
jnfrati 4 лет назад
Родитель
Сommit
be4aa067c9

+ 12 - 3
dashboard/src/components/MultiSaveButton.tsx

@@ -1,7 +1,8 @@
-import React, { useState } from "react";
+import React, { useEffect, useRef, useState } from "react";
 import styled from "styled-components";
 import loading from "assets/loading.gif";
 import Description from "./Description";
+import { useOutsideAlerter } from "shared/hooks/useOutsideAlerter";
 
 type MultiSelectOption = {
   text: string;
@@ -34,6 +35,12 @@ const MultiSaveButton: React.FC<Props> = (props) => {
 
   const [isDropdownExpanded, setIsDropdownExpanded] = useState(false);
 
+  const wrapperRef = useRef<HTMLDivElement>();
+
+  useOutsideAlerter(wrapperRef, () => {
+    setIsDropdownExpanded(false);
+  });
+
   const renderStatus = () => {
     if (props.status) {
       if (props.status === "successful") {
@@ -82,7 +89,6 @@ const MultiSaveButton: React.FC<Props> = (props) => {
     if (isDropdownExpanded) {
       return (
         <>
-          <DropdownOverlay onClick={() => setIsDropdownExpanded(false)} />
           <OptionWrapper
             expandTo={props.expandTo || "right"}
             dropdownWidth="400px"
@@ -115,7 +121,7 @@ const MultiSaveButton: React.FC<Props> = (props) => {
   };
 
   return (
-    <DropdownSelector>
+    <DropdownSelector ref={wrapperRef}>
       <ButtonWrapper
         makeFlush={props.makeFlush}
         clearPosition={props.clearPosition}
@@ -134,6 +140,9 @@ const MultiSaveButton: React.FC<Props> = (props) => {
           disabled={props.disabled}
           color={props.color || "#5561C0"}
           onClick={() => setIsDropdownExpanded(!isDropdownExpanded)}
+          onBlur={() => {
+            console.log("BLUR 2");
+          }}
         >
           <i className="material-icons expand-icon">
             {isDropdownExpanded ? "expand_less" : "expand_more"}

+ 30 - 0
dashboard/src/shared/hooks/useOutsideAlerter.ts

@@ -0,0 +1,30 @@
+import React, { MutableRefObject, RefObject, useEffect, useRef } from "react";
+
+/**
+ * Hook that alerts clicks outside of the passed ref
+ */
+export function useOutsideAlerter(
+  ref: React.RefObject<HTMLDivElement>,
+  callback: () => void
+) {
+  useEffect(() => {
+    /**
+     * Alert if clicked on outside of element
+     */
+    function handleClickOutside(event: any) {
+      if (
+        ref.current &&
+        !ref.current.contains(event.target) &&
+        typeof callback === "function"
+      ) {
+        callback();
+      }
+    }
+    // Bind the event listener
+    document.addEventListener("mousedown", handleClickOutside);
+    return () => {
+      // Unbind the event listener on clean up
+      document.removeEventListener("mousedown", handleClickOutside);
+    };
+  }, [ref]);
+}