{"version":3,"file":"GhlBookingEmbed.CHR7f4cS.mjs","names":["useRef","useState","useEffect","useLayoutEffect","__esmMin","init_npm_react_18_3_1","le","window","ce","c","init_jsx_runtime","_e","de","init_ssg_sandbox_shims","useIsStaticRenderer","addPropertyControls","ControlType","init_framer_DKWANagr","bookingId","m","url","reportedHeight","data","SIZER","parts","frameId","NOT_A_SIZE","h","GhlBookingEmbed","props","isStatic","id","bookingUrl","frameRef","contentH","setContentH","boxRef","box","setBox","matchBreakpoints","el","measure","w","vw","b","ro","fitContent","answered","onMessage","f","e","tries","ask","sizerInit","timer","keepPageStill","lastY","lastScrollAt","lastInputAt","restoring","onInput","onScroll","now","y","JUMP_MIN","IDLE_MS","INPUT_MS","opts","inputs","t","renderW","min","max","desktopFrom","GHL_THREE_COL","tabletFrom","GHL_STACKED","scale","maxInner","widgetHeight","innerH","FIRST_GUESS","height","ease","style","init_GhlBookingEmbed","p"],"sources":["https:/framerusercontent.com/modules/XiNvvDUuogOAF62djlHs/ZbB4M2VJIEcJUlANFxc8/GhlBookingEmbed.js"],"sourcesContent":["// GoHighLevel booking widget (Contact Us and Book a Demo).\n//\n// Size: the GHL widget speaks the iframe-resizer protocol (the same one GHL's own\n// form_embed.js uses). We send it the setup message and it replies with the true height\n// of its current step every time that changes. (Its \"highlevel.setHeight\" message is not\n// usable: it reports the visible area, so the widget would keep growing.)\n// With \"Fit Content\" on, the widget takes that height, so nothing is cut off and there is\n// no second scrollbar, but never more than \"Max Height\": a taller step (GHL's long phone\n// list of times) scrolls inside the widget instead of stretching the page.\n// With \"Fit Content\" off, the widget is always exactly \"Max Height\" and scrolls inside.\n//\n// \"Match Breakpoints\": GHL picks its layout from the widget's own width (phone list under\n// 726px, stacked from 726px, three columns from 982px), which never lines up with the\n// Framer breakpoints. So we read the Framer breakpoint from the screen width (Desktop from\n// 1080, Tablet from 810, Phone below) and load GHL at a width that gives the matching\n// layout, then scale it to fill the space exactly (at most about 10% at the edges).\n//\n// \"Keep Page Still\": at every step GHL calls scrollIntoView inside the widget, and the\n// browser carries that scroll up to our page, snapping the widget to the top of the\n// screen. We can't change GHL's code, so we watch for that one sudden jump (the widget\n// has focus, nobody touched the page, and the page goes from still to a big leap in one\n// frame) and put the page back where it was. Normal scrolling starts with small steps\n// and is never touched.\nimport{jsx as _jsx}from\"react/jsx-runtime\";import{addPropertyControls,ControlType,useIsStaticRenderer}from\"framer\";import{useEffect,useLayoutEffect,useRef,useState}from\"react\";const JUMP_MIN=24// px: smaller moves are left alone\n;const IDLE_MS=150// the page must have been still this long before the jump\n;const INPUT_MS=400// page input (wheel, touch, keys) this recent means the user is scrolling\n;// GHL layout widths, measured 2026-11-09 (with a little margin): three columns from 982,\n// stacked from 726, phone list below that\nconst GHL_THREE_COL=984;const GHL_STACKED=728;const FIRST_GUESS=820// height before GHL reports (its first step is 800 to 1000 tall)\n;/** The widget id GHL uses: the booking id from the URL */function bookingId(url){const m=url.match(/\\/booking\\/([A-Za-z0-9]+)/);return m?m[1]:\"ghl-booking\";}const SIZER=\"[iFrameSizer]\";// Setup message, same settings GHL's form_embed.js sends: id, body margin, size width, log,\n// interval, public methods, auto resize, margin, height method, background, padding, tolerance\nconst sizerInit=frameId=>`${SIZER}${frameId}:8:false:false:32:true:true:null:offset:null:null:0`;const NOT_A_SIZE=new Set([\"close\",\"message\",\"scrollTo\",\"scrollToOffset\",\"pageInfo\",\"pageInfoStop\",\"inPageLink\",\"reset\",\"autoResize\"]);/** Height from a reply like \"[iFrameSizer]<id>:<height>:<width>:<type>\" */function reportedHeight(data,frameId){if(typeof data!==\"string\"||data.indexOf(SIZER)!==0)return null;const parts=data.slice(SIZER.length).split(\":\");if(parts[0]!==frameId||NOT_A_SIZE.has(parts[3]))return null;const h=Number(parts[1]);return Number.isFinite(h)&&h>100?h:null;}/**\n * GHL Booking Embed\n *\n * @framerIntrinsicWidth 600\n * @framerIntrinsicHeight 820\n *\n * @framerSupportedLayoutWidth fixed\n * @framerSupportedLayoutHeight auto\n */export default function GhlBookingEmbed(props){const{bookingUrl=\"https://api.leadconnectorhq.com/widget/booking/spI8oiDywY6Ny52YqlCS\",widgetHeight=1e3,fitContent=true,keepPageStill=true,matchBreakpoints=true,desktopFrom=1080,tabletFrom=810,style}=props;const isStatic=useIsStaticRenderer();const id=bookingId(bookingUrl);const frameRef=useRef(null);const[contentH,setContentH]=useState(null);const boxRef=useRef(null);const[box,setBox]=useState(null);// Our width and the screen width (for the Framer breakpoint)\nconst useIsoLayoutEffect=typeof window===\"undefined\"?useEffect:useLayoutEffect;useIsoLayoutEffect(()=>{if(!matchBreakpoints||isStatic||typeof window===\"undefined\")return;const el=boxRef.current;if(!el)return;const measure=()=>{const w=el.getBoundingClientRect().width;const vw=window.innerWidth;setBox(b=>b&&Math.abs(b.w-w)<.5&&b.vw===vw?b:{w,vw});};measure();const ro=typeof ResizeObserver!==\"undefined\"?new ResizeObserver(measure):null;ro?.observe(el);window.addEventListener(\"resize\",measure);return()=>{ro?.disconnect();window.removeEventListener(\"resize\",measure);};},[matchBreakpoints,isStatic]);// Ask GHL for its true height and follow it for each step\nuseEffect(()=>{if(!fitContent||isStatic||typeof window===\"undefined\")return;const frameId=`${id}_embed`;let answered=false;const onMessage=e=>{const f=frameRef.current;if(!f||e.source!==f.contentWindow)return;const h=reportedHeight(e.data,frameId);if(h){answered=true;setContentH(Math.ceil(h));}};window.addEventListener(\"message\",onMessage);// The widget only listens once its page has loaded, so keep asking until it answers\n// (it loads lazily, so this can take a while); ask again whenever its page reloads.\nlet tries=0;const ask=()=>frameRef.current?.contentWindow?.postMessage(sizerInit(frameId),\"*\");const timer=window.setInterval(()=>{if(answered||tries++>600)return window.clearInterval(timer);ask();},500);const f=frameRef.current;f?.addEventListener(\"load\",ask);return()=>{window.removeEventListener(\"message\",onMessage);window.clearInterval(timer);f?.removeEventListener(\"load\",ask);};},[fitContent,isStatic,id]);// Undo the page jump GHL causes when it moves to the next step\nuseEffect(()=>{if(!keepPageStill||isStatic||typeof window===\"undefined\")return;let lastY=window.scrollY;let lastScrollAt=0;let lastInputAt=0;let restoring=false;const onInput=()=>{lastInputAt=performance.now();};const onScroll=()=>{const now=performance.now();const y=window.scrollY;if(restoring){restoring=false;}else if(document.activeElement===frameRef.current&&Math.abs(y-lastY)>=JUMP_MIN&&now-lastScrollAt>IDLE_MS&&now-lastInputAt>INPUT_MS){restoring=true;window.scrollTo({top:lastY,behavior:\"instant\"});lastScrollAt=now;return;}lastY=y;lastScrollAt=now;};const opts={passive:true,capture:true};const inputs=[\"wheel\",\"touchstart\",\"touchmove\",\"keydown\",\"pointerdown\"];window.addEventListener(\"scroll\",onScroll,{passive:true});for(const t of inputs)window.addEventListener(t,onInput,opts);return()=>{window.removeEventListener(\"scroll\",onScroll);for(const t of inputs)window.removeEventListener(t,onInput,opts);};},[keepPageStill,isStatic]);// Width GHL is loaded at, so it shows the layout for this Framer breakpoint\nlet renderW=0;if(matchBreakpoints&&box&&box.w>0){const[min,max]=box.vw>=desktopFrom?[GHL_THREE_COL,Infinity]:box.vw>=tabletFrom?[GHL_STACKED,GHL_THREE_COL-6]:[0,GHL_STACKED-6];renderW=Math.min(Math.max(box.w,min),max);}const scale=renderW?box.w/renderW:1;const maxInner=widgetHeight/scale// Max Height is in page pixels\n;const innerH=fitContent?Math.min(contentH??Math.min(FIRST_GUESS,maxInner),maxInner):maxInner;const height=innerH*scale;const ease=\"height 0.25s ease\";return /*#__PURE__*/_jsx(\"div\",{ref:boxRef,style:{...style,position:\"relative\",width:\"100%\",height,overflow:\"hidden\",transition:ease},children:/*#__PURE__*/_jsx(\"iframe\",{ref:frameRef,src:bookingUrl,id:`${id}_embed`,title:\"Book a time with Spacture AI\",allow:\"payment\",loading:\"lazy\",scrolling:\"yes\",style:{display:\"block\",position:\"absolute\",top:0,left:0,width:renderW?renderW:\"100%\",height:innerH,border:\"none\",overflow:\"auto\",transform:scale!==1?`scale(${scale})`:undefined,transformOrigin:\"0 0\",transition:ease}})});}addPropertyControls(GhlBookingEmbed,{bookingUrl:{type:ControlType.String,title:\"Booking URL\",defaultValue:\"https://api.leadconnectorhq.com/widget/booking/spI8oiDywY6Ny52YqlCS\",description:\"The src from GoHighLevel's embed code.\"},fitContent:{type:ControlType.Boolean,title:\"Fit Content\",defaultValue:true,description:\"On: as tall as each step, up to Max Height. Off: always Max Height.\"},widgetHeight:{type:ControlType.Number,title:\"Max Height\",defaultValue:1e3,min:300,max:2e3,step:10,unit:\"px\",description:\"Taller steps scroll inside the widget.\"},matchBreakpoints:{type:ControlType.Boolean,title:\"Match Breakpoints\",defaultValue:true,description:\"Show GHL's three-column layout on Desktop, stacked on Tablet, list on Phone.\"},desktopFrom:{type:ControlType.Number,title:\"Desktop From\",defaultValue:1080,min:600,max:2e3,step:1,unit:\"px\",hidden:p=>!p.matchBreakpoints},tabletFrom:{type:ControlType.Number,title:\"Tablet From\",defaultValue:810,min:300,max:1600,step:1,unit:\"px\",hidden:p=>!p.matchBreakpoints},keepPageStill:{type:ControlType.Boolean,title:\"Keep Page Still\",defaultValue:true,description:\"Stops the page snapping the widget to the top when GHL moves to the next step.\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"GhlBookingEmbed\",\"slots\":[],\"annotations\":{\"framerIntrinsicHeight\":\"820\",\"framerContractVersion\":\"1\",\"framerIntrinsicWidth\":\"600\",\"framerSupportedLayoutHeight\":\"auto\",\"framerSupportedLayoutWidth\":\"fixed\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./GhlBookingEmbed.map"],"mappings":"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"}