diff --git a/src/components/_fs-search-accordion.scss b/src/components/_fs-search-accordion.scss new file mode 100644 index 0000000..6cd5fbe --- /dev/null +++ b/src/components/_fs-search-accordion.scss @@ -0,0 +1,132 @@ +/** + * search-accordion.scss + * Define search accordion styles. + * + * @copyright Copyright (c) 2017-2020 Palantir.net + */ + +.fs-search-accordion { + margin-bottom: rhythm(1); + color: $gray-dark; + padding: 0; +} + +.fs-search-accordion__title { + @include adjust-font-size-to($sm-heading, 1); + display: block; + padding-right: 1.25rem; + padding-left: 1.25rem; + + &:hover, + &:focus, + &:active { + text-decoration: none; + } + + // Display plus symbol at initial state + &:after { + content: "+"; + float: right; + } +} + +.fs-search-accordion__checkbox-input { + @extend %input; +} + +.fs-search-accordion__checkbox-label { + cursor: pointer; + display: block; + padding: rhythm(.5) 0; + + @include breakpoint($bp2) { + @include adjust-font-size-to($label, .8); + padding: rhythm(.35) 0; + } +} + +.fs-search-accordion__content { + @extend %list; + margin: 0; + padding: rhythm(.5) 1.25rem; + + @media only screen and (min-width: 1025px) { + // Center date-picker which we can't set to display:block. + #solr-list-facet-ds_federated_date & { + text-align: center; + } + } + + @media only screen and (max-width: 425px) { + // Center date-picker which we can't set to display:block. + #solr-list-facet-ds_federated_date & { + text-align: center; + } + } + + @media only screen and (max-width: 1350px) and (min-width: 768px) { + #solr-list-facet-ds_federated_date & { + padding: rhythm(.5) .5rem; + } + } +} + +.fs-search-accordion__group, +.fs-search-accordion__subgroup { + list-style: none; + padding: 0; +} + +.fs-search-accordion__group-item, +.fs-search-accordion__content-item { + display: block; + margin: 0; + overflow: hidden; + + // Date widget overflow fix. + &#solr-list-facet-ds_federated_date { + overflow: visible; + + .fs-search-accordion__content-item { + overflow: visible; + } + } +} + +.fs-search-accordion__group { + @extend %list; + margin: 0; +} + +.fs-search-accordion__subgroup { + margin: 0 0 0 rhythm(.5); +} + +.fs-search-accordion__title { + @extend %h2; + border-bottom: solid 1px $gray-light; + padding-top: rhythm(.75); + padding-bottom: rhythm(.75); + + @include breakpoint($bp2) { + @include adjust-font-size-to($label, .8); + padding-top: rhythm(.3); + padding-bottom: rhythm(.3); + } + + &:active, + &:hover, + &:focus { + border-bottom: solid 1px darken($gray-light, 10); + outline: 0; + } + + &:hover { + cursor: pointer; + } + + // Replace plus symbol with en dash when search-accordion is open + &.js-fs-search-accordion-open:after { + content: "–"; + } +} diff --git a/src/components/federated-solr-faceted-search.js b/src/components/federated-solr-faceted-search.js index c3dd389..78982eb 100644 --- a/src/components/federated-solr-faceted-search.js +++ b/src/components/federated-solr-faceted-search.js @@ -106,7 +106,16 @@ class FederatedSolrFacetedSearch extends React.Component { gridTemplateColumns = '', reverseDesktopColumns = false, reverseMobileOrder = false, + sortFilterInAccordion = false, } = this.props.options.layoutAndClasses || {}; + const sortFilterComponent = ( + + ); return ( @@ -140,8 +149,11 @@ class FederatedSolrFacetedSearch extends React.Component { {...searchField} bootstrapCss={bootstrapCss} facets={facets} + sortFields={sortFields} truncateFacetListsAt={truncateFacetListsAt} onChange={onSearchFieldChange} + onSortFieldChange={onSortFieldChange} + sortFilterInAccordion={sortFilterInAccordion} /> ); }) @@ -164,11 +176,7 @@ class FederatedSolrFacetedSearch extends React.Component { {...this.props} onChange={onSearchFieldChange} /> - + {sortFilterInAccordion ? '' : sortFilterComponent}

sf.field === 'tm_rendered_item').value || this.props.options.showEmptySearchResults) ? 'solr-search-results-container__prompt fs-element-invisible' : 'solr-search-results-container__prompt'}>{this.props.options.searchPrompt || 'Please enter a search term.'}

