UNPKG

fk-react-ui-components

Version:

Step 1 : Create a file in [ Seeds / Plants / Trees ] <br> Step 2 : It should export an Object with component name and story Component [Refer other components] <br> Step 3 : Story Component should return a react component <br> Step 3 : Created file should

280 lines (259 loc) 8.86 kB
import React from 'react'; import { PropTypes } from 'prop-types'; import FilterComponent from './FilterComponent'; import CheckboxTreeFilter from '../CheckboxTreeFilter'; import Slider from '../Slider'; import ToggleComponent from '../ToggleComponent'; import Card from '../Card'; class FilterComponentWrapper extends React.Component { constructor(props) { super(props); this.state = { filterChips: [], ...props.appliedFilters }; this.getInput = this.getInput.bind(this); this.updateFilters = this.updateFilters.bind(this); this.onFilterClear = this.onFilterClear.bind(this); this.onFilterReset = this.onFilterReset.bind(this); this.onFilterSubmit = this.onFilterSubmit.bind(this); this.state.filterChips = this.props.templateParams .map(param => param.name) .reduce( (list, key) => [...list, ...this.getFilterContent(key)], [] ); } componentWillReceiveProps(newProps) { this.setState({ ...newProps.appliedFilters }); } onFilterClear(filterChip) { this.updateState(prevState => { const selectedFilter = prevState[filterChip.type]; return { [filterChip.type]: Array.isArray(selectedFilter) ? selectedFilter.filter(filter => filter !== filterChip.key) : undefined }; }); } onFilterReset() { const state = this.props.templateParams.reduce((obj, param) => { obj[param.name] = undefined; return obj; }, {}); state.filterChips = []; this.setState(state); } onFilterSubmit() { if (this.props.onFilterSubmit) { this.props.onFilterSubmit( this.props.templateParams.reduce((obj, param) => { obj[param.name] = this.state[param.name]; return obj; }, {}) ); } } getFilterCount() { return this.filterChips.length; } getInput(param) { switch (param.type) { case 'toggleCheckboxTree': return this.getToggleCheckboxTree(param); case 'toggleSlider': return this.getToggleSlider(param); case 'component': return this.getComponent(param); default: return null; } } getFilterContent(key) { const param = this.props.templateParams.find(item => item.name === key); const selectedFilter = this.state[key]; return selectedFilter ? Array.isArray(selectedFilter) ? selectedFilter.map(filter => ({ key: filter, value: param.displayContent ? param.displayContent(filter) : filter, type: key })) : [ { key: selectedFilter, value: param.displayContent ? param.displayContent(selectedFilter) : selectedFilter, type: key } ] : []; } getToggleCheckboxTree(param) { return ( param.name && ( <CheckboxTreeFilter {...param.props} key={param.name} type="checkbox" onChange={checked => this.updateState({ [param.name]: checked }) } checked={this.state[param.name] || []} includeSearch={param.includeSearch} searchClassName="toggle-filter-search" placeholder={param.searchPlaceholder} label={param.label} nodes={param.nodes} /> ) ); } getToggleSlider(param) { const value = this.state[param.name]; return ( param.name && ( <ToggleComponent key={param.name} label={param.label} name={param.name} resetFilters={() => this.updateState({ [param.name]: undefined }) } activeFilter={this.state[param.name]} openedClass="toggle-open-carrot" closedClass="toggle-closed-carrot" > <Card width="100%" position="absolute" padding="10px" boxShadow="rgba(208, 208, 208, 0.5) 1px 0px 6px 0px" zIndex="1" className="toggle-slider" > <Slider {...param.props} range={param.range} min={param.min} max={param.max} steps={param.steps} styles={{ slider: { width: '100%' } }} onChange={values => { this.updateState({ [param.name]: Array.isArray(values) ? { min: values[0], max: values[1] } : values }); }} value={ typeof value === 'object' ? [value.min, value.max] : value } /> </Card> </ToggleComponent> ) ); } /** * * Can accept external Component. * The input component should accept `onChange` and `value` props * and handle as needed. */ getComponent(param) { const { Component, name } = param; return ( name && Component && ( <Component value={this.state[name]} onChange={value => this.updateState({ [name]: value }) } /> ) ); } updateFilters() { const filterChips = this.props.templateParams .map(param => param.name) .reduce( (list, key) => [...list, ...this.getFilterContent(key)], [] ); this.setState({ filterChips }); if (this.props.onFilterChange) { this.props.onFilterChange( this.props.templateParams.reduce((obj, param) => { obj[param.name] = this.state[param.name]; return obj; }, {}) ); } } updateState(state) { if (state) { this.setState(state, this.updateFilters); } } render() { const templateParams = this.props.templateParams || []; const filterComponentProps = { filterChips: this.state.filterChips, onFilterClear: this.onFilterClear, onFilterReset: this.onFilterReset, onFilterSubmit: this.onFilterSubmit }; return ( <FilterComponent {...this.props} {...filterComponentProps}> {Array.isArray(templateParams) && templateParams.length && templateParams.map(this.getInput)} </FilterComponent> ); } } FilterComponentWrapper.defaultProps = { expand: false, className: '', onFilterChange: () => {} }; FilterComponentWrapper.propTypes = { /** * expands/collapses the filter component */ expand: PropTypes.bool, /** * class for the component */ className: PropTypes.string, /** * function to call on Apply clicked */ onFilterSubmit: PropTypes.func.isRequired, /** * function to call when any filter is changed */ onFilterChange: PropTypes.func, /** * Filters to be preselected */ appliedFilters: PropTypes.element.isRequired, /** * Template params used to render filter elements */ templateParams: PropTypes.arrayOf(PropTypes.object).isRequired }; export default FilterComponentWrapper;