PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.8.2
GenerateBlocks v1.8.2
trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.3.0
generateblocks / src / components / color-picker / index.js
generateblocks / src / components / color-picker Last commit date
editor.scss 4 years ago index.js 3 years ago
index.js
206 lines
1 /**
2 * External dependencies
3 */
4 import { RgbStringColorPicker, RgbaStringColorPicker } from 'react-colorful';
5 import { colord } from 'colord';
6 import { useDebounce } from '@wordpress/compose';
7 import { __ } from '@wordpress/i18n';
8 import { ColorPalette } from '@wordpress/block-editor';
9 import { useState, useEffect, useMemo, useRef } from '@wordpress/element';
10 import {
11 Tooltip,
12 BaseControl,
13 RangeControl,
14 Dropdown,
15 Button,
16 TextControl,
17 } from '@wordpress/components';
18
19 /**
20 * Internal dependencies
21 */
22 import hexToRGBA from '../../utils/hex-to-rgba';
23 import getIcon from '../../utils/get-icon';
24 import './editor.scss';
25
26 export default function ColorPicker( props ) {
27 const {
28 value,
29 onChange,
30 onOpacityChange,
31 label,
32 alpha = false,
33 valueOpacity = 1,
34 tooltip,
35 } = props;
36
37 const [ valueState, setValueState ] = useState( value || '' );
38 const inputRef = useRef( null );
39
40 const Component = alpha && 1 === valueOpacity
41 ? RgbaStringColorPicker
42 : RgbStringColorPicker;
43
44 const isHex = ( hex ) => {
45 return /^([0-9A-F]{3}){1,2}$/i.test( hex );
46 };
47
48 const getPaletteValue = ( colorValue ) => {
49 if ( String( colorValue ).startsWith( 'var(' ) ) {
50 const variableName = colorValue.match( /\(([^)]+)\)/ );
51
52 if ( variableName ) {
53 const variableValue = getComputedStyle( document.documentElement ).getPropertyValue( variableName[ 1 ] );
54
55 if ( variableValue ) {
56 colorValue = variableValue;
57 }
58 }
59 }
60
61 return colord( colorValue ).toRgbString();
62 };
63
64 const rgbColor = useMemo( () => getPaletteValue( value ), [ value ] );
65 const debouncedSetColor = useDebounce( onChange );
66
67 useEffect( () => {
68 if ( value !== valueState ) {
69 setValueState( value );
70 }
71 }, [ value ] );
72
73 useEffect( () => {
74 if ( value !== valueState ) {
75 debouncedSetColor( valueState );
76 }
77
78 // Keep the input focused.
79 setTimeout( () => {
80 if ( inputRef.current ) {
81 inputRef.current.focus();
82 }
83 }, 10 );
84 }, [ valueState ] );
85
86 return (
87 <div className="gblocks-color-component">
88 { !! label &&
89 <span className="gblocks-color-component__label">{ label }</span>
90 }
91
92 <Dropdown
93 className="gblocks-color-component__toggle"
94 contentClassName="gblocks-color-component-content"
95 position="top left"
96 renderToggle={ ( { isOpen, onToggle } ) => {
97 const button = <Button
98 className="gblocks-color-component__toggle-button"
99 onClick={ onToggle }
100 aria-expanded={ isOpen }
101 >
102 <span
103 className="gblocks-color-component__toggle-indicator"
104 style={ { background: value ? hexToRGBA( value, valueOpacity ) : null } }
105 />
106 </Button>;
107
108 return (
109 <>
110 { !! tooltip
111 ? <Tooltip text={ tooltip }>{ button }</Tooltip>
112 : button
113 }
114 </>
115 );
116 } }
117 renderContent={ () =>
118 <>
119 <Component
120 color={ rgbColor }
121 onChange={ ( nextColor ) => {
122 if ( colord( nextColor ).isValid() ) {
123 const alphaValue = colord( nextColor ).alpha();
124 nextColor = 1 === alphaValue ? colord( nextColor ).toHex() : nextColor;
125 }
126
127 setValueState( nextColor );
128 } }
129 />
130
131 <div className="gblocks-color-component-content__input-wrapper">
132 <TextControl
133 ref={ inputRef }
134 className="gblocks-color-input"
135 type={ 'text' }
136 value={ valueState }
137 onChange={ ( nextColor ) => {
138 if ( ! nextColor.startsWith( '#' ) && isHex( nextColor ) ) {
139 nextColor = '#' + nextColor;
140 }
141
142 setValueState( nextColor );
143 } }
144 onBlur={ () => {
145 if ( colord( value ).isValid() ) {
146 const alphaValue = colord( value ).alpha();
147
148 if ( 1 === alphaValue ) {
149 setValueState( colord( value ).toHex() );
150 }
151 }
152 } }
153 />
154
155 <Button
156 isSmall
157 isSecondary
158 className="gblocks-color-input-clear"
159 onClick={ () => {
160 setValueState( '' );
161
162 if ( alpha && 1 !== valueOpacity ) {
163 onOpacityChange( 1 );
164 }
165 } }
166 >
167 { __( 'Clear', 'generateblocks' ) }
168 </Button>
169 </div>
170
171 { alpha && 1 !== valueOpacity &&
172 <div className="gblocks-color-component-content__opacity">
173 <Tooltip text={ __( 'Opacity', 'generateblocks' ) }>
174 { getIcon( 'gradient' ) }
175 </Tooltip>
176
177 <RangeControl
178 value={ valueOpacity ? valueOpacity : 0 }
179 onChange={ ( opacityValue ) => onOpacityChange( opacityValue ) }
180 min={ 0 }
181 max={ 1 }
182 step={ 0.01 }
183 initialPosition={ 1 }
184 />
185 </div>
186 }
187
188 <BaseControl
189 className="gblocks-color-component-content__palette"
190 >
191 <ColorPalette
192 value={ value ? value : '' }
193 onChange={ ( color ) => {
194 setValueState( color );
195 } }
196 disableCustomColors={ true }
197 clearable={ false }
198 />
199 </BaseControl>
200 </>
201 }
202 />
203 </div>
204 );
205 }
206