PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 2.2.0
GenerateBlocks v2.2.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 / components / dimensions / index.js
generateblocks / src / components / dimensions Last commit date
editor.scss 2 years ago index.js 2 years ago labels.js 2 years ago
index.js
130 lines
1 /**
2 * External dependencies
3 */
4 import { __ } from '@wordpress/i18n';
5 import { BaseControl, Button, Tooltip } from '@wordpress/components';
6 import { link, linkOff } from '@wordpress/icons';
7 import { useState, useEffect } from '@wordpress/element';
8
9 /**
10 * Internal dependencies
11 */
12 import './editor.scss';
13 import UnitControl from '../unit-control';
14 import { labels } from './labels';
15 import isNumeric from '../../utils/is-numeric';
16
17 export default function Dimensions( props ) {
18 const {
19 label = __( 'Padding', 'generateblocks' ),
20 units = [],
21 attributeNames = [],
22 values,
23 placeholders,
24 onChange,
25 } = props;
26
27 // values can have other attributes not related to this component.
28 // This builds an object of values related to this component.
29 const attributes = attributeNames.reduce( ( o, k ) => {
30 o[ k ] = values[ k ];
31
32 return o;
33 }, {} );
34
35 const [ sync, setSync ] = useState( false );
36 const [ lastFocused, setLastFocused ] = useState( '' );
37
38 useEffect( () => {
39 const areAllValuesEqual = ( arr ) => arr.length === attributeNames.length && arr.every( ( value ) => value === arr[ 0 ] );
40 const attributeValues = Object.values( attributes ).filter( ( n ) => n );
41 setSync( areAllValuesEqual( attributeValues ) );
42 }, [ JSON.stringify( attributes ) ] );
43
44 const syncUnits = () => {
45 const sides = [ ...attributeNames ].reverse();
46
47 const firstValue = sides.reduce( ( result, key ) => {
48 return attributes[ key ] || isNumeric( attributes[ key ] ) ? attributes[ key ] : result;
49 }, '' );
50
51 if ( ! firstValue ) {
52 setSync( ! sync );
53
54 return;
55 }
56
57 const syncValue = lastFocused
58 ? attributes[ lastFocused ]
59 : firstValue;
60
61 const newAttributes = attributeNames.reduce( ( o, key ) => ( { ...o, [ key ]: syncValue } ), {} );
62 onChange( newAttributes );
63 setSync( ! sync );
64 };
65
66 const style = attributeNames.find( ( name ) => name.includes( 'Radius' ) )
67 ? 'corners'
68 : 'circle';
69
70 return (
71 <BaseControl className="components-gblocks-dimensions-control" label={ label } id={ attributeNames[ 0 ] }>
72 <Tooltip text={ !! sync ? __( 'Unlink Sides', 'generateblocks' ) : __( 'Link Sides', 'generateblocks' ) } >
73 <Button
74 className="components-gblocks-dimensions-control_sync"
75 aria-label={ !! sync ? __( 'Unlink Sides', 'generateblocks' ) : __( 'Link Sides', 'generateblocks' ) }
76 variant={ !! sync ? 'primary' : '' }
77 aria-pressed={ !! sync }
78 onClick={ () => syncUnits() }
79 >
80 { !! sync ? link : linkOff }
81 </Button>
82 </Tooltip>
83
84 <div
85 className={ 'components-gblocks-dimensions-control__inputs style-' + style }
86 style={ { display: !! sync ? 'block' : '' } }
87 >
88 { attributeNames.map( ( attributeName, index ) => {
89 if ( sync && index > 0 ) {
90 return null;
91 }
92
93 return (
94 <div key={ attributeName }>
95 <UnitControl
96 id={ attributeName }
97 value={ attributes[ attributeName ] || '' }
98 placeholder={ placeholders[ attributeName ] || '' }
99 units={ units }
100 onChange={ ( value ) => {
101 let newAttributes = {};
102
103 if ( sync ) {
104 newAttributes = attributeNames.reduce( ( o, key ) => ( { ...o, [ key ]: value } ), {} );
105 } else {
106 newAttributes[ attributeName ] = value;
107 }
108
109 onChange( newAttributes );
110 } }
111 onFocus={ () => setLastFocused( attributeName ) }
112 />
113
114 { ! sync &&
115 <label htmlFor={ attributeName } className="gblocks-dimensions-control__label">
116 {
117 attributeName.includes( 'Radius' )
118 ? labels.borderRadius[ index ]
119 : labels.default[ index ]
120 }
121 </label>
122 }
123 </div>
124 );
125 } ) }
126 </div>
127 </BaseControl>
128 );
129 }
130