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