1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7003],{7003:function(e,t,i){i.r(t),i.d(t,{ContentUpdater:function(){return o},FieldRegistry:function(){return n},FrameworkIntegration:function(){return a},MessageBridge:function(){return r},OverlayManager:function(){return s},Preview:function(){return l},createComponentChainLink:function(){return h},createPreviewAttributes:function(){return d},default:function(){return l},serializeComponentChain:function(){return u},withFieldPath:function(){return c}});class n{constructor(e){this.registry={},this.observer=null,this.isDestroyed=!1,this.config=e,this.initializeObserver(),this.scanExistingElements()}getElementsForField(e){let t=[];for(let i of Object.values(this.registry))for(let n of i)n.fieldApiId===e&&t.push(n);return t}getElementsForEntryField(e,t){let i=[];for(let n of Object.values(this.registry))for(let r of n)r.entryId===e&&r.fieldApiId===t&&i.push(r);return i}getElementsForEntry(e){let t=[];for(let i of Object.values(this.registry))for(let n of i)n.entryId===e&&t.push(n);return t}getElement(e,t){let i=this.createRegistryKey(e,t),n=this.registry[i];return(null==n?void 0:n[0])||null}refresh(){this.isDestroyed||this.scanExistingElements()}destroy(){var e;this.isDestroyed=!0,null==(e=this.observer)||e.disconnect(),this.registry={}}initializeObserver(){this.observer=new MutationObserver(e=>{var t;if(!this.isDestroyed)for(let i of e){if("childList"===i.type)for(let e of i.addedNodes)e.nodeType===Node.ELEMENT_NODE&&this.scanElement(e);"attributes"===i.type&&(null==(t=i.attributeName)?void 0:t.startsWith("data-hygraph-"))&&this.updateElementRegistration(i.target)}}),this.observer.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-hygraph-entry-id","data-hygraph-field-api-id","data-hygraph-component-chain"]})}scanExistingElements(){let e=document.querySelectorAll("[data-hygraph-entry-id]");e.forEach(e=>this.scanElement(e))}scanElement(e){this.hasHygraphAttributes(e)&&this.registerElement(e);let t=e.querySelectorAll("[data-hygraph-entry-id]");t.forEach(e=>this.registerElement(e))}hasHygraphAttributes(e){return e.hasAttribute("data-hygraph-entry-id")}registerElement(e){let t=e.getAttribute("data-hygraph-entry-id");if(!t)return;let i=e.getAttribute("data-hygraph-field-api-id")||void 0,n=e.getAttribute("data-hygraph-component-chain")||void 0,r={element:e,entryId:t,fieldApiId:i,componentChainRaw:n,lastUpdated:Date.now()},o=this.createRegistryKey(t,i);this.registry[o]||(this.registry[o]=[]);let s=this.registry[o].findIndex(t=>t.element===e);s>=0?this.registry[o][s]=r:this.registry[o].push(r),this.config.debug&&console.log("[FieldRegistry] Registered element:",{entryId:t,fieldApiId:i,element:e.tagName})}updateElementRegistration(e){this.unregisterElement(e),this.hasHygraphAttributes(e)&&this.registerElement(e)}unregisterElement(e){for(let[t,i]of Object.entries(this.registry)){let n=i.filter(t=>t.element!==e);0===n.length?delete this.registry[t]:this.registry[t]=n}}createRegistryKey(e,t){let i=[e];return t&&i.push(t),i.join(":")}getStats(){let e=new Set,t=new Set,i=0;for(let n of Object.values(this.registry))for(let r of(i+=n.length,n))e.add(r.entryId),r.fieldApiId&&t.add(`${r.entryId}:${r.fieldApiId}`);return{totalElements:i,entriesCount:e.size,fieldsCount:t.size}}getRegistryKeys(){return Object.keys(this.registry)}}
1class r{constructor(e){this.isConnected=!1,this.studioOrigin=null,this.messageQueue=[],this.isDestroyed=!1,this.handleMessage=e=>{if(this.isDestroyed)return;if(!this.isOriginAllowed(e.origin)){this.config.debug&&console.log("[MessageBridge] Ignored message from disallowed origin:",e.origin);return}let t=e.data;if(!this.isValidStudioMessage(t)){this.config.debug&&console.log("[MessageBridge] Ignored invalid message:",t);return}this.config.debug&&console.log("[MessageBridge] Received message:",t),"init"===t.type&&this.handleConnection(e.origin),this.config.onMessage(t)},this.config=e,this.setupMessageListener()}sendMessage(e){if(this.isDestroyed)return!1;if(!this.isConnected||!this.studioOrigin)return this.messageQueue.push(e),!1;try{return window.parent.postMessage(e,this.studioOrigin),this.config.debug&&console.log("[MessageBridge] Sent message:",e),!0}catch(e){return console.error("[MessageBridge] Failed to send message:",e),!1}}sendReadyMessage(e){if(this.isDestroyed)return!1;try{return window.parent.postMessage(e,"*"),this.config.debug&&console.log("[MessageBridge] Sent ready message to parent window, message:",e),!0}catch(e){return console.error("[MessageBridge] Failed to send ready message to origin: * error:",e),!1}}isConnectedToStudio(){return this.isConnected}getStudioOrigin(){return this.studioOrigin}destroy(){this.isDestroyed=!0,this.isConnected=!1,this.studioOrigin=null,this.messageQueue=[],window.removeEventListener("message",this.handleMessage)}setupMessageListener(){this.config.debug&&console.log("[MessageBridge] Setting up message listener, allowed origins:",this.config.allowedOrigins),window.addEventListener("message",this.handleMessage),this.config.onReady&&setTimeout(()=>{this.config.onReady()},0)}isOriginAllowed(e){return this.config.allowedOrigins.includes(e)||this.config.allowedOrigins.some(t=>{if(t.includes("*")){let i=t.replace(/\*/g,".*");return RegExp(`^${i}$`).test(e)}return!1})}isValidStudioMessage(e){if("object"!=typeof e||null===e||"string"!=typeof e.type||"number"!=typeof e.timestamp)return!1;switch(e.type){case"init":return"string"==typeof e.studioOrigin;case"field-update":return"string"==typeof e.entryId&&"string"==typeof e.fieldApiId&&"string"==typeof e.fieldType&&void 0!==e.newValue;case"field-focus":return"string"==typeof e.entryId&&"string"==typeof e.fieldApiId;case"content-saved":return"string"==typeof e.entryId;case"disconnect":return!0;default:return!1}}handleConnection(e){this.isConnected||(this.isConnected=!0,this.studioOrigin=e,this.config.debug&&console.log("[MessageBridge] Connected to Studio:",e),this.flushMessageQueue())}flushMessageQueue(){let e=[...this.messageQueue];for(let t of(this.messageQueue=[],e))this.sendMessage(t);this.config.debug&&e.length>0&&console.log(`[MessageBridge] Sent ${e.length} queued messages`)}}class o{constructor(e){this.updateQueue=new Map,this.isDestroyed=!1,this.config=e}async updateField(e){if(this.config.debug&&console.log("[ContentUpdater] updateField called:",{entryId:e.entryId,fieldApiId:e.fieldApiId,fieldType:e.fieldType,componentChain:e.componentChain}),this.isDestroyed)return{success:!1,error:"ContentUpdater is destroyed"};try{let t=e.componentChain?JSON.stringify(e.componentChain):"",i=`${e.entryId}:${e.fieldApiId}:${t}`;this.updateQueue.set(i,e),await this.delay(this.config.updateDelay||50);let n=this.updateQueue.get(i);if(n!==e)return{success:!0,superseded:!0};this.updateQueue.delete(i);let r=this.findElements(e.entryId,e.fieldApiId,e.componentChain);if(0===r.length)return{success:!1,error:"No matching elements found"};let o=!1,s="";for(let t of r)try{await this.updateElement(t,e)}catch(e){o=!0,s=e instanceof Error?e.message:String(e),console.error("[ContentUpdater] Failed to update element:",e)}if(o)return{success:!1,error:s};return this.config.debug&&console.log("[ContentUpdater] Updated field:",{entryId:e.entryId,fieldApiId:e.fieldApiId,elementsCount:r.length}),{success:!0,element:r[0]}}catch(t){let e=t instanceof Error?t.message:String(t);return console.error("[ContentUpdater] Update failed:",t),{success:!1,error:e}}}destroy(){this.isDestroyed=!0,this.updateQueue.clear()}findElements(e,t,i){let n=`[data-hygraph-entry-id="${e}"]`;t&&(n+=`[data-hygraph-field-api-id="${t}"]`);let r=document.querySelectorAll(n),o=Array.from(r);
1if(this.config.debug&&console.log("[ContentUpdater] findElements:",{selector:n,foundCount:o.length,componentChain:i}),i&&i.length>0){let e=JSON.stringify(i);this.config.debug&&console.log("[ContentUpdater] Filtering by component chain:",{targetChainStr:e,elementsBeforeFilter:o.length});let t=o.filter(t=>{let i=t.getAttribute("data-hygraph-component-chain");return this.config.debug&&console.log("[ContentUpdater] Comparing chains:",{target:e,element:i,matches:i===e}),!!i&&i===e});if(t.length>0)o=t,this.config.debug&&console.log("[ContentUpdater] Using filtered elements:",{elementsAfterFilter:o.length});else{let t=o.some(e=>null!==e.getAttribute("data-hygraph-component-chain"));t?(this.config.debug&&console.log("[ContentUpdater] Component chain mismatch, skipping update:",{targetChain:e,existingElements:o.length}),o=[]):this.config.debug&&console.log("[ContentUpdater] No elements have component chains, falling back to all elements:",{fallbackCount:o.length})}}return o}async updateElement(e,t){if(t.isList){this.updateListField(e,t.newValue);return}switch(t.fieldType){case"STRING":case"ID":case"ENUMERATION":this.updateTextField(e,t.newValue);break;case"RICHTEXT":await this.updateRichTextField(e,t.newValue);break;case"INT":case"FLOAT":this.updateNumberField(e,t.newValue);break;case"BOOLEAN":this.updateBooleanField(e,t.newValue);break;case"DATETIME":case"DATE":this.updateDateField(e,t.newValue);break;case"ASSET":await this.updateAssetField(e,t.newValue);break;case"LOCATION":this.updateLocationField(e,t.newValue);break;case"COLOR":this.updateColorField(e,t.newValue);break;case"COMPONENT":await this.updateComponentField(e,t.newValue);break;case"COMPONENT_ARRAY":{this.config.debug&&console.log("[ContentUpdater] COMPONENT_ARRAY change detected, reordering DOM elements");let i=t.transformedValue??t.newValue;await this.reorderComponentArray(e,i);break}case"JSON":this.updateJsonField(e,t.newValue);break;case"RELATION":this.updateRelationField(e,t.newValue);break;default:throw Error("Unsupported field type")}}updateListField(e,t){let i=Array.isArray(t)?t:[t],n=e=>null==e?"":String(e),r=e.getAttribute("data-hygraph-list-index");if(null!==r){let t=Number(r);this.setTextValue(e,Number.isInteger(t)?n(i[t]):"");return}if(!this.isTextValueElement(e)&&e.children.length>0)throw Error(`Cannot render list field "${e.getAttribute("data-hygraph-field-api-id")}" into <${e.tagName.toLowerCase()}>: it has child elements that would be destroyed. Tag each item with data-hygraph-list-index, or render the list yourself via onFieldUpdate / the preview:field-updated event.`);this.setTextValue(e,i.map(n).join(", "))}isTextValueElement(e){return"INPUT"===e.tagName||"TEXTAREA"===e.tagName}setTextValue(e,t){this.isTextValueElement(e)?e.value=t:e.textContent=t}updateTextField(e,t){(t||""===t)&&this.setTextValue(e,t)}async updateRichTextField(e,t){var i;try{let n;if("string"==typeof t){n=t,this.shouldUseInnerHTML(e,n)?e.innerHTML=n:e.textContent=n;return}if(t&&"object"==typeof t){if("html"in t&&"markdown"in t){let r=e.getAttribute("data-hygraph-rich-text-format");if(this.config.debug&&console.log("[ContentUpdater] Rich Text multi-format update:",{formatPreference:r,availableFormats:Object.keys(t)}),"html"===r&&t.html){if(n=t.html,this.hasMorphdom()){let t=document.createElement(e.tagName);t.innerHTML=n,null==(i=window.morphdom)||i.call(window,e,t)}else e.innerHTML=n}else"markdown"===r&&t.markdown?(n=t.markdown,e.textContent=n):"text"===r&&t.text?(n=t.text,e.textContent=n):(n=t.html||this.richTextToHTML(t.ast||t),e.innerHTML=n)}else"children"in t&&(n=this.richTextToHTML(t),e.innerHTML=n)}}catch(e){throw console.error("[ContentUpdater] Rich text update failed:",e),e}}updateNumberField(e,t){if(null==t)return;let i=String(t);"INPUT"===e.tagName?e.value=i:e.textContent=i}updateBooleanField(e,t){"INPUT"===e.tagName&&"checkbox"===e.type?e.checked=t:e.textContent=String(t)}updateDateField(e,t){if(!t)return;let i=new Date(t),n=i.toLocaleDateString();"INPUT"===e.tagName&&"date"===e.type?e.value=t.split("T")[0]:e.textContent=n}async updateAssetField(e,t){if(t){if(Array.isArray(t)){t.length>0&&await this.updateSingleAsset(e,t[0]);return}await this.updateSingleAsset(e,t)}}async updateSingleAsset(e,t){"IMG"===e.tagName?(e.src=t.url,t.alt&&(e.alt=t.alt),t.width&&(e.width=t.width),t.height&&(e.height=t.height)):"VIDEO"===e.tagName?e.src=t.url:"AUDIO"===e.tagName?e.src=t.url:"A"===e.tagName?(e.href=t.url,e.textContent||(e.textContent=t.fileName)):e.innerHTML=`<img src="${t.url}" alt="${t.alt||""}" />`}updateLocationField(e,t){if(!t||"number"!=typeof t.latitude||"number"!=typeof t.longitude)return;let i=`${t.latitude}, ${t.longitude}`;e.textContent=i,e.setAttribute("data-latitude",String(t.latitude)),e.setAttribute("data-longitude",String(t.longitude))}updateColorField(e,t){t&&(e.textContent=t,e.style&&(e.style.backgroundColor=t))}async updateComponentField(e,t){var i;if(t)try{let n=this.renderComponent(t);if(this.hasMorphdom()){let t=document.createElement(e.tagName);t.innerHTML=n,null==(i=window.morphdom)||i.call(window,e,t)}else e.innerHTML=n}catch(e){throw console.error("[ContentUpdater] Component update failed:",e),e}}updateJsonField(e,t){if(null==t)return;let i=JSON.stringify(t,null,2);e.textContent=i}updateRelationField(e,t){if(null===t){e.textContent="";return}if(Array.isArray(t)){e.textContent=t.join(", ");return}e.textContent=t}richTextToHTML(e){return e.children?e.children.map(e=>this.renderRichTextNode(e)).join(""):""}renderRichTextNode(e){if("string"==typeof e.text)return this.escapeHtml(e.text);let t=Array.isArray(e.children)?e.children.map(e=>this.renderRichTextNode(e)).join(""):"";switch(e.type){case"paragraph":return`<p>${t}</p>`;case"heading-one":return`<h1>${t}</h1>`;case"heading-two":return`<h2>${t}</h2>`;case"heading-three":return`<h3>${t}</h3>`;case"heading-four":return`<h4>${t}</h4>`;case"heading-five":return`<h5>${t}</h5>`;case"heading-six":return`<h6>${t}</h6>`;case"block-quote":return`<blockquote>${t}</blockquote>`;case"bulleted-list":return`<ul>${t}</ul>`;case"numbered-list":return`<ol>${t}</ol>`;case"list-item":return`<li>${t}</li>`;case"link":{let i="string"==typeof e.href?e.href:"";return`<a href="${i}">${t}</a>`}case"bold":return`<strong>${t}</strong>`;case"italic":return`<em>${t}</em>`;case"underline":return`<u>${t}</u>`;case"code":return`<code>${t}</code>`;default:return t}}async reorderComponentArray(e,t){if(!Array.isArray(t)){console.warn("[ContentUpdater] Invalid components array");return}if(0===t.length){this.config.debug&&console.log("[ContentUpdater] Empty component array, clearing container"),e.innerHTML="";return}this.config.debug&&console.log("[ContentUpdater] Reordering",t.length,"components");let i=Array.from(e.children),n=new Map;
1i.forEach(e=>{var t;let i=e.getAttribute("data-hygraph-component-chain");if(i)try{let r=JSON.parse(i);if(Array.isArray(r)&&r.length>0){let i=null==(t=r[r.length-1])?void 0:t.instanceId;i&&(n.set(i,e),this.config.debug&&console.log("[ContentUpdater] Mapped component instance",i,"to DOM element"))}}catch(e){console.warn("[ContentUpdater] Failed to parse component chain:",i)}});let r=document.createDocumentFragment(),o=0;t.forEach((e,t)=>{let i=e.id;if(!i){console.warn("[ContentUpdater] Component missing ID at index",t);return}let s=n.get(i);s?(r.appendChild(s),o++):this.config.debug&&console.log("[ContentUpdater] New component not in DOM, skipping:",i)}),o>0?(e.innerHTML="",e.appendChild(r),this.config.debug&&console.log("[ContentUpdater] Successfully reordered",o,"elements")):console.warn("[ContentUpdater] Could not match any components to DOM elements");let s=t.length-o;s>0&&this.config.debug&&console.log("[ContentUpdater]",s,"new component(s) not in DOM â will appear after save")}renderComponent(e){let t=e.__typename,i=Object.entries(e).filter(([e])=>"__typename"!==e&&"id"!==e).map(([e,t])=>{let i=this.formatComponentValue(t),n=i.includes("<")&&i.includes(">");return`<div data-field="${e}">${n?i:this.escapeHtml(i)}</div>`}).join("");return`<div data-component="${t}">${i}</div>`}formatComponentValue(e){if(null==e)return"";if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e)return String(e);if(this.isRichTextFormats(e))return e.html||"";try{return JSON.stringify(e)}catch{return String(e)}}isRichTextFormats(e){return null!==e&&"object"==typeof e&&"html"in e&&"markdown"in e&&"text"in e&&"ast"in e}escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}hasMorphdom(){return"function"==typeof window.morphdom}shouldUseInnerHTML(e,t){return!!(t.includes("<")&&t.includes(">"))}delay(e){return new Promise(t=>setTimeout(t,e))}}class s{constructor(e){this.overlayElement=null,this.editButtonElement=null,this.currentTarget=null,this.isDestroyed=!1,this.hoverTimeout=null,this.handleMouseMove=e=>{var t;if(this.isDestroyed)return;let i=e.target;if(i===this.editButtonElement||(null==(t=this.editButtonElement)?void 0:t.contains(i)))return;let n=i.closest("[data-hygraph-entry-id]");if(n&&n!==this.currentTarget){this.hoverTimeout&&(clearTimeout(this.hoverTimeout),this.hoverTimeout=null);let e=n.getAttribute("data-hygraph-entry-id"),t=n.getAttribute("data-hygraph-field-api-id");e&&this.showOverlay(n,{element:n,entryId:e,fieldApiId:t||void 0})}else!n&&this.currentTarget&&(this.hoverTimeout&&(clearTimeout(this.hoverTimeout),this.hoverTimeout=null),setTimeout(()=>{this.currentTarget&&!this.isMouseOverEditButton(e)&&this.hideOverlay()},50))},this.handleMouseLeave=()=>{this.hideOverlay()},this.handleScroll=()=>{this.currentTarget&&this.updateOverlayPosition(this.currentTarget)},this.handleResize=()=>{this.currentTarget&&this.updateOverlayPosition(this.currentTarget)},this.config=e,this.createOverlayElements(),this.setupEventListeners()}showOverlay(e,t){!this.isDestroyed&&this.config.overlayEnabled&&(this.currentTarget=e,this.updateOverlayPosition(e),this.updateEditButton(t),this.showOverlayElements())}hideOverlay(){this.isDestroyed||(this.currentTarget=null,this.hideOverlayElements())}destroy(){this.isDestroyed=!0,this.hoverTimeout&&(clearTimeout(this.hoverTimeout),this.hoverTimeout=null),this.removeOverlayElements(),this.removeEventListeners()}createOverlayElements(){var e,t;let i=(null==(e=this.config.overlay)?void 0:e.style)||{},n=i.borderColor||"#3B82F6",r=i.borderWidth||"2px",o=i.backgroundColor||"rgba(59, 130, 246, 0.1)",s=void 0!==i.opacity?i.opacity:1,a=i.borderRadius||"4px";this.config.debug&&console.log("[OverlayManager] Creating overlay with config:",{borderColor:n,borderWidth:r,backgroundColor:o,opacity:s,borderRadius:a}),this.overlayElement=document.createElement("div"),this.overlayElement.id="hygraph-preview-overlay",this.overlayElement.style.cssText=` 2 position: fixed; 3 pointer-events: none; 4 z-index: 9999; 5 border: ${r} solid ${n}; 6 background: ${o}; 7 border-radius: ${a}; 8 display: none; 9 transition: all 0.2s ease; 10 box-sizing: border-box; 11 opacity: ${s}; 12 `;let l=(null==(t=this.config.overlay)?void 0:t.button)||{},d=l.backgroundColor||"#3B82F6",h=l.color||"white",u=l.borderRadius||"6px",c=l.fontSize||"14px",g=l.padding||"8px 12px";this.editButtonElement=document.createElement("button"),this.editButtonElement.id="hygraph-preview-edit-button",this.editButtonElement.innerHTML=`
13 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 14 <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 15 <path d="m18.5 2.5 3 3L12 15l-4 1 1-4 9.5-9.5z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 16 </svg> 17 Edit 18 `,this.editButtonElement.style.cssText=` 19 position: fixed; 20 z-index: 10000; 21 background: ${d}; 22 color: ${h}; 23 border: 1px solid rgba(255, 255, 255, 0.2); 24 border-radius: ${u}; 25 padding: ${g}; 26 font-size: ${c}; 27 font-weight: 500; 28 cursor: pointer; 29 display: none; 30 align-items: center; 31 gap: 6px; 32 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1); 33 transition: all 0.2s ease; 34 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif; 35 pointer-events: auto; 36 width: 72px; 37 height: 32px; 38 justify-content: center; 39 box-sizing: border-box; 40 backdrop-filter: blur(8px); 41 -webkit-backdrop-filter: blur(8px); 42 `;let p=this.darkenColor(d,.1);this.editButtonElement.addEventListener("mouseenter",()=>{this.editButtonElement.style.background=p,this.editButtonElement.style.transform="scale(1.05)"}),this.editButtonElement.addEventListener("mouseleave",()=>{this.editButtonElement.style.background=d,this.editButtonElement.style.transform="scale(1)"}),document.body.appendChild(this.overlayElement),document.body.appendChild(this.editButtonElement)}setupEventListeners(){document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("mouseleave",this.handleMouseLeave),document.addEventListener("scroll",this.handleScroll,!0),window.addEventListener("resize",this.handleResize)}removeEventListeners(){document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseleave",this.handleMouseLeave),document.removeEventListener("scroll",this.handleScroll,!0),window.removeEventListener("resize",this.handleResize)}isMouseOverEditButton(e){if(!this.editButtonElement)return!1;let t=this.editButtonElement.getBoundingClientRect();return e.clientX>=t.left&&e.clientX<=t.right&&e.clientY>=t.top&&e.clientY<=t.bottom}updateOverlayPosition(e){if(!this.overlayElement)return;let t=e.getBoundingClientRect();this.overlayElement.style.left=`${t.left}px`,this.overlayElement.style.top=`${t.top}px`,this.overlayElement.style.width=`${t.width}px`,this.overlayElement.style.height=`${t.height}px`}updateEditButton(e){if(!this.editButtonElement||!this.currentTarget)return;let t=this.currentTarget.getBoundingClientRect(),i=t.top+4,n=t.right-72-4;n<t.left+4&&(n=t.left+4),i+32+4>t.bottom&&(i=Math.max(t.top+4,t.bottom-32-4)),n=Math.max(t.left+4,Math.min(n,t.right-72-4)),i=Math.max(t.top+4,Math.min(i,t.bottom-32-4)),this.editButtonElement.style.left=`${n}px`,this.editButtonElement.style.top=`${i}px`,this.editButtonElement.onclick=t=>{t.preventDefault(),t.stopPropagation(),this.handleEditClick(e)};let r=e.fieldApiId||"entry";this.editButtonElement.title=`Edit ${r}`}handleEditClick(e){let t=new CustomEvent("hygraph-edit-click",{detail:e,bubbles:!0});document.dispatchEvent(t),this.config.debug&&console.log("[OverlayManager] Edit button clicked:",e)}showOverlayElements(){this.overlayElement&&(this.overlayElement.style.display="block"),this.editButtonElement&&(this.editButtonElement.style.display="flex")}hideOverlayElements(){this.overlayElement&&(this.overlayElement.style.display="none"),this.editButtonElement&&(this.editButtonElement.style.display="none")}removeOverlayElements(){this.overlayElement&&(this.overlayElement.remove(),this.overlayElement=null),this.editButtonElement&&(this.editButtonElement.remove(),this.editButtonElement=null)}darkenColor(e,t){if(e.startsWith("#")){let i=e.replace("#",""),n=parseInt(i.substr(0,2),16),r=parseInt(i.substr(2,2),16),o=parseInt(i.substr(4,2),16);return`#${Math.floor(n*(1-t)).toString(16).padStart(2,"0")}${Math.floor(r*(1-t)).toString(16).padStart(2,"0")}${Math.floor(o*(1-t)).toString(16).padStart(2,"0")}`}return"#3B82F6"===e?"#2563EB":e}}class a{constructor(){this.detectedFramework=null,this.detectFramework()}getFramework(){return this.detectedFramework}getRefreshFunction(){if(!this.detectedFramework)return null;switch(this.detectedFramework.type){case"nextjs":return this.getNextjsRefresh();case"remix":return this.getRemixRefresh();case"gatsby":return this.getGatsbyRefresh();case"nuxt":return this.getNuxtRefresh();
42case"sveltekit":return this.getSveltekitRefresh();default:return this.getVanillaRefresh()}}async refresh(){let e=this.getRefreshFunction();e?(console.log("[FrameworkIntegration] Using framework-specific refresh"),await e()):(console.log("[FrameworkIntegration] No framework-specific refresh found, using window.location.reload()"),window.location.reload())}detectFramework(){if(this.hasNextjs()){this.detectedFramework={type:"nextjs",router:this.getNextjsRouter()};return}if(this.hasRemix()){this.detectedFramework={type:"remix",revalidator:this.getRemixRevalidator()};return}if(this.hasGatsby()){this.detectedFramework={type:"gatsby"};return}if(this.hasNuxt()){this.detectedFramework={type:"nuxt"};return}if(this.hasSveltekit()){this.detectedFramework={type:"sveltekit"};return}this.detectedFramework={type:"vanilla"}}hasNextjs(){return"undefined"!=typeof window&&(!!window.__NEXT_DATA__||!!window.next||null!==document.querySelector('script[src*="/_next/"]'))}hasRemix(){return"undefined"!=typeof window&&(!!window.__remixContext||!!window.__remixRouterContext||null!==document.querySelector('script[src*="/build/"]'))}hasGatsby(){return"undefined"!=typeof window&&(!!window.___gatsby||!!window.__GATSBY||null!==document.querySelector("[data-gatsby-browser-entry]"))}hasNuxt(){return"undefined"!=typeof window&&(!!window.__NUXT__||!!window.$nuxt||null!==document.querySelector("#__nuxt"))}hasSveltekit(){return"undefined"!=typeof window&&(!!window.__SVELTEKIT__||null!==document.querySelector("[data-sveltekit-preload-data]"))}getNextjsRouter(){var e,t;return"undefined"==typeof window?null:(null==(e=window.next)?void 0:e.router)??(null==(t=window.__NEXT_DATA__)?void 0:t.router)??null}getRemixRevalidator(){var e;return"undefined"==typeof window?null:window.__remixRevalidator??(null==(e=window.__remixRouterContext)?void 0:e.revalidator)??null}getNextjsRefresh(){let e=this.getNextjsRouter();if(e&&"function"==typeof e.refresh){let t=e.refresh.bind(e);return()=>{console.log("[FrameworkIntegration] Using Next.js App Router refresh()"),t()}}if(e&&"function"==typeof e.replace){let t=e.replace.bind(e);return()=>{console.log("[FrameworkIntegration] Using Next.js Pages Router replace()"),t(e.asPath||window.location.pathname)}}return"function"==typeof window.location.reload?()=>{console.log("[FrameworkIntegration] Falling back to window.location.reload()"),window.location.reload()}:null}getRemixRefresh(){let e=this.getRemixRevalidator();if(e&&"function"==typeof e.revalidate)return()=>e.revalidate();let t=window.__remixRevalidate;return"function"==typeof t?()=>t():null}getGatsbyRefresh(){return()=>window.location.reload()}getNuxtRefresh(){let e=window.$nuxt;if(e&&"function"==typeof e.refresh){let t=e.refresh.bind(e);return()=>t()}let t=window.refreshCookie;return"function"==typeof t?()=>t():()=>window.location.reload()}getSveltekitRefresh(){let e=window.invalidateAll;return"function"==typeof e?()=>e():()=>window.location.reload()}getVanillaRefresh(){return()=>window.location.reload()}getSetupInstructions(){if(!this.detectedFramework)return"";switch(this.detectedFramework.type){case"nextjs":return` 43// Next.js setup: 44import { HygraphPreview } from '@hygraph/preview-sdk/react'; 45import { useRouter } from 'next/router'; 46 47function App() { 48 const router = useRouter(); 49 50 return ( 51 <HygraphPreview 52 endpoint="your-endpoint" 53 onSave={() => router.replace(router.asPath)} 54 > 55 {/* Your content */} 56 </HygraphPreview> 57 ); 58}`;case"remix":return` 59// Remix setup: 60import { HygraphPreview } from '@hygraph/preview-sdk/react'; 61import { useRevalidator } from '@remix-run/react'; 62 63export default function App() { 64 const revalidator = useRevalidator(); 65 66 return ( 67 <HygraphPreview 68 endpoint="your-endpoint" 69 onSave={() => revalidator.revalidate()} 70 > 71 {/* Your content */} 72 </HygraphPreview> 73 ); 74}`;case"vanilla":return` 75// Vanilla JS setup: 76import { Preview } from '@hygraph/preview-sdk'; 77 78const preview = new Preview({ 79 endpoint: 'your-endpoint' 80}); 81 82preview.subscribe('save', { 83 callback: () => window.location.reload() 84});`;default:return` 85// ${this.detectedFramework.type} setup: 86import { Preview } from '@hygraph/preview-sdk'; 87 88const preview = new Preview({ 89 endpoint: 'your-endpoint' 90}); 91 92preview.subscribe('save', { 93 callback: () => { 94 // Add framework-specific refresh logic here 95 window.location.reload(); 96 } 97});`}}}
97class l{constructor(e){this.messageBridge=null,this.saveCallbacks=new Set,this.handleEditClick=e=>{let t=e.detail,i=t.element;"iframe"===this.mode?this.handleIframeEditClick(i):this.handleStandaloneEditClick(i)},this.config={debug:!1,overlayEnabled:!0,updateDelay:50,retryAttempts:3,autoConnect:!0,allowedOrigins:["https://*.hygraph.com","https://*.hygraph.dev","http://localhost:*"],...e},this.frameworkIntegration=new a,this.mode=this.determineMode(),this.fieldRegistry=new n(this.config),this.contentUpdater=new o(this.config),this.overlayManager=new s(this.config),"iframe"===this.mode?this.initializeIframeMode():this.initializeStandaloneMode(),this.setupEditClickHandler(),this.config.debug&&(window.__HYGRAPH_PREVIEW__=this),this.emitEvent("preview:ready",{preview:this})}subscribe(e,t){if("save"===e)return this.saveCallbacks.add(t.callback),()=>this.saveCallbacks.delete(t.callback);throw Error(`Unknown event type: ${e}`)}getVersion(){return"1.1.0"}getMode(){return this.mode}getFrameworkIntegration(){return this.frameworkIntegration}getFieldRegistryStats(){return this.fieldRegistry.getStats()}getFieldRegistryKeys(){return this.fieldRegistry.getRegistryKeys()}isConnected(){var e;return(null==(e=this.messageBridge)?void 0:e.isConnectedToStudio())??!1}refresh(){this.fieldRegistry.refresh()}configureOverlay(e){this.config.overlay||(this.config.overlay={}),e.style&&(this.config.overlay.style={...this.config.overlay.style,...e.style}),e.button&&(this.config.overlay.button={...this.config.overlay.button,...e.button}),this.overlayManager.destroy(),this.overlayManager=new s(this.config),this.config.debug&&console.log("[Preview] Overlay configuration updated:",e)}destroy(){var e;this.fieldRegistry.destroy(),null==(e=this.messageBridge)||e.destroy(),this.contentUpdater.destroy(),this.overlayManager.destroy(),this.saveC
97allbacks.clear(),document.removeEventListener("hygraph-edit-click",this.handleEditClick),window.__HYGRAPH_PREVIEW__===this&&delete window.__HYGRAPH_PREVIEW__}determineMode(){if("iframe"===this.config.mode)return"iframe";if("standalone"===this.config.mode)return"standalone";try{return window.self===window.top?"standalone":"iframe"}catch(e){return"iframe"}}initializeIframeMode(){this.config.debug&&console.log("[Preview] Initializing in iframe mode"),this.messageBridge=new r({debug:this.config.debug,allowedOrigins:this.getAllowedOrigins(),onMessage:this.handleStudioMessage.bind(this),onReady:()=>{this.config.debug&&console.log("[Preview] MessageBridge ready, sending ready message to Studio"),this.config.autoConnect&&this.sendReadyMessage()}}),this.setupIframeEditHandlers()}initializeStandaloneMode(){this.config.debug&&console.log("[Preview] Initializing in standalone mode"),this.config.studioUrl||this.isProductionEndpoint()||console.warn("[Preview] Consider setting studioUrl for development endpoints"),this.setupStandaloneEditHandlers()}getAllowedOrigins(){let e=[...this.config.allowedOrigins||[]];return this.config.studioUrl&&e.push(new URL(this.config.studioUrl).origin),e}isProductionEndpoint(){return!!this.config.endpoint&&(this.config.endpoint.includes("api.hygraph.com")||this.config.endpoint.includes(".hygraph.com")||this.config.endpoint.includes(".hygraph.dev"))}scanRichTextFormatPreferences(){let e={},t={};return document.querySelectorAll("[data-hygraph-entry-id][data-hygraph-rich-text-format]").forEach(i=>{let n=i.getAttribute("data-hygraph-entry-id"),r=i.getAttribute("data-hygraph-field-api-id"),o=i.getAttribute("data-hygraph-rich-text-format");if(n&&r&&o&&["html","markdown","text"].includes(o)){let i=`${n}:${r}`;e[i]?(t[i]||(t[i]=[e[i]]),t[i].push(o)):e[i]=o,this.config.debug&&console.log(`[Preview] Rich Text format preference detected: ${i} -> ${o}`)}}),Object.entries(t).forEach(([e,t])=>{let i=[...new Set(t)];i.length>1&&console.warn(`ð¨ [Preview] UNSUPPORTED USAGE: Rich Text field "${e}" appears multiple times with different formats: [${t.join(", ")}]. 98 99â ï¸ LIMITATION: Each Rich Text field should appear only ONCE per format in your preview. 100â SOLUTION: Use different field API IDs or choose one format. 101 102Example: 103â <div data-hygraph-field-api-id="description" data-hygraph-rich-text-format="html"> 104â <div data-hygraph-field-api-id="description" data-hygraph-rich-text-format="markdown"> 105 106â <div data-hygraph-field-api-id="description" data-hygraph-rich-text-format="html"> 107â <div data-hygraph-field-api-id="descriptionMd" data-hygraph-rich-text-format="markdown"> 108 109ð See: https://docs.claude.com/preview-sdk#rich-text-limitations`)}),e}sendReadyMessage(){var e,t;if(!this.messageBridge)return;let i={fieldFocusSync:(null==(e=this.config.sync)?void 0:e.fieldFocus)??!1,fieldUpdateSync:(null==(t=this.config.sync)?void 0:t.fieldUpdate)??!1,scalarListSync:!0,richTextFormatPreferences:this.scanRichTextFormatPreferences()},n={type:"ready",sdkVersion:this.getVersion(),capabilities:i,timestamp:Date.now()};this.messageBridge.sendReadyMessage(n)}handleStudioMessage(e){switch(console.log("[Preview] handleStudioMessage called with:",e.type,e),e.type){case"init":this.handleInitMessage(e);break;case"field-update":this.handleFieldUpdate(e);break;case"field-focus":console.log("[Preview] Routing to handleFieldFocus"),this.handleFieldFocus(e);break;case"content-saved":this.handleContentSaved(e);break;case"disconnect":this.handleDisconnect()}}handleInitMessage(e){this.config.debug&&console.log("[Preview] Connected to Studio:",e.studioOrigin),this.emitEvent("preview:connected",{studioOrigin:e.studioOrigin})}async handleFieldUpdate(e){if(this.config.onFieldUpdate)console.log("[Preview] Using custom onFieldU
109pdate handler"),this.config.onFieldUpdate(e);else{console.log("[Preview] Using built-in ContentUpdater"),console.log("[Preview] About to call contentUpdater.updateField with:",e);let t=await this.contentUpdater.updateField(e);if(t.superseded)return;if(!t.success){this.emitEvent("preview:update-failed",{entryId:e.entryId,fieldApiId:e.fieldApiId,error:t.error||"Unknown error"});return}}this.emitEvent("preview:field-updated",{entryId:e.entryId,fieldApiId:e.fieldApiId,newValue:e.newValue,transformedValue:"COMPONENT_ARRAY"===e.fieldType?e.transformedValue:void 0,componentChain:e.componentChain,isList:e.isList,fieldType:e.fieldType})}handleFieldFocus(e){if(console.log("[Preview] Received field-focus message:",{entryId:e.entryId,fieldApiId:e.fieldApiId,componentChain:e.componentChain}),this.emitEvent("preview:field-focus",{entryId:e.entryId,fieldApiId:e.fieldApiId}),this.config.onFieldFocus){console.log("[Preview] Using custom onFieldFocus handler"),this.config.onFieldFocus(e.fieldApiId);return}console.log("[Preview] Searching for field in registry...");let t=this.fieldRegistry.getElementsForEntryField(e.entryId,e.fieldApiId);if(console.log("[Preview] Initial registry search result:",{foundCount:t.length,foundElements:t.map(e=>({fieldApiId:e.fieldApiId,entryId:e.entryId,element:e.element.tagName,componentChainRaw:e.componentChainRaw}))}),e.componentChain&&e.componentChain.length>0){console.log("[Preview] Filtering by component chain:",e.componentChain);let i=JSON.stringify(e.componentChain);console.log("[Preview] After filtering by component chain:",{foundCount:(t=t.filter(e=>{if(!e.componentChainRaw)return console.log("[Preview] Element has no component chain, skipping"),!1;try{let t=e.componentChainRaw;return console.log("[Preview] Comparing chains:",{target:i,element:t}),t===i}catch(e){return console.log("[Preview] Error comparing chains:",e),!1}})).length})}if(t.length>0){let e=t[0].element;console.log("[Preview] Scrolling to element:",e),e.scrollIntoView({behavior:"smooth",block:"center"}),e.classList.add("hygraph-field-highlight"),setTimeout(()=>{e.classList.remove("hygraph-field-highlight")},2e3),(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)&&e.focus()}else console.warn("[Preview] Could not find element for field focus:",{entryId:e.entryId,fieldApiId:e.fieldApiId,componentChain:e.componentChain}),console.log("[Preview] All registered elements:",this.fieldRegistry.getRegistryKeys())}async handleContentSaved(e){for(let t of(this.config.debug&&console.log("[Preview] Content saved, triggering framework refresh"),this.emitEvent("preview:content-saved",{entryId:e.entryId,timestamp:e.timestamp}
109),this.saveCallbacks))try{await t(e.entryId)}catch(e){console.error("[Preview] Save callback failed:",e)}}handleDisconnect(){this.config.debug&&console.log("[Preview] Disconnected from Studio"),this.emitEvent("preview:disconnected",{})}setupEditClickHandler(){document.addEventListener("hygraph-edit-click",this.handleEditClick)}setupIframeEditHandlers(){}setupStandaloneEditHandlers(){}handleIframeEditClick(e){var t;let i=e.getAttribute("data-hygraph-entry-id"),n=e.getAttribute("data-hygraph-field-api-id")||void 0,r=this.parseComponentChain(e.getAttribute("data-hygraph-component-chain")||void 0);if(i){if(this.messageBridge){let o={type:"field-click",entryId:i,fieldApiId:n,componentChain:r,timestamp:Date.now()},s=this.messageBridge.sendMessage(o);s||(null==(t=this.config.standalone)?void 0:t.fallbackToNewTab)===!1||(this.config.debug&&console.log("[Preview] Studio not connected, falling back to new tab"),this.handleStandaloneEditClick(e))}this.emitEvent("preview:field-click",{entryId:i,fieldApiId:n,componentChain:r,mode:this.mode})}}handleStandaloneEditClick(e){let t=e.getAttribute("data-hygraph-entry-id"),i=e.getAttribute("data-hygraph-field-api-id")||void 0,n=this.parseComponentChain(e.getAttribute("data-hygraph-component-chain")||void 0);if(!t)return;if(!this.config.endpoint){console.error("[Preview] Cannot open Studio - no endpoint configured");return}let r=this.buildStudioUrl(t,i,n);window.open(r,"_blank","noopener,noreferrer"),this.config.debug&&console.log("[Preview] Opened Studio in new tab:",r),this.emitEvent("preview:field-click",{entryId:t,fieldApiId:i,componentChain:n,mode:this.mode})}buildStudioUrl(e,t,i){let n=(this.config.studioUrl||"https://app.hygraph.com").replace(/\/+$/,""),r=new URLSearchParams({endpoint:this.config.endpoint,entryId:e});return t&&r.set("fieldApiId",t),i&&i.length>0&&r.set("componentChain",JSON.stringify(i)),`${n}/entry?${r.toString()}`}parseComponentChain(e){if(e)try{let t=JSON.parse(e);if(!Array.isArray(t))return;let i=t.map(e=>{if(!e||"object"!=typeof e)return null;let{fieldApiId:t,instanceId:i}=e;return"string"==typeof t&&"string"==typeof i&&i?{fieldApiId:t,instanceId:i}:null}).filter(e=>!!e);return i.length>0?i:void 0}catch(t){this.config.debug&&console.warn("[Preview] Failed to parse component chain attribute",e,t);return}}emitEvent(e,t){let i=new CustomEvent(e,{detail:t});document.dispatchEvent(i)}}function d(e){let{entryId:t,fieldApiId:i,componentChain:n,listIndex:r}=e;if(!t)throw Error("[Preview SDK] createPreviewAttributes requires an entryId");let o={"data-hygraph-entry-id":t};i&&(o["data-hygraph-field-api-id"]=i);let s=u(n);if(s&&(o["data-hygraph-component-chain"]=s),void 0!==r){if(!Number.isInteger(r)||r<0)throw Error("[Preview SDK] createPreviewAttributes requires listIndex to be a non-negative integer");o["data-hygraph-list-index"]=String(r)}return o}function h(e,t){if(!e)throw Error("[Preview SDK] createComponentChainLink requires a fieldApiId");if(!t)throw Error("[Preview SDK] createComponentChainLink requires an instanceId");return{fieldApiId:e,instanceId:t}}function u(e){if(!e||0===e.length)return;let t=e.filter(e=>!!(e&&"string"==typeof e.fieldApiId&&"string"==typeof e.instanceId)).map(e=>({fieldApiId:e.fieldApiId,instanceId:e.instanceId}));if(t.length)return JSON.stringify(t)}function c(e,t){return{...e,"data-hygraph-field-path":t}}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.