From 255dcc31902a6dbd4083e8e77d7e934b83e9f011 Mon Sep 17 00:00:00 2001
From: Himanshu Aggarwal <aggarwah@mcmaster.ca>
Date: Fri, 18 Mar 2022 21:13:21 -0400
Subject: [PATCH] Make dropdown components modular

---
 .../components/dropdown/Dropdown.js           | 17 +---
 .../components/dropdown/DropdownItem.js       | 20 ++++
 .../components/dropdown/FilterDropdown.js     | 93 +------------------
 .../components/dropdown/FilterDropdownItem.js | 37 ++++++++
 .../dropdown/SecondaryFilterDropdown.js       | 60 ++++++++++++
 src/cryptometrics/pages/index.js              |  2 +-
 6 files changed, 123 insertions(+), 106 deletions(-)
 create mode 100644 src/cryptometrics/components/dropdown/DropdownItem.js
 create mode 100644 src/cryptometrics/components/dropdown/FilterDropdownItem.js
 create mode 100644 src/cryptometrics/components/dropdown/SecondaryFilterDropdown.js

diff --git a/src/cryptometrics/components/dropdown/Dropdown.js b/src/cryptometrics/components/dropdown/Dropdown.js
index 963426f..793467b 100644
--- a/src/cryptometrics/components/dropdown/Dropdown.js
+++ b/src/cryptometrics/components/dropdown/Dropdown.js
@@ -2,6 +2,7 @@ import React, { useState, useEffect, useRef, useCallback } from "react";
 import classNames from "classnames";
 import { ChevronDownIcon } from "@heroicons/react/outline";
 import { useOnClickOutside } from "../../hooks";
