redux-search-filter
Version:
[![NPM version][npm-image]][npm-url] [![build status][travis-image]][travis-url] [![Test coverage][codecov-image]][codecov-url] [![npm download][download-image]][download-url]
79 lines (70 loc) • 2.24 kB
JavaScript
import { Component, createElement } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import lodashProperty from 'lodash-es/property';
import { updateFilter, setOperator, setNegated } from './actions';
import filterOneSelector from './filterOneSelector';
import * as kinds from './constants/kinds';
const specialProps = new Set(['component', 'data', 'filterUpdate', 'filters']);
class ConnectedFilter extends Component {
constructor(props) {
super(props);
this.setupSelector();
}
setupSelector() {
const data = (props) => props.data;
const name = (props) => props.name;
const propFunc = (props) => lodashProperty(props.prop);
const kind = (props) => props.kind;
const filters = (props) => props.filters;
this.selector = createSelector(
data,
name,
propFunc,
kind,
filters,
filterOneSelector
);
}
render() {
const currentFilter = this.props.filters
? this.props.filters.get(this.props.name)
: null;
const newProps = {
onChange: this.props.filterUpdate
};
for (var propName in this.props) {
if (!specialProps.has(propName)) {
newProps[propName] = this.props[propName];
}
}
if (this.props.kind === kinds.range) {
newProps.range = this.selector(this.props);
newProps.value = currentFilter;
} else {
newProps.options = this.selector(this.props);
newProps.filter = currentFilter;
}
return createElement(this.props.component, newProps);
}
}
export default connect(
(state, props) => {
const searchFilterName = props.searchFilter.name;
return {
data: props.searchFilter.getData(state),
filters: state.searchFilter.get(searchFilterName)
};
},
(dispatch, props) => {
const name = props.searchFilter.name;
return {
filterUpdate: (value) =>
dispatch(updateFilter(name, props.name, props.prop, props.kind, value)),
setOperator: (value) =>
dispatch(setOperator(name, props.name, props.prop, props.kind, value)),
setNegated: (value) =>
dispatch(setNegated(name, props.name, props.prop, props.kind, value))
};
}
)(ConnectedFilter);