UNPKG

react-mapfilter

Version:

These components are designed for viewing data in Mapeo. They share a common interface:

228 lines (185 loc) 8.29 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property"); _Object$defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _indexOf = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/index-of")); var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice")); var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/json/stringify")); var _find = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/find")); var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map")); var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat")); var _sort = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/sort")); var _set = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/set")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/toConsumableArray")); var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/typeof")); var _reduce = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/reduce")); var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter")); var React = _interopRequireWildcard(require("react")); var _StyledCheckbox = _interopRequireDefault(require("./StyledCheckbox")); var _List = _interopRequireDefault(require("@material-ui/icons/List")); var _styles = require("@material-ui/core/styles"); var _ListItem = _interopRequireDefault(require("@material-ui/core/ListItem")); var _ListItemIcon = _interopRequireDefault(require("@material-ui/core/ListItemIcon")); var _ListItemSecondaryAction = _interopRequireDefault(require("@material-ui/core/ListItemSecondaryAction")); var _ListItemText = _interopRequireDefault(require("@material-ui/core/ListItemText")); var _FilterSection = _interopRequireDefault(require("./FilterSection")); var _OnlyButton = _interopRequireDefault(require("./OnlyButton")); var _data_analysis = require("../lib/data_analysis"); var _FormattedValue = _interopRequireDefault(require("../internal/FormattedValue")); // @flow // import {FIELD_TYPE_BOOLEAN, FIELD_TYPE_NUMBER} from '../../constants' var FilterItem = function FilterItem(_ref) { var onClick = _ref.onClick, checked = _ref.checked, label = _ref.label, id = _ref.id, onOnlyClick = _ref.onOnlyClick; var cx = useStyles(); return /*#__PURE__*/React.createElement(_ListItem.default, { role: undefined, dense: true, button: true, onClick: onClick, className: cx.filterItem }, /*#__PURE__*/React.createElement(_ListItemIcon.default, { className: cx.checkboxIcon }, /*#__PURE__*/React.createElement(_StyledCheckbox.default, { edge: "start", checked: checked, tabIndex: -1, disableRipple: true, inputProps: { 'aria-labelledby': id }, className: cx.checkbox })), /*#__PURE__*/React.createElement(_ListItemText.default, { id: id, primary: label }), /*#__PURE__*/React.createElement(_ListItemSecondaryAction.default, null, /*#__PURE__*/React.createElement(_OnlyButton.default, { className: cx.onlyButton, onClick: onOnlyClick }))); }; /*:: type Props = { label: React.Node, fieldKey: Key, filter?: Filter | null, options: SelectOptions, onChangeFilter: (filter: Array<any> | null) => void }*/ var DiscreteFilter = function DiscreteFilter(_ref2) { var _context, _context2; var label = _ref2.label, fieldKey = _ref2.fieldKey, filter = (0, _filter.default)(_ref2), options = _ref2.options, onChangeFilter = _ref2.onChangeFilter; var values /*: Array<number | string | boolean>*/ = (0, _reduce.default)(options).call(options, function (acc, cur) { // Filter null values if (cur == null) return acc; if ((0, _typeof2.default)(cur) === 'object' && cur.value != null) acc.push(cur.value);else if ((0, _typeof2.default)(cur) !== 'object') acc.push(cur); return acc; }, []); var shownValues = valuesFromFilter(filter, values); var allValues = (0, _toConsumableArray2.default)(new _set.default((0, _sort.default)(_context = (0, _concat.default)(_context2 = []).call(_context2, (0, _toConsumableArray2.default)(shownValues), (0, _toConsumableArray2.default)(values))).call(_context))); var handleClick = function handleClick(value) { return function (e) { var _context3, _context4; if (shownValues.has(value)) shownValues.delete(value);else shownValues.add(value); var newFilter = // If all items are selected we're implicitly including undefined and null // values, so we clear the filter altogether if everything is selected shownValues.size === allValues.length ? null : shownValues.size > 0 ? (0, _concat.default)(_context3 = ['in', fieldKey]).call(_context3, (0, _toConsumableArray2.default)(shownValues)) : (0, _concat.default)(_context4 = ['!in', fieldKey]).call(_context4, (0, _toConsumableArray2.default)(allValues)); onChangeFilter(newFilter); }; }; var handleOnlyClick = function handleOnlyClick(value) { return function () { onChangeFilter(['in', fieldKey, value]); }; }; // Don't render the filter if there is nothing to choose from if (!allValues || allValues.length === 0) return null; return /*#__PURE__*/React.createElement(_FilterSection.default, { title: label, icon: /*#__PURE__*/React.createElement(_List.default, null), isFiltered: !!filter, onShowAllClick: function onShowAllClick() { return onChangeFilter(null); } }, (0, _map.default)(allValues).call(allValues, function (v, i) { // TODO use FormattedValue here var option = (0, _find.default)(options).call(options, function (o) { return (0, _typeof2.default)(o) === 'object' && o !== null && o.value === v; }); var label = option ? // $FlowFixMe - pretty sure the find above means this must have a label prop option.label : v == null ? '[No Value]' : /*#__PURE__*/ // This is kind of a hack just to re-use code that detects and formats dates if they are options React.createElement(_FormattedValue.default, { value: v, field: (0, _data_analysis.getField)([], v) }); var key = (0, _stringify.default)(v); return /*#__PURE__*/React.createElement(FilterItem, { key: key, id: key, label: label, checked: shownValues.has(v), onClick: handleClick(v), onOnlyClick: handleOnlyClick(v) }); })); }; function valuesFromFilter(filter) /*: Set<SelectableFieldValue>*/ { var values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; if (!filter || filter.length < 3) return new _set.default(values); // $FlowFixMe - need to better define type for filter if (filter[0] === 'in') return new _set.default((0, _slice.default)(filter).call(filter, 2)); if (filter[0] === '!in') { var notShown = (0, _slice.default)(filter).call(filter, 2); var shown = (0, _filter.default)(values).call(values, function (v) { return (0, _indexOf.default)(notShown).call(notShown, v) < 0; }); return new _set.default(shown); } return new _set.default(values); } var _default = DiscreteFilter; exports.default = _default; var useStyles = (0, _styles.makeStyles)(function (theme) { return { filterItem: { paddingTop: 0, paddingBottom: 0, '& $onlyButton': { display: 'none' }, '&:hover $onlyButton': { display: 'block' } }, onlyButton: { fontSize: 12, lineHeight: '16px', minWidth: 'auto' }, checkboxIcon: { minWidth: 36, paddingLeft: 4 }, checkbox: { padding: 0, paddingLeft: 12, '&:hover': { backgroundColor: 'inherit !important' } } }; }); //# sourceMappingURL=DiscreteFilter.js.map