sf.field === 'tm_rendered_item').value || this.props.options.showEmptySearchResults) ? 'solr-search-results-container__wrapper' : 'solr-search-results-container__wrapper fs-element-invisible'}> diff --git a/src/components/list-facet/index.js b/src/components/list-facet/index.js index 28155c0..9a46422 100644 --- a/src/components/list-facet/index.js +++ b/src/components/list-facet/index.js @@ -12,7 +12,22 @@ class FederatedListFacet extends React.Component { this.state = { filter: '', truncateFacetListsAt: props.truncateFacetListsAt, + sort: 'score', }; + this.onSelect = this.onSelect.bind(this); + } + + onSelect(event) { + this.setState({sort: event.target.value}); + + const sortField = event.target.value; + const foundIdx = this.props.sortFields.indexOf(sortField); + + if (foundIdx < 0) { + this.props.onSortFieldChange(sortField, "desc"); + } else { + this.props.onSortFieldChange(sortField, null); + } } handleClick(value) { @@ -99,9 +114,10 @@ class FederatedListFacet extends React.Component { collapse, hierarchy, options, + sortFields, + sortFilterInAccordion, } = this.props; const { truncateFacetListsAt } = this.state; - const siteList = options.siteList; const facetCounts = facets.filter((facet, i) => i % 2 === 1); const facetValues = facets.filter((facet, i) => i % 2 === 0); @@ -224,7 +240,37 @@ class FederatedListFacet extends React.Component { ); + }); + listFacetHierarchyLis.push( + sortFilterInAccordion + ? ( +
  • +
    {if (event.keyCode === 13) {this.toggleExpand()}}} + >Sort
    + +
      +
    • + +
    • +
    +
    +
  • + ) + : '', + ); // Render the group of accordion lis with their facet value checkbox lists. return listFacetHierarchyLis; } @@ -300,6 +346,8 @@ FederatedListFacet.propTypes = { onChange: PropTypes.func, onFacetSortChange: PropTypes.func, onSetCollapse: PropTypes.func, + sortFields: PropTypes.array, + sortFilterInAccordion: PropTypes.bool, query: PropTypes.object, truncateFacetListsAt: PropTypes.number, value: PropTypes.array, diff --git a/src/components/search-field-container.js b/src/components/search-field-container.js index 46f6496..59c3f15 100644 --- a/src/components/search-field-container.js +++ b/src/components/search-field-container.js @@ -3,7 +3,6 @@ import React from 'react'; import cx from 'classnames'; import AnimateHeight from 'react-animate-height'; - class FederatedSearchFieldContainer extends React.Component { constructor(props) { super(props); @@ -41,7 +40,12 @@ class FederatedSearchFieldContainer extends React.Component { } render() { - const { onNewSearch } = this.props; + const { onNewSearch, sortFilterComponent } = this.props; + // Grab env vars. + const { + sortFilterInAccordion = false, + } = this.props.options.layoutAndClasses || {}; + const height = this.state.expanded ? 'auto' : 0; return ( @@ -64,7 +68,12 @@ class FederatedSearchFieldContainer extends React.Component {

    Filter Results

    { this.props.resultsCount > 0 - ? (
      {this.props.children}
    ) + ? ( +
      + {this.props.children} + {sortFilterInAccordion ? sortFilterComponent : ''} +
    + ) :
    There are no results to filter.
    } @@ -78,10 +87,12 @@ class FederatedSearchFieldContainer extends React.Component { } } + FederatedSearchFieldContainer.propTypes = { children: PropTypes.array, onNewSearch: PropTypes.func, options: PropTypes.object, + sortFilterComponent: PropTypes.object, }; export default FederatedSearchFieldContainer; diff --git a/src/components/sort-menu/index.js b/src/components/sort-menu/index.js index 7f60ace..34f2aab 100644 --- a/src/components/sort-menu/index.js +++ b/src/components/sort-menu/index.js @@ -2,50 +2,55 @@ import PropTypes from 'prop-types'; import React from "react"; class FederatedSortMenu extends React.Component { - constructor(props) { - super(props); + constructor(props) { + super(props); - this.state = { - sort: 'score' - }; + this.state = { + sort: 'score', + }; this.onSelect = this.onSelect.bind(this); - } - - onSelect(event) { - this.setState({sort: event.target.value}); - - const sortField = event.target.value; - const foundIdx = this.props.sortFields.indexOf(sortField); - if (foundIdx < 0) { - this.props.onChange(sortField, "desc"); - } else { - this.props.onChange(sortField, null); - } - } - - render() { - const { sortFields } = this.props; - if (sortFields.length === 0) { return null; } - - return ( -
    + this.toggleExpand = this.toggleExpand.bind(this); + } + toggleExpand() { + this.props.onSetCollapse(this.props.field, !(this.props.collapse || false)); + } + + onSelect(event) { + this.setState({sort: event.target.value}); + + const sortField = event.target.value; + const foundIdx = this.props.sortFields.indexOf(sortField); + + if (foundIdx < 0) { + this.props.onChange(sortField, "desc"); + } else { + this.props.onChange(sortField, null); + } + } + + render() { + const { sortFields } = this.props; + if (sortFields.length === 0) { return null; } + + return ( +
    -
    - ); - } +
    + ); + } } FederatedSortMenu.propTypes = { - bootstrapCss: PropTypes.bool, - onChange: PropTypes.func, - sortFields: PropTypes.array + bootstrapCss: PropTypes.bool, + onChange: PropTypes.func, + sortFields: PropTypes.array, }; export default FederatedSortMenu;