diff --git a/extensions/blocks/calendly/attributes.js b/extensions/blocks/calendly/attributes.js
new file mode 100644
index 0000000000000..be78741617c68
--- /dev/null
+++ b/extensions/blocks/calendly/attributes.js
@@ -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;
+ },
+ {}
+ );
diff --git a/extensions/blocks/calendly/blockStylesPreviewAndSelector.js b/extensions/blocks/calendly/blockStylesPreviewAndSelector.js
new file mode 100644
index 0000000000000..5248c13e0d090
--- /dev/null
+++ b/extensions/blocks/calendly/blockStylesPreviewAndSelector.js
@@ -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 (
+
+ { styleOptions.map( styleOption => {
+ return (
+
{
+ 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 }
+ >
+
+
+
+
{ styleOption.label }
+
+ );
+ } ) }
+
+ );
+}
diff --git a/extensions/blocks/calendly/calendly.php b/extensions/blocks/calendly/calendly.php
new file mode 100644
index 0000000000000..d327d20058359
--- /dev/null
+++ b/extensions/blocks/calendly/calendly.php
@@ -0,0 +1,123 @@
+ '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(
+ '',
+ esc_attr( $classes ),
+ esc_url( $url ),
+ esc_html( $submit_button_text )
+ );
+ } else { // Button style.
+ $content = sprintf(
+ '',
+ 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 ];
+}
diff --git a/extensions/blocks/calendly/edit.js b/extensions/blocks/calendly/edit.js
new file mode 100644
index 0000000000000..9eefd50951f91
--- /dev/null
+++ b/extensions/blocks/calendly/edit.js
@@ -0,0 +1,253 @@
+/**
+ * External Dependencies
+ */
+import 'url-polyfill';
+import { isEqual } from 'lodash';
+import queryString from 'query-string';
+
+/**
+ * WordPress dependencies
+ */
+import { BlockControls, BlockIcon, InspectorControls } from '@wordpress/block-editor';
+import {
+ Button,
+ ExternalLink,
+ Notice,
+ PanelBody,
+ Placeholder,
+ ToggleControl,
+ Toolbar,
+} from '@wordpress/components';
+import { useState } from '@wordpress/element';
+import { __, _x } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies
+ */
+import './editor.scss';
+import icon from './icon';
+import attributeDetails, { getValidatedAttributes } from './attributes';
+import SubmitButton from '../../shared/submit-button';
+import { getAttributesFromEmbedCode } from './utils';
+import BlockStylesPreviewAndSelector from './blockStylesPreviewAndSelector';
+
+export default function CalendlyEdit( { attributes, className, clientId, setAttributes } ) {
+ const validatedAttributes = getValidatedAttributes( attributeDetails, attributes );
+
+ if ( ! isEqual( validatedAttributes, attributes ) ) {
+ setAttributes( validatedAttributes );
+ }
+
+ const {
+ backgroundColor,
+ submitButtonText,
+ hideEventTypeDetails,
+ primaryColor,
+ textColor,
+ style,
+ url,
+ } = validatedAttributes;
+ const [ embedCode, setEmbedCode ] = useState( '' );
+ const [ notice, setNotice ] = useState();
+
+ const setErrorNotice = () =>
+ setNotice(
+ <>
+ { __(
+ "Your calendar couldn't be embedded. Please double check your URL or code.",
+ 'jetpack'
+ ) }
+ >
+ );
+
+ const parseEmbedCode = event => {
+ if ( ! event ) {
+ setErrorNotice();
+ return;
+ }
+
+ event.preventDefault();
+
+ const newAttributes = getAttributesFromEmbedCode( embedCode );
+ if ( ! newAttributes ) {
+ setErrorNotice();
+ return;
+ }
+
+ const newValidatedAttributes = getValidatedAttributes( attributeDetails, newAttributes );
+
+ setAttributes( newValidatedAttributes );
+ };
+
+ const embedCodeForm = (
+
+ );
+
+ const blockPlaceholder = (
+ }
+ notices={
+ notice && (
+
+ { notice }
+
+ )
+ }
+ >
+ { embedCodeForm }
+
+ );
+
+ const iframeSrc = () => {
+ const query = queryString.stringify( {
+ embed_domain: 'wordpress.com',
+ embed_type: 'Inline',
+ hide_event_type_details: hideEventTypeDetails ? 1 : 0,
+ background_color: backgroundColor,
+ primary_color: primaryColor,
+ text_color: textColor,
+ } );
+ return `${ url }?${ query }`;
+ };
+
+ const inlinePreview = (
+ <>
+
+
+ >
+ );
+
+ const submitButtonPreview = (
+
+ );
+
+ const linkPreview = (
+ <>
+
+ { submitButtonText }
+
+ >
+ );
+
+ const blockPreview = ( previewStyle, disabled ) => {
+ if ( previewStyle === 'inline' ) {
+ return inlinePreview;
+ }
+
+ if ( disabled ) {
+ return linkPreview;
+ }
+
+ return submitButtonPreview;
+ };
+
+ const styleOptions = [
+ { name: 'inline', label: __( 'Inline', 'jetpack' ) },
+ { name: 'link', label: __( 'Link', 'jetpack' ) },
+ ];
+
+ const blockControls = (
+
+ { url && (
+ ( {
+ title: styleOption.label,
+ isActive: styleOption.name === style,
+ onClick: () => setAttributes( { style: styleOption.name } ),
+ } ) ) }
+ popoverProps={ { className: 'is-calendly' } }
+ />
+ ) }
+
+ );
+
+ const inspectorControls = (
+
+ { url && (
+ <>
+
+
+
+ >
+ ) }
+
+
+
+
+ setAttributes( { hideEventTypeDetails: ! hideEventTypeDetails } ) }
+ />
+
+
+ );
+
+ return (
+ <>
+ { inspectorControls }
+ { blockControls }
+ { url ? blockPreview( style ) : blockPlaceholder }
+ >
+ );
+}
diff --git a/extensions/blocks/calendly/editor.js b/extensions/blocks/calendly/editor.js
new file mode 100644
index 0000000000000..d05f403942058
--- /dev/null
+++ b/extensions/blocks/calendly/editor.js
@@ -0,0 +1,7 @@
+/**
+ * Internal dependencies
+ */
+import registerJetpackBlock from '../../shared/register-jetpack-block';
+import { name, settings } from '.';
+
+registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/calendly/editor.scss b/extensions/blocks/calendly/editor.scss
new file mode 100644
index 0000000000000..20358deff4128
--- /dev/null
+++ b/extensions/blocks/calendly/editor.scss
@@ -0,0 +1,31 @@
+/**
+ * Editor styles for Calendly
+ */
+
+.wp-block-jetpack-calendly {
+ &-overlay {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ z-index: 10;
+ }
+
+ &-link-editable {
+ cursor: text;
+ }
+
+ &-embed-form-sidebar {
+ display: flex;
+ margin-bottom: 1em;
+ }
+
+ &-learn-more {
+ margin-top: 1em;
+ }
+}
+
+.is-calendly {
+ .is-active {
+ font-weight: bold;
+ }
+}
diff --git a/extensions/blocks/calendly/icon.js b/extensions/blocks/calendly/icon.js
new file mode 100644
index 0000000000000..0547b1c73799d
--- /dev/null
+++ b/extensions/blocks/calendly/icon.js
@@ -0,0 +1,26 @@
+/**
+ * External dependencies
+ */
+import { SVG, G, Path, Rect } from '@wordpress/components';
+
+export default (
+
+);
diff --git a/extensions/blocks/calendly/index.js b/extensions/blocks/calendly/index.js
new file mode 100644
index 0000000000000..98e5a40778420
--- /dev/null
+++ b/extensions/blocks/calendly/index.js
@@ -0,0 +1,44 @@
+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies
+ */
+import attributes from './attributes';
+import edit from './edit';
+import icon from './icon';
+
+/**
+ * Style dependencies
+ */
+import './editor.scss';
+
+export const name = 'calendly';
+export const title = __( 'Calendly', 'jetpack' );
+export const settings = {
+ title,
+ description: __( 'Embed a calendar for customers to schedule appointments', 'jetpack' ),
+ icon,
+ category: 'jetpack',
+ keywords: [
+ __( 'calendar', 'jetpack' ),
+ __( 'schedule', 'jetpack' ),
+ __( 'appointments', 'jetpack' ),
+ ],
+ supports: {
+ html: false,
+ },
+ edit,
+ save: () => null,
+ attributes,
+ example: {
+ attributes: {
+ submitButtonText: __( 'Schedule time with me', 'jetpack' ),
+ hideEventTypeDetails: false,
+ style: 'inline',
+ url: 'https://calendly.com/wordpresscom/jetpack-block-example',
+ },
+ },
+};
diff --git a/extensions/blocks/calendly/test/utils.js b/extensions/blocks/calendly/test/utils.js
new file mode 100644
index 0000000000000..b95cc34b8893f
--- /dev/null
+++ b/extensions/blocks/calendly/test/utils.js
@@ -0,0 +1,158 @@
+/**
+ * External dependencies
+ */
+
+/**
+ * Internal dependencies
+ */
+import { getAttributesFromEmbedCode } from '../utils';
+
+const inlineEmbedCode = '' +
+ '' +
+ '' +
+ '';
+
+const widgetEmbedCode = '' +
+ '' +
+ '' +
+ '' +
+ '';
+
+const textEmbedCode = '' +
+ '' +
+ '' +
+ 'Schedule time with me' +
+ '';
+
+const customInlineEmbedCode = '' +
+ '' +
+ '' +
+ '';
+
+const customWidgetEmbedCode = '' +
+ '' +
+ '' +
+ '' +
+ '';
+
+const customTextEmbedCode = '' +
+ '' +
+ '' +
+ 'Schedule some time with me' +
+ '';
+
+describe( 'getAttributesFromEmbedCode', () => {
+ test( 'URL with http', () => {
+ expect(
+ getAttributesFromEmbedCode( 'https://calendly.com/wordpresscom/jetpack-block-example' )
+ ).toEqual(
+ {
+ "url": "https://calendly.com/wordpresscom/jetpack-block-example"
+ }
+ );
+ } );
+
+ test( 'URL without http', () => {
+ expect(
+ getAttributesFromEmbedCode( 'calendly.com/wordpresscom/jetpack-block-example' )
+ ).toEqual(
+ {
+ "url": "https://calendly.com/wordpresscom/jetpack-block-example"
+ }
+ );
+ } );
+
+ test( 'URL with query string', () => {
+ expect(
+ getAttributesFromEmbedCode( '//calendly.com/wordpresscom/jetpack-block-example?month=2020-01' )
+ ).toEqual(
+ {
+ "url": "https://calendly.com/wordpresscom/jetpack-block-example"
+ }
+ );
+ } );
+
+ test( 'Inline embed code', () => {
+ expect(
+ getAttributesFromEmbedCode( inlineEmbedCode )
+ ).toEqual(
+ {
+ "style": "inline",
+ "url": "https://calendly.com/wordpresscom/jetpack-block-example"
+ }
+ );
+ } );
+
+ test( 'Widget embed code', () => {
+ expect(
+ getAttributesFromEmbedCode( widgetEmbedCode )
+ ).toEqual(
+ {
+ "style": "link",
+ "submitButtonText": "Schedule time with me",
+ "customBackgroundButtonColor": "#00a2ff",
+ "customTextButtonColor": "#ffffff",
+ "url": "https://calendly.com/wordpresscom/jetpack-block-example"
+ }
+ );
+ } );
+
+ test( 'Text embed code', () => {
+ expect(
+ getAttributesFromEmbedCode( textEmbedCode )
+ ).toEqual(
+ {
+ "style": "link",
+ "submitButtonText": "Schedule time with me",
+ "url": "https://calendly.com/wordpresscom/jetpack-block-example"
+ }
+ );
+ } );
+
+ test( 'Customised inline embed code', () => {
+ expect(
+ getAttributesFromEmbedCode( customInlineEmbedCode )
+ ).toEqual(
+ {
+ "backgroundColor": "691414",
+ "hideEventTypeDetails": "1",
+ "primaryColor": "1d6e9c",
+ "style": "inline",
+ "textColor": "2051a3",
+ "url": "https://calendly.com/wordpresscom/jetpack-block-example"
+ }
+ );
+ } );
+
+ test( 'Customised widget embed code', () => {
+ expect(
+ getAttributesFromEmbedCode( customWidgetEmbedCode )
+ ).toEqual(
+ {
+ "backgroundColor": "c51414",
+ "customBackgroundButtonColor": "#000609",
+ "customTextButtonColor": "#b50000",
+ "primaryColor": "1d73a4",
+ "style": "link",
+ "submitButtonText": "Schedule some time with me",
+ "textColor": "2563ca",
+ "url": "https://calendly.com/wordpresscom/jetpack-block-example"
+ }
+ );
+ } );
+
+ test( 'Customised text embed code', () => {
+ expect(
+ getAttributesFromEmbedCode( customTextEmbedCode )
+ ).toEqual(
+ {
+ "backgroundColor": "e32424",
+ "primaryColor": "0e425f",
+ "style": "link",
+ "submitButtonText": "Schedule some time with me",
+ "textColor": "2a74ef",
+ "url": "https://calendly.com/wordpresscom/jetpack-block-example"
+ }
+ );
+ } )
+} );
diff --git a/extensions/blocks/calendly/utils.js b/extensions/blocks/calendly/utils.js
new file mode 100644
index 0000000000000..b1cac47a8ac09
--- /dev/null
+++ b/extensions/blocks/calendly/utils.js
@@ -0,0 +1,111 @@
+export const getURLFromEmbedCode = embedCode => {
+ const url = embedCode.match( /(? {
+ let submitButtonText = embedCode.match( /(?<=false;"\>).+(?=<\/)/ );
+ if ( submitButtonText ) {
+ return submitButtonText[ 0 ];
+ }
+
+ submitButtonText = embedCode.match( /(?<=text: ').*?(?=')/ );
+ if ( submitButtonText ) {
+ return submitButtonText[ 0 ];
+ }
+};
+
+const getSubmitButtonTextColorFromEmbedCode = embedCode => {
+ const submitButtonTextColor = embedCode.match( /(?<= textColor: ').*?(?=')/ );
+ if ( submitButtonTextColor ) {
+ return submitButtonTextColor[ 0 ];
+ }
+};
+
+const getSubmitButtonBackgroundColorFromEmbedCode = embedCode => {
+ const submitButtonBackgroundColor = embedCode.match( /(?<= color: ').*?(?=')/ );
+ if ( submitButtonBackgroundColor ) {
+ return submitButtonBackgroundColor[ 0 ];
+ }
+};
+
+export const getAttributesFromUrl = url => {
+ const attributes = {};
+ const urlObject = new URL( url );
+ attributes.url = urlObject.origin + urlObject.pathname;
+
+ if ( ! urlObject.search ) {
+ return attributes;
+ }
+
+ const searchParams = new URLSearchParams( urlObject.search );
+ const backgroundColor = searchParams.get( 'background_color' );
+ const primaryColor = searchParams.get( 'primary_color' );
+ const textColor = searchParams.get( 'text_color' );
+ const hexRegex = /^[A-Za-z0-9]{6}$/;
+
+ if ( searchParams.get( 'hide_event_type_details' ) ) {
+ attributes.hideEventTypeDetails = searchParams.get( 'hide_event_type_details' );
+ }
+
+ if ( backgroundColor && backgroundColor.match( hexRegex ) ) {
+ attributes.backgroundColor = backgroundColor;
+ }
+
+ if ( primaryColor && primaryColor.match( hexRegex ) ) {
+ attributes.primaryColor = primaryColor;
+ }
+
+ if ( textColor && textColor.match( hexRegex ) ) {
+ attributes.textColor = textColor;
+ }
+
+ return attributes;
+};
+
+const getStyleFromEmbedCode = embedCode => {
+ if ( embedCode.indexOf( 'data-url' ) > 0 ) {
+ return 'inline';
+ }
+
+ if ( embedCode.indexOf( 'initPopupWidget' ) > 0 || embedCode.indexOf( 'initBadgeWidget' ) > 0 ) {
+ return 'link';
+ }
+};
+
+export const getAttributesFromEmbedCode = embedCode => {
+ if ( ! embedCode ) {
+ return;
+ }
+
+ const newUrl = getURLFromEmbedCode( embedCode );
+ if ( ! newUrl ) {
+ return;
+ }
+
+ const newAttributes = getAttributesFromUrl( newUrl );
+
+ const newStyle = getStyleFromEmbedCode( embedCode );
+ if ( newStyle ) {
+ newAttributes.style = newStyle;
+ }
+
+ const submitButtonText = getSubmitButtonTextFromEmbedCode( embedCode );
+ if ( submitButtonText ) {
+ newAttributes.submitButtonText = submitButtonText;
+ }
+
+ const submitButtonTextColor = getSubmitButtonTextColorFromEmbedCode( embedCode );
+ if ( submitButtonTextColor ) {
+ newAttributes.customTextButtonColor = submitButtonTextColor;
+ }
+
+ const submitButtonBackgroundColor = getSubmitButtonBackgroundColorFromEmbedCode( embedCode );
+ if ( submitButtonBackgroundColor ) {
+ newAttributes.customBackgroundButtonColor = submitButtonBackgroundColor;
+ }
+
+ return newAttributes;
+};
diff --git a/extensions/index.json b/extensions/index.json
index 454fd3e95f9f6..551d29858d682 100644
--- a/extensions/index.json
+++ b/extensions/index.json
@@ -23,5 +23,5 @@
"videopress",
"wordads"
],
- "beta": [ "seo", "opentable" ]
+ "beta": [ "seo", "opentable", "calendly" ]
}