Convert ColorScaleDropdown to TypeScript

pull/10616/head
Alex P 2018-05-11 15:50:31 -07:00
parent a28dfed8ff
commit 5ebf5137db
2 changed files with 130 additions and 119 deletions

View File

@ -1,119 +0,0 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import uuid from 'uuid'
import classnames from 'classnames'
import OnClickOutside from 'shared/components/OnClickOutside'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {LINE_COLOR_SCALES} from 'src/shared/constants/graphColorPalettes'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class ColorScaleDropdown extends Component {
constructor(props) {
super(props)
this.state = {
expanded: false,
}
}
handleToggleMenu = () => {
const {disabled} = this.props
if (disabled) {
return
}
this.setState({expanded: !this.state.expanded})
}
handleClickOutside = () => {
this.setState({expanded: false})
}
handleDropdownClick = colorScale => () => {
this.props.onChoose(colorScale)
this.setState({expanded: false})
}
generateGradientStyle = colors => ({
background: `linear-gradient(to right, ${colors[0].hex} 0%,${
colors[1].hex
} 50%,${colors[2].hex} 100%)`,
})
render() {
const {expanded} = this.state
const {selected, disabled, stretchToFit} = this.props
const dropdownClassNames = classnames('color-dropdown', {
open: expanded,
'color-dropdown--stretch': stretchToFit,
})
const toggleClassNames = classnames(
'btn btn-sm btn-default color-dropdown--toggle',
{active: expanded, 'color-dropdown__disabled': disabled}
)
return (
<div className={dropdownClassNames}>
<div
className={toggleClassNames}
onClick={this.handleToggleMenu}
disabled={disabled}
>
<div
className="color-dropdown--swatches"
style={this.generateGradientStyle(selected)}
/>
<div className="color-dropdown--name">{selected[0].name}</div>
<span className="caret" />
</div>
{expanded ? (
<div className="color-dropdown--menu">
<FancyScrollbar autoHide={false} autoHeight={true}>
{LINE_COLOR_SCALES.map(colorScale => (
<div
className={
colorScale.name === selected[0].name
? 'color-dropdown--item active'
: 'color-dropdown--item'
}
key={uuid.v4()}
onClick={this.handleDropdownClick(colorScale)}
>
<div
className="color-dropdown--swatches"
style={this.generateGradientStyle(colorScale.colors)}
/>
<span className="color-dropdown--name">
{colorScale.name}
</span>
</div>
))}
</FancyScrollbar>
</div>
) : null}
</div>
)
}
}
const {arrayOf, bool, func, shape, string} = PropTypes
ColorScaleDropdown.propTypes = {
selected: arrayOf(
shape({
type: string.isRequired,
hex: string.isRequired,
id: string.isRequired,
name: string.isRequired,
}).isRequired
).isRequired,
onChoose: func.isRequired,
stretchToFit: bool,
disabled: bool,
}
export default OnClickOutside(ColorScaleDropdown)

View File

@ -0,0 +1,130 @@
import React, {Component} from 'react'
import uuid from 'uuid'
import classnames from 'classnames'
import {ClickOutside} from 'src/shared/components/ClickOutside'
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
import {ColorNumber} from 'src/types/colors'
import {LINE_COLOR_SCALES} from 'src/shared/constants/graphColorPalettes'
import {ErrorHandling} from 'src/shared/decorators/errors'
interface Props {
onChoose: (colors: ColorNumber[]) => void
stretchToFit?: boolean
disabled?: boolean
selected: ColorNumber[]
}
interface State {
expanded: boolean
}
@ErrorHandling
export default class ColorScaleDropdown extends Component<Props, State> {
public static defaultProps: Partial<Props> = {
disabled: false,
stretchToFit: false,
}
constructor(props) {
super(props)
this.state = {
expanded: false,
}
}
public render() {
const {expanded} = this.state
const {selected} = this.props
return (
<ClickOutside onClickOutside={this.handleClickOutside}>
<div className={this.dropdownClassName}>
<div className={this.buttonClassName} onClick={this.handleToggleMenu}>
<div
className="color-dropdown--swatches"
style={this.generateGradientStyle(selected)}
/>
<div className="color-dropdown--name">{selected[0].name}</div>
<span className="caret" />
</div>
{expanded && this.renderMenu}
</div>
</ClickOutside>
)
}
private get renderMenu(): JSX.Element {
const {selected} = this.props
return (
<div className="color-dropdown--menu">
<FancyScrollbar autoHide={false} autoHeight={true}>
{LINE_COLOR_SCALES.map(colorScale => (
<div
className={
colorScale.name === selected[0].name
? 'color-dropdown--item active'
: 'color-dropdown--item'
}
key={uuid.v4()}
onClick={this.handleDropdownClick(colorScale)}
>
<div
className="color-dropdown--swatches"
style={this.generateGradientStyle(colorScale.colors)}
/>
<span className="color-dropdown--name">{colorScale.name}</span>
</div>
))}
</FancyScrollbar>
</div>
)
}
private get buttonClassName(): string {
const {disabled} = this.props
const {expanded} = this.state
return classnames('btn btn-sm btn-default color-dropdown--toggle', {
active: expanded,
'color-dropdown__disabled': disabled,
})
}
private get dropdownClassName(): string {
const {stretchToFit} = this.props
const {expanded} = this.state
return classnames('color-dropdown', {
open: expanded,
'color-dropdown--stretch': stretchToFit,
})
}
private handleToggleMenu = (): void => {
const {disabled} = this.props
if (disabled) {
return
}
this.setState({expanded: !this.state.expanded})
}
private handleClickOutside = (): void => {
this.setState({expanded: false})
}
private handleDropdownClick = colorScale => (): void => {
this.props.onChoose(colorScale)
this.setState({expanded: false})
}
private generateGradientStyle = colors => ({
background: `linear-gradient(to right, ${colors[0].hex} 0%,${
colors[1].hex
} 50%,${colors[2].hex} 100%)`,
})
}