PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.1.2
GenerateBlocks v1.1.2
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 / grid / edit.js
generateblocks / src / blocks / grid Last commit date
css 6 years ago attributes.js 6 years ago block.js 6 years ago edit.js 6 years ago editor.scss 6 years ago save.js 6 years ago
edit.js
889 lines
1 /**
2 * Block: Grid
3 */
4
5 import classnames from 'classnames';
6 import getIcon from '../../utils/get-icon';
7 import getSelectedDevice from '../../utils/get-selected-device';
8 import ResponsiveTabs from '../../components/responsive-tabs';
9 import DesktopCSS from './css/desktop.js';
10 import PanelArea from '../../components/panel-area/';
11
12 const { __ } = wp.i18n;
13
14 const {
15 TextControl,
16 SelectControl,
17 Tooltip,
18 Placeholder,
19 Button,
20 Toolbar,
21 } = wp.components;
22
23 const {
24 Fragment,
25 Component,
26 } = wp.element;
27
28 const {
29 InspectorControls,
30 InnerBlocks,
31 BlockControls,
32 } = wp.blockEditor;
33
34 const {
35 createBlock,
36 } = wp.blocks;
37
38 const {
39 applyFilters,
40 } = wp.hooks;
41
42 const ELEMENT_ID_REGEX = /[\s#]/g;
43 const gbGridIds = [];
44
45 class GenerateBlockGridContainer extends Component {
46 constructor() {
47 super( ...arguments );
48
49 this.state = {
50 selectedLayout: false,
51 selectedDevice: 'desktop',
52 };
53
54 this.onLayoutSelect = this.onLayoutSelect.bind( this );
55 this.getColumnsFromLayout = this.getColumnsFromLayout.bind( this );
56 this.getLayoutsSelector = this.getLayoutsSelector.bind( this );
57 }
58
59 componentDidMount() {
60 const id = this.props.clientId.substr( 2, 9 ).replace( '-', '' );
61
62 if ( ! this.props.attributes.uniqueId ) {
63 this.props.setAttributes( {
64 uniqueId: id,
65 } );
66
67 gbGridIds.push( id );
68 } else if ( gbGridIds.includes( this.props.attributes.uniqueId ) ) {
69 this.props.setAttributes( {
70 uniqueId: id,
71 } );
72
73 gbGridIds.push( id );
74 } else {
75 gbGridIds.push( this.props.attributes.uniqueId );
76 }
77 }
78
79 componentDidUpdate() {
80 const {
81 attributes,
82 setAttributes,
83 clientId,
84 } = this.props;
85
86 let {
87 columns,
88 } = attributes;
89
90 if ( this.state.selectedLayout ) {
91 const columnsData = this.getColumnsFromLayout( this.state.selectedLayout );
92
93 columnsData.forEach( ( colAttrs ) => {
94 wp.data.dispatch( 'core/block-editor' ).insertBlocks( createBlock( 'generateblocks/container', colAttrs ), undefined, clientId, false );
95 } );
96
97 columns = columnsData.length;
98
99 setAttributes( {
100 columns,
101 } );
102
103 this.setState( {
104 selectedLayout: false,
105 } );
106 } else {
107 const parentBlock = wp.data.select( 'core/block-editor' ).getBlocksByClientId( clientId )[ 0 ];
108
109 if ( parentBlock ) {
110 const childBlocks = parentBlock.innerBlocks;
111 columns = childBlocks.length;
112
113 setAttributes( {
114 columns,
115 } );
116 }
117 }
118 }
119
120 /**
121 * Get columns sizes array from layout string
122 *
123 * @param {string} layout - layout data. Example: `3-6-3`
124 *
125 * @return {array}.
126 */
127 getColumnsFromLayout( layout ) {
128 const result = [];
129 const columnsData = layout.split( '-' );
130
131 let i = 0;
132 columnsData.forEach( () => {
133 const colAttrs = {
134 isGrid: true,
135 gridId: this.props.attributes.uniqueId,
136 paddingTop: generateBlocksStyling.container.gridItemPaddingTop || '0',
137 paddingRight: generateBlocksStyling.container.gridItemPaddingRight || '0',
138 paddingBottom: generateBlocksStyling.container.gridItemPaddingBottom || '0',
139 paddingLeft: generateBlocksStyling.container.gridItemPaddingLeft || '0',
140 };
141
142 colAttrs.width = Number( columnsData[ i ] );
143 i++;
144
145 result.push( colAttrs );
146 } );
147
148 return result;
149 }
150
151 /**
152 * Layouts selector when no columns selected.
153 *
154 * @return {jsx}.
155 */
156 getLayoutsSelector() {
157 const layouts = [
158 '100',
159 '50-50',
160 '33.33-33.33-33.33',
161 '25-25-25-25',
162
163 '25-75',
164 '75-25',
165 '25-25-50',
166 '25-50-25',
167
168 '50-25-25',
169 '20-60-20',
170 '20-20-20-20-20',
171 '16.66-16.66-16.66-16.66-16.66-16.66',
172 ];
173
174 return (
175 <Placeholder
176 label={ __( 'Grid', 'generateblocks' ) }
177 instructions={ __( 'Select one layout to get started.', 'generateblocks' ) }
178 className="gb-select-layout"
179 >
180 <div className="gb-grid-wrapper-layout-preview">
181 { layouts.map( ( layout ) => {
182 const columnsData = this.getColumnsFromLayout( layout );
183
184 return (
185 <button
186 key={ `layout-${ layout }` }
187 className="gb-grid-wrapper-layout-preview-btn"
188 onClick={ () => this.onLayoutSelect( layout ) }
189 >
190 { columnsData.map( ( colAttrs, i ) => {
191 return (
192 <div
193 key={ `layout-${ layout }-col-${ i }` }
194 className={ classnames( 'gb-col', `gb-col-${ colAttrs.width }` ) }
195 />
196 );
197 } ) }
198 </button>
199 );
200 } ) }
201 </div>
202 </Placeholder>
203 );
204 }
205
206 /**
207 * Select predefined layout.
208 *
209 * @param {String} layout layout string.
210 */
211 onLayoutSelect( layout ) {
212 this.setState( {
213 selectedLayout: layout,
214 } );
215 }
216
217 render() {
218 const {
219 attributes,
220 setAttributes,
221 clientId,
222 } = this.props;
223
224 const {
225 selectedDevice,
226 } = this.state;
227
228 const {
229 uniqueId,
230 elementId,
231 cssClasses,
232 columns,
233 horizontalGap,
234 verticalGap,
235 verticalAlignment,
236 horizontalGapTablet,
237 verticalGapTablet,
238 verticalAlignmentTablet,
239 horizontalGapMobile,
240 verticalGapMobile,
241 verticalAlignmentMobile,
242 horizontalAlignment,
243 horizontalAlignmentTablet,
244 horizontalAlignmentMobile,
245 } = attributes;
246
247 const horizontalGapPlaceholderTablet = horizontalGap || 0 === horizontalGap ? horizontalGap : '',
248 verticalGapPlaceholderTablet = verticalGap || 0 === verticalGap ? verticalGap : '';
249
250 let horizontalGapPlaceholderMobile = horizontalGap || 0 === horizontalGap ? horizontalGap : '',
251 verticalGapPlaceholderMobile = verticalGap || 0 === verticalGap ? verticalGap : '';
252
253 if ( horizontalGapTablet ) {
254 horizontalGapPlaceholderMobile = horizontalGapTablet;
255 }
256
257 if ( verticalGapTablet ) {
258 verticalGapPlaceholderMobile = verticalGapTablet;
259 }
260
261 let htmlAttributes = {
262 id: !! elementId ? elementId : undefined,
263 className: classnames( {
264 'gb-grid-wrapper': true,
265 [ `gb-grid-wrapper-${ uniqueId }` ]: true,
266 [ `${ cssClasses }` ]: '' !== cssClasses,
267 } ),
268 };
269
270 htmlAttributes = applyFilters( 'generateblocks.frontend.htmlAttributes', htmlAttributes, 'generateblocks/grid', attributes );
271
272 return (
273 <Fragment>
274 <BlockControls>
275 <Toolbar>
276 <Tooltip text={ __( 'Add Grid Item', 'generateblocks' ) }>
277 <Button
278 className="gblocks-block-control-icon gblocks-add-grid-item"
279 icon={ getIcon( 'addContainer' ) }
280 onClick={ () => {
281 wp.data.dispatch( 'core/block-editor' ).insertBlocks(
282 createBlock( 'generateblocks/container', {
283 isGrid: true,
284 gridId: uniqueId,
285 paddingTop: generateBlocksStyling.container.gridItemPaddingTop || '0',
286 paddingRight: generateBlocksStyling.container.gridItemPaddingRight || '0',
287 paddingBottom: generateBlocksStyling.container.gridItemPaddingBottom || '0',
288 paddingLeft: generateBlocksStyling.container.gridItemPaddingLeft || '0',
289 } ),
290 undefined,
291 clientId
292 );
293 } }
294 />
295 </Tooltip>
296 </Toolbar>
297 </BlockControls>
298 <InspectorControls>
299 <ResponsiveTabs { ...this.props }
300 selectedDevice={ getSelectedDevice( selectedDevice ) }
301 onClick={ ( device ) => {
302 window.localStorage.setItem( 'generateblocksSelectedDevice', device );
303
304 this.setState( {
305 selectedDevice: device,
306 } );
307 } }
308 />
309
310 <PanelArea { ...this.props }
311 id={ 'gridLayout' }
312 state={ this.state }
313 >
314 { 'desktop' === getSelectedDevice( selectedDevice ) && (
315 <Fragment>
316 <div className="components-gblocks-control__header">
317 <div className="components-gblocks-control__label">
318 { __( 'Horizontal Gap', 'generateblocks' ) }
319 </div>
320
321 <div className="components-gblocks-control__units">
322 <Tooltip text={ __( 'Pixel Units', 'generateblocks' ) } key={ 'h-gap-unit' }>
323 <Button
324 key={ 'h-gap-unit' }
325 isSmall
326 isPrimary={ true }
327 aria-label={ __( 'Pixel Units', 'generateblocks' ) }
328 >
329 px
330 </Button>
331 </Tooltip>
332 </div>
333 </div>
334
335 <div className="components-base-control components-gblocks-typography-control__inputs">
336 <TextControl
337 type={ 'number' }
338 value={ horizontalGap || 0 === horizontalGap ? horizontalGap : '' }
339 min="0"
340 onChange={ ( value ) => {
341 // No hyphens allowed here.
342 value = value.toString().replace( /-/g, '' );
343
344 setAttributes( {
345 horizontalGap: value,
346 } );
347 } }
348 onBlur={ () => {
349 if ( ! horizontalGap && generateBlocksDefaults.gridContainer.horizontalGap ) {
350 // If we have no value and a default exists, set to 0 to prevent default from coming back.
351 setAttributes( {
352 horizontalGap: 0,
353 } );
354 } else {
355 setAttributes( {
356 horizontalGap: parseFloat( horizontalGap ),
357 } );
358 }
359 } }
360 onClick={ ( e ) => {
361 // Make sure onBlur fires in Firefox.
362 e.currentTarget.focus();
363 } }
364 />
365
366 <Button
367 isSmall
368 isSecondary
369 className="components-gblocks-default-number"
370 onClick={ () => {
371 setAttributes( {
372 horizontalGap: generateBlocksDefaults.gridContainer.horizontalGap,
373 } );
374 } }
375 >
376 { __( 'Reset', 'generateblocks' ) }
377 </Button>
378 </div>
379
380 <div className="components-gblocks-control__header">
381 <div className="components-gblocks-control__label">
382 { __( 'Vertical Gap', 'generateblocks' ) }
383 </div>
384
385 <div className="components-gblocks-control__units">
386 <Tooltip text={ __( 'Pixel Units', 'generateblocks' ) } key={ 'v-gap-unit' }>
387 <Button
388 key={ 'v-gap-unit' }
389 isSmall
390 isPrimary={ true }
391 aria-label={ __( 'Pixel Units', 'generateblocks' ) }
392 >
393 px
394 </Button>
395 </Tooltip>
396 </div>
397 </div>
398
399 <div className="components-base-control components-gblocks-typography-control__inputs">
400 <TextControl
401 type={ 'number' }
402 value={ verticalGap || 0 === verticalGap ? verticalGap : '' }
403 min="0"
404 onChange={ ( value ) => {
405 // No negative values allowed here.
406 value = value.toString().replace( /-/g, '' );
407
408 setAttributes( {
409 verticalGap: value,
410 } );
411 } }
412 onBlur={ () => {
413 if ( ! verticalGap && generateBlocksDefaults.gridContainer.verticalGap ) {
414 // If we have no value and a default exists, set to 0 to prevent default from coming back.
415 setAttributes( {
416 verticalGap: 0,
417 } );
418 } else {
419 setAttributes( {
420 verticalGap: parseFloat( verticalGap ),
421 } );
422 }
423 } }
424 onClick={ ( e ) => {
425 // Make sure onBlur fires in Firefox.
426 e.currentTarget.focus();
427 } }
428 />
429
430 <Button
431 isSmall
432 isSecondary
433 className="components-gblocks-default-number"
434 onClick={ () => {
435 setAttributes( {
436 verticalGap: generateBlocksDefaults.gridContainer.verticalGap,
437 } );
438 } }
439 >
440 { __( 'Reset', 'generateblocks' ) }
441 </Button>
442 </div>
443
444 <SelectControl
445 label={ __( 'Vertical Alignment', 'generateblocks' ) }
446 value={ verticalAlignment }
447 help={ __( 'Align grid items. Removes same height columns and overrides grid item content alignment.', 'generateblocks' ) }
448 options={ [
449 { label: __( 'Default', 'generateblocks' ), value: '' },
450 { label: __( 'Top', 'generateblocks' ), value: 'flex-start' },
451 { label: __( 'Center', 'generateblocks' ), value: 'center' },
452 { label: __( 'Bottom', 'generateblocks' ), value: 'flex-end' },
453 ] }
454 onChange={ ( value ) => {
455 setAttributes( {
456 verticalAlignment: value,
457 } );
458 } }
459 />
460
461 <SelectControl
462 label={ __( 'Horizontal Alignment', 'generateblocks' ) }
463 value={ horizontalAlignment }
464 options={ [
465 { label: __( 'Default', 'generateblocks' ), value: '' },
466 { label: __( 'Left', 'generateblocks' ), value: 'flex-start' },
467 { label: __( 'Center', 'generateblocks' ), value: 'center' },
468 { label: __( 'Right', 'generateblocks' ), value: 'flex-end' },
469 ] }
470 onChange={ ( value ) => {
471 setAttributes( {
472 horizontalAlignment: value,
473 } );
474 } }
475 />
476 </Fragment>
477 ) }
478
479 { 'tablet' === getSelectedDevice( selectedDevice ) && (
480 <Fragment>
481 <div className="components-gblocks-control__header">
482 <div className="components-gblocks-control__label">
483 { __( 'Horizontal Gap', 'generateblocks' ) }
484 </div>
485
486 <div className="components-gblocks-control__units">
487 <Tooltip text={ __( 'Pixel Units', 'generateblocks' ) } key={ 'h-gap-tablet-unit' }>
488 <Button
489 key={ 'h-gap-tablet-unit' }
490 isSmall
491 isPrimary={ true }
492 aria-label={ __( 'Pixel Units', 'generateblocks' ) }
493 >
494 px
495 </Button>
496 </Tooltip>
497 </div>
498 </div>
499
500 <div className="components-base-control components-gblocks-typography-control__inputs">
501 <TextControl
502 type={ 'number' }
503 value={ horizontalGapTablet || 0 === horizontalGapTablet ? horizontalGapTablet : '' }
504 min="0"
505 placeholder={ horizontalGapPlaceholderTablet }
506 onChange={ ( value ) => {
507 // No negative values allowed here.
508 value = value.toString().replace( /-/g, '' );
509
510 setAttributes( {
511 horizontalGapTablet: value,
512 } );
513 } }
514 onBlur={ () => {
515 if ( ! horizontalGapTablet && generateBlocksDefaults.gridContainer.horizontalGapTablet ) {
516 // If we have no value and a default exists, set to 0 to prevent default from coming back.
517 setAttributes( {
518 horizontalGapTablet: 0,
519 } );
520 } else {
521 setAttributes( {
522 horizontalGapTablet: parseFloat( horizontalGapTablet ),
523 } );
524 }
525 } }
526 onClick={ ( e ) => {
527 // Make sure onBlur fires in Firefox.
528 e.currentTarget.focus();
529 } }
530 />
531
532 <Button
533 isSmall
534 isSecondary
535 className="components-gblocks-default-number"
536 onClick={ () => {
537 setAttributes( {
538 horizontalGapTablet: generateBlocksDefaults.gridContainer.horizontalGapTablet,
539 } );
540 } }
541 >
542 { __( 'Reset', 'generateblocks' ) }
543 </Button>
544 </div>
545
546 <div className="components-gblocks-control__header">
547 <div className="components-gblocks-control__label">
548 { __( 'Vertical Gap', 'generateblocks' ) }
549 </div>
550
551 <div className="components-gblocks-control__units">
552 <Tooltip text={ __( 'Pixel Units', 'generateblocks' ) } key={ 'v-gap-tablet-unit' }>
553 <Button
554 key={ 'v-gap-tablet-unit' }
555 isSmall
556 isPrimary={ true }
557 aria-label={ __( 'Pixel Units', 'generateblocks' ) }
558 >
559 px
560 </Button>
561 </Tooltip>
562 </div>
563 </div>
564
565 <div className="components-base-control components-gblocks-typography-control__inputs">
566 <TextControl
567 type={ 'number' }
568 value={ verticalGapTablet || 0 === verticalGapTablet ? verticalGapTablet : '' }
569 min="0"
570 placeholder={ verticalGapPlaceholderTablet }
571 onChange={ ( value ) => {
572 // No negative values allowed here.
573 value = value.toString().replace( /-/g, '' );
574
575 setAttributes( {
576 verticalGapTablet: value,
577 } );
578 } }
579 onBlur={ () => {
580 if ( ! verticalGapTablet && generateBlocksDefaults.gridContainer.verticalGapTablet ) {
581 // If we have no value and a default exists, set to 0 to prevent default from coming back.
582 setAttributes( {
583 verticalGapTablet: 0,
584 } );
585 } else {
586 setAttributes( {
587 verticalGapTablet: parseFloat( verticalGapTablet ),
588 } );
589 }
590 } }
591 onClick={ ( e ) => {
592 // Make sure onBlur fires in Firefox.
593 e.currentTarget.focus();
594 } }
595 />
596
597 <Button
598 isSmall
599 isSecondary
600 className="components-gblocks-default-number"
601 onClick={ () => {
602 setAttributes( {
603 verticalGapTablet: generateBlocksDefaults.gridContainer.verticalGapTablet,
604 } );
605 } }
606 >
607 { __( 'Reset', 'generateblocks' ) }
608 </Button>
609 </div>
610
611 <SelectControl
612 label={ __( 'Vertical Alignment', 'generateblocks' ) }
613 help={ __( 'Align grid items. Removes same height columns and overrides grid item content alignment.', 'generateblocks' ) }
614 value={ verticalAlignmentTablet }
615 options={ [
616 { label: __( 'Inherit', 'generateblocks' ), value: 'inherit' },
617 { label: __( 'Default', 'generateblocks' ), value: '' },
618 { label: __( 'Top', 'generateblocks' ), value: 'flex-start' },
619 { label: __( 'Center', 'generateblocks' ), value: 'center' },
620 { label: __( 'Bottom', 'generateblocks' ), value: 'flex-end' },
621 ] }
622 onChange={ ( value ) => {
623 setAttributes( {
624 verticalAlignmentTablet: value,
625 } );
626 } }
627 />
628
629 <SelectControl
630 label={ __( 'Horizontal Alignment', 'generateblocks' ) }
631 value={ horizontalAlignmentTablet }
632 options={ [
633 { label: __( 'Inherit', 'generateblocks' ), value: 'inherit' },
634 { label: __( 'Default', 'generateblocks' ), value: '' },
635 { label: __( 'Left', 'generateblocks' ), value: 'flex-start' },
636 { label: __( 'Center', 'generateblocks' ), value: 'center' },
637 { label: __( 'Right', 'generateblocks' ), value: 'flex-end' },
638 ] }
639 onChange={ ( value ) => {
640 setAttributes( {
641 horizontalAlignmentTablet: value,
642 } );
643 } }
644 />
645 </Fragment>
646 ) }
647
648 { 'mobile' === getSelectedDevice( selectedDevice ) && (
649 <Fragment>
650 <div className="components-gblocks-control__header">
651 <div className="components-gblocks-control__label">
652 { __( 'Horizontal Gap', 'generateblocks' ) }
653 </div>
654
655 <div className="components-gblocks-control__units">
656 <Tooltip text={ __( 'Pixel Units', 'generateblocks' ) } key={ 'h-gap-mobile-unit' }>
657 <Button
658 key={ 'h-gap-mobile-unit' }
659 isSmall
660 isPrimary={ true }
661 aria-label={ __( 'Pixel Units', 'generateblocks' ) }
662 >
663 px
664 </Button>
665 </Tooltip>
666 </div>
667 </div>
668
669 <div className="components-base-control components-gblocks-typography-control__inputs">
670 <TextControl
671 type={ 'number' }
672 value={ horizontalGapMobile || 0 === horizontalGapMobile ? horizontalGapMobile : '' }
673 min="0"
674 placeholder={ horizontalGapPlaceholderMobile }
675 onChange={ ( value ) => {
676 // No negative values allowed here.
677 value = value.toString().replace( /-/g, '' );
678
679 setAttributes( {
680 horizontalGapMobile: value,
681 } );
682 } }
683 onBlur={ () => {
684 if ( ! horizontalGapMobile && generateBlocksDefaults.gridContainer.horizontalGapMobile ) {
685 // If we have no value and a default exists, set to 0 to prevent default from coming back.
686 setAttributes( {
687 horizontalGapMobile: 0,
688 } );
689 } else {
690 setAttributes( {
691 horizontalGapMobile: parseFloat( horizontalGapMobile ),
692 } );
693 }
694 } }
695 onClick={ ( e ) => {
696 // Make sure onBlur fires in Firefox.
697 e.currentTarget.focus();
698 } }
699 />
700
701 <Button
702 isSmall
703 isSecondary
704 className="components-gblocks-default-number"
705 onClick={ () => {
706 setAttributes( {
707 horizontalGapMobile: generateBlocksDefaults.gridContainer.horizontalGapMobile,
708 } );
709 } }
710 >
711 { __( 'Reset', 'generateblocks' ) }
712 </Button>
713 </div>
714
715 <div className="components-gblocks-control__header">
716 <div className="components-gblocks-control__label">
717 { __( 'Vertical Gap', 'generateblocks' ) }
718 </div>
719
720 <div className="components-gblocks-control__units">
721 <Tooltip text={ __( 'Pixel Units', 'generateblocks' ) } key={ 'v-gap-mobile-unit' }>
722 <Button
723 key={ 'v-gap-mobile-unit' }
724 isSmall
725 isPrimary={ true }
726 aria-label={ __( 'Pixel Units', 'generateblocks' ) }
727 >
728 px
729 </Button>
730 </Tooltip>
731 </div>
732 </div>
733
734 <div className="components-base-control components-gblocks-typography-control__inputs">
735 <TextControl
736 type={ 'number' }
737 value={ verticalGapMobile || 0 === verticalGapMobile ? verticalGapMobile : '' }
738 min="0"
739 placeholder={ verticalGapPlaceholderMobile }
740 onChange={ ( value ) => {
741 // No negative values allowed here.
742 value = value.toString().replace( /-/g, '' );
743
744 setAttributes( {
745 verticalGapMobile: value,
746 } );
747 } }
748 onBlur={ () => {
749 if ( ! verticalGapMobile && generateBlocksDefaults.gridContainer.verticalGapMobile ) {
750 // If we have no value and a default exists, set to 0 to prevent default from coming back.
751 setAttributes( {
752 verticalGapMobile: 0,
753 } );
754 } else {
755 setAttributes( {
756 verticalGapMobile: parseFloat( verticalGapMobile ),
757 } );
758 }
759 } }
760 onClick={ ( e ) => {
761 // Make sure onBlur fires in Firefox.
762 e.currentTarget.focus();
763 } }
764 />
765
766 <Button
767 isSmall
768 isSecondary
769 className="components-gblocks-default-number"
770 onClick={ () => {
771 setAttributes( {
772 verticalGapMobile: generateBlocksDefaults.gridContainer.verticalGapMobile,
773 } );
774 } }
775 >
776 { __( 'Reset', 'generateblocks' ) }
777 </Button>
778 </div>
779
780 <SelectControl
781 label={ __( 'Vertical Alignment', 'generateblocks' ) }
782 help={ __( 'Align grid items. Removes same height columns and overrides grid item content alignment.', 'generateblocks' ) }
783 value={ verticalAlignmentMobile }
784 options={ [
785 { label: __( 'Inherit', 'generateblocks' ), value: 'inherit' },
786 { label: __( 'Default', 'generateblocks' ), value: '' },
787 { label: __( 'Top', 'generateblocks' ), value: 'flex-start' },
788 { label: __( 'Center', 'generateblocks' ), value: 'center' },
789 { label: __( 'Bottom', 'generateblocks' ), value: 'flex-end' },
790 ] }
791 onChange={ ( value ) => {
792 setAttributes( {
793 verticalAlignmentMobile: value,
794 } );
795 } }
796 />
797
798 <SelectControl
799 label={ __( 'Horizontal Alignment', 'generateblocks' ) }
800 value={ horizontalAlignmentMobile }
801 options={ [
802 { label: __( 'Inherit', 'generateblocks' ), value: 'inherit' },
803 { label: __( 'Default', 'generateblocks' ), value: '' },
804 { label: __( 'Left', 'generateblocks' ), value: 'flex-start' },
805 { label: __( 'Center', 'generateblocks' ), value: 'center' },
806 { label: __( 'Right', 'generateblocks' ), value: 'flex-end' },
807 ] }
808 onChange={ ( value ) => {
809 setAttributes( {
810 horizontalAlignmentMobile: value,
811 } );
812 } }
813 />
814 </Fragment>
815 ) }
816
817 { applyFilters( 'generateblocks.editor.controls', '', 'gridLayout', this.props, this.state ) }
818 </PanelArea>
819
820 <PanelArea { ...this.props }
821 title={ __( 'Advanced', 'generateblocks' ) }
822 initialOpen={ false }
823 icon={ getIcon( 'advanced' ) }
824 className={ 'gblocks-panel-label' }
825 id={ 'gridAdvanced' }
826 state={ this.state }
827 showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || false }
828 >
829 <TextControl
830 label={ __( 'Element ID', 'generateblocks' ) }
831 value={ elementId }
832 onChange={ ( value ) => {
833 const newElementId = value.replace( ELEMENT_ID_REGEX, '-' );
834
835 setAttributes( {
836 elementId: newElementId,
837 } );
838 } }
839 />
840
841 <TextControl
842 label={ __( 'CSS Classes', 'generateblocks' ) }
843 value={ cssClasses }
844 onChange={ ( value ) => {
845 setAttributes( {
846 cssClasses: value,
847 } );
848 } }
849 />
850
851 { applyFilters( 'generateblocks.editor.controls', '', 'gridAdvanced', this.props, this.state ) }
852 </PanelArea>
853
854 <PanelArea { ...this.props }
855 title={ __( 'Documentation', 'generateblocks' ) }
856 icon={ getIcon( 'documentation' ) }
857 initialOpen={ false }
858 className={ 'gblocks-panel-label' }
859 id={ 'gridDocumentation' }
860 state={ this.state }
861 >
862 <p>{ __( 'Need help with this block?', 'generateblocks' ) }</p>
863 <a href="https://docs.generateblocks.com/collection/grid/" target="_blank" rel="noreferrer noopener">{ __( 'Visit our documentation', 'generateblocks' ) }</a>
864
865 { applyFilters( 'generateblocks.editor.controls', '', 'gridDocumentation', this.props, this.state ) }
866 </PanelArea>
867 </InspectorControls>
868
869 <DesktopCSS { ...this.props } />
870
871 <div
872 { ...htmlAttributes }
873 >
874 { columns > 0 || this.state.selectedLayout ? (
875 <Fragment>
876 <InnerBlocks
877 allowedBlocks={ [ 'generateblocks/container' ] }
878 renderAppender={ false }
879 />
880 </Fragment>
881 ) : this.getLayoutsSelector() }
882 </div>
883 </Fragment>
884 );
885 }
886 }
887
888 export default ( GenerateBlockGridContainer );
889