UNPKG

react-mapfilter

Version:

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

185 lines (166 loc) 6.2 kB
import "core-js/modules/es.array.iterator"; import "core-js/modules/web.dom-collections.iterator"; import _indexOfInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/index-of"; import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter"; import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice"; import _JSON$stringify from "@babel/runtime-corejs3/core-js-stable/json/stringify"; import _findInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find"; import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map"; import _sortInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/sort"; import _Set from "@babel/runtime-corejs3/core-js-stable/set"; import _reduceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/reduce"; // @flow import * as React from 'react'; import Checkbox from './StyledCheckbox'; import ListIcon from '@material-ui/icons/List'; import { makeStyles } from '@material-ui/core/styles'; import ListItem from '@material-ui/core/ListItem'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import FilterSection from './FilterSection'; import OnlyButton from './OnlyButton'; import { getField } from '../lib/data_analysis'; import FormattedValue from '../internal/FormattedValue'; /*:: import type { Key, Filter, SelectOptions, SelectableFieldValue } from '../types'*/ // import {FIELD_TYPE_BOOLEAN, FIELD_TYPE_NUMBER} from '../../constants' const FilterItem = ({ onClick, checked, label, id, onOnlyClick }) => { const cx = useStyles(); return /*#__PURE__*/React.createElement(ListItem, { role: undefined, dense: true, button: true, onClick: onClick, className: cx.filterItem }, /*#__PURE__*/React.createElement(ListItemIcon, { className: cx.checkboxIcon }, /*#__PURE__*/React.createElement(Checkbox, { edge: "start", checked: checked, tabIndex: -1, disableRipple: true, inputProps: { 'aria-labelledby': id }, className: cx.checkbox })), /*#__PURE__*/React.createElement(ListItemText, { id: id, primary: label }), /*#__PURE__*/React.createElement(ListItemSecondaryAction, null, /*#__PURE__*/React.createElement(OnlyButton, { className: cx.onlyButton, onClick: onOnlyClick }))); }; /*:: type Props = { label: React.Node, fieldKey: Key, filter?: Filter | null, options: SelectOptions, onChangeFilter: (filter: Array<any> | null) => void }*/ const DiscreteFilter = ({ label, fieldKey, filter, options, onChangeFilter } /*: Props*/ ) => { var _context; const values /*: Array<number | string | boolean>*/ = _reduceInstanceProperty(options).call(options, (acc, cur) => { // Filter null values if (cur == null) return acc; if (typeof cur === 'object' && cur.value != null) acc.push(cur.value);else if (typeof cur !== 'object') acc.push(cur); return acc; }, []); const shownValues = valuesFromFilter(filter, values); const allValues = [...new _Set(_sortInstanceProperty(_context = [...shownValues, ...values]).call(_context))]; const handleClick = value => e => { if (shownValues.has(value)) shownValues.delete(value);else shownValues.add(value); const 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 ? ['in', fieldKey, ...shownValues] : ['!in', fieldKey, ...allValues]; onChangeFilter(newFilter); }; const handleOnlyClick = value => () => { 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, { title: label, icon: /*#__PURE__*/React.createElement(ListIcon, null), isFiltered: !!filter, onShowAllClick: () => onChangeFilter(null) }, _mapInstanceProperty(allValues).call(allValues, (v, i) => { // TODO use FormattedValue here const option = _findInstanceProperty(options).call(options, o => typeof o === 'object' && o !== null && o.value === v); const 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, { value: v, field: getField([], v) }); const key = _JSON$stringify(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, values = []) /*: Set<SelectableFieldValue>*/ { if (!filter || filter.length < 3) return new _Set(values); // $FlowFixMe - need to better define type for filter if (filter[0] === 'in') return new _Set(_sliceInstanceProperty(filter).call(filter, 2)); if (filter[0] === '!in') { const notShown = _sliceInstanceProperty(filter).call(filter, 2); const shown = _filterInstanceProperty(values).call(values, v => _indexOfInstanceProperty(notShown).call(notShown, v) < 0); return new _Set(shown); } return new _Set(values); } export default DiscreteFilter; const useStyles = makeStyles(theme => ({ 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