Convert ColorDropdown to TypeScript

pull/10616/head
Alex P 2018-05-11 15:50:20 -07:00
parent cd337f8e1b
commit a28dfed8ff
2 changed files with 125 additions and 110 deletions

View File

@ -1,110 +0,0 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import OnClickOutside from 'shared/components/OnClickOutside'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class ColorDropdown extends Component {
constructor(props) {
super(props)
this.state = {
visible: false,
}
}
handleToggleMenu = () => {
const {disabled} = this.props
if (disabled) {
return
}
this.setState({visible: !this.state.visible})
}
handleClickOutside = () => {
this.setState({visible: false})
}
handleColorClick = color => () => {
this.props.onChoose(color)
this.setState({visible: false})
}
render() {
const {visible} = this.state
const {colors, selected, disabled, stretchToFit} = this.props
const dropdownClassNames = classnames('color-dropdown', {
open: visible,
'color-dropdown--stretch': stretchToFit,
})
const toggleClassNames = classnames(
'btn btn-sm btn-default color-dropdown--toggle',
{active: visible, 'color-dropdown__disabled': disabled}
)
return (
<div className={dropdownClassNames}>
<div
className={toggleClassNames}
onClick={this.handleToggleMenu}
disabled={disabled}
>
<div
className="color-dropdown--swatch"
style={{backgroundColor: selected.hex}}
/>
<div className="color-dropdown--name">{selected.name}</div>
<span className="caret" />
</div>
{visible ? (
<div className="color-dropdown--menu">
<FancyScrollbar autoHide={false} autoHeight={true}>
{colors.map((color, i) => (
<div
className={
color.name === selected.name
? 'color-dropdown--item active'
: 'color-dropdown--item'
}
key={i}
onClick={this.handleColorClick(color)}
>
<span
className="color-dropdown--swatch"
style={{backgroundColor: color.hex}}
/>
<span className="color-dropdown--name">{color.name}</span>
</div>
))}
</FancyScrollbar>
</div>
) : null}
</div>
)
}
}
const {arrayOf, bool, func, shape, string} = PropTypes
ColorDropdown.propTypes = {
selected: shape({
hex: string.isRequired,
name: string.isRequired,
}).isRequired,
onChoose: func.isRequired,
colors: arrayOf(
shape({
hex: string.isRequired,
name: string.isRequired,
}).isRequired
).isRequired,
stretchToFit: bool,
disabled: bool,
}
export default OnClickOutside(ColorDropdown)

View File

@ -0,0 +1,125 @@
import React, {Component} from 'react'
import classnames from 'classnames'
import {ClickOutside} from 'src/shared/components/ClickOutside'
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {ColorNumber} from 'src/types/colors'
import {DROPDOWN_MENU_MAX_HEIGHT} from 'src/shared/constants/index'
interface Props {
selected: ColorNumber
disabled: boolean
stretchToFit: boolean
colors: ColorNumber[]
onChoose: (colors: ColorNumber[]) => void
}
interface State {
visible: boolean
}
@ErrorHandling
export default class ColorDropdown extends Component<Props, State> {
constructor(props) {
super(props)
this.state = {
visible: false,
}
}
public render() {
const {visible} = this.state
const {selected} = this.props
return (
<ClickOutside onClickOutside={this.handleClickOutside}>
<div className={this.dropdownClassNames}>
<div
className={this.buttonClassNames}
onClick={this.handleToggleMenu}
>
<div
className="color-dropdown--swatch"
style={{backgroundColor: selected.hex}}
/>
<div className="color-dropdown--name">{selected.name}</div>
<span className="caret" />
</div>
{visible && this.renderMenu}
</div>
</ClickOutside>
)
}
private get dropdownClassNames(): string {
const {stretchToFit} = this.props
const {visible} = this.state
return classnames('color-dropdown', {
open: visible,
'color-dropdown--stretch': stretchToFit,
})
}
private get buttonClassNames(): string {
const {disabled} = this.props
const {visible} = this.state
return classnames('btn btn-sm btn-default color-dropdown--toggle', {
active: visible,
'color-dropdown__disabled': disabled,
})
}
private get renderMenu(): JSX.Element {
const {colors, selected} = this.props
return (
<div className="color-dropdown--menu">
<FancyScrollbar
autoHide={false}
autoHeight={true}
maxHeight={DROPDOWN_MENU_MAX_HEIGHT}
>
{colors.map((color, i) => (
<div
className={
color.name === selected.name
? 'color-dropdown--item active'
: 'color-dropdown--item'
}
key={i}
onClick={this.handleColorClick(color)}
>
<span
className="color-dropdown--swatch"
style={{backgroundColor: color.hex}}
/>
<span className="color-dropdown--name">{color.name}</span>
</div>
))}
</FancyScrollbar>
</div>
)
}
private handleToggleMenu = (): void => {
const {disabled} = this.props
if (disabled) {
return
}
this.setState({visible: !this.state.visible})
}
private handleClickOutside = (): void => {
this.setState({visible: false})
}
private handleColorClick = color => (): void => {
this.props.onChoose(color)
this.setState({visible: false})
}
}