Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FacetList: Prevent scrolling when ExtendedDescriptionPopover is open #73

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion es/components/browse/EmbeddedSearchView.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ export var EmbeddedSearchView = /*#__PURE__*/function (_React$PureComponent) {
passProps = _objectWithoutProperties(_this$props, ["href", "context", "currentAction", "searchHref", "navigate", "columns", "hideColumns", "facets", "aboveTableComponent", "aboveFacetListComponent", "facetListComponent", "columnExtensionMap", "onLoad", "filterFacetFxn", "filterColumnFxn", "windowWidth", "embeddedTableHeader", "embeddedTableFooter", "onClearFiltersVirtual", "isClearFiltersBtnVisible", "facetColumnClassName", "tableColumnClassName", "allowPostRequest"]); // If facets are null (hidden/excluded) and no props.tableColumnClassName set table col to be full width of container instead of the default set by ControlsAndResults.


var tableColumnClassName = propTableColumnClassName || (facets === null ? "col-12" : undefined); // Includes pass-through props like `maxHeight`, `hideFacets`, etc.
var tableColumnClassName = propTableColumnClassName || (facets === null ? "col-12" : undefined); // Includes pass-through props like `maxHeight`, `hideFacets`, `addToBodyClassList`, etc.

var viewProps = _objectSpread(_objectSpread({}, passProps), {}, {
aboveTableComponent: aboveTableComponent,
Expand Down
1 change: 0 additions & 1 deletion es/components/browse/SearchView.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ export var SearchView = /*#__PURE__*/function (_React$PureComponent) {
// As well as in ControlsAndResults.

var childViewProps = _objectSpread(_objectSpread({}, passProps), {}, {
// Includes pass-thru props like 'facetListComponent', 'aboveTableComponent', 'aboveFacetListComponent', etc.
currentAction: currentAction,
schemas: schemas,
windowWidth: windowWidth,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,11 @@
'use strict';

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

import React, { useMemo, useState, useRef } from 'react';
import memoize from 'memoize-one';
import PropTypes from 'prop-types';
import _ from 'underscore';
import Fade from 'react-bootstrap/esm/Fade';
import Popover from 'react-bootstrap/esm/Popover';
export function FacetListPopoverController(props) {
var children = props.children; // In this state we will store the entirety of the Popover JSX to display
// to allow flexibility in what to display in Popover contents
// in case we add more types of Popovers later.

var _useState = useState(null),
_useState2 = _slicedToArray(_useState, 2),
openPopoverID = _useState2[0],
setOpenPopoverID = _useState2[1];

var adjustedChildren = React.Children.map(children, function (child) {
return /*#__PURE__*/React.cloneElement(child, {
openPopoverID: openPopoverID,
setOpenPopoverID: setOpenPopoverID
});
});
return /*#__PURE__*/React.createElement(React.Fragment, null, adjustedChildren);
}
/**
* @todo Potentially refactor to use ReactDOM.createPortal along w. semi-opaque dark background that will close this onClick.
* @todo Alternatively if we don't want the background, could attach event listener to window maybe..
Expand Down
35 changes: 23 additions & 12 deletions es/components/browse/components/FacetList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ export var FacetList = /*#__PURE__*/function (_React$PureComponent) {
filteringFieldTerm: null // will contain `{ field: string, term: string|[from, to] }`. Used to show loading indicators on clicked-on terms.

};
_this.scrollContainerRef = /*#__PURE__*/React.createRef();
return _this;
}

Expand Down Expand Up @@ -567,13 +568,24 @@ export var FacetList = /*#__PURE__*/function (_React$PureComponent) {

if (openFacets !== prevOpenFacets) {
ReactTooltip.rebuild();
}
} // Disable scrolling while popover is open FacetList scroll container & body (if possible)


if (openPopover !== prevOpenPopover) {
var hasBodyScrollHandlers = typeof addToBodyClassList === "function" && typeof removeFromBodyClassList === "function";

if (openPopover !== prevOpenPopover && typeof addToBodyClassList === "function" && typeof removeFromBodyClassList === "function") {
if (!openPopover) {
removeFromBodyClassList("overflow-hidden");
if (hasBodyScrollHandlers) {
removeFromBodyClassList("overflow-hidden");
}

this.scrollContainerRef.current.classList.remove("overflow-hidden");
} else if (openPopover && !prevOpenPopover) {
addToBodyClassList("overflow-hidden");
if (hasBodyScrollHandlers) {
addToBodyClassList("overflow-hidden");
}

this.scrollContainerRef.current.classList.add("overflow-hidden");
}
}

Expand Down Expand Up @@ -820,13 +832,6 @@ export var FacetList = /*#__PURE__*/function (_React$PureComponent) {
}, "No facets available");
}

var bodyProps = {
className: "facets-body" + (typeof maxHeight === "number" ? " has-max-height" : ""),
style: typeof maxHeight === "number" ? {
maxHeight: maxHeight
} : null
};

var _this$renderFacetComp3 = this.renderFacetComponents(),
staticFacetElements = _this$renderFacetComp3.staticFacetElements,
selectableFacetElements = _this$renderFacetComp3.selectableFacetElements;
Expand All @@ -841,7 +846,13 @@ export var FacetList = /*#__PURE__*/function (_React$PureComponent) {
showClearFiltersButton: showClearFiltersButton
}, {
onCollapseFacets: this.handleCollapseAllFacets
})), /*#__PURE__*/React.createElement("div", bodyProps, selectableFacetElements, staticFacetElements.length > 0 ? /*#__PURE__*/React.createElement("div", {
})), /*#__PURE__*/React.createElement("div", {
ref: this.scrollContainerRef,
className: "facets-body" + (typeof maxHeight === "number" ? " has-max-height" : ""),
style: typeof maxHeight === "number" ? {
maxHeight: maxHeight
} : null
}, selectableFacetElements, staticFacetElements.length > 0 ? /*#__PURE__*/React.createElement("div", {
className: "row facet-list-separator"
}, /*#__PURE__*/React.createElement("div", {
className: "col-12"
Expand Down
2 changes: 1 addition & 1 deletion src/components/browse/EmbeddedSearchView.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export class EmbeddedSearchView extends React.PureComponent {

// If facets are null (hidden/excluded) and no props.tableColumnClassName set table col to be full width of container instead of the default set by ControlsAndResults.
const tableColumnClassName = propTableColumnClassName || (facets === null ? "col-12" : undefined);
// Includes pass-through props like `maxHeight`, `hideFacets`, etc.
// Includes pass-through props like `maxHeight`, `hideFacets`, `addToBodyClassList`, etc.
const viewProps = { ...passProps, aboveTableComponent, aboveFacetListComponent, facetListComponent, tableColumnClassName, facetColumnClassName };
const filterFacetFxn = propFacetFilterFxn || this.filterFacetFxn;

Expand Down
3 changes: 2 additions & 1 deletion src/components/browse/SearchView.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ export class SearchView extends React.PureComponent {
// As well as in ControlsAndResults.

const childViewProps = {
...passProps, // Includes pass-thru props like 'facetListComponent', 'aboveTableComponent', 'aboveFacetListComponent', etc.
// Includes pass-thru props like 'facetListComponent', 'aboveTableComponent', 'aboveFacetListComponent', 'addToBodyClassList', etc.
...passProps,
currentAction,
schemas,
windowWidth,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,6 @@ import Fade from 'react-bootstrap/esm/Fade';
import Popover from 'react-bootstrap/esm/Popover';


export function FacetListPopoverController (props) {
const { children } = props;
// In this state we will store the entirety of the Popover JSX to display
// to allow flexibility in what to display in Popover contents
// in case we add more types of Popovers later.
const [ openPopoverID, setOpenPopoverID ] = useState(null);
const adjustedChildren = React.Children.map(children, function(child){
return React.cloneElement(child, { openPopoverID, setOpenPopoverID });
});
return (
<React.Fragment>
{ adjustedChildren }

</React.Fragment>
);
}


/**
* @todo Potentially refactor to use ReactDOM.createPortal along w. semi-opaque dark background that will close this onClick.
* @todo Alternatively if we don't want the background, could attach event listener to window maybe..
Expand Down
25 changes: 16 additions & 9 deletions src/components/browse/components/FacetList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ export class FacetList extends React.PureComponent {
openPopover: null, // will contain `{ ref: React Ref, popover: JSX element/component }`. We might want to move this functionality up into like App.js.
filteringFieldTerm: null // will contain `{ field: string, term: string|[from, to] }`. Used to show loading indicators on clicked-on terms.
};

this.scrollContainerRef = React.createRef();
}

componentDidMount(){
Expand Down Expand Up @@ -490,11 +492,19 @@ export class FacetList extends React.PureComponent {
ReactTooltip.rebuild();
}

if (openPopover !== prevOpenPopover && typeof addToBodyClassList === "function" && typeof removeFromBodyClassList === "function") {
// Disable scrolling while popover is open FacetList scroll container & body (if possible)
if (openPopover !== prevOpenPopover) {
const hasBodyScrollHandlers = typeof addToBodyClassList === "function" && typeof removeFromBodyClassList === "function";
if (!openPopover) {
removeFromBodyClassList("overflow-hidden");
if (hasBodyScrollHandlers) {
removeFromBodyClassList("overflow-hidden");
}
this.scrollContainerRef.current.classList.remove("overflow-hidden");
} else if (openPopover && !prevOpenPopover) {
addToBodyClassList("overflow-hidden");
if (hasBodyScrollHandlers) {
addToBodyClassList("overflow-hidden");
}
this.scrollContainerRef.current.classList.add("overflow-hidden");
}
}

Expand Down Expand Up @@ -684,18 +694,15 @@ export class FacetList extends React.PureComponent {
);
}

const bodyProps = {
className: "facets-body" + (typeof maxHeight === "number" ? " has-max-height" : ""),
style: typeof maxHeight === "number" ? { maxHeight } : null
};

const { staticFacetElements, selectableFacetElements } = this.renderFacetComponents();

return (
<React.Fragment>
<div className="facets-container facets with-header-bg" data-context-loading={isContextLoading}>
<FacetListHeader {...{ openFacets, title, onClearFilters, showClearFiltersButton }} onCollapseFacets={this.handleCollapseAllFacets} />
<div {...bodyProps}>
<div ref={this.scrollContainerRef}
className={"facets-body" + (typeof maxHeight === "number" ? " has-max-height" : "")}
style={typeof maxHeight === "number" ? { maxHeight } : null}>
{ selectableFacetElements }
{ staticFacetElements.length > 0 ?
<div className="row facet-list-separator">
Expand Down