DocSpace-client/web/ASC.Web.Components/src/components/combobox/index.js

211 lines
5.5 KiB
JavaScript
Raw Normal View History

2019-07-18 08:00:54 +00:00
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components';
import InputBlock from '../input-block'
import DropDownItem from '../drop-down-item'
import DropDown from '../drop-down'
import { Icons } from '../icons'
import { handleAnyClick } from '../../utils/event';
2019-07-18 08:00:54 +00:00
const StyledComboBox = styled.div`
* {
${props => !props.withBorder && `border-color: transparent !important;`}
}
${state => state.isOpen && `
.input-group-append > div {
-moz-transform: scaleY(-1);
-o-transform: scaleY(-1);
-webkit-transform: scaleY(-1);
transform: scaleY(-1);
}
`}
& > div > input {
&::placeholder {
font-family: Open Sans;
font-style: normal;
font-weight: 600;
font-size: 13px;
line-height: 20px;
${props => !props.isDisabled && `color: #333333;`}
${props => (!props.withBorder & !props.isDisabled) && `border-bottom: 1px dotted #333333;`}
opacity: 1;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
2019-07-18 08:00:54 +00:00
}
}
`;
const StyledIcon = styled.span`
width: 16px;
margin-left: 8px;
line-height: 14px;
2019-07-18 08:00:54 +00:00
`;
class ComboBox extends React.PureComponent {
constructor(props) {
super(props);
2019-07-18 08:00:54 +00:00
this.ref = React.createRef();
const selectedItem = this.getSelected();
this.state = {
isOpen: props.opened,
boxLabel: selectedItem && selectedItem.label,
boxIcon: selectedItem && selectedItem.icon,
options: props.options
};
this.handleClick = this.handleClick.bind(this);
this.stopAction = this.stopAction.bind(this);
this.toggle = this.toggle.bind(this);
this.comboBoxClick = this.comboBoxClick.bind(this);
this.optionClick = this.optionClick.bind(this);
if (props.opened)
handleAnyClick(true, this.handleClick);
}
2019-07-18 08:00:54 +00:00
handleClick = (e) => this.state.isOpen && !this.ref.current.contains(e.target) && this.toggle(false);
stopAction = (e) => e.preventDefault();
toggle = (isOpen) => this.setState({ isOpen: isOpen });
comboBoxClick = (e) => {
if (this.props.isDisabled || !!e.target.closest('.input-group-prepend')) return;
this.setState({
2019-07-31 18:42:23 +00:00
option: this.props.option,
isOpen: !this.state.isOpen
});
};
optionClick = (option) => {
this.setState({
2019-07-31 18:42:23 +00:00
boxLabel: option.label,
boxIcon: option.icon,
2019-07-31 18:42:23 +00:00
isOpen: !this.state.isOpen
});
this.props.onSelect && this.props.onSelect(option);
};
2019-07-18 08:00:54 +00:00
componentWillUnmount() {
handleAnyClick(false, this.handleClick);
}
getSelected = () => {
const selectedItem = this.props.options.find(x => x.key === this.props.selectedOption)
|| this.props.options[0];
return selectedItem;
}
getSelectedLabel = () => {
const selectedItem = this.getSelected();
return selectedItem ? selectedItem.label : "1-1";
}
componentDidUpdate(prevProps, prevState) {
if (this.props.opened !== prevProps.opened) {
this.toggle(this.props.opened);
2019-07-18 08:00:54 +00:00
}
if (this.state.isOpen !== prevState.isOpen) {
handleAnyClick(this.state.isOpen, this.handleClick);
}
if (this.props.options.length !== prevProps.options.length) { //TODO: Move options from state
const label = this.getSelectedLabel();
this.setState({
options: this.props.options,
boxLabel: label
});
}
if (this.props.selectedOption !== prevProps.selectedOption) {
const label = this.getSelectedLabel();
this.setState({ boxLabel: label });
}
}
2019-07-18 08:00:54 +00:00
render() {
console.log("ComboBox render");
const dropDownMaxHeightProp = this.props.dropDownMaxHeight ? { maxHeight: this.props.dropDownMaxHeight } : {}
return (
<StyledComboBox ref={this.ref}
{...this.props}
{...this.state}
data={this.state.boxLabel}
onClick={this.comboBoxClick}
onSelect={this.stopAction}
>
<InputBlock placeholder={this.state.boxLabel}
iconName='ExpanderDownIcon'
iconSize={8}
isIconFill={true}
iconColor='#A3A9AE'
scale={true}
isDisabled={this.props.isDisabled}
isReadOnly={true}
>
{this.state.boxIcon &&
<StyledIcon>
{React.createElement(Icons[this.state.boxIcon],
{
size: "scale",
color: this.props.isDisabled ? '#D0D5DA' : '#333333',
isfill: true
})
}
</StyledIcon>}
{this.props.children}
<DropDown
directionX={this.props.directionX}
directionY={this.props.directionY}
manualWidth='100%'
manualY='102%'
isOpen={this.state.isOpen}
{...dropDownMaxHeightProp}
>
{this.state.options.map((option) =>
<DropDownItem {...option}
disabled={option.label === this.state.boxLabel}
2019-07-31 18:42:23 +00:00
onClick={this.optionClick.bind(this, option)}
/>
)}
</DropDown>
</InputBlock>
</StyledComboBox>
);
}
2019-07-18 08:00:54 +00:00
};
ComboBox.propTypes = {
isDisabled: PropTypes.bool,
withBorder: PropTypes.bool,
selectedOption: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
options: PropTypes.array,
onSelect: PropTypes.func,
dropDownMaxHeight: PropTypes.string
2019-07-18 08:00:54 +00:00
}
ComboBox.defaultProps = {
isDisabled: false,
withBorder: true,
dropDownMaxHeight: null
2019-07-18 08:00:54 +00:00
}
2019-07-18 08:00:54 +00:00
export default ComboBox;