diff --git a/package-lock.json b/package-lock.json index 0692afacc..e768a40e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "auspice", - "version": "2.29.1", + "version": "2.31.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -15461,6 +15461,11 @@ "react-transition-group": "^1.2.0" } }, + "react-collapsible": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/react-collapsible/-/react-collapsible-2.8.4.tgz", + "integrity": "sha512-oG4yOk6AGKswe0OD/8t3/nf4Rgj4UhlZUUvqL5jop0/ez02B3dBDmNvs3sQz0PcTpJvt0ai8zF7Atd1SzN/UNw==" + }, "react-dom": { "version": "16.8.6", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", diff --git a/package.json b/package.json index 91887172f..8410bd2dc 100644 --- a/package.json +++ b/package.json @@ -101,6 +101,7 @@ "query-string": "^4.2.3", "react": "^16.8.6", "react-addons-css-transition-group": "^15.6.0", + "react-collapsible": "^2.8.4", "react-dom": "^16.8.6", "react-ga": "^2.2.0", "react-helmet": "^5.2.1", diff --git a/src/components/framework/footer.js b/src/components/framework/footer.js index c4a03c335..630ffaf33 100644 --- a/src/components/framework/footer.js +++ b/src/components/framework/footer.js @@ -1,7 +1,9 @@ import React, { Suspense, lazy } from "react"; import { connect } from "react-redux"; import styled from 'styled-components'; +import Collapsible from "react-collapsible"; import { withTranslation } from "react-i18next"; +import {FaAngleUp, FaAngleDown} from "react-icons/fa"; import { dataFont } from "../../globalStyles"; import Flex from "./flex"; import { applyFilter } from "../../actions/tree"; @@ -92,8 +94,8 @@ const FooterStyles = styled.div` } .line { - margin-top: 20px; - margin-bottom: 20px; + margin-top: 15px; + margin-bottom: 15px; border-bottom: 1px solid #CCC; } @@ -163,6 +165,24 @@ const removeFiltersButton = (dispatch, filterNames, outerClassName, label) => ( ); +const TitleContainer = styled.div` + display: flex; + justify-content: space-between; + margin: 0px; + padding: 0px; +`; +const IconContainer = styled.span` + font-size: 22px; + font-weight: 500; +`; + +const CollapseTitle = ({name, isExpanded=false}) => ( + + {name} + {isExpanded ? : } + +); + @connect((state) => { return { @@ -197,30 +217,39 @@ class Footer extends React.Component { const totalStateCount = this.props.totalStateCounts[filterName]; const filterTitle = this.props.metadata.colorings[filterName] ? this.props.metadata.colorings[filterName].title : filterName; const activeFilterItems = this.props.activeFilters[filterName].filter((x) => x.active).map((x) => x.value); + const title = (
+ {t("Filter by {{filterTitle}}", {filterTitle: filterTitle}) + ` (n=${totalStateCount.size})`} + {this.props.activeFilters[filterName].length ? removeFiltersButton(this.props.dispatch, [filterName], "inlineRight", t("Clear {{filterName}} filter", { filterName: filterName})) : null} +
); return (
- {t("Filter by {{filterTitle}}", {filterTitle: filterTitle})} - {this.props.activeFilters[filterName].length ? removeFiltersButton(this.props.dispatch, [filterName], "inlineRight", t("Clear {{filterName}} filter", { filterName: filterName})) : null} -
- - { - Array.from(totalStateCount.keys()) - .filter((itemName) => isValueValid(itemName)) // remove invalid values present across the tree - .sort() // filters are sorted alphabetically - .map((itemName) => ( - dispatchFilter(this.props.dispatch, this.props.activeFilters, filterName, itemName)} - > - - {`${itemName} (${totalStateCount.get(itemName)})`} - - - )) - } - -
+ } + trigger={} + triggerStyle={{cursor: "pointer", textDecoration: "none"}} + transitionTime={100} + > +
+ + { + Array.from(totalStateCount.keys()) + .filter((itemName) => isValueValid(itemName)) // remove invalid values present across the tree + .sort() // filters are sorted alphabetically + .map((itemName) => ( + dispatchFilter(this.props.dispatch, this.props.activeFilters, filterName, itemName)} + > + + {`${itemName} (${totalStateCount.get(itemName)})`} + + + )) + } + +
+
); }