import React, { Component } from 'react'
import cx from 'classnames'
import PropTypes from 'prop-types'
import DropDownStyled from './dropdown.styled'
import DropdownIcon from './dropdown-icon'
class DropDown extends Component {
constructor () {
super()
this.state = {
visible: false,
arrowPosition: 0
}
}
open = (e) => {
e.stopPropagation()
if (this.state.visible) {
this.close();
return;
}
const { offsetX } = e.nativeEvent
const { clientWidth } = e.nativeEvent.target
this.focusElement.focus()
this.setState({
visible: true,
arrowPosition: offsetX,
referenceSize: clientWidth
})
}
close = () => {
this.setState({
visible: false
})
}
definePositionArrow = () => {
const { arrowPosition, referenceSize } = this.state
const minValue = 10
const arrowSize = 14
let position = 0
if (arrowPosition < minValue) { position = minValue } else if ((arrowPosition + arrowSize) > referenceSize) {
position = referenceSize - arrowSize
} else { position = parseInt(referenceSize / 2) }
return position
}
render () {
const { visible, referenceSize } = this.state
const { className, reference, direction = 'bottom-right', children } = this.props
let element = <DropdownIcon onClick={this.open} />
if (reference) {
element = React.cloneElement(reference, { onClick: this.open })
}
const dropdownArrowClass = {
'arrow-top': (direction.indexOf('top') > -1),
'arrow-left': (direction.indexOf('left') > -1),
'arrow-bottom': (direction.indexOf('bottom') > -1),
'arrow-right': (direction.indexOf('right') > -1)
}
const dropdownItemsContainerClass = {
'top': (direction.indexOf('top') > -1),
'bottom': (direction.indexOf('bottom') > -1),
'left': (direction.indexOf('left') > -1),
'right': (direction.indexOf('right') > -1)
}
return (
<DropDownStyled className={className} arrowPosition={this.definePositionArrow()} referenceSize={referenceSize}>
<input className='input-focus' ref={(input) => { this.focusElement = input }} onBlur={() => { setTimeout(this.close, 200) }} />
{direction.indexOf('bottom') > -1 && element}
<div className={cx({ 'show': visible }, 'dropdown-container')}>
<div className={cx(dropdownArrowClass, 'dropdown-arrow')} />
<div className={cx(dropdownItemsContainerClass, 'dropdown-items-container')}>
{children}
</div>
</div>
{direction.indexOf('top') > -1 && element}
</DropDownStyled>
)
}
}
DropDown.propTypes = {
className: PropTypes.string,
reference: PropTypes.node,
children: PropTypes.node,
direction: PropTypes.oneOf([
'top-left',
'top-right',
'bottom-left',
'bottom-right'
])
}
export { DropDownItem } from './dropdown-item'
export { DropDown }
|