PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.3.0
GenerateBlocks v1.3.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 / typography / index.js
generateblocks / src / components / typography Last commit date
editor.scss 6 years ago google-fonts.js 6 years ago index.js 5 years ago
index.js
480 lines
1 /**
2 * Internal dependencies
3 */
4 import './editor.scss';
5 import googleFonts from './google-fonts';
6 import UnitPicker from '../unit-picker';
7
8 /**
9 * WordPress dependencies
10 */
11 import {
12 __,
13 } from '@wordpress/i18n';
14
15 import {
16 Component,
17 Fragment,
18 } from '@wordpress/element';
19
20 import {
21 BaseControl,
22 SelectControl,
23 ToggleControl,
24 TextControl,
25 Button,
26 } from '@wordpress/components';
27
28 /**
29 * Typography Component
30 */
31 class TypographyControls extends Component {
32 render() {
33 const {
34 setAttributes,
35 attributes,
36 device = '',
37 showFontSize = false,
38 showFontFamily = false,
39 showFontWeight = false,
40 showTextTransform = false,
41 showLineHeight = false,
42 showLetterSpacing = false,
43 disableAdvancedToggle = false,
44 fontSizePlaceholder = '17',
45 } = this.props;
46
47 const fonts = [
48 { value: '', label: __( 'Select font', 'generateblocks' ) },
49 { value: 'Arial', label: 'Arial' },
50 { value: 'Helvetica', label: 'Helvetica' },
51 { value: 'Times New Roman', label: 'Times New Roman' },
52 { value: 'Georgia', label: 'Georgia' },
53 ];
54
55 Object.keys( googleFonts ).slice( 0, 20 ).forEach( ( k ) => {
56 fonts.push(
57 { value: k, label: k }
58 );
59 } );
60
61 fonts.push(
62 { value: 'other', label: __( 'Other', 'generateblocks' ) }
63 );
64
65 let weight = [
66 { value: '', label: __( 'Default', 'generateblocks' ) },
67 { value: 'normal', label: __( 'Normal', 'generateblocks' ) },
68 { value: 'bold', label: __( 'Bold', 'generateblocks' ) },
69 { value: '100', label: '100' },
70 { value: '200', label: '200' },
71 { value: '300', label: '300' },
72 { value: '400', label: '400' },
73 { value: '500', label: '500' },
74 { value: '600', label: '600' },
75 { value: '700', label: '700' },
76 { value: '800', label: '800' },
77 { value: '900', label: '900' },
78 ];
79
80 const transform = [
81 { value: '', label: __( 'Default', 'generateblocks' ) },
82 { value: 'uppercase', label: __( 'Uppercase', 'generateblocks' ) },
83 { value: 'lowercase', label: __( 'Lowercase', 'generateblocks' ) },
84 { value: 'capitalize', label: __( 'Capitalize', 'generateblocks' ) },
85 { value: 'initial', label: __( 'Normal', 'generateblocks' ) },
86 ];
87
88 if ( typeof googleFonts[ attributes.fontFamily ] !== 'undefined' && typeof googleFonts[ attributes.fontFamily ].weight !== 'undefined' ) {
89 weight = [
90 { value: '', label: __( 'Default', 'generateblocks' ) },
91 { value: 'normal', label: __( 'Normal', 'generateblocks' ) },
92 { value: 'bold', label: __( 'Bold', 'generateblocks' ) },
93 ];
94
95 googleFonts[ attributes.fontFamily ].weight.filter( function( k ) {
96 const hasLetters = k.match( /[a-z]/g );
97 const hasNumbers = k.match( /[0-9]/g );
98
99 if ( ( hasLetters && hasNumbers ) || 'italic' === k ) {
100 return false;
101 }
102
103 return true;
104 } ).forEach( ( k ) => {
105 weight.push(
106 { value: k, label: k }
107 );
108 } );
109 }
110
111 const onFontChange = ( value ) => {
112 if ( 'other' === value ) {
113 value = '';
114 }
115
116 let fontWeight = attributes.fontWeight; // eslint-disable-line no-unused-vars
117
118 setAttributes( { fontFamily: value } );
119
120 if ( attributes.fontWeight && Object.values( weight ).indexOf( attributes.fontWeight ) < 0 ) {
121 fontWeight = ''; // eslint-disable-line no-unused-vars
122 }
123
124 if ( typeof googleFonts[ value ] !== 'undefined' ) {
125 setAttributes( {
126 'googleFont': true, // eslint-disable-line quote-props
127 'fontFamilyFallback': googleFonts[ value ].fallback, // eslint-disable-line quote-props
128 'googleFontVariants': googleFonts[ value ].weight.join( ', ' ), // eslint-disable-line quote-props
129 } );
130 } else {
131 setAttributes( {
132 'googleFont': false, // eslint-disable-line quote-props
133 'fontFamilyFallback': '', // eslint-disable-line quote-props
134 'googleFontVariants': '', // eslint-disable-line quote-props
135 } );
136 }
137 };
138
139 const onFontShortcut = ( event ) => {
140 setAttributes( { 'fontFamily': event.target.value } ); // eslint-disable-line quote-props
141 onFontChange( event.target.value );
142 };
143
144 const getValue = ( value, setDevice ) => {
145 const valueName = value + setDevice;
146
147 return attributes[ valueName ];
148 };
149
150 const getAttributeName = ( name, setDevice ) => {
151 const attributeName = name + setDevice;
152
153 return attributeName;
154 };
155
156 let showAdvancedToggle = attributes.showAdvancedTypography;
157
158 if ( disableAdvancedToggle ) {
159 showAdvancedToggle = true;
160 }
161
162 let responsiveFontSizePlaceholder = fontSizePlaceholder;
163
164 if ( 'Tablet' === device && attributes.fontSize ) {
165 responsiveFontSizePlaceholder = attributes.fontSize;
166 }
167
168 if ( 'Mobile' === device ) {
169 if ( attributes.fontSizeTablet ) {
170 responsiveFontSizePlaceholder = attributes.fontSizeTablet;
171 } else if ( attributes.fontSize ) {
172 responsiveFontSizePlaceholder = attributes.fontSize;
173 }
174 }
175
176 let responsiveLineHeightPlaceholder = '';
177
178 if ( 'Tablet' === device && attributes.lineHeight ) {
179 responsiveLineHeightPlaceholder = attributes.lineHeight;
180 }
181
182 if ( 'Mobile' === device ) {
183 if ( attributes.lineHeightTablet ) {
184 responsiveLineHeightPlaceholder = attributes.lineHeightTablet;
185 } else if ( attributes.lineHeight ) {
186 responsiveLineHeightPlaceholder = attributes.lineHeight;
187 }
188 }
189
190 return (
191 <Fragment>
192 <div className={ 'components-gblocks-typography-weight-transform' }>
193 { showFontWeight &&
194 <SelectControl
195 label={ __( 'Weight', 'generateblocks' ) }
196 value={ attributes.fontWeight }
197 options={ weight }
198 onChange={ ( value ) => {
199 setAttributes( {
200 'fontWeight': value, // eslint-disable-line quote-props
201 } );
202 } }
203 className="components-base-control"
204 />
205 }
206
207 { showTextTransform &&
208 <SelectControl
209 label={ __( 'Transform', 'generateblocks' ) }
210 value={ attributes.textTransform }
211 options={ transform }
212 onChange={ ( value ) => {
213 setAttributes( {
214 'textTransform': value, // eslint-disable-line quote-props
215 } );
216 } }
217 className="components-base-control"
218 />
219 }
220 </div>
221
222 { ! disableAdvancedToggle &&
223 <ToggleControl
224 label={ __( 'Show Advanced Typography', 'generateblocks' ) }
225 checked={ !! attributes.showAdvancedTypography }
226 onChange={ ( value ) => {
227 setAttributes( {
228 'showAdvancedTypography': value, // eslint-disable-line quote-props
229 } );
230 } }
231 />
232 }
233
234 { showFontFamily && showAdvancedToggle &&
235 <BaseControl className={ 'gblocks-font-family-shortcuts' }>
236 <span className="components-base-control__label">{ __( 'Font Family', 'generateblocks' ) }</span>
237
238 <select
239 className="components-select-control__input components-select-control__input--gblocks-fontfamily"
240 onChange={ onFontShortcut }
241 onBlur={ onFontShortcut }
242 >
243 { fonts.map( ( option, index ) =>
244 <option
245 key={ `${ option.label }-${ option.value }-${ index }` }
246 value={ option.value }
247 >
248 { option.label }
249 </option>
250 ) }
251 </select>
252 </BaseControl>
253 }
254
255 { showFontFamily && showAdvancedToggle &&
256 <TextControl
257 value={ attributes.fontFamily }
258 placeholder={ __( 'Enter font name', 'generateblocks' ) }
259 onChange={ ( nextFontFamily ) => onFontChange( nextFontFamily ) }
260 />
261 }
262
263 { showFontFamily && '' !== attributes.fontFamily && showAdvancedToggle &&
264 <Fragment>
265 <ToggleControl
266 label={ __( 'Google Font', 'generateblocks' ) }
267 checked={ !! attributes.googleFont }
268 onChange={ ( value ) => {
269 setAttributes( {
270 'googleFont': value, // eslint-disable-line quote-props
271 } );
272
273 if ( value ) {
274 if ( typeof googleFonts[ attributes.fontFamily ] !== 'undefined' ) {
275 setAttributes( {
276 'fontFamilyFallback': googleFonts[ attributes.fontFamily ].fallback, // eslint-disable-line quote-props
277 'googleFontVariants': googleFonts[ attributes.fontFamily ].weight.join( ', ' ), // eslint-disable-line quote-props
278 } );
279 }
280 }
281 } }
282 />
283
284 { !! attributes.googleFont &&
285 <TextControl
286 label={ __( 'Variants', 'generateblocks' ) }
287 value={ attributes.googleFontVariants }
288 placeholder={ __( '300, 400, 400i', 'generateblocks' ) }
289 onChange={ ( value ) => {
290 setAttributes( {
291 'googleFontVariants': value, // eslint-disable-line quote-props
292 } );
293 } }
294 />
295 }
296 </Fragment>
297 }
298
299 { showFontFamily && showAdvancedToggle &&
300 <TextControl
301 label={ __( 'Font Family Fallback', 'generateblocks' ) }
302 value={ attributes.fontFamilyFallback }
303 placeholder={ __( 'sans-serif', 'generateblocks' ) }
304 onChange={ ( value ) => {
305 setAttributes( {
306 'fontFamilyFallback': value, // eslint-disable-line quote-props
307 } );
308 } }
309 />
310 }
311
312 { showFontSize && showAdvancedToggle &&
313 <BaseControl>
314 <UnitPicker
315 label={ __( 'Font Size', 'generateblocks' ) }
316 value={ attributes.fontSizeUnit }
317 units={ [ 'px', 'em', '%' ] }
318 onClick={ ( value ) => {
319 setAttributes( {
320 fontSizeUnit: value,
321 } );
322 } }
323 />
324
325 <div className="components-gblocks-typography-control__inputs">
326 <TextControl
327 type={ 'number' }
328 value={ getValue( 'fontSize', device ) || '' }
329 placeholder={ responsiveFontSizePlaceholder }
330 onChange={ ( value ) => {
331 const name = getAttributeName( 'fontSize', device );
332
333 setAttributes( {
334 [ name ]: parseFloat( value ),
335 } );
336 } }
337 min={ 1 }
338 autoComplete="off"
339 />
340
341 <Button
342 isSmall
343 isSecondary
344 className="components-gblocks-default-number"
345 onClick={ () => {
346 const name = getAttributeName( 'fontSize', device );
347
348 setAttributes( {
349 [ name ]: this.props.defaultFontSize,
350 } );
351 } }
352 >
353 { __( 'Reset', 'generateblocks' ) }
354 </Button>
355 </div>
356 </BaseControl>
357 }
358
359 { showLineHeight && showAdvancedToggle &&
360 <BaseControl>
361 <UnitPicker
362 label={ __( 'Line Height', 'generateblocks' ) }
363 value={ attributes.lineHeightUnit }
364 units={ [ 'px', 'em', '%' ] }
365 onClick={ ( value ) => {
366 setAttributes( {
367 lineHeightUnit: value,
368 } );
369 } }
370 />
371
372 <div className="components-gblocks-typography-control__inputs">
373 <TextControl
374 type={ 'number' }
375 value={ getValue( 'lineHeight', device ) || 0 === getValue( 'lineHeight', device ) ? getValue( 'lineHeight', device ) : '' }
376 placeholder={ responsiveLineHeightPlaceholder }
377 onChange={ ( value ) => {
378 const name = getAttributeName( 'lineHeight', device );
379
380 setAttributes( {
381 [ name ]: value,
382 } );
383 } }
384 onBlur={ () => {
385 const name = getAttributeName( 'lineHeight', device );
386
387 setAttributes( {
388 [ name ]: parseFloat( getValue( 'lineHeight', device ) ),
389 } );
390 } }
391 onClick={ ( e ) => {
392 // Make sure onBlur fires in Firefox.
393 e.currentTarget.focus();
394 } }
395 min={ 0 }
396 step={ .1 }
397 autoComplete="off"
398 />
399
400 <Button
401 isSmall
402 isSecondary
403 className="components-gblocks-default-number"
404 onClick={ () => {
405 const name = getAttributeName( 'lineHeight', device );
406
407 setAttributes( {
408 [ name ]: this.props.defaultLineHeight,
409 } );
410 } }
411 >
412 { __( 'Reset', 'generateblocks' ) }
413 </Button>
414 </div>
415 </BaseControl>
416 }
417
418 { showLetterSpacing && showAdvancedToggle &&
419 <BaseControl>
420 <UnitPicker
421 label={ __( 'Letter Spacing', 'generateblocks' ) }
422 value={ 'em' }
423 units={ [ 'em' ] }
424 onClick={ () => {
425 return false;
426 } }
427 />
428
429 <div className="components-gblocks-typography-control__inputs">
430 <TextControl
431 type={ 'number' }
432 value={ getValue( 'letterSpacing', device ) || '' }
433 placeholder="0.01"
434 onChange={ ( value ) => {
435 const name = getAttributeName( 'letterSpacing', device );
436
437 setAttributes( {
438 [ name ]: value,
439 } );
440 } }
441 onBlur={ () => {
442 const name = getAttributeName( 'letterSpacing', device );
443
444 setAttributes( {
445 [ name ]: parseFloat( getValue( 'letterSpacing', device ) ),
446 } );
447 } }
448 onClick={ ( e ) => {
449 // Make sure onBlur fires in Firefox.
450 e.currentTarget.focus();
451 } }
452 min={ -1 }
453 step={ .01 }
454 autoComplete="off"
455 />
456
457 <Button
458 isSmall
459 isSecondary
460 className="components-gblocks-default-number"
461 onClick={ () => {
462 const name = getAttributeName( 'letterSpacing', device );
463
464 setAttributes( {
465 [ name ]: this.props.defaultLetterSpacing,
466 } );
467 } }
468 >
469 { __( 'Reset', 'generateblocks' ) }
470 </Button>
471 </div>
472 </BaseControl>
473 }
474 </Fragment>
475 );
476 }
477 }
478
479 export default TypographyControls;
480