diff --git a/package.json b/package.json index 9c3a1354..41ddbbdc 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,16 @@ "extends": [ "react-app", "react-app/jest" + ], + "overrides": [ + { + "files": [ "src/components/*/*.js" ], + "rules": { + "react/prop-types": "error", + "react/require-default-props": "error", + "react/default-props-match-prop-types": "error" + } + } ] }, "browserslist": { diff --git a/src/components/Button/index.js b/src/components/Button/index.js index 217657d5..a54dc9d5 100644 --- a/src/components/Button/index.js +++ b/src/components/Button/index.js @@ -1,4 +1,5 @@ import React from "react"; +import PropTypes from 'prop-types'; import classNames from "classnames"; const Button = ({ children, disabled, onClick }) => { @@ -16,3 +17,15 @@ const Button = ({ children, disabled, onClick }) => { }; export default Button; + +Button.propTypes = { + children: PropTypes.node, + disabled: PropTypes.bool, + onClick: PropTypes.func.isRequired, +}; + +Button.defaultProps = { + children: null, + disabled: false, +}; + diff --git a/src/components/Checkbox/index.js b/src/components/Checkbox/index.js index f3a63cd3..780b9b49 100644 --- a/src/components/Checkbox/index.js +++ b/src/components/Checkbox/index.js @@ -1,4 +1,5 @@ import React from "react"; +import PropTypes from 'prop-types'; const Checkbox = ({ name, selected, onClick }) => { return ( @@ -17,3 +18,14 @@ const Checkbox = ({ name, selected, onClick }) => { }; export default Checkbox; + +Checkbox.propTypes = { + name: PropTypes.string, + selected: PropTypes.bool, + onClick: PropTypes.func.isRequired, +}; + +Checkbox.defaultProps = { + name: null, + selected: false, +}; diff --git a/src/components/Dropdown/index.js b/src/components/Dropdown/index.js index d6fa75da..808a5926 100644 --- a/src/components/Dropdown/index.js +++ b/src/components/Dropdown/index.js @@ -1,6 +1,7 @@ import Button from "../DropdownButton"; import { Listbox } from "@headlessui/react"; import React from "react"; +import PropTypes from 'prop-types'; import { SelectorIcon } from "@heroicons/react/solid"; const Dropdown = ({ name, disabled, value, setValue, customStyle, Icon }) => { @@ -95,3 +96,20 @@ const Dropdown = ({ name, disabled, value, setValue, customStyle, Icon }) => { }; export default Dropdown; + +Dropdown.propTypes = { + name: PropTypes.string, + disabled: PropTypes.bool, + value: PropTypes.string, + setValue: PropTypes.func.isRequired, + customStyle: PropTypes.string, + Icon: PropTypes.elementType, +}; + +Dropdown.defaultProps = { + name: null, + disabled: false, + value: null, + customStyle: '', + Icon: null, +}; diff --git a/src/components/DropdownButton/index.js b/src/components/DropdownButton/index.js index e3393d6c..d75e4a80 100644 --- a/src/components/DropdownButton/index.js +++ b/src/components/DropdownButton/index.js @@ -1,5 +1,6 @@ import { CheckIcon } from "@heroicons/react/solid"; import React from "react"; +import PropTypes from 'prop-types'; import classNames from "classnames"; const Button = ({ text, active, selected }) => { @@ -20,3 +21,15 @@ const Button = ({ text, active, selected }) => { }; export default Button; + +Button.propTypes = { + text: PropTypes.string, + active: PropTypes.bool, + selected: PropTypes.bool, +}; + +Button.defaultProps = { + text: null, + active: false, + selected: false, +}; diff --git a/src/components/Layout/Dialogue.js b/src/components/Layout/Dialogue.js index de6d07c4..5e83b601 100644 --- a/src/components/Layout/Dialogue.js +++ b/src/components/Layout/Dialogue.js @@ -1,5 +1,6 @@ import { Dialog, Transition } from "@headlessui/react"; import React, { Fragment } from "react"; +import PropTypes from 'prop-types'; import DocumentationIcon from "../../assets/images/documentation_icon.png"; import GitHubIcon from "../../assets/images/github_icon.png"; @@ -133,3 +134,12 @@ const HelpDialog = ({ isOpen, setIsOpen }) => { }; export default HelpDialog; + +HelpDialog.propTypes = { + isOpen: PropTypes.bool, + setIsOpen: PropTypes.func.isRequired, +}; + +HelpDialog.defaultProps = { + isOpen: false, +}; diff --git a/src/components/Layout/Navbar.js b/src/components/Layout/Navbar.js index e03081f0..b14a75d2 100644 --- a/src/components/Layout/Navbar.js +++ b/src/components/Layout/Navbar.js @@ -4,6 +4,7 @@ import { QuestionMarkCircleIcon, } from "@heroicons/react/outline"; import React, { useState } from "react"; +import PropTypes from 'prop-types'; import Dialogue from "./Dialogue"; import Logo from "../../assets/images/Group 295.svg"; @@ -66,3 +67,11 @@ const Navbar = ({ setSidebarOpen }) => { }; export default Navbar; + +Navbar.propTypes = { + setSidebarOpen: PropTypes.func, +}; + +Navbar.defaultProps = { + setSidebarOpen: () => null, +}; diff --git a/src/components/Layout/Sidebar.js b/src/components/Layout/Sidebar.js index 53a6a5dc..8ddd39af 100644 --- a/src/components/Layout/Sidebar.js +++ b/src/components/Layout/Sidebar.js @@ -1,6 +1,7 @@ import { ChevronDownIcon, XIcon } from "@heroicons/react/outline"; import { Dialog, Disclosure, Transition } from "@headlessui/react"; import React, { Fragment } from "react"; +import PropTypes from 'prop-types'; import Logo from "../../assets/images/Group 295.svg"; @@ -130,3 +131,15 @@ const Sidebar = ({ setSidebarOpen, sidebarOpen, labels }) => { }; export default Sidebar; + +Sidebar.propTypes = { + setSidebarOpen: PropTypes.func.isRequired, + sidebarOpen: PropTypes.bool, + labels: PropTypes.string, +}; + +Sidebar.defaultProps = { + sidebarOpen: false, + labels: null, +}; + diff --git a/src/components/Layout/index.js b/src/components/Layout/index.js index 6a3dd8dc..0147bea8 100644 --- a/src/components/Layout/index.js +++ b/src/components/Layout/index.js @@ -1,4 +1,5 @@ import React, { useState } from "react"; +import PropTypes from 'prop-types'; import Navbar from "./Navbar"; import Sidebar from "./Sidebar"; @@ -20,3 +21,13 @@ export default function Layout({ children, labels }) { ); } + +Layout.propTypes = { + children: PropTypes.node, + labels: PropTypes.string, +}; + +Layout.defaultProps = { + children: null, + labels: null, +}; diff --git a/src/components/MultiSelectDropdown/index.js b/src/components/MultiSelectDropdown/index.js index 610739ca..342d387a 100644 --- a/src/components/MultiSelectDropdown/index.js +++ b/src/components/MultiSelectDropdown/index.js @@ -3,6 +3,7 @@ import { ChevronDownIcon } from "@heroicons/react/outline"; import { Listbox } from "@headlessui/react"; import Pill from "../Pill"; import React from "react"; +import PropTypes from 'prop-types'; const MultipleSelectDropdown = ({ name, @@ -58,3 +59,17 @@ const MultipleSelectDropdown = ({ ); export default MultipleSelectDropdown; + +MultipleSelectDropdown.propTypes = { + name: PropTypes.string, + values: PropTypes.arrayOf(PropTypes.string), + setSelectedValues: PropTypes.func.isRequired, + data: PropTypes.arrayOf(PropTypes.string), + removeValue: PropTypes.func.isRequired, +}; + +MultipleSelectDropdown.defaultProps = { + name: null, + values: [], + data: [], +}; diff --git a/src/components/Pill/index.js b/src/components/Pill/index.js index 6ebc4383..4ecf126a 100644 --- a/src/components/Pill/index.js +++ b/src/components/Pill/index.js @@ -1,4 +1,5 @@ import React from "react"; +import PropTypes from 'prop-types'; import { XCircleIcon } from "@heroicons/react/solid"; const Pill = ({ text, onClose, equal }) => { @@ -16,3 +17,15 @@ const Pill = ({ text, onClose, equal }) => { }; export default Pill; + +Pill.propTypes = { + text: PropTypes.string, + onClose: PropTypes.func, + equal: PropTypes.bool, +}; + +Pill.defaultProps = { + text: null, + onClose: null, + equal: false, +}; diff --git a/src/components/PillFilter/index.js b/src/components/PillFilter/index.js index 3596a2e3..b17570f1 100644 --- a/src/components/PillFilter/index.js +++ b/src/components/PillFilter/index.js @@ -1,4 +1,5 @@ import React from "react"; +import PropTypes from 'prop-types'; import className from "classnames"; const PillFilter = ({ text, onClick, selected }) => { @@ -17,3 +18,14 @@ const PillFilter = ({ text, onClick, selected }) => { }; export default PillFilter; + +PillFilter.propTypes = { + text: PropTypes.string, + onClick: PropTypes.func.isRequired, + selected: PropTypes.bool, +}; + +PillFilter.defaultProps = { + text: null, + selected: false, +}; diff --git a/src/components/PillFilterList/index.js b/src/components/PillFilterList/index.js index 4970120b..47599402 100644 --- a/src/components/PillFilterList/index.js +++ b/src/components/PillFilterList/index.js @@ -1,4 +1,5 @@ import React, { useRef, useState } from "react"; +import PropTypes from 'prop-types'; import PillFilter from "../PillFilter"; import className from "classnames"; @@ -38,17 +39,17 @@ export function PillFilterList({ x, onAdd, onRemove, values }) { "max-h-[5rem] overflow-hidden": !selectedShowMore, })} > - {x.map((x) => ( + {x.map((item) => ( { - if (selected.includes(x)) { - onRemove(x) - setSelected([...selected.filter((val) => val !== x)]); + if (selected.includes(item)) { + onRemove(item) + setSelected([...selected.filter((val) => val !== item)]); } else { - onAdd(x) - setSelected([...selected, x]); + onAdd(item) + setSelected([...selected, item]); } }} /> @@ -65,3 +66,15 @@ export function PillFilterList({ x, onAdd, onRemove, values }) { ); } + +PillFilterList.propTypes = { + x: PropTypes.arrayOf(PropTypes.string), + onAdd: PropTypes.func.isRequired, + onRemove: PropTypes.func.isRequired, + values: PropTypes.arrayOf(PropTypes.string), +}; + +PillFilterList.defaultProps = { + x: [], + values: [], +}; diff --git a/src/components/SearchableDropdown/index.js b/src/components/SearchableDropdown/index.js index ed97977c..bff50363 100644 --- a/src/components/SearchableDropdown/index.js +++ b/src/components/SearchableDropdown/index.js @@ -1,4 +1,5 @@ import React, { memo, useState } from "react"; +import PropTypes from 'prop-types'; import { Combobox } from "@headlessui/react"; import DropdownButton from "../DropdownButton"; @@ -65,3 +66,22 @@ const SearchableDropdown = ({ data, setValue, value, label, defaultValue }) => { }; export default memo(SearchableDropdown); + +SearchableDropdown.propTypes = { + data: PropTypes.arrayOf(PropTypes.shape({ + name: PropTypes.string, + })), + value: PropTypes.shape({ + name: PropTypes.string, + }), + setValue: PropTypes.func.isRequired, + label: PropTypes.string, + defaultValue: PropTypes.string, +}; + +SearchableDropdown.defaultProps = { + data: [], + value: null, + label: null, + defaultValue: null, +}; diff --git a/src/components/SideDialog/index.js b/src/components/SideDialog/index.js index ac9606cb..3d87a857 100644 --- a/src/components/SideDialog/index.js +++ b/src/components/SideDialog/index.js @@ -1,5 +1,6 @@ import { Dialog, Transition } from "@headlessui/react"; import React, { Fragment } from "react"; +import PropTypes from 'prop-types'; import { XIcon } from "@heroicons/react/outline"; import moment from "moment"; @@ -111,3 +112,18 @@ export default function SideDialog({ open, setOpen, data }) { ); } + +SideDialog.propTypes = { + open: PropTypes.bool, + setOpen: PropTypes.func.isRequired, + data: PropTypes.shape({ + time: PropTypes.string, + p_tags: PropTypes.string, + p_metadata: PropTypes.string, + }) +}; + +SideDialog.defaultProps = { + open: false, + data: {}, +};