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

300 lines (279 loc) 10.2 kB
/** * Created by manoraj.k on 17/08/17. */ import React from 'react'; import _ from 'lodash'; import PropTypes from 'prop-types'; import { CheckboxTreeFilterContainer, Chip, ChipContainer, Filter } from './styles/CheckboxTreeFilter'; import ToggleComponent from '../ToggleComponent'; import Card from '../Card'; import CheckboxTree from '../CheckboxTree'; import SimpleSearch from '../SimpleSearch'; import { colors } from './../colorCodes'; const snakeCaseCapitalize = function snakeCaseCapitalize(strn) { if (strn) { const str = strn.toLowerCase(); const newStrArr = str.split('_'); const isUnderscorePresent = str.indexOf('_') > -1; let newStr = ''; for (let i = 0; i < newStrArr.length; i++) { newStr += newStrArr[i].charAt(0).toUpperCase() + newStrArr[i].substring(1) + (isUnderscorePresent ? ' ' : ''); } return newStr; } return ''; }; const filterNodes = function filterNodes(nodes, value, root, expanded) { _.each(nodes, node => { const nodeName = node.value .replace(/_+?/g, '') .toLowerCase() .indexOf(value.trim().toLowerCase()); if (Object.prototype.hasOwnProperty.call(node, 'children')) { filterNodes(node.children, value, false, expanded); node.children = _.filter(node.children, child => child.search); if (node.children.length > 0) { node.search = true; expanded.push(node.value); } else { node.search = false; } } else if (nodeName > -1) { node.search = true; } else { node.search = false; } }); if (root) { return _.filter(nodes, node => node.search); } }; class CheckboxTreeFilter extends React.Component { constructor(props) { super(); this.state = { checked: props.checked || [], expanded: props.expanded || [], search: props.searchValue || '', nodes: props.nodes, showAllFilters: false }; this.nodes = _.cloneDeep(props.nodes); this.searchThreshold = props.searchThreshold || 2; _.bindAll( this, 'onSearchType', 'isFilterActive', 'resetFilters', 'clearFilter', 'onFilterChange', 'onFilterExpand', 'toggleFilter', 'showFilters' ); } componentWillReceiveProps(nextProps) { if ( !_.isEqual(this.state.nodes, nextProps.nodes) || (nextProps.checked && !_.isEqual(this.state.checked, nextProps.checked)) ) { this.nodes = _.cloneDeep(nextProps.nodes); this.setState({ nodes: nextProps.nodes, checked: nextProps.checked }); } } componentDidUpdate(prevProps, prevState) { if (this.state.checked.length !== prevState.checked.length) { if (this.props.onChange) { this.props.onChange(this.state.checked, this.props.name); } } } onFilterChange(checked) { this.setState({ checked }); } onSearchType(value) { if (value.length <= 0) { this.setState({ nodes: this.nodes }); } else if (value.length > this.searchThreshold) { const expanded = []; this.expanded = this.state.expanded; this.checked = this.state.checked; const newNodes = filterNodes( _.cloneDeep(this.nodes), value, true, expanded ); this.setState({ nodes: newNodes, expanded }); } } onFilterExpand(expanded) { this.setState({ expanded }); } clearFilter(index) { const checked = _.cloneDeep(this.state).checked; checked.splice(index, 1); this.setState({ checked, showAllFilters: checked.length <= this.props.showFilterOption ? false : this.state.showAllFilters }); } resetFilters() { this.setState({ checked: [], showAllFilters: false }); } isFilterActive() { return this.state.checked.length > 0; } toggleFilter() { this.setState(prevState => ({ showAllFilters: !prevState.showAllFilters })); } showFilters(initShowFilters) { const countCheckItems = this.state.checked.length; if (countCheckItems) { let filters = null; if (countCheckItems > initShowFilters) { filters = ( <Filter onClick={this.toggleFilter}> {this.state.showAllFilters ? 'Show Less' : `Show More (${countCheckItems - initShowFilters})`} </Filter> ); } return ( <ChipContainer className="selected-values-container"> {this.state.checked.map((filter, index) => { const display = index < initShowFilters ? 'inline-block' : this.state.showAllFilters ? 'inline-block' : 'none'; return ( <div> <Chip key={filter} style={{ display, whiteSpace: 'nowrap' }} onClick={() => { this.clearFilter(index); }} > <span style={{ paddingRight: '5px' }}> {snakeCaseCapitalize(filter)} </span> <i className="fa fa-times" aria-hidden="true" /> </Chip> </div> ); })} {filters} </ChipContainer> ); } return null; } render() { return ( <CheckboxTreeFilterContainer className={this.props.className}> <ToggleComponent label={this.props.label} name={this.props.name} resetFilters={this.resetFilters} activeFilter={this.isFilterActive()} default={this.props.defaultShow} > {this.props.type === 'checkbox' && ( <Card width="auto" position="absolute" padding="10px" boxShadow="rgba(208, 208, 208, 0.5) 1px 0px 6px 0px" zIndex="1" className="checkbox-toggle-content" > {this.showFilters(this.props.showFilterOption)} {this.props.includeSearch && ( <SimpleSearch width="100%" height="23px" padding="0px" className={this.props.searchClassName} placeholder={this.props.placeholder} backgroundColor={colors.whiteText} value={this.state.search} onChange={this.onSearchType} fontSize="12px" /> )} <CheckboxTree nodes={this.state.nodes} showNodeIcon={false} expanded={this.state.expanded} checked={this.state.checked} onCheck={this.onFilterChange} onExpand={this.onFilterExpand} height={this.props.treeHeight} className="check-box-tree-container" /> </Card> )} </ToggleComponent> </CheckboxTreeFilterContainer> ); } } export default CheckboxTreeFilter; CheckboxTreeFilter.propTypes = { checked: PropTypes.arrayOf(PropTypes.string).isRequired, expanded: PropTypes.arrayOf(PropTypes.string).isRequired, searchValue: PropTypes.string.isRequired, nodes: PropTypes.arrayOf( PropTypes.shape({ label: PropTypes.string.isRequired, value: PropTypes.string.isRequired, className: PropTypes.string, children: PropTypes.array }) ).isRequired, searchThreshold: PropTypes.number, name: PropTypes.string.isRequired, showFilterOption: PropTypes.number, className: PropTypes.string.isRequired, label: PropTypes.string.isRequired, defaultShow: PropTypes.bool.isRequired, type: PropTypes.string.isRequired, includeSearch: PropTypes.bool.isRequired, searchClassName: PropTypes.string.isRequired, placeholder: PropTypes.string.isRequired, treeHeight: PropTypes.string.isRequired, onChange: PropTypes.func }; CheckboxTreeFilter.defaultProps = { onChange: undefined, searchThreshold: 2, showFilterOption: 2 };