Kaynağa Gözat

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