UNPKG

wix-style-react

Version:
200 lines (172 loc) • 5.86 kB
import React from 'react'; import color from 'color'; import PropTypes from 'prop-types'; import ColorPickerHsb from './ColorPickerHsb'; import ColorPickerHue from './ColorPickerHue'; import ColorPickerHistory from './ColorPickerHistory'; import ColorPickerConverter from './ColorPickerConverter'; import ColorPickerActions from './ColorPickerActions'; import { classes } from './ColorPicker.st.css'; import { safeColor, isTransparent } from './utils'; import { DataHooks } from './constants'; const FALLBACK_COLOR = color('#86c6e5'); /** * Color Picker * * Under the hood uses color manipulation library [https://github.com/Qix-/color](https://github.com/Qix-/color). * Value for this component can be given in `string` or `object` format. * The callbacks always respond with color `object` format. */ class ColorPicker extends React.PureComponent { constructor(props) { super(props); const _color = safeColor(props.value, props.allowEmpty) || FALLBACK_COLOR; this.state = { current: _color, previous: _color }; } render() { const { showHistory, showInput, showConverter, children, value, onAdd, addTooltipContent, allowEmpty, emptyPlaceholder, dataHook, } = this.props; const { current, previous } = this.state; return ( <div className={classes.root} data-hook={dataHook}> <ColorPickerHsb dataHook={DataHooks.hsb} current={current} onChange={this.change} /> <ColorPickerHue dataHook={DataHooks.hue} current={current} onChange={this.change} /> <ColorPickerHistory show={showHistory} current={current} previous={previous} onClick={this.change} /> <ColorPickerConverter dataHook={DataHooks.converter} showConverter={showConverter} showInput={showInput} current={current} onChange={this.change} onEnter={this.confirm} onAdd={onAdd} addTooltipContent={addTooltipContent} allowEmpty={allowEmpty} hexPlaceholder={emptyPlaceholder} /> {children && ( <div className={classes.children} data-hook={DataHooks.children}> {this._renderChildren()} </div> )} <ColorPickerActions disabled={!allowEmpty && value === ''} onConfirm={this.confirm} onCancel={this.cancel} /> </div> ); } _renderChildren = () => { const { children } = this.props; const childrenInterface = { changeColor: _color => { try { let colorObject = _color; if (typeof _color !== 'object') { colorObject = _color === '' ? color().fade(1) : color(_color); } this.change(colorObject); } catch (err) {} }, }; if (typeof children === 'function') { return children(childrenInterface); } return children; }; UNSAFE_componentWillReceiveProps(props) { const _color = safeColor(props.value, props.allowEmpty); if (!_color) return; if ( _color.hex() !== this.state.current.hex() || isTransparent(_color) !== isTransparent(this.state.current) ) { this.setState({ current: _color }); } } /** * sets the selected color * @param {object} color - An object that contains data for the selected color, model, and valpha. */ change = _color => { this.setState({ current: _color }, () => { this.props.onChange(_color); }); }; /** * confirms the selected color */ confirm = () => { this.setState({ previous: this.state.current }); this.props.onConfirm(this.state.current); }; /** * cancels the selected color */ cancel = () => { this.props.onCancel(this.state.previous); }; } ColorPicker.displayName = 'ColorPicker'; ColorPicker.propTypes = { /** Applies a data-hook HTML attribute that can be used in the tests */ dataHook: PropTypes.string, /** Defines current color. It can be provided in `string` or `object` format [https://github.com/Qix-/color](https://github.com/Qix-/color) */ value: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, /** Specifies whether current and previously used colors should be displayed */ showHistory: PropTypes.bool, /** Specifies whether `HEX`/`RGB`/`HSB` converter tabs be displayed */ showConverter: PropTypes.bool, /** Specifies whether color input in HEX mode should be displayed. This is relevant only if `showConverter` is `false` */ showInput: PropTypes.bool, /** Defines an event handler for color change. */ onChange: PropTypes.func, /** Defines an event handler for cancel button click. */ onCancel: PropTypes.func, /** Defines an event handler for confirm button click. */ onConfirm: PropTypes.func, /** Defines an event handler for color add button click. If not passed, the plus icon will not be visible. */ onAdd: PropTypes.func, /** Defines child items to be rendered above action buttons. Accepts any kind of content. */ children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), /** Defines content to show in add button tooltip. Does not appear if `onAdd` is not passed. */ addTooltipContent: PropTypes.node, /** Allows to submit when color is not selected. Returns a color object with alpha equal to 0. */ allowEmpty: PropTypes.bool, /** Defines a placeholder text to show in an input when `allowEmpty` is true */ emptyPlaceholder: PropTypes.string, }; ColorPicker.defaultProps = { showHistory: false, showConverter: true, showInput: true, allowEmpty: false, onChange: () => {}, onCancel: () => {}, onConfirm: () => {}, }; export default ColorPicker;