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
419 lines
| 1 | /** |
| 2 | * Block: Button Container |
| 3 | */ |
| 4 | |
| 5 | import classnames from 'classnames'; |
| 6 | import DimensionsControl from '../../components/dimensions/'; |
| 7 | import ResponsiveTabs from '../../components/responsive-tabs'; |
| 8 | import getIcon from '../../utils/get-icon'; |
| 9 | import getSelectedDevice from '../../utils/get-selected-device'; |
| 10 | import DesktopCSS from './css/desktop.js'; |
| 11 | import PanelArea from '../../components/panel-area/'; |
| 12 | |
| 13 | const { __ } = wp.i18n; // Import __() from wp.i18n |
| 14 | const { |
| 15 | TextControl, |
| 16 | Tooltip, |
| 17 | Button, |
| 18 | ToggleControl, |
| 19 | Toolbar, |
| 20 | } = wp.components; |
| 21 | |
| 22 | const { |
| 23 | Fragment, |
| 24 | Component, |
| 25 | } = wp.element; |
| 26 | |
| 27 | const { |
| 28 | InspectorControls, |
| 29 | InnerBlocks, |
| 30 | AlignmentToolbar, |
| 31 | BlockControls, |
| 32 | } = wp.blockEditor; |
| 33 | |
| 34 | const { |
| 35 | createBlock, |
| 36 | cloneBlock, |
| 37 | } = wp.blocks; |
| 38 | |
| 39 | const { |
| 40 | applyFilters, |
| 41 | } = wp.hooks; |
| 42 | |
| 43 | const ELEMENT_ID_REGEX = /[\s#]/g; |
| 44 | const gbButtonContainerIds = []; |
| 45 | |
| 46 | const ALIGNMENT_CONTROLS = [ |
| 47 | { |
| 48 | icon: 'editor-alignleft', |
| 49 | title: __( 'Align Buttons Left', 'generateblocks' ), |
| 50 | align: 'left', |
| 51 | }, |
| 52 | { |
| 53 | icon: 'editor-aligncenter', |
| 54 | title: __( 'Align Buttons Center', 'generateblocks' ), |
| 55 | align: 'center', |
| 56 | }, |
| 57 | { |
| 58 | icon: 'editor-alignright', |
| 59 | title: __( 'Align Buttons Right', 'generateblocks' ), |
| 60 | align: 'right', |
| 61 | }, |
| 62 | ]; |
| 63 | |
| 64 | class GenerateButtonContainer extends Component { |
| 65 | constructor() { |
| 66 | super( ...arguments ); |
| 67 | |
| 68 | this.state = { |
| 69 | selectedDevice: 'desktop', |
| 70 | }; |
| 71 | } |
| 72 | |
| 73 | componentDidMount() { |
| 74 | const id = this.props.clientId.substr( 2, 9 ).replace( '-', '' ); |
| 75 | |
| 76 | if ( ! this.props.attributes.uniqueId ) { |
| 77 | this.props.setAttributes( { |
| 78 | uniqueId: id, |
| 79 | } ); |
| 80 | |
| 81 | gbButtonContainerIds.push( id ); |
| 82 | } else if ( gbButtonContainerIds.includes( this.props.attributes.uniqueId ) ) { |
| 83 | this.props.setAttributes( { |
| 84 | uniqueId: id, |
| 85 | } ); |
| 86 | |
| 87 | gbButtonContainerIds.push( id ); |
| 88 | } else { |
| 89 | gbButtonContainerIds.push( this.props.attributes.uniqueId ); |
| 90 | } |
| 91 | |
| 92 | const thisBlock = wp.data.select( 'core/block-editor' ).getBlocksByClientId( this.props.clientId )[ 0 ]; |
| 93 | |
| 94 | if ( thisBlock ) { |
| 95 | const childBlocks = thisBlock.innerBlocks; |
| 96 | |
| 97 | if ( 0 === childBlocks.length ) { |
| 98 | wp.data.dispatch( 'core/block-editor' ).insertBlocks( createBlock( 'generateblocks/button', generateBlocksStyling.button ), undefined, this.props.clientId ); |
| 99 | } |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | render() { |
| 104 | const { |
| 105 | attributes, |
| 106 | setAttributes, |
| 107 | clientId, |
| 108 | } = this.props; |
| 109 | |
| 110 | const { |
| 111 | selectedDevice, |
| 112 | } = this.state; |
| 113 | |
| 114 | const { |
| 115 | uniqueId, |
| 116 | elementId, |
| 117 | cssClasses, |
| 118 | alignment, |
| 119 | alignmentTablet, |
| 120 | alignmentMobile, |
| 121 | stack, |
| 122 | stackTablet, |
| 123 | stackMobile, |
| 124 | fillHorizontalSpace, |
| 125 | fillHorizontalSpaceTablet, |
| 126 | fillHorizontalSpaceMobile, |
| 127 | } = attributes; |
| 128 | |
| 129 | let htmlAttributes = { |
| 130 | id: !! elementId ? elementId : undefined, |
| 131 | className: classnames( { |
| 132 | 'gb-button-wrapper': true, |
| 133 | [ `gb-button-wrapper-${ uniqueId }` ]: true, |
| 134 | [ `${ cssClasses }` ]: '' !== cssClasses, |
| 135 | } ), |
| 136 | }; |
| 137 | |
| 138 | htmlAttributes = applyFilters( 'generateblocks.frontend.htmlAttributes', htmlAttributes, 'generateblocks/button-container', attributes ); |
| 139 | |
| 140 | return ( |
| 141 | <Fragment> |
| 142 | <BlockControls> |
| 143 | <Toolbar> |
| 144 | <Tooltip text={ __( 'Add Button', 'generateblocks' ) }> |
| 145 | <Button |
| 146 | className="gblocks-add-new-button" |
| 147 | icon={ 'insert' } |
| 148 | onClick={ () => { |
| 149 | const thisBlock = wp.data.select( 'core/block-editor' ).getBlocksByClientId( clientId )[ 0 ]; |
| 150 | |
| 151 | if ( thisBlock ) { |
| 152 | const childBlocks = thisBlock.innerBlocks; |
| 153 | const keys = Object.keys( childBlocks ); |
| 154 | const lastKey = keys[ keys.length - 1 ]; |
| 155 | |
| 156 | if ( typeof childBlocks[ lastKey ] !== 'undefined' ) { |
| 157 | const blockToCopyId = childBlocks[ lastKey ].clientId; |
| 158 | |
| 159 | if ( blockToCopyId ) { |
| 160 | const blockToCopy = wp.data.select( 'core/block-editor' ).getBlocksByClientId( blockToCopyId )[ 0 ]; |
| 161 | const clonedBlock = cloneBlock( blockToCopy ); |
| 162 | |
| 163 | wp.data.dispatch( 'core/block-editor' ).insertBlocks( clonedBlock, undefined, clientId ); |
| 164 | } |
| 165 | } else if ( 0 === childBlocks.length ) { |
| 166 | wp.data.dispatch( 'core/block-editor' ).insertBlocks( createBlock( 'generateblocks/button', generateBlocksStyling.button ), undefined, clientId ); |
| 167 | } |
| 168 | } |
| 169 | } } |
| 170 | /> |
| 171 | </Tooltip> |
| 172 | </Toolbar> |
| 173 | <AlignmentToolbar |
| 174 | isCollapsed={ false } |
| 175 | value={ alignment } |
| 176 | alignmentControls={ ALIGNMENT_CONTROLS } |
| 177 | onChange={ ( nextAlign ) => { |
| 178 | setAttributes( { alignment: nextAlign } ); |
| 179 | } } |
| 180 | /> |
| 181 | </BlockControls> |
| 182 | |
| 183 | <InspectorControls> |
| 184 | <ResponsiveTabs { ...this.props } |
| 185 | selectedDevice={ getSelectedDevice( selectedDevice ) } |
| 186 | onClick={ ( device ) => { |
| 187 | window.localStorage.setItem( 'generateblocksSelectedDevice', device ); |
| 188 | |
| 189 | this.setState( { |
| 190 | selectedDevice: device, |
| 191 | } ); |
| 192 | } } |
| 193 | /> |
| 194 | |
| 195 | <PanelArea { ...this.props } |
| 196 | title={ __( 'Spacing', 'generateblocks' ) } |
| 197 | initialOpen={ true } |
| 198 | icon={ getIcon( 'spacing' ) } |
| 199 | className={ 'gblocks-panel-label' } |
| 200 | id={ 'buttonContainerSpacing' } |
| 201 | state={ this.state } |
| 202 | > |
| 203 | { 'desktop' === getSelectedDevice( selectedDevice ) && ( |
| 204 | <Fragment> |
| 205 | <AlignmentToolbar |
| 206 | isCollapsed={ false } |
| 207 | value={ alignment } |
| 208 | alignmentControls={ ALIGNMENT_CONTROLS } |
| 209 | onChange={ ( value ) => { |
| 210 | setAttributes( { alignment: value } ); |
| 211 | } } |
| 212 | /> |
| 213 | |
| 214 | <DimensionsControl { ...this.props } |
| 215 | device={ getSelectedDevice( selectedDevice ) } |
| 216 | type={ 'margin' } |
| 217 | label={ __( 'Margin', 'generateblocks' ) } |
| 218 | attrTop={ 'marginTop' } |
| 219 | attrRight={ 'marginRight' } |
| 220 | attrBottom={ 'marginBottom' } |
| 221 | attrLeft={ 'marginLeft' } |
| 222 | attrUnit={ 'marginUnit' } |
| 223 | attrSyncUnits={ 'marginSyncUnits' } |
| 224 | defaults={ generateBlocksDefaults.buttonContainer } |
| 225 | /> |
| 226 | |
| 227 | <ToggleControl |
| 228 | label={ __( 'Stack Vertically', 'generateblocks' ) } |
| 229 | checked={ !! stack } |
| 230 | onChange={ ( value ) => { |
| 231 | setAttributes( { |
| 232 | stack: value, |
| 233 | } ); |
| 234 | } } |
| 235 | /> |
| 236 | |
| 237 | <ToggleControl |
| 238 | label={ __( 'Fill Horizontal Space', 'generateblocks' ) } |
| 239 | checked={ !! fillHorizontalSpace } |
| 240 | onChange={ ( value ) => { |
| 241 | setAttributes( { |
| 242 | fillHorizontalSpace: value, |
| 243 | } ); |
| 244 | } } |
| 245 | /> |
| 246 | </Fragment> |
| 247 | ) } |
| 248 | |
| 249 | { 'tablet' === getSelectedDevice( selectedDevice ) && ( |
| 250 | <Fragment> |
| 251 | <AlignmentToolbar |
| 252 | isCollapsed={ false } |
| 253 | value={ alignmentTablet } |
| 254 | alignmentControls={ ALIGNMENT_CONTROLS } |
| 255 | onChange={ ( value ) => { |
| 256 | setAttributes( { alignmentTablet: value } ); |
| 257 | } } |
| 258 | /> |
| 259 | |
| 260 | <DimensionsControl { ...this.props } |
| 261 | device={ getSelectedDevice( selectedDevice ) } |
| 262 | type={ 'margin' } |
| 263 | label={ __( 'Margin', 'generateblocks' ) } |
| 264 | attrTop={ 'marginTopTablet' } |
| 265 | attrRight={ 'marginRightTablet' } |
| 266 | attrBottom={ 'marginBottomTablet' } |
| 267 | attrLeft={ 'marginLeftTablet' } |
| 268 | attrUnit={ 'marginUnit' } |
| 269 | attrSyncUnits={ 'marginSyncUnits' } |
| 270 | defaults={ generateBlocksDefaults.buttonContainer } |
| 271 | /> |
| 272 | |
| 273 | <ToggleControl |
| 274 | label={ __( 'Stack Vertically', 'generateblocks' ) } |
| 275 | checked={ !! stackTablet } |
| 276 | onChange={ ( value ) => { |
| 277 | setAttributes( { |
| 278 | stackTablet: value, |
| 279 | } ); |
| 280 | } } |
| 281 | /> |
| 282 | |
| 283 | <ToggleControl |
| 284 | label={ __( 'Fill Horizontal Space', 'generateblocks' ) } |
| 285 | checked={ !! fillHorizontalSpaceTablet } |
| 286 | onChange={ ( value ) => { |
| 287 | setAttributes( { |
| 288 | fillHorizontalSpaceTablet: value, |
| 289 | } ); |
| 290 | } } |
| 291 | /> |
| 292 | </Fragment> |
| 293 | ) } |
| 294 | |
| 295 | { 'mobile' === getSelectedDevice( selectedDevice ) && ( |
| 296 | <Fragment> |
| 297 | <AlignmentToolbar |
| 298 | isCollapsed={ false } |
| 299 | value={ alignmentMobile } |
| 300 | alignmentControls={ ALIGNMENT_CONTROLS } |
| 301 | onChange={ ( value ) => { |
| 302 | setAttributes( { alignmentMobile: value } ); |
| 303 | } } |
| 304 | /> |
| 305 | |
| 306 | <DimensionsControl { ...this.props } |
| 307 | device={ getSelectedDevice( selectedDevice ) } |
| 308 | type={ 'margin' } |
| 309 | label={ __( 'Margin', 'generateblocks' ) } |
| 310 | attrTop={ 'marginTopMobile' } |
| 311 | attrRight={ 'marginRightMobile' } |
| 312 | attrBottom={ 'marginBottomMobile' } |
| 313 | attrLeft={ 'marginLeftMobile' } |
| 314 | attrUnit={ 'marginUnit' } |
| 315 | attrSyncUnits={ 'marginSyncUnits' } |
| 316 | defaults={ generateBlocksDefaults.buttonContainer } |
| 317 | /> |
| 318 | |
| 319 | <ToggleControl |
| 320 | label={ __( 'Stack Vertically', 'generateblocks' ) } |
| 321 | checked={ !! stackMobile } |
| 322 | onChange={ ( value ) => { |
| 323 | setAttributes( { |
| 324 | stackMobile: value, |
| 325 | } ); |
| 326 | } } |
| 327 | /> |
| 328 | |
| 329 | <ToggleControl |
| 330 | label={ __( 'Fill Horizontal Space', 'generateblocks' ) } |
| 331 | checked={ !! fillHorizontalSpaceMobile } |
| 332 | onChange={ ( value ) => { |
| 333 | setAttributes( { |
| 334 | fillHorizontalSpaceMobile: value, |
| 335 | } ); |
| 336 | } } |
| 337 | /> |
| 338 | </Fragment> |
| 339 | ) } |
| 340 | |
| 341 | { applyFilters( 'generateblocks.editor.controls', '', 'buttonContainerSpacing', this.props, this.state ) } |
| 342 | </PanelArea> |
| 343 | |
| 344 | <PanelArea { ...this.props } |
| 345 | title={ __( 'Advanced', 'generateblocks' ) } |
| 346 | initialOpen={ false } |
| 347 | icon={ getIcon( 'advanced' ) } |
| 348 | className={ 'gblocks-panel-label' } |
| 349 | id={ 'buttonContainerAdvanced' } |
| 350 | state={ this.state } |
| 351 | showPanel={ 'desktop' === getSelectedDevice( selectedDevice ) || false } |
| 352 | > |
| 353 | <TextControl |
| 354 | label={ __( 'Element ID', 'generateblocks' ) } |
| 355 | value={ elementId } |
| 356 | onChange={ ( value ) => { |
| 357 | const newElementId = value.replace( ELEMENT_ID_REGEX, '-' ); |
| 358 | |
| 359 | setAttributes( { |
| 360 | elementId: newElementId, |
| 361 | } ); |
| 362 | } } |
| 363 | /> |
| 364 | |
| 365 | <TextControl |
| 366 | label={ __( 'CSS Classes', 'generateblocks' ) } |
| 367 | value={ cssClasses } |
| 368 | onChange={ ( value ) => { |
| 369 | setAttributes( { |
| 370 | cssClasses: value, |
| 371 | } ); |
| 372 | } } |
| 373 | /> |
| 374 | |
| 375 | { applyFilters( 'generateblocks.editor.controls', '', 'buttonContainerAdvanced', this.props, this.state ) } |
| 376 | </PanelArea> |
| 377 | |
| 378 | <PanelArea { ...this.props } |
| 379 | title={ __( 'Documentation', 'generateblocks' ) } |
| 380 | icon={ getIcon( 'documentation' ) } |
| 381 | initialOpen={ false } |
| 382 | className={ 'gblocks-panel-label' } |
| 383 | id={ 'buttonContainerDocumentation' } |
| 384 | state={ this.state } |
| 385 | > |
| 386 | <p>{ __( 'Need help with this block?', 'generateblocks' ) }</p> |
| 387 | <a href="https://docs.generateblocks.com/collection/buttons/" target="_blank" rel="noreferrer noopener">{ __( 'Visit our documentation', 'generateblocks' ) }</a> |
| 388 | |
| 389 | { applyFilters( 'generateblocks.editor.controls', '', 'buttonContainerDocumentation', this.props, this.state ) } |
| 390 | </PanelArea> |
| 391 | </InspectorControls> |
| 392 | |
| 393 | <DesktopCSS { ...this.props } /> |
| 394 | |
| 395 | <div |
| 396 | { ...htmlAttributes } |
| 397 | > |
| 398 | <InnerBlocks |
| 399 | allowedBlocks={ [ 'generateblocks/button' ] } |
| 400 | renderAppender={ () => ( |
| 401 | <Tooltip text={ __( 'Add Button', 'generateblocks' ) }> |
| 402 | <Button |
| 403 | className="gblocks-add-new-button gblocks-button-container-appender" |
| 404 | icon={ 'insert' } |
| 405 | onClick={ () => { |
| 406 | wp.data.dispatch( 'core/block-editor' ).insertBlocks( createBlock( 'generateblocks/button', generateBlocksStyling.button ), undefined, clientId ); |
| 407 | } } |
| 408 | /> |
| 409 | </Tooltip> |
| 410 | ) } |
| 411 | /> |
| 412 | </div> |
| 413 | </Fragment> |
| 414 | ); |
| 415 | } |
| 416 | } |
| 417 | |
| 418 | export default ( GenerateButtonContainer ); |
| 419 |