+import DropdownItem from "./DropdownItem";
 
 function getCoin(list, id) {
   for (let i = 0; i < list.length; i++) {
@@ -58,20 +59,4 @@ function Dropdown({ list, value, setValue, disabled }) {
   );
 }
 
-function DropdownItem({ children, onClick, selected, disabled }) {
-  return (
-    <div
-      className={classNames("py-2 px-4 rounded-xl mx-2", {
-        "opacity-75 dark:text-gray-500": disabled,
-        "bg-white dark:text-black": selected,
-        "hover:bg-dark-600 dark:text-white cursor-pointer":
-          !disabled && !selected,
-      })}
-      onClick={selected || disabled ? undefined : onClick}
-    >
-      {children}
-    </div>
-  );
-}
-
 export default Dropdown;
diff --git a/src/cryptometrics/components/dropdown/DropdownItem.js b/src/cryptometrics/components/dropdown/DropdownItem.js
new file mode 100644
index 0000000..ba89336
--- /dev/null
+++ b/src/cryptometrics/components/dropdown/DropdownItem.js
@@ -0,0 +1,20 @@
+import classNames from "classnames";
+import React from "react";
+
+function DropdownItem({ children, onClick, selected, disabled }) {
+  return (
+    <div
+      className={classNames("py-2 px-4 rounded-xl mx-2", {
+        "opacity-75 dark:text-gray-500": disabled,
+        "bg-white dark:text-black": selected,
+        "hover:bg-dark-600 dark:text-white cursor-pointer":
+          !disabled && !selected,
+      })}
+      onClick={selected || disabled ? undefined : onClick}
+    >
+      {children}
+    </div>
+  );
+}
+
+export default DropdownItem;
diff --git a/src/cryptometrics/components/dropdown/FilterDropdown.js b/src/cryptometrics/components/dropdown/FilterDropdown.js
index ec8b87f..9889a8d 100644
--- a/src/cryptometrics/components/dropdown/FilterDropdown.js
+++ b/src/cryptometrics/components/dropdown/FilterDropdown.js
@@ -1,9 +1,8 @@
-import { ArrowRightIcon } from "@heroicons/react/outline";
-import classNames from "classnames";
 import React, { useState, useEffect, useRef } from "react";
-import Button from "../button/Button";
-import RadioInputForm from "../radio/RadioForm";
 import { CSSTransition } from "react-transition-group";
+import FilterDropdownItem from "./FilterDropdownItem";
+import SecondaryFilterDropdown from "./SecondaryFilterDropdown";
+import classNames from "classnames";
 
 export function FilterDropdown({
   filterOptions,
@@ -98,88 +97,4 @@ export function FilterDropdown({
   );
 }
 
-export function SecondaryFilterDropdown({
-  open,
-  onSelectedFilterChange,
-  radioOptions,
-  radioValue,
-  onRadioChange,
-  inputValue,
-  onInputChange,
-  onFilterAdd,
-  inputLeftSymbol,
-  inputRightSymbol,
-  inputType,
-}) {
-  return (
-    <div
-      className={classNames(
-        "dark:bg-dark-600 w-72 max-h-72 rounded-xl mt-2 transition-all duration-100 px-5 py-2 overflow-y-scroll shadow-lg shadow-dark-600",
-        {
-          block: open,
-          hidden: !open,
-        }
-      )}
-    >
-      <RadioInputForm
-        options={radioOptions}
-        radioValue={radioValue}
-        onRadioChange={onRadioChange}
-        inputValue={inputValue}
-        onInputChange={onInputChange}
-        inputLeftSymbol={inputLeftSymbol}
-        inputRightSymbol={inputRightSymbol}
-        inputType={inputType}
-        onSubmit={onFilterAdd}
-      />
-      <div className="flex flex-row space-x-2 mb-2">
-        <Button
-          className="bg-neutral-100 text-gray-700 font-semibold"
-          onClick={() => onSelectedFilterChange(null)}
-        >
-          Cancel
-        </Button>
-        <Button
-          className="bg-indigo-600 text-white font-semibold w-full"
-          onClick={onFilterAdd}
-          type="submit"
-          disabled={inputValue === ""}
-        >
-          Filter
-        </Button>
-      </div>
-    </div>
-  );
-}
-
-// selected: boolean
-function FilterDropdownItem({
-  children,
-  selected,
-  onClick,
-  id,
-  disabled = false,
-}) {
-  return (
-    <div
-      className={classNames(
-        "py-3 px-4 rounded-xl dark:text-neutral-100 border-1 transition-all duration-100 cursor-pointer",
-        {
-          "border-transparent": !selected,
-          "bg-dark-800  border-indigo-600 font-semibold": selected,
-          "hover:bg-dark-800": !disabled,
-        }
-      )}
-      onClick={disabled || !onClick ? undefined : () => onClick(id)}
-    >
-      <div className="flex flex-row items-center">
-        {children}
-        {selected && (
-          <span className="ml-auto">
-            <ArrowRightIcon className="w-4 h-4" />
-          </span>
-        )}
-      </div>
-    </div>
-  );
-}
+export default FilterDropdown;
diff --git a/src/cryptometrics/components/dropdown/FilterDropdownItem.js b/src/cryptometrics/components/dropdown/FilterDropdownItem.js
new file mode 100644
index 0000000..d9c4730
--- /dev/null
+++ b/src/cryptometrics/components/dropdown/FilterDropdownItem.js
@@ -0,0 +1,37 @@
+import React from "react";
+import classNames from "classnames";
+import { ArrowRightIcon } from "@heroicons/react/outline";
+
+// selected: boolean
+function FilterDropdownItem({
+  children,
+  selected,
+  onClick,
+  id,
+  disabled = false,
+}) {
+  return (
+    <div
+      className={classNames(
+        "py-3 px-4 rounded-xl dark:text-neutral-100 border-1 transition-all duration-100 cursor-pointer",
+        {
+          "border-transparent": !selected,
+          "bg-dark-800  border-indigo-600 font-semibold": selected,
+          "hover:bg-dark-800": !disabled,
+        }
+      )}
+      onClick={disabled || !onClick ? undefined : () => onClick(id)}
+    >
+      <div className="flex flex-row items-center">
+        {children}
+        {selected && (
+          <span className="ml-auto">
+            <ArrowRightIcon className="w-4 h-4" />
+          </span>
+        )}
+      </div>
+    </div>
+  );
+}
+
+export default FilterDropdownItem;
diff --git a/src/cryptometrics/components/dropdown/SecondaryFilterDropdown.js b/src/cryptometrics/components/dropdown/SecondaryFilterDropdown.js
new file mode 100644
index 0000000..ac78481
--- /dev/null
+++ b/src/cryptometrics/components/dropdown/SecondaryFilterDropdown.js
@@ -0,0 +1,60 @@
+import React from "react";
+import { Button } from "../button";
+import RadioInputForm from "../radio/RadioForm";
+import classNames from "classnames";
+
+export function SecondaryFilterDropdown({
+  open,
+  onSelectedFilterChange,
+  radioOptions,
+  radioValue,
+  onRadioChange,
+  inputValue,
+  onInputChange,
+  onFilterAdd,
+  inputLeftSymbol,
+  inputRightSymbol,
+  inputType,
+}) {
+  return (
+    <div
+      className={classNames(
+        "dark:bg-dark-600 w-72 max-h-72 rounded-xl mt-2 transition-all duration-100 px-5 py-2 overflow-y-scroll shadow-lg shadow-dark-600",
+        {
+          block: open,
+          hidden: !open,
+        }
+      )}
+    >
+      <RadioInputForm
+        options={radioOptions}
+        radioValue={radioValue}
+        onRadioChange={onRadioChange}
+        inputValue={inputValue}
+        onInputChange={onInputChange}
+        inputLeftSymbol={inputLeftSymbol}
+        inputRightSymbol={inputRightSymbol}
+        inputType={inputType}
+        onSubmit={onFilterAdd}
+      />
+      <div className="flex flex-row space-x-2 mb-2">
+        <Button
+          className="bg-neutral-100 text-gray-700 font-semibold"
+          onClick={() => onSelectedFilterChange(null)}
+        >
+          Cancel
+        </Button>
+        <Button
+          className="bg-indigo-600 text-white font-semibold w-full"
+          onClick={onFilterAdd}
+          type="submit"
+          disabled={inputValue === ""}
+        >
+          Filter
+        </Button>
+      </div>
+    </div>
+  );
+}
+
+export default SecondaryFilterDropdown;
diff --git a/src/cryptometrics/pages/index.js b/src/cryptometrics/pages/index.js
index 0a0f82d..b4421aa 100644
--- a/src/cryptometrics/pages/index.js
+++ b/src/cryptometrics/pages/index.js
@@ -19,7 +19,7 @@ import {
 } from "@heroicons/react/outline";
 import { useFilters, useOnClickOutside } from "../hooks";
 import { Filter, Filters } from "../components/filters";
-import { FilterDropdown } from "../components/dropdown/FilterDropdown";
+import FilterDropdown from "../components/dropdown/FilterDropdown";
 import { filterOptions } from "../constants";
 import {
   Table,
-- 
GitLab