UNPKG

@salesforce/design-system-react

Version:

Salesforce Lightning Design System for React

181 lines (167 loc) 5.05 kB
import React from 'react'; import KEYS from '../../../utilities/key-code'; import RadioButtonGroup from '../../../components/radio-button-group'; import Radio from '../../../components/radio-button-group/radio'; import ColorUtils from '../../../utilities/color'; const handleClick = (event, rangeIndicator, { onSaturationValueChange }) => { const rect = event.currentTarget.getBoundingClientRect(); rangeIndicator.focus(); onSaturationValueChange(event, { saturation: Math.round((event.clientX - rect.left) / rect.width * 100), value: Math.round((rect.bottom - event.clientY) / rect.height * 100), }); }; const handleKeyDown = (event, { onSaturationNavigate, onValueNavigate }) => { const keyDownCallbacks = { [KEYS.LEFT]: (multiplier) => { onSaturationNavigate(event, { delta: multiplier * -1, }); }, [KEYS.RIGHT]: (multiplier) => { onSaturationNavigate(event, { delta: multiplier, }); }, [KEYS.UP]: (multiplier) => { onValueNavigate(event, { delta: multiplier, }); }, [KEYS.DOWN]: (multiplier) => { onValueNavigate(event, { delta: multiplier * -1, }); }, }; if (keyDownCallbacks[event.keyCode]) { event.preventDefault(); keyDownCallbacks[event.keyCode](event.shiftKey ? 10 : 1); } }; const selectedStyle = { border: '1px solid #9e9e9e', boxShadow: 'rgb(117, 112, 112) 1px 1px 1px', marginRight: '2px', }; const unselectedStyle = { border: '1px solid #9e9e9e', marginRight: '2px', }; class HsvColor extends React.Component { static displayName = 'SLDSHsvColor'; handleSwatchChange = (event) => { this.setState({ isTransparentSelected: event.target.value === '', }); this.props.onSwatchChange(event); }; isTransparent = () => this.props.color.hex === ''; render() { const style = { border: 'none', borderRadius: 'unset' }; const swatchStyle = this.isTransparent() ? { ...unselectedStyle } : { ...selectedStyle }; const transparentSwatchStyle = this.isTransparent() ? { ...selectedStyle } : { ...unselectedStyle }; // when working color is transparent: either use the previous color or default to black const fallbackWorkingColor = this.props.previousColor.hex ? this.props.previousColor : ColorUtils.getNewColor({ hex: '#000000' }); const workingColor = this.isTransparent() ? fallbackWorkingColor : this.props.color; return ( <div> <p className="slds-assistive-text" id={`color-picker-instructions-${this.props.id}`} > {this.props.assistiveText.saturationValueGrid} </p> <div className="slds-color-picker__custom-range" style={{ background: `hsl(${workingColor.hsv.hue}, 100%, 50%)`, }} onClick={(event) => { handleClick(event, this.rangeIndicator, { onSaturationValueChange: this.props.onSaturationValueChange, }); }} role="presentation" > {/* eslint-disable jsx-a11y/anchor-has-content */} <a aria-atomic="true" aria-describedby={`color-picker-instructions-${this.props.id}`} aria-live="assertive" className="slds-color-picker__range-indicator" onKeyDown={(event) => { handleKeyDown(event, { ...this.props }); }} ref={(rangeIndicator) => { this.rangeIndicator = rangeIndicator; }} role="button" style={{ bottom: `${workingColor.hsv.value}%`, left: `${workingColor.hsv.saturation}%`, }} tabIndex={0} > <span className="slds-assistive-text">{`Saturation ${ workingColor.hsv.saturation }% Brightness: ${workingColor.hsv.value}%`}</span> </a> </div> <div className="slds-color-picker__hue-and-preview"> <label className="slds-assistive-text" htmlFor={`color-picker-input-range-${this.props.id}`} > {this.props.assistiveText.hueSlider} </label> <input type="range" min="0" max="360" className="slds-color-picker__hue-slider" id={`color-picker-input-range-${this.props.id}`} value={workingColor.hsv.hue} onChange={this.props.onHueChange} /> <RadioButtonGroup name={`${this.props.id}-color-picker-swatch-toggle-button-group`} assistiveText={{ label: 'Toggle Transparency' }} style={style} onChange={this.handleSwatchChange} > <Radio checked={!this.isTransparent()} id={`color-picker-active-working-color-swatch-${this.props.id}`} key="working-color" labels={{ label: this.props.labels.customTabActiveWorkingColorSwatch, }} style={swatchStyle} value={workingColor.hex} variant="swatch" /> <Radio checked={this.isTransparent()} id={`color-picker-transparent-swatch-${this.props.id}`} key="transparent" labels={{ label: this.props.labels.customTabTransparentSwatch }} style={transparentSwatchStyle} value="" // transparent variant="swatch" /> </RadioButtonGroup> </div> </div> ); } } export default HsvColor;