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