Skip to content

Commit

Permalink
Blocks: Calendly block (#14252)
Browse files Browse the repository at this point in the history
* Add caldendly block

* update the example

* fix wrong file name
  • Loading branch information
scruffian authored and jeherve committed Jan 16, 2020
1 parent 0addb54 commit 2c3dbd9
Show file tree
Hide file tree
Showing 11 changed files with 916 additions and 1 deletion.
90 changes: 90 additions & 0 deletions extensions/blocks/calendly/attributes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* External Dependencies
*/
import { reduce } from 'lodash';
import { __ } from '@wordpress/i18n';

const hexRegex = /^#?[A-Fa-f0-9]{6}$/;

const colourValidator = value => hexRegex.test( value );

const urlValidator = url => ! url || url.startsWith( 'https://calendly.com/' );

export default {
backgroundColor: {
type: 'string',
default: 'ffffff',
validator: colourValidator,
},
submitButtonText: {
type: 'string',
default: __( 'Schedule time with me', 'jetpack' ),
},
submitButtonTextColor: {
type: 'string',
validator: colourValidator,
},
submitButtonBackgroundColor: {
type: 'string',
validator: colourValidator,
},
submitButtonClasses: { type: 'string' },
hideEventTypeDetails: {
type: 'boolean',
default: false,
},
primaryColor: {
type: 'string',
default: '00A2FF',
validator: colourValidator,
},
textColor: {
type: 'string',
default: '4D5055',
validator: colourValidator,
},
style: {
type: 'string',
default: 'inline',
validValues: [ 'inline', 'link' ],
},
url: {
type: 'string',
validator: urlValidator,
},
backgroundButtonColor: {
type: 'string',
},
textButtonColor: {
type: 'string',
},
customBackgroundButtonColor: {
type: 'string',
validator: colourValidator,
},
customTextButtonColor: {
type: 'string',
validator: colourValidator,
},
};

export const getValidatedAttributes = ( attributeDetails, attributes ) =>
reduce(
attributes,
( ret, attribute, attributeKey ) => {
const { type, validator, validValues, default: defaultVal } = attributeDetails[
attributeKey
];
if ( 'boolean' === type ) {
ret[ attributeKey ] = !! attribute;
} else if ( validator ) {
ret[ attributeKey ] = validator( attribute ) ? attribute : defaultVal;
} else if ( validValues ) {
ret[ attributeKey ] = validValues.includes( attribute ) ? attribute : defaultVal;
} else {
ret[ attributeKey ] = attribute;
}
return ret;
},
{}
);
72 changes: 72 additions & 0 deletions extensions/blocks/calendly/blockStylesPreviewAndSelector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* External Dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { getBlockType, cloneBlock, getBlockFromExample } from '@wordpress/blocks';
import { BlockPreview } from '@wordpress/block-editor';
import { useSelect } from '@wordpress/data';
import { ENTER, SPACE } from '@wordpress/keycodes';

export default function BlockStylesPreviewAndSelector( {
attributes,
clientId,
styleOptions,
onSelectStyle,
activeStyle,
} ) {
const block = useSelect( select => {
const { getBlock } = select( 'core/block-editor' );
return getBlock( clientId );
} );

const type = getBlockType( block.name );

return (
<div className="block-editor-block-styles">
{ styleOptions.map( styleOption => {
return (
<div
key={ styleOption.name }
className={ classnames( 'block-editor-block-styles__item', {
'is-active': styleOption.name === activeStyle,
} ) }
onClick={ () => {
onSelectStyle( { style: styleOption.name } );
} }
onKeyDown={ event => {
if ( ENTER === event.keyCode || SPACE === event.keyCode ) {
event.preventDefault();
onSelectStyle( { style: styleOption.name } );
}
} }
role="button"
tabIndex="0"
aria-label={ styleOption.label }
>
<div className="block-editor-block-styles__item-preview editor-styles-wrapper">
<BlockPreview
viewportWidth={ 500 }
blocks={
type.example
? getBlockFromExample( block.name, {
attributes: { ...type.example.attributes, style: styleOption.name },
innerBlocks: type.example.innerBlocks,
} )
: cloneBlock( block, {
...attributes,
style: styleOption.name,
} )
}
/>
</div>
<div className="block-editor-block-styles__item-label">{ styleOption.label }</div>
</div>
);
} ) }
</div>
);
}
123 changes: 123 additions & 0 deletions extensions/blocks/calendly/calendly.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php
/**
* Calendly Block.
*
* @since 8.2.0
*
* @package Jetpack
*/

jetpack_register_block(
'jetpack/calendly',
array( 'render_callback' => 'jetpack_calendly_block_load_assets' )
);

/**
* Calendly block registration/dependency declaration.
*
* @param array $attr Array containing the Calendly block attributes.
* @param string $content String containing the Calendly block content.
*
* @return string
*/
function jetpack_calendly_block_load_assets( $attr, $content ) {
$url = jetpack_calendly_block_get_attribute( $attr, 'url' );
if ( empty( $url ) ) {
return;
}

/*
* Enqueue necessary scripts and styles.
*/
Jetpack_Gutenberg::load_assets_as_required( 'calendly' );
wp_enqueue_script(
'jetpack-calendly-external-js',
'https://assets.calendly.com/assets/external/widget.js',
null,
JETPACK__VERSION,
false
);

$style = jetpack_calendly_block_get_attribute( $attr, 'style' );
$hide_event_type_details = jetpack_calendly_block_get_attribute( $attr, 'hideEventTypeDetails' );
$background_color = jetpack_calendly_block_get_attribute( $attr, 'backgroundColor' );
$text_color = jetpack_calendly_block_get_attribute( $attr, 'textColor' );
$primary_color = jetpack_calendly_block_get_attribute( $attr, 'primaryColor' );
$submit_button_text = jetpack_calendly_block_get_attribute( $attr, 'submitButtonText' );
$submit_button_text_color = jetpack_calendly_block_get_attribute( $attr, 'customTextButtonColor' );
$submit_button_background_color = jetpack_calendly_block_get_attribute( $attr, 'customBackgroundButtonColor' );
$classes = Jetpack_Gutenberg::block_classes( 'calendly', $attr );

$url = add_query_arg(
array(
'hide_event_type_details' => (int) $hide_event_type_details,
'background_color' => sanitize_hex_color_no_hash( $background_color ),
'text_color' => sanitize_hex_color_no_hash( $text_color ),
'primary_color' => sanitize_hex_color_no_hash( $primary_color ),
),
$url
);

if ( 'link' === $style ) {
wp_enqueue_style( 'jetpack-calendly-external-css', 'https://assets.calendly.com/assets/external/widget.css', null, JETPACK__VERSION );

/*
* If we have some additional styles from the editor
* (a custom text color, custom bg color, or both )
* Let's add that CSS inline.
*/
if ( ! empty( $submit_button_text_color ) || ! empty( $submit_button_background_color ) ) {
$inline_styles = sprintf(
'.wp-block-jetpack-calendly .button{%1$s%2$s}',
! empty( $submit_button_text_color )
? 'color:#' . sanitize_hex_color_no_hash( $submit_button_text_color ) . ';'
: '',
! empty( $submit_button_background_color )
? 'background-color:#' . sanitize_hex_color_no_hash( $submit_button_background_color ) . ';'
: ''
);
wp_add_inline_style( 'jetpack-calendly-external-css', $inline_styles );
}

$content = sprintf(
'<div class="%1$s"><a class="button" href="" onclick="Calendly.initPopupWidget({url:\'%2$s\'});return false;">%3$s</a></div>',
esc_attr( $classes ),
esc_url( $url ),
esc_html( $submit_button_text )
);
} else { // Button style.
$content = sprintf(
'<div class="calendly-inline-widget %1$s" data-url="%2$s" style="min-width:320px;height:630px;"></div>',
esc_attr( $classes ),
esc_url( $url )
);
}

return $content;
}

/**
* Get filtered attributes.
*
* @param array $attributes Array containing the Calendly block attributes.
* @param string $attribute_name String containing the attribute name to get.
*
* @return string
*/
function jetpack_calendly_block_get_attribute( $attributes, $attribute_name ) {
if ( isset( $attributes[ $attribute_name ] ) ) {
return $attributes[ $attribute_name ];
}

$default_attributes = array(
'url' => 'url',
'style' => 'inline',
'submitButtonText' => esc_html__( 'Schedule time with me', 'jetpack' ),
'backgroundColor' => 'ffffff',
'textColor' => '4D5055',
'primaryColor' => '00A2FF',
'hideEventTypeDetails' => false,
);

return $default_attributes[ $attribute_name ];
}
Loading

0 comments on commit 2c3dbd9

Please sign in to comment.