PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.9.0
GenerateBlocks v1.9.0
2.4.1 2.4.0 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 / extend / inspector-control / controls / shapes-panel / index.js
generateblocks / src / extend / inspector-control / controls / shapes-panel Last commit date
index.js 3 years ago
index.js
508 lines
1 import { __, sprintf } from '@wordpress/i18n';
2 import PanelArea from '../../../../components/panel-area';
3 import getIcon from '../../../../utils/get-icon';
4 import { Fragment, useContext } from '@wordpress/element';
5 import ControlsContext from '../../../../block-context';
6 import classnames from 'classnames';
7 import sanitizeSVG from '../../../../utils/sanitize-svg';
8 import {
9 BaseControl,
10 Button,
11 Dropdown,
12 PanelBody,
13 PanelRow,
14 SelectControl,
15 TextControl, ToggleControl,
16 Tooltip,
17 } from '@wordpress/components';
18 import ColorPicker from '../../../../components/color-picker';
19 import UnitPicker from '../../../../components/unit-picker';
20 import getDeviceType from '../../../../utils/get-device-type';
21
22 export default function ShapesPanel( { attributes, setAttributes } ) {
23 const { id } = useContext( ControlsContext );
24 const deviceType = getDeviceType();
25 const {
26 backgroundColor,
27 shapeDividers,
28 position,
29 } = attributes;
30
31 const allShapes = [];
32
33 Object.keys( generateBlocksInfo.svgShapes ).forEach( ( key ) => {
34 const shapes = generateBlocksInfo.svgShapes[ key ].svgs;
35
36 Object.keys( shapes ).forEach( ( shapeName ) => {
37 allShapes[ shapeName ] = {
38 label: shapes[ shapeName ].label,
39 icon: shapes[ shapeName ].icon,
40 };
41 } );
42 } );
43
44 const handleAddShape = () => {
45 const shapeDividersValues = [ ...shapeDividers ];
46
47 shapeDividersValues.push( {
48 shape: generateBlocksStyling.container.shapeDividers.shape,
49 color: generateBlocksStyling.container.shapeDividers.color,
50 colorOpacity: generateBlocksStyling.container.shapeDividers.colorOpacity,
51 location: generateBlocksStyling.container.shapeDividers.location,
52 height: generateBlocksStyling.container.shapeDividers.height,
53 heightTablet: generateBlocksStyling.container.shapeDividers.heightTablet,
54 heightMobile: generateBlocksStyling.container.shapeDividers.heightMobile,
55 width: generateBlocksStyling.container.shapeDividers.width,
56 widthTablet: generateBlocksStyling.container.shapeDividers.widthTablet,
57 widthMobile: generateBlocksStyling.container.shapeDividers.widthMobile,
58 flipHorizontally: generateBlocksStyling.container.shapeDividers.flipHorizontally,
59 zindex: generateBlocksStyling.container.shapeDividers.zindex,
60 } );
61
62 setAttributes( {
63 shapeDividers: shapeDividersValues,
64 position: ! position ? 'relative' : position,
65 } );
66 };
67
68 const handleRemoveShape = ( index ) => {
69 const shapeDividersValues = [ ...shapeDividers ];
70
71 shapeDividersValues.splice( index, 1 );
72 setAttributes( { shapeDividers: shapeDividersValues } );
73 };
74
75 return (
76 <PanelArea
77 title={ __( 'Shapes', 'generateblocks' ) }
78 initialOpen={ false }
79 icon={ getIcon( 'shapes' ) }
80 className={ 'gblocks-panel-label' }
81 id={ `${ id }Shapes` }
82 >
83 <BaseControl className="gb-icon-chooser gb-shape-chooser">
84 {
85 shapeDividers.map( ( location, index ) => {
86 const shapeNumber = index + 1;
87
88 return <Fragment key={ index }>
89 <div className="gblocks-shape-container">
90 <div
91 className={ classnames( {
92 'gblocks-shape-toggle-preview': true,
93 [ `gblocks-shape-toggle-preview-${ shapeNumber }` ]: true,
94 } ) }
95 style={ { backgroundColor } }
96 >
97 { 'undefined' !== typeof allShapes[ shapeDividers[ index ].shape ] &&
98 <div
99 className="gblocks-shape-divider-preview"
100 style={ { color: shapeDividers[ index ].color } }
101 dangerouslySetInnerHTML={ { __html: sanitizeSVG( allShapes[ shapeDividers[ index ].shape ].icon ) } }
102 />
103 }
104 </div>
105
106 {
107 /* translators: Shape number */
108 sprintf( __( 'Shape %s', 'generateblocks' ), shapeNumber )
109 }
110
111 <Fragment>
112 <Dropdown
113 contentClassName="gblocks-shapes-dropdown"
114 renderToggle={ ( { isOpen, onToggle } ) => (
115 <Tooltip text={ __( 'Edit Shape', 'generateblocks' ) }>
116 <Button
117 className="gblocks-shape-dropdown"
118 isSecondary={ isOpen ? undefined : true }
119 isPrimary={ isOpen ? true : undefined }
120 icon={ getIcon( 'wrench' ) }
121 onClick={ onToggle }
122 aria-expanded={ isOpen }
123 />
124 </Tooltip>
125 ) }
126 renderContent={ () => (
127 <div className="gblocks-shape-controls">
128 { 'Desktop' === deviceType &&
129 <Fragment>
130 <BaseControl className="gb-icon-chooser">
131 {
132 Object.keys( generateBlocksInfo.svgShapes ).map( ( svg, i ) => {
133 const svgItems = generateBlocksInfo.svgShapes[ svg ].svgs;
134
135 return (
136 <PanelBody
137 title={ generateBlocksInfo.svgShapes[ svg ].group }
138 initialOpen={ svgItems.hasOwnProperty( shapeDividers[ index ].shape ) }
139 key={ i }
140 >
141 <PanelRow>
142 <BaseControl>
143 <ul className="gblocks-icon-chooser gblocks-shape-chooser">
144 {
145 Object.keys( svgItems ).map( ( svgItem, iconIndex ) => {
146 return (
147 <li key={ `editor-pblock-types-list-item-${ iconIndex }` }>
148 <Tooltip text={ ( svgItems[ svgItem ].label ) }>
149 <Button
150 className={ classnames( {
151 'editor-block-list-item-button': true,
152 'gblocks-shape-is-active': shapeDividers[ index ].shape === svgItem,
153 } ) }
154 onClick={ () => {
155 const shapes = [ ...shapeDividers ];
156
157 shapes[ index ] = {
158 ...shapes[ index ],
159 shape: svgItem,
160 };
161
162 setAttributes( {
163 shapeDividers: shapes,
164 } );
165 } }
166 >
167 { 'string' === typeof svgItems[ svgItem ].icon ? (
168 <Fragment>
169 <span
170 className="editor-block-types-list__item-icon"
171 dangerouslySetInnerHTML={ { __html: sanitizeSVG( svgItems[ svgItem ].icon ) } }
172 />
173 </Fragment>
174 ) : (
175 <Fragment>
176 <span className="editor-block-types-list__item-icon">
177 { svgItems[ svgItem ].icon }
178 </span>
179 </Fragment>
180 ) }
181 </Button>
182 </Tooltip>
183 </li>
184 );
185 } )
186 }
187 </ul>
188 </BaseControl>
189 </PanelRow>
190 </PanelBody>
191 );
192 } )
193 }
194 </BaseControl>
195
196 <BaseControl>
197 <ColorPicker
198 label={ __( 'Color', 'generateblocks' ) }
199 value={ shapeDividers[ index ].color }
200 alpha={ true }
201 valueOpacity={ shapeDividers[ index ].colorOpacity }
202 onChange={ ( value ) => {
203 const shapes = [ ...shapeDividers ];
204
205 shapes[ index ] = {
206 ...shapes[ index ],
207 color: value,
208 };
209
210 setAttributes( {
211 shapeDividers: shapes,
212 } );
213 } }
214 onOpacityChange={ ( value ) => {
215 const shapes = [ ...shapeDividers ];
216
217 shapes[ index ] = {
218 ...shapes[ index ],
219 colorOpacity: value,
220 };
221
222 setAttributes( {
223 shapeDividers: shapes,
224 } );
225 } }
226 />
227 </BaseControl>
228
229 <SelectControl
230 label={ __( 'Location', 'generateblocks' ) }
231 value={ shapeDividers[ index ].location }
232 options={ [
233 { label: __( 'Top', 'generateblocks' ), value: 'top' },
234 { label: __( 'Bottom', 'generateblocks' ), value: 'bottom' },
235 ] }
236 onChange={ ( value ) => {
237 const shapes = [ ...shapeDividers ];
238
239 shapes[ index ] = {
240 ...shapes[ index ],
241 location: value,
242 };
243
244 setAttributes( {
245 shapeDividers: shapes,
246 } );
247 } }
248 />
249
250 <UnitPicker
251 label={ __( 'Height', 'generateblocks' ) }
252 value={ 'px' }
253 units={ [ 'px' ] }
254 onClick={ () => {
255 return false;
256 } }
257 />
258
259 <TextControl
260 type={ 'number' }
261 value={ shapeDividers[ index ].height ? shapeDividers[ index ].height : '' }
262 onChange={ ( value ) => {
263 const shapes = [ ...shapeDividers ];
264
265 shapes[ index ] = {
266 ...shapes[ index ],
267 height: parseFloat( value ),
268 };
269
270 setAttributes( {
271 shapeDividers: shapes,
272 } );
273 } }
274 />
275
276 <UnitPicker
277 label={ __( 'Width', 'generateblocks' ) }
278 value={ '%' }
279 units={ [ '%' ] }
280 onClick={ () => {
281 return false;
282 } }
283 />
284
285 <TextControl
286 type={ 'number' }
287 value={ shapeDividers[ index ].width ? shapeDividers[ index ].width : '' }
288 min="100"
289 onChange={ ( value ) => {
290 const shapes = [ ...shapeDividers ];
291
292 shapes[ index ] = {
293 ...shapes[ index ],
294 width: parseFloat( value ),
295 };
296
297 setAttributes( {
298 shapeDividers: shapes,
299 } );
300 } }
301 />
302
303 <ToggleControl
304 label={ __( 'Flip Horizontally', 'generateblocks' ) }
305 checked={ !! shapeDividers[ index ].flipHorizontally }
306 onChange={ ( value ) => {
307 const shapes = [ ...shapeDividers ];
308
309 shapes[ index ] = {
310 ...shapes[ index ],
311 flipHorizontally: value,
312 };
313
314 setAttributes( {
315 shapeDividers: shapes,
316 } );
317 } }
318 />
319
320 <TextControl
321 label={ __( 'z-index', 'generateblocks' ) }
322 type={ 'number' }
323 min="0"
324 value={ shapeDividers[ index ].zindex || 0 === shapeDividers[ index ].zindex ? shapeDividers[ index ].zindex : '' }
325 onChange={ ( value ) => {
326 const shapes = [ ...shapeDividers ];
327
328 shapes[ index ] = {
329 ...shapes[ index ],
330 zindex: value,
331 };
332
333 setAttributes( {
334 shapeDividers: shapes,
335 } );
336 } }
337 onBlur={ () => {
338 const shapes = [ ...shapeDividers ];
339
340 shapes[ index ] = {
341 ...shapes[ index ],
342 zindex: parseFloat( shapeDividers[ index ].zindex ),
343 };
344
345 setAttributes( {
346 shapeDividers: shapes,
347 } );
348 } }
349 onClick={ ( e ) => {
350 // Make sure onBlur fires in Firefox.
351 e.currentTarget.focus();
352 } }
353 />
354 </Fragment>
355 }
356
357 { 'Tablet' === deviceType &&
358 <Fragment>
359 <UnitPicker
360 label={ __( 'Height', 'generateblocks' ) }
361 value={ 'px' }
362 units={ [ 'px' ] }
363 onClick={ () => {
364 return false;
365 } }
366 />
367
368 <TextControl
369 type={ 'number' }
370 value={ shapeDividers[ index ].heightTablet ? shapeDividers[ index ].heightTablet : '' }
371 onChange={ ( value ) => {
372 const shapes = [ ...shapeDividers ];
373
374 shapes[ index ] = {
375 ...shapes[ index ],
376 heightTablet: parseFloat( value ),
377 };
378
379 setAttributes( {
380 shapeDividers: shapes,
381 } );
382 } }
383 />
384
385 <UnitPicker
386 label={ __( 'Width', 'generateblocks' ) }
387 value={ '%' }
388 units={ [ '%' ] }
389 onClick={ () => {
390 return false;
391 } }
392 />
393
394 <TextControl
395 type={ 'number' }
396 value={ shapeDividers[ index ].widthTablet ? shapeDividers[ index ].widthTablet : '' }
397 min="100"
398 onChange={ ( value ) => {
399 const shapes = [ ...shapeDividers ];
400
401 shapes[ index ] = {
402 ...shapes[ index ],
403 widthTablet: parseFloat( value ),
404 };
405
406 setAttributes( {
407 shapeDividers: shapes,
408 } );
409 } }
410 />
411 </Fragment>
412 }
413
414 { 'Mobile' === deviceType &&
415 <Fragment>
416 <UnitPicker
417 label={ __( 'Height', 'generateblocks' ) }
418 value={ 'px' }
419 units={ [ 'px' ] }
420 onClick={ () => {
421 return false;
422 } }
423 />
424
425 <TextControl
426 type={ 'number' }
427 value={ shapeDividers[ index ].heightMobile ? shapeDividers[ index ].heightMobile : '' }
428 onChange={ ( value ) => {
429 const shapes = [ ...shapeDividers ];
430
431 shapes[ index ] = {
432 ...shapes[ index ],
433 heightMobile: parseFloat( value ),
434 };
435
436 setAttributes( {
437 shapeDividers: shapes,
438 } );
439 } }
440 />
441
442 <UnitPicker
443 label={ __( 'Width', 'generateblocks' ) }
444 value={ '%' }
445 units={ [ '%' ] }
446 onClick={ () => {
447 return false;
448 } }
449 />
450
451 <TextControl
452 type={ 'number' }
453 value={ shapeDividers[ index ].widthMobile ? shapeDividers[ index ].widthMobile : '' }
454 min="100"
455 onChange={ ( value ) => {
456 const shapes = [ ...shapeDividers ];
457
458 shapes[ index ] = {
459 ...shapes[ index ],
460 widthMobile: parseFloat( value ),
461 };
462
463 setAttributes( {
464 shapeDividers: shapes,
465 } );
466 } }
467 />
468 </Fragment>
469 }
470 </div>
471 ) }
472 />
473 </Fragment>
474
475 { 'Desktop' === deviceType &&
476 <Tooltip text={ __( 'Delete Shape', 'generateblocks' ) }>
477 <Button
478 className="gblocks-remove-shape"
479 onClick={ () => {
480 // eslint-disable-next-line
481 if ( window.confirm( __( 'This will permanently delete this shape.', 'generateblocks' ) ) ) {
482 handleRemoveShape( index );
483 }
484 } }
485 icon={ getIcon( 'x' ) }
486 />
487 </Tooltip>
488 }
489 </div>
490 </Fragment>;
491 } )
492 }
493
494 { 'Desktop' === deviceType &&
495 <div className="gblocks-add-new-shape">
496 <Button
497 isSecondary
498 onClick={ handleAddShape }
499 >
500 { __( 'Add Shape', 'generateblocks' ) }
501 </Button>
502 </div>
503 }
504 </BaseControl>
505 </PanelArea>
506 );
507 }
508