PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.1.0
GenerateBlocks v1.1.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 / blocks / button / edit.js
generateblocks / src / blocks / button Last commit date
css 6 years ago attributes.js 6 years ago block.js 6 years ago edit.js 6 years ago editor.scss 6 years ago save.js 6 years ago style.scss 6 years ago
edit.js
1076 lines
1 /**
2 * Block: Buttons
3 */
4
5 import classnames from 'classnames';
6 import ColorPicker from '../../components/color-picker';
7 import IconPicker from '../../components/icon-picker';
8 import URLInput from '../../components/url-input';
9 import DimensionsControl from '../../components/dimensions/';
10 import TypographyControls from '../../components/typography';
11 import GradientControl from '../../components/gradient/';
12 import ResponsiveTabs from '../../components/responsive-tabs';
13 import PanelArea from '../../components/panel-area/';
14 import getIcon from '../../utils/get-icon';
15 import getSelectedDevice from '../../utils/get-selected-device';
16 import DesktopCSS from './css/desktop.js';
17 import sanitizeSVG from '../../utils/sanitize-svg';
18
19 const {
20 __,
21 _x,
22 sprintf,
23 } = wp.i18n;
24
25 const {
26 TabPanel,
27 TextControl,
28 Toolbar,
29 Tooltip,
30 Button,
31 ButtonGroup,
32 } = wp.components;
33
34 const {
35 Fragment,
36 Component,
37 } = wp.element;
38
39 const {
40 InspectorControls,
41 RichText,
42 BlockControls,
43 } = wp.blockEditor;
44
45 const {
46 cloneBlock,
47 } = wp.blocks;
48
49 const {
50 applyFilters,
51 } = wp.hooks;
52
53 const ELEMENT_ID_REGEX = /[\s#]/g;
54 const gbButtonIds = [];
55
56 class GenerateBlockButton extends Component {
57 constructor() {
58 super( ...arguments );
59
60 this.getFontSizePlaceholder = this.getFontSizePlaceholder.bind( this );
61
62 this.state = {
63 selectedDevice: 'desktop',
64 fontSizePlaceholder: '17',
65 };
66 }
67
68 componentDidMount() {
69 const id = this.props.clientId.substr( 2, 9 ).replace( '-', '' );
70
71 if ( ! this.props.attributes.uniqueId ) {
72 this.props.setAttributes( {
73 uniqueId: id,
74 } );
75
76 gbButtonIds.push( id );
77 } else if ( gbButtonIds.includes( this.props.attributes.uniqueId ) ) {
78 this.props.setAttributes( {
79 uniqueId: id,
80 } );
81
82 gbButtonIds.push( id );
83 } else {
84 gbButtonIds.push( this.props.attributes.uniqueId );
85 }
86
87 const tempFontSizePlaceholder = this.getFontSizePlaceholder();
88
89 if ( tempFontSizePlaceholder !== this.state.fontSizePlaceholder ) {
90 this.setState( {
91 fontSizePlaceholder: tempFontSizePlaceholder,
92 } );
93 }
94
95 // hasIcon came late, so let's set it on mount if we have an icon.
96 if ( ! this.props.attributes.hasIcon && this.props.attributes.icon ) {
97 this.props.setAttributes( {
98 hasIcon: true,
99 } );
100 }
101 }
102
103 componentDidUpdate() {
104 const tempFontSizePlaceholder = this.getFontSizePlaceholder();
105
106 if ( tempFontSizePlaceholder !== this.state.fontSizePlaceholder ) {
107 this.setState( {
108 fontSizePlaceholder: tempFontSizePlaceholder,
109 } );
110 }
111 }
112
113 getFontSizePlaceholder() {
114 let placeholder = '17';
115 const buttonId = document.querySelector( '.gb-button-' + this.props.attributes.uniqueId );
116
117 if ( buttonId ) {
118 placeholder = parseFloat( window.getComputedStyle( buttonId ).fontSize );
119 }
120
121 return placeholder;
122 }
123
124 render() {
125 const {
126 attributes,
127 setAttributes,
128 isSelected,
129 clientId,
130 } = this.props;
131
132 const {
133 selectedDevice,
134 fontSizePlaceholder,
135 } = this.state;
136
137 const {
138 uniqueId,
139 elementId,
140 cssClasses,
141 text,
142 url,
143 target,
144 relNoFollow,
145 relSponsored,
146 icon,
147 iconLocation,
148 removeText,
149 ariaLabel,
150 backgroundColor,
151 backgroundColorOpacity,
152 textColor,
153 backgroundColorHover,
154 backgroundColorHoverOpacity,
155 textColorHover,
156 fontFamily,
157 googleFont,
158 googleFontVariants,
159 borderColor,
160 borderColorOpacity,
161 borderColorHover,
162 borderColorHoverOpacity,
163 iconSize,
164 iconSizeTablet,
165 iconSizeMobile,
166 iconSizeUnit,
167 } = attributes;
168
169 jQuery( '.gb-button' ).on( 'click', function( e ) {
170 e.preventDefault();
171 } );
172
173 const relAttributes = [];
174
175 if ( relNoFollow ) {
176 relAttributes.push( 'nofollow' );
177 }
178
179 if ( target ) {
180 relAttributes.push( 'noopener', 'noreferrer' );
181 }
182
183 if ( relSponsored ) {
184 relAttributes.push( 'sponsored' );
185 }
186
187 let googleFontsAttr = '';
188
189 if ( googleFontVariants ) {
190 googleFontsAttr = ':' + googleFontVariants;
191 }
192
193 const unitSizes = [
194 {
195 name: _x( 'Pixel', 'A size unit for CSS markup', 'generateblocks' ),
196 unitValue: 'px',
197 },
198 {
199 name: _x( 'Em', 'A size unit for CSS markup', 'generateblocks' ),
200 unitValue: 'em',
201 },
202 ];
203
204 let htmlAttributes = {
205 id: !! elementId ? elementId : undefined,
206 className: classnames( {
207 'gb-button': true,
208 [ `gb-button-${ uniqueId }` ]: true,
209 [ `${ cssClasses }` ]: '' !== cssClasses,
210 } ),
211 href: !! url ? url : undefined,
212 target: !! target ? '_blank' : undefined,
213 rel: relAttributes && relAttributes.length > 0 ? relAttributes.join( ' ' ) : undefined,
214 'aria-label': !! ariaLabel ? ariaLabel : undefined,
215 };
216
217 htmlAttributes = applyFilters( 'generateblocks.frontend.htmlAttributes', htmlAttributes, 'generateblocks/button', attributes );
218
219 return (
220 <Fragment>
221 <BlockControls>
222 <Toolbar>
223 <Tooltip text={ __( 'Add Button', 'generateblocks' ) }>
224 <Button
225 className="gblocks-add-new-button"
226 icon={ 'insert' }
227 onClick={ () => {
228 let parentBlockId = false;
229
230 if ( typeof wp.data.select( 'core/block-editor' ).getBlockParentsByBlockName === 'function' ) {
231 parentBlockId = wp.data.select( 'core/block-editor' ).getBlockParentsByBlockName( clientId, 'generateblocks/button-container', true )[ 0 ];
232 } else {
233 parentBlockId = wp.data.select( 'core/block-editor' ).getBlockRootClientId( clientId );
234 }
235
236 const thisBlock = wp.data.select( 'core/block-editor' ).getBlocksByClientId( clientId )[ 0 ];
237 const clonedBlock = cloneBlock( thisBlock );
238
239 wp.data.dispatch( 'core/block-editor' ).insertBlocks( clonedBlock, undefined, parentBlockId );
240 } }
241 />
242 </Tooltip>
243 </Toolbar>
244 </BlockControls>
245
246 <InspectorControls>
247 <ResponsiveTabs { ...this.props }
248 selectedDevice={ getSelectedDevice( selectedDevice ) }
249 onClick={ ( device ) => {
250 window.localStorage.setItem( 'generateblocksSelectedDevice', device );
251
252 this.setState( {
253 selectedDevice: device,
254 } );
255 } }
256 />
257
258 <PanelArea { ...this.props }
259 title={ __( 'Typography', 'generateblocks' ) }
260 initialOpen={ false }
261 icon={ getIcon( 'typography' ) }
262 className={ 'gblocks-panel-label' }
263 id={ 'buttonTypography' }
264 state={ this.state }
265 showPanel={ ! removeText || false }
266 >
267
268 { 'desktop' === getSelectedDevice( selectedDevice ) && (
269 <Fragment>
270 <TypographyControls { ...this.props }
271 showFontFamily={ true }
272 showFontWeight={ true }
273 showTextTransform={ true }
274 showFontSize={ true }
275 showLetterSpacing={ true }
276 fontSizePlaceholder={ fontSizePlaceholder }
277 defaultFontSize={ generateBlocksDefaults.button.fontSize }
278 defaultFontSizeUnit={ generateBlocksDefaults.button.fontSizeUnit }
279 defaultLetterSpacing={ generateBlocksDefaults.button.letterSpacing }
280 />
281 </Fragment>
282 ) }
283
284 { 'tablet' === getSelectedDevice( selectedDevice ) && (
285 <Fragment>
286 <TypographyControls { ...this.props }
287 device={ 'Tablet' }
288 showFontSize={ true }
289 showLetterSpacing={ true }
290 disableAdvancedToggle={ true }
291 defaultFontSize={ generateBlocksDefaults.button.fontSizeTablet }
292 defaultFontSizeUnit={ generateBlocksDefaults.button.fontSizeUnit }
293 defaultLetterSpacing={ generateBlocksDefaults.button.letterSpacingTablet }
294 />
295 </Fragment>
296 ) }
297
298 { 'mobile' === getSelectedDevice( selectedDevice ) && (
299 <Fragment>
300 <TypographyControls { ...this.props }
301 device={ 'Mobile' }
302 showFontSize={ true }
303 showLetterSpacing={ true }
304 disableAdvancedToggle={ true }
305 defaultFontSize={ generateBlocksDefaults.button.fontSizeMobile }
306 defaultFontSizeUnit={ generateBlocksDefaults.button.fontSizeUnit }
307 defaultLetterSpacing={ generateBlocksDefaults.button.letterSpacingMobile }
308 />
309 </Fragment>
310 ) }
311
312 { applyFilters( 'generateblocks.editor.controls', '', 'buttonTypography', this.props, this.state ) }
313 </PanelArea>
314
315 <PanelArea { ...this.props }
316 title={ __( 'Spacing', 'generateblocks' ) }
317 initialOpen={ false }
318 icon={ getIcon( 'spacing' ) }
319 className={ 'gblocks-panel-label' }
320 id={ 'buttonSpacing' }
321 state={ this.state }
322 >
323
324 { 'desktop' === getSelectedDevice( selectedDevice ) && (
325 <Fragment>
326 <DimensionsControl { ...this.props }
327 device={ getSelectedDevice( selectedDevice ) }
328 type={ 'padding' }
329 label={ __( 'Padding', 'generateblocks' ) }
330 attrTop={ 'paddingTop' }
331 attrRight={ 'paddingRight' }
332 attrBottom={ 'paddingBottom' }
333 attrLeft={ 'paddingLeft' }
334 attrUnit={ 'paddingUnit' }
335 attrSyncUnits={ 'paddingSyncUnits' }
336 defaults={ generateBlocksDefaults.button }
337 />
338
339 <DimensionsControl { ...this.props }
340 device={ getSelectedDevice( selectedDevice ) }
341 type={ 'margin' }
342 label={ __( 'Margin', 'generateblocks' ) }
343 attrTop={ 'marginTop' }
344 attrRight={ 'marginRight' }
345 attrBottom={ 'marginBottom' }
346 attrLeft={ 'marginLeft' }
347 attrUnit={ 'marginUnit' }
348 attrSyncUnits={ 'marginSyncUnits' }
349 defaults={ generateBlocksDefaults.button }
350 />
351
352 <DimensionsControl { ...this.props }
353 device={ getSelectedDevice( selectedDevice ) }
354 type={ 'padding' }
355 label={ __( 'Border Size', 'generateblocks' ) }
356 attrTop={ 'borderSizeTop' }
357 attrRight={ 'borderSizeRight' }
358 attrBottom={ 'borderSizeBottom' }
359 attrLeft={ 'borderSizeLeft' }
360 attrSyncUnits={ 'borderSizeSyncUnits' }
361 displayUnit={ 'px' }
362 defaults={ generateBlocksDefaults.button }
363 />
364
365 <DimensionsControl { ...this.props }
366 device={ getSelectedDevice( selectedDevice ) }
367 type={ 'padding' }
368 label={ __( 'Border Radius', 'generateblocks' ) }
369 attrTop={ 'borderRadiusTopLeft' }
370 attrRight={ 'borderRadiusTopRight' }
371 attrBottom={ 'borderRadiusBottomRight' }
372 attrLeft={ 'borderRadiusBottomLeft' }
373 attrUnit={ 'borderRadiusUnit' }
374 attrSyncUnits={ 'borderRadiusSyncUnits' }
375 labelTop={ __( 'T-Left', 'generateblocks' ) }
376 labelRight={ __( 'T-Right', 'generateblocks' ) }
377 labelBottom={ __( 'B-Right', 'generateblocks' ) }
378 labelLeft={ __( 'B-Left', 'generateblocks' ) }
379 defaults={ generateBlocksDefaults.button }
380 />
381 </Fragment>
382 ) }
383
384 { 'tablet' === getSelectedDevice( selectedDevice ) && (
385 <Fragment>
386 <DimensionsControl { ...this.props }
387 device={ getSelectedDevice( selectedDevice ) }
388 type={ 'padding' }
389 label={ __( 'Padding', 'generateblocks' ) }
390 attrTop={ 'paddingTopTablet' }
391 attrRight={ 'paddingRightTablet' }
392 attrBottom={ 'paddingBottomTablet' }
393 attrLeft={ 'paddingLeftTablet' }
394 attrUnit={ 'paddingUnit' }
395 attrSyncUnits={ 'paddingSyncUnits' }
396 defaults={ generateBlocksDefaults.button }
397 />
398
399 <DimensionsControl { ...this.props }
400 device={ getSelectedDevice( selectedDevice ) }
401 type={ 'margin' }
402 label={ __( 'Margin', 'generateblocks' ) }
403 attrTop={ 'marginTopTablet' }
404 attrRight={ 'marginRightTablet' }
405 attrBottom={ 'marginBottomTablet' }
406 attrLeft={ 'marginLeftTablet' }
407 attrUnit={ 'marginUnit' }
408 attrSyncUnits={ 'marginSyncUnits' }
409 defaults={ generateBlocksDefaults.button }
410 />
411
412 <DimensionsControl { ...this.props }
413 device={ getSelectedDevice( selectedDevice ) }
414 type={ 'padding' }
415 label={ __( 'Border Size', 'generateblocks' ) }
416 attrTop={ 'borderSizeTopTablet' }
417 attrRight={ 'borderSizeRightTablet' }
418 attrBottom={ 'borderSizeBottomTablet' }
419 attrLeft={ 'borderSizeLeftTablet' }
420 attrSyncUnits={ 'borderSizeSyncUnits' }
421 displayUnit={ 'px' }
422 defaults={ generateBlocksDefaults.button }
423 />
424
425 <DimensionsControl { ...this.props }
426 device={ getSelectedDevice( selectedDevice ) }
427 type={ 'padding' }
428 label={ __( 'Border Radius', 'generateblocks' ) }
429 attrTop={ 'borderRadiusTopLeftTablet' }
430 attrRight={ 'borderRadiusTopRightTablet' }
431 attrBottom={ 'borderRadiusBottomRightTablet' }
432 attrLeft={ 'borderRadiusBottomLeftTablet' }
433 attrUnit={ 'borderRadiusUnit' }
434 attrSyncUnits={ 'borderRadiusSyncUnits' }
435 labelTop={ __( 'T-Left', 'generateblocks' ) }
436 labelRight={ __( 'T-Right', 'generateblocks' ) }
437 labelBottom={ __( 'B-Right', 'generateblocks' ) }
438 labelLeft={ __( 'B-Left', 'generateblocks' ) }
439 defaults={ generateBlocksDefaults.button }
440 />
441 </Fragment>
442 ) }
443
444 { 'mobile' === getSelectedDevice( selectedDevice ) && (
445 <Fragment>
446 <DimensionsControl { ...this.props }
447 device={ getSelectedDevice( selectedDevice ) }
448 type={ 'padding' }
449 label={ __( 'Padding', 'generateblocks' ) }
450 attrTop={ 'paddingTopMobile' }
451 attrRight={ 'paddingRightMobile' }
452 attrBottom={ 'paddingBottomMobile' }
453 attrLeft={ 'paddingLeftMobile' }
454 attrUnit={ 'paddingUnit' }
455 attrSyncUnits={ 'paddingSyncUnits' }
456 defaults={ generateBlocksDefaults.button }
457 />
458
459 <DimensionsControl { ...this.props }
460 device={ getSelectedDevice( selectedDevice ) }
461 type={ 'padding' }
462 label={ __( 'Margin', 'generateblocks' ) }
463 attrTop={ 'marginTopMobile' }
464 attrRight={ 'marginRightMobile' }
465 attrBottom={ 'marginBottomMobile' }
466 attrLeft={ 'marginLeftMobile' }
467 attrUnit={ 'marginUnit' }
468 attrSyncUnits={ 'marginSyncUnits' }
469 defaults={ generateBlocksDefaults.button }
470 />
471
472 <DimensionsControl { ...this.props }
473 device={ getSelectedDevice( selectedDevice ) }
474 type={ 'padding' }
475 label={ __( 'Border Size', 'generateblocks' ) }
476 attrTop={ 'borderSizeTopMobile' }
477 attrRight={ 'borderSizeRightMobile' }
478 attrBottom={ 'borderSizeBottomMobile' }
479 attrLeft={ 'borderSizeLeftMobile' }
480 attrSyncUnits={ 'borderSizeSyncUnits' }
481 displayUnit={ 'px' }
482 defaults={ generateBlocksDefaults.button }
483 />
484
485 <DimensionsControl { ...this.props }
486 device={ getSelectedDevice( selectedDevice ) }
487 type={ 'padding' }
488 label={ __( 'Border Radius', 'generateblocks' ) }
489 attrTop={ 'borderRadiusTopLeftMobile' }
490 attrRight={ 'borderRadiusTopRightMobile' }
491 attrBottom={ 'borderRadiusBottomRightMobile' }
492 attrLeft={ 'borderRadiusBottomLeftMobile' }
493 attrUnit={ 'borderRadiusUnit' }
494 attrSyncUnits={ 'borderRadiusSyncUnits' }
495 labelTop={ __( 'T-Left', 'generateblocks' ) }
496 labelRight={ __( 'T-Right', 'generateblocks' ) }
497 labelBottom={ __( 'B-Right', 'generateblocks' ) }
498 labelLeft={ __( 'B-Left', 'generateblocks' ) }
499 defaults={ generateBlocksDefaults.button }
500 />
501 </Fragment>
502 ) }
503
504 { applyFilters( 'generateblocks.editor.controls', '', 'buttonSpacing', this.props, this.state ) }
505 </PanelArea>
506
507 <PanelArea { ...this.props }
508 title={ __( 'Colors', 'generateblocks' ) }
509 initialOpen={ false }
510 icon={ getIcon( 'colors' ) }
511 className={ 'gblocks-panel-label' }
512 id={ 'buttonColors' }
513 state={ this.state }
514 showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || false }
515 >
516 <TabPanel className="layout-tab-panel gblocks-control-tabs"
517 activeClass="active-tab"
518 tabs={ [
519 {
520 name: 'button-colors',
521 title: __( 'Normal', 'generateblocks' ),
522 className: 'button-colors',
523 },
524 {
525 name: 'button-colors-hover',
526 title: __( 'Hover', 'generateblocks' ),
527 className: 'button-colors-hover',
528 },
529 ] }>
530 {
531 ( tab ) => {
532 const isNormal = tab.name === 'button-colors';
533
534 return (
535 <div>
536 { isNormal ? (
537 <Fragment>
538 <ColorPicker
539 label={ __( 'Background Color', 'generateblocks' ) }
540 value={ backgroundColor }
541 alpha={ true }
542 valueOpacity={ backgroundColorOpacity }
543 attrOpacity={ 'backgroundColorOpacity' }
544 key={ 'buttonBackgroundColor' }
545 onChange={ ( nextBackgroundColor ) =>
546 setAttributes( {
547 backgroundColor: nextBackgroundColor,
548 } )
549 }
550 onOpacityChange={ ( value ) =>
551 setAttributes( {
552 backgroundColorOpacity: value,
553 } )
554 }
555 />
556
557 <ColorPicker
558 label={ __( 'Text Color', 'generateblocks' ) }
559 value={ textColor }
560 alpha={ false }
561 key={ 'buttonTextColor' }
562 onChange={ ( nextTextColor ) =>
563 setAttributes( {
564 textColor: nextTextColor,
565 } )
566 }
567 />
568
569 <ColorPicker
570 label={ __( 'Border Color', 'generateblocks' ) }
571 value={ borderColor }
572 alpha={ true }
573 valueOpacity={ borderColorOpacity }
574 attrOpacity={ 'borderColorOpacity' }
575 key={ 'buttonBorderColor' }
576 onChange={ ( value ) =>
577 setAttributes( {
578 borderColor: value,
579 } )
580 }
581 onOpacityChange={ ( value ) =>
582 setAttributes( {
583 borderColorOpacity: value,
584 } )
585 }
586 />
587
588 { applyFilters( 'generateblocks.editor.controls', '', 'buttonColorsNormal', this.props, this.state ) }
589 </Fragment>
590
591 ) : (
592
593 <Fragment>
594 <ColorPicker
595 label={ __( 'Background Color', 'generateblocks' ) }
596 value={ backgroundColorHover }
597 alpha={ true }
598 valueOpacity={ backgroundColorHoverOpacity }
599 attrOpacity={ 'backgroundColorHoverOpacity' }
600 key={ 'buttonBackgroundColorHover' }
601 onChange={ ( nextBackgroundColorHover ) =>
602 setAttributes( {
603 backgroundColorHover: nextBackgroundColorHover,
604 } )
605 }
606 onOpacityChange={ ( value ) =>
607 setAttributes( {
608 backgroundColorHoverOpacity: value,
609 } )
610 }
611 />
612
613 <ColorPicker
614 label={ __( 'Text Color', 'generateblocks' ) }
615 value={ textColorHover }
616 alpha={ false }
617 key={ 'buttonTextColorHover' }
618 onChange={ ( nextTextColorHover ) =>
619 setAttributes( {
620 textColorHover: nextTextColorHover,
621 } )
622 }
623 />
624
625 <ColorPicker
626 label={ __( 'Border Color', 'generateblocks' ) }
627 value={ borderColorHover }
628 alpha={ true }
629 valueOpacity={ borderColorHoverOpacity }
630 attrOpacity={ 'borderColorHoverOpacity' }
631 key={ 'buttonBorderColorHover' }
632 onChange={ ( value ) =>
633 setAttributes( {
634 borderColorHover: value,
635 } )
636 }
637 onOpacityChange={ ( value ) =>
638 setAttributes( {
639 borderColorHoverOpacity: value,
640 } )
641 }
642 />
643
644 { applyFilters( 'generateblocks.editor.controls', '', 'buttonColorsHover', this.props, this.state ) }
645 </Fragment>
646 ) }
647 </div>
648 );
649 }
650 }
651 </TabPanel>
652
653 { applyFilters( 'generateblocks.editor.controls', '', 'buttonColors', this.props, this.state ) }
654 </PanelArea>
655
656 <PanelArea { ...this.props }
657 title={ __( 'Background Gradient', 'generateblocks' ) }
658 initialOpen={ false }
659 icon={ getIcon( 'gradients' ) }
660 className={ 'gblocks-panel-label' }
661 id={ 'buttonBackgroundGradient' }
662 state={ this.state }
663 showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || false }
664 >
665 <GradientControl { ...this.props }
666 attrGradient={ 'gradient' }
667 attrGradientDirection={ 'gradientDirection' }
668 attrGradientColorOne={ 'gradientColorOne' }
669 attrGradientColorOneOpacity={ 'gradientColorOneOpacity' }
670 attrGradientColorStopOne={ 'gradientColorStopOne' }
671 attrGradientColorTwo={ 'gradientColorTwo' }
672 attrGradientColorTwoOpacity={ 'gradientColorTwoOpacity' }
673 attrGradientColorStopTwo={ 'gradientColorStopTwo' }
674 defaultColorOne={ generateBlocksDefaults.button.gradientColorOne }
675 defaultColorTwo={ generateBlocksDefaults.button.gradientColorTwo }
676 />
677
678 { applyFilters( 'generateblocks.editor.controls', '', 'buttonBackgroundGradient', this.props, this.state ) }
679 </PanelArea>
680
681 <PanelArea { ...this.props }
682 title={ __( 'Icon', 'generateblocks' ) }
683 initialOpen={ false }
684 icon={ getIcon( 'icons' ) }
685 className={ 'gblocks-panel-label' }
686 id={ 'buttonIcon' }
687 state={ this.state }
688 showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || !! icon ? true : false }
689 >
690
691 { 'desktop' === getSelectedDevice( selectedDevice ) &&
692 <IconPicker { ...this.props }
693 attrIcon={ 'icon' }
694 attrIconLocation={ 'iconLocation' }
695 attrRemoveText={ 'removeText' }
696 locationOptions={ [
697 { label: __( 'Left', 'generateblocks' ), value: 'left' },
698 { label: __( 'Right', 'generateblocks' ), value: 'right' },
699 ] }
700 />
701 }
702
703 { 'desktop' === getSelectedDevice( selectedDevice ) && !! icon && (
704 <Fragment>
705 { ! removeText &&
706 <Fragment>
707 <DimensionsControl { ...this.props }
708 device={ getSelectedDevice( selectedDevice ) }
709 type={ 'padding' }
710 label={ __( 'Padding', 'generateblocks' ) }
711 attrTop={ 'iconPaddingTop' }
712 attrRight={ 'iconPaddingRight' }
713 attrBottom={ 'iconPaddingBottom' }
714 attrLeft={ 'iconPaddingLeft' }
715 attrUnit={ 'iconPaddingUnit' }
716 attrSyncUnits={ 'iconPaddingSyncUnits' }
717 defaults={ generateBlocksDefaults.button }
718 />
719 </Fragment>
720 }
721
722 <div className="components-gblocks-typography-control__header">
723 <div className="components-gblocks-typography-control__label components-base-control__label">
724 { __( 'Icon Size', 'generateblocks' ) }
725 </div>
726
727 <div className="components-gblocks-control__units">
728 <ButtonGroup className="components-gblocks-typography-control__units" aria-label={ __( 'Select Units', 'generateblocks' ) }>
729 { unitSizes.map( ( unit ) =>
730 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
731 <Tooltip text={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) } key={ unit.unitValue }>
732 <Button
733 key={ unit.unitValue }
734 className={ 'components-gblocks-typography-control__units--' + unit.name }
735 isSmall
736 isPrimary={ iconSizeUnit === unit.unitValue }
737 aria-pressed={ iconSizeUnit === unit.unitValue }
738 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
739 aria-label={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) }
740 onClick={ () => setAttributes( { iconSizeUnit: unit.unitValue } ) }
741 >
742 { unit.unitValue }
743 </Button>
744 </Tooltip>
745 ) }
746 </ButtonGroup>
747 </div>
748 </div>
749
750 <div className="components-base-control components-gblocks-typography-control__inputs">
751 <TextControl
752 type={ 'number' }
753 value={ iconSize || '' }
754 step={ 'em' === iconSizeUnit ? .1 : 1 }
755 onChange={ ( value ) => {
756 setAttributes( {
757 iconSize: value,
758 } );
759 } }
760 onBlur={ () => {
761 setAttributes( {
762 iconSize: parseFloat( iconSize ),
763 } );
764 } }
765 onClick={ ( e ) => {
766 // Make sure onBlur fires in Firefox.
767 e.currentTarget.focus();
768 } }
769 />
770
771 <Button
772 isSmall
773 isSecondary
774 className="components-gblocks-default-number"
775 onClick={ () => {
776 setAttributes( {
777 iconSize: generateBlocksDefaults.button.iconSize,
778 } );
779 } }
780 >
781 { __( 'Reset', 'generateblocks' ) }
782 </Button>
783 </div>
784 </Fragment>
785 ) }
786
787 { 'tablet' === getSelectedDevice( selectedDevice ) && !! icon &&
788 <Fragment>
789 { ! removeText &&
790 <Fragment>
791 <DimensionsControl { ...this.props }
792 device={ getSelectedDevice( selectedDevice ) }
793 type={ 'padding' }
794 label={ __( 'Padding', 'generateblocks' ) }
795 attrTop={ 'iconPaddingTopTablet' }
796 attrRight={ 'iconPaddingRightTablet' }
797 attrBottom={ 'iconPaddingBottomTablet' }
798 attrLeft={ 'iconPaddingLeftTablet' }
799 attrUnit={ 'iconPaddingUnit' }
800 attrSyncUnits={ 'iconPaddingSyncUnits' }
801 defaults={ generateBlocksDefaults.button }
802 />
803 </Fragment>
804 }
805
806 <div className="components-gblocks-typography-control__header">
807 <div className="components-gblocks-typography-control__label components-base-control__label">
808 { __( 'Icon Size', 'generateblocks' ) }
809 </div>
810
811 <div className="components-gblocks-control__units">
812 <ButtonGroup className="components-gblocks-typography-control__units" aria-label={ __( 'Select Units', 'generateblocks' ) }>
813 { unitSizes.map( ( unit ) =>
814 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
815 <Tooltip text={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) } key={ unit.unitValue }>
816 <Button
817 key={ unit.unitValue }
818 className={ 'components-gblocks-typography-control__units--' + unit.name }
819 isSmall
820 isPrimary={ iconSizeUnit === unit.unitValue }
821 aria-pressed={ iconSizeUnit === unit.unitValue }
822 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
823 aria-label={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) }
824 onClick={ () => setAttributes( { iconSizeUnit: unit.unitValue } ) }
825 >
826 { unit.unitValue }
827 </Button>
828 </Tooltip>
829 ) }
830 </ButtonGroup>
831 </div>
832 </div>
833
834 <div className="components-base-control components-gblocks-typography-control__inputs">
835 <TextControl
836 type={ 'number' }
837 value={ iconSizeTablet || '' }
838 step={ 'em' === iconSizeUnit ? .1 : 1 }
839 placeholder="1"
840 onChange={ ( value ) => {
841 setAttributes( {
842 iconSizeTablet: value,
843 } );
844 } }
845 onBlur={ () => {
846 setAttributes( {
847 iconSizeTablet: parseFloat( iconSizeTablet ),
848 } );
849 } }
850 onClick={ ( e ) => {
851 // Make sure onBlur fires in Firefox.
852 e.currentTarget.focus();
853 } }
854 />
855
856 <Button
857 isSmall
858 isSecondary
859 className="components-gblocks-default-number"
860 onClick={ () => {
861 setAttributes( {
862 iconSizeTablet: generateBlocksDefaults.button.iconSizeTablet,
863 } );
864 } }
865 >
866 { __( 'Reset', 'generateblocks' ) }
867 </Button>
868 </div>
869 </Fragment>
870 }
871
872 { 'mobile' === getSelectedDevice( selectedDevice ) && !! icon && (
873 <Fragment>
874 { ! removeText &&
875 <Fragment>
876 <DimensionsControl { ...this.props }
877 device={ getSelectedDevice( selectedDevice ) }
878 type={ 'padding' }
879 label={ __( 'Padding', 'generateblocks' ) }
880 attrTop={ 'iconPaddingTopMobile' }
881 attrRight={ 'iconPaddingRightMobile' }
882 attrBottom={ 'iconPaddingBottomMobile' }
883 attrLeft={ 'iconPaddingLeftMobile' }
884 attrUnit={ 'iconPaddingUnit' }
885 attrSyncUnits={ 'iconPaddingSyncUnits' }
886 defaults={ generateBlocksDefaults.button }
887 />
888 </Fragment>
889 }
890
891 <div className="components-gblocks-typography-control__header">
892 <div className="components-gblocks-typography-control__label components-base-control__label">
893 { __( 'Icon Size', 'generateblocks' ) }
894 </div>
895
896 <div className="components-gblocks-control__units">
897 <ButtonGroup className="components-gblocks-typography-control__units" aria-label={ __( 'Select Units', 'generateblocks' ) }>
898 { unitSizes.map( ( unit ) =>
899 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
900 <Tooltip text={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) } key={ unit.unitValue }>
901 <Button
902 key={ unit.unitValue }
903 className={ 'components-gblocks-typography-control__units--' + unit.name }
904 isSmall
905 isPrimary={ iconSizeUnit === unit.unitValue }
906 aria-pressed={ iconSizeUnit === unit.unitValue }
907 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
908 aria-label={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) }
909 onClick={ () => setAttributes( { iconSizeUnit: unit.unitValue } ) }
910 >
911 { unit.unitValue }
912 </Button>
913 </Tooltip>
914 ) }
915 </ButtonGroup>
916 </div>
917 </div>
918
919 <div className="components-base-control components-gblocks-typography-control__inputs">
920 <TextControl
921 type={ 'number' }
922 value={ iconSizeMobile || '' }
923 step={ 'em' === iconSizeUnit ? .1 : 1 }
924 placeholder="1"
925 onChange={ ( value ) => {
926 setAttributes( {
927 iconSizeMobile: value,
928 } );
929 } }
930 onBlur={ () => {
931 setAttributes( {
932 iconSizeMobile: parseFloat( iconSizeMobile ),
933 } );
934 } }
935 onClick={ ( e ) => {
936 // Make sure onBlur fires in Firefox.
937 e.currentTarget.focus();
938 } }
939 />
940
941 <Button
942 isSmall
943 isSecondary
944 className="components-gblocks-default-number"
945 onClick={ () => {
946 setAttributes( {
947 iconSizeMobile: generateBlocksDefaults.button.iconSizeMobile,
948 } );
949 } }
950 >
951 { __( 'Reset', 'generateblocks' ) }
952 </Button>
953 </div>
954 </Fragment>
955 ) }
956
957 { applyFilters( 'generateblocks.editor.controls', '', 'buttonIcon', this.props, this.state ) }
958 </PanelArea>
959
960 <PanelArea { ...this.props }
961 title={ __( 'Advanced', 'generateblocks' ) }
962 initialOpen={ false }
963 icon={ getIcon( 'advanced' ) }
964 className={ 'gblocks-panel-label' }
965 id={ 'buttonAdvanced' }
966 state={ this.state }
967 showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || false }
968 >
969 <TextControl
970 label={ __( 'Element ID', 'generateblocks' ) }
971 value={ elementId }
972 onChange={ ( value ) => {
973 const newElementId = value.replace( ELEMENT_ID_REGEX, '-' );
974
975 setAttributes( {
976 elementId: newElementId,
977 } );
978 } }
979 />
980
981 <TextControl
982 label={ __( 'CSS Classes', 'generateblocks' ) }
983 value={ cssClasses }
984 onChange={ ( value ) => {
985 setAttributes( {
986 cssClasses: value,
987 } );
988 } }
989 />
990
991 <TextControl
992 label={ __( 'ARIA Label', 'generateblocks' ) }
993 help={ __( 'Helpful to people using screen readers.', 'generateblocks' ) }
994 value={ ariaLabel }
995 onChange={ ( value ) => {
996 setAttributes( {
997 ariaLabel: value,
998 } );
999 } }
1000 />
1001
1002 { applyFilters( 'generateblocks.editor.controls', '', 'buttonAdvanced', this.props, this.state ) }
1003 </PanelArea>
1004
1005 <PanelArea { ...this.props }
1006 title={ __( 'Documentation', 'generateblocks' ) }
1007 icon={ getIcon( 'documentation' ) }
1008 initialOpen={ false }
1009 className={ 'gblocks-panel-label' }
1010 id={ 'buttonDocumentation' }
1011 state={ this.state }
1012 >
1013 <p>{ __( 'Need help with this block?', 'generateblocks' ) }</p>
1014 <a href="https://docs.generateblocks.com/collection/buttons/" target="_blank" rel="noreferrer noopener">{ __( 'Visit our documentation', 'generateblocks' ) }</a>
1015
1016 { applyFilters( 'generateblocks.editor.controls', '', 'buttonDocumentation', this.props, this.state ) }
1017 </PanelArea>
1018 </InspectorControls>
1019
1020 <DesktopCSS { ...this.props } />
1021
1022 { fontFamily && googleFont &&
1023 <link
1024 rel="stylesheet"
1025 href={ 'https://fonts.googleapis.com/css?family=' + fontFamily.replace( / /g, '+' ) + googleFontsAttr }
1026 />
1027 }
1028
1029 <a
1030 { ...htmlAttributes }
1031 >
1032 { icon && 'left' === iconLocation &&
1033 <span
1034 className="gb-icon"
1035 dangerouslySetInnerHTML={ { __html: sanitizeSVG( icon ) } }
1036 />
1037 }
1038 { ! removeText &&
1039 <span className={ 'button-text' }>
1040 <RichText
1041 placeholder={ __( 'Add text…', 'generateblocks' ) }
1042 value={ text }
1043 onChange={ ( value ) => setAttributes( { text: value } ) }
1044 allowedFormats={ [ 'core/bold', 'core/italic', 'core/strikethrough' ] }
1045 isSelected={ isSelected }
1046 keepPlaceholderOnFocus
1047 />
1048 </span>
1049 }
1050 { icon && 'right' === iconLocation &&
1051 <span
1052 className="gb-icon"
1053 dangerouslySetInnerHTML={ { __html: sanitizeSVG( icon ) } }
1054 />
1055 }
1056 </a>
1057 { isSelected &&
1058 <URLInput
1059 url={ url }
1060 target={ target }
1061 relNoFollow={ relNoFollow }
1062 relSponsored={ relSponsored }
1063 onChange={ ( data ) => {
1064 setAttributes( data );
1065 } }
1066 autoFocus={ false } // eslint-disable-line jsx-a11y/no-autofocus
1067 className="gblocks-component-url-input-float"
1068 />
1069 }
1070 </Fragment>
1071 );
1072 }
1073 }
1074
1075 export default ( GenerateBlockButton );
1076