Convert ColorDropdown to TypeScript
parent
cd337f8e1b
commit
a28dfed8ff
|
@ -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)
|
|
@ -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})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue