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 / container / edit.js
generateblocks / src / blocks / container Last commit date
css 6 years ago attributes.js 6 years ago block-controls.js 6 years ago block.js 6 years ago edit.js 6 years ago editor.scss 6 years ago save.js 6 years ago section-tag.js 6 years ago style.scss 6 years ago
edit.js
1605 lines
1 /**
2 * Block: Container
3 */
4
5 import Section from './section-tag';
6 import ColorPicker from '../../components/color-picker';
7 import getIcon from '../../utils/get-icon';
8 import getSelectedDevice from '../../utils/get-selected-device';
9 import classnames from 'classnames';
10 import DimensionsControl from '../../components/dimensions/';
11 import PanelArea from '../../components/panel-area/';
12 import TypographyControls from '../../components/typography';
13 import GradientControl from '../../components/gradient/';
14 import ResponsiveTabs from '../../components/responsive-tabs';
15 import DesktopCSS from './css/desktop.js';
16
17 const {
18 __,
19 _x,
20 sprintf,
21 } = wp.i18n;
22
23 const {
24 RangeControl,
25 Button,
26 ButtonGroup,
27 ResponsiveWrapper,
28 ToggleControl,
29 SelectControl,
30 TextControl,
31 Tooltip,
32 BaseControl,
33 Notice,
34 } = wp.components;
35
36 const {
37 Fragment,
38 Component,
39 } = wp.element;
40
41 const {
42 InspectorControls,
43 InnerBlocks,
44 MediaUpload,
45 AlignmentToolbar,
46 } = wp.blockEditor;
47
48 const {
49 applyFilters,
50 } = wp.hooks;
51
52 const ELEMENT_ID_REGEX = /[\s#]/g;
53 const gbContainerIds = [];
54
55 class GenerateBlockContainer extends Component {
56 constructor() {
57 super( ...arguments );
58
59 this.state = {
60 selectedDevice: 'desktop',
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 gbContainerIds.push( id );
73 } else if ( gbContainerIds.includes( this.props.attributes.uniqueId ) ) {
74 this.props.setAttributes( {
75 uniqueId: id,
76 } );
77
78 gbContainerIds.push( id );
79 } else {
80 gbContainerIds.push( this.props.attributes.uniqueId );
81 }
82
83 const thisBlock = document.getElementById( 'block-' + this.props.clientId );
84
85 if ( thisBlock && 'full' === this.props.attributes.align ) {
86 thisBlock.setAttribute( 'data-align', 'full' );
87 }
88 }
89
90 componentDidUpdate() {
91 const thisBlock = document.getElementById( 'block-' + this.props.clientId );
92
93 if ( thisBlock ) {
94 const alignValue = this.props.attributes.align;
95 let currentDataAlign = '';
96
97 if ( thisBlock.getAttribute( 'data-align' ) ) {
98 currentDataAlign = thisBlock.getAttribute( 'data-align' );
99 }
100
101 if ( alignValue !== currentDataAlign ) {
102 if ( ( '' === alignValue || undefined === alignValue ) && '' !== currentDataAlign ) {
103 thisBlock.removeAttribute( 'data-align' );
104 } else {
105 thisBlock.setAttribute( 'data-align', alignValue );
106 }
107 }
108 }
109 }
110
111 render() {
112 const {
113 attributes,
114 setAttributes,
115 hasChildBlocks,
116 clientId,
117 } = this.props;
118
119 const {
120 selectedDevice,
121 } = this.state;
122
123 const onSelectBgImage = ( media ) => {
124 let size = generateBlocksStyling.container.bgImageSize;
125
126 if ( 'undefined' === typeof media.sizes[ size ] ) {
127 size = 'full';
128 }
129
130 setAttributes( {
131 bgImage: {
132 id: media.id,
133 image: media.sizes[ size ],
134 },
135 } );
136 };
137
138 const onRemoveBgImage = () => {
139 setAttributes( {
140 bgImage: null,
141 } );
142 };
143
144 const {
145 uniqueId,
146 tagName,
147 elementId,
148 cssClasses,
149 isGrid,
150 width,
151 widthTablet,
152 widthMobile,
153 outerContainer,
154 innerContainer,
155 containerWidth,
156 minHeight,
157 minHeightUnit,
158 minHeightTablet,
159 minHeightUnitTablet,
160 minHeightMobile,
161 minHeightUnitMobile,
162 borderColor,
163 borderColorOpacity,
164 backgroundColor,
165 backgroundColorOpacity,
166 textColor,
167 linkColor,
168 linkColorHover,
169 bgImage,
170 bgOptions,
171 verticalAlignment,
172 verticalAlignmentTablet,
173 verticalAlignmentMobile,
174 zindex,
175 removeVerticalGap,
176 removeVerticalGapTablet,
177 removeVerticalGapMobile,
178 orderTablet,
179 orderMobile,
180 alignment,
181 alignmentTablet,
182 alignmentMobile,
183 fontFamily,
184 googleFont,
185 googleFontVariants,
186 fullWidthContent,
187 align,
188 } = attributes;
189
190 const minHeightUnits = [
191 {
192 name: _x( 'Pixel', 'A size unit for CSS markup' ),
193 unitValue: 'px',
194 },
195 {
196 name: _x( 'VH', 'A size unit for CSS markup' ),
197 unitValue: 'vh',
198 },
199 {
200 name: _x( 'VW', 'A size unit for CSS markup' ),
201 unitValue: 'vw',
202 },
203 ];
204
205 const tagNames = [
206 { label: 'div', value: 'div' },
207 { label: 'section', value: 'section' },
208 { label: 'header', value: 'header' },
209 { label: 'footer', value: 'footer' },
210 ];
211
212 const pageBuilderContainerOption = document.getElementById( '_generate-full-width-content' );
213 const changeEvent = new Event( 'change' ); // eslint-disable-line no-undef
214 const getRootId = wp.data.select( 'core/block-editor' ).getBlockHierarchyRootClientId( clientId );
215 const isRootContainer = getRootId === clientId;
216
217 const fullWidthContentOptions = () => {
218 return (
219 <Fragment>
220 { generateBlocksInfo.isGeneratePress && isRootContainer && pageBuilderContainerOption &&
221 <BaseControl
222 label={ __( 'If you want to build a full width page, use the option below to remove the page width, margin and padding.', 'generateblocks' ) }
223 className="gblocks-gpress-full-width"
224 >
225 <ToggleControl
226 label={ __( 'Make page full-width', 'generateblocks' ) }
227 checked={ fullWidthContent ? true : false }
228 onChange={ ( value ) => {
229 if ( value ) {
230 if ( 'select' === pageBuilderContainerOption.tagName.toLowerCase() ) {
231 pageBuilderContainerOption.value = 'true';
232 pageBuilderContainerOption.dispatchEvent( changeEvent );
233 } else {
234 pageBuilderContainerOption.checked = true;
235 pageBuilderContainerOption.setAttribute( 'value', 'true' );
236 pageBuilderContainerOption.dispatchEvent( changeEvent );
237 }
238
239 setAttributes( {
240 fullWidthContent: 'true',
241 align: '',
242 } );
243 } else {
244 if ( 'select' === pageBuilderContainerOption.tagName.toLowerCase() ) {
245 pageBuilderContainerOption.value = '';
246 pageBuilderContainerOption.dispatchEvent( changeEvent );
247 } else {
248 pageBuilderContainerOption.checked = false;
249 pageBuilderContainerOption.setAttribute( 'value', '' );
250 document.querySelector( 'input[name="_generate-full-width-content"]#default-content' ).checked = true;
251 pageBuilderContainerOption.dispatchEvent( changeEvent );
252 }
253
254 setAttributes( {
255 fullWidthContent: '',
256 } );
257 }
258 } }
259 />
260 </BaseControl>
261 }
262 </Fragment>
263 );
264 };
265
266 let googleFontsAttr = '';
267
268 if ( googleFontVariants ) {
269 googleFontsAttr = ':' + googleFontVariants;
270 }
271
272 let parentBlockId = false,
273 parentBlock = false,
274 hasGridContainer = false,
275 gridContainerId = '';
276
277 if ( typeof wp.data.select( 'core/block-editor' ).getBlockParents === 'function' ) {
278 parentBlockId = wp.data.select( 'core/block-editor' ).getBlockParents( clientId, true )[ 0 ];
279
280 if ( parentBlockId ) {
281 parentBlock = wp.data.select( 'core/block-editor' ).getBlocksByClientId( parentBlockId );
282
283 if ( parentBlock && 'generateblocks/grid' === parentBlock[ 0 ].name ) {
284 hasGridContainer = true;
285 gridContainerId = parentBlock[ 0 ].attributes.uniqueId;
286 }
287 }
288 }
289
290 return (
291 <Fragment>
292 <InspectorControls>
293 <ResponsiveTabs { ...this.props }
294 selectedDevice={ getSelectedDevice( selectedDevice ) }
295 onClick={ ( device ) => {
296 window.localStorage.setItem( 'generateblocksSelectedDevice', device );
297
298 this.setState( {
299 selectedDevice: device,
300 } );
301 } }
302 />
303
304 { ! isGrid && (
305 <PanelArea { ...this.props }
306 title={ __( 'Layout', 'generateblocks' ) }
307 initialOpen={ true }
308 icon={ getIcon( 'layout' ) }
309 className={ 'gblocks-panel-label' }
310 id={ 'containerLayout' }
311 state={ this.state }
312 showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || false }
313 >
314
315 <Fragment>
316 { hasGridContainer &&
317 <ToggleControl
318 label={ __( 'Grid Item', 'generateblocks' ) }
319 help={ __( 'This Container is inside a Grid Block but is not set as a grid item. Enable this option for optimal results.', 'generateblocks' ) }
320 checked={ !! isGrid }
321 onChange={ ( value ) => {
322 setAttributes( {
323 isGrid: value,
324 gridId: gridContainerId,
325 } );
326 } }
327 />
328 }
329
330 <SelectControl
331 label={ __( 'Container', 'generateblocks' ) }
332 value={ outerContainer }
333 options={ [
334 { label: __( 'Full width', 'generateblocks' ), value: 'full' },
335 { label: __( 'Contained width', 'generateblocks' ), value: 'contained' },
336 ] }
337 onChange={ ( value ) => {
338 setAttributes( {
339 outerContainer: value,
340 } );
341
342 if ( 'contained' === value && 'full' === align ) {
343 setAttributes( {
344 align: '',
345 } );
346 }
347 } }
348 />
349
350 { 'full' === outerContainer &&
351 <SelectControl
352 label={ __( 'Inner Container', 'generateblocks' ) }
353 value={ innerContainer }
354 options={ [
355 { label: __( 'Full width', 'generateblocks' ), value: 'full' },
356 { label: __( 'Contained width', 'generateblocks' ), value: 'contained' },
357 ] }
358 onChange={ ( value ) => {
359 setAttributes( {
360 innerContainer: value,
361 } );
362 } }
363 />
364 }
365
366 { ( 'contained' === outerContainer || 'contained' === innerContainer ) &&
367 <Fragment>
368 <div className="components-gblocks-control__header">
369 <div className="components-gblocks-control__label">
370 { __( 'Contained Width', 'generateblocks' ) }
371 </div>
372
373 <div className="components-gblocks-control__units">
374 <Tooltip text={ __( 'Pixel Units', 'generateblocks' ) } key={ 'container-width-unit' }>
375 <Button
376 key={ 'container-width-unit' }
377 isSmall
378 isPrimary={ true }
379 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
380 aria-label={ __( 'Pixel Units', 'generateblocks' ) }
381 >
382 px
383 </Button>
384 </Tooltip>
385 </div>
386 </div>
387
388 <TextControl
389 type={ 'number' }
390 className="gblocks-container-width"
391 value={ parseFloat( containerWidth ) || '' }
392 placeholder={ generateBlocksDefaults.container.containerWidth }
393 onChange={ ( value ) => {
394 setAttributes( {
395 containerWidth: '' !== value ? parseFloat( value ) : undefined,
396 } );
397 } }
398 />
399 </Fragment>
400 }
401
402 { fullWidthContentOptions() }
403 </Fragment>
404
405 { applyFilters( 'generateblocks.editor.controls', '', 'containerLayout', this.props, this.state ) }
406 </PanelArea>
407 ) }
408
409 { isGrid && (
410 <PanelArea { ...this.props }
411 title={ __( 'Layout', 'generateblocks' ) }
412 initialOpen={ true }
413 icon={ getIcon( 'layout' ) }
414 className={ 'gblocks-panel-label' }
415 id={ 'containerGridLayout' }
416 state={ this.state }
417 >
418 { ! hasGridContainer &&
419 <ToggleControl
420 label={ __( 'Grid Item', 'generateblocks' ) }
421 help={ __( 'This container is set as a grid item but is not inside a grid block. Deactivate this option for optimal results.', 'generateblocks' ) }
422 checked={ !! isGrid }
423 onChange={ ( value ) => {
424 setAttributes( {
425 isGrid: value,
426 gridId: '',
427 } );
428 } }
429 />
430 }
431
432 { 'desktop' === getSelectedDevice( selectedDevice ) && (
433 <Fragment>
434 <div className="components-gblocks-control__header">
435 <div className="components-gblocks-control__label">
436 { __( 'Container Width', 'generateblocks' ) }
437 </div>
438
439 <div className="components-gblocks-control__units">
440 <Tooltip text={ __( 'Percentage Units', 'generateblocks' ) } key={ 'percentage-unit' }>
441 <Button
442 key={ 'percentage-unit' }
443 isSmall
444 isPrimary={ true }
445 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
446 aria-label={ __( 'Percentage Units', 'generateblocks' ) }
447 >
448 %
449 </Button>
450 </Tooltip>
451 </div>
452 </div>
453
454 <ButtonGroup className={ 'widthButtons' }>
455 <Button isLarge isPrimary={ width === 25 } onClick={ () => setAttributes( { width: 25 } ) }>25</Button>
456 <Button isLarge isPrimary={ width === 33.33 } onClick={ () => setAttributes( { width: 33.33 } ) }>33</Button>
457 <Button isLarge isPrimary={ width === 50 } onClick={ () => setAttributes( { width: 50 } ) }>50</Button>
458 <Button isLarge isPrimary={ width === 66.66 } onClick={ () => setAttributes( { width: 66.66 } ) }>66</Button>
459 <Button isLarge isPrimary={ width === 75 } onClick={ () => setAttributes( { width: 75 } ) }>75</Button>
460 <Button isLarge isPrimary={ width === 100 } onClick={ () => setAttributes( { width: 100 } ) }>100</Button>
461 </ButtonGroup>
462
463 <RangeControl
464 className={ 'gblocks-column-width-control' }
465 value={ width || '' }
466 onChange={ ( value ) => {
467 setAttributes( {
468 width: value,
469 } );
470 } }
471 min={ 0 }
472 max={ 100 }
473 step={ 0.01 }
474 initialPosition={ generateBlocksDefaults.container.width }
475 />
476
477 <SelectControl
478 label={ __( 'Vertical Alignment', 'generateblocks' ) }
479 help={ __( 'Align grid item content. Does not apply if vertical alignment is set in the grid.', 'generateblocks' ) }
480 value={ verticalAlignment }
481 options={ [
482 { label: __( 'Default', 'generateblocks' ), value: '' },
483 { label: __( 'Top', 'generateblocks' ), value: 'flex-start' },
484 { label: __( 'Center', 'generateblocks' ), value: 'center' },
485 { label: __( 'Bottom', 'generateblocks' ), value: 'flex-end' },
486 ] }
487 onChange={ ( value ) => {
488 setAttributes( {
489 verticalAlignment: value,
490 } );
491 } }
492 />
493
494 <ToggleControl
495 label={ __( 'Remove Vertical Gap', 'generateblocks' ) }
496 checked={ !! removeVerticalGap }
497 onChange={ ( value ) => {
498 setAttributes( {
499 removeVerticalGap: value,
500 } );
501 } }
502 />
503 </Fragment>
504 ) }
505
506 { 'tablet' === getSelectedDevice( selectedDevice ) && (
507 <Fragment>
508 <div className="components-gblocks-control__header">
509 <div className="components-gblocks-control__label">
510 { __( 'Container Width', 'generateblocks' ) }
511 </div>
512
513 <div className="components-gblocks-control__units">
514 <Tooltip text={ __( 'Percentage Units', 'generateblocks' ) } key={ 'percentage-unit' }>
515 <Button
516 key={ 'percentage-unit' }
517 isSmall
518 isPrimary={ true }
519 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
520 aria-label={ __( 'Percentage Units', 'generateblocks' ) }
521 >
522 %
523 </Button>
524 </Tooltip>
525 </div>
526 </div>
527
528 <ButtonGroup className={ 'widthButtons' }>
529 <Button isLarge isPrimary={ widthTablet === 25 } onClick={ () => setAttributes( { widthTablet: 25 } ) }>25</Button>
530 <Button isLarge isPrimary={ widthTablet === 33.33 } onClick={ () => setAttributes( { widthTablet: 33.33 } ) }>33</Button>
531 <Button isLarge isPrimary={ widthTablet === 50 } onClick={ () => setAttributes( { widthTablet: 50 } ) }>50</Button>
532 <Button isLarge isPrimary={ widthTablet === 66.66 } onClick={ () => setAttributes( { widthTablet: 66.66 } ) }>66</Button>
533 <Button isLarge isPrimary={ widthTablet === 75 } onClick={ () => setAttributes( { widthTablet: 75 } ) }>75</Button>
534 <Button isLarge isPrimary={ widthTablet === 100 } onClick={ () => setAttributes( { widthTablet: 100 } ) }>100</Button>
535 </ButtonGroup>
536
537 <RangeControl
538 className={ 'gblocks-column-width-control' }
539 value={ widthTablet || '' }
540 onChange={ ( value ) => {
541 setAttributes( {
542 widthTablet: value,
543 } );
544 } }
545 min={ 0 }
546 max={ 100 }
547 step={ 0.01 }
548 initialPosition={ generateBlocksDefaults.container.widthTablet }
549 />
550
551 <SelectControl
552 label={ __( 'Vertical Alignment', 'generateblocks' ) }
553 help={ __( 'Align grid item content. Does not apply if vertical alignment is set in the grid.', 'generateblocks' ) }
554 value={ verticalAlignmentTablet }
555 options={ [
556 { label: __( 'Inherit', 'generateblocks' ), value: 'inherit' },
557 { label: __( 'Default', 'generateblocks' ), value: '' },
558 { label: __( 'Top', 'generateblocks' ), value: 'flex-start' },
559 { label: __( 'Center', 'generateblocks' ), value: 'center' },
560 { label: __( 'Bottom', 'generateblocks' ), value: 'flex-end' },
561 ] }
562 onChange={ ( value ) => {
563 setAttributes( {
564 verticalAlignmentTablet: value,
565 } );
566 } }
567 />
568
569 <ToggleControl
570 label={ __( 'Remove Vertical Gap', 'generateblocks' ) }
571 checked={ !! removeVerticalGapTablet }
572 onChange={ ( value ) => {
573 setAttributes( {
574 removeVerticalGapTablet: value,
575 } );
576 } }
577 />
578
579 <TextControl
580 type={ 'number' }
581 label={ __( 'Order', 'generateblocks' ) }
582 value={ orderTablet || 0 === orderTablet ? orderTablet : '' }
583 onChange={ ( value ) => {
584 setAttributes( {
585 orderTablet: parseFloat( value ),
586 } );
587 } }
588 />
589 </Fragment>
590 ) }
591
592 { 'mobile' === getSelectedDevice( selectedDevice ) && (
593 <Fragment>
594 <div className="components-gblocks-control__header">
595 <div className="components-gblocks-control__label">
596 { __( 'Container Width', 'generateblocks' ) }
597 </div>
598
599 <div className="components-gblocks-control__units">
600 <Tooltip text={ __( 'Percentage Units', 'generateblocks' ) } key={ 'percentage-unit' }>
601 <Button
602 key={ 'percentage-unit' }
603 isSmall
604 isPrimary={ true }
605 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
606 aria-label={ __( 'Percentage Units', 'generateblocks' ) }
607 >
608 %
609 </Button>
610 </Tooltip>
611 </div>
612 </div>
613
614 <ButtonGroup className={ 'widthButtons' }>
615 <Button isLarge isPrimary={ widthMobile === 25 } onClick={ () => setAttributes( { widthMobile: 25 } ) }>25</Button>
616 <Button isLarge isPrimary={ widthMobile === 33.33 } onClick={ () => setAttributes( { widthMobile: 33.33 } ) }>33</Button>
617 <Button isLarge isPrimary={ widthMobile === 50 } onClick={ () => setAttributes( { widthMobile: 50 } ) }>50</Button>
618 <Button isLarge isPrimary={ widthMobile === 66.66 } onClick={ () => setAttributes( { widthMobile: 66.66 } ) }>66</Button>
619 <Button isLarge isPrimary={ widthMobile === 75 } onClick={ () => setAttributes( { widthMobile: 75 } ) }>75</Button>
620 <Button isLarge isPrimary={ widthMobile === 100 } onClick={ () => setAttributes( { widthMobile: 100 } ) }>100</Button>
621 </ButtonGroup>
622
623 <RangeControl
624 className={ 'gblocks-column-width-control' }
625 value={ widthMobile || '' }
626 onChange={ ( value ) => {
627 setAttributes( {
628 widthMobile: value,
629 } );
630 } }
631 min={ 0 }
632 max={ 100 }
633 step={ 0.01 }
634 initialPosition={ generateBlocksDefaults.container.widthMobile }
635 />
636
637 <SelectControl
638 label={ __( 'Vertical Alignment', 'generateblocks' ) }
639 help={ __( 'Align grid item content. Does not apply if vertical alignment is set in the grid.', 'generateblocks' ) }
640 value={ verticalAlignmentMobile }
641 options={ [
642 { label: __( 'Inherit', 'generateblocks' ), value: 'inherit' },
643 { label: __( 'Default', 'generateblocks' ), value: '' },
644 { label: __( 'Top', 'generateblocks' ), value: 'flex-start' },
645 { label: __( 'Center', 'generateblocks' ), value: 'center' },
646 { label: __( 'Bottom', 'generateblocks' ), value: 'flex-end' },
647 ] }
648 onChange={ ( value ) => {
649 setAttributes( {
650 verticalAlignmentMobile: value,
651 } );
652 } }
653 />
654
655 <ToggleControl
656 label={ __( 'Remove Vertical Gap', 'generateblocks' ) }
657 checked={ !! removeVerticalGapMobile }
658 onChange={ ( value ) => {
659 setAttributes( {
660 removeVerticalGapMobile: value,
661 } );
662 } }
663 />
664
665 <TextControl
666 type={ 'number' }
667 label={ __( 'Order', 'generateblocks' ) }
668 value={ orderMobile || 0 === orderMobile ? orderMobile : '' }
669 onChange={ ( value ) => {
670 setAttributes( {
671 orderMobile: parseFloat( value ),
672 } );
673 } }
674 />
675 </Fragment>
676 ) }
677
678 { applyFilters( 'generateblocks.editor.controls', '', 'containerGridLayout', this.props, this.state ) }
679 </PanelArea>
680 ) }
681
682 <PanelArea { ...this.props }
683 title={ __( 'Typography', 'generateblocks' ) }
684 initialOpen={ false }
685 icon={ getIcon( 'typography' ) }
686 className={ 'gblocks-panel-label' }
687 id={ 'containerTypography' }
688 state={ this.state }
689 >
690
691 { 'desktop' === getSelectedDevice( selectedDevice ) && (
692 <Fragment>
693 <BaseControl
694 className="gblocks-container-text-alignment"
695 label={ __( 'Text Alignment', 'generateblocks' ) }
696 >
697 <AlignmentToolbar
698 isCollapsed={ false }
699 value={ alignment }
700 onChange={ ( value ) => {
701 setAttributes( { alignment: value } );
702 } }
703 />
704 </BaseControl>
705
706 <TypographyControls { ...this.props }
707 showFontFamily={ true }
708 showFontWeight={ true }
709 showTextTransform={ true }
710 showFontSize={ true }
711 defaultFontSize={ generateBlocksDefaults.container.fontSize }
712 defaultFontSizeUnit={ generateBlocksDefaults.container.fontSizeUnit }
713 defaultLineHeight={ generateBlocksDefaults.container.lineHeight }
714 defaultLineHeightUnit={ generateBlocksDefaults.container.lineHeightUnit }
715 defaultLetterSpacing={ generateBlocksDefaults.container.letterSpacing }
716 />
717 </Fragment>
718 ) }
719
720 { 'tablet' === getSelectedDevice( selectedDevice ) && (
721 <Fragment>
722 <BaseControl label={ __( 'Text Alignment', 'generateblocks' ) }>
723 <AlignmentToolbar
724 isCollapsed={ false }
725 value={ alignmentTablet }
726 onChange={ ( value ) => {
727 setAttributes( { alignmentTablet: value } );
728 } }
729 />
730 </BaseControl>
731
732 <TypographyControls { ...this.props }
733 showFontSize={ true }
734 defaultFontSize={ generateBlocksDefaults.container.fontSizeTablet }
735 defaultFontSizeUnit={ generateBlocksDefaults.container.fontSizeUnit }
736 defaultLineHeight={ generateBlocksDefaults.container.lineHeightTablet }
737 defaultLineHeightUnit={ generateBlocksDefaults.container.lineHeightUnit }
738 defaultLetterSpacing={ generateBlocksDefaults.container.letterSpacingTablet }
739 />
740 </Fragment>
741 ) }
742
743 { 'mobile' === getSelectedDevice( selectedDevice ) && (
744 <Fragment>
745 <BaseControl label={ __( 'Text Alignment', 'generateblocks' ) }>
746 <AlignmentToolbar
747 isCollapsed={ false }
748 value={ alignmentMobile }
749 onChange={ ( value ) => {
750 setAttributes( { alignmentMobile: value } );
751 } }
752 />
753 </BaseControl>
754
755 <TypographyControls { ...this.props }
756 showFontSize={ true }
757 defaultFontSize={ generateBlocksDefaults.container.fontSizeMobile }
758 defaultFontSizeUnit={ generateBlocksDefaults.container.fontSizeUnit }
759 defaultLineHeight={ generateBlocksDefaults.container.lineHeightMobile }
760 defaultLineHeightUnit={ generateBlocksDefaults.container.lineHeightUnit }
761 defaultLetterSpacing={ generateBlocksDefaults.container.letterSpacingMobile }
762 />
763 </Fragment>
764 ) }
765
766 { applyFilters( 'generateblocks.editor.controls', '', 'containerTypography', this.props, this.state ) }
767 </PanelArea>
768
769 <PanelArea { ...this.props }
770 title={ __( 'Spacing', 'generateblocks' ) }
771 initialOpen={ false }
772 icon={ getIcon( 'spacing' ) }
773 className={ 'gblocks-panel-label' }
774 id={ 'containerSpacing' }
775 state={ this.state }
776 >
777
778 { 'desktop' === getSelectedDevice( selectedDevice ) && (
779 <Fragment>
780 <div className="components-gblocks-dimensions-control__header">
781 <div className="components-gblocks-dimensions-control__label">
782 { __( 'Minimum Height', 'generateblocks' ) }
783 </div>
784
785 <div className="components-gblocks-control__units">
786 <ButtonGroup className="components-gblocks-dimensions-control__units" aria-label={ __( 'Select Units', 'generateblocks' ) }>
787 { minHeightUnits.map( ( unit ) =>
788 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
789 <Tooltip text={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) } key={ unit.unitValue }>
790 <Button
791 key={ unit.unitValue }
792 className={ 'components-gblocks-dimensions-control__units--' + unit.name }
793 isSmall
794 isPrimary={ minHeightUnit === unit.unitValue }
795 aria-pressed={ minHeightUnit === unit.unitValue }
796 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
797 aria-label={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) }
798 onClick={ () => setAttributes( { minHeightUnit: unit.unitValue } ) }
799 >
800 { unit.unitValue }
801 </Button>
802 </Tooltip>
803 ) }
804 </ButtonGroup>
805 </div>
806 </div>
807
808 <TextControl
809 type={ 'number' }
810 value={ minHeight ? minHeight : '' }
811 onChange={ ( value ) => {
812 setAttributes( {
813 minHeight: parseFloat( value ),
814 } );
815 } }
816 />
817
818 { !! minHeight && ! isGrid &&
819 <SelectControl
820 label={ __( 'Vertical Alignment', 'generateblocks' ) }
821 value={ verticalAlignment }
822 options={ [
823 { label: __( 'Default', 'generateblocks' ), value: '' },
824 { label: __( 'Top', 'generateblocks' ), value: 'flex-start' },
825 { label: __( 'Center', 'generateblocks' ), value: 'center' },
826 { label: __( 'Bottom', 'generateblocks' ), value: 'flex-end' },
827 ] }
828 onChange={ ( value ) => {
829 setAttributes( {
830 verticalAlignment: value,
831 } );
832 } }
833 />
834 }
835
836 <DimensionsControl { ...this.props }
837 device={ getSelectedDevice( selectedDevice ) }
838 type={ 'padding' }
839 label={ __( 'Padding', 'generateblocks' ) }
840 attrTop={ 'paddingTop' }
841 attrRight={ 'paddingRight' }
842 attrBottom={ 'paddingBottom' }
843 attrLeft={ 'paddingLeft' }
844 attrUnit={ 'paddingUnit' }
845 attrSyncUnits={ 'paddingSyncUnits' }
846 defaults={ generateBlocksDefaults.container }
847 />
848
849 <DimensionsControl { ...this.props }
850 device={ getSelectedDevice( selectedDevice ) }
851 type={ 'margin' }
852 label={ __( 'Margin', 'generateblocks' ) }
853 attrTop={ 'marginTop' }
854 attrRight={ 'marginRight' }
855 attrBottom={ 'marginBottom' }
856 attrLeft={ 'marginLeft' }
857 attrUnit={ 'marginUnit' }
858 attrSyncUnits={ 'marginSyncUnits' }
859 defaults={ generateBlocksDefaults.container }
860 />
861
862 <DimensionsControl { ...this.props }
863 device={ getSelectedDevice( selectedDevice ) }
864 type={ 'padding' }
865 label={ __( 'Border Size', 'generateblocks' ) }
866 attrTop={ 'borderSizeTop' }
867 attrRight={ 'borderSizeRight' }
868 attrBottom={ 'borderSizeBottom' }
869 attrLeft={ 'borderSizeLeft' }
870 attrSyncUnits={ 'borderSizeSyncUnits' }
871 displayUnit={ 'px' }
872 defaults={ generateBlocksDefaults.container }
873 />
874
875 <DimensionsControl { ...this.props }
876 device={ getSelectedDevice( selectedDevice ) }
877 type={ 'padding' }
878 label={ __( 'Border Radius', 'generateblocks' ) }
879 attrTop={ 'borderRadiusTopLeft' }
880 attrRight={ 'borderRadiusTopRight' }
881 attrBottom={ 'borderRadiusBottomRight' }
882 attrLeft={ 'borderRadiusBottomLeft' }
883 attrUnit={ 'borderRadiusUnit' }
884 attrSyncUnits={ 'borderRadiusSyncUnits' }
885 labelTop={ __( 'T-Left', 'generateblocks' ) }
886 labelRight={ __( 'T-Right', 'generateblocks' ) }
887 labelBottom={ __( 'B-Right', 'generateblocks' ) }
888 labelLeft={ __( 'B-Left', 'generateblocks' ) }
889 defaults={ generateBlocksDefaults.container }
890 />
891 </Fragment>
892 ) }
893
894 { 'tablet' === getSelectedDevice( selectedDevice ) && (
895 <Fragment>
896 <div className="components-gblocks-dimensions-control__header">
897 <div className="components-gblocks-dimensions-control__label">
898 { __( 'Minimum Height', 'generateblocks' ) }
899 </div>
900
901 <div className="components-gblocks-control__units">
902 <ButtonGroup className="components-gblocks-dimensions-control__units" aria-label={ __( 'Select Units', 'generateblocks' ) }>
903 { minHeightUnits.map( ( unit ) =>
904 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
905 <Tooltip text={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) } key={ unit.unitValue }>
906 <Button
907 key={ unit.unitValue }
908 className={ 'components-gblocks-dimensions-control__units--' + unit.name }
909 isSmall
910 isPrimary={ minHeightUnitTablet === unit.unitValue }
911 aria-pressed={ minHeightUnitTablet === unit.unitValue }
912 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
913 aria-label={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) }
914 onClick={ () => setAttributes( { minHeightUnitTablet: unit.unitValue } ) }
915 >
916 { unit.unitValue }
917 </Button>
918 </Tooltip>
919 ) }
920 </ButtonGroup>
921 </div>
922 </div>
923
924 <TextControl
925 type={ 'number' }
926 value={ minHeightTablet ? minHeightTablet : '' }
927 onChange={ ( value ) => {
928 setAttributes( {
929 minHeightTablet: parseFloat( value ),
930 } );
931 } }
932 />
933
934 { ( !! minHeight || !! minHeightTablet ) && ! isGrid &&
935 <SelectControl
936 label={ __( 'Vertical Alignment', 'generateblocks' ) }
937 value={ verticalAlignmentTablet }
938 options={ [
939 { label: __( 'Inherit', 'generateblocks' ), value: 'inherit' },
940 { label: __( 'Default', 'generateblocks' ), value: '' },
941 { label: __( 'Top', 'generateblocks' ), value: 'flex-start' },
942 { label: __( 'Center', 'generateblocks' ), value: 'center' },
943 { label: __( 'Bottom', 'generateblocks' ), value: 'flex-end' },
944 ] }
945 onChange={ ( value ) => {
946 setAttributes( {
947 verticalAlignmentTablet: value,
948 } );
949 } }
950 />
951 }
952
953 <DimensionsControl { ...this.props }
954 device={ getSelectedDevice( selectedDevice ) }
955 type={ 'padding' }
956 label={ __( 'Padding', 'generateblocks' ) }
957 attrTop={ 'paddingTopTablet' }
958 attrRight={ 'paddingRightTablet' }
959 attrBottom={ 'paddingBottomTablet' }
960 attrLeft={ 'paddingLeftTablet' }
961 attrUnit={ 'paddingUnit' }
962 attrSyncUnits={ 'paddingSyncUnits' }
963 defaults={ generateBlocksDefaults.container }
964 />
965
966 <DimensionsControl { ...this.props }
967 device={ getSelectedDevice( selectedDevice ) }
968 type={ 'margin' }
969 label={ __( 'Margin', 'generateblocks' ) }
970 attrTop={ 'marginTopTablet' }
971 attrRight={ 'marginRightTablet' }
972 attrBottom={ 'marginBottomTablet' }
973 attrLeft={ 'marginLeftTablet' }
974 attrUnit={ 'marginUnit' }
975 attrSyncUnits={ 'marginSyncUnits' }
976 defaults={ generateBlocksDefaults.container }
977 />
978
979 <DimensionsControl { ...this.props }
980 device={ getSelectedDevice( selectedDevice ) }
981 type={ 'padding' }
982 label={ __( 'Border Size', 'generateblocks' ) }
983 attrTop={ 'borderSizeTopTablet' }
984 attrRight={ 'borderSizeRightTablet' }
985 attrBottom={ 'borderSizeBottomTablet' }
986 attrLeft={ 'borderSizeLeftTablet' }
987 attrSyncUnits={ 'borderSizeSyncUnits' }
988 displayUnit={ 'px' }
989 defaults={ generateBlocksDefaults.container }
990 />
991
992 <DimensionsControl { ...this.props }
993 device={ getSelectedDevice( selectedDevice ) }
994 type={ 'padding' }
995 label={ __( 'Border Radius', 'generateblocks' ) }
996 attrTop={ 'borderRadiusTopLeftTablet' }
997 attrRight={ 'borderRadiusTopRightTablet' }
998 attrBottom={ 'borderRadiusBottomRightTablet' }
999 attrLeft={ 'borderRadiusBottomLeftTablet' }
1000 attrUnit={ 'borderRadiusUnit' }
1001 attrSyncUnits={ 'borderRadiusSyncUnits' }
1002 labelTop={ __( 'T-Left', 'generateblocks' ) }
1003 labelRight={ __( 'T-Right', 'generateblocks' ) }
1004 labelBottom={ __( 'B-Right', 'generateblocks' ) }
1005 labelLeft={ __( 'B-Left', 'generateblocks' ) }
1006 defaults={ generateBlocksDefaults.container }
1007 />
1008 </Fragment>
1009 ) }
1010
1011 { 'mobile' === getSelectedDevice( selectedDevice ) && (
1012 <Fragment>
1013 <div className="components-gblocks-dimensions-control__header">
1014 <div className="components-gblocks-dimensions-control__label">
1015 { __( 'Minimum Height', 'generateblocks' ) }
1016 </div>
1017
1018 <div className="components-gblocks-control__units">
1019 <ButtonGroup className="components-gblocks-dimensions-control__units" aria-label={ __( 'Select Units', 'generateblocks' ) }>
1020 { minHeightUnits.map( ( unit ) =>
1021 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
1022 <Tooltip text={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) } key={ unit.unitValue }>
1023 <Button
1024 key={ unit.unitValue }
1025 className={ 'components-gblocks-dimensions-control__units--' + unit.name }
1026 isSmall
1027 isPrimary={ minHeightUnitMobile === unit.unitValue }
1028 aria-pressed={ minHeightUnitMobile === unit.unitValue }
1029 /* translators: %s: values associated with CSS syntax, 'Pixel', 'Em', 'Percentage' */
1030 aria-label={ sprintf( __( '%s Units', 'generateblocks' ), unit.name ) }
1031 onClick={ () => setAttributes( { minHeightUnitMobile: unit.unitValue } ) }
1032 >
1033 { unit.unitValue }
1034 </Button>
1035 </Tooltip>
1036 ) }
1037 </ButtonGroup>
1038 </div>
1039 </div>
1040
1041 <TextControl
1042 type={ 'number' }
1043 value={ minHeightMobile ? minHeightMobile : '' }
1044 onChange={ ( value ) => {
1045 setAttributes( {
1046 minHeightMobile: parseFloat( value ),
1047 } );
1048 } }
1049 />
1050
1051 { ( !! minHeight || !! minHeightTablet || !! minHeightMobile ) && ! isGrid &&
1052 <SelectControl
1053 label={ __( 'Vertical Alignment', 'generateblocks' ) }
1054 value={ verticalAlignmentMobile }
1055 options={ [
1056 { label: __( 'Inherit', 'generateblocks' ), value: 'inherit' },
1057 { label: __( 'Default', 'generateblocks' ), value: '' },
1058 { label: __( 'Top', 'generateblocks' ), value: 'flex-start' },
1059 { label: __( 'Center', 'generateblocks' ), value: 'center' },
1060 { label: __( 'Bottom', 'generateblocks' ), value: 'flex-end' },
1061 ] }
1062 onChange={ ( value ) => {
1063 setAttributes( {
1064 verticalAlignmentMobile: value,
1065 } );
1066 } }
1067 />
1068 }
1069
1070 <DimensionsControl { ...this.props }
1071 device={ getSelectedDevice( selectedDevice ) }
1072 type={ 'padding' }
1073 label={ __( 'Padding', 'generateblocks' ) }
1074 attrTop={ 'paddingTopMobile' }
1075 attrRight={ 'paddingRightMobile' }
1076 attrBottom={ 'paddingBottomMobile' }
1077 attrLeft={ 'paddingLeftMobile' }
1078 attrUnit={ 'paddingUnit' }
1079 attrSyncUnits={ 'paddingSyncUnits' }
1080 defaults={ generateBlocksDefaults.container }
1081 />
1082
1083 <DimensionsControl { ...this.props }
1084 device={ getSelectedDevice( selectedDevice ) }
1085 type={ 'margin' }
1086 label={ __( 'Margin', 'generateblocks' ) }
1087 attrTop={ 'marginTopMobile' }
1088 attrRight={ 'marginRightMobile' }
1089 attrBottom={ 'marginBottomMobile' }
1090 attrLeft={ 'marginLeftMobile' }
1091 attrUnit={ 'marginUnit' }
1092 attrSyncUnits={ 'marginSyncUnits' }
1093 defaults={ generateBlocksDefaults.container }
1094 />
1095
1096 <DimensionsControl { ...this.props }
1097 device={ getSelectedDevice( selectedDevice ) }
1098 type={ 'padding' }
1099 label={ __( 'Border Size', 'generateblocks' ) }
1100 attrTop={ 'borderSizeTopMobile' }
1101 attrRight={ 'borderSizeRightMobile' }
1102 attrBottom={ 'borderSizeBottomMobile' }
1103 attrLeft={ 'borderSizeLeftMobile' }
1104 attrSyncUnits={ 'borderSizeSyncUnits' }
1105 displayUnit={ 'px' }
1106 defaults={ generateBlocksDefaults.container }
1107 />
1108
1109 <DimensionsControl { ...this.props }
1110 device={ getSelectedDevice( selectedDevice ) }
1111 type={ 'padding' }
1112 label={ __( 'Border Radius', 'generateblocks' ) }
1113 attrTop={ 'borderRadiusTopLeftMobile' }
1114 attrRight={ 'borderRadiusTopRightMobile' }
1115 attrBottom={ 'borderRadiusBottomRightMobile' }
1116 attrLeft={ 'borderRadiusBottomLeftMobile' }
1117 attrUnit={ 'borderRadiusUnit' }
1118 attrSyncUnits={ 'borderRadiusSyncUnits' }
1119 labelTop={ __( 'T-Left', 'generateblocks' ) }
1120 labelRight={ __( 'T-Right', 'generateblocks' ) }
1121 labelBottom={ __( 'B-Right', 'generateblocks' ) }
1122 labelLeft={ __( 'B-Left', 'generateblocks' ) }
1123 defaults={ generateBlocksDefaults.container }
1124 />
1125 </Fragment>
1126 ) }
1127
1128 { applyFilters( 'generateblocks.editor.controls', '', 'containerSpacing', this.props, this.state ) }
1129 </PanelArea>
1130
1131 <PanelArea { ...this.props }
1132 title={ __( 'Colors', 'generateblocks' ) }
1133 initialOpen={ false }
1134 icon={ getIcon( 'colors' ) }
1135 className={ 'gblocks-panel-label' }
1136 id={ 'containerColors' }
1137 state={ this.state }
1138 showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || false }
1139 >
1140 <Fragment>
1141 <ColorPicker
1142 label={ __( 'Background Color', 'generateblocks' ) }
1143 value={ backgroundColor }
1144 alpha={ true }
1145 valueOpacity={ backgroundColorOpacity }
1146 attrOpacity={ 'backgroundColorOpacity' }
1147 onChange={ ( nextBackgroundColor ) =>
1148 setAttributes( {
1149 backgroundColor: nextBackgroundColor,
1150 } )
1151 }
1152 onOpacityChange={ ( value ) =>
1153 setAttributes( {
1154 backgroundColorOpacity: value,
1155 } )
1156 }
1157 />
1158
1159 <ColorPicker
1160 label={ __( 'Text Color', 'generateblocks' ) }
1161 value={ textColor }
1162 alpha={ false }
1163 onChange={ ( nextTextColor ) =>
1164 setAttributes( {
1165 textColor: nextTextColor,
1166 } )
1167 }
1168 />
1169
1170 <ColorPicker
1171 label={ __( 'Link Color', 'generateblocks' ) }
1172 value={ linkColor }
1173 alpha={ false }
1174 onChange={ ( nextLinkColor ) =>
1175 setAttributes( {
1176 linkColor: nextLinkColor,
1177 } )
1178 }
1179 />
1180
1181 <ColorPicker
1182 label={ __( 'Link Color Hover', 'generateblocks' ) }
1183 value={ linkColorHover }
1184 alpha={ false }
1185 onChange={ ( nextLinkColorHover ) =>
1186 setAttributes( {
1187 linkColorHover: nextLinkColorHover,
1188 } )
1189 }
1190 />
1191
1192 <ColorPicker
1193 label={ __( 'Border Color', 'generateblocks' ) }
1194 value={ borderColor }
1195 alpha={ true }
1196 valueOpacity={ borderColorOpacity }
1197 attrOpacity={ 'borderColorOpacity' }
1198 onChange={ ( value ) =>
1199 setAttributes( {
1200 borderColor: value,
1201 } )
1202 }
1203 onOpacityChange={ ( value ) =>
1204 setAttributes( {
1205 borderColorOpacity: value,
1206 } )
1207 }
1208 />
1209 </Fragment>
1210
1211 { applyFilters( 'generateblocks.editor.controls', '', 'containerColors', this.props, this.state ) }
1212 </PanelArea>
1213
1214 <PanelArea { ...this.props }
1215 title={ __( 'Background Gradient', 'generateblocks' ) }
1216 initialOpen={ false }
1217 icon={ getIcon( 'gradients' ) }
1218 className={ 'gblocks-panel-label' }
1219 id={ 'containerBackgroundGradient' }
1220 state={ this.state }
1221 showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || false }
1222 >
1223 <GradientControl { ...this.props }
1224 attrGradient={ 'gradient' }
1225 attrGradientDirection={ 'gradientDirection' }
1226 attrGradientColorOne={ 'gradientColorOne' }
1227 attrGradientColorStopOne={ 'gradientColorStopOne' }
1228 attrGradientColorTwo={ 'gradientColorTwo' }
1229 attrGradientColorStopTwo={ 'gradientColorStopTwo' }
1230 attrGradientColorOneOpacity={ 'gradientColorOneOpacity' }
1231 attrGradientColorTwoOpacity={ 'gradientColorTwoOpacity' }
1232 defaultColorOne={ generateBlocksDefaults.container.gradientColorOne }
1233 defaultColorTwo={ generateBlocksDefaults.container.gradientColorTwo }
1234 />
1235
1236 { applyFilters( 'generateblocks.editor.controls', '', 'containerBackgroundGradient', this.props, this.state ) }
1237 </PanelArea>
1238
1239 <PanelArea { ...this.props }
1240 title={ __( 'Background Image', 'generateblocks' ) }
1241 initialOpen={ false }
1242 icon={ getIcon( 'backgrounds' ) }
1243 className={ 'gblocks-panel-label' }
1244 id={ 'containerBackgroundImage' }
1245 state={ this.state }
1246 showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || false }
1247 >
1248 { ! bgImage && (
1249 <div>
1250 <MediaUpload
1251 title={ __( 'Set background image', 'generateblocks' ) }
1252 onSelect={ onSelectBgImage }
1253 allowedTypes={ [ 'image' ] }
1254 modalClass="editor-post-featured-image__media-modal"
1255 render={ ( { open } ) => (
1256 <Button className="editor-post-featured-image__toggle" onClick={ open }>
1257 { __( 'Set background image', 'generateblocks' ) }
1258 </Button>
1259 ) }
1260 />
1261 </div>
1262 ) }
1263
1264 { !! bgImage && (
1265 <MediaUpload
1266 title={ __( 'Set background image', 'generateblocks' ) }
1267 onSelect={ onSelectBgImage }
1268 allowedTypes={ [ 'image' ] }
1269 value={ bgImage.id }
1270 modalClass="editor-post-featured-image__media-modal"
1271 render={ ( { open } ) => (
1272 <div className="editor-bg-image">
1273 <Button className="editor-post-featured-image__preview" onClick={ open }>
1274 <ResponsiveWrapper
1275 naturalWidth={ bgImage.image.width }
1276 naturalHeight={ bgImage.image.height }
1277 >
1278 <img src={ bgImage.image.url } alt={ __( 'Background Image', 'generateblocks' ) } />
1279 </ResponsiveWrapper>
1280 </Button>
1281 <div className={ 'edit-bg-buttons' }>
1282 <Button onClick={ open } isSecondary isLarge>
1283 { __( 'Replace image', 'generateblocks' ) }
1284 </Button>
1285 <Button onClick={ onRemoveBgImage } isLink isDestructive>
1286 { __( 'Remove background image', 'generateblocks' ) }
1287 </Button>
1288 </div>
1289 </div>
1290 ) }
1291 />
1292 ) }
1293
1294 { !! bgImage && (
1295 <div className="section-bg-settings">
1296 { !! bgOptions.overlay ? ( // This option is deprecated, so only show it if it's in use.
1297 <Fragment>
1298 <ToggleControl
1299 label={ __( 'Background Color Overlay', 'generateblocks' ) }
1300 checked={ !! bgOptions.overlay }
1301 onChange={ ( nextOverlay ) => {
1302 setAttributes( {
1303 bgOptions: {
1304 ...bgOptions,
1305 overlay: nextOverlay,
1306 },
1307 } );
1308 } }
1309 />
1310
1311 <Notice
1312 className="gblocks-option-notice"
1313 status="info"
1314 isDismissible={ false }
1315 >
1316 { __( 'The background color overlay option is deprecated. Toggle this option to use the new method.', 'generateblocks' ) }
1317 </Notice>
1318 </Fragment>
1319 ) : ( // These options is only for people not using the deprecated overlay option.
1320 <Fragment>
1321 <SelectControl
1322 label={ __( 'Selector', 'generateblocks' ) }
1323 value={ bgOptions.selector }
1324 options={ [
1325 { label: __( 'Element', 'generateblocks' ), value: 'element' },
1326 { label: __( 'Pseudo Element', 'generateblocks' ), value: 'pseudo-element' },
1327 ] }
1328 onChange={ ( value ) => {
1329 setAttributes( {
1330 bgOptions: {
1331 ...bgOptions,
1332 selector: value,
1333 },
1334 } );
1335 } }
1336 />
1337
1338 <RangeControl
1339 label={ __( 'Image Opacity', 'generateblocks' ) }
1340 value={ bgOptions.opacity }
1341 onChange={ ( value ) => {
1342 setAttributes( {
1343 bgOptions: {
1344 ...bgOptions,
1345 opacity: value,
1346 },
1347 } );
1348
1349 if ( 'pseudo-element' !== bgOptions.selector ) {
1350 setAttributes( {
1351 bgOptions: {
1352 ...bgOptions,
1353 selector: 'pseudo-element',
1354 },
1355 } );
1356 }
1357 } }
1358 min={ 0 }
1359 max={ 1 }
1360 step={ 0.1 }
1361 initialPosition={ generateBlocksDefaults.container.bgOptions.opacity }
1362 />
1363
1364 { 'pseudo-element' !== bgOptions.selector &&
1365 <Notice
1366 className="gblocks-option-notice"
1367 status="info"
1368 isDismissible={ false }
1369 >
1370 { __( 'Your selector must be set to Pseudo Element to use opacity.', 'generateblocks' ) }
1371 </Notice>
1372 }
1373 </Fragment>
1374 ) }
1375
1376 <TextControl
1377 label={ __( 'Size', 'generateblocks' ) }
1378 value={ bgOptions.size }
1379 onChange={ ( nextSize ) => {
1380 setAttributes( {
1381 bgOptions: {
1382 ...bgOptions,
1383 size: nextSize,
1384 },
1385 } );
1386 } }
1387 />
1388
1389 <TextControl
1390 label={ __( 'Position', 'generateblocks' ) }
1391 value={ bgOptions.position }
1392 onChange={ ( nextPosition ) => {
1393 setAttributes( {
1394 bgOptions: {
1395 ...bgOptions,
1396 position: nextPosition,
1397 },
1398 } );
1399 } }
1400 />
1401
1402 <SelectControl
1403 label={ __( 'Repeat', 'generateblocks' ) }
1404 value={ bgOptions.repeat }
1405 options={ [
1406 { label: 'no-repeat', value: 'no-repeat' },
1407 { label: 'repeat', value: 'repeat' },
1408 { label: 'repeat-x', value: 'repeat-x' },
1409 { label: 'repeat-y', value: 'repeat-y' },
1410 ] }
1411 onChange={ ( nextRepeat ) => {
1412 setAttributes( {
1413 bgOptions: {
1414 ...bgOptions,
1415 repeat: nextRepeat,
1416 },
1417 } );
1418 } }
1419 />
1420
1421 <SelectControl
1422 label={ __( 'Attachment', 'generateblocks' ) }
1423 value={ bgOptions.attachment }
1424 options={ [
1425 { label: 'scroll', value: '' },
1426 { label: 'fixed', value: 'fixed' },
1427 { label: 'local', value: 'local' },
1428 ] }
1429 onChange={ ( nextAttachment ) => {
1430 setAttributes( {
1431 bgOptions: {
1432 ...bgOptions,
1433 attachment: nextAttachment,
1434 },
1435 } );
1436 } }
1437 />
1438 </div>
1439 ) }
1440
1441 { applyFilters( 'generateblocks.editor.controls', '', 'containerBackgroundImage', this.props, this.state ) }
1442 </PanelArea>
1443
1444 <PanelArea { ...this.props }
1445 title={ __( 'Advanced', 'generateblocks' ) }
1446 initialOpen={ false }
1447 icon={ getIcon( 'advanced' ) }
1448 className={ 'gblocks-panel-label' }
1449 id={ 'containerAdvanced' }
1450 state={ this.state }
1451 showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || false }
1452 >
1453 <SelectControl
1454 label={ __( 'Element Tag', 'generateblocks' ) }
1455 value={ tagName }
1456 options={ applyFilters( 'generateblocks.editor.containerTagNames', tagNames, this.props, this.state ) }
1457 onChange={ ( value ) => {
1458 setAttributes( {
1459 tagName: value,
1460 } );
1461 } }
1462 />
1463
1464 { applyFilters( 'generateblocks.editor.controls', '', 'containerAfterElementTag', this.props, this.state ) }
1465
1466 <TextControl
1467 label={ __( 'Element ID', 'generateblocks' ) }
1468 value={ elementId }
1469 onChange={ ( value ) => {
1470 const newElementId = value.replace( ELEMENT_ID_REGEX, '-' );
1471
1472 setAttributes( {
1473 elementId: newElementId,
1474 } );
1475 } }
1476 />
1477
1478 <TextControl
1479 label={ __( 'CSS Classes', 'generateblocks' ) }
1480 value={ cssClasses }
1481 onChange={ ( value ) => {
1482 setAttributes( {
1483 cssClasses: value,
1484 } );
1485 } }
1486 />
1487
1488 <TextControl
1489 label={ __( 'z-index', 'generateblocks' ) }
1490 type={ 'number' }
1491 value={ zindex || 0 === zindex ? zindex : '' }
1492 onChange={ ( value ) => {
1493 setAttributes( {
1494 zindex: value,
1495 } );
1496 } }
1497 onBlur={ () => {
1498 setAttributes( {
1499 zindex: parseFloat( zindex ),
1500 } );
1501 } }
1502 onClick={ ( e ) => {
1503 // Make sure onBlur fires in Firefox.
1504 e.currentTarget.focus();
1505 } }
1506 />
1507
1508 { applyFilters( 'generateblocks.editor.controls', '', 'containerAdvanced', this.props, this.state ) }
1509 </PanelArea>
1510
1511 <PanelArea { ...this.props }
1512 title={ __( 'Documentation', 'generateblocks' ) }
1513 initialOpen={ false }
1514 icon={ getIcon( 'documentation' ) }
1515 className={ 'gblocks-panel-label' }
1516 id={ 'containerDocumentation' }
1517 state={ this.state }
1518 >
1519 <p>{ __( 'Need help with this block?', 'generateblocks' ) }</p>
1520 <a href="https://docs.generateblocks.com/collection/container/" target="_blank" rel="noreferrer noopener">{ __( 'Visit our documentation', 'generateblocks' ) }</a>
1521
1522 { applyFilters( 'generateblocks.editor.controls', '', 'containerDocumentation', this.props, this.state ) }
1523 </PanelArea>
1524 </InspectorControls>
1525
1526 <DesktopCSS { ...this.props } />
1527
1528 { fontFamily && googleFont &&
1529 <link
1530 rel="stylesheet"
1531 href={ 'https://fonts.googleapis.com/css?family=' + fontFamily.replace( / /g, '+' ) + googleFontsAttr }
1532 />
1533 }
1534
1535 { !! isGrid && (
1536 <div className={ classnames( {
1537 'gb-grid-column': true,
1538 [ `gb-grid-column-${ uniqueId }` ]: true,
1539 } ) }>
1540 <Section
1541 attributes={ attributes }
1542 tagName={ tagName }
1543 id={ elementId }
1544 className={ classnames( {
1545 'gb-container': true,
1546 [ `gb-container-${ uniqueId }` ]: true,
1547 [ `${ cssClasses }` ]: '' !== cssClasses,
1548 } ) }
1549 >
1550 { applyFilters( 'generateblocks.frontend.insideContainer', '', attributes ) }
1551 <div
1552 className={ classnames( {
1553 'gb-inside-container': true,
1554 } ) }
1555 >
1556 <InnerBlocks
1557 templateLock={ false }
1558 renderAppender={ (
1559 hasChildBlocks ?
1560 undefined :
1561 () => <InnerBlocks.ButtonBlockAppender />
1562 ) }
1563 />
1564 </div>
1565 </Section>
1566 </div>
1567 ) }
1568
1569 { ! isGrid && (
1570 <Section
1571 attributes={ attributes }
1572 tagName={ tagName }
1573 id={ elementId }
1574 className={ classnames( {
1575 'gb-container': true,
1576 [ `gb-container-${ uniqueId }` ]: true,
1577 [ `${ cssClasses }` ]: '' !== cssClasses,
1578 [ `align${ align }` ]: !! align,
1579 } ) }
1580 >
1581 { applyFilters( 'generateblocks.frontend.insideContainer', '', attributes ) }
1582 <div
1583 className={ classnames( {
1584 'gb-inside-container': true,
1585 } ) }
1586 >
1587 <InnerBlocks
1588 templateLock={ false }
1589 renderAppender={ (
1590 hasChildBlocks ?
1591 undefined :
1592 () => <InnerBlocks.ButtonBlockAppender />
1593 ) }
1594 />
1595 </div>
1596 </Section>
1597 ) }
1598
1599 </Fragment>
1600 );
1601 }
1602 }
1603
1604 export default ( GenerateBlockContainer );
1605