Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@mtg-rio/formengine-wrapper

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mtg-rio/formengine-wrapper - npm Package Compare versions

Comparing version
0.1.2
to
0.1.3
+4
README.md
A React component wrapper for seamless MTG FormEngine integration. Simplifies embedding FormEngine forms into React applications with an intuitive API and TypeScript support.
Complete document refer to git repository ReactFormEngine / FormEnginev2_Frontend / packages / FormEngineWrapper / LOCAL_README.md
+1
-1

@@ -1,2 +0,2 @@

"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime"),t=require("react"),r=t.createContext({baseUrl:"",baseName:"FormEngineV2",defaultConfig:{},defaultStyles:{},debug:!1}),o=()=>{const e=t.useContext(r);if(!e)throw new Error("useFormEngineContext must be used within a FormEngineProvider. Wrap your component tree with <FormEngineProvider> to fix this error.");return e},n={REF_OBJ:"refObj",REF_ID:"refId",TPL_NAME:"tplName",EDITOR:"editor",EDITOR_SHOW:"editorShow",EDITOR_ENABLE:"editorEnable",EDITOR_REQUIRED:"editorRequired",MINI:"st_mini",FOOTER:"footer",FORM_FOOTER:"form_footer",HISTORY:"history_show",READ_ONLY:"readOnly",INIT_DATA:"initData",EXTRA_DATA:"extraData",PREVIEW_DATA:"previewData"},a={CREATE:"/form-data/create",DUMMY_CREATE:"/form-data/dummy-create",EDIT:"/form-data/edit",CREATE_OR_EDIT:"/form-data/createOrEdit",VIEW:"/form-data/view"};function s(e){try{const t=JSON.stringify(e);return"function"==typeof btoa?btoa(encodeURIComponent(t)):Buffer.from(t).toString("base64")}catch{return""}}function i(e){const{baseUrl:t,baseName:r="FormEngineV2",mode:o,refObj:i,refId:u,tplName:l,id:E,config:m}=e,c=t.replace(/\/+$/,"");let d;switch(o){case"create":d=a.CREATE;break;case"edit":case"view":d=E?`${a.EDIT}/${E}`:a.CREATE_OR_EDIT;break;case"createOrEdit":default:d=a.CREATE_OR_EDIT;break;case"dummy-create":d=a.DUMMY_CREATE}const _=function(e){const t=new URLSearchParams;return e?(e.editor&&(void 0!==e.editor.show&&t.set(n.EDITOR_SHOW,e.editor.show?"1":"0"),void 0!==e.editor.enabled&&t.set(n.EDITOR_ENABLE,e.editor.enabled?"1":"0"),void 0!==e.editor.required&&t.set(n.EDITOR_REQUIRED,e.editor.required?"1":"0"),e.editor.defaultValue&&t.set(n.EDITOR,e.editor.defaultValue)),e.layout&&(void 0!==e.layout.mini&&t.set(n.MINI,e.layout.mini?"1":"0"),void 0!==e.layout.showFooter&&t.set(n.FOOTER,e.layout.showFooter?"1":"0"),void 0!==e.layout.showHistory&&t.set(n.HISTORY,e.layout.showHistory?"1":"0"),void 0!==e.layout.readOnly&&t.set(n.READ_ONLY,e.layout.readOnly?"1":"0"),void 0!==e.layout.showFormFooter&&t.set(n.FORM_FOOTER,e.layout.showFormFooter?"1":"0")),e.initData&&Object.keys(e.initData).length>0&&t.set(n.INIT_DATA,encodeURIComponent(JSON.stringify(e.initData))),e.extraData&&Object.keys(e.extraData).length>0&&t.set(n.EXTRA_DATA,s(e.extraData)),e.previewData&&Object.keys(e.previewData).length>0&&t.set(n.PREVIEW_DATA,encodeURIComponent(JSON.stringify(e.previewData))),t):t}(m);_.set(n.REF_OBJ,i),_.set(n.REF_ID,String(u)),_.set(n.TPL_NAME,l),"view"===o&&_.set(n.READ_ONLY,"1");const F=_.toString();return`${c}${r?`/${r}${d}`:d}${F?`?${F}`:""}`}const u="MTG_FORMENGINE",l="submit",E="get_form_data",m="set_form_data",c="set_field_labels",d="FormSubmitStart",_="FormSubmitSuccess",F="FormSubmitFail",f="ReturnFormData",T="ReturnSetFormData",g="FormOnLoadSuccess",R="FormOnLoadFail",S="FormDataChange",b="Submit",D="GetFormData",p="SetFormData",A="SetFieldLabels";function N(e){var t;return(null==(t=e.data)?void 0:t.messageFrom)===u}function v(e,t,r={}){return{messageFrom:"FORMENGINE_WRAPPER",messageEventType:e,messageEventName:t,messageEventContent:r}}function O(e,t,r="*"){if(!(null==e?void 0:e.contentWindow))return!1;try{return e.contentWindow.postMessage(t,r),!0}catch(o){return!1}}function x(e,t="*"){return O(e,v(l,b),t)}function M(e,t="*"){return O(e,v(E,D),t)}function w(e,t,r={},o="*"){return O(e,v(m,p,{...r,data:t}),o)}function I(e,t,r=!0,o="*"){return O(e,v(c,A,{labels:t,merge:r}),o)}function y(e,t){var r,o,n,a,s,i,u,l,E;if(!N(e))return;const m=e.data;switch(null==(r=t.onAnyMessage)||r.call(t,m),m.messageEventName){case d:null==(o=t.onSubmitStart)||o.call(t,m.messageEventContent);break;case _:null==(n=t.onSubmitSuccess)||n.call(t,m.messageEventContent);break;case F:null==(a=t.onSubmitFail)||a.call(t,m.messageEventContent);break;case f:null==(s=t.onFormDataReturn)||s.call(t,m.messageEventContent);break;case T:null==(i=t.onSetFormDataReturn)||i.call(t,m.messageEventContent);break;case g:null==(u=t.onFormLoadSuccess)||u.call(t,m.messageEventContent);break;case R:null==(l=t.onFormLoadFail)||l.call(t,m.messageEventContent);break;case S:null==(E=t.onFormDataChange)||E.call(t,m.messageEventContent)}}function L(e,t=5e3,r="*"){return new Promise((o,n)=>{if(!e)return void n(new Error("Iframe is null"));let a;const s=e=>{if(!N(e))return;const t=e.data;t.messageEventName===f&&(clearTimeout(a),window.removeEventListener("message",s),o(t.messageEventContent.data))};window.addEventListener("message",s),a=setTimeout(()=>{window.removeEventListener("message",s),n(new Error("Form data request timed out"))},t),M(e,r)||(clearTimeout(a),window.removeEventListener("message",s),n(new Error("Failed to send form data request")))})}const C={width:"100%",height:"100%",position:"relative",overflow:"hidden"},h={width:"100%",height:"100%",border:"none"};const U=t.forwardRef((r,n)=>{const{refObj:a,refId:s,tplName:u,id:l,mode:E="createOrEdit",styles:m,config:c,onSubmitStart:d,onSubmitSuccess:_,onSubmitFail:F,onFormLoad:f,onFormDataChange:T,onMessage:g,className:R,title:S="FormEngine Form",allowFullScreen:b=!1,sandbox:D="allow-same-origin allow-scripts allow-forms allow-popups"}=r,{baseUrl:p,baseName:A,defaultConfig:N,defaultStyles:v,debug:O}=o(),M=t.useRef(null),U=t.useRef(null),V=t.useMemo(()=>function(e,t){return{root:{...e.root,...null==t?void 0:t.root},iframe:{...e.iframe,...null==t?void 0:t.iframe}}}({root:C,iframe:h,...v},m),[v,m]),P=t.useMemo(()=>function(e,t){return{editor:{...e.editor,...null==t?void 0:t.editor},layout:{...e.layout,...null==t?void 0:t.layout},initData:{...e.initData,...null==t?void 0:t.initData},extraData:{...e.extraData,...null==t?void 0:t.extraData},previewData:{...e.previewData,...null==t?void 0:t.previewData}}}(N,c),[N,c]),k=t.useMemo(()=>p?i({baseUrl:p,baseName:A,mode:E,refObj:a,refId:s,tplName:u,id:l,config:P}):"",[p,A,E,a,s,u,l,P]);t.useEffect(()=>{},[O,k,P]);const B=t.useCallback(e=>{y(e,{onSubmitStart:e=>{null==d||d(e)},onSubmitSuccess:e=>{null==_||_(e)},onSubmitFail:e=>{null==F||F(e)},onFormDataReturn:e=>{var t;null==(t=U.current)||t.call(U,e.data),U.current=null},onFormDataChange:e=>{null==T||T(e)},onFormLoadSuccess:e=>{null==f||f(e)},onFormLoadFail:e=>{},onAnyMessage:e=>{null==g||g(e)}})},[O,d,_,F,f,T,g]);return t.useEffect(()=>(window.addEventListener("message",B),()=>{window.removeEventListener("message",B)}),[B]),t.useImperativeHandle(n,()=>({submit:()=>{x(M.current)},getFormData:()=>L(M.current,5e3),setFormData:e=>{w(M.current,e)},setFieldLabels:(e,t=!0)=>{I(M.current,e,t)},getIframe:()=>M.current,reload:()=>{M.current&&(M.current.src=M.current.src)}}),[]),p?e.jsx("div",{style:V.root,className:R,children:e.jsx("iframe",{ref:M,src:k,style:V.iframe,title:S,allowFullScreen:b,sandbox:D})}):e.jsx("div",{style:V.root,className:R,children:e.jsx("p",{style:{color:"red",padding:"20px"},children:"Error: FormEngine baseUrl is not configured. Please wrap this component with FormEngineProvider."})})});U.displayName="FormEngineWrapper",exports.FORM_DATA_CHANGE_EVENT_NAME=S,exports.FORM_DATA_CHANGE_EVENT_TYPE="form_data_change",exports.FORM_ONLOAD_EVENT_TYPE="form_onload",exports.FORM_ONLOAD_FAIL_EVENT_NAME=R,exports.FORM_ONLOAD_SUCCESS_EVENT_NAME=g,exports.FORM_SUBMIT_EVENT_NAME=b,exports.FORM_SUBMIT_EVENT_TYPE=l,exports.FormEngineContext=r,exports.FormEngineProvider=({baseUrl:o="/",baseName:n="FormEngineV2",defaultConfig:a={},defaultStyles:s={},debug:i=!1,children:u})=>{const l=t.useMemo(()=>({baseUrl:o,baseName:n,defaultConfig:a,defaultStyles:s,debug:i}),[o,n,a,s,i]);return e.jsx(r.Provider,{value:l,children:u})},exports.FormEngineWrapper=U,exports.GET_FORM_DATA_EVENT_NAME=D,exports.GET_FORM_DATA_EVENT_TYPE=E,exports.MESSAGE_FROM=u,exports.RETURN_FORM_DATA_EVENT_NAME=f,exports.RETURN_FORM_DATA_EVENT_TYPE="return_form_data",exports.RETURN_SET_FORM_DATA_EVENT_NAME=T,exports.RETURN_SET_FORM_DATA_EVENT_TYPE="return_set_form_data",exports.ROUTES=a,exports.SET_FIELD_LABELS_EVENT_NAME=A,exports.SET_FIELD_LABELS_EVENT_TYPE=c,exports.SET_FORM_DATA_EVENT_NAME=p,exports.SET_FORM_DATA_EVENT_TYPE=m,exports.SUBMIT_RESULT_EVENT_TYPE="submit_result",exports.SUBMIT_RESULT_FAIL_EVENT_NAME=F,exports.SUBMIT_RESULT_SUCCESS_EVENT_NAME=_,exports.SUBMIT_START_EVENT_NAME=d,exports.SUBMIT_START_EVENT_TYPE="submit_start",exports.URL_PARAMS=n,exports.buildFormEngineUrl=i,exports.default=U,exports.encodeBase64=s,exports.handleFormEngineMessage=y,exports.isFormEngineMessage=N,exports.parseFormEngineUrl=function(e){try{const t=new URL(e),r=t.searchParams;return{baseUrl:t.origin,refObj:r.get(n.REF_OBJ)||void 0,refId:r.get(n.REF_ID)||void 0,tplName:r.get(n.TPL_NAME)||void 0}}catch{return null}},exports.postMessageToIframe=O,exports.requestFormData=M,exports.requestFormDataAsync=L,exports.sendFieldLabels=I,exports.sendFormData=w,exports.triggerSubmit=x,exports.useFormEngine=function(e={}){const{timeout:r=5e3,targetOrigin:o="*"}=e,n=t.useRef(null),a=t.useCallback(()=>{x(n.current,o)},[o]),s=t.useCallback(async()=>L(n.current,r,o),[r,o]),i=t.useCallback(e=>{w(n.current,e,{},o)},[o]),u=t.useCallback(e=>{I(n.current,e,!0,o)},[o]),l=t.useCallback(()=>n.current,[]),E=t.useCallback(()=>{n.current&&(n.current.src=n.current.src)},[]);return{iframeRef:n,submit:a,getFormData:s,setFormData:i,setFieldLabels:u,getIframe:l,reload:E}},exports.useFormEngineBaseUrl=()=>{const{baseUrl:e}=o();return e},exports.useFormEngineContext=o,exports.useFormEngineDebug=()=>{const{debug:e}=o();return e},exports.useFormEngineMessageListener=function(e,r=!0){const o=t.useRef(e);t.useEffect(()=>{o.current=e},[e]),t.useEffect(()=>{if(!r)return;const e=e=>{N(e)&&o.current(e.data)};return window.addEventListener("message",e),()=>{window.removeEventListener("message",e)}},[r])},exports.useFormMessages=function(e={}){const{enabled:r=!0,onSubmitStart:o,onSubmitSuccess:n,onSubmitFail:a,onFormDataReturn:s,onSetFormDataReturn:i,onFormLoadSuccess:u,onFormLoadFail:l,onAnyMessage:E}=e,m=t.useRef({});t.useEffect(()=>{m.current={onSubmitStart:o,onSubmitSuccess:n,onSubmitFail:a,onFormDataReturn:s,onSetFormDataReturn:i,onFormLoadSuccess:u,onFormLoadFail:l,onAnyMessage:E}},[o,n,a,s,i,u,l,E]);const c=t.useCallback(e=>{y(e,m.current)},[]);t.useEffect(()=>{if(r)return window.addEventListener("message",c),()=>{window.removeEventListener("message",c)}},[r,c])};
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime"),t=require("react"),r=t.createContext({baseUrl:"",baseName:"FormEngineV2",defaultConfig:{},defaultStyles:{},debug:!1}),o=()=>{const e=t.useContext(r);if(!e)throw new Error("useFormEngineContext must be used within a FormEngineProvider. Wrap your component tree with <FormEngineProvider> to fix this error.");return e},n={REF_OBJ:"refObj",REF_ID:"refId",TPL_NAME:"tplName",EDITOR:"editor",EDITOR_SHOW:"editorShow",EDITOR_ENABLE:"editorEnable",EDITOR_REQUIRED:"editorRequired",MINI:"st_mini",FOOTER:"footer",FORM_FOOTER:"form_footer",HISTORY:"history_show",READ_ONLY:"readOnly",INIT_DATA:"initData",EXTRA_DATA:"extraData",PREVIEW_DATA:"previewData"},a={CREATE:"/form-data/create",DUMMY_CREATE:"/form-data/dummy-create",EDIT:"/form-data/edit",CREATE_OR_EDIT:"/form-data/createOrEdit",VIEW:"/form-data/view"};function s(e){try{const t=JSON.stringify(e);return"function"==typeof btoa?btoa(encodeURIComponent(t)):Buffer.from(t).toString("base64")}catch{return""}}function i(e){const{baseUrl:t,baseName:r="FormEngineV2",mode:o,refObj:i,refId:u,tplName:l,id:E,config:m}=e,c=t.replace(/\/+$/,"");let d;switch(o){case"create":d=a.CREATE;break;case"edit":case"view":d=E?`${a.EDIT}/${E}`:a.CREATE_OR_EDIT;break;case"createOrEdit":default:d=a.CREATE_OR_EDIT;break;case"dummy-create":d=a.DUMMY_CREATE}const _=function(e){const t=new URLSearchParams;return e?(e.editor&&(void 0!==e.editor.show&&t.set(n.EDITOR_SHOW,e.editor.show?"1":"0"),void 0!==e.editor.enabled&&t.set(n.EDITOR_ENABLE,e.editor.enabled?"1":"0"),void 0!==e.editor.required&&t.set(n.EDITOR_REQUIRED,e.editor.required?"1":"0"),e.editor.defaultValue&&t.set(n.EDITOR,e.editor.defaultValue)),e.layout&&(void 0!==e.layout.mini&&t.set(n.MINI,e.layout.mini?"1":"0"),void 0!==e.layout.showFooter&&t.set(n.FOOTER,e.layout.showFooter?"1":"0"),void 0!==e.layout.showHistory&&t.set(n.HISTORY,e.layout.showHistory?"1":"0"),void 0!==e.layout.readOnly&&t.set(n.READ_ONLY,e.layout.readOnly?"1":"0"),void 0!==e.layout.showFormFooter&&t.set(n.FORM_FOOTER,e.layout.showFormFooter?"1":"0")),e.initData&&Object.keys(e.initData).length>0&&t.set(n.INIT_DATA,encodeURIComponent(JSON.stringify(e.initData))),e.extraData&&Object.keys(e.extraData).length>0&&t.set(n.EXTRA_DATA,s(e.extraData)),e.previewData&&Object.keys(e.previewData).length>0&&t.set(n.PREVIEW_DATA,encodeURIComponent(JSON.stringify(e.previewData))),t):t}(m);_.set(n.REF_OBJ,i),_.set(n.REF_ID,String(u)),_.set(n.TPL_NAME,l),"view"===o&&_.set(n.READ_ONLY,"1");const F=_.toString();return`${c}${r?`/${r}${d}`:d}${F?`?${F}`:""}`}const u="MTG_FORMENGINE",l="submit",E="get_form_data",m="set_form_data",c="set_field_labels",d="FormSubmitStart",_="FormSubmitSuccess",F="FormSubmitFail",f="ReturnFormData",T="ReturnSetFormData",g="FormOnLoadSuccess",R="FormOnLoadFail",S="FormDataChange",b="Submit",D="GetFormData",p="SetFormData",A="SetFieldLabels";function N(e){var t;return(null==(t=e.data)?void 0:t.messageFrom)===u}function v(e,t,r={}){return{messageFrom:"FORMENGINE_WRAPPER",messageEventType:e,messageEventName:t,messageEventContent:r}}function O(e,t,r="*"){if(!(null==e?void 0:e.contentWindow))return!1;try{return e.contentWindow.postMessage(t,r),!0}catch(o){return!1}}function x(e,t="*"){return O(e,v(l,b),t)}function M(e,t="*"){return O(e,v(E,D),t)}function w(e,t,r={},o="*"){return O(e,v(m,p,{...r,data:t}),o)}function I(e,t,r=!0,o="*"){return O(e,v(c,A,{labels:t,merge:r}),o)}function y(e,t){var r,o,n,a,s,i,u,l,E;if(!N(e))return;const m=e.data;switch(null==(r=t.onAnyMessage)||r.call(t,m),m.messageEventName){case d:null==(o=t.onSubmitStart)||o.call(t,m.messageEventContent);break;case _:null==(n=t.onSubmitSuccess)||n.call(t,m.messageEventContent);break;case F:null==(a=t.onSubmitFail)||a.call(t,m.messageEventContent);break;case f:null==(s=t.onFormDataReturn)||s.call(t,m.messageEventContent);break;case T:null==(i=t.onSetFormDataReturn)||i.call(t,m.messageEventContent);break;case g:null==(u=t.onFormLoadSuccess)||u.call(t,m.messageEventContent);break;case R:null==(l=t.onFormLoadFail)||l.call(t,m.messageEventContent);break;case S:null==(E=t.onFormDataChange)||E.call(t,m.messageEventContent)}}function L(e,t=5e3,r="*"){return new Promise((o,n)=>{if(!e)return void n(new Error("Iframe is null"));let a;const s=e=>{if(!N(e))return;const t=e.data;t.messageEventName===f&&(clearTimeout(a),window.removeEventListener("message",s),o(t.messageEventContent.data))};window.addEventListener("message",s),a=setTimeout(()=>{window.removeEventListener("message",s),n(new Error("Form data request timed out"))},t),M(e,r)||(clearTimeout(a),window.removeEventListener("message",s),n(new Error("Failed to send form data request")))})}const C={width:"100%",height:"100%",position:"relative",overflow:"hidden"},h={width:"100%",height:"100%",border:"none"};const U=t.forwardRef((r,n)=>{const{refObj:a,refId:s,tplName:u,id:l,mode:E="createOrEdit",styles:m,config:c,onSubmitStart:d,onSubmitSuccess:_,onSubmitFail:F,onFormLoad:f,onFormDataChange:T,onMessage:g,className:R,title:S="FormEngine Form",allowFullScreen:b=!1,sandbox:D="allow-same-origin allow-scripts allow-forms allow-popups"}=r,{baseUrl:p,baseName:A,defaultConfig:N,defaultStyles:v,debug:O}=o(),M=t.useRef(null),U=t.useRef(null),V=t.useMemo(()=>function(e,t){return{container:{...e.container,...null==t?void 0:t.container},iframe:{...e.iframe,...null==t?void 0:t.iframe}}}({container:C,iframe:h,...v},m),[v,m]),P=t.useMemo(()=>function(e,t){return{editor:{...e.editor,...null==t?void 0:t.editor},layout:{...e.layout,...null==t?void 0:t.layout},initData:{...e.initData,...null==t?void 0:t.initData},extraData:{...e.extraData,...null==t?void 0:t.extraData},previewData:{...e.previewData,...null==t?void 0:t.previewData}}}(N,c),[N,c]),k=t.useMemo(()=>p?i({baseUrl:p,baseName:A,mode:E,refObj:a,refId:s,tplName:u,id:l,config:P}):"",[p,A,E,a,s,u,l,P]);t.useEffect(()=>{},[O,k,P]);const B=t.useCallback(e=>{y(e,{onSubmitStart:e=>{null==d||d(e)},onSubmitSuccess:e=>{null==_||_(e)},onSubmitFail:e=>{null==F||F(e)},onFormDataReturn:e=>{var t;null==(t=U.current)||t.call(U,e.data),U.current=null},onFormDataChange:e=>{null==T||T(e)},onFormLoadSuccess:e=>{null==f||f(e)},onFormLoadFail:e=>{},onAnyMessage:e=>{null==g||g(e)}})},[O,d,_,F,f,T,g]);return t.useEffect(()=>(window.addEventListener("message",B),()=>{window.removeEventListener("message",B)}),[B]),t.useImperativeHandle(n,()=>({submit:()=>{x(M.current)},getFormData:()=>L(M.current,5e3),setFormData:e=>{w(M.current,e)},setFieldLabels:(e,t=!0)=>{I(M.current,e,t)},getIframe:()=>M.current,reload:()=>{M.current&&(M.current.src=M.current.src)}}),[]),p?e.jsx("div",{style:V.container,className:R,children:e.jsx("iframe",{ref:M,src:k,style:V.iframe,title:S,allowFullScreen:b,sandbox:D})}):e.jsx("div",{style:V.container,className:R,children:e.jsx("p",{style:{color:"red",padding:"20px"},children:"Error: FormEngine baseUrl is not configured. Please wrap this component with FormEngineProvider."})})});U.displayName="FormEngineWrapper",exports.FORM_DATA_CHANGE_EVENT_NAME=S,exports.FORM_DATA_CHANGE_EVENT_TYPE="form_data_change",exports.FORM_ONLOAD_EVENT_TYPE="form_onload",exports.FORM_ONLOAD_FAIL_EVENT_NAME=R,exports.FORM_ONLOAD_SUCCESS_EVENT_NAME=g,exports.FORM_SUBMIT_EVENT_NAME=b,exports.FORM_SUBMIT_EVENT_TYPE=l,exports.FormEngineContext=r,exports.FormEngineProvider=({baseUrl:o="/",baseName:n="FormEngineV2",defaultConfig:a={},defaultStyles:s={},debug:i=!1,children:u})=>{const l=t.useMemo(()=>({baseUrl:o,baseName:n,defaultConfig:a,defaultStyles:s,debug:i}),[o,n,a,s,i]);return e.jsx(r.Provider,{value:l,children:u})},exports.FormEngineWrapper=U,exports.GET_FORM_DATA_EVENT_NAME=D,exports.GET_FORM_DATA_EVENT_TYPE=E,exports.MESSAGE_FROM=u,exports.RETURN_FORM_DATA_EVENT_NAME=f,exports.RETURN_FORM_DATA_EVENT_TYPE="return_form_data",exports.RETURN_SET_FORM_DATA_EVENT_NAME=T,exports.RETURN_SET_FORM_DATA_EVENT_TYPE="return_set_form_data",exports.ROUTES=a,exports.SET_FIELD_LABELS_EVENT_NAME=A,exports.SET_FIELD_LABELS_EVENT_TYPE=c,exports.SET_FORM_DATA_EVENT_NAME=p,exports.SET_FORM_DATA_EVENT_TYPE=m,exports.SUBMIT_RESULT_EVENT_TYPE="submit_result",exports.SUBMIT_RESULT_FAIL_EVENT_NAME=F,exports.SUBMIT_RESULT_SUCCESS_EVENT_NAME=_,exports.SUBMIT_START_EVENT_NAME=d,exports.SUBMIT_START_EVENT_TYPE="submit_start",exports.URL_PARAMS=n,exports.buildFormEngineUrl=i,exports.default=U,exports.encodeBase64=s,exports.handleFormEngineMessage=y,exports.isFormEngineMessage=N,exports.parseFormEngineUrl=function(e){try{const t=new URL(e),r=t.searchParams;return{baseUrl:t.origin,refObj:r.get(n.REF_OBJ)||void 0,refId:r.get(n.REF_ID)||void 0,tplName:r.get(n.TPL_NAME)||void 0}}catch{return null}},exports.postMessageToIframe=O,exports.requestFormData=M,exports.requestFormDataAsync=L,exports.sendFieldLabels=I,exports.sendFormData=w,exports.triggerSubmit=x,exports.useFormEngine=function(e={}){const{timeout:r=5e3,targetOrigin:o="*"}=e,n=t.useRef(null),a=t.useCallback(()=>{x(n.current,o)},[o]),s=t.useCallback(async()=>L(n.current,r,o),[r,o]),i=t.useCallback(e=>{w(n.current,e,{},o)},[o]),u=t.useCallback(e=>{I(n.current,e,!0,o)},[o]),l=t.useCallback(()=>n.current,[]),E=t.useCallback(()=>{n.current&&(n.current.src=n.current.src)},[]);return{iframeRef:n,submit:a,getFormData:s,setFormData:i,setFieldLabels:u,getIframe:l,reload:E}},exports.useFormEngineBaseUrl=()=>{const{baseUrl:e}=o();return e},exports.useFormEngineContext=o,exports.useFormEngineDebug=()=>{const{debug:e}=o();return e},exports.useFormEngineMessageListener=function(e,r=!0){const o=t.useRef(e);t.useEffect(()=>{o.current=e},[e]),t.useEffect(()=>{if(!r)return;const e=e=>{N(e)&&o.current(e.data)};return window.addEventListener("message",e),()=>{window.removeEventListener("message",e)}},[r])},exports.useFormMessages=function(e={}){const{enabled:r=!0,onSubmitStart:o,onSubmitSuccess:n,onSubmitFail:a,onFormDataReturn:s,onSetFormDataReturn:i,onFormLoadSuccess:u,onFormLoadFail:l,onAnyMessage:E}=e,m=t.useRef({});t.useEffect(()=>{m.current={onSubmitStart:o,onSubmitSuccess:n,onSubmitFail:a,onFormDataReturn:s,onSetFormDataReturn:i,onFormLoadSuccess:u,onFormLoadFail:l,onAnyMessage:E}},[o,n,a,s,i,u,l,E]);const c=t.useCallback(e=>{y(e,m.current)},[]);t.useEffect(()=>{if(r)return window.addEventListener("message",c),()=>{window.removeEventListener("message",c)}},[r,c])};
//# sourceMappingURL=index.cjs.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs.js","sources":["../src/context/FormEngineContext.tsx","../src/utils/urlBuilder.ts","../src/types/messages.ts","../src/utils/messageHandler.ts","../src/components/FormEngineWrapper.tsx","../src/hooks/useFormEngine.ts","../src/hooks/useFormMessages.ts"],"sourcesContent":["import React, { createContext, useContext, useMemo, type ReactNode } from 'react';\r\nimport type { FormEngineProviderConfig, FormEngineConfig, StyleConfig } from '../types';\r\n\r\n/**\r\n * Context value interface for FormEngine provider\r\n */\r\nexport interface FormEngineContextValue {\r\n /** Base URL of the FormEngine frontend application */\r\n baseUrl: string;\r\n /** Base name/path prefix for the FormEngine routes */\r\n baseName: string;\r\n /** Default configuration for all FormEngineWrapper instances */\r\n defaultConfig: FormEngineConfig;\r\n /** Default styles for all FormEngineWrapper instances */\r\n defaultStyles: StyleConfig;\r\n /** Whether debug mode is enabled */\r\n debug: boolean;\r\n}\r\n\r\n/** Default context values */\r\nconst defaultContextValue: FormEngineContextValue = {\r\n baseUrl: '',\r\n baseName: 'FormEngineV2',\r\n defaultConfig: {},\r\n defaultStyles: {},\r\n debug: false,\r\n};\r\n\r\n/**\r\n * React Context for FormEngine configuration\r\n */\r\nconst FormEngineContext = createContext<FormEngineContextValue>(defaultContextValue);\r\n\r\n/**\r\n * Props for FormEngineProvider component\r\n */\r\nexport interface FormEngineProviderProps extends FormEngineProviderConfig {\r\n /** Child components */\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * Provider component for FormEngine configuration\r\n * \r\n * Wrap your application (or a portion of it) with this provider to configure\r\n * the FormEngine wrapper components with default settings.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { FormEngineProvider } from '@formengine/wrapper';\r\n * \r\n * function App() {\r\n * return (\r\n * <FormEngineProvider\r\n * baseUrl=\"https://forms.example.com\"\r\n * defaultConfig={{\r\n * layout: { mini: true },\r\n * editor: { show: true, enabled: true },\r\n * }}\r\n * >\r\n * <YourApp />\r\n * </FormEngineProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const FormEngineProvider: React.FC<FormEngineProviderProps> = ({\r\n baseUrl = \"/\",\r\n baseName = 'FormEngineV2',\r\n defaultConfig = {},\r\n defaultStyles = {},\r\n debug = false,\r\n children,\r\n}) => {\r\n // Memoize the context value to prevent unnecessary re-renders\r\n const contextValue = useMemo<FormEngineContextValue>(\r\n () => ({\r\n baseUrl,\r\n baseName,\r\n defaultConfig,\r\n defaultStyles,\r\n debug,\r\n }),\r\n [baseUrl, baseName, defaultConfig, defaultStyles, debug]\r\n );\r\n \r\n // Validate required props\r\n if (!baseUrl) {\r\n console.warn('FormEngineProvider: baseUrl is required but was not provided');\r\n }\r\n \r\n return (\r\n <FormEngineContext.Provider value={contextValue}>\r\n {children}\r\n </FormEngineContext.Provider>\r\n );\r\n};\r\n\r\n/**\r\n * Hook to access FormEngine context\r\n * \r\n * @returns The FormEngine context value\r\n * @throws Error if used outside of FormEngineProvider\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormEngineContext } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * const { baseUrl, debug } = useFormEngineContext();\r\n * \r\n * if (debug) {\r\n * console.log('FormEngine baseUrl:', baseUrl);\r\n * }\r\n * \r\n * return <div>...</div>;\r\n * }\r\n * ```\r\n */\r\nexport const useFormEngineContext = (): FormEngineContextValue => {\r\n const context = useContext(FormEngineContext);\r\n \r\n if (!context) {\r\n throw new Error(\r\n 'useFormEngineContext must be used within a FormEngineProvider. ' +\r\n 'Wrap your component tree with <FormEngineProvider> to fix this error.'\r\n );\r\n }\r\n \r\n return context;\r\n};\r\n\r\n/**\r\n * Hook to get the configured base URL\r\n */\r\nexport const useFormEngineBaseUrl = (): string => {\r\n const { baseUrl } = useFormEngineContext();\r\n return baseUrl;\r\n};\r\n\r\n/**\r\n * Hook to check if debug mode is enabled\r\n */\r\nexport const useFormEngineDebug = (): boolean => {\r\n const { debug } = useFormEngineContext();\r\n return debug;\r\n};\r\n\r\nexport { FormEngineContext };\r\n","import type { FormMode, FormEngineConfig } from '../types';\r\n\r\n/**\r\n * URL parameter keys for FormEngine routes\r\n */\r\nexport const URL_PARAMS = {\r\n REF_OBJ: 'refObj',\r\n REF_ID: 'refId',\r\n TPL_NAME: 'tplName',\r\n EDITOR: 'editor',\r\n EDITOR_SHOW: 'editorShow',\r\n EDITOR_ENABLE: 'editorEnable',\r\n EDITOR_REQUIRED: 'editorRequired',\r\n MINI: 'st_mini',\r\n FOOTER: 'footer',\r\n FORM_FOOTER: 'form_footer',\r\n HISTORY: 'history_show',\r\n READ_ONLY: 'readOnly',\r\n INIT_DATA: 'initData',\r\n EXTRA_DATA: 'extraData',\r\n PREVIEW_DATA: 'previewData',\r\n} as const;\r\n\r\n/**\r\n * Route paths for different form modes\r\n */\r\nexport const ROUTES = {\r\n CREATE: '/form-data/create',\r\n DUMMY_CREATE: '/form-data/dummy-create',\r\n EDIT: '/form-data/edit',\r\n CREATE_OR_EDIT: '/form-data/createOrEdit',\r\n VIEW: '/form-data/view',\r\n} as const;\r\n\r\n/**\r\n * Options for building the iframe URL\r\n */\r\nexport interface BuildUrlOptions {\r\n /** Base URL of the FormEngine application */\r\n baseUrl: string;\r\n /** Base name/path prefix (default: 'FormEngineV2') */\r\n baseName?: string;\r\n /** Form operation mode */\r\n mode: FormMode;\r\n /** Reference object identifier */\r\n refObj: string;\r\n /** Reference ID */\r\n refId: string | number;\r\n /** Template name */\r\n tplName: string;\r\n /** Form data ID (required for edit/view modes) */\r\n id?: number | string;\r\n /** Form configuration */\r\n config?: FormEngineConfig;\r\n}\r\n\r\n/**\r\n * Encode an object to base64 string for URL parameter\r\n */\r\nexport function encodeBase64(data: Record<string, unknown>): string {\r\n try {\r\n const jsonString = JSON.stringify(data);\r\n // Use btoa for browser environment, or Buffer for Node.js\r\n if (typeof btoa === 'function') {\r\n return btoa(encodeURIComponent(jsonString));\r\n }\r\n return Buffer.from(jsonString).toString('base64');\r\n } catch {\r\n console.error('Failed to encode data to base64');\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Build URL parameters from config\r\n */\r\nfunction buildConfigParams(config?: FormEngineConfig): URLSearchParams {\r\n const params = new URLSearchParams();\r\n \r\n if (!config) return params;\r\n \r\n // Editor config\r\n if (config.editor) {\r\n if (config.editor.show !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_SHOW, config.editor.show ? '1' : '0');\r\n }\r\n if (config.editor.enabled !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_ENABLE, config.editor.enabled ? '1' : '0');\r\n }\r\n if (config.editor.required !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_REQUIRED, config.editor.required ? '1' : '0');\r\n }\r\n if (config.editor.defaultValue) {\r\n params.set(URL_PARAMS.EDITOR, config.editor.defaultValue);\r\n }\r\n }\r\n \r\n // Layout config\r\n if (config.layout) {\r\n if (config.layout.mini !== undefined) {\r\n params.set(URL_PARAMS.MINI, config.layout.mini ? '1' : '0');\r\n }\r\n if (config.layout.showFooter !== undefined) {\r\n params.set(URL_PARAMS.FOOTER, config.layout.showFooter ? '1' : '0');\r\n }\r\n if (config.layout.showHistory !== undefined) {\r\n params.set(URL_PARAMS.HISTORY, config.layout.showHistory ? '1' : '0');\r\n }\r\n if (config.layout.readOnly !== undefined) {\r\n params.set(URL_PARAMS.READ_ONLY, config.layout.readOnly ? '1' : '0');\r\n }\r\n if (config.layout.showFormFooter !== undefined) {\r\n params.set(URL_PARAMS.FORM_FOOTER, config.layout.showFormFooter ? '1' : '0');\r\n }\r\n }\r\n \r\n // Data params\r\n if (config.initData && Object.keys(config.initData).length > 0) {\r\n params.set(URL_PARAMS.INIT_DATA, encodeURIComponent(JSON.stringify(config.initData)));\r\n }\r\n \r\n if (config.extraData && Object.keys(config.extraData).length > 0) {\r\n params.set(URL_PARAMS.EXTRA_DATA, encodeBase64(config.extraData));\r\n }\r\n \r\n if (config.previewData && Object.keys(config.previewData).length > 0) {\r\n params.set(URL_PARAMS.PREVIEW_DATA, encodeURIComponent(JSON.stringify(config.previewData)));\r\n }\r\n \r\n return params;\r\n}\r\n\r\n/**\r\n * Build the full iframe URL for FormEngine\r\n * \r\n * @param options - URL building options\r\n * @returns The complete URL string for the iframe\r\n * \r\n * @example\r\n * ```typescript\r\n * const url = buildFormEngineUrl({\r\n * baseUrl: 'https://forms.example.com',\r\n * mode: 'createOrEdit',\r\n * refObj: 'Order',\r\n * refId: '12345',\r\n * tplName: 'order-form',\r\n * });\r\n * // => \"https://forms.example.com/FormEngineV2/form-data/createOrEdit?refObj=Order&refId=12345&tplName=order-form\"\r\n * ```\r\n */\r\nexport function buildFormEngineUrl(options: BuildUrlOptions): string {\r\n const {\r\n baseUrl,\r\n baseName = 'FormEngineV2',\r\n mode,\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n config,\r\n } = options;\r\n \r\n // Normalize base URL (remove trailing slash)\r\n const normalizedBaseUrl = baseUrl.replace(/\\/+$/, '');\r\n \r\n // Build the route path based on mode\r\n let routePath: string;\r\n \r\n switch (mode) {\r\n case 'create':\r\n routePath = ROUTES.CREATE;\r\n break;\r\n case 'edit':\r\n case 'view':\r\n if (!id) {\r\n console.warn(`Mode \"${mode}\" requires an id. Falling back to createOrEdit.`);\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n } else {\r\n routePath = `${ROUTES.EDIT}/${id}`;\r\n }\r\n break;\r\n case 'createOrEdit':\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n break;\r\n case 'dummy-create':\r\n routePath = ROUTES.DUMMY_CREATE;\r\n break;\r\n default:\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n break;\r\n }\r\n \r\n // Build query parameters\r\n const params = buildConfigParams(config);\r\n params.set(URL_PARAMS.REF_OBJ, refObj);\r\n params.set(URL_PARAMS.REF_ID, String(refId));\r\n params.set(URL_PARAMS.TPL_NAME, tplName);\r\n \r\n // For view mode, set readOnly\r\n if (mode === 'view') {\r\n params.set(URL_PARAMS.READ_ONLY, '1');\r\n }\r\n \r\n // Construct the full URL\r\n const queryString = params.toString();\r\n const fullPath = baseName ? `/${baseName}${routePath}` : routePath;\r\n \r\n return `${normalizedBaseUrl}${fullPath}${queryString ? `?${queryString}` : ''}`;\r\n}\r\n\r\n/**\r\n * Parse a FormEngine URL to extract its components\r\n * Useful for debugging or validation\r\n */\r\nexport function parseFormEngineUrl(url: string): Partial<BuildUrlOptions> | null {\r\n try {\r\n const urlObj = new URL(url);\r\n const params = urlObj.searchParams;\r\n \r\n return {\r\n baseUrl: urlObj.origin,\r\n refObj: params.get(URL_PARAMS.REF_OBJ) || undefined,\r\n refId: params.get(URL_PARAMS.REF_ID) || undefined,\r\n tplName: params.get(URL_PARAMS.TPL_NAME) || undefined,\r\n };\r\n } catch {\r\n console.error('Failed to parse FormEngine URL');\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Message types for communication between FormEngineWrapper and FormEngine iframe\r\n * These types mirror the FormEngine's internal message system\r\n */\r\n\r\nimport { FieldLabelsMap } from \"./config\";\r\n\r\n\r\n/** Identifier for messages from FormEngine */\r\nexport const MESSAGE_FROM = 'MTG_FORMENGINE';\r\n\r\n// =============================================================================\r\n// Event Types - Categories of messages\r\n// =============================================================================\r\n\r\n/** Event types sent FROM FormEngine TO parent window */\r\nexport const SUBMIT_START_EVENT_TYPE = 'submit_start' as const;\r\nexport const SUBMIT_RESULT_EVENT_TYPE = 'submit_result' as const;\r\nexport const RETURN_FORM_DATA_EVENT_TYPE = 'return_form_data' as const;\r\nexport const RETURN_SET_FORM_DATA_EVENT_TYPE = 'return_set_form_data' as const;\r\nexport const FORM_ONLOAD_EVENT_TYPE = 'form_onload' as const;\r\nexport const FORM_DATA_CHANGE_EVENT_TYPE = 'form_data_change' as const;\r\n\r\n/** Event types sent FROM parent TO FormEngine */\r\nexport const FORM_SUBMIT_EVENT_TYPE = 'submit' as const;\r\nexport const GET_FORM_DATA_EVENT_TYPE = 'get_form_data' as const;\r\nexport const SET_FORM_DATA_EVENT_TYPE = 'set_form_data' as const;\r\nexport const SET_FIELD_LABELS_EVENT_TYPE = 'set_field_labels' as const;\r\n\r\n// =============================================================================\r\n// Event Names - Specific events within each type\r\n// =============================================================================\r\n\r\n/** Event names FROM FormEngine */\r\nexport const SUBMIT_START_EVENT_NAME = 'FormSubmitStart' as const;\r\nexport const SUBMIT_RESULT_SUCCESS_EVENT_NAME = 'FormSubmitSuccess' as const;\r\nexport const SUBMIT_RESULT_FAIL_EVENT_NAME = 'FormSubmitFail' as const;\r\nexport const RETURN_FORM_DATA_EVENT_NAME = 'ReturnFormData' as const;\r\nexport const RETURN_SET_FORM_DATA_EVENT_NAME = 'ReturnSetFormData' as const;\r\nexport const FORM_ONLOAD_SUCCESS_EVENT_NAME = 'FormOnLoadSuccess' as const;\r\nexport const FORM_ONLOAD_FAIL_EVENT_NAME = 'FormOnLoadFail' as const;\r\nexport const FORM_DATA_CHANGE_EVENT_NAME = 'FormDataChange' as const;\r\n\r\n/** Event names TO FormEngine */\r\nexport const FORM_SUBMIT_EVENT_NAME = 'Submit' as const;\r\nexport const GET_FORM_DATA_EVENT_NAME = 'GetFormData' as const;\r\nexport const SET_FORM_DATA_EVENT_NAME = 'SetFormData' as const;\r\nexport const SET_FIELD_LABELS_EVENT_NAME = 'SetFieldLabels' as const;\r\n\r\n// =============================================================================\r\n// Type Definitions\r\n// =============================================================================\r\n\r\n/** Event types from FormEngine to parent */\r\nexport type MessageEventTypeFromFormEngine =\r\n | typeof SUBMIT_START_EVENT_TYPE\r\n | typeof SUBMIT_RESULT_EVENT_TYPE\r\n | typeof RETURN_FORM_DATA_EVENT_TYPE\r\n | typeof RETURN_SET_FORM_DATA_EVENT_TYPE\r\n | typeof FORM_ONLOAD_EVENT_TYPE\r\n | typeof FORM_DATA_CHANGE_EVENT_TYPE;\r\n\r\n/** Event names from FormEngine to parent */\r\nexport type MessageEventNameFromFormEngine =\r\n | typeof SUBMIT_START_EVENT_NAME\r\n | typeof SUBMIT_RESULT_SUCCESS_EVENT_NAME\r\n | typeof SUBMIT_RESULT_FAIL_EVENT_NAME\r\n | typeof RETURN_FORM_DATA_EVENT_NAME\r\n | typeof RETURN_SET_FORM_DATA_EVENT_NAME\r\n | typeof FORM_ONLOAD_SUCCESS_EVENT_NAME\r\n | typeof FORM_ONLOAD_FAIL_EVENT_NAME\r\n | typeof FORM_DATA_CHANGE_EVENT_NAME;\r\n\r\n/** Event types from parent to FormEngine */\r\nexport type MessageEventTypeToFormEngine =\r\n | typeof FORM_SUBMIT_EVENT_TYPE\r\n | typeof GET_FORM_DATA_EVENT_TYPE\r\n | typeof SET_FORM_DATA_EVENT_TYPE\r\n | typeof SET_FIELD_LABELS_EVENT_TYPE;\r\n\r\n/** Event names from parent to FormEngine */\r\nexport type MessageEventNameToFormEngine =\r\n | typeof FORM_SUBMIT_EVENT_NAME\r\n | typeof GET_FORM_DATA_EVENT_NAME\r\n | typeof SET_FORM_DATA_EVENT_NAME\r\n | typeof SET_FIELD_LABELS_EVENT_NAME;\r\n\r\n/** All possible message event types */\r\nexport type MessageEventType = MessageEventTypeFromFormEngine | MessageEventTypeToFormEngine;\r\n\r\n/** All possible message event names */\r\nexport type MessageEventName = MessageEventNameFromFormEngine | MessageEventNameToFormEngine;\r\n\r\n// =============================================================================\r\n// Message Object Interfaces\r\n// =============================================================================\r\n\r\n/**\r\n * Base message object interface for FormEngine communication\r\n */\r\nexport interface MessageObject {\r\n /** Source identifier for the message */\r\n messageFrom: string;\r\n /** The specific event name */\r\n messageEventName: MessageEventName;\r\n /** The category of the event */\r\n messageEventType: MessageEventType;\r\n /** The payload of the message */\r\n messageEventContent: any;\r\n /** Whether the operation was successful (for response messages) */\r\n success?: boolean;\r\n}\r\n\r\n/**\r\n * Content structure for submit-related messages\r\n */\r\nexport interface SubmitMessageContent {\r\n /** Form data ID (present when editing existing form) */\r\n id?: number;\r\n /** Template name */\r\n tplName?: string;\r\n /** Reference object identifier */\r\n refObj?: string;\r\n /** Reference ID */\r\n refId?: string | number;\r\n /** Type of submit operation */\r\n submitType?: 'createOrEdit' | 'edit' | 'create' | 'dummy-create';\r\n /** Additional data */\r\n extra?: unknown;\r\n}\r\n\r\n/**\r\n * Message for setting form data\r\n */\r\nexport interface SetFormDataMessage extends Omit<MessageObject, 'messageEventContent' | 'messageEventName'> {\r\n messageEventName: typeof SET_FORM_DATA_EVENT_NAME;\r\n messageEventType: typeof SET_FORM_DATA_EVENT_TYPE;\r\n messageEventContent: {\r\n id?: string | number;\r\n tplName?: string;\r\n data: unknown;\r\n };\r\n}\r\n\r\n/**\r\n * Message for getting form data response\r\n */\r\nexport interface ReturnFormDataMessage extends MessageObject {\r\n messageEventName: typeof RETURN_FORM_DATA_EVENT_NAME;\r\n messageEventType: typeof RETURN_FORM_DATA_EVENT_TYPE;\r\n messageEventContent: {\r\n id?: string | number;\r\n data: unknown;\r\n };\r\n}\r\n\r\n/**\r\n * Form information in onload messages\r\n */\r\nexport interface FormOnLoadMessageForm {\r\n /** Form data ID */\r\n id?: number;\r\n /** Reference object */\r\n refObj?: string;\r\n /** Reference ID */\r\n refId?: string;\r\n /** Template name */\r\n tplName: string;\r\n /** Template display title */\r\n templateTitle: string;\r\n}\r\n\r\n/**\r\n * Content for form onload messages\r\n */\r\nexport interface FormOnLoadMessageContent {\r\n /** Whether the form has child forms */\r\n hasChildren: boolean;\r\n /** Number of tabs (for tabular forms) */\r\n tabCount: number;\r\n /** Parent form information */\r\n form: FormOnLoadMessageForm;\r\n /** Child forms information */\r\n childrenForms: FormOnLoadMessageForm[];\r\n}\r\n\r\n/**\r\n * Submit start message from FormEngine\r\n */\r\nexport interface SubmitStartMessage extends MessageObject {\r\n messageEventName: typeof SUBMIT_START_EVENT_NAME;\r\n messageEventType: typeof SUBMIT_START_EVENT_TYPE;\r\n messageEventContent: SubmitMessageContent;\r\n}\r\n\r\n/**\r\n * Submit result message from FormEngine\r\n */\r\nexport interface SubmitResultMessage extends MessageObject {\r\n messageEventName: typeof SUBMIT_RESULT_SUCCESS_EVENT_NAME | typeof SUBMIT_RESULT_FAIL_EVENT_NAME;\r\n messageEventType: typeof SUBMIT_RESULT_EVENT_TYPE;\r\n messageEventContent: SubmitMessageContent;\r\n}\r\n\r\n/**\r\n * Form onload message from FormEngine\r\n */\r\nexport interface FormOnLoadMessage extends MessageObject {\r\n messageEventName: typeof FORM_ONLOAD_SUCCESS_EVENT_NAME | typeof FORM_ONLOAD_FAIL_EVENT_NAME;\r\n messageEventType: typeof FORM_ONLOAD_EVENT_TYPE;\r\n messageEventContent: FormOnLoadMessageContent;\r\n}\r\n\r\n/**\r\n * Content for form data change messages\r\n */\r\nexport interface FormDataChangeMessageContent {\r\n /** The path/field that changed (e.g., \"root_field1\" or \"root_section_field2\") */\r\n path?: string;\r\n /** The new value of the changed field */\r\n value?: unknown;\r\n /** The complete form data after the change */\r\n formData: unknown;\r\n /** Form ID if available */\r\n id?: string | number;\r\n /** Template name */\r\n tplName?: string;\r\n}\r\n\r\n/**\r\n * Form data change message from FormEngine\r\n */\r\nexport interface FormDataChangeMessage extends MessageObject {\r\n messageEventName: typeof FORM_DATA_CHANGE_EVENT_NAME;\r\n messageEventType: typeof FORM_DATA_CHANGE_EVENT_TYPE;\r\n messageEventContent: FormDataChangeMessageContent;\r\n}\r\n\r\n/**\r\n * Message content for setting field labels\r\n */\r\nexport interface SetFieldLabelsMessageContent {\r\n /** Map of pathId to label config */\r\n labels: FieldLabelsMap;\r\n /** Whether to merge with existing labels (true) or replace all (false) */\r\n merge?: boolean;\r\n}\r\n\r\n/**\r\n * Message for setting field labels\r\n */\r\nexport interface SetFieldLabelsMessage extends MessageObject {\r\n messageEventType: typeof SET_FIELD_LABELS_EVENT_TYPE;\r\n messageEventName: typeof SET_FIELD_LABELS_EVENT_NAME;\r\n messageEventContent: SetFieldLabelsMessageContent;\r\n}\r\n","import { FieldLabelsMap } from '../types';\r\nimport {\r\n MESSAGE_FROM,\r\n SUBMIT_START_EVENT_NAME,\r\n SUBMIT_RESULT_SUCCESS_EVENT_NAME,\r\n SUBMIT_RESULT_FAIL_EVENT_NAME,\r\n RETURN_FORM_DATA_EVENT_NAME,\r\n RETURN_SET_FORM_DATA_EVENT_NAME,\r\n FORM_ONLOAD_SUCCESS_EVENT_NAME,\r\n FORM_ONLOAD_FAIL_EVENT_NAME,\r\n FORM_DATA_CHANGE_EVENT_NAME,\r\n FORM_SUBMIT_EVENT_TYPE,\r\n FORM_SUBMIT_EVENT_NAME,\r\n GET_FORM_DATA_EVENT_TYPE,\r\n GET_FORM_DATA_EVENT_NAME,\r\n SET_FORM_DATA_EVENT_TYPE,\r\n SET_FORM_DATA_EVENT_NAME,\r\n SET_FIELD_LABELS_EVENT_TYPE,\r\n SET_FIELD_LABELS_EVENT_NAME,\r\n type MessageObject,\r\n type MessageEventType,\r\n type MessageEventName,\r\n} from '../types/messages';\r\n\r\n/** Identifier for messages from the wrapper */\r\nconst WRAPPER_MESSAGE_FROM = 'FORMENGINE_WRAPPER';\r\n\r\n/**\r\n * Check if a message is from FormEngine\r\n */\r\nexport function isFormEngineMessage(event: MessageEvent): boolean {\r\n return event.data?.messageFrom === MESSAGE_FROM;\r\n}\r\n\r\n/**\r\n * Create a message object to send to FormEngine\r\n */\r\nfunction createMessage(\r\n eventType: MessageEventType,\r\n eventName: MessageEventName,\r\n content: Record<string, unknown> = {}\r\n): MessageObject {\r\n return {\r\n messageFrom: WRAPPER_MESSAGE_FROM,\r\n messageEventType: eventType,\r\n messageEventName: eventName,\r\n messageEventContent: content,\r\n };\r\n}\r\n\r\n/**\r\n * Send a message to the FormEngine iframe\r\n */\r\nexport function postMessageToIframe(\r\n iframe: HTMLIFrameElement | null,\r\n message: MessageObject,\r\n targetOrigin = '*'\r\n): boolean {\r\n if (!iframe?.contentWindow) {\r\n console.warn('Cannot post message: iframe or contentWindow is null');\r\n return false;\r\n }\r\n \r\n try {\r\n iframe.contentWindow.postMessage(message, targetOrigin);\r\n return true;\r\n } catch (error) {\r\n console.error('Failed to post message to iframe:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Trigger form submission in the iframe\r\n */\r\nexport function triggerSubmit(\r\n iframe: HTMLIFrameElement | null,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n FORM_SUBMIT_EVENT_TYPE,\r\n FORM_SUBMIT_EVENT_NAME\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Request form data from the iframe\r\n */\r\nexport function requestFormData(\r\n iframe: HTMLIFrameElement | null,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n GET_FORM_DATA_EVENT_TYPE,\r\n GET_FORM_DATA_EVENT_NAME\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Set form data in the iframe\r\n */\r\nexport function sendFormData(\r\n iframe: HTMLIFrameElement | null,\r\n data: unknown,\r\n options: { id?: string | number; tplName?: string } = {},\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n SET_FORM_DATA_EVENT_TYPE,\r\n SET_FORM_DATA_EVENT_NAME,\r\n {\r\n ...options,\r\n data,\r\n }\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Set field labels in the iframe\r\n * \r\n * @param iframe - The iframe element\r\n * @param labels - Map of pathId to label configuration\r\n * @param merge - Whether to merge with existing labels (default: true)\r\n * @param targetOrigin - Target origin for postMessage\r\n * \r\n * @example\r\n * ```typescript\r\n * sendFieldLabels(iframeRef.current, {\r\n * 'root_firstName': {\r\n * content: 'Edited by John @ 2024-01-01',\r\n * style: { color: 'blue', fontStyle: 'italic' }\r\n * },\r\n * 'root_lastName': {\r\n * content: 'Required field',\r\n * style: { color: 'red' }\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function sendFieldLabels(\r\n iframe: HTMLIFrameElement | null,\r\n labels: FieldLabelsMap,\r\n merge = true,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n SET_FIELD_LABELS_EVENT_TYPE,\r\n SET_FIELD_LABELS_EVENT_NAME,\r\n {\r\n labels,\r\n merge,\r\n }\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Message handler callback types\r\n */\r\nexport interface MessageHandlers {\r\n onSubmitStart?: (content: Record<string, unknown>) => void;\r\n onSubmitSuccess?: (content: Record<string, unknown>) => void;\r\n onSubmitFail?: (content: Record<string, unknown>) => void;\r\n onFormDataReturn?: (content: Record<string, unknown>) => void;\r\n onSetFormDataReturn?: (content: Record<string, unknown>) => void;\r\n onFormLoadSuccess?: (content: Record<string, unknown>) => void;\r\n onFormLoadFail?: (content: Record<string, unknown>) => void;\r\n onFormDataChange?: (content: Record<string, unknown>) => void;\r\n onAnyMessage?: (message: MessageObject) => void;\r\n}\r\n\r\n/**\r\n * Handle incoming messages from FormEngine\r\n */\r\nexport function handleFormEngineMessage(\r\n event: MessageEvent,\r\n handlers: MessageHandlers\r\n): void {\r\n // Validate message source\r\n if (!isFormEngineMessage(event)) {\r\n return;\r\n }\r\n \r\n const message = event.data as MessageObject;\r\n \r\n // Call the generic message handler\r\n handlers.onAnyMessage?.(message);\r\n \r\n // Route to specific handlers based on event name\r\n switch (message.messageEventName) {\r\n case SUBMIT_START_EVENT_NAME:\r\n handlers.onSubmitStart?.(message.messageEventContent);\r\n break;\r\n \r\n case SUBMIT_RESULT_SUCCESS_EVENT_NAME:\r\n handlers.onSubmitSuccess?.(message.messageEventContent);\r\n break;\r\n \r\n case SUBMIT_RESULT_FAIL_EVENT_NAME:\r\n handlers.onSubmitFail?.(message.messageEventContent);\r\n break;\r\n \r\n case RETURN_FORM_DATA_EVENT_NAME:\r\n handlers.onFormDataReturn?.(message.messageEventContent);\r\n break;\r\n \r\n case RETURN_SET_FORM_DATA_EVENT_NAME:\r\n handlers.onSetFormDataReturn?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_ONLOAD_SUCCESS_EVENT_NAME:\r\n handlers.onFormLoadSuccess?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_ONLOAD_FAIL_EVENT_NAME:\r\n handlers.onFormLoadFail?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_DATA_CHANGE_EVENT_NAME:\r\n handlers.onFormDataChange?.(message.messageEventContent);\r\n break;\r\n \r\n default:\r\n // Unknown message type - already logged via onAnyMessage if handler provided\r\n break;\r\n }\r\n}\r\n\r\n/**\r\n * Create a promise-based form data request\r\n * Returns a promise that resolves when form data is received\r\n */\r\nexport function requestFormDataAsync(\r\n iframe: HTMLIFrameElement | null,\r\n timeout = 5000,\r\n targetOrigin = '*'\r\n): Promise<unknown> {\r\n return new Promise((resolve, reject) => {\r\n if (!iframe) {\r\n reject(new Error('Iframe is null'));\r\n return;\r\n }\r\n \r\n let timeoutId: ReturnType<typeof setTimeout>;\r\n \r\n const messageHandler = (event: MessageEvent) => {\r\n if (!isFormEngineMessage(event)) return;\r\n \r\n const message = event.data as MessageObject;\r\n if (message.messageEventName === RETURN_FORM_DATA_EVENT_NAME) {\r\n clearTimeout(timeoutId);\r\n window.removeEventListener('message', messageHandler);\r\n resolve(message.messageEventContent.data);\r\n }\r\n };\r\n \r\n window.addEventListener('message', messageHandler);\r\n \r\n // Set timeout for the request\r\n timeoutId = setTimeout(() => {\r\n window.removeEventListener('message', messageHandler);\r\n reject(new Error('Form data request timed out'));\r\n }, timeout);\r\n \r\n // Send the request\r\n if (!requestFormData(iframe, targetOrigin)) {\r\n clearTimeout(timeoutId);\r\n window.removeEventListener('message', messageHandler);\r\n reject(new Error('Failed to send form data request'));\r\n }\r\n });\r\n}\r\n","import React, {\r\n forwardRef,\r\n useImperativeHandle,\r\n useEffect,\r\n useCallback,\r\n useMemo,\r\n useRef,\r\n type CSSProperties,\r\n} from 'react';\r\nimport type {\r\n FormEngineWrapperProps,\r\n FormEngineWrapperRef,\r\n StyleConfig,\r\n FormEngineConfig,\r\n SubmitEventData,\r\n FormLoadEventData,\r\n FormDataChangeEvent,\r\n} from '../types';\r\nimport { useFormEngineContext } from '../context';\r\nimport { buildFormEngineUrl } from '../utils/urlBuilder';\r\nimport {\r\n handleFormEngineMessage,\r\n triggerSubmit,\r\n sendFormData,\r\n sendFieldLabels,\r\n requestFormDataAsync,\r\n} from '../utils/messageHandler';\r\nimport type { FieldLabelsMap } from '../types/config';\r\n\r\n/** Default styles for the wrapper container */\r\nconst defaultRootStyle: CSSProperties = {\r\n width: '100%',\r\n height: '100%',\r\n position: 'relative',\r\n overflow: 'hidden',\r\n};\r\n\r\n/** Default styles for the iframe */\r\nconst defaultIframeStyle: CSSProperties = {\r\n width: '100%',\r\n height: '100%',\r\n border: 'none',\r\n};\r\n\r\n/**\r\n * Merge styles with defaults\r\n */\r\nfunction mergeStyles(\r\n defaultStyles: StyleConfig,\r\n propStyles?: StyleConfig\r\n): StyleConfig {\r\n return {\r\n root: { ...defaultStyles.root, ...propStyles?.root },\r\n iframe: { ...defaultStyles.iframe, ...propStyles?.iframe },\r\n };\r\n}\r\n\r\n/**\r\n * Deep merge configs with defaults\r\n */\r\nfunction mergeConfig(\r\n defaultConfig: FormEngineConfig,\r\n propConfig?: FormEngineConfig\r\n): FormEngineConfig {\r\n return {\r\n editor: { ...defaultConfig.editor, ...propConfig?.editor },\r\n layout: { ...defaultConfig.layout, ...propConfig?.layout },\r\n initData: { ...defaultConfig.initData, ...propConfig?.initData },\r\n extraData: { ...defaultConfig.extraData, ...propConfig?.extraData },\r\n previewData: { ...defaultConfig.previewData, ...propConfig?.previewData },\r\n };\r\n}\r\n\r\n/**\r\n * FormEngineWrapper Component\r\n * \r\n * A React component that wraps the FormEngine application in an iframe,\r\n * providing a simple interface for integration with other React applications.\r\n * \r\n * @example\r\n * Basic usage:\r\n * ```tsx\r\n * import { FormEngineWrapper, FormEngineProvider } from '@formengine/wrapper';\r\n * \r\n * function App() {\r\n * return (\r\n * <FormEngineProvider baseUrl=\"https://forms.example.com\">\r\n * <FormEngineWrapper\r\n * refObj=\"Order\"\r\n * refId=\"12345\"\r\n * tplName=\"order-form\"\r\n * mode=\"createOrEdit\"\r\n * onSubmitSuccess={(data) => {\r\n * console.log('Form submitted:', data);\r\n * }}\r\n * />\r\n * </FormEngineProvider>\r\n * );\r\n * }\r\n * ```\r\n * \r\n * @example\r\n * With ref for programmatic control:\r\n * ```tsx\r\n * import { useRef } from 'react';\r\n * import { FormEngineWrapper, FormEngineWrapperRef } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * const formRef = useRef<FormEngineWrapperRef>(null);\r\n * \r\n * const handleExternalSubmit = () => {\r\n * formRef.current?.submit();\r\n * };\r\n * \r\n * const handleGetData = async () => {\r\n * const data = await formRef.current?.getFormData();\r\n * console.log('Form data:', data);\r\n * };\r\n * \r\n * return (\r\n * <>\r\n * <FormEngineWrapper\r\n * ref={formRef}\r\n * refObj=\"Order\"\r\n * refId=\"12345\"\r\n * tplName=\"order-form\"\r\n * />\r\n * <button onClick={handleExternalSubmit}>Submit</button>\r\n * <button onClick={handleGetData}>Get Data</button>\r\n * </>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const FormEngineWrapper = forwardRef<FormEngineWrapperRef, FormEngineWrapperProps>(\r\n (props, ref) => {\r\n const {\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n mode = 'createOrEdit',\r\n styles: propStyles,\r\n config: propConfig,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormLoad,\r\n onFormDataChange,\r\n onMessage,\r\n className,\r\n title = 'FormEngine Form',\r\n allowFullScreen = false,\r\n sandbox = 'allow-same-origin allow-scripts allow-forms allow-popups',\r\n } = props;\r\n \r\n // Get context values\r\n const {\r\n baseUrl,\r\n baseName,\r\n defaultConfig,\r\n defaultStyles,\r\n debug,\r\n } = useFormEngineContext();\r\n \r\n // Refs\r\n const iframeRef = useRef<HTMLIFrameElement>(null);\r\n const formDataResolverRef = useRef<((data: unknown) => void) | null>(null);\r\n \r\n // Merge styles and config with defaults\r\n const mergedStyles = useMemo(\r\n () => mergeStyles(\r\n { root: defaultRootStyle, iframe: defaultIframeStyle, ...defaultStyles },\r\n propStyles\r\n ),\r\n [defaultStyles, propStyles]\r\n );\r\n \r\n const mergedConfig = useMemo(\r\n () => mergeConfig(defaultConfig, propConfig),\r\n [defaultConfig, propConfig]\r\n );\r\n \r\n // Build the iframe URL\r\n const iframeUrl = useMemo(() => {\r\n if (!baseUrl) {\r\n console.warn('FormEngineWrapper: baseUrl is not configured');\r\n return '';\r\n }\r\n \r\n return buildFormEngineUrl({\r\n baseUrl,\r\n baseName,\r\n mode,\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n config: mergedConfig,\r\n });\r\n }, [baseUrl, baseName, mode, refObj, refId, tplName, id, mergedConfig]);\r\n \r\n // Debug logging\r\n useEffect(() => {\r\n if (debug) {\r\n console.log('[FormEngineWrapper] URL:', iframeUrl);\r\n console.log('[FormEngineWrapper] Config:', mergedConfig);\r\n }\r\n }, [debug, iframeUrl, mergedConfig]);\r\n \r\n // Message handler\r\n const handleMessage = useCallback(\r\n (event: MessageEvent) => {\r\n handleFormEngineMessage(event, {\r\n onSubmitStart: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit started:', content);\r\n onSubmitStart?.(content as SubmitEventData);\r\n },\r\n onSubmitSuccess: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit success:', content);\r\n onSubmitSuccess?.(content as SubmitEventData);\r\n },\r\n onSubmitFail: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit failed:', content);\r\n onSubmitFail?.(content as SubmitEventData);\r\n },\r\n onFormDataReturn: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form data returned:', content);\r\n formDataResolverRef.current?.(content.data);\r\n formDataResolverRef.current = null;\r\n },\r\n onFormDataChange: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form data changed:', content);\r\n onFormDataChange?.(content as unknown as FormDataChangeEvent);\r\n },\r\n onFormLoadSuccess: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form loaded:', content);\r\n onFormLoad?.(content as unknown as FormLoadEventData);\r\n },\r\n onFormLoadFail: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form load failed:', content);\r\n },\r\n onAnyMessage: (message) => {\r\n onMessage?.(message);\r\n },\r\n });\r\n },\r\n [\r\n debug,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormLoad,\r\n onFormDataChange,\r\n onMessage,\r\n ]\r\n );\r\n \r\n // Set up message listener\r\n useEffect(() => {\r\n window.addEventListener('message', handleMessage);\r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [handleMessage]);\r\n \r\n // Expose imperative methods via ref\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n submit: () => {\r\n triggerSubmit(iframeRef.current);\r\n },\r\n getFormData: () => {\r\n return requestFormDataAsync(iframeRef.current, 5000);\r\n },\r\n setFormData: (data: unknown) => {\r\n sendFormData(iframeRef.current, data);\r\n },\r\n setFieldLabels: (labels: FieldLabelsMap, merge = true) => {\r\n sendFieldLabels(iframeRef.current, labels, merge);\r\n },\r\n getIframe: () => iframeRef.current,\r\n reload: () => {\r\n if (iframeRef.current) {\r\n iframeRef.current.src = iframeRef.current.src;\r\n }\r\n },\r\n }),\r\n []\r\n );\r\n \r\n // Don't render if no baseUrl\r\n if (!baseUrl) {\r\n return (\r\n <div style={mergedStyles.root} className={className}>\r\n <p style={{ color: 'red', padding: '20px' }}>\r\n Error: FormEngine baseUrl is not configured. \r\n Please wrap this component with FormEngineProvider.\r\n </p>\r\n </div>\r\n );\r\n }\r\n \r\n return (\r\n <div style={mergedStyles.root} className={className}>\r\n <iframe\r\n ref={iframeRef}\r\n src={iframeUrl}\r\n style={mergedStyles.iframe}\r\n title={title}\r\n allowFullScreen={allowFullScreen}\r\n sandbox={sandbox}\r\n />\r\n </div>\r\n );\r\n }\r\n);\r\n\r\n// Display name for React DevTools\r\nFormEngineWrapper.displayName = 'FormEngineWrapper';\r\n\r\nexport default FormEngineWrapper;\r\n","import { useRef, useCallback } from 'react';\r\nimport type { FieldLabelsMap, FormEngineWrapperRef } from '../types';\r\nimport {\r\n triggerSubmit,\r\n sendFormData,\r\n requestFormDataAsync,\r\n sendFieldLabels,\r\n} from '../utils/messageHandler';\r\n\r\n/**\r\n * Options for useFormEngine hook\r\n */\r\nexport interface UseFormEngineOptions {\r\n /** Timeout for async operations in milliseconds */\r\n timeout?: number;\r\n /** Target origin for postMessage (use '*' with caution) */\r\n targetOrigin?: string;\r\n}\r\n\r\n/**\r\n * Return type for useFormEngine hook\r\n */\r\nexport interface UseFormEngineReturn extends FormEngineWrapperRef {\r\n /** Ref to attach to the iframe element */\r\n iframeRef: React.RefObject<HTMLIFrameElement | null>;\r\n}\r\n\r\n/**\r\n * Hook to interact with FormEngine iframe\r\n * \r\n * Provides methods to programmatically interact with the form inside the iframe.\r\n * \r\n * @param options - Configuration options\r\n * @returns Object with iframe ref and control methods\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormEngine } from '@formengine/wrapper';\r\n * \r\n * function MyForm() {\r\n * const { iframeRef, submit, getFormData, setFormData } = useFormEngine();\r\n * \r\n * const handleSubmit = async () => {\r\n * const data = await getFormData();\r\n * console.log('Current form data:', data);\r\n * submit();\r\n * };\r\n * \r\n * return (\r\n * <div>\r\n * <iframe ref={iframeRef} src=\"...\" />\r\n * <button onClick={handleSubmit}>Submit</button>\r\n * </div>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function useFormEngine(options: UseFormEngineOptions = {}): UseFormEngineReturn {\r\n const { timeout = 5000, targetOrigin = '*' } = options;\r\n \r\n const iframeRef = useRef<HTMLIFrameElement>(null);\r\n \r\n /**\r\n * Trigger form submission\r\n */\r\n const submit = useCallback(() => {\r\n triggerSubmit(iframeRef.current, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Get form data asynchronously\r\n */\r\n const getFormData = useCallback(async (): Promise<unknown> => {\r\n return requestFormDataAsync(iframeRef.current, timeout, targetOrigin);\r\n }, [timeout, targetOrigin]);\r\n \r\n /**\r\n * Set form data\r\n */\r\n const setFormData = useCallback((data: unknown) => {\r\n sendFormData(iframeRef.current, data, {}, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Set field labels\r\n */\r\n const setFieldLabels = useCallback((labels: FieldLabelsMap) => {\r\n sendFieldLabels(iframeRef.current, labels, true, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Get the iframe element\r\n */\r\n const getIframe = useCallback(() => {\r\n return iframeRef.current;\r\n }, []);\r\n \r\n /**\r\n * Reload the iframe\r\n */\r\n const reload = useCallback(() => {\r\n if (iframeRef.current) {\r\n iframeRef.current.src = iframeRef.current.src;\r\n }\r\n }, []);\r\n \r\n return {\r\n iframeRef,\r\n submit,\r\n getFormData,\r\n setFormData,\r\n setFieldLabels,\r\n getIframe,\r\n reload,\r\n };\r\n}\r\n\r\nexport default useFormEngine;\r\n","import { useEffect, useCallback, useRef } from 'react';\r\nimport {\r\n handleFormEngineMessage,\r\n isFormEngineMessage,\r\n type MessageHandlers,\r\n} from '../utils/messageHandler';\r\nimport type { MessageObject } from '../types/messages';\r\n\r\n/**\r\n * Options for useFormMessages hook\r\n */\r\nexport interface UseFormMessagesOptions {\r\n /** Whether to enable message listening */\r\n enabled?: boolean;\r\n /** Callback when form submission starts */\r\n onSubmitStart?: (content: Record<string, unknown>) => void;\r\n /** Callback when form submission succeeds */\r\n onSubmitSuccess?: (content: Record<string, unknown>) => void;\r\n /** Callback when form submission fails */\r\n onSubmitFail?: (content: Record<string, unknown>) => void;\r\n /** Callback when form data is returned */\r\n onFormDataReturn?: (content: Record<string, unknown>) => void;\r\n /** Callback when setFormData completes */\r\n onSetFormDataReturn?: (content: Record<string, unknown>) => void;\r\n /** Callback when form loads successfully */\r\n onFormLoadSuccess?: (content: Record<string, unknown>) => void;\r\n /** Callback when form load fails */\r\n onFormLoadFail?: (content: Record<string, unknown>) => void;\r\n /** Callback for any message (useful for debugging) */\r\n onAnyMessage?: (message: MessageObject) => void;\r\n}\r\n\r\n/**\r\n * Hook to listen for messages from FormEngine iframe\r\n * \r\n * Sets up event listeners for postMessage events from the FormEngine iframe\r\n * and routes them to the appropriate callback handlers.\r\n * \r\n * @param options - Message handling options and callbacks\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormMessages } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * useFormMessages({\r\n * onSubmitStart: (data) => {\r\n * console.log('Form submission started:', data);\r\n * setLoading(true);\r\n * },\r\n * onSubmitSuccess: (data) => {\r\n * console.log('Form submitted successfully:', data);\r\n * setLoading(false);\r\n * showSuccessMessage();\r\n * },\r\n * onSubmitFail: (data) => {\r\n * console.log('Form submission failed:', data);\r\n * setLoading(false);\r\n * showErrorMessage();\r\n * },\r\n * });\r\n * \r\n * return <div>...</div>;\r\n * }\r\n * ```\r\n */\r\nexport function useFormMessages(options: UseFormMessagesOptions = {}): void {\r\n const {\r\n enabled = true,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n } = options;\r\n \r\n // Use refs to avoid recreating the handler on every render\r\n const handlersRef = useRef<MessageHandlers>({});\r\n \r\n // Update handlers ref when callbacks change\r\n useEffect(() => {\r\n handlersRef.current = {\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n };\r\n }, [\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n ]);\r\n \r\n // Message event handler\r\n const handleMessage = useCallback((event: MessageEvent) => {\r\n handleFormEngineMessage(event, handlersRef.current);\r\n }, []);\r\n \r\n // Set up message listener\r\n useEffect(() => {\r\n if (!enabled) return;\r\n \r\n window.addEventListener('message', handleMessage);\r\n \r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [enabled, handleMessage]);\r\n}\r\n\r\n/**\r\n * Hook to filter and handle only FormEngine messages\r\n * \r\n * A simpler hook that just filters FormEngine messages and calls a single handler.\r\n * Useful when you want more control over message handling.\r\n * \r\n * @param handler - Callback function for FormEngine messages\r\n * @param enabled - Whether to enable listening\r\n * \r\n * @example\r\n * ```tsx\r\n * useFormEngineMessageListener((message) => {\r\n * switch (message.messageEventName) {\r\n * case 'FormSubmitSuccess':\r\n * handleSuccess(message);\r\n * break;\r\n * case 'FormSubmitFail':\r\n * handleFailure(message);\r\n * break;\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function useFormEngineMessageListener(\r\n handler: (message: MessageObject) => void,\r\n enabled = true\r\n): void {\r\n const handlerRef = useRef(handler);\r\n \r\n useEffect(() => {\r\n handlerRef.current = handler;\r\n }, [handler]);\r\n \r\n useEffect(() => {\r\n if (!enabled) return;\r\n \r\n const handleMessage = (event: MessageEvent) => {\r\n if (isFormEngineMessage(event)) {\r\n handlerRef.current(event.data as MessageObject);\r\n }\r\n };\r\n \r\n window.addEventListener('message', handleMessage);\r\n \r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [enabled]);\r\n}\r\n\r\nexport default useFormMessages;\r\n"],"names":["FormEngineContext","createContext","baseUrl","baseName","defaultConfig","defaultStyles","debug","useFormEngineContext","context","useContext","Error","URL_PARAMS","REF_OBJ","REF_ID","TPL_NAME","EDITOR","EDITOR_SHOW","EDITOR_ENABLE","EDITOR_REQUIRED","MINI","FOOTER","FORM_FOOTER","HISTORY","READ_ONLY","INIT_DATA","EXTRA_DATA","PREVIEW_DATA","ROUTES","CREATE","DUMMY_CREATE","EDIT","CREATE_OR_EDIT","VIEW","encodeBase64","data","jsonString","JSON","stringify","btoa","encodeURIComponent","Buffer","from","toString","buildFormEngineUrl","options","mode","refObj","refId","tplName","id","config","normalizedBaseUrl","replace","routePath","params","URLSearchParams","editor","show","set","enabled","required","defaultValue","layout","mini","showFooter","showHistory","readOnly","showFormFooter","initData","Object","keys","length","extraData","previewData","buildConfigParams","String","queryString","MESSAGE_FROM","FORM_SUBMIT_EVENT_TYPE","GET_FORM_DATA_EVENT_TYPE","SET_FORM_DATA_EVENT_TYPE","SET_FIELD_LABELS_EVENT_TYPE","SUBMIT_START_EVENT_NAME","SUBMIT_RESULT_SUCCESS_EVENT_NAME","SUBMIT_RESULT_FAIL_EVENT_NAME","RETURN_FORM_DATA_EVENT_NAME","RETURN_SET_FORM_DATA_EVENT_NAME","FORM_ONLOAD_SUCCESS_EVENT_NAME","FORM_ONLOAD_FAIL_EVENT_NAME","FORM_DATA_CHANGE_EVENT_NAME","FORM_SUBMIT_EVENT_NAME","GET_FORM_DATA_EVENT_NAME","SET_FORM_DATA_EVENT_NAME","SET_FIELD_LABELS_EVENT_NAME","isFormEngineMessage","event","_a","messageFrom","createMessage","eventType","eventName","content","messageEventType","messageEventName","messageEventContent","postMessageToIframe","iframe","message","targetOrigin","contentWindow","postMessage","error","triggerSubmit","requestFormData","sendFormData","sendFieldLabels","labels","merge","handleFormEngineMessage","handlers","onAnyMessage","call","_b","onSubmitStart","_c","onSubmitSuccess","_d","onSubmitFail","_e","onFormDataReturn","_f","onSetFormDataReturn","_g","onFormLoadSuccess","_h","onFormLoadFail","_i","onFormDataChange","requestFormDataAsync","timeout","Promise","resolve","reject","timeoutId","messageHandler","clearTimeout","window","removeEventListener","addEventListener","setTimeout","defaultRootStyle","width","height","position","overflow","defaultIframeStyle","border","FormEngineWrapper","forwardRef","props","ref","styles","propStyles","propConfig","onFormLoad","onMessage","className","title","allowFullScreen","sandbox","iframeRef","useRef","formDataResolverRef","mergedStyles","useMemo","root","mergeStyles","mergedConfig","mergeConfig","iframeUrl","useEffect","handleMessage","useCallback","current","useImperativeHandle","submit","getFormData","setFormData","setFieldLabels","getIframe","reload","src","jsx","style","children","color","padding","displayName","contextValue","Provider","value","url","urlObj","URL","searchParams","origin","get","async","handler","handlerRef","handlersRef"],"mappings":"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"}
{"version":3,"file":"index.cjs.js","sources":["../src/context/FormEngineContext.tsx","../src/utils/urlBuilder.ts","../src/types/messages.ts","../src/utils/messageHandler.ts","../src/components/FormEngineWrapper.tsx","../src/hooks/useFormEngine.ts","../src/hooks/useFormMessages.ts"],"sourcesContent":["import React, { createContext, useContext, useMemo, type ReactNode } from 'react';\r\nimport type { FormEngineProviderConfig, FormEngineConfig, StyleConfig } from '../types';\r\n\r\n/**\r\n * Context value interface for FormEngine provider\r\n */\r\nexport interface FormEngineContextValue {\r\n /** Base URL of the FormEngine frontend application */\r\n baseUrl: string;\r\n /** Base name/path prefix for the FormEngine routes */\r\n baseName: string;\r\n /** Default configuration for all FormEngineWrapper instances */\r\n defaultConfig: FormEngineConfig;\r\n /** Default styles for all FormEngineWrapper instances */\r\n defaultStyles: StyleConfig;\r\n /** Whether debug mode is enabled */\r\n debug: boolean;\r\n}\r\n\r\n/** Default context values */\r\nconst defaultContextValue: FormEngineContextValue = {\r\n baseUrl: '',\r\n baseName: 'FormEngineV2',\r\n defaultConfig: {},\r\n defaultStyles: {},\r\n debug: false,\r\n};\r\n\r\n/**\r\n * React Context for FormEngine configuration\r\n */\r\nconst FormEngineContext = createContext<FormEngineContextValue>(defaultContextValue);\r\n\r\n/**\r\n * Props for FormEngineProvider component\r\n */\r\nexport interface FormEngineProviderProps extends FormEngineProviderConfig {\r\n /** Child components */\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * Provider component for FormEngine configuration\r\n * \r\n * Wrap your application (or a portion of it) with this provider to configure\r\n * the FormEngine wrapper components with default settings.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { FormEngineProvider } from '@formengine/wrapper';\r\n * \r\n * function App() {\r\n * return (\r\n * <FormEngineProvider\r\n * baseUrl=\"https://forms.example.com\"\r\n * defaultConfig={{\r\n * layout: { mini: true },\r\n * editor: { show: true, enabled: true },\r\n * }}\r\n * >\r\n * <YourApp />\r\n * </FormEngineProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const FormEngineProvider: React.FC<FormEngineProviderProps> = ({\r\n baseUrl = \"/\",\r\n baseName = 'FormEngineV2',\r\n defaultConfig = {},\r\n defaultStyles = {},\r\n debug = false,\r\n children,\r\n}) => {\r\n // Memoize the context value to prevent unnecessary re-renders\r\n const contextValue = useMemo<FormEngineContextValue>(\r\n () => ({\r\n baseUrl,\r\n baseName,\r\n defaultConfig,\r\n defaultStyles,\r\n debug,\r\n }),\r\n [baseUrl, baseName, defaultConfig, defaultStyles, debug]\r\n );\r\n \r\n // Validate required props\r\n if (!baseUrl) {\r\n console.warn('FormEngineProvider: baseUrl is required but was not provided');\r\n }\r\n \r\n return (\r\n <FormEngineContext.Provider value={contextValue}>\r\n {children}\r\n </FormEngineContext.Provider>\r\n );\r\n};\r\n\r\n/**\r\n * Hook to access FormEngine context\r\n * \r\n * @returns The FormEngine context value\r\n * @throws Error if used outside of FormEngineProvider\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormEngineContext } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * const { baseUrl, debug } = useFormEngineContext();\r\n * \r\n * if (debug) {\r\n * console.log('FormEngine baseUrl:', baseUrl);\r\n * }\r\n * \r\n * return <div>...</div>;\r\n * }\r\n * ```\r\n */\r\nexport const useFormEngineContext = (): FormEngineContextValue => {\r\n const context = useContext(FormEngineContext);\r\n \r\n if (!context) {\r\n throw new Error(\r\n 'useFormEngineContext must be used within a FormEngineProvider. ' +\r\n 'Wrap your component tree with <FormEngineProvider> to fix this error.'\r\n );\r\n }\r\n \r\n return context;\r\n};\r\n\r\n/**\r\n * Hook to get the configured base URL\r\n */\r\nexport const useFormEngineBaseUrl = (): string => {\r\n const { baseUrl } = useFormEngineContext();\r\n return baseUrl;\r\n};\r\n\r\n/**\r\n * Hook to check if debug mode is enabled\r\n */\r\nexport const useFormEngineDebug = (): boolean => {\r\n const { debug } = useFormEngineContext();\r\n return debug;\r\n};\r\n\r\nexport { FormEngineContext };\r\n","import type { FormMode, FormEngineConfig } from '../types';\r\n\r\n/**\r\n * URL parameter keys for FormEngine routes\r\n */\r\nexport const URL_PARAMS = {\r\n REF_OBJ: 'refObj',\r\n REF_ID: 'refId',\r\n TPL_NAME: 'tplName',\r\n EDITOR: 'editor',\r\n EDITOR_SHOW: 'editorShow',\r\n EDITOR_ENABLE: 'editorEnable',\r\n EDITOR_REQUIRED: 'editorRequired',\r\n MINI: 'st_mini',\r\n FOOTER: 'footer',\r\n FORM_FOOTER: 'form_footer',\r\n HISTORY: 'history_show',\r\n READ_ONLY: 'readOnly',\r\n INIT_DATA: 'initData',\r\n EXTRA_DATA: 'extraData',\r\n PREVIEW_DATA: 'previewData',\r\n} as const;\r\n\r\n/**\r\n * Route paths for different form modes\r\n */\r\nexport const ROUTES = {\r\n CREATE: '/form-data/create',\r\n DUMMY_CREATE: '/form-data/dummy-create',\r\n EDIT: '/form-data/edit',\r\n CREATE_OR_EDIT: '/form-data/createOrEdit',\r\n VIEW: '/form-data/view',\r\n} as const;\r\n\r\n/**\r\n * Options for building the iframe URL\r\n */\r\nexport interface BuildUrlOptions {\r\n /** Base URL of the FormEngine application */\r\n baseUrl: string;\r\n /** Base name/path prefix (default: 'FormEngineV2') */\r\n baseName?: string;\r\n /** Form operation mode */\r\n mode: FormMode;\r\n /** Reference object identifier */\r\n refObj: string;\r\n /** Reference ID */\r\n refId: string | number;\r\n /** Template name */\r\n tplName: string;\r\n /** Form data ID (required for edit/view modes) */\r\n id?: number | string;\r\n /** Form configuration */\r\n config?: FormEngineConfig;\r\n}\r\n\r\n/**\r\n * Encode an object to base64 string for URL parameter\r\n */\r\nexport function encodeBase64(data: Record<string, unknown>): string {\r\n try {\r\n const jsonString = JSON.stringify(data);\r\n // Use btoa for browser environment, or Buffer for Node.js\r\n if (typeof btoa === 'function') {\r\n return btoa(encodeURIComponent(jsonString));\r\n }\r\n return Buffer.from(jsonString).toString('base64');\r\n } catch {\r\n console.error('Failed to encode data to base64');\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Build URL parameters from config\r\n */\r\nfunction buildConfigParams(config?: FormEngineConfig): URLSearchParams {\r\n const params = new URLSearchParams();\r\n \r\n if (!config) return params;\r\n \r\n // Editor config\r\n if (config.editor) {\r\n if (config.editor.show !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_SHOW, config.editor.show ? '1' : '0');\r\n }\r\n if (config.editor.enabled !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_ENABLE, config.editor.enabled ? '1' : '0');\r\n }\r\n if (config.editor.required !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_REQUIRED, config.editor.required ? '1' : '0');\r\n }\r\n if (config.editor.defaultValue) {\r\n params.set(URL_PARAMS.EDITOR, config.editor.defaultValue);\r\n }\r\n }\r\n \r\n // Layout config\r\n if (config.layout) {\r\n if (config.layout.mini !== undefined) {\r\n params.set(URL_PARAMS.MINI, config.layout.mini ? '1' : '0');\r\n }\r\n if (config.layout.showFooter !== undefined) {\r\n params.set(URL_PARAMS.FOOTER, config.layout.showFooter ? '1' : '0');\r\n }\r\n if (config.layout.showHistory !== undefined) {\r\n params.set(URL_PARAMS.HISTORY, config.layout.showHistory ? '1' : '0');\r\n }\r\n if (config.layout.readOnly !== undefined) {\r\n params.set(URL_PARAMS.READ_ONLY, config.layout.readOnly ? '1' : '0');\r\n }\r\n if (config.layout.showFormFooter !== undefined) {\r\n params.set(URL_PARAMS.FORM_FOOTER, config.layout.showFormFooter ? '1' : '0');\r\n }\r\n }\r\n \r\n // Data params\r\n if (config.initData && Object.keys(config.initData).length > 0) {\r\n params.set(URL_PARAMS.INIT_DATA, encodeURIComponent(JSON.stringify(config.initData)));\r\n }\r\n \r\n if (config.extraData && Object.keys(config.extraData).length > 0) {\r\n params.set(URL_PARAMS.EXTRA_DATA, encodeBase64(config.extraData));\r\n }\r\n \r\n if (config.previewData && Object.keys(config.previewData).length > 0) {\r\n params.set(URL_PARAMS.PREVIEW_DATA, encodeURIComponent(JSON.stringify(config.previewData)));\r\n }\r\n \r\n return params;\r\n}\r\n\r\n/**\r\n * Build the full iframe URL for FormEngine\r\n * \r\n * @param options - URL building options\r\n * @returns The complete URL string for the iframe\r\n * \r\n * @example\r\n * ```typescript\r\n * const url = buildFormEngineUrl({\r\n * baseUrl: 'https://forms.example.com',\r\n * mode: 'createOrEdit',\r\n * refObj: 'Order',\r\n * refId: '12345',\r\n * tplName: 'order-form',\r\n * });\r\n * // => \"https://forms.example.com/FormEngineV2/form-data/createOrEdit?refObj=Order&refId=12345&tplName=order-form\"\r\n * ```\r\n */\r\nexport function buildFormEngineUrl(options: BuildUrlOptions): string {\r\n const {\r\n baseUrl,\r\n baseName = 'FormEngineV2',\r\n mode,\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n config,\r\n } = options;\r\n \r\n // Normalize base URL (remove trailing slash)\r\n const normalizedBaseUrl = baseUrl.replace(/\\/+$/, '');\r\n \r\n // Build the route path based on mode\r\n let routePath: string;\r\n \r\n switch (mode) {\r\n case 'create':\r\n routePath = ROUTES.CREATE;\r\n break;\r\n case 'edit':\r\n case 'view':\r\n if (!id) {\r\n console.warn(`Mode \"${mode}\" requires an id. Falling back to createOrEdit.`);\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n } else {\r\n routePath = `${ROUTES.EDIT}/${id}`;\r\n }\r\n break;\r\n case 'createOrEdit':\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n break;\r\n case 'dummy-create':\r\n routePath = ROUTES.DUMMY_CREATE;\r\n break;\r\n default:\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n break;\r\n }\r\n \r\n // Build query parameters\r\n const params = buildConfigParams(config);\r\n params.set(URL_PARAMS.REF_OBJ, refObj);\r\n params.set(URL_PARAMS.REF_ID, String(refId));\r\n params.set(URL_PARAMS.TPL_NAME, tplName);\r\n \r\n // For view mode, set readOnly\r\n if (mode === 'view') {\r\n params.set(URL_PARAMS.READ_ONLY, '1');\r\n }\r\n \r\n // Construct the full URL\r\n const queryString = params.toString();\r\n const fullPath = baseName ? `/${baseName}${routePath}` : routePath;\r\n \r\n return `${normalizedBaseUrl}${fullPath}${queryString ? `?${queryString}` : ''}`;\r\n}\r\n\r\n/**\r\n * Parse a FormEngine URL to extract its components\r\n * Useful for debugging or validation\r\n */\r\nexport function parseFormEngineUrl(url: string): Partial<BuildUrlOptions> | null {\r\n try {\r\n const urlObj = new URL(url);\r\n const params = urlObj.searchParams;\r\n \r\n return {\r\n baseUrl: urlObj.origin,\r\n refObj: params.get(URL_PARAMS.REF_OBJ) || undefined,\r\n refId: params.get(URL_PARAMS.REF_ID) || undefined,\r\n tplName: params.get(URL_PARAMS.TPL_NAME) || undefined,\r\n };\r\n } catch {\r\n console.error('Failed to parse FormEngine URL');\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Message types for communication between FormEngineWrapper and FormEngine iframe\r\n * These types mirror the FormEngine's internal message system\r\n */\r\n\r\nimport { FieldLabelsMap } from \"./config\";\r\n\r\n\r\n/** Identifier for messages from FormEngine */\r\nexport const MESSAGE_FROM = 'MTG_FORMENGINE';\r\n\r\n// =============================================================================\r\n// Event Types - Categories of messages\r\n// =============================================================================\r\n\r\n/** Event types sent FROM FormEngine TO parent window */\r\nexport const SUBMIT_START_EVENT_TYPE = 'submit_start' as const;\r\nexport const SUBMIT_RESULT_EVENT_TYPE = 'submit_result' as const;\r\nexport const RETURN_FORM_DATA_EVENT_TYPE = 'return_form_data' as const;\r\nexport const RETURN_SET_FORM_DATA_EVENT_TYPE = 'return_set_form_data' as const;\r\nexport const FORM_ONLOAD_EVENT_TYPE = 'form_onload' as const;\r\nexport const FORM_DATA_CHANGE_EVENT_TYPE = 'form_data_change' as const;\r\n\r\n/** Event types sent FROM parent TO FormEngine */\r\nexport const FORM_SUBMIT_EVENT_TYPE = 'submit' as const;\r\nexport const GET_FORM_DATA_EVENT_TYPE = 'get_form_data' as const;\r\nexport const SET_FORM_DATA_EVENT_TYPE = 'set_form_data' as const;\r\nexport const SET_FIELD_LABELS_EVENT_TYPE = 'set_field_labels' as const;\r\n\r\n// =============================================================================\r\n// Event Names - Specific events within each type\r\n// =============================================================================\r\n\r\n/** Event names FROM FormEngine */\r\nexport const SUBMIT_START_EVENT_NAME = 'FormSubmitStart' as const;\r\nexport const SUBMIT_RESULT_SUCCESS_EVENT_NAME = 'FormSubmitSuccess' as const;\r\nexport const SUBMIT_RESULT_FAIL_EVENT_NAME = 'FormSubmitFail' as const;\r\nexport const RETURN_FORM_DATA_EVENT_NAME = 'ReturnFormData' as const;\r\nexport const RETURN_SET_FORM_DATA_EVENT_NAME = 'ReturnSetFormData' as const;\r\nexport const FORM_ONLOAD_SUCCESS_EVENT_NAME = 'FormOnLoadSuccess' as const;\r\nexport const FORM_ONLOAD_FAIL_EVENT_NAME = 'FormOnLoadFail' as const;\r\nexport const FORM_DATA_CHANGE_EVENT_NAME = 'FormDataChange' as const;\r\n\r\n/** Event names TO FormEngine */\r\nexport const FORM_SUBMIT_EVENT_NAME = 'Submit' as const;\r\nexport const GET_FORM_DATA_EVENT_NAME = 'GetFormData' as const;\r\nexport const SET_FORM_DATA_EVENT_NAME = 'SetFormData' as const;\r\nexport const SET_FIELD_LABELS_EVENT_NAME = 'SetFieldLabels' as const;\r\n\r\n// =============================================================================\r\n// Type Definitions\r\n// =============================================================================\r\n\r\n/** Event types from FormEngine to parent */\r\nexport type MessageEventTypeFromFormEngine =\r\n | typeof SUBMIT_START_EVENT_TYPE\r\n | typeof SUBMIT_RESULT_EVENT_TYPE\r\n | typeof RETURN_FORM_DATA_EVENT_TYPE\r\n | typeof RETURN_SET_FORM_DATA_EVENT_TYPE\r\n | typeof FORM_ONLOAD_EVENT_TYPE\r\n | typeof FORM_DATA_CHANGE_EVENT_TYPE;\r\n\r\n/** Event names from FormEngine to parent */\r\nexport type MessageEventNameFromFormEngine =\r\n | typeof SUBMIT_START_EVENT_NAME\r\n | typeof SUBMIT_RESULT_SUCCESS_EVENT_NAME\r\n | typeof SUBMIT_RESULT_FAIL_EVENT_NAME\r\n | typeof RETURN_FORM_DATA_EVENT_NAME\r\n | typeof RETURN_SET_FORM_DATA_EVENT_NAME\r\n | typeof FORM_ONLOAD_SUCCESS_EVENT_NAME\r\n | typeof FORM_ONLOAD_FAIL_EVENT_NAME\r\n | typeof FORM_DATA_CHANGE_EVENT_NAME;\r\n\r\n/** Event types from parent to FormEngine */\r\nexport type MessageEventTypeToFormEngine =\r\n | typeof FORM_SUBMIT_EVENT_TYPE\r\n | typeof GET_FORM_DATA_EVENT_TYPE\r\n | typeof SET_FORM_DATA_EVENT_TYPE\r\n | typeof SET_FIELD_LABELS_EVENT_TYPE;\r\n\r\n/** Event names from parent to FormEngine */\r\nexport type MessageEventNameToFormEngine =\r\n | typeof FORM_SUBMIT_EVENT_NAME\r\n | typeof GET_FORM_DATA_EVENT_NAME\r\n | typeof SET_FORM_DATA_EVENT_NAME\r\n | typeof SET_FIELD_LABELS_EVENT_NAME;\r\n\r\n/** All possible message event types */\r\nexport type MessageEventType = MessageEventTypeFromFormEngine | MessageEventTypeToFormEngine;\r\n\r\n/** All possible message event names */\r\nexport type MessageEventName = MessageEventNameFromFormEngine | MessageEventNameToFormEngine;\r\n\r\n// =============================================================================\r\n// Message Object Interfaces\r\n// =============================================================================\r\n\r\n/**\r\n * Base message object interface for FormEngine communication\r\n */\r\nexport interface MessageObject {\r\n /** Source identifier for the message */\r\n messageFrom: string;\r\n /** The specific event name */\r\n messageEventName: MessageEventName;\r\n /** The category of the event */\r\n messageEventType: MessageEventType;\r\n /** The payload of the message */\r\n messageEventContent: any;\r\n /** Whether the operation was successful (for response messages) */\r\n success?: boolean;\r\n}\r\n\r\n/**\r\n * Content structure for submit-related messages\r\n */\r\nexport interface SubmitMessageContent {\r\n /** Form data ID (present when editing existing form) */\r\n id?: number;\r\n /** Template name */\r\n tplName?: string;\r\n /** Reference object identifier */\r\n refObj?: string;\r\n /** Reference ID */\r\n refId?: string | number;\r\n /** Type of submit operation */\r\n submitType?: 'createOrEdit' | 'edit' | 'create' | 'dummy-create';\r\n /** Additional data */\r\n extra?: unknown;\r\n}\r\n\r\n/**\r\n * Message for setting form data\r\n */\r\nexport interface SetFormDataMessage extends Omit<MessageObject, 'messageEventContent' | 'messageEventName'> {\r\n messageEventName: typeof SET_FORM_DATA_EVENT_NAME;\r\n messageEventType: typeof SET_FORM_DATA_EVENT_TYPE;\r\n messageEventContent: {\r\n id?: string | number;\r\n tplName?: string;\r\n data: unknown;\r\n };\r\n}\r\n\r\n/**\r\n * Message for getting form data response\r\n */\r\nexport interface ReturnFormDataMessage extends MessageObject {\r\n messageEventName: typeof RETURN_FORM_DATA_EVENT_NAME;\r\n messageEventType: typeof RETURN_FORM_DATA_EVENT_TYPE;\r\n messageEventContent: {\r\n id?: string | number;\r\n data: unknown;\r\n };\r\n}\r\n\r\n/**\r\n * Form information in onload messages\r\n */\r\nexport interface FormOnLoadMessageForm {\r\n /** Form data ID */\r\n id?: number;\r\n /** Reference object */\r\n refObj?: string;\r\n /** Reference ID */\r\n refId?: string;\r\n /** Template name */\r\n tplName: string;\r\n /** Template display title */\r\n templateTitle: string;\r\n}\r\n\r\n/**\r\n * Content for form onload messages\r\n */\r\nexport interface FormOnLoadMessageContent {\r\n /** Whether the form has child forms */\r\n hasChildren: boolean;\r\n /** Number of tabs (for tabular forms) */\r\n tabCount: number;\r\n /** Parent form information */\r\n form: FormOnLoadMessageForm;\r\n /** Child forms information */\r\n childrenForms: FormOnLoadMessageForm[];\r\n}\r\n\r\n/**\r\n * Submit start message from FormEngine\r\n */\r\nexport interface SubmitStartMessage extends MessageObject {\r\n messageEventName: typeof SUBMIT_START_EVENT_NAME;\r\n messageEventType: typeof SUBMIT_START_EVENT_TYPE;\r\n messageEventContent: SubmitMessageContent;\r\n}\r\n\r\n/**\r\n * Submit result message from FormEngine\r\n */\r\nexport interface SubmitResultMessage extends MessageObject {\r\n messageEventName: typeof SUBMIT_RESULT_SUCCESS_EVENT_NAME | typeof SUBMIT_RESULT_FAIL_EVENT_NAME;\r\n messageEventType: typeof SUBMIT_RESULT_EVENT_TYPE;\r\n messageEventContent: SubmitMessageContent;\r\n}\r\n\r\n/**\r\n * Form onload message from FormEngine\r\n */\r\nexport interface FormOnLoadMessage extends MessageObject {\r\n messageEventName: typeof FORM_ONLOAD_SUCCESS_EVENT_NAME | typeof FORM_ONLOAD_FAIL_EVENT_NAME;\r\n messageEventType: typeof FORM_ONLOAD_EVENT_TYPE;\r\n messageEventContent: FormOnLoadMessageContent;\r\n}\r\n\r\n/**\r\n * Content for form data change messages\r\n */\r\nexport interface FormDataChangeMessageContent {\r\n /** The path/field that changed (e.g., \"root_field1\" or \"root_section_field2\") */\r\n path?: string;\r\n /** The new value of the changed field */\r\n value?: unknown;\r\n /** The complete form data after the change */\r\n formData: unknown;\r\n /** Form ID if available */\r\n id?: string | number;\r\n /** Template name */\r\n tplName?: string;\r\n}\r\n\r\n/**\r\n * Form data change message from FormEngine\r\n */\r\nexport interface FormDataChangeMessage extends MessageObject {\r\n messageEventName: typeof FORM_DATA_CHANGE_EVENT_NAME;\r\n messageEventType: typeof FORM_DATA_CHANGE_EVENT_TYPE;\r\n messageEventContent: FormDataChangeMessageContent;\r\n}\r\n\r\n/**\r\n * Message content for setting field labels\r\n */\r\nexport interface SetFieldLabelsMessageContent {\r\n /** Map of pathId to label config */\r\n labels: FieldLabelsMap;\r\n /** Whether to merge with existing labels (true) or replace all (false) */\r\n merge?: boolean;\r\n}\r\n\r\n/**\r\n * Message for setting field labels\r\n */\r\nexport interface SetFieldLabelsMessage extends MessageObject {\r\n messageEventType: typeof SET_FIELD_LABELS_EVENT_TYPE;\r\n messageEventName: typeof SET_FIELD_LABELS_EVENT_NAME;\r\n messageEventContent: SetFieldLabelsMessageContent;\r\n}\r\n","import { FieldLabelsMap } from '../types';\r\nimport {\r\n MESSAGE_FROM,\r\n SUBMIT_START_EVENT_NAME,\r\n SUBMIT_RESULT_SUCCESS_EVENT_NAME,\r\n SUBMIT_RESULT_FAIL_EVENT_NAME,\r\n RETURN_FORM_DATA_EVENT_NAME,\r\n RETURN_SET_FORM_DATA_EVENT_NAME,\r\n FORM_ONLOAD_SUCCESS_EVENT_NAME,\r\n FORM_ONLOAD_FAIL_EVENT_NAME,\r\n FORM_DATA_CHANGE_EVENT_NAME,\r\n FORM_SUBMIT_EVENT_TYPE,\r\n FORM_SUBMIT_EVENT_NAME,\r\n GET_FORM_DATA_EVENT_TYPE,\r\n GET_FORM_DATA_EVENT_NAME,\r\n SET_FORM_DATA_EVENT_TYPE,\r\n SET_FORM_DATA_EVENT_NAME,\r\n SET_FIELD_LABELS_EVENT_TYPE,\r\n SET_FIELD_LABELS_EVENT_NAME,\r\n type MessageObject,\r\n type MessageEventType,\r\n type MessageEventName,\r\n} from '../types/messages';\r\n\r\n/** Identifier for messages from the wrapper */\r\nconst WRAPPER_MESSAGE_FROM = 'FORMENGINE_WRAPPER';\r\n\r\n/**\r\n * Check if a message is from FormEngine\r\n */\r\nexport function isFormEngineMessage(event: MessageEvent): boolean {\r\n return event.data?.messageFrom === MESSAGE_FROM;\r\n}\r\n\r\n/**\r\n * Create a message object to send to FormEngine\r\n */\r\nfunction createMessage(\r\n eventType: MessageEventType,\r\n eventName: MessageEventName,\r\n content: Record<string, unknown> = {}\r\n): MessageObject {\r\n return {\r\n messageFrom: WRAPPER_MESSAGE_FROM,\r\n messageEventType: eventType,\r\n messageEventName: eventName,\r\n messageEventContent: content,\r\n };\r\n}\r\n\r\n/**\r\n * Send a message to the FormEngine iframe\r\n */\r\nexport function postMessageToIframe(\r\n iframe: HTMLIFrameElement | null,\r\n message: MessageObject,\r\n targetOrigin = '*'\r\n): boolean {\r\n if (!iframe?.contentWindow) {\r\n console.warn('Cannot post message: iframe or contentWindow is null');\r\n return false;\r\n }\r\n \r\n try {\r\n iframe.contentWindow.postMessage(message, targetOrigin);\r\n return true;\r\n } catch (error) {\r\n console.error('Failed to post message to iframe:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Trigger form submission in the iframe\r\n */\r\nexport function triggerSubmit(\r\n iframe: HTMLIFrameElement | null,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n FORM_SUBMIT_EVENT_TYPE,\r\n FORM_SUBMIT_EVENT_NAME\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Request form data from the iframe\r\n */\r\nexport function requestFormData(\r\n iframe: HTMLIFrameElement | null,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n GET_FORM_DATA_EVENT_TYPE,\r\n GET_FORM_DATA_EVENT_NAME\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Set form data in the iframe\r\n */\r\nexport function sendFormData(\r\n iframe: HTMLIFrameElement | null,\r\n data: unknown,\r\n options: { id?: string | number; tplName?: string } = {},\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n SET_FORM_DATA_EVENT_TYPE,\r\n SET_FORM_DATA_EVENT_NAME,\r\n {\r\n ...options,\r\n data,\r\n }\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Set field labels in the iframe\r\n * \r\n * @param iframe - The iframe element\r\n * @param labels - Map of pathId to label configuration\r\n * @param merge - Whether to merge with existing labels (default: true)\r\n * @param targetOrigin - Target origin for postMessage\r\n * \r\n * @example\r\n * ```typescript\r\n * sendFieldLabels(iframeRef.current, {\r\n * 'root_firstName': {\r\n * content: 'Edited by John @ 2024-01-01',\r\n * style: { color: 'blue', fontStyle: 'italic' }\r\n * },\r\n * 'root_lastName': {\r\n * content: 'Required field',\r\n * style: { color: 'red' }\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function sendFieldLabels(\r\n iframe: HTMLIFrameElement | null,\r\n labels: FieldLabelsMap,\r\n merge = true,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n SET_FIELD_LABELS_EVENT_TYPE,\r\n SET_FIELD_LABELS_EVENT_NAME,\r\n {\r\n labels,\r\n merge,\r\n }\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Message handler callback types\r\n */\r\nexport interface MessageHandlers {\r\n onSubmitStart?: (content: Record<string, unknown>) => void;\r\n onSubmitSuccess?: (content: Record<string, unknown>) => void;\r\n onSubmitFail?: (content: Record<string, unknown>) => void;\r\n onFormDataReturn?: (content: Record<string, unknown>) => void;\r\n onSetFormDataReturn?: (content: Record<string, unknown>) => void;\r\n onFormLoadSuccess?: (content: Record<string, unknown>) => void;\r\n onFormLoadFail?: (content: Record<string, unknown>) => void;\r\n onFormDataChange?: (content: Record<string, unknown>) => void;\r\n onAnyMessage?: (message: MessageObject) => void;\r\n}\r\n\r\n/**\r\n * Handle incoming messages from FormEngine\r\n */\r\nexport function handleFormEngineMessage(\r\n event: MessageEvent,\r\n handlers: MessageHandlers\r\n): void {\r\n // Validate message source\r\n if (!isFormEngineMessage(event)) {\r\n return;\r\n }\r\n \r\n const message = event.data as MessageObject;\r\n \r\n // Call the generic message handler\r\n handlers.onAnyMessage?.(message);\r\n \r\n // Route to specific handlers based on event name\r\n switch (message.messageEventName) {\r\n case SUBMIT_START_EVENT_NAME:\r\n handlers.onSubmitStart?.(message.messageEventContent);\r\n break;\r\n \r\n case SUBMIT_RESULT_SUCCESS_EVENT_NAME:\r\n handlers.onSubmitSuccess?.(message.messageEventContent);\r\n break;\r\n \r\n case SUBMIT_RESULT_FAIL_EVENT_NAME:\r\n handlers.onSubmitFail?.(message.messageEventContent);\r\n break;\r\n \r\n case RETURN_FORM_DATA_EVENT_NAME:\r\n handlers.onFormDataReturn?.(message.messageEventContent);\r\n break;\r\n \r\n case RETURN_SET_FORM_DATA_EVENT_NAME:\r\n handlers.onSetFormDataReturn?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_ONLOAD_SUCCESS_EVENT_NAME:\r\n handlers.onFormLoadSuccess?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_ONLOAD_FAIL_EVENT_NAME:\r\n handlers.onFormLoadFail?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_DATA_CHANGE_EVENT_NAME:\r\n handlers.onFormDataChange?.(message.messageEventContent);\r\n break;\r\n \r\n default:\r\n // Unknown message type - already logged via onAnyMessage if handler provided\r\n break;\r\n }\r\n}\r\n\r\n/**\r\n * Create a promise-based form data request\r\n * Returns a promise that resolves when form data is received\r\n */\r\nexport function requestFormDataAsync(\r\n iframe: HTMLIFrameElement | null,\r\n timeout = 5000,\r\n targetOrigin = '*'\r\n): Promise<unknown> {\r\n return new Promise((resolve, reject) => {\r\n if (!iframe) {\r\n reject(new Error('Iframe is null'));\r\n return;\r\n }\r\n \r\n let timeoutId: ReturnType<typeof setTimeout>;\r\n \r\n const messageHandler = (event: MessageEvent) => {\r\n if (!isFormEngineMessage(event)) return;\r\n \r\n const message = event.data as MessageObject;\r\n if (message.messageEventName === RETURN_FORM_DATA_EVENT_NAME) {\r\n clearTimeout(timeoutId);\r\n window.removeEventListener('message', messageHandler);\r\n resolve(message.messageEventContent.data);\r\n }\r\n };\r\n \r\n window.addEventListener('message', messageHandler);\r\n \r\n // Set timeout for the request\r\n timeoutId = setTimeout(() => {\r\n window.removeEventListener('message', messageHandler);\r\n reject(new Error('Form data request timed out'));\r\n }, timeout);\r\n \r\n // Send the request\r\n if (!requestFormData(iframe, targetOrigin)) {\r\n clearTimeout(timeoutId);\r\n window.removeEventListener('message', messageHandler);\r\n reject(new Error('Failed to send form data request'));\r\n }\r\n });\r\n}\r\n","import React, {\r\n forwardRef,\r\n useImperativeHandle,\r\n useEffect,\r\n useCallback,\r\n useMemo,\r\n useRef,\r\n type CSSProperties,\r\n} from 'react';\r\nimport type {\r\n FormEngineWrapperProps,\r\n FormEngineWrapperRef,\r\n StyleConfig,\r\n FormEngineConfig,\r\n SubmitEventData,\r\n FormLoadEventData,\r\n FormDataChangeEvent,\r\n} from '../types';\r\nimport { useFormEngineContext } from '../context';\r\nimport { buildFormEngineUrl } from '../utils/urlBuilder';\r\nimport {\r\n handleFormEngineMessage,\r\n triggerSubmit,\r\n sendFormData,\r\n sendFieldLabels,\r\n requestFormDataAsync,\r\n} from '../utils/messageHandler';\r\nimport type { FieldLabelsMap } from '../types/config';\r\n\r\n/** Default styles for the wrapper container */\r\nconst defaultRootStyle: CSSProperties = {\r\n width: '100%',\r\n height: '100%',\r\n position: 'relative',\r\n overflow: 'hidden',\r\n};\r\n\r\n/** Default styles for the iframe */\r\nconst defaultIframeStyle: CSSProperties = {\r\n width: '100%',\r\n height: '100%',\r\n border: 'none',\r\n};\r\n\r\n/**\r\n * Merge styles with defaults\r\n */\r\nfunction mergeStyles(\r\n defaultStyles: StyleConfig,\r\n propStyles?: StyleConfig\r\n): StyleConfig {\r\n return {\r\n container: { ...defaultStyles.container, ...propStyles?.container },\r\n iframe: { ...defaultStyles.iframe, ...propStyles?.iframe },\r\n };\r\n}\r\n\r\n/**\r\n * Deep merge configs with defaults\r\n */\r\nfunction mergeConfig(\r\n defaultConfig: FormEngineConfig,\r\n propConfig?: FormEngineConfig\r\n): FormEngineConfig {\r\n return {\r\n editor: { ...defaultConfig.editor, ...propConfig?.editor },\r\n layout: { ...defaultConfig.layout, ...propConfig?.layout },\r\n initData: { ...defaultConfig.initData, ...propConfig?.initData },\r\n extraData: { ...defaultConfig.extraData, ...propConfig?.extraData },\r\n previewData: { ...defaultConfig.previewData, ...propConfig?.previewData },\r\n };\r\n}\r\n\r\n/**\r\n * FormEngineWrapper Component\r\n * \r\n * A React component that wraps the FormEngine application in an iframe,\r\n * providing a simple interface for integration with other React applications.\r\n * \r\n * @example\r\n * Basic usage:\r\n * ```tsx\r\n * import { FormEngineWrapper, FormEngineProvider } from '@formengine/wrapper';\r\n * \r\n * function App() {\r\n * return (\r\n * <FormEngineProvider baseUrl=\"https://forms.example.com\">\r\n * <FormEngineWrapper\r\n * refObj=\"Order\"\r\n * refId=\"12345\"\r\n * tplName=\"order-form\"\r\n * mode=\"createOrEdit\"\r\n * onSubmitSuccess={(data) => {\r\n * console.log('Form submitted:', data);\r\n * }}\r\n * />\r\n * </FormEngineProvider>\r\n * );\r\n * }\r\n * ```\r\n * \r\n * @example\r\n * With ref for programmatic control:\r\n * ```tsx\r\n * import { useRef } from 'react';\r\n * import { FormEngineWrapper, FormEngineWrapperRef } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * const formRef = useRef<FormEngineWrapperRef>(null);\r\n * \r\n * const handleExternalSubmit = () => {\r\n * formRef.current?.submit();\r\n * };\r\n * \r\n * const handleGetData = async () => {\r\n * const data = await formRef.current?.getFormData();\r\n * console.log('Form data:', data);\r\n * };\r\n * \r\n * return (\r\n * <>\r\n * <FormEngineWrapper\r\n * ref={formRef}\r\n * refObj=\"Order\"\r\n * refId=\"12345\"\r\n * tplName=\"order-form\"\r\n * />\r\n * <button onClick={handleExternalSubmit}>Submit</button>\r\n * <button onClick={handleGetData}>Get Data</button>\r\n * </>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const FormEngineWrapper = forwardRef<FormEngineWrapperRef, FormEngineWrapperProps>(\r\n (props, ref) => {\r\n const {\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n mode = 'createOrEdit',\r\n styles: propStyles,\r\n config: propConfig,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormLoad,\r\n onFormDataChange,\r\n onMessage,\r\n className,\r\n title = 'FormEngine Form',\r\n allowFullScreen = false,\r\n sandbox = 'allow-same-origin allow-scripts allow-forms allow-popups',\r\n } = props;\r\n \r\n // Get context values\r\n const {\r\n baseUrl,\r\n baseName,\r\n defaultConfig,\r\n defaultStyles,\r\n debug,\r\n } = useFormEngineContext();\r\n \r\n // Refs\r\n const iframeRef = useRef<HTMLIFrameElement>(null);\r\n const formDataResolverRef = useRef<((data: unknown) => void) | null>(null);\r\n \r\n // Merge styles and config with defaults\r\n const mergedStyles = useMemo(\r\n () => mergeStyles(\r\n { container: defaultRootStyle, iframe: defaultIframeStyle, ...defaultStyles },\r\n propStyles\r\n ),\r\n [defaultStyles, propStyles]\r\n );\r\n \r\n const mergedConfig = useMemo(\r\n () => mergeConfig(defaultConfig, propConfig),\r\n [defaultConfig, propConfig]\r\n );\r\n \r\n // Build the iframe URL\r\n const iframeUrl = useMemo(() => {\r\n if (!baseUrl) {\r\n console.warn('FormEngineWrapper: baseUrl is not configured');\r\n return '';\r\n }\r\n \r\n return buildFormEngineUrl({\r\n baseUrl,\r\n baseName,\r\n mode,\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n config: mergedConfig,\r\n });\r\n }, [baseUrl, baseName, mode, refObj, refId, tplName, id, mergedConfig]);\r\n \r\n // Debug logging\r\n useEffect(() => {\r\n if (debug) {\r\n console.log('[FormEngineWrapper] URL:', iframeUrl);\r\n console.log('[FormEngineWrapper] Config:', mergedConfig);\r\n }\r\n }, [debug, iframeUrl, mergedConfig]);\r\n \r\n // Message handler\r\n const handleMessage = useCallback(\r\n (event: MessageEvent) => {\r\n handleFormEngineMessage(event, {\r\n onSubmitStart: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit started:', content);\r\n onSubmitStart?.(content as SubmitEventData);\r\n },\r\n onSubmitSuccess: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit success:', content);\r\n onSubmitSuccess?.(content as SubmitEventData);\r\n },\r\n onSubmitFail: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit failed:', content);\r\n onSubmitFail?.(content as SubmitEventData);\r\n },\r\n onFormDataReturn: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form data returned:', content);\r\n formDataResolverRef.current?.(content.data);\r\n formDataResolverRef.current = null;\r\n },\r\n onFormDataChange: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form data changed:', content);\r\n onFormDataChange?.(content as unknown as FormDataChangeEvent);\r\n },\r\n onFormLoadSuccess: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form loaded:', content);\r\n onFormLoad?.(content as unknown as FormLoadEventData);\r\n },\r\n onFormLoadFail: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form load failed:', content);\r\n },\r\n onAnyMessage: (message) => {\r\n onMessage?.(message);\r\n },\r\n });\r\n },\r\n [\r\n debug,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormLoad,\r\n onFormDataChange,\r\n onMessage,\r\n ]\r\n );\r\n \r\n // Set up message listener\r\n useEffect(() => {\r\n window.addEventListener('message', handleMessage);\r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [handleMessage]);\r\n \r\n // Expose imperative methods via ref\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n submit: () => {\r\n triggerSubmit(iframeRef.current);\r\n },\r\n getFormData: () => {\r\n return requestFormDataAsync(iframeRef.current, 5000);\r\n },\r\n setFormData: (data: unknown) => {\r\n sendFormData(iframeRef.current, data);\r\n },\r\n setFieldLabels: (labels: FieldLabelsMap, merge = true) => {\r\n sendFieldLabels(iframeRef.current, labels, merge);\r\n },\r\n getIframe: () => iframeRef.current,\r\n reload: () => {\r\n if (iframeRef.current) {\r\n iframeRef.current.src = iframeRef.current.src;\r\n }\r\n },\r\n }),\r\n []\r\n );\r\n \r\n // Don't render if no baseUrl\r\n if (!baseUrl) {\r\n return (\r\n <div style={mergedStyles.container} className={className}>\r\n <p style={{ color: 'red', padding: '20px' }}>\r\n Error: FormEngine baseUrl is not configured. \r\n Please wrap this component with FormEngineProvider.\r\n </p>\r\n </div>\r\n );\r\n }\r\n \r\n return (\r\n <div style={mergedStyles.container} className={className}>\r\n <iframe\r\n ref={iframeRef}\r\n src={iframeUrl}\r\n style={mergedStyles.iframe}\r\n title={title}\r\n allowFullScreen={allowFullScreen}\r\n sandbox={sandbox}\r\n />\r\n </div>\r\n );\r\n }\r\n);\r\n\r\n// Display name for React DevTools\r\nFormEngineWrapper.displayName = 'FormEngineWrapper';\r\n\r\nexport default FormEngineWrapper;\r\n","import { useRef, useCallback } from 'react';\r\nimport type { FieldLabelsMap, FormEngineWrapperRef } from '../types';\r\nimport {\r\n triggerSubmit,\r\n sendFormData,\r\n requestFormDataAsync,\r\n sendFieldLabels,\r\n} from '../utils/messageHandler';\r\n\r\n/**\r\n * Options for useFormEngine hook\r\n */\r\nexport interface UseFormEngineOptions {\r\n /** Timeout for async operations in milliseconds */\r\n timeout?: number;\r\n /** Target origin for postMessage (use '*' with caution) */\r\n targetOrigin?: string;\r\n}\r\n\r\n/**\r\n * Return type for useFormEngine hook\r\n */\r\nexport interface UseFormEngineReturn extends FormEngineWrapperRef {\r\n /** Ref to attach to the iframe element */\r\n iframeRef: React.RefObject<HTMLIFrameElement | null>;\r\n}\r\n\r\n/**\r\n * Hook to interact with FormEngine iframe\r\n * \r\n * Provides methods to programmatically interact with the form inside the iframe.\r\n * \r\n * @param options - Configuration options\r\n * @returns Object with iframe ref and control methods\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormEngine } from '@formengine/wrapper';\r\n * \r\n * function MyForm() {\r\n * const { iframeRef, submit, getFormData, setFormData } = useFormEngine();\r\n * \r\n * const handleSubmit = async () => {\r\n * const data = await getFormData();\r\n * console.log('Current form data:', data);\r\n * submit();\r\n * };\r\n * \r\n * return (\r\n * <div>\r\n * <iframe ref={iframeRef} src=\"...\" />\r\n * <button onClick={handleSubmit}>Submit</button>\r\n * </div>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function useFormEngine(options: UseFormEngineOptions = {}): UseFormEngineReturn {\r\n const { timeout = 5000, targetOrigin = '*' } = options;\r\n \r\n const iframeRef = useRef<HTMLIFrameElement>(null);\r\n \r\n /**\r\n * Trigger form submission\r\n */\r\n const submit = useCallback(() => {\r\n triggerSubmit(iframeRef.current, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Get form data asynchronously\r\n */\r\n const getFormData = useCallback(async (): Promise<unknown> => {\r\n return requestFormDataAsync(iframeRef.current, timeout, targetOrigin);\r\n }, [timeout, targetOrigin]);\r\n \r\n /**\r\n * Set form data\r\n */\r\n const setFormData = useCallback((data: unknown) => {\r\n sendFormData(iframeRef.current, data, {}, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Set field labels\r\n */\r\n const setFieldLabels = useCallback((labels: FieldLabelsMap) => {\r\n sendFieldLabels(iframeRef.current, labels, true, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Get the iframe element\r\n */\r\n const getIframe = useCallback(() => {\r\n return iframeRef.current;\r\n }, []);\r\n \r\n /**\r\n * Reload the iframe\r\n */\r\n const reload = useCallback(() => {\r\n if (iframeRef.current) {\r\n iframeRef.current.src = iframeRef.current.src;\r\n }\r\n }, []);\r\n \r\n return {\r\n iframeRef,\r\n submit,\r\n getFormData,\r\n setFormData,\r\n setFieldLabels,\r\n getIframe,\r\n reload,\r\n };\r\n}\r\n\r\nexport default useFormEngine;\r\n","import { useEffect, useCallback, useRef } from 'react';\r\nimport {\r\n handleFormEngineMessage,\r\n isFormEngineMessage,\r\n type MessageHandlers,\r\n} from '../utils/messageHandler';\r\nimport type { MessageObject } from '../types/messages';\r\n\r\n/**\r\n * Options for useFormMessages hook\r\n */\r\nexport interface UseFormMessagesOptions {\r\n /** Whether to enable message listening */\r\n enabled?: boolean;\r\n /** Callback when form submission starts */\r\n onSubmitStart?: (content: Record<string, unknown>) => void;\r\n /** Callback when form submission succeeds */\r\n onSubmitSuccess?: (content: Record<string, unknown>) => void;\r\n /** Callback when form submission fails */\r\n onSubmitFail?: (content: Record<string, unknown>) => void;\r\n /** Callback when form data is returned */\r\n onFormDataReturn?: (content: Record<string, unknown>) => void;\r\n /** Callback when setFormData completes */\r\n onSetFormDataReturn?: (content: Record<string, unknown>) => void;\r\n /** Callback when form loads successfully */\r\n onFormLoadSuccess?: (content: Record<string, unknown>) => void;\r\n /** Callback when form load fails */\r\n onFormLoadFail?: (content: Record<string, unknown>) => void;\r\n /** Callback for any message (useful for debugging) */\r\n onAnyMessage?: (message: MessageObject) => void;\r\n}\r\n\r\n/**\r\n * Hook to listen for messages from FormEngine iframe\r\n * \r\n * Sets up event listeners for postMessage events from the FormEngine iframe\r\n * and routes them to the appropriate callback handlers.\r\n * \r\n * @param options - Message handling options and callbacks\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormMessages } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * useFormMessages({\r\n * onSubmitStart: (data) => {\r\n * console.log('Form submission started:', data);\r\n * setLoading(true);\r\n * },\r\n * onSubmitSuccess: (data) => {\r\n * console.log('Form submitted successfully:', data);\r\n * setLoading(false);\r\n * showSuccessMessage();\r\n * },\r\n * onSubmitFail: (data) => {\r\n * console.log('Form submission failed:', data);\r\n * setLoading(false);\r\n * showErrorMessage();\r\n * },\r\n * });\r\n * \r\n * return <div>...</div>;\r\n * }\r\n * ```\r\n */\r\nexport function useFormMessages(options: UseFormMessagesOptions = {}): void {\r\n const {\r\n enabled = true,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n } = options;\r\n \r\n // Use refs to avoid recreating the handler on every render\r\n const handlersRef = useRef<MessageHandlers>({});\r\n \r\n // Update handlers ref when callbacks change\r\n useEffect(() => {\r\n handlersRef.current = {\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n };\r\n }, [\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n ]);\r\n \r\n // Message event handler\r\n const handleMessage = useCallback((event: MessageEvent) => {\r\n handleFormEngineMessage(event, handlersRef.current);\r\n }, []);\r\n \r\n // Set up message listener\r\n useEffect(() => {\r\n if (!enabled) return;\r\n \r\n window.addEventListener('message', handleMessage);\r\n \r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [enabled, handleMessage]);\r\n}\r\n\r\n/**\r\n * Hook to filter and handle only FormEngine messages\r\n * \r\n * A simpler hook that just filters FormEngine messages and calls a single handler.\r\n * Useful when you want more control over message handling.\r\n * \r\n * @param handler - Callback function for FormEngine messages\r\n * @param enabled - Whether to enable listening\r\n * \r\n * @example\r\n * ```tsx\r\n * useFormEngineMessageListener((message) => {\r\n * switch (message.messageEventName) {\r\n * case 'FormSubmitSuccess':\r\n * handleSuccess(message);\r\n * break;\r\n * case 'FormSubmitFail':\r\n * handleFailure(message);\r\n * break;\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function useFormEngineMessageListener(\r\n handler: (message: MessageObject) => void,\r\n enabled = true\r\n): void {\r\n const handlerRef = useRef(handler);\r\n \r\n useEffect(() => {\r\n handlerRef.current = handler;\r\n }, [handler]);\r\n \r\n useEffect(() => {\r\n if (!enabled) return;\r\n \r\n const handleMessage = (event: MessageEvent) => {\r\n if (isFormEngineMessage(event)) {\r\n handlerRef.current(event.data as MessageObject);\r\n }\r\n };\r\n \r\n window.addEventListener('message', handleMessage);\r\n \r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [enabled]);\r\n}\r\n\r\nexport default useFormMessages;\r\n"],"names":["FormEngineContext","createContext","baseUrl","baseName","defaultConfig","defaultStyles","debug","useFormEngineContext","context","useContext","Error","URL_PARAMS","REF_OBJ","REF_ID","TPL_NAME","EDITOR","EDITOR_SHOW","EDITOR_ENABLE","EDITOR_REQUIRED","MINI","FOOTER","FORM_FOOTER","HISTORY","READ_ONLY","INIT_DATA","EXTRA_DATA","PREVIEW_DATA","ROUTES","CREATE","DUMMY_CREATE","EDIT","CREATE_OR_EDIT","VIEW","encodeBase64","data","jsonString","JSON","stringify","btoa","encodeURIComponent","Buffer","from","toString","buildFormEngineUrl","options","mode","refObj","refId","tplName","id","config","normalizedBaseUrl","replace","routePath","params","URLSearchParams","editor","show","set","enabled","required","defaultValue","layout","mini","showFooter","showHistory","readOnly","showFormFooter","initData","Object","keys","length","extraData","previewData","buildConfigParams","String","queryString","MESSAGE_FROM","FORM_SUBMIT_EVENT_TYPE","GET_FORM_DATA_EVENT_TYPE","SET_FORM_DATA_EVENT_TYPE","SET_FIELD_LABELS_EVENT_TYPE","SUBMIT_START_EVENT_NAME","SUBMIT_RESULT_SUCCESS_EVENT_NAME","SUBMIT_RESULT_FAIL_EVENT_NAME","RETURN_FORM_DATA_EVENT_NAME","RETURN_SET_FORM_DATA_EVENT_NAME","FORM_ONLOAD_SUCCESS_EVENT_NAME","FORM_ONLOAD_FAIL_EVENT_NAME","FORM_DATA_CHANGE_EVENT_NAME","FORM_SUBMIT_EVENT_NAME","GET_FORM_DATA_EVENT_NAME","SET_FORM_DATA_EVENT_NAME","SET_FIELD_LABELS_EVENT_NAME","isFormEngineMessage","event","_a","messageFrom","createMessage","eventType","eventName","content","messageEventType","messageEventName","messageEventContent","postMessageToIframe","iframe","message","targetOrigin","contentWindow","postMessage","error","triggerSubmit","requestFormData","sendFormData","sendFieldLabels","labels","merge","handleFormEngineMessage","handlers","onAnyMessage","call","_b","onSubmitStart","_c","onSubmitSuccess","_d","onSubmitFail","_e","onFormDataReturn","_f","onSetFormDataReturn","_g","onFormLoadSuccess","_h","onFormLoadFail","_i","onFormDataChange","requestFormDataAsync","timeout","Promise","resolve","reject","timeoutId","messageHandler","clearTimeout","window","removeEventListener","addEventListener","setTimeout","defaultRootStyle","width","height","position","overflow","defaultIframeStyle","border","FormEngineWrapper","forwardRef","props","ref","styles","propStyles","propConfig","onFormLoad","onMessage","className","title","allowFullScreen","sandbox","iframeRef","useRef","formDataResolverRef","mergedStyles","useMemo","container","mergeStyles","mergedConfig","mergeConfig","iframeUrl","useEffect","handleMessage","useCallback","current","useImperativeHandle","submit","getFormData","setFormData","setFieldLabels","getIframe","reload","src","jsx","style","children","color","padding","displayName","contextValue","Provider","value","url","urlObj","URL","searchParams","origin","get","async","handler","handlerRef","handlersRef"],"mappings":"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"}

@@ -374,3 +374,3 @@ /**

/**
* Additional className for the root element
* Additional className for the container element
*/

@@ -683,4 +683,4 @@ className?: string;

export declare interface StyleConfig {
/** Styles for the root wrapper container */
root?: CSSProperties;
/** Styles for the container wrapper */
container?: CSSProperties;
/** Styles for the iframe element */

@@ -687,0 +687,0 @@ iframe?: CSSProperties;

@@ -354,3 +354,3 @@ import { jsx } from "react/jsx-runtime";

return {
root: { ...defaultStyles.root, ...propStyles == null ? void 0 : propStyles.root },
container: { ...defaultStyles.container, ...propStyles == null ? void 0 : propStyles.container },
iframe: { ...defaultStyles.iframe, ...propStyles == null ? void 0 : propStyles.iframe }

@@ -400,3 +400,3 @@ };

() => mergeStyles(
{ root: defaultRootStyle, iframe: defaultIframeStyle, ...defaultStyles },
{ container: defaultRootStyle, iframe: defaultIframeStyle, ...defaultStyles },
propStyles

@@ -510,5 +510,5 @@ ),

if (!baseUrl) {
return /* @__PURE__ */ jsx("div", { style: mergedStyles.root, className, children: /* @__PURE__ */ jsx("p", { style: { color: "red", padding: "20px" }, children: "Error: FormEngine baseUrl is not configured. Please wrap this component with FormEngineProvider." }) });
return /* @__PURE__ */ jsx("div", { style: mergedStyles.container, className, children: /* @__PURE__ */ jsx("p", { style: { color: "red", padding: "20px" }, children: "Error: FormEngine baseUrl is not configured. Please wrap this component with FormEngineProvider." }) });
}
return /* @__PURE__ */ jsx("div", { style: mergedStyles.root, className, children: /* @__PURE__ */ jsx(
return /* @__PURE__ */ jsx("div", { style: mergedStyles.container, className, children: /* @__PURE__ */ jsx(
"iframe",

@@ -515,0 +515,0 @@ {

@@ -1,1 +0,1 @@

{"version":3,"file":"index.es.js","sources":["../src/context/FormEngineContext.tsx","../src/utils/urlBuilder.ts","../src/types/messages.ts","../src/utils/messageHandler.ts","../src/components/FormEngineWrapper.tsx","../src/hooks/useFormEngine.ts","../src/hooks/useFormMessages.ts"],"sourcesContent":["import React, { createContext, useContext, useMemo, type ReactNode } from 'react';\r\nimport type { FormEngineProviderConfig, FormEngineConfig, StyleConfig } from '../types';\r\n\r\n/**\r\n * Context value interface for FormEngine provider\r\n */\r\nexport interface FormEngineContextValue {\r\n /** Base URL of the FormEngine frontend application */\r\n baseUrl: string;\r\n /** Base name/path prefix for the FormEngine routes */\r\n baseName: string;\r\n /** Default configuration for all FormEngineWrapper instances */\r\n defaultConfig: FormEngineConfig;\r\n /** Default styles for all FormEngineWrapper instances */\r\n defaultStyles: StyleConfig;\r\n /** Whether debug mode is enabled */\r\n debug: boolean;\r\n}\r\n\r\n/** Default context values */\r\nconst defaultContextValue: FormEngineContextValue = {\r\n baseUrl: '',\r\n baseName: 'FormEngineV2',\r\n defaultConfig: {},\r\n defaultStyles: {},\r\n debug: false,\r\n};\r\n\r\n/**\r\n * React Context for FormEngine configuration\r\n */\r\nconst FormEngineContext = createContext<FormEngineContextValue>(defaultContextValue);\r\n\r\n/**\r\n * Props for FormEngineProvider component\r\n */\r\nexport interface FormEngineProviderProps extends FormEngineProviderConfig {\r\n /** Child components */\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * Provider component for FormEngine configuration\r\n * \r\n * Wrap your application (or a portion of it) with this provider to configure\r\n * the FormEngine wrapper components with default settings.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { FormEngineProvider } from '@formengine/wrapper';\r\n * \r\n * function App() {\r\n * return (\r\n * <FormEngineProvider\r\n * baseUrl=\"https://forms.example.com\"\r\n * defaultConfig={{\r\n * layout: { mini: true },\r\n * editor: { show: true, enabled: true },\r\n * }}\r\n * >\r\n * <YourApp />\r\n * </FormEngineProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const FormEngineProvider: React.FC<FormEngineProviderProps> = ({\r\n baseUrl = \"/\",\r\n baseName = 'FormEngineV2',\r\n defaultConfig = {},\r\n defaultStyles = {},\r\n debug = false,\r\n children,\r\n}) => {\r\n // Memoize the context value to prevent unnecessary re-renders\r\n const contextValue = useMemo<FormEngineContextValue>(\r\n () => ({\r\n baseUrl,\r\n baseName,\r\n defaultConfig,\r\n defaultStyles,\r\n debug,\r\n }),\r\n [baseUrl, baseName, defaultConfig, defaultStyles, debug]\r\n );\r\n \r\n // Validate required props\r\n if (!baseUrl) {\r\n console.warn('FormEngineProvider: baseUrl is required but was not provided');\r\n }\r\n \r\n return (\r\n <FormEngineContext.Provider value={contextValue}>\r\n {children}\r\n </FormEngineContext.Provider>\r\n );\r\n};\r\n\r\n/**\r\n * Hook to access FormEngine context\r\n * \r\n * @returns The FormEngine context value\r\n * @throws Error if used outside of FormEngineProvider\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormEngineContext } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * const { baseUrl, debug } = useFormEngineContext();\r\n * \r\n * if (debug) {\r\n * console.log('FormEngine baseUrl:', baseUrl);\r\n * }\r\n * \r\n * return <div>...</div>;\r\n * }\r\n * ```\r\n */\r\nexport const useFormEngineContext = (): FormEngineContextValue => {\r\n const context = useContext(FormEngineContext);\r\n \r\n if (!context) {\r\n throw new Error(\r\n 'useFormEngineContext must be used within a FormEngineProvider. ' +\r\n 'Wrap your component tree with <FormEngineProvider> to fix this error.'\r\n );\r\n }\r\n \r\n return context;\r\n};\r\n\r\n/**\r\n * Hook to get the configured base URL\r\n */\r\nexport const useFormEngineBaseUrl = (): string => {\r\n const { baseUrl } = useFormEngineContext();\r\n return baseUrl;\r\n};\r\n\r\n/**\r\n * Hook to check if debug mode is enabled\r\n */\r\nexport const useFormEngineDebug = (): boolean => {\r\n const { debug } = useFormEngineContext();\r\n return debug;\r\n};\r\n\r\nexport { FormEngineContext };\r\n","import type { FormMode, FormEngineConfig } from '../types';\r\n\r\n/**\r\n * URL parameter keys for FormEngine routes\r\n */\r\nexport const URL_PARAMS = {\r\n REF_OBJ: 'refObj',\r\n REF_ID: 'refId',\r\n TPL_NAME: 'tplName',\r\n EDITOR: 'editor',\r\n EDITOR_SHOW: 'editorShow',\r\n EDITOR_ENABLE: 'editorEnable',\r\n EDITOR_REQUIRED: 'editorRequired',\r\n MINI: 'st_mini',\r\n FOOTER: 'footer',\r\n FORM_FOOTER: 'form_footer',\r\n HISTORY: 'history_show',\r\n READ_ONLY: 'readOnly',\r\n INIT_DATA: 'initData',\r\n EXTRA_DATA: 'extraData',\r\n PREVIEW_DATA: 'previewData',\r\n} as const;\r\n\r\n/**\r\n * Route paths for different form modes\r\n */\r\nexport const ROUTES = {\r\n CREATE: '/form-data/create',\r\n DUMMY_CREATE: '/form-data/dummy-create',\r\n EDIT: '/form-data/edit',\r\n CREATE_OR_EDIT: '/form-data/createOrEdit',\r\n VIEW: '/form-data/view',\r\n} as const;\r\n\r\n/**\r\n * Options for building the iframe URL\r\n */\r\nexport interface BuildUrlOptions {\r\n /** Base URL of the FormEngine application */\r\n baseUrl: string;\r\n /** Base name/path prefix (default: 'FormEngineV2') */\r\n baseName?: string;\r\n /** Form operation mode */\r\n mode: FormMode;\r\n /** Reference object identifier */\r\n refObj: string;\r\n /** Reference ID */\r\n refId: string | number;\r\n /** Template name */\r\n tplName: string;\r\n /** Form data ID (required for edit/view modes) */\r\n id?: number | string;\r\n /** Form configuration */\r\n config?: FormEngineConfig;\r\n}\r\n\r\n/**\r\n * Encode an object to base64 string for URL parameter\r\n */\r\nexport function encodeBase64(data: Record<string, unknown>): string {\r\n try {\r\n const jsonString = JSON.stringify(data);\r\n // Use btoa for browser environment, or Buffer for Node.js\r\n if (typeof btoa === 'function') {\r\n return btoa(encodeURIComponent(jsonString));\r\n }\r\n return Buffer.from(jsonString).toString('base64');\r\n } catch {\r\n console.error('Failed to encode data to base64');\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Build URL parameters from config\r\n */\r\nfunction buildConfigParams(config?: FormEngineConfig): URLSearchParams {\r\n const params = new URLSearchParams();\r\n \r\n if (!config) return params;\r\n \r\n // Editor config\r\n if (config.editor) {\r\n if (config.editor.show !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_SHOW, config.editor.show ? '1' : '0');\r\n }\r\n if (config.editor.enabled !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_ENABLE, config.editor.enabled ? '1' : '0');\r\n }\r\n if (config.editor.required !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_REQUIRED, config.editor.required ? '1' : '0');\r\n }\r\n if (config.editor.defaultValue) {\r\n params.set(URL_PARAMS.EDITOR, config.editor.defaultValue);\r\n }\r\n }\r\n \r\n // Layout config\r\n if (config.layout) {\r\n if (config.layout.mini !== undefined) {\r\n params.set(URL_PARAMS.MINI, config.layout.mini ? '1' : '0');\r\n }\r\n if (config.layout.showFooter !== undefined) {\r\n params.set(URL_PARAMS.FOOTER, config.layout.showFooter ? '1' : '0');\r\n }\r\n if (config.layout.showHistory !== undefined) {\r\n params.set(URL_PARAMS.HISTORY, config.layout.showHistory ? '1' : '0');\r\n }\r\n if (config.layout.readOnly !== undefined) {\r\n params.set(URL_PARAMS.READ_ONLY, config.layout.readOnly ? '1' : '0');\r\n }\r\n if (config.layout.showFormFooter !== undefined) {\r\n params.set(URL_PARAMS.FORM_FOOTER, config.layout.showFormFooter ? '1' : '0');\r\n }\r\n }\r\n \r\n // Data params\r\n if (config.initData && Object.keys(config.initData).length > 0) {\r\n params.set(URL_PARAMS.INIT_DATA, encodeURIComponent(JSON.stringify(config.initData)));\r\n }\r\n \r\n if (config.extraData && Object.keys(config.extraData).length > 0) {\r\n params.set(URL_PARAMS.EXTRA_DATA, encodeBase64(config.extraData));\r\n }\r\n \r\n if (config.previewData && Object.keys(config.previewData).length > 0) {\r\n params.set(URL_PARAMS.PREVIEW_DATA, encodeURIComponent(JSON.stringify(config.previewData)));\r\n }\r\n \r\n return params;\r\n}\r\n\r\n/**\r\n * Build the full iframe URL for FormEngine\r\n * \r\n * @param options - URL building options\r\n * @returns The complete URL string for the iframe\r\n * \r\n * @example\r\n * ```typescript\r\n * const url = buildFormEngineUrl({\r\n * baseUrl: 'https://forms.example.com',\r\n * mode: 'createOrEdit',\r\n * refObj: 'Order',\r\n * refId: '12345',\r\n * tplName: 'order-form',\r\n * });\r\n * // => \"https://forms.example.com/FormEngineV2/form-data/createOrEdit?refObj=Order&refId=12345&tplName=order-form\"\r\n * ```\r\n */\r\nexport function buildFormEngineUrl(options: BuildUrlOptions): string {\r\n const {\r\n baseUrl,\r\n baseName = 'FormEngineV2',\r\n mode,\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n config,\r\n } = options;\r\n \r\n // Normalize base URL (remove trailing slash)\r\n const normalizedBaseUrl = baseUrl.replace(/\\/+$/, '');\r\n \r\n // Build the route path based on mode\r\n let routePath: string;\r\n \r\n switch (mode) {\r\n case 'create':\r\n routePath = ROUTES.CREATE;\r\n break;\r\n case 'edit':\r\n case 'view':\r\n if (!id) {\r\n console.warn(`Mode \"${mode}\" requires an id. Falling back to createOrEdit.`);\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n } else {\r\n routePath = `${ROUTES.EDIT}/${id}`;\r\n }\r\n break;\r\n case 'createOrEdit':\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n break;\r\n case 'dummy-create':\r\n routePath = ROUTES.DUMMY_CREATE;\r\n break;\r\n default:\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n break;\r\n }\r\n \r\n // Build query parameters\r\n const params = buildConfigParams(config);\r\n params.set(URL_PARAMS.REF_OBJ, refObj);\r\n params.set(URL_PARAMS.REF_ID, String(refId));\r\n params.set(URL_PARAMS.TPL_NAME, tplName);\r\n \r\n // For view mode, set readOnly\r\n if (mode === 'view') {\r\n params.set(URL_PARAMS.READ_ONLY, '1');\r\n }\r\n \r\n // Construct the full URL\r\n const queryString = params.toString();\r\n const fullPath = baseName ? `/${baseName}${routePath}` : routePath;\r\n \r\n return `${normalizedBaseUrl}${fullPath}${queryString ? `?${queryString}` : ''}`;\r\n}\r\n\r\n/**\r\n * Parse a FormEngine URL to extract its components\r\n * Useful for debugging or validation\r\n */\r\nexport function parseFormEngineUrl(url: string): Partial<BuildUrlOptions> | null {\r\n try {\r\n const urlObj = new URL(url);\r\n const params = urlObj.searchParams;\r\n \r\n return {\r\n baseUrl: urlObj.origin,\r\n refObj: params.get(URL_PARAMS.REF_OBJ) || undefined,\r\n refId: params.get(URL_PARAMS.REF_ID) || undefined,\r\n tplName: params.get(URL_PARAMS.TPL_NAME) || undefined,\r\n };\r\n } catch {\r\n console.error('Failed to parse FormEngine URL');\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Message types for communication between FormEngineWrapper and FormEngine iframe\r\n * These types mirror the FormEngine's internal message system\r\n */\r\n\r\nimport { FieldLabelsMap } from \"./config\";\r\n\r\n\r\n/** Identifier for messages from FormEngine */\r\nexport const MESSAGE_FROM = 'MTG_FORMENGINE';\r\n\r\n// =============================================================================\r\n// Event Types - Categories of messages\r\n// =============================================================================\r\n\r\n/** Event types sent FROM FormEngine TO parent window */\r\nexport const SUBMIT_START_EVENT_TYPE = 'submit_start' as const;\r\nexport const SUBMIT_RESULT_EVENT_TYPE = 'submit_result' as const;\r\nexport const RETURN_FORM_DATA_EVENT_TYPE = 'return_form_data' as const;\r\nexport const RETURN_SET_FORM_DATA_EVENT_TYPE = 'return_set_form_data' as const;\r\nexport const FORM_ONLOAD_EVENT_TYPE = 'form_onload' as const;\r\nexport const FORM_DATA_CHANGE_EVENT_TYPE = 'form_data_change' as const;\r\n\r\n/** Event types sent FROM parent TO FormEngine */\r\nexport const FORM_SUBMIT_EVENT_TYPE = 'submit' as const;\r\nexport const GET_FORM_DATA_EVENT_TYPE = 'get_form_data' as const;\r\nexport const SET_FORM_DATA_EVENT_TYPE = 'set_form_data' as const;\r\nexport const SET_FIELD_LABELS_EVENT_TYPE = 'set_field_labels' as const;\r\n\r\n// =============================================================================\r\n// Event Names - Specific events within each type\r\n// =============================================================================\r\n\r\n/** Event names FROM FormEngine */\r\nexport const SUBMIT_START_EVENT_NAME = 'FormSubmitStart' as const;\r\nexport const SUBMIT_RESULT_SUCCESS_EVENT_NAME = 'FormSubmitSuccess' as const;\r\nexport const SUBMIT_RESULT_FAIL_EVENT_NAME = 'FormSubmitFail' as const;\r\nexport const RETURN_FORM_DATA_EVENT_NAME = 'ReturnFormData' as const;\r\nexport const RETURN_SET_FORM_DATA_EVENT_NAME = 'ReturnSetFormData' as const;\r\nexport const FORM_ONLOAD_SUCCESS_EVENT_NAME = 'FormOnLoadSuccess' as const;\r\nexport const FORM_ONLOAD_FAIL_EVENT_NAME = 'FormOnLoadFail' as const;\r\nexport const FORM_DATA_CHANGE_EVENT_NAME = 'FormDataChange' as const;\r\n\r\n/** Event names TO FormEngine */\r\nexport const FORM_SUBMIT_EVENT_NAME = 'Submit' as const;\r\nexport const GET_FORM_DATA_EVENT_NAME = 'GetFormData' as const;\r\nexport const SET_FORM_DATA_EVENT_NAME = 'SetFormData' as const;\r\nexport const SET_FIELD_LABELS_EVENT_NAME = 'SetFieldLabels' as const;\r\n\r\n// =============================================================================\r\n// Type Definitions\r\n// =============================================================================\r\n\r\n/** Event types from FormEngine to parent */\r\nexport type MessageEventTypeFromFormEngine =\r\n | typeof SUBMIT_START_EVENT_TYPE\r\n | typeof SUBMIT_RESULT_EVENT_TYPE\r\n | typeof RETURN_FORM_DATA_EVENT_TYPE\r\n | typeof RETURN_SET_FORM_DATA_EVENT_TYPE\r\n | typeof FORM_ONLOAD_EVENT_TYPE\r\n | typeof FORM_DATA_CHANGE_EVENT_TYPE;\r\n\r\n/** Event names from FormEngine to parent */\r\nexport type MessageEventNameFromFormEngine =\r\n | typeof SUBMIT_START_EVENT_NAME\r\n | typeof SUBMIT_RESULT_SUCCESS_EVENT_NAME\r\n | typeof SUBMIT_RESULT_FAIL_EVENT_NAME\r\n | typeof RETURN_FORM_DATA_EVENT_NAME\r\n | typeof RETURN_SET_FORM_DATA_EVENT_NAME\r\n | typeof FORM_ONLOAD_SUCCESS_EVENT_NAME\r\n | typeof FORM_ONLOAD_FAIL_EVENT_NAME\r\n | typeof FORM_DATA_CHANGE_EVENT_NAME;\r\n\r\n/** Event types from parent to FormEngine */\r\nexport type MessageEventTypeToFormEngine =\r\n | typeof FORM_SUBMIT_EVENT_TYPE\r\n | typeof GET_FORM_DATA_EVENT_TYPE\r\n | typeof SET_FORM_DATA_EVENT_TYPE\r\n | typeof SET_FIELD_LABELS_EVENT_TYPE;\r\n\r\n/** Event names from parent to FormEngine */\r\nexport type MessageEventNameToFormEngine =\r\n | typeof FORM_SUBMIT_EVENT_NAME\r\n | typeof GET_FORM_DATA_EVENT_NAME\r\n | typeof SET_FORM_DATA_EVENT_NAME\r\n | typeof SET_FIELD_LABELS_EVENT_NAME;\r\n\r\n/** All possible message event types */\r\nexport type MessageEventType = MessageEventTypeFromFormEngine | MessageEventTypeToFormEngine;\r\n\r\n/** All possible message event names */\r\nexport type MessageEventName = MessageEventNameFromFormEngine | MessageEventNameToFormEngine;\r\n\r\n// =============================================================================\r\n// Message Object Interfaces\r\n// =============================================================================\r\n\r\n/**\r\n * Base message object interface for FormEngine communication\r\n */\r\nexport interface MessageObject {\r\n /** Source identifier for the message */\r\n messageFrom: string;\r\n /** The specific event name */\r\n messageEventName: MessageEventName;\r\n /** The category of the event */\r\n messageEventType: MessageEventType;\r\n /** The payload of the message */\r\n messageEventContent: any;\r\n /** Whether the operation was successful (for response messages) */\r\n success?: boolean;\r\n}\r\n\r\n/**\r\n * Content structure for submit-related messages\r\n */\r\nexport interface SubmitMessageContent {\r\n /** Form data ID (present when editing existing form) */\r\n id?: number;\r\n /** Template name */\r\n tplName?: string;\r\n /** Reference object identifier */\r\n refObj?: string;\r\n /** Reference ID */\r\n refId?: string | number;\r\n /** Type of submit operation */\r\n submitType?: 'createOrEdit' | 'edit' | 'create' | 'dummy-create';\r\n /** Additional data */\r\n extra?: unknown;\r\n}\r\n\r\n/**\r\n * Message for setting form data\r\n */\r\nexport interface SetFormDataMessage extends Omit<MessageObject, 'messageEventContent' | 'messageEventName'> {\r\n messageEventName: typeof SET_FORM_DATA_EVENT_NAME;\r\n messageEventType: typeof SET_FORM_DATA_EVENT_TYPE;\r\n messageEventContent: {\r\n id?: string | number;\r\n tplName?: string;\r\n data: unknown;\r\n };\r\n}\r\n\r\n/**\r\n * Message for getting form data response\r\n */\r\nexport interface ReturnFormDataMessage extends MessageObject {\r\n messageEventName: typeof RETURN_FORM_DATA_EVENT_NAME;\r\n messageEventType: typeof RETURN_FORM_DATA_EVENT_TYPE;\r\n messageEventContent: {\r\n id?: string | number;\r\n data: unknown;\r\n };\r\n}\r\n\r\n/**\r\n * Form information in onload messages\r\n */\r\nexport interface FormOnLoadMessageForm {\r\n /** Form data ID */\r\n id?: number;\r\n /** Reference object */\r\n refObj?: string;\r\n /** Reference ID */\r\n refId?: string;\r\n /** Template name */\r\n tplName: string;\r\n /** Template display title */\r\n templateTitle: string;\r\n}\r\n\r\n/**\r\n * Content for form onload messages\r\n */\r\nexport interface FormOnLoadMessageContent {\r\n /** Whether the form has child forms */\r\n hasChildren: boolean;\r\n /** Number of tabs (for tabular forms) */\r\n tabCount: number;\r\n /** Parent form information */\r\n form: FormOnLoadMessageForm;\r\n /** Child forms information */\r\n childrenForms: FormOnLoadMessageForm[];\r\n}\r\n\r\n/**\r\n * Submit start message from FormEngine\r\n */\r\nexport interface SubmitStartMessage extends MessageObject {\r\n messageEventName: typeof SUBMIT_START_EVENT_NAME;\r\n messageEventType: typeof SUBMIT_START_EVENT_TYPE;\r\n messageEventContent: SubmitMessageContent;\r\n}\r\n\r\n/**\r\n * Submit result message from FormEngine\r\n */\r\nexport interface SubmitResultMessage extends MessageObject {\r\n messageEventName: typeof SUBMIT_RESULT_SUCCESS_EVENT_NAME | typeof SUBMIT_RESULT_FAIL_EVENT_NAME;\r\n messageEventType: typeof SUBMIT_RESULT_EVENT_TYPE;\r\n messageEventContent: SubmitMessageContent;\r\n}\r\n\r\n/**\r\n * Form onload message from FormEngine\r\n */\r\nexport interface FormOnLoadMessage extends MessageObject {\r\n messageEventName: typeof FORM_ONLOAD_SUCCESS_EVENT_NAME | typeof FORM_ONLOAD_FAIL_EVENT_NAME;\r\n messageEventType: typeof FORM_ONLOAD_EVENT_TYPE;\r\n messageEventContent: FormOnLoadMessageContent;\r\n}\r\n\r\n/**\r\n * Content for form data change messages\r\n */\r\nexport interface FormDataChangeMessageContent {\r\n /** The path/field that changed (e.g., \"root_field1\" or \"root_section_field2\") */\r\n path?: string;\r\n /** The new value of the changed field */\r\n value?: unknown;\r\n /** The complete form data after the change */\r\n formData: unknown;\r\n /** Form ID if available */\r\n id?: string | number;\r\n /** Template name */\r\n tplName?: string;\r\n}\r\n\r\n/**\r\n * Form data change message from FormEngine\r\n */\r\nexport interface FormDataChangeMessage extends MessageObject {\r\n messageEventName: typeof FORM_DATA_CHANGE_EVENT_NAME;\r\n messageEventType: typeof FORM_DATA_CHANGE_EVENT_TYPE;\r\n messageEventContent: FormDataChangeMessageContent;\r\n}\r\n\r\n/**\r\n * Message content for setting field labels\r\n */\r\nexport interface SetFieldLabelsMessageContent {\r\n /** Map of pathId to label config */\r\n labels: FieldLabelsMap;\r\n /** Whether to merge with existing labels (true) or replace all (false) */\r\n merge?: boolean;\r\n}\r\n\r\n/**\r\n * Message for setting field labels\r\n */\r\nexport interface SetFieldLabelsMessage extends MessageObject {\r\n messageEventType: typeof SET_FIELD_LABELS_EVENT_TYPE;\r\n messageEventName: typeof SET_FIELD_LABELS_EVENT_NAME;\r\n messageEventContent: SetFieldLabelsMessageContent;\r\n}\r\n","import { FieldLabelsMap } from '../types';\r\nimport {\r\n MESSAGE_FROM,\r\n SUBMIT_START_EVENT_NAME,\r\n SUBMIT_RESULT_SUCCESS_EVENT_NAME,\r\n SUBMIT_RESULT_FAIL_EVENT_NAME,\r\n RETURN_FORM_DATA_EVENT_NAME,\r\n RETURN_SET_FORM_DATA_EVENT_NAME,\r\n FORM_ONLOAD_SUCCESS_EVENT_NAME,\r\n FORM_ONLOAD_FAIL_EVENT_NAME,\r\n FORM_DATA_CHANGE_EVENT_NAME,\r\n FORM_SUBMIT_EVENT_TYPE,\r\n FORM_SUBMIT_EVENT_NAME,\r\n GET_FORM_DATA_EVENT_TYPE,\r\n GET_FORM_DATA_EVENT_NAME,\r\n SET_FORM_DATA_EVENT_TYPE,\r\n SET_FORM_DATA_EVENT_NAME,\r\n SET_FIELD_LABELS_EVENT_TYPE,\r\n SET_FIELD_LABELS_EVENT_NAME,\r\n type MessageObject,\r\n type MessageEventType,\r\n type MessageEventName,\r\n} from '../types/messages';\r\n\r\n/** Identifier for messages from the wrapper */\r\nconst WRAPPER_MESSAGE_FROM = 'FORMENGINE_WRAPPER';\r\n\r\n/**\r\n * Check if a message is from FormEngine\r\n */\r\nexport function isFormEngineMessage(event: MessageEvent): boolean {\r\n return event.data?.messageFrom === MESSAGE_FROM;\r\n}\r\n\r\n/**\r\n * Create a message object to send to FormEngine\r\n */\r\nfunction createMessage(\r\n eventType: MessageEventType,\r\n eventName: MessageEventName,\r\n content: Record<string, unknown> = {}\r\n): MessageObject {\r\n return {\r\n messageFrom: WRAPPER_MESSAGE_FROM,\r\n messageEventType: eventType,\r\n messageEventName: eventName,\r\n messageEventContent: content,\r\n };\r\n}\r\n\r\n/**\r\n * Send a message to the FormEngine iframe\r\n */\r\nexport function postMessageToIframe(\r\n iframe: HTMLIFrameElement | null,\r\n message: MessageObject,\r\n targetOrigin = '*'\r\n): boolean {\r\n if (!iframe?.contentWindow) {\r\n console.warn('Cannot post message: iframe or contentWindow is null');\r\n return false;\r\n }\r\n \r\n try {\r\n iframe.contentWindow.postMessage(message, targetOrigin);\r\n return true;\r\n } catch (error) {\r\n console.error('Failed to post message to iframe:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Trigger form submission in the iframe\r\n */\r\nexport function triggerSubmit(\r\n iframe: HTMLIFrameElement | null,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n FORM_SUBMIT_EVENT_TYPE,\r\n FORM_SUBMIT_EVENT_NAME\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Request form data from the iframe\r\n */\r\nexport function requestFormData(\r\n iframe: HTMLIFrameElement | null,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n GET_FORM_DATA_EVENT_TYPE,\r\n GET_FORM_DATA_EVENT_NAME\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Set form data in the iframe\r\n */\r\nexport function sendFormData(\r\n iframe: HTMLIFrameElement | null,\r\n data: unknown,\r\n options: { id?: string | number; tplName?: string } = {},\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n SET_FORM_DATA_EVENT_TYPE,\r\n SET_FORM_DATA_EVENT_NAME,\r\n {\r\n ...options,\r\n data,\r\n }\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Set field labels in the iframe\r\n * \r\n * @param iframe - The iframe element\r\n * @param labels - Map of pathId to label configuration\r\n * @param merge - Whether to merge with existing labels (default: true)\r\n * @param targetOrigin - Target origin for postMessage\r\n * \r\n * @example\r\n * ```typescript\r\n * sendFieldLabels(iframeRef.current, {\r\n * 'root_firstName': {\r\n * content: 'Edited by John @ 2024-01-01',\r\n * style: { color: 'blue', fontStyle: 'italic' }\r\n * },\r\n * 'root_lastName': {\r\n * content: 'Required field',\r\n * style: { color: 'red' }\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function sendFieldLabels(\r\n iframe: HTMLIFrameElement | null,\r\n labels: FieldLabelsMap,\r\n merge = true,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n SET_FIELD_LABELS_EVENT_TYPE,\r\n SET_FIELD_LABELS_EVENT_NAME,\r\n {\r\n labels,\r\n merge,\r\n }\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Message handler callback types\r\n */\r\nexport interface MessageHandlers {\r\n onSubmitStart?: (content: Record<string, unknown>) => void;\r\n onSubmitSuccess?: (content: Record<string, unknown>) => void;\r\n onSubmitFail?: (content: Record<string, unknown>) => void;\r\n onFormDataReturn?: (content: Record<string, unknown>) => void;\r\n onSetFormDataReturn?: (content: Record<string, unknown>) => void;\r\n onFormLoadSuccess?: (content: Record<string, unknown>) => void;\r\n onFormLoadFail?: (content: Record<string, unknown>) => void;\r\n onFormDataChange?: (content: Record<string, unknown>) => void;\r\n onAnyMessage?: (message: MessageObject) => void;\r\n}\r\n\r\n/**\r\n * Handle incoming messages from FormEngine\r\n */\r\nexport function handleFormEngineMessage(\r\n event: MessageEvent,\r\n handlers: MessageHandlers\r\n): void {\r\n // Validate message source\r\n if (!isFormEngineMessage(event)) {\r\n return;\r\n }\r\n \r\n const message = event.data as MessageObject;\r\n \r\n // Call the generic message handler\r\n handlers.onAnyMessage?.(message);\r\n \r\n // Route to specific handlers based on event name\r\n switch (message.messageEventName) {\r\n case SUBMIT_START_EVENT_NAME:\r\n handlers.onSubmitStart?.(message.messageEventContent);\r\n break;\r\n \r\n case SUBMIT_RESULT_SUCCESS_EVENT_NAME:\r\n handlers.onSubmitSuccess?.(message.messageEventContent);\r\n break;\r\n \r\n case SUBMIT_RESULT_FAIL_EVENT_NAME:\r\n handlers.onSubmitFail?.(message.messageEventContent);\r\n break;\r\n \r\n case RETURN_FORM_DATA_EVENT_NAME:\r\n handlers.onFormDataReturn?.(message.messageEventContent);\r\n break;\r\n \r\n case RETURN_SET_FORM_DATA_EVENT_NAME:\r\n handlers.onSetFormDataReturn?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_ONLOAD_SUCCESS_EVENT_NAME:\r\n handlers.onFormLoadSuccess?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_ONLOAD_FAIL_EVENT_NAME:\r\n handlers.onFormLoadFail?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_DATA_CHANGE_EVENT_NAME:\r\n handlers.onFormDataChange?.(message.messageEventContent);\r\n break;\r\n \r\n default:\r\n // Unknown message type - already logged via onAnyMessage if handler provided\r\n break;\r\n }\r\n}\r\n\r\n/**\r\n * Create a promise-based form data request\r\n * Returns a promise that resolves when form data is received\r\n */\r\nexport function requestFormDataAsync(\r\n iframe: HTMLIFrameElement | null,\r\n timeout = 5000,\r\n targetOrigin = '*'\r\n): Promise<unknown> {\r\n return new Promise((resolve, reject) => {\r\n if (!iframe) {\r\n reject(new Error('Iframe is null'));\r\n return;\r\n }\r\n \r\n let timeoutId: ReturnType<typeof setTimeout>;\r\n \r\n const messageHandler = (event: MessageEvent) => {\r\n if (!isFormEngineMessage(event)) return;\r\n \r\n const message = event.data as MessageObject;\r\n if (message.messageEventName === RETURN_FORM_DATA_EVENT_NAME) {\r\n clearTimeout(timeoutId);\r\n window.removeEventListener('message', messageHandler);\r\n resolve(message.messageEventContent.data);\r\n }\r\n };\r\n \r\n window.addEventListener('message', messageHandler);\r\n \r\n // Set timeout for the request\r\n timeoutId = setTimeout(() => {\r\n window.removeEventListener('message', messageHandler);\r\n reject(new Error('Form data request timed out'));\r\n }, timeout);\r\n \r\n // Send the request\r\n if (!requestFormData(iframe, targetOrigin)) {\r\n clearTimeout(timeoutId);\r\n window.removeEventListener('message', messageHandler);\r\n reject(new Error('Failed to send form data request'));\r\n }\r\n });\r\n}\r\n","import React, {\r\n forwardRef,\r\n useImperativeHandle,\r\n useEffect,\r\n useCallback,\r\n useMemo,\r\n useRef,\r\n type CSSProperties,\r\n} from 'react';\r\nimport type {\r\n FormEngineWrapperProps,\r\n FormEngineWrapperRef,\r\n StyleConfig,\r\n FormEngineConfig,\r\n SubmitEventData,\r\n FormLoadEventData,\r\n FormDataChangeEvent,\r\n} from '../types';\r\nimport { useFormEngineContext } from '../context';\r\nimport { buildFormEngineUrl } from '../utils/urlBuilder';\r\nimport {\r\n handleFormEngineMessage,\r\n triggerSubmit,\r\n sendFormData,\r\n sendFieldLabels,\r\n requestFormDataAsync,\r\n} from '../utils/messageHandler';\r\nimport type { FieldLabelsMap } from '../types/config';\r\n\r\n/** Default styles for the wrapper container */\r\nconst defaultRootStyle: CSSProperties = {\r\n width: '100%',\r\n height: '100%',\r\n position: 'relative',\r\n overflow: 'hidden',\r\n};\r\n\r\n/** Default styles for the iframe */\r\nconst defaultIframeStyle: CSSProperties = {\r\n width: '100%',\r\n height: '100%',\r\n border: 'none',\r\n};\r\n\r\n/**\r\n * Merge styles with defaults\r\n */\r\nfunction mergeStyles(\r\n defaultStyles: StyleConfig,\r\n propStyles?: StyleConfig\r\n): StyleConfig {\r\n return {\r\n root: { ...defaultStyles.root, ...propStyles?.root },\r\n iframe: { ...defaultStyles.iframe, ...propStyles?.iframe },\r\n };\r\n}\r\n\r\n/**\r\n * Deep merge configs with defaults\r\n */\r\nfunction mergeConfig(\r\n defaultConfig: FormEngineConfig,\r\n propConfig?: FormEngineConfig\r\n): FormEngineConfig {\r\n return {\r\n editor: { ...defaultConfig.editor, ...propConfig?.editor },\r\n layout: { ...defaultConfig.layout, ...propConfig?.layout },\r\n initData: { ...defaultConfig.initData, ...propConfig?.initData },\r\n extraData: { ...defaultConfig.extraData, ...propConfig?.extraData },\r\n previewData: { ...defaultConfig.previewData, ...propConfig?.previewData },\r\n };\r\n}\r\n\r\n/**\r\n * FormEngineWrapper Component\r\n * \r\n * A React component that wraps the FormEngine application in an iframe,\r\n * providing a simple interface for integration with other React applications.\r\n * \r\n * @example\r\n * Basic usage:\r\n * ```tsx\r\n * import { FormEngineWrapper, FormEngineProvider } from '@formengine/wrapper';\r\n * \r\n * function App() {\r\n * return (\r\n * <FormEngineProvider baseUrl=\"https://forms.example.com\">\r\n * <FormEngineWrapper\r\n * refObj=\"Order\"\r\n * refId=\"12345\"\r\n * tplName=\"order-form\"\r\n * mode=\"createOrEdit\"\r\n * onSubmitSuccess={(data) => {\r\n * console.log('Form submitted:', data);\r\n * }}\r\n * />\r\n * </FormEngineProvider>\r\n * );\r\n * }\r\n * ```\r\n * \r\n * @example\r\n * With ref for programmatic control:\r\n * ```tsx\r\n * import { useRef } from 'react';\r\n * import { FormEngineWrapper, FormEngineWrapperRef } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * const formRef = useRef<FormEngineWrapperRef>(null);\r\n * \r\n * const handleExternalSubmit = () => {\r\n * formRef.current?.submit();\r\n * };\r\n * \r\n * const handleGetData = async () => {\r\n * const data = await formRef.current?.getFormData();\r\n * console.log('Form data:', data);\r\n * };\r\n * \r\n * return (\r\n * <>\r\n * <FormEngineWrapper\r\n * ref={formRef}\r\n * refObj=\"Order\"\r\n * refId=\"12345\"\r\n * tplName=\"order-form\"\r\n * />\r\n * <button onClick={handleExternalSubmit}>Submit</button>\r\n * <button onClick={handleGetData}>Get Data</button>\r\n * </>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const FormEngineWrapper = forwardRef<FormEngineWrapperRef, FormEngineWrapperProps>(\r\n (props, ref) => {\r\n const {\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n mode = 'createOrEdit',\r\n styles: propStyles,\r\n config: propConfig,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormLoad,\r\n onFormDataChange,\r\n onMessage,\r\n className,\r\n title = 'FormEngine Form',\r\n allowFullScreen = false,\r\n sandbox = 'allow-same-origin allow-scripts allow-forms allow-popups',\r\n } = props;\r\n \r\n // Get context values\r\n const {\r\n baseUrl,\r\n baseName,\r\n defaultConfig,\r\n defaultStyles,\r\n debug,\r\n } = useFormEngineContext();\r\n \r\n // Refs\r\n const iframeRef = useRef<HTMLIFrameElement>(null);\r\n const formDataResolverRef = useRef<((data: unknown) => void) | null>(null);\r\n \r\n // Merge styles and config with defaults\r\n const mergedStyles = useMemo(\r\n () => mergeStyles(\r\n { root: defaultRootStyle, iframe: defaultIframeStyle, ...defaultStyles },\r\n propStyles\r\n ),\r\n [defaultStyles, propStyles]\r\n );\r\n \r\n const mergedConfig = useMemo(\r\n () => mergeConfig(defaultConfig, propConfig),\r\n [defaultConfig, propConfig]\r\n );\r\n \r\n // Build the iframe URL\r\n const iframeUrl = useMemo(() => {\r\n if (!baseUrl) {\r\n console.warn('FormEngineWrapper: baseUrl is not configured');\r\n return '';\r\n }\r\n \r\n return buildFormEngineUrl({\r\n baseUrl,\r\n baseName,\r\n mode,\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n config: mergedConfig,\r\n });\r\n }, [baseUrl, baseName, mode, refObj, refId, tplName, id, mergedConfig]);\r\n \r\n // Debug logging\r\n useEffect(() => {\r\n if (debug) {\r\n console.log('[FormEngineWrapper] URL:', iframeUrl);\r\n console.log('[FormEngineWrapper] Config:', mergedConfig);\r\n }\r\n }, [debug, iframeUrl, mergedConfig]);\r\n \r\n // Message handler\r\n const handleMessage = useCallback(\r\n (event: MessageEvent) => {\r\n handleFormEngineMessage(event, {\r\n onSubmitStart: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit started:', content);\r\n onSubmitStart?.(content as SubmitEventData);\r\n },\r\n onSubmitSuccess: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit success:', content);\r\n onSubmitSuccess?.(content as SubmitEventData);\r\n },\r\n onSubmitFail: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit failed:', content);\r\n onSubmitFail?.(content as SubmitEventData);\r\n },\r\n onFormDataReturn: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form data returned:', content);\r\n formDataResolverRef.current?.(content.data);\r\n formDataResolverRef.current = null;\r\n },\r\n onFormDataChange: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form data changed:', content);\r\n onFormDataChange?.(content as unknown as FormDataChangeEvent);\r\n },\r\n onFormLoadSuccess: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form loaded:', content);\r\n onFormLoad?.(content as unknown as FormLoadEventData);\r\n },\r\n onFormLoadFail: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form load failed:', content);\r\n },\r\n onAnyMessage: (message) => {\r\n onMessage?.(message);\r\n },\r\n });\r\n },\r\n [\r\n debug,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormLoad,\r\n onFormDataChange,\r\n onMessage,\r\n ]\r\n );\r\n \r\n // Set up message listener\r\n useEffect(() => {\r\n window.addEventListener('message', handleMessage);\r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [handleMessage]);\r\n \r\n // Expose imperative methods via ref\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n submit: () => {\r\n triggerSubmit(iframeRef.current);\r\n },\r\n getFormData: () => {\r\n return requestFormDataAsync(iframeRef.current, 5000);\r\n },\r\n setFormData: (data: unknown) => {\r\n sendFormData(iframeRef.current, data);\r\n },\r\n setFieldLabels: (labels: FieldLabelsMap, merge = true) => {\r\n sendFieldLabels(iframeRef.current, labels, merge);\r\n },\r\n getIframe: () => iframeRef.current,\r\n reload: () => {\r\n if (iframeRef.current) {\r\n iframeRef.current.src = iframeRef.current.src;\r\n }\r\n },\r\n }),\r\n []\r\n );\r\n \r\n // Don't render if no baseUrl\r\n if (!baseUrl) {\r\n return (\r\n <div style={mergedStyles.root} className={className}>\r\n <p style={{ color: 'red', padding: '20px' }}>\r\n Error: FormEngine baseUrl is not configured. \r\n Please wrap this component with FormEngineProvider.\r\n </p>\r\n </div>\r\n );\r\n }\r\n \r\n return (\r\n <div style={mergedStyles.root} className={className}>\r\n <iframe\r\n ref={iframeRef}\r\n src={iframeUrl}\r\n style={mergedStyles.iframe}\r\n title={title}\r\n allowFullScreen={allowFullScreen}\r\n sandbox={sandbox}\r\n />\r\n </div>\r\n );\r\n }\r\n);\r\n\r\n// Display name for React DevTools\r\nFormEngineWrapper.displayName = 'FormEngineWrapper';\r\n\r\nexport default FormEngineWrapper;\r\n","import { useRef, useCallback } from 'react';\r\nimport type { FieldLabelsMap, FormEngineWrapperRef } from '../types';\r\nimport {\r\n triggerSubmit,\r\n sendFormData,\r\n requestFormDataAsync,\r\n sendFieldLabels,\r\n} from '../utils/messageHandler';\r\n\r\n/**\r\n * Options for useFormEngine hook\r\n */\r\nexport interface UseFormEngineOptions {\r\n /** Timeout for async operations in milliseconds */\r\n timeout?: number;\r\n /** Target origin for postMessage (use '*' with caution) */\r\n targetOrigin?: string;\r\n}\r\n\r\n/**\r\n * Return type for useFormEngine hook\r\n */\r\nexport interface UseFormEngineReturn extends FormEngineWrapperRef {\r\n /** Ref to attach to the iframe element */\r\n iframeRef: React.RefObject<HTMLIFrameElement | null>;\r\n}\r\n\r\n/**\r\n * Hook to interact with FormEngine iframe\r\n * \r\n * Provides methods to programmatically interact with the form inside the iframe.\r\n * \r\n * @param options - Configuration options\r\n * @returns Object with iframe ref and control methods\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormEngine } from '@formengine/wrapper';\r\n * \r\n * function MyForm() {\r\n * const { iframeRef, submit, getFormData, setFormData } = useFormEngine();\r\n * \r\n * const handleSubmit = async () => {\r\n * const data = await getFormData();\r\n * console.log('Current form data:', data);\r\n * submit();\r\n * };\r\n * \r\n * return (\r\n * <div>\r\n * <iframe ref={iframeRef} src=\"...\" />\r\n * <button onClick={handleSubmit}>Submit</button>\r\n * </div>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function useFormEngine(options: UseFormEngineOptions = {}): UseFormEngineReturn {\r\n const { timeout = 5000, targetOrigin = '*' } = options;\r\n \r\n const iframeRef = useRef<HTMLIFrameElement>(null);\r\n \r\n /**\r\n * Trigger form submission\r\n */\r\n const submit = useCallback(() => {\r\n triggerSubmit(iframeRef.current, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Get form data asynchronously\r\n */\r\n const getFormData = useCallback(async (): Promise<unknown> => {\r\n return requestFormDataAsync(iframeRef.current, timeout, targetOrigin);\r\n }, [timeout, targetOrigin]);\r\n \r\n /**\r\n * Set form data\r\n */\r\n const setFormData = useCallback((data: unknown) => {\r\n sendFormData(iframeRef.current, data, {}, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Set field labels\r\n */\r\n const setFieldLabels = useCallback((labels: FieldLabelsMap) => {\r\n sendFieldLabels(iframeRef.current, labels, true, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Get the iframe element\r\n */\r\n const getIframe = useCallback(() => {\r\n return iframeRef.current;\r\n }, []);\r\n \r\n /**\r\n * Reload the iframe\r\n */\r\n const reload = useCallback(() => {\r\n if (iframeRef.current) {\r\n iframeRef.current.src = iframeRef.current.src;\r\n }\r\n }, []);\r\n \r\n return {\r\n iframeRef,\r\n submit,\r\n getFormData,\r\n setFormData,\r\n setFieldLabels,\r\n getIframe,\r\n reload,\r\n };\r\n}\r\n\r\nexport default useFormEngine;\r\n","import { useEffect, useCallback, useRef } from 'react';\r\nimport {\r\n handleFormEngineMessage,\r\n isFormEngineMessage,\r\n type MessageHandlers,\r\n} from '../utils/messageHandler';\r\nimport type { MessageObject } from '../types/messages';\r\n\r\n/**\r\n * Options for useFormMessages hook\r\n */\r\nexport interface UseFormMessagesOptions {\r\n /** Whether to enable message listening */\r\n enabled?: boolean;\r\n /** Callback when form submission starts */\r\n onSubmitStart?: (content: Record<string, unknown>) => void;\r\n /** Callback when form submission succeeds */\r\n onSubmitSuccess?: (content: Record<string, unknown>) => void;\r\n /** Callback when form submission fails */\r\n onSubmitFail?: (content: Record<string, unknown>) => void;\r\n /** Callback when form data is returned */\r\n onFormDataReturn?: (content: Record<string, unknown>) => void;\r\n /** Callback when setFormData completes */\r\n onSetFormDataReturn?: (content: Record<string, unknown>) => void;\r\n /** Callback when form loads successfully */\r\n onFormLoadSuccess?: (content: Record<string, unknown>) => void;\r\n /** Callback when form load fails */\r\n onFormLoadFail?: (content: Record<string, unknown>) => void;\r\n /** Callback for any message (useful for debugging) */\r\n onAnyMessage?: (message: MessageObject) => void;\r\n}\r\n\r\n/**\r\n * Hook to listen for messages from FormEngine iframe\r\n * \r\n * Sets up event listeners for postMessage events from the FormEngine iframe\r\n * and routes them to the appropriate callback handlers.\r\n * \r\n * @param options - Message handling options and callbacks\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormMessages } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * useFormMessages({\r\n * onSubmitStart: (data) => {\r\n * console.log('Form submission started:', data);\r\n * setLoading(true);\r\n * },\r\n * onSubmitSuccess: (data) => {\r\n * console.log('Form submitted successfully:', data);\r\n * setLoading(false);\r\n * showSuccessMessage();\r\n * },\r\n * onSubmitFail: (data) => {\r\n * console.log('Form submission failed:', data);\r\n * setLoading(false);\r\n * showErrorMessage();\r\n * },\r\n * });\r\n * \r\n * return <div>...</div>;\r\n * }\r\n * ```\r\n */\r\nexport function useFormMessages(options: UseFormMessagesOptions = {}): void {\r\n const {\r\n enabled = true,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n } = options;\r\n \r\n // Use refs to avoid recreating the handler on every render\r\n const handlersRef = useRef<MessageHandlers>({});\r\n \r\n // Update handlers ref when callbacks change\r\n useEffect(() => {\r\n handlersRef.current = {\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n };\r\n }, [\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n ]);\r\n \r\n // Message event handler\r\n const handleMessage = useCallback((event: MessageEvent) => {\r\n handleFormEngineMessage(event, handlersRef.current);\r\n }, []);\r\n \r\n // Set up message listener\r\n useEffect(() => {\r\n if (!enabled) return;\r\n \r\n window.addEventListener('message', handleMessage);\r\n \r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [enabled, handleMessage]);\r\n}\r\n\r\n/**\r\n * Hook to filter and handle only FormEngine messages\r\n * \r\n * A simpler hook that just filters FormEngine messages and calls a single handler.\r\n * Useful when you want more control over message handling.\r\n * \r\n * @param handler - Callback function for FormEngine messages\r\n * @param enabled - Whether to enable listening\r\n * \r\n * @example\r\n * ```tsx\r\n * useFormEngineMessageListener((message) => {\r\n * switch (message.messageEventName) {\r\n * case 'FormSubmitSuccess':\r\n * handleSuccess(message);\r\n * break;\r\n * case 'FormSubmitFail':\r\n * handleFailure(message);\r\n * break;\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function useFormEngineMessageListener(\r\n handler: (message: MessageObject) => void,\r\n enabled = true\r\n): void {\r\n const handlerRef = useRef(handler);\r\n \r\n useEffect(() => {\r\n handlerRef.current = handler;\r\n }, [handler]);\r\n \r\n useEffect(() => {\r\n if (!enabled) return;\r\n \r\n const handleMessage = (event: MessageEvent) => {\r\n if (isFormEngineMessage(event)) {\r\n handlerRef.current(event.data as MessageObject);\r\n }\r\n };\r\n \r\n window.addEventListener('message', handleMessage);\r\n \r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [enabled]);\r\n}\r\n\r\nexport default useFormMessages;\r\n"],"names":[],"mappings":"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"}
{"version":3,"file":"index.es.js","sources":["../src/context/FormEngineContext.tsx","../src/utils/urlBuilder.ts","../src/types/messages.ts","../src/utils/messageHandler.ts","../src/components/FormEngineWrapper.tsx","../src/hooks/useFormEngine.ts","../src/hooks/useFormMessages.ts"],"sourcesContent":["import React, { createContext, useContext, useMemo, type ReactNode } from 'react';\r\nimport type { FormEngineProviderConfig, FormEngineConfig, StyleConfig } from '../types';\r\n\r\n/**\r\n * Context value interface for FormEngine provider\r\n */\r\nexport interface FormEngineContextValue {\r\n /** Base URL of the FormEngine frontend application */\r\n baseUrl: string;\r\n /** Base name/path prefix for the FormEngine routes */\r\n baseName: string;\r\n /** Default configuration for all FormEngineWrapper instances */\r\n defaultConfig: FormEngineConfig;\r\n /** Default styles for all FormEngineWrapper instances */\r\n defaultStyles: StyleConfig;\r\n /** Whether debug mode is enabled */\r\n debug: boolean;\r\n}\r\n\r\n/** Default context values */\r\nconst defaultContextValue: FormEngineContextValue = {\r\n baseUrl: '',\r\n baseName: 'FormEngineV2',\r\n defaultConfig: {},\r\n defaultStyles: {},\r\n debug: false,\r\n};\r\n\r\n/**\r\n * React Context for FormEngine configuration\r\n */\r\nconst FormEngineContext = createContext<FormEngineContextValue>(defaultContextValue);\r\n\r\n/**\r\n * Props for FormEngineProvider component\r\n */\r\nexport interface FormEngineProviderProps extends FormEngineProviderConfig {\r\n /** Child components */\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * Provider component for FormEngine configuration\r\n * \r\n * Wrap your application (or a portion of it) with this provider to configure\r\n * the FormEngine wrapper components with default settings.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { FormEngineProvider } from '@formengine/wrapper';\r\n * \r\n * function App() {\r\n * return (\r\n * <FormEngineProvider\r\n * baseUrl=\"https://forms.example.com\"\r\n * defaultConfig={{\r\n * layout: { mini: true },\r\n * editor: { show: true, enabled: true },\r\n * }}\r\n * >\r\n * <YourApp />\r\n * </FormEngineProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const FormEngineProvider: React.FC<FormEngineProviderProps> = ({\r\n baseUrl = \"/\",\r\n baseName = 'FormEngineV2',\r\n defaultConfig = {},\r\n defaultStyles = {},\r\n debug = false,\r\n children,\r\n}) => {\r\n // Memoize the context value to prevent unnecessary re-renders\r\n const contextValue = useMemo<FormEngineContextValue>(\r\n () => ({\r\n baseUrl,\r\n baseName,\r\n defaultConfig,\r\n defaultStyles,\r\n debug,\r\n }),\r\n [baseUrl, baseName, defaultConfig, defaultStyles, debug]\r\n );\r\n \r\n // Validate required props\r\n if (!baseUrl) {\r\n console.warn('FormEngineProvider: baseUrl is required but was not provided');\r\n }\r\n \r\n return (\r\n <FormEngineContext.Provider value={contextValue}>\r\n {children}\r\n </FormEngineContext.Provider>\r\n );\r\n};\r\n\r\n/**\r\n * Hook to access FormEngine context\r\n * \r\n * @returns The FormEngine context value\r\n * @throws Error if used outside of FormEngineProvider\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormEngineContext } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * const { baseUrl, debug } = useFormEngineContext();\r\n * \r\n * if (debug) {\r\n * console.log('FormEngine baseUrl:', baseUrl);\r\n * }\r\n * \r\n * return <div>...</div>;\r\n * }\r\n * ```\r\n */\r\nexport const useFormEngineContext = (): FormEngineContextValue => {\r\n const context = useContext(FormEngineContext);\r\n \r\n if (!context) {\r\n throw new Error(\r\n 'useFormEngineContext must be used within a FormEngineProvider. ' +\r\n 'Wrap your component tree with <FormEngineProvider> to fix this error.'\r\n );\r\n }\r\n \r\n return context;\r\n};\r\n\r\n/**\r\n * Hook to get the configured base URL\r\n */\r\nexport const useFormEngineBaseUrl = (): string => {\r\n const { baseUrl } = useFormEngineContext();\r\n return baseUrl;\r\n};\r\n\r\n/**\r\n * Hook to check if debug mode is enabled\r\n */\r\nexport const useFormEngineDebug = (): boolean => {\r\n const { debug } = useFormEngineContext();\r\n return debug;\r\n};\r\n\r\nexport { FormEngineContext };\r\n","import type { FormMode, FormEngineConfig } from '../types';\r\n\r\n/**\r\n * URL parameter keys for FormEngine routes\r\n */\r\nexport const URL_PARAMS = {\r\n REF_OBJ: 'refObj',\r\n REF_ID: 'refId',\r\n TPL_NAME: 'tplName',\r\n EDITOR: 'editor',\r\n EDITOR_SHOW: 'editorShow',\r\n EDITOR_ENABLE: 'editorEnable',\r\n EDITOR_REQUIRED: 'editorRequired',\r\n MINI: 'st_mini',\r\n FOOTER: 'footer',\r\n FORM_FOOTER: 'form_footer',\r\n HISTORY: 'history_show',\r\n READ_ONLY: 'readOnly',\r\n INIT_DATA: 'initData',\r\n EXTRA_DATA: 'extraData',\r\n PREVIEW_DATA: 'previewData',\r\n} as const;\r\n\r\n/**\r\n * Route paths for different form modes\r\n */\r\nexport const ROUTES = {\r\n CREATE: '/form-data/create',\r\n DUMMY_CREATE: '/form-data/dummy-create',\r\n EDIT: '/form-data/edit',\r\n CREATE_OR_EDIT: '/form-data/createOrEdit',\r\n VIEW: '/form-data/view',\r\n} as const;\r\n\r\n/**\r\n * Options for building the iframe URL\r\n */\r\nexport interface BuildUrlOptions {\r\n /** Base URL of the FormEngine application */\r\n baseUrl: string;\r\n /** Base name/path prefix (default: 'FormEngineV2') */\r\n baseName?: string;\r\n /** Form operation mode */\r\n mode: FormMode;\r\n /** Reference object identifier */\r\n refObj: string;\r\n /** Reference ID */\r\n refId: string | number;\r\n /** Template name */\r\n tplName: string;\r\n /** Form data ID (required for edit/view modes) */\r\n id?: number | string;\r\n /** Form configuration */\r\n config?: FormEngineConfig;\r\n}\r\n\r\n/**\r\n * Encode an object to base64 string for URL parameter\r\n */\r\nexport function encodeBase64(data: Record<string, unknown>): string {\r\n try {\r\n const jsonString = JSON.stringify(data);\r\n // Use btoa for browser environment, or Buffer for Node.js\r\n if (typeof btoa === 'function') {\r\n return btoa(encodeURIComponent(jsonString));\r\n }\r\n return Buffer.from(jsonString).toString('base64');\r\n } catch {\r\n console.error('Failed to encode data to base64');\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Build URL parameters from config\r\n */\r\nfunction buildConfigParams(config?: FormEngineConfig): URLSearchParams {\r\n const params = new URLSearchParams();\r\n \r\n if (!config) return params;\r\n \r\n // Editor config\r\n if (config.editor) {\r\n if (config.editor.show !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_SHOW, config.editor.show ? '1' : '0');\r\n }\r\n if (config.editor.enabled !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_ENABLE, config.editor.enabled ? '1' : '0');\r\n }\r\n if (config.editor.required !== undefined) {\r\n params.set(URL_PARAMS.EDITOR_REQUIRED, config.editor.required ? '1' : '0');\r\n }\r\n if (config.editor.defaultValue) {\r\n params.set(URL_PARAMS.EDITOR, config.editor.defaultValue);\r\n }\r\n }\r\n \r\n // Layout config\r\n if (config.layout) {\r\n if (config.layout.mini !== undefined) {\r\n params.set(URL_PARAMS.MINI, config.layout.mini ? '1' : '0');\r\n }\r\n if (config.layout.showFooter !== undefined) {\r\n params.set(URL_PARAMS.FOOTER, config.layout.showFooter ? '1' : '0');\r\n }\r\n if (config.layout.showHistory !== undefined) {\r\n params.set(URL_PARAMS.HISTORY, config.layout.showHistory ? '1' : '0');\r\n }\r\n if (config.layout.readOnly !== undefined) {\r\n params.set(URL_PARAMS.READ_ONLY, config.layout.readOnly ? '1' : '0');\r\n }\r\n if (config.layout.showFormFooter !== undefined) {\r\n params.set(URL_PARAMS.FORM_FOOTER, config.layout.showFormFooter ? '1' : '0');\r\n }\r\n }\r\n \r\n // Data params\r\n if (config.initData && Object.keys(config.initData).length > 0) {\r\n params.set(URL_PARAMS.INIT_DATA, encodeURIComponent(JSON.stringify(config.initData)));\r\n }\r\n \r\n if (config.extraData && Object.keys(config.extraData).length > 0) {\r\n params.set(URL_PARAMS.EXTRA_DATA, encodeBase64(config.extraData));\r\n }\r\n \r\n if (config.previewData && Object.keys(config.previewData).length > 0) {\r\n params.set(URL_PARAMS.PREVIEW_DATA, encodeURIComponent(JSON.stringify(config.previewData)));\r\n }\r\n \r\n return params;\r\n}\r\n\r\n/**\r\n * Build the full iframe URL for FormEngine\r\n * \r\n * @param options - URL building options\r\n * @returns The complete URL string for the iframe\r\n * \r\n * @example\r\n * ```typescript\r\n * const url = buildFormEngineUrl({\r\n * baseUrl: 'https://forms.example.com',\r\n * mode: 'createOrEdit',\r\n * refObj: 'Order',\r\n * refId: '12345',\r\n * tplName: 'order-form',\r\n * });\r\n * // => \"https://forms.example.com/FormEngineV2/form-data/createOrEdit?refObj=Order&refId=12345&tplName=order-form\"\r\n * ```\r\n */\r\nexport function buildFormEngineUrl(options: BuildUrlOptions): string {\r\n const {\r\n baseUrl,\r\n baseName = 'FormEngineV2',\r\n mode,\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n config,\r\n } = options;\r\n \r\n // Normalize base URL (remove trailing slash)\r\n const normalizedBaseUrl = baseUrl.replace(/\\/+$/, '');\r\n \r\n // Build the route path based on mode\r\n let routePath: string;\r\n \r\n switch (mode) {\r\n case 'create':\r\n routePath = ROUTES.CREATE;\r\n break;\r\n case 'edit':\r\n case 'view':\r\n if (!id) {\r\n console.warn(`Mode \"${mode}\" requires an id. Falling back to createOrEdit.`);\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n } else {\r\n routePath = `${ROUTES.EDIT}/${id}`;\r\n }\r\n break;\r\n case 'createOrEdit':\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n break;\r\n case 'dummy-create':\r\n routePath = ROUTES.DUMMY_CREATE;\r\n break;\r\n default:\r\n routePath = ROUTES.CREATE_OR_EDIT;\r\n break;\r\n }\r\n \r\n // Build query parameters\r\n const params = buildConfigParams(config);\r\n params.set(URL_PARAMS.REF_OBJ, refObj);\r\n params.set(URL_PARAMS.REF_ID, String(refId));\r\n params.set(URL_PARAMS.TPL_NAME, tplName);\r\n \r\n // For view mode, set readOnly\r\n if (mode === 'view') {\r\n params.set(URL_PARAMS.READ_ONLY, '1');\r\n }\r\n \r\n // Construct the full URL\r\n const queryString = params.toString();\r\n const fullPath = baseName ? `/${baseName}${routePath}` : routePath;\r\n \r\n return `${normalizedBaseUrl}${fullPath}${queryString ? `?${queryString}` : ''}`;\r\n}\r\n\r\n/**\r\n * Parse a FormEngine URL to extract its components\r\n * Useful for debugging or validation\r\n */\r\nexport function parseFormEngineUrl(url: string): Partial<BuildUrlOptions> | null {\r\n try {\r\n const urlObj = new URL(url);\r\n const params = urlObj.searchParams;\r\n \r\n return {\r\n baseUrl: urlObj.origin,\r\n refObj: params.get(URL_PARAMS.REF_OBJ) || undefined,\r\n refId: params.get(URL_PARAMS.REF_ID) || undefined,\r\n tplName: params.get(URL_PARAMS.TPL_NAME) || undefined,\r\n };\r\n } catch {\r\n console.error('Failed to parse FormEngine URL');\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Message types for communication between FormEngineWrapper and FormEngine iframe\r\n * These types mirror the FormEngine's internal message system\r\n */\r\n\r\nimport { FieldLabelsMap } from \"./config\";\r\n\r\n\r\n/** Identifier for messages from FormEngine */\r\nexport const MESSAGE_FROM = 'MTG_FORMENGINE';\r\n\r\n// =============================================================================\r\n// Event Types - Categories of messages\r\n// =============================================================================\r\n\r\n/** Event types sent FROM FormEngine TO parent window */\r\nexport const SUBMIT_START_EVENT_TYPE = 'submit_start' as const;\r\nexport const SUBMIT_RESULT_EVENT_TYPE = 'submit_result' as const;\r\nexport const RETURN_FORM_DATA_EVENT_TYPE = 'return_form_data' as const;\r\nexport const RETURN_SET_FORM_DATA_EVENT_TYPE = 'return_set_form_data' as const;\r\nexport const FORM_ONLOAD_EVENT_TYPE = 'form_onload' as const;\r\nexport const FORM_DATA_CHANGE_EVENT_TYPE = 'form_data_change' as const;\r\n\r\n/** Event types sent FROM parent TO FormEngine */\r\nexport const FORM_SUBMIT_EVENT_TYPE = 'submit' as const;\r\nexport const GET_FORM_DATA_EVENT_TYPE = 'get_form_data' as const;\r\nexport const SET_FORM_DATA_EVENT_TYPE = 'set_form_data' as const;\r\nexport const SET_FIELD_LABELS_EVENT_TYPE = 'set_field_labels' as const;\r\n\r\n// =============================================================================\r\n// Event Names - Specific events within each type\r\n// =============================================================================\r\n\r\n/** Event names FROM FormEngine */\r\nexport const SUBMIT_START_EVENT_NAME = 'FormSubmitStart' as const;\r\nexport const SUBMIT_RESULT_SUCCESS_EVENT_NAME = 'FormSubmitSuccess' as const;\r\nexport const SUBMIT_RESULT_FAIL_EVENT_NAME = 'FormSubmitFail' as const;\r\nexport const RETURN_FORM_DATA_EVENT_NAME = 'ReturnFormData' as const;\r\nexport const RETURN_SET_FORM_DATA_EVENT_NAME = 'ReturnSetFormData' as const;\r\nexport const FORM_ONLOAD_SUCCESS_EVENT_NAME = 'FormOnLoadSuccess' as const;\r\nexport const FORM_ONLOAD_FAIL_EVENT_NAME = 'FormOnLoadFail' as const;\r\nexport const FORM_DATA_CHANGE_EVENT_NAME = 'FormDataChange' as const;\r\n\r\n/** Event names TO FormEngine */\r\nexport const FORM_SUBMIT_EVENT_NAME = 'Submit' as const;\r\nexport const GET_FORM_DATA_EVENT_NAME = 'GetFormData' as const;\r\nexport const SET_FORM_DATA_EVENT_NAME = 'SetFormData' as const;\r\nexport const SET_FIELD_LABELS_EVENT_NAME = 'SetFieldLabels' as const;\r\n\r\n// =============================================================================\r\n// Type Definitions\r\n// =============================================================================\r\n\r\n/** Event types from FormEngine to parent */\r\nexport type MessageEventTypeFromFormEngine =\r\n | typeof SUBMIT_START_EVENT_TYPE\r\n | typeof SUBMIT_RESULT_EVENT_TYPE\r\n | typeof RETURN_FORM_DATA_EVENT_TYPE\r\n | typeof RETURN_SET_FORM_DATA_EVENT_TYPE\r\n | typeof FORM_ONLOAD_EVENT_TYPE\r\n | typeof FORM_DATA_CHANGE_EVENT_TYPE;\r\n\r\n/** Event names from FormEngine to parent */\r\nexport type MessageEventNameFromFormEngine =\r\n | typeof SUBMIT_START_EVENT_NAME\r\n | typeof SUBMIT_RESULT_SUCCESS_EVENT_NAME\r\n | typeof SUBMIT_RESULT_FAIL_EVENT_NAME\r\n | typeof RETURN_FORM_DATA_EVENT_NAME\r\n | typeof RETURN_SET_FORM_DATA_EVENT_NAME\r\n | typeof FORM_ONLOAD_SUCCESS_EVENT_NAME\r\n | typeof FORM_ONLOAD_FAIL_EVENT_NAME\r\n | typeof FORM_DATA_CHANGE_EVENT_NAME;\r\n\r\n/** Event types from parent to FormEngine */\r\nexport type MessageEventTypeToFormEngine =\r\n | typeof FORM_SUBMIT_EVENT_TYPE\r\n | typeof GET_FORM_DATA_EVENT_TYPE\r\n | typeof SET_FORM_DATA_EVENT_TYPE\r\n | typeof SET_FIELD_LABELS_EVENT_TYPE;\r\n\r\n/** Event names from parent to FormEngine */\r\nexport type MessageEventNameToFormEngine =\r\n | typeof FORM_SUBMIT_EVENT_NAME\r\n | typeof GET_FORM_DATA_EVENT_NAME\r\n | typeof SET_FORM_DATA_EVENT_NAME\r\n | typeof SET_FIELD_LABELS_EVENT_NAME;\r\n\r\n/** All possible message event types */\r\nexport type MessageEventType = MessageEventTypeFromFormEngine | MessageEventTypeToFormEngine;\r\n\r\n/** All possible message event names */\r\nexport type MessageEventName = MessageEventNameFromFormEngine | MessageEventNameToFormEngine;\r\n\r\n// =============================================================================\r\n// Message Object Interfaces\r\n// =============================================================================\r\n\r\n/**\r\n * Base message object interface for FormEngine communication\r\n */\r\nexport interface MessageObject {\r\n /** Source identifier for the message */\r\n messageFrom: string;\r\n /** The specific event name */\r\n messageEventName: MessageEventName;\r\n /** The category of the event */\r\n messageEventType: MessageEventType;\r\n /** The payload of the message */\r\n messageEventContent: any;\r\n /** Whether the operation was successful (for response messages) */\r\n success?: boolean;\r\n}\r\n\r\n/**\r\n * Content structure for submit-related messages\r\n */\r\nexport interface SubmitMessageContent {\r\n /** Form data ID (present when editing existing form) */\r\n id?: number;\r\n /** Template name */\r\n tplName?: string;\r\n /** Reference object identifier */\r\n refObj?: string;\r\n /** Reference ID */\r\n refId?: string | number;\r\n /** Type of submit operation */\r\n submitType?: 'createOrEdit' | 'edit' | 'create' | 'dummy-create';\r\n /** Additional data */\r\n extra?: unknown;\r\n}\r\n\r\n/**\r\n * Message for setting form data\r\n */\r\nexport interface SetFormDataMessage extends Omit<MessageObject, 'messageEventContent' | 'messageEventName'> {\r\n messageEventName: typeof SET_FORM_DATA_EVENT_NAME;\r\n messageEventType: typeof SET_FORM_DATA_EVENT_TYPE;\r\n messageEventContent: {\r\n id?: string | number;\r\n tplName?: string;\r\n data: unknown;\r\n };\r\n}\r\n\r\n/**\r\n * Message for getting form data response\r\n */\r\nexport interface ReturnFormDataMessage extends MessageObject {\r\n messageEventName: typeof RETURN_FORM_DATA_EVENT_NAME;\r\n messageEventType: typeof RETURN_FORM_DATA_EVENT_TYPE;\r\n messageEventContent: {\r\n id?: string | number;\r\n data: unknown;\r\n };\r\n}\r\n\r\n/**\r\n * Form information in onload messages\r\n */\r\nexport interface FormOnLoadMessageForm {\r\n /** Form data ID */\r\n id?: number;\r\n /** Reference object */\r\n refObj?: string;\r\n /** Reference ID */\r\n refId?: string;\r\n /** Template name */\r\n tplName: string;\r\n /** Template display title */\r\n templateTitle: string;\r\n}\r\n\r\n/**\r\n * Content for form onload messages\r\n */\r\nexport interface FormOnLoadMessageContent {\r\n /** Whether the form has child forms */\r\n hasChildren: boolean;\r\n /** Number of tabs (for tabular forms) */\r\n tabCount: number;\r\n /** Parent form information */\r\n form: FormOnLoadMessageForm;\r\n /** Child forms information */\r\n childrenForms: FormOnLoadMessageForm[];\r\n}\r\n\r\n/**\r\n * Submit start message from FormEngine\r\n */\r\nexport interface SubmitStartMessage extends MessageObject {\r\n messageEventName: typeof SUBMIT_START_EVENT_NAME;\r\n messageEventType: typeof SUBMIT_START_EVENT_TYPE;\r\n messageEventContent: SubmitMessageContent;\r\n}\r\n\r\n/**\r\n * Submit result message from FormEngine\r\n */\r\nexport interface SubmitResultMessage extends MessageObject {\r\n messageEventName: typeof SUBMIT_RESULT_SUCCESS_EVENT_NAME | typeof SUBMIT_RESULT_FAIL_EVENT_NAME;\r\n messageEventType: typeof SUBMIT_RESULT_EVENT_TYPE;\r\n messageEventContent: SubmitMessageContent;\r\n}\r\n\r\n/**\r\n * Form onload message from FormEngine\r\n */\r\nexport interface FormOnLoadMessage extends MessageObject {\r\n messageEventName: typeof FORM_ONLOAD_SUCCESS_EVENT_NAME | typeof FORM_ONLOAD_FAIL_EVENT_NAME;\r\n messageEventType: typeof FORM_ONLOAD_EVENT_TYPE;\r\n messageEventContent: FormOnLoadMessageContent;\r\n}\r\n\r\n/**\r\n * Content for form data change messages\r\n */\r\nexport interface FormDataChangeMessageContent {\r\n /** The path/field that changed (e.g., \"root_field1\" or \"root_section_field2\") */\r\n path?: string;\r\n /** The new value of the changed field */\r\n value?: unknown;\r\n /** The complete form data after the change */\r\n formData: unknown;\r\n /** Form ID if available */\r\n id?: string | number;\r\n /** Template name */\r\n tplName?: string;\r\n}\r\n\r\n/**\r\n * Form data change message from FormEngine\r\n */\r\nexport interface FormDataChangeMessage extends MessageObject {\r\n messageEventName: typeof FORM_DATA_CHANGE_EVENT_NAME;\r\n messageEventType: typeof FORM_DATA_CHANGE_EVENT_TYPE;\r\n messageEventContent: FormDataChangeMessageContent;\r\n}\r\n\r\n/**\r\n * Message content for setting field labels\r\n */\r\nexport interface SetFieldLabelsMessageContent {\r\n /** Map of pathId to label config */\r\n labels: FieldLabelsMap;\r\n /** Whether to merge with existing labels (true) or replace all (false) */\r\n merge?: boolean;\r\n}\r\n\r\n/**\r\n * Message for setting field labels\r\n */\r\nexport interface SetFieldLabelsMessage extends MessageObject {\r\n messageEventType: typeof SET_FIELD_LABELS_EVENT_TYPE;\r\n messageEventName: typeof SET_FIELD_LABELS_EVENT_NAME;\r\n messageEventContent: SetFieldLabelsMessageContent;\r\n}\r\n","import { FieldLabelsMap } from '../types';\r\nimport {\r\n MESSAGE_FROM,\r\n SUBMIT_START_EVENT_NAME,\r\n SUBMIT_RESULT_SUCCESS_EVENT_NAME,\r\n SUBMIT_RESULT_FAIL_EVENT_NAME,\r\n RETURN_FORM_DATA_EVENT_NAME,\r\n RETURN_SET_FORM_DATA_EVENT_NAME,\r\n FORM_ONLOAD_SUCCESS_EVENT_NAME,\r\n FORM_ONLOAD_FAIL_EVENT_NAME,\r\n FORM_DATA_CHANGE_EVENT_NAME,\r\n FORM_SUBMIT_EVENT_TYPE,\r\n FORM_SUBMIT_EVENT_NAME,\r\n GET_FORM_DATA_EVENT_TYPE,\r\n GET_FORM_DATA_EVENT_NAME,\r\n SET_FORM_DATA_EVENT_TYPE,\r\n SET_FORM_DATA_EVENT_NAME,\r\n SET_FIELD_LABELS_EVENT_TYPE,\r\n SET_FIELD_LABELS_EVENT_NAME,\r\n type MessageObject,\r\n type MessageEventType,\r\n type MessageEventName,\r\n} from '../types/messages';\r\n\r\n/** Identifier for messages from the wrapper */\r\nconst WRAPPER_MESSAGE_FROM = 'FORMENGINE_WRAPPER';\r\n\r\n/**\r\n * Check if a message is from FormEngine\r\n */\r\nexport function isFormEngineMessage(event: MessageEvent): boolean {\r\n return event.data?.messageFrom === MESSAGE_FROM;\r\n}\r\n\r\n/**\r\n * Create a message object to send to FormEngine\r\n */\r\nfunction createMessage(\r\n eventType: MessageEventType,\r\n eventName: MessageEventName,\r\n content: Record<string, unknown> = {}\r\n): MessageObject {\r\n return {\r\n messageFrom: WRAPPER_MESSAGE_FROM,\r\n messageEventType: eventType,\r\n messageEventName: eventName,\r\n messageEventContent: content,\r\n };\r\n}\r\n\r\n/**\r\n * Send a message to the FormEngine iframe\r\n */\r\nexport function postMessageToIframe(\r\n iframe: HTMLIFrameElement | null,\r\n message: MessageObject,\r\n targetOrigin = '*'\r\n): boolean {\r\n if (!iframe?.contentWindow) {\r\n console.warn('Cannot post message: iframe or contentWindow is null');\r\n return false;\r\n }\r\n \r\n try {\r\n iframe.contentWindow.postMessage(message, targetOrigin);\r\n return true;\r\n } catch (error) {\r\n console.error('Failed to post message to iframe:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Trigger form submission in the iframe\r\n */\r\nexport function triggerSubmit(\r\n iframe: HTMLIFrameElement | null,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n FORM_SUBMIT_EVENT_TYPE,\r\n FORM_SUBMIT_EVENT_NAME\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Request form data from the iframe\r\n */\r\nexport function requestFormData(\r\n iframe: HTMLIFrameElement | null,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n GET_FORM_DATA_EVENT_TYPE,\r\n GET_FORM_DATA_EVENT_NAME\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Set form data in the iframe\r\n */\r\nexport function sendFormData(\r\n iframe: HTMLIFrameElement | null,\r\n data: unknown,\r\n options: { id?: string | number; tplName?: string } = {},\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n SET_FORM_DATA_EVENT_TYPE,\r\n SET_FORM_DATA_EVENT_NAME,\r\n {\r\n ...options,\r\n data,\r\n }\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Set field labels in the iframe\r\n * \r\n * @param iframe - The iframe element\r\n * @param labels - Map of pathId to label configuration\r\n * @param merge - Whether to merge with existing labels (default: true)\r\n * @param targetOrigin - Target origin for postMessage\r\n * \r\n * @example\r\n * ```typescript\r\n * sendFieldLabels(iframeRef.current, {\r\n * 'root_firstName': {\r\n * content: 'Edited by John @ 2024-01-01',\r\n * style: { color: 'blue', fontStyle: 'italic' }\r\n * },\r\n * 'root_lastName': {\r\n * content: 'Required field',\r\n * style: { color: 'red' }\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function sendFieldLabels(\r\n iframe: HTMLIFrameElement | null,\r\n labels: FieldLabelsMap,\r\n merge = true,\r\n targetOrigin = '*'\r\n): boolean {\r\n const message = createMessage(\r\n SET_FIELD_LABELS_EVENT_TYPE,\r\n SET_FIELD_LABELS_EVENT_NAME,\r\n {\r\n labels,\r\n merge,\r\n }\r\n );\r\n return postMessageToIframe(iframe, message, targetOrigin);\r\n}\r\n\r\n/**\r\n * Message handler callback types\r\n */\r\nexport interface MessageHandlers {\r\n onSubmitStart?: (content: Record<string, unknown>) => void;\r\n onSubmitSuccess?: (content: Record<string, unknown>) => void;\r\n onSubmitFail?: (content: Record<string, unknown>) => void;\r\n onFormDataReturn?: (content: Record<string, unknown>) => void;\r\n onSetFormDataReturn?: (content: Record<string, unknown>) => void;\r\n onFormLoadSuccess?: (content: Record<string, unknown>) => void;\r\n onFormLoadFail?: (content: Record<string, unknown>) => void;\r\n onFormDataChange?: (content: Record<string, unknown>) => void;\r\n onAnyMessage?: (message: MessageObject) => void;\r\n}\r\n\r\n/**\r\n * Handle incoming messages from FormEngine\r\n */\r\nexport function handleFormEngineMessage(\r\n event: MessageEvent,\r\n handlers: MessageHandlers\r\n): void {\r\n // Validate message source\r\n if (!isFormEngineMessage(event)) {\r\n return;\r\n }\r\n \r\n const message = event.data as MessageObject;\r\n \r\n // Call the generic message handler\r\n handlers.onAnyMessage?.(message);\r\n \r\n // Route to specific handlers based on event name\r\n switch (message.messageEventName) {\r\n case SUBMIT_START_EVENT_NAME:\r\n handlers.onSubmitStart?.(message.messageEventContent);\r\n break;\r\n \r\n case SUBMIT_RESULT_SUCCESS_EVENT_NAME:\r\n handlers.onSubmitSuccess?.(message.messageEventContent);\r\n break;\r\n \r\n case SUBMIT_RESULT_FAIL_EVENT_NAME:\r\n handlers.onSubmitFail?.(message.messageEventContent);\r\n break;\r\n \r\n case RETURN_FORM_DATA_EVENT_NAME:\r\n handlers.onFormDataReturn?.(message.messageEventContent);\r\n break;\r\n \r\n case RETURN_SET_FORM_DATA_EVENT_NAME:\r\n handlers.onSetFormDataReturn?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_ONLOAD_SUCCESS_EVENT_NAME:\r\n handlers.onFormLoadSuccess?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_ONLOAD_FAIL_EVENT_NAME:\r\n handlers.onFormLoadFail?.(message.messageEventContent);\r\n break;\r\n \r\n case FORM_DATA_CHANGE_EVENT_NAME:\r\n handlers.onFormDataChange?.(message.messageEventContent);\r\n break;\r\n \r\n default:\r\n // Unknown message type - already logged via onAnyMessage if handler provided\r\n break;\r\n }\r\n}\r\n\r\n/**\r\n * Create a promise-based form data request\r\n * Returns a promise that resolves when form data is received\r\n */\r\nexport function requestFormDataAsync(\r\n iframe: HTMLIFrameElement | null,\r\n timeout = 5000,\r\n targetOrigin = '*'\r\n): Promise<unknown> {\r\n return new Promise((resolve, reject) => {\r\n if (!iframe) {\r\n reject(new Error('Iframe is null'));\r\n return;\r\n }\r\n \r\n let timeoutId: ReturnType<typeof setTimeout>;\r\n \r\n const messageHandler = (event: MessageEvent) => {\r\n if (!isFormEngineMessage(event)) return;\r\n \r\n const message = event.data as MessageObject;\r\n if (message.messageEventName === RETURN_FORM_DATA_EVENT_NAME) {\r\n clearTimeout(timeoutId);\r\n window.removeEventListener('message', messageHandler);\r\n resolve(message.messageEventContent.data);\r\n }\r\n };\r\n \r\n window.addEventListener('message', messageHandler);\r\n \r\n // Set timeout for the request\r\n timeoutId = setTimeout(() => {\r\n window.removeEventListener('message', messageHandler);\r\n reject(new Error('Form data request timed out'));\r\n }, timeout);\r\n \r\n // Send the request\r\n if (!requestFormData(iframe, targetOrigin)) {\r\n clearTimeout(timeoutId);\r\n window.removeEventListener('message', messageHandler);\r\n reject(new Error('Failed to send form data request'));\r\n }\r\n });\r\n}\r\n","import React, {\r\n forwardRef,\r\n useImperativeHandle,\r\n useEffect,\r\n useCallback,\r\n useMemo,\r\n useRef,\r\n type CSSProperties,\r\n} from 'react';\r\nimport type {\r\n FormEngineWrapperProps,\r\n FormEngineWrapperRef,\r\n StyleConfig,\r\n FormEngineConfig,\r\n SubmitEventData,\r\n FormLoadEventData,\r\n FormDataChangeEvent,\r\n} from '../types';\r\nimport { useFormEngineContext } from '../context';\r\nimport { buildFormEngineUrl } from '../utils/urlBuilder';\r\nimport {\r\n handleFormEngineMessage,\r\n triggerSubmit,\r\n sendFormData,\r\n sendFieldLabels,\r\n requestFormDataAsync,\r\n} from '../utils/messageHandler';\r\nimport type { FieldLabelsMap } from '../types/config';\r\n\r\n/** Default styles for the wrapper container */\r\nconst defaultRootStyle: CSSProperties = {\r\n width: '100%',\r\n height: '100%',\r\n position: 'relative',\r\n overflow: 'hidden',\r\n};\r\n\r\n/** Default styles for the iframe */\r\nconst defaultIframeStyle: CSSProperties = {\r\n width: '100%',\r\n height: '100%',\r\n border: 'none',\r\n};\r\n\r\n/**\r\n * Merge styles with defaults\r\n */\r\nfunction mergeStyles(\r\n defaultStyles: StyleConfig,\r\n propStyles?: StyleConfig\r\n): StyleConfig {\r\n return {\r\n container: { ...defaultStyles.container, ...propStyles?.container },\r\n iframe: { ...defaultStyles.iframe, ...propStyles?.iframe },\r\n };\r\n}\r\n\r\n/**\r\n * Deep merge configs with defaults\r\n */\r\nfunction mergeConfig(\r\n defaultConfig: FormEngineConfig,\r\n propConfig?: FormEngineConfig\r\n): FormEngineConfig {\r\n return {\r\n editor: { ...defaultConfig.editor, ...propConfig?.editor },\r\n layout: { ...defaultConfig.layout, ...propConfig?.layout },\r\n initData: { ...defaultConfig.initData, ...propConfig?.initData },\r\n extraData: { ...defaultConfig.extraData, ...propConfig?.extraData },\r\n previewData: { ...defaultConfig.previewData, ...propConfig?.previewData },\r\n };\r\n}\r\n\r\n/**\r\n * FormEngineWrapper Component\r\n * \r\n * A React component that wraps the FormEngine application in an iframe,\r\n * providing a simple interface for integration with other React applications.\r\n * \r\n * @example\r\n * Basic usage:\r\n * ```tsx\r\n * import { FormEngineWrapper, FormEngineProvider } from '@formengine/wrapper';\r\n * \r\n * function App() {\r\n * return (\r\n * <FormEngineProvider baseUrl=\"https://forms.example.com\">\r\n * <FormEngineWrapper\r\n * refObj=\"Order\"\r\n * refId=\"12345\"\r\n * tplName=\"order-form\"\r\n * mode=\"createOrEdit\"\r\n * onSubmitSuccess={(data) => {\r\n * console.log('Form submitted:', data);\r\n * }}\r\n * />\r\n * </FormEngineProvider>\r\n * );\r\n * }\r\n * ```\r\n * \r\n * @example\r\n * With ref for programmatic control:\r\n * ```tsx\r\n * import { useRef } from 'react';\r\n * import { FormEngineWrapper, FormEngineWrapperRef } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * const formRef = useRef<FormEngineWrapperRef>(null);\r\n * \r\n * const handleExternalSubmit = () => {\r\n * formRef.current?.submit();\r\n * };\r\n * \r\n * const handleGetData = async () => {\r\n * const data = await formRef.current?.getFormData();\r\n * console.log('Form data:', data);\r\n * };\r\n * \r\n * return (\r\n * <>\r\n * <FormEngineWrapper\r\n * ref={formRef}\r\n * refObj=\"Order\"\r\n * refId=\"12345\"\r\n * tplName=\"order-form\"\r\n * />\r\n * <button onClick={handleExternalSubmit}>Submit</button>\r\n * <button onClick={handleGetData}>Get Data</button>\r\n * </>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const FormEngineWrapper = forwardRef<FormEngineWrapperRef, FormEngineWrapperProps>(\r\n (props, ref) => {\r\n const {\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n mode = 'createOrEdit',\r\n styles: propStyles,\r\n config: propConfig,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormLoad,\r\n onFormDataChange,\r\n onMessage,\r\n className,\r\n title = 'FormEngine Form',\r\n allowFullScreen = false,\r\n sandbox = 'allow-same-origin allow-scripts allow-forms allow-popups',\r\n } = props;\r\n \r\n // Get context values\r\n const {\r\n baseUrl,\r\n baseName,\r\n defaultConfig,\r\n defaultStyles,\r\n debug,\r\n } = useFormEngineContext();\r\n \r\n // Refs\r\n const iframeRef = useRef<HTMLIFrameElement>(null);\r\n const formDataResolverRef = useRef<((data: unknown) => void) | null>(null);\r\n \r\n // Merge styles and config with defaults\r\n const mergedStyles = useMemo(\r\n () => mergeStyles(\r\n { container: defaultRootStyle, iframe: defaultIframeStyle, ...defaultStyles },\r\n propStyles\r\n ),\r\n [defaultStyles, propStyles]\r\n );\r\n \r\n const mergedConfig = useMemo(\r\n () => mergeConfig(defaultConfig, propConfig),\r\n [defaultConfig, propConfig]\r\n );\r\n \r\n // Build the iframe URL\r\n const iframeUrl = useMemo(() => {\r\n if (!baseUrl) {\r\n console.warn('FormEngineWrapper: baseUrl is not configured');\r\n return '';\r\n }\r\n \r\n return buildFormEngineUrl({\r\n baseUrl,\r\n baseName,\r\n mode,\r\n refObj,\r\n refId,\r\n tplName,\r\n id,\r\n config: mergedConfig,\r\n });\r\n }, [baseUrl, baseName, mode, refObj, refId, tplName, id, mergedConfig]);\r\n \r\n // Debug logging\r\n useEffect(() => {\r\n if (debug) {\r\n console.log('[FormEngineWrapper] URL:', iframeUrl);\r\n console.log('[FormEngineWrapper] Config:', mergedConfig);\r\n }\r\n }, [debug, iframeUrl, mergedConfig]);\r\n \r\n // Message handler\r\n const handleMessage = useCallback(\r\n (event: MessageEvent) => {\r\n handleFormEngineMessage(event, {\r\n onSubmitStart: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit started:', content);\r\n onSubmitStart?.(content as SubmitEventData);\r\n },\r\n onSubmitSuccess: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit success:', content);\r\n onSubmitSuccess?.(content as SubmitEventData);\r\n },\r\n onSubmitFail: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Submit failed:', content);\r\n onSubmitFail?.(content as SubmitEventData);\r\n },\r\n onFormDataReturn: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form data returned:', content);\r\n formDataResolverRef.current?.(content.data);\r\n formDataResolverRef.current = null;\r\n },\r\n onFormDataChange: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form data changed:', content);\r\n onFormDataChange?.(content as unknown as FormDataChangeEvent);\r\n },\r\n onFormLoadSuccess: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form loaded:', content);\r\n onFormLoad?.(content as unknown as FormLoadEventData);\r\n },\r\n onFormLoadFail: (content) => {\r\n if (debug) console.log('[FormEngineWrapper] Form load failed:', content);\r\n },\r\n onAnyMessage: (message) => {\r\n onMessage?.(message);\r\n },\r\n });\r\n },\r\n [\r\n debug,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormLoad,\r\n onFormDataChange,\r\n onMessage,\r\n ]\r\n );\r\n \r\n // Set up message listener\r\n useEffect(() => {\r\n window.addEventListener('message', handleMessage);\r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [handleMessage]);\r\n \r\n // Expose imperative methods via ref\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n submit: () => {\r\n triggerSubmit(iframeRef.current);\r\n },\r\n getFormData: () => {\r\n return requestFormDataAsync(iframeRef.current, 5000);\r\n },\r\n setFormData: (data: unknown) => {\r\n sendFormData(iframeRef.current, data);\r\n },\r\n setFieldLabels: (labels: FieldLabelsMap, merge = true) => {\r\n sendFieldLabels(iframeRef.current, labels, merge);\r\n },\r\n getIframe: () => iframeRef.current,\r\n reload: () => {\r\n if (iframeRef.current) {\r\n iframeRef.current.src = iframeRef.current.src;\r\n }\r\n },\r\n }),\r\n []\r\n );\r\n \r\n // Don't render if no baseUrl\r\n if (!baseUrl) {\r\n return (\r\n <div style={mergedStyles.container} className={className}>\r\n <p style={{ color: 'red', padding: '20px' }}>\r\n Error: FormEngine baseUrl is not configured. \r\n Please wrap this component with FormEngineProvider.\r\n </p>\r\n </div>\r\n );\r\n }\r\n \r\n return (\r\n <div style={mergedStyles.container} className={className}>\r\n <iframe\r\n ref={iframeRef}\r\n src={iframeUrl}\r\n style={mergedStyles.iframe}\r\n title={title}\r\n allowFullScreen={allowFullScreen}\r\n sandbox={sandbox}\r\n />\r\n </div>\r\n );\r\n }\r\n);\r\n\r\n// Display name for React DevTools\r\nFormEngineWrapper.displayName = 'FormEngineWrapper';\r\n\r\nexport default FormEngineWrapper;\r\n","import { useRef, useCallback } from 'react';\r\nimport type { FieldLabelsMap, FormEngineWrapperRef } from '../types';\r\nimport {\r\n triggerSubmit,\r\n sendFormData,\r\n requestFormDataAsync,\r\n sendFieldLabels,\r\n} from '../utils/messageHandler';\r\n\r\n/**\r\n * Options for useFormEngine hook\r\n */\r\nexport interface UseFormEngineOptions {\r\n /** Timeout for async operations in milliseconds */\r\n timeout?: number;\r\n /** Target origin for postMessage (use '*' with caution) */\r\n targetOrigin?: string;\r\n}\r\n\r\n/**\r\n * Return type for useFormEngine hook\r\n */\r\nexport interface UseFormEngineReturn extends FormEngineWrapperRef {\r\n /** Ref to attach to the iframe element */\r\n iframeRef: React.RefObject<HTMLIFrameElement | null>;\r\n}\r\n\r\n/**\r\n * Hook to interact with FormEngine iframe\r\n * \r\n * Provides methods to programmatically interact with the form inside the iframe.\r\n * \r\n * @param options - Configuration options\r\n * @returns Object with iframe ref and control methods\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormEngine } from '@formengine/wrapper';\r\n * \r\n * function MyForm() {\r\n * const { iframeRef, submit, getFormData, setFormData } = useFormEngine();\r\n * \r\n * const handleSubmit = async () => {\r\n * const data = await getFormData();\r\n * console.log('Current form data:', data);\r\n * submit();\r\n * };\r\n * \r\n * return (\r\n * <div>\r\n * <iframe ref={iframeRef} src=\"...\" />\r\n * <button onClick={handleSubmit}>Submit</button>\r\n * </div>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function useFormEngine(options: UseFormEngineOptions = {}): UseFormEngineReturn {\r\n const { timeout = 5000, targetOrigin = '*' } = options;\r\n \r\n const iframeRef = useRef<HTMLIFrameElement>(null);\r\n \r\n /**\r\n * Trigger form submission\r\n */\r\n const submit = useCallback(() => {\r\n triggerSubmit(iframeRef.current, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Get form data asynchronously\r\n */\r\n const getFormData = useCallback(async (): Promise<unknown> => {\r\n return requestFormDataAsync(iframeRef.current, timeout, targetOrigin);\r\n }, [timeout, targetOrigin]);\r\n \r\n /**\r\n * Set form data\r\n */\r\n const setFormData = useCallback((data: unknown) => {\r\n sendFormData(iframeRef.current, data, {}, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Set field labels\r\n */\r\n const setFieldLabels = useCallback((labels: FieldLabelsMap) => {\r\n sendFieldLabels(iframeRef.current, labels, true, targetOrigin);\r\n }, [targetOrigin]);\r\n \r\n /**\r\n * Get the iframe element\r\n */\r\n const getIframe = useCallback(() => {\r\n return iframeRef.current;\r\n }, []);\r\n \r\n /**\r\n * Reload the iframe\r\n */\r\n const reload = useCallback(() => {\r\n if (iframeRef.current) {\r\n iframeRef.current.src = iframeRef.current.src;\r\n }\r\n }, []);\r\n \r\n return {\r\n iframeRef,\r\n submit,\r\n getFormData,\r\n setFormData,\r\n setFieldLabels,\r\n getIframe,\r\n reload,\r\n };\r\n}\r\n\r\nexport default useFormEngine;\r\n","import { useEffect, useCallback, useRef } from 'react';\r\nimport {\r\n handleFormEngineMessage,\r\n isFormEngineMessage,\r\n type MessageHandlers,\r\n} from '../utils/messageHandler';\r\nimport type { MessageObject } from '../types/messages';\r\n\r\n/**\r\n * Options for useFormMessages hook\r\n */\r\nexport interface UseFormMessagesOptions {\r\n /** Whether to enable message listening */\r\n enabled?: boolean;\r\n /** Callback when form submission starts */\r\n onSubmitStart?: (content: Record<string, unknown>) => void;\r\n /** Callback when form submission succeeds */\r\n onSubmitSuccess?: (content: Record<string, unknown>) => void;\r\n /** Callback when form submission fails */\r\n onSubmitFail?: (content: Record<string, unknown>) => void;\r\n /** Callback when form data is returned */\r\n onFormDataReturn?: (content: Record<string, unknown>) => void;\r\n /** Callback when setFormData completes */\r\n onSetFormDataReturn?: (content: Record<string, unknown>) => void;\r\n /** Callback when form loads successfully */\r\n onFormLoadSuccess?: (content: Record<string, unknown>) => void;\r\n /** Callback when form load fails */\r\n onFormLoadFail?: (content: Record<string, unknown>) => void;\r\n /** Callback for any message (useful for debugging) */\r\n onAnyMessage?: (message: MessageObject) => void;\r\n}\r\n\r\n/**\r\n * Hook to listen for messages from FormEngine iframe\r\n * \r\n * Sets up event listeners for postMessage events from the FormEngine iframe\r\n * and routes them to the appropriate callback handlers.\r\n * \r\n * @param options - Message handling options and callbacks\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useFormMessages } from '@formengine/wrapper';\r\n * \r\n * function MyComponent() {\r\n * useFormMessages({\r\n * onSubmitStart: (data) => {\r\n * console.log('Form submission started:', data);\r\n * setLoading(true);\r\n * },\r\n * onSubmitSuccess: (data) => {\r\n * console.log('Form submitted successfully:', data);\r\n * setLoading(false);\r\n * showSuccessMessage();\r\n * },\r\n * onSubmitFail: (data) => {\r\n * console.log('Form submission failed:', data);\r\n * setLoading(false);\r\n * showErrorMessage();\r\n * },\r\n * });\r\n * \r\n * return <div>...</div>;\r\n * }\r\n * ```\r\n */\r\nexport function useFormMessages(options: UseFormMessagesOptions = {}): void {\r\n const {\r\n enabled = true,\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n } = options;\r\n \r\n // Use refs to avoid recreating the handler on every render\r\n const handlersRef = useRef<MessageHandlers>({});\r\n \r\n // Update handlers ref when callbacks change\r\n useEffect(() => {\r\n handlersRef.current = {\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n };\r\n }, [\r\n onSubmitStart,\r\n onSubmitSuccess,\r\n onSubmitFail,\r\n onFormDataReturn,\r\n onSetFormDataReturn,\r\n onFormLoadSuccess,\r\n onFormLoadFail,\r\n onAnyMessage,\r\n ]);\r\n \r\n // Message event handler\r\n const handleMessage = useCallback((event: MessageEvent) => {\r\n handleFormEngineMessage(event, handlersRef.current);\r\n }, []);\r\n \r\n // Set up message listener\r\n useEffect(() => {\r\n if (!enabled) return;\r\n \r\n window.addEventListener('message', handleMessage);\r\n \r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [enabled, handleMessage]);\r\n}\r\n\r\n/**\r\n * Hook to filter and handle only FormEngine messages\r\n * \r\n * A simpler hook that just filters FormEngine messages and calls a single handler.\r\n * Useful when you want more control over message handling.\r\n * \r\n * @param handler - Callback function for FormEngine messages\r\n * @param enabled - Whether to enable listening\r\n * \r\n * @example\r\n * ```tsx\r\n * useFormEngineMessageListener((message) => {\r\n * switch (message.messageEventName) {\r\n * case 'FormSubmitSuccess':\r\n * handleSuccess(message);\r\n * break;\r\n * case 'FormSubmitFail':\r\n * handleFailure(message);\r\n * break;\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function useFormEngineMessageListener(\r\n handler: (message: MessageObject) => void,\r\n enabled = true\r\n): void {\r\n const handlerRef = useRef(handler);\r\n \r\n useEffect(() => {\r\n handlerRef.current = handler;\r\n }, [handler]);\r\n \r\n useEffect(() => {\r\n if (!enabled) return;\r\n \r\n const handleMessage = (event: MessageEvent) => {\r\n if (isFormEngineMessage(event)) {\r\n handlerRef.current(event.data as MessageObject);\r\n }\r\n };\r\n \r\n window.addEventListener('message', handleMessage);\r\n \r\n return () => {\r\n window.removeEventListener('message', handleMessage);\r\n };\r\n }, [enabled]);\r\n}\r\n\r\nexport default useFormMessages;\r\n"],"names":[],"mappings":"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"}
{
"name": "@mtg-rio/formengine-wrapper",
"version": "0.1.2",
"version": "0.1.3",
"description": "React component wrapper for FormEngine integration via iframe",

@@ -5,0 +5,0 @@ "type": "module",