UNPKG

@shakthillc/components

Version:

React generic components for shakthi products

205 lines (191 loc) 6.08 kB
import React from "react"; import PropTypes from "prop-types"; import style from "./MultiSelector.module.css"; import Badge from "./Badge"; import Popup from "../Popup/Popup"; import Avatar from "./../Avatar/Avatar"; import _ from "lodash"; class MultiSelector extends React.Component { constructor(props) { super(props); this.state = { selectedOption: this.props.selectedOption, isOpen: false, options: this.props.options || [], selectedValue: this.props.selectedOption || [], }; this.handleChange = this.handleChange.bind(this); this.removeBadge = this.removeBadge.bind(this); this.changePicker = this.changePicker.bind(this); } componentDidMount() { const { selectedOption, options } = this.props; if ( selectedOption && selectedOption.length > 0 ) { let filteredOptions = this.props.options.filter( ({ value: id1 }) => !this.props.selectedOption.some(({ value: id2 }) => id2 === id1) ); this.setState({ selectedValue: selectedOption, options: filteredOptions, }); } if (options && options.length > 0) { var filteredOptions = options; if (selectedOption && selectedOption.length > 0) { filteredOptions = this.props.options.filter( ({ value: id1 }) => !this.props.selectedOption.some(({ value: id2 }) => id2 === id1) ); } this.setState({ options: filteredOptions }); } } componentDidUpdate(prevProps, prevState) { // const { selectedValue, options, orig_options } = this.state; const { selectedOption, options } = this.props; if ( selectedOption && selectedOption.length > prevProps.selectedOption.length ) { let filteredOptions = this.props.options.filter( ({ value: id1 }) => !this.props.selectedOption.some(({ value: id2 }) => id2 === id1) ); this.setState({ selectedValue: selectedOption, options: filteredOptions, }); } if (options && options.length != prevProps.options.length) { var filteredOptions = options; if (selectedOption && selectedOption.length > 0) { filteredOptions = this.props.options.filter( ({ value: id1 }) => !this.props.selectedOption.some(({ value: id2 }) => id2 === id1) ); } this.setState({ options: filteredOptions,selectedValue:selectedOption || [] }); } } handleChange(val, mode) { let { onChange } = this.props; const { options } = this.state; let modifedOptions = options.filter((data) => { if (_.isEqual(data, val)) { } else { return data; } }); var selectedValue = this.state.selectedValue; selectedValue.push(val); this.setState({ selectedValue, options: modifedOptions }); onChange && onChange(selectedValue); } removeBadge(badgeObj) { const { onChange } = this.props; var selectedValue = [...this.state.selectedValue]; var options = [...this.state.options, badgeObj]; selectedValue = selectedValue.filter((obj) => obj.value !== badgeObj.value); this.setState({ selectedValue, options }); onChange && onChange(selectedValue); } changePicker(val) { let result = null; const { selectedOption } = this.state; let selectedValue = this.state.selectedValue; result = selectedValue.map((obj) => { return ( <Badge text={obj.label} avatar={obj.avatar} color={obj["color"]} onClick={(e) => this.removeBadge(obj)} /> ); }); return result; } render() { let { disabled = false, mode, isPopupOpen, togglePopup, removeClose, text1 = "Choose one or more people", text2 = "add more people", } = this.props; const { isOpen, selectedValue = "", options } = this.state; let selectedLabel = this.changePicker(this.props.mode); let inputText; let singleStyle = mode === "S" ? "32px" : ""; if (mode !== "S") { inputText = selectedValue.length !== 0 ? text2 : text1; } else { inputText = selectedValue.length !== 0 ? "" : "Enter people"; } let html = options.map((obj, i) => { return ( <span key={i} className={style.dropdownList} onClick={this.handleChange.bind(this, obj, mode)} > <Avatar size="24px" text={obj["label"]} /> {obj.label} </span> ); }); html.push( <span style={{ display: options.length != 0 ? "none" : "" }} className={style.dropdownList__noitems} > {" "} No items found </span> ); return ( <div className={style.selectContainer}> <div style={{ maxHeight: singleStyle }} className={ isPopupOpen === true ? style.selectStyle_click : style.selectStyle } onClick={togglePopup} > <div className={style.inputContainer}> <div style={{ display: "inline" }} onClick={removeClose}> {selectedLabel} </div> <p className={style.selectedTxt}>{inputText}</p> </div> </div> {isPopupOpen ? ( <div onClick={removeClose} className={style.selectDropdown}> {html} </div> ) : null} </div> ); } } MultiSelector.defaultProps = { options: [ { value: "Rick", label: "Rick", color: "lightblue" }, { value: "Morty", label: "Morty", color: "orange" }, { value: "Perry", label: "Perry", color: "lightgreen" }, ], disabled: false, }; MultiSelector.propTypes = { disabled: PropTypes.bool, onChange: PropTypes.func, options: PropTypes.array, selectedValue: PropTypes.string, }; export default Popup(MultiSelector);