PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.4.0
GenerateBlocks v1.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 / components / dimensions / index.js
generateblocks / src / components / dimensions Last commit date
editor.scss 5 years ago index.js 4 years ago
index.js
340 lines
1 /**
2 * External dependencies
3 */
4 import classnames from 'classnames';
5 import './editor.scss';
6 import getIcon from '../../utils/get-icon';
7 import UnitPicker from '../unit-picker';
8
9 /**
10 * WordPress dependencies
11 */
12 import {
13 __,
14 sprintf,
15 } from '@wordpress/i18n';
16
17 import {
18 Component,
19 Fragment,
20 } from '@wordpress/element';
21
22 import {
23 Button,
24 Tooltip,
25 } from '@wordpress/components';
26
27 class DimensionsControl extends Component {
28 constructor() {
29 super( ...arguments );
30 this.onChangeTop = this.onChangeTop.bind( this );
31 this.onChangeRight = this.onChangeRight.bind( this );
32 this.onChangeBottom = this.onChangeBottom.bind( this );
33 this.onChangeLeft = this.onChangeLeft.bind( this );
34 this.onChangeAll = this.onChangeAll.bind( this );
35 this.syncUnits = this.syncUnits.bind( this );
36 this.onChangeUnits = this.onChangeUnits.bind( this );
37 }
38
39 onReset( type ) {
40 this.props.setAttributes( { [ this.props[ type ] ]: '' } );
41 }
42
43 onChangeTop( value ) {
44 this.props.setAttributes( { [ this.props[ 'attrTop' ] ]: value } ); // eslint-disable-line dot-notation
45 }
46
47 onChangeRight( value ) {
48 this.props.setAttributes( { [ this.props[ 'attrRight' ] ]: value } ); // eslint-disable-line dot-notation
49 }
50
51 onChangeBottom( value ) {
52 this.props.setAttributes( { [ this.props[ 'attrBottom' ] ]: value } ); // eslint-disable-line dot-notation
53 }
54
55 onChangeLeft( value ) {
56 this.props.setAttributes( { [ this.props[ 'attrLeft' ] ]: value } ); // eslint-disable-line dot-notation
57 }
58
59 onChangeAll( value ) {
60 this.props.setAttributes( { [ this.props[ 'attrTop' ] ]: value, [ this.props[ 'attrRight' ] ]: value, [ this.props[ 'attrBottom' ] ]: value, [ this.props[ 'attrLeft' ] ]: value } ); // eslint-disable-line dot-notation
61 }
62
63 syncUnits() {
64 const numbers = [ this.props.attributes[ this.props.attrTop ], this.props.attributes[ this.props.attrRight ], this.props.attributes[ this.props.attrBottom ], this.props.attributes[ this.props.attrLeft ] ];
65
66 const syncValue = Math.max.apply( null, numbers );
67
68 this.props.setAttributes( {
69 [ this.props[ 'attrSyncUnits' ] ]: ! this.props.attributes[ this.props.attrSyncUnits ], // eslint-disable-line dot-notation
70 [ this.props[ 'attrTop' ] ]: syncValue.toString(), [ this.props[ 'attrRight' ] ]: syncValue.toString(), [ this.props[ 'attrBottom' ] ]: syncValue.toString(), [ this.props[ 'attrLeft' ] ]: syncValue.toString(), // eslint-disable-line dot-notation
71 } );
72 }
73
74 onChangeUnits( value ) {
75 this.props.setAttributes( { [ this.props[ 'attrUnit' ] ]: value } ); // eslint-disable-line dot-notation
76 }
77
78 render() {
79 const {
80 attributes,
81 label = __( 'Margin', 'generateblocks' ),
82 type = 'margin',
83 attrTop,
84 attrRight,
85 attrBottom,
86 attrLeft,
87 attrSyncUnits,
88 attrUnit,
89 labelTop = __( 'Top', 'generateblocks' ),
90 labelRight = __( 'Right', 'generateblocks' ),
91 labelBottom = __( 'Bottom', 'generateblocks' ),
92 labelLeft = __( 'Left', 'generateblocks' ),
93 device,
94 block,
95 units,
96 } = this.props;
97
98 const classes = classnames(
99 'components-base-control',
100 'components-gblocks-dimensions-control',
101 );
102
103 const onChangeTopValue = ( event ) => {
104 let newValue = event.target.value;
105
106 if ( 'padding' === type ) {
107 // No negative values allowed here.
108 newValue = newValue.toString().replace( /-/g, '' );
109 }
110
111 if ( '' === newValue ) {
112 this.onReset( 'attrTop' );
113 return;
114 }
115
116 if ( this.props.attributes[ this.props.attrSyncUnits ] ) {
117 this.onChangeAll( newValue );
118 } else {
119 this.onChangeTop( newValue );
120 }
121 };
122
123 const onChangeRightValue = ( event ) => {
124 let newValue = event.target.value;
125
126 if ( 'padding' === type ) {
127 // No negative values allowed here.
128 newValue = newValue.toString().replace( /-/g, '' );
129 }
130
131 if ( '' === newValue ) {
132 this.onReset( 'attrRight' );
133 return;
134 }
135
136 if ( this.props.attributes[ this.props.attrSyncUnits ] ) {
137 this.onChangeAll( newValue );
138 } else {
139 this.onChangeRight( newValue );
140 }
141 };
142
143 const onChangeBottomValue = ( event ) => {
144 let newValue = event.target.value;
145
146 if ( 'padding' === type ) {
147 // No negative values allowed here.
148 newValue = newValue.toString().replace( /-/g, '' );
149 }
150
151 if ( '' === newValue ) {
152 this.onReset( 'attrBottom' );
153 return;
154 }
155
156 if ( this.props.attributes[ this.props.attrSyncUnits ] ) {
157 this.onChangeAll( newValue );
158 } else {
159 this.onChangeBottom( newValue );
160 }
161 };
162
163 const onChangeLeftValue = ( event ) => {
164 let newValue = event.target.value;
165
166 if ( 'padding' === type ) {
167 // No negative values allowed here.
168 newValue = newValue.toString().replace( /-/g, '' );
169 }
170
171 if ( '' === newValue ) {
172 this.onReset( 'attrLeft' );
173 return;
174 }
175
176 if ( this.props.attributes[ this.props.attrSyncUnits ] ) {
177 this.onChangeAll( newValue );
178 } else {
179 this.onChangeLeft( newValue );
180 }
181 };
182
183 let topPlaceholder = '',
184 rightPlaceholder = '',
185 bottomPlaceholder = '',
186 leftPlaceholder = '';
187
188 if ( 'headline' === block && attrBottom.includes( 'marginBottom' ) ) {
189 if ( 'px' === this.props.attributes.marginUnit ) {
190 const headlineId = document.querySelector( '.gb-headline-' + this.props.attributes.uniqueId );
191
192 if ( headlineId ) {
193 bottomPlaceholder = parseFloat( window.getComputedStyle( headlineId ).marginBottom );
194 }
195 } else if ( 'em' === this.props.attributes.marginUnit && 'undefined' !== typeof generateBlocksStyling.headline ) {
196 if ( 'undefined' !== typeof generateBlocksStyling.headline[ attributes.element ] && 'undefined' !== typeof generateBlocksStyling.headline[ attributes.element ].marginBottom ) {
197 if ( generateBlocksStyling.headline[ attributes.element ].marginUnit === attributes.marginUnit ) {
198 bottomPlaceholder = generateBlocksStyling.headline[ attributes.element ].marginBottom;
199 }
200 }
201 }
202
203 if ( 'div' === this.props.attributes.element || 'span' === this.props.attributes.element ) {
204 bottomPlaceholder = '';
205 }
206 }
207
208 if ( 'Tablet' === device ) {
209 const topAttrName = attrTop.replace( 'Tablet', '' ),
210 rightAttrName = attrRight.replace( 'Tablet', '' ),
211 bottomAttrName = attrBottom.replace( 'Tablet', '' ),
212 leftAttrName = attrLeft.replace( 'Tablet', '' );
213
214 topPlaceholder = attributes[ topAttrName ] ? attributes[ topAttrName ] : topPlaceholder;
215 rightPlaceholder = attributes[ rightAttrName ] ? attributes[ rightAttrName ] : rightPlaceholder;
216 bottomPlaceholder = attributes[ bottomAttrName ] ? attributes[ bottomAttrName ] : bottomPlaceholder;
217 leftPlaceholder = attributes[ leftAttrName ] ? attributes[ leftAttrName ] : leftPlaceholder;
218 }
219
220 if ( 'Mobile' === device ) {
221 const topAttrName = attrTop.replace( 'Mobile', '' ),
222 rightAttrName = attrRight.replace( 'Mobile', '' ),
223 bottomAttrName = attrBottom.replace( 'Mobile', '' ),
224 leftAttrName = attrLeft.replace( 'Mobile', '' );
225
226 if ( attributes[ topAttrName + 'Tablet' ] ) {
227 topPlaceholder = attributes[ topAttrName + 'Tablet' ];
228 } else if ( attributes[ topAttrName ] ) {
229 topPlaceholder = attributes[ topAttrName ];
230 }
231
232 if ( attributes[ rightAttrName + 'Tablet' ] ) {
233 rightPlaceholder = attributes[ rightAttrName + 'Tablet' ];
234 } else if ( attributes[ rightAttrName ] ) {
235 rightPlaceholder = attributes[ rightAttrName ];
236 }
237
238 if ( attributes[ bottomAttrName + 'Tablet' ] ) {
239 bottomPlaceholder = attributes[ bottomAttrName + 'Tablet' ];
240 } else if ( attributes[ bottomAttrName ] ) {
241 bottomPlaceholder = attributes[ bottomAttrName ];
242 }
243
244 if ( attributes[ leftAttrName + 'Tablet' ] ) {
245 leftPlaceholder = attributes[ leftAttrName + 'Tablet' ];
246 } else if ( attributes[ leftAttrName ] ) {
247 leftPlaceholder = attributes[ leftAttrName ];
248 }
249 }
250
251 return (
252 <Fragment>
253 <div className={ classes }>
254 <UnitPicker
255 label={ label }
256 value={ 'undefined' !== typeof attributes[ attrUnit ] ? attributes[ attrUnit ] : 'px' }
257 units={ units }
258 onClick={ ( value ) => {
259 if ( 'undefined' !== typeof attributes[ attrUnit ] ) {
260 this.onChangeUnits( value );
261 } else {
262 return false;
263 }
264 } }
265 />
266
267 <div className="components-gblocks-dimensions-control__inputs">
268 <input
269 className="components-gblocks-dimensions-control__number"
270 placeholder={ topPlaceholder }
271 type="number"
272 onChange={ onChangeTopValue }
273 /* translators: Dimension label (padding, margin, border) */
274 aria-label={ sprintf( __( '%s Top', 'generateblocks' ), label ) }
275 value={ attributes[ attrTop ] ? attributes[ attrTop ] : '' }
276 min={ type === 'padding' ? 0 : undefined }
277 data-attribute={ type }
278 />
279 <input
280 className="components-gblocks-dimensions-control__number"
281 placeholder={ rightPlaceholder }
282 type="number"
283 onChange={ onChangeRightValue }
284 /* translators: Dimension label (padding, margin, border) */
285 aria-label={ sprintf( __( '%s Right', 'generateblocks' ), label ) }
286 value={ attributes[ attrRight ] ? attributes[ attrRight ] : '' }
287 min={ type === 'padding' ? 0 : undefined }
288 data-attribute={ type }
289 />
290 <input
291 className="components-gblocks-dimensions-control__number"
292 placeholder={ bottomPlaceholder }
293 type="number"
294 onChange={ onChangeBottomValue }
295 /* translators: Dimension label (padding, margin, border) */
296 aria-label={ sprintf( __( '%s Bottom', 'generateblocks' ), label ) }
297 value={ attributes[ attrBottom ] ? attributes[ attrBottom ] : '' }
298 min={ type === 'padding' ? 0 : undefined }
299 data-attribute={ type }
300 />
301 <input
302 className="components-gblocks-dimensions-control__number"
303 placeholder={ leftPlaceholder }
304 type="number"
305 onChange={ onChangeLeftValue }
306 /* translators: Dimension label (padding, margin, border) */
307 aria-label={ sprintf( __( '%s Left', 'generateblocks' ), label ) }
308 value={ attributes[ attrLeft ] ? attributes[ attrLeft ] : '' }
309 min={ type === 'padding' ? 0 : undefined }
310 data-attribute={ type }
311 />
312 <Tooltip text={ !! attributes[ attrSyncUnits ] ? __( 'Unsync', 'generateblocks' ) : __( 'Sync', 'generateblocks' ) } >
313 <Button
314 className="components-gblocks-dimensions-control_sync"
315 aria-label={ __( 'Sync Units', 'generateblocks' ) }
316 isPrimary={ attributes[ attrSyncUnits ] ? attributes[ attrSyncUnits ] : false }
317 aria-pressed={ attributes[ attrSyncUnits ] ? attributes[ attrSyncUnits ] : false }
318 onClick={ ( value ) => this.syncUnits( value, '' ) }
319 isSmall
320 >
321 { !! attributes[ attrSyncUnits ] ? getIcon( 'sync' ) : getIcon( 'sync' ) }
322 </Button>
323 </Tooltip>
324 </div>
325
326 <div className="components-gblocks-dimensions-control__input-labels">
327 <span className="components-gblocks-dimensions-control__number-label">{ labelTop }</span>
328 <span className="components-gblocks-dimensions-control__number-label">{ labelRight }</span>
329 <span className="components-gblocks-dimensions-control__number-label">{ labelBottom }</span>
330 <span className="components-gblocks-dimensions-control__number-label">{ labelLeft }</span>
331 <span className="components-gblocks-dimensions-control__number-label"></span>
332 </div>
333 </div>
334 </Fragment>
335 );
336 }
337 }
338
339 export default DimensionsControl;
340