import * as React from "react" ; import '../../calendly-widget.css' ; import { loadScript , PageSettings , withPageSettings , Prefill , Utm , } from "../../calendly" ; export interface Props { url : string ; prefill ? : Prefill ; utm ? : Utm ; styles ? : React . CSSProperties | undefined ; pageSettings ? : PageSettings ; } export interface InlineWidgetOptions { url : string ; parentElement : HTMLElement ; prefill ? : Prefill ; utm ? : Utm ; } const defaultStyles = { minWidth : "320px" , height : "630px" , } ; class InlineWidget extends React . Component < Props > { private readonly widgetParentContainerRef : React . RefObject < HTMLDivElement > ; constructor ( props ) { super ( props ) ; this . widgetParentContainerRef = React . createRef < HTMLDivElement > ( ) ; this . destroyInlineWidget = this . destroyInlineWidget . bind ( this ) ; this . getChildNodeCount = this . getChildNodeCount . bind ( this ) ; this . shouldWidgetUpdate = this . shouldWidgetUpdate . bind ( this ) ; this . initWidget = this . initWidget . bind ( this ) ; } componentDidUpdate ( prevProps ) { const shouldUpdate = this . shouldWidgetUpdate ( prevProps ) ; if ( shouldUpdate ) { if ( ! this . getChildNodeCount ( ) ) { this . calendlyWidgetListener ( "inserted" , ( ) => { this . calendlyWidgetListener ( "removed" , this . initWidget ) ; this . destroyInlineWidget ( ) ; } ) ; } else { this . destroyInlineWidget ( ) ; this . initWidget ( ) ; } } } componentDidMount ( ) { loadScript ( ) ; window . Calendly . initInlineWidget ( { url : withPageSettings ( this . props . url , this . props . pageSettings ) , parentElement : this . widgetParentContainerRef . current ! , prefill : this . props . prefill , utm : this . props . utm , } ) ; } render ( ) { return ( < div className = "calendly-inline-widget" style = { this . props . styles || defaultStyles } ref = { this . widgetParentContainerRef } data - auto - load = "false" > < /div>); } private destroyInlineWidget ( ) { this . widgetParentContainerRef . current ! . innerHTML = "" ; } private getChildNodeCount ( ) { return this . widgetParentContainerRef . current ! . childNodes . length ; } private initWidget ( ) { window . Calendly . initInlineWidget ( { url : withPageSettings ( this . props . url , this . props . pageSettings ) , parentElement : this . widgetParentContainerRef . current ! , prefill : this . props . prefill , utm : this . props . utm , } ) ; } private calendlyWidgetListener ( event , callback ) { const isInsertedEvent = event === "inserted" ; const isRemovedEvent = event === "removed" ; return new MutationObserver ( ( mutationsList , observer ) => { observer . disconnect ( ) ; if ( isInsertedEvent ) { const nodesAdded = mutationsList . some ( ( record ) => ! ! record . addedNodes . length ) ; if ( nodesAdded ) callback ( ) ; } if ( isRemovedEvent ) { const nodesRemoved = mutationsList . some ( ( record ) => ! ! record . removedNodes . length ) ; if ( nodesRemoved ) callback ( ) ; } } ) . observe ( this . widgetParentContainerRef . current ! , { childList : true , } ) ; } private shouldWidgetUpdate ( prevProps ) { return ( prevProps . url !== this . props . url || [ "pageSettings" , "prefill" , "utm" ] . some ( ( prop ) => JSON . stringify ( prevProps [ prop ] ) !== JSON . stringify ( this . props [ prop ] ) ) ) ; } } export default InlineWidget ;