// Copyright (c) 2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import React, {Component, createRef, MouseEvent} from 'react'; import styled from 'styled-components'; import {rgbToHex} from 'utils/color-utils'; import SingleColorPaletteFactory from 'components/side-panel/layer-panel/single-color-palette'; import ColorRangeSelectFactory from './color-range-selector'; import ColorPalette from 'components/side-panel/layer-panel/color-palette'; import {StyledPanelDropdown} from 'components/common/styled-components'; import onClickOutside from 'react-onclickoutside'; import {ColorUI} from 'layers/layer-factory'; import {ColorRange} from 'constants/color-ranges'; import {NestedPartial, RGBColor} from 'reducers'; type ColorSelectorInputProps = { active: boolean; disabled?: boolean; inputTheme?: string; }; type ColorSelectorProps = { fields?: any[]; colorSets: { selectedColor: RGBColor | ColorRange; setColor: ((v: RGBColor) => void) | ((v: ColorRange) => void); isRange?: boolean; label?: string; }[]; colorUI?: ColorUI; inputTheme?: string; disabled?: boolean; setColorUI?: (newConfig: NestedPartial) => void; }; export const ColorBlock = styled.div<{backgroundColor: RGBColor}>` width: 32px; height: 18px; border-radius: 1px; background-color: ${props => `rgb(${props.backgroundColor.slice(0, 3).join(',')})`}; `; export const ColorSelectorInput = styled.div` ${props => (props.inputTheme === 'secondary' ? props.theme.secondaryInput : props.theme.input)}; height: ${props => props.theme.inputBoxHeight}; .color-selector__selector__label { text-transform: capitalize; font-size: 12px; text-align: center; color: ${props => props.theme.inputPlaceholderColor}; } `; export const InputBoxContainer = styled.div` display: flex; justify-content: space-between; .color-select__input-group { flex-grow: 1; } .color-select__input-group:nth-child(2) { margin-left: 12px; } `; ColorSelectorFactory.deps = [SingleColorPaletteFactory, ColorRangeSelectFactory]; function ColorSelectorFactory(SingleColorPalette, ColorRangeSelector) { class ColorSelector extends Component { static defaultProps = { colorSets: [] }; state = { showDropdown: false }; node = createRef(); handleClickOutside = e => { if (this.props.colorUI && Number.isInteger(this.props.colorUI.showSketcher)) { // if sketcher is open, let sketch to close itself first return; } this._closePanelDropdown(); }; _getEditing = () => { return this.props.colorUI ? this.props.colorUI.showDropdown : this.state.showDropdown; }; _closePanelDropdown = () => { if (this._getEditing() === false) { return; } if (this.props.setColorUI) { this.props.setColorUI({showDropdown: false, showSketcher: false}); } else { this.setState({showDropdown: false}); } }; _onSelectColor = (color: RGBColor | ColorRange, e: MouseEvent) => { e?.stopPropagation(); const editing = this._getEditing(); if (this.props.colorSets[editing as unknown as string]) { this.props.colorSets[editing as unknown as string].setColor(color); } }; _showDropdown = (e, i) => { e.stopPropagation(); e.preventDefault(); if (this.props.setColorUI) { this.props.setColorUI({showDropdown: i}); } else { this.setState({showDropdown: i}); } }; render() { const {colorSets, disabled, inputTheme, colorUI} = this.props; const editing = this._getEditing(); const currentEditing = typeof editing === 'number' && colorSets[editing] && typeof colorSets[editing] === 'object'; return (
{colorSets.map((cSet, i) => (
this._showDropdown(e, i)} > {cSet.isRange ? ( ) : ( )} {cSet.label ? (
{cSet.label}
) : null}
))}
{currentEditing ? ( {colorSets[editing].isRange ? ( ) : ( )} ) : null}
); } } return onClickOutside(ColorSelector); } export default ColorSelectorFactory;