@momentco-ai/moment-sdk 0.2.0 → 0.2.2-dev.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -129,7 +129,7 @@ Programmatically create a styled trigger button:
129
129
  </script>
130
130
  ```
131
131
 
132
- The button renders with Moment's default styling (stone-900 background, subtle border, rounded corners). Override with CSS or pass a `className` option.
132
+ The button uses the same default `.moment-sync-trigger` styling as declarative HTML triggers. Override with CSS or pass a `className` option.
133
133
 
134
134
  ### Styling, fonts, and labels
135
135
 
@@ -171,7 +171,7 @@ You can customize trigger button appearance in a few ways:
171
171
  </script>
172
172
  ```
173
173
 
174
- You can also create plain HTML triggers and fully own styles/text:
174
+ You can also create plain HTML triggers the SDK applies minimal default button styles automatically, or you can fully own styles/text with your own CSS classes:
175
175
 
176
176
  ```html
177
177
  <button
@@ -1 +1,25 @@
1
- (function(h){"use strict";class y{popup=null;pollTimer=null;messageHandler=null;resultReceived=!1;opts;constructor(e){this.opts=e}open(e){this.cleanup(),this.resultReceived=!1;const t=this.buildPopupUrl(e),i=Math.round(window.screenX+(window.outerWidth-500)/2),r=Math.round(window.screenY+(window.outerHeight-700)/2);if(this.popup=window.open(t,"moment-oauth-popup",`width=500,height=700,left=${i},top=${r},menubar=no,toolbar=no,location=yes,status=no`),!this.popup||this.popup.closed){this.sendStatusToIframe("popup-blocked"),this.opts.onPopupBlocked();return}this.sendStatusToIframe("popup-opened"),this.startPolling(),this.messageHandler=s=>{if(s.origin!==this.opts.liveOrigin||s.source!==this.popup)return;const n=s.data;!n||typeof n!="object"||n.source!=="moment-live-embed"||n.type!=="moment.embed.result"||(this.resultReceived=!0,this.sendStatusToIframe("completed"),this.opts.iframeWindow&&this.opts.iframeWindow.postMessage(n,this.opts.liveOrigin),this.opts.onResult(n),this.cleanup())},window.addEventListener("message",this.messageHandler)}cleanup(){if(this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.popup&&!this.popup.closed)try{this.popup.close()}catch{}this.popup=null}buildPopupUrl(e){const t=window.location.origin,i=new URLSearchParams({provider:e.provider,teamSlug:e.teamSlug,ids:e.ids.join(","),triggerType:e.triggerType,returnOrigin:t});return e.subscriptionType&&i.set("subscriptionType",e.subscriptionType),`${this.opts.liveBaseUrl}/en/embed/oauth-popup?${i.toString()}`}startPolling(){this.pollTimer=setInterval(()=>{(!this.popup||this.popup.closed)&&(this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.resultReceived||(this.sendStatusToIframe("popup-closed"),this.opts.onPopupClosed()),this.cleanup())},500)}sendStatusToIframe(e){if(!this.opts.iframeWindow)return;const t={source:"moment-sdk",type:"moment.embed.oauth.status",status:e};this.opts.iframeWindow.postMessage(t,this.opts.liveOrigin)}}const w=".moment-sync-trigger",T="https://live.momentco.ai";class g{opts;liveBaseUrl;liveOrigin;overlay=null;iframe=null;popupBridge=null;messageHandler=null;boundClickHandlers=new Map;activePayload=null;previousFocusedElement=null;previousBodyOverflow="";didManageBodyOverflow=!1;closeTimer=null;constructor(e){this.opts={triggerSelector:w,...e},this.liveBaseUrl=T;try{this.liveOrigin=new URL(this.liveBaseUrl).origin}catch{throw new Error(`[MomentSdk] Invalid VITE_LIVE_BASE_URL: "${this.liveBaseUrl}"`)}this.bindTriggers(),this.emitAnalytics("embed.init")}open(e){this.emitAnalytics("embed.open",{teamSlug:e.teamSlug,triggerType:e.triggerType}),this.createModal(e)}close(){this.handleCancel()}rebind(){this.unbindTriggers(),this.bindTriggers()}destroy(){this.cleanup(),this.unbindTriggers()}bindTriggers(){document.querySelectorAll(this.opts.triggerSelector).forEach(t=>{const i=s=>{s.preventDefault(),this.handleTriggerClick(t)},r=this.boundClickHandlers.get(t);r&&t.removeEventListener("click",r),t.addEventListener("click",i),this.boundClickHandlers.set(t,i)})}unbindTriggers(){this.boundClickHandlers.forEach((e,t)=>{t.removeEventListener("click",e)}),this.boundClickHandlers.clear()}handleTriggerClick(e){const t=e.getAttribute("data-moment-team-slug")??"",i=e.getAttribute("data-moment-slug")??void 0,r=e.getAttribute("data-moment-list-slug")??void 0,s=e.getAttribute("data-moment-trigger-type");let n="moment";s!=null&&s!==""&&(s==="moment"||s==="list"||s==="team"?n=s:console.warn("[MomentSdk] Invalid data-moment-trigger-type, falling back to 'moment':",s));const d=e.getAttribute("data-moment-ids")??e.getAttribute("data-moment-game-id")??"",u=d?d.split(",").filter(Boolean):[],a=e.getAttribute("data-moment-calendar");let m;if(a!=null&&a!==""&&(a==="google"||a==="outlook"?m=a:console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:",a)),!t){console.warn("[MomentSdk] Missing data-moment-team-slug on trigger element");return}const l=n==="team"?void 0:i,c=n==="team"?void 0:r,p=n==="team"?[]:u;this.emitAnalytics("embed.trigger.click",{teamSlug:t,triggerType:n,momentIds:p}),this.open({teamSlug:t,momentSlug:l,listSlug:c,triggerType:n,ids:p,calendar:m??void 0})}createModal(e){this.cleanup(),this.previousFocusedElement=document.activeElement||null,this.activePayload=e;const t=this.buildIframeUrl(e);this.overlay=document.createElement("div"),this.overlay.setAttribute("role","presentation"),Object.assign(this.overlay.style,{position:"fixed",inset:"0",zIndex:"999999",display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"rgba(0, 0, 0, 0.5)",backdropFilter:"blur(2px)",padding:"16px"}),this.overlay.addEventListener("click",l=>{l.target===this.overlay&&this.handleCancel()});const i=l=>{l.key==="Escape"&&this.handleCancel()};document.addEventListener("keydown",i);const r=document.createElement("div");Object.assign(r.style,{position:"relative",width:"100%",maxWidth:"380px",borderRadius:"16px",overflow:"hidden",backgroundColor:"#000000",boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.25)",display:"flex",flexDirection:"column"});const s=document.createElement("div");s.setAttribute("role","dialog"),s.setAttribute("aria-modal","true"),s.setAttribute("aria-label","Calendar sync modal"),s.tabIndex=-1,Object.assign(s.style,{position:"relative",width:"100%",maxHeight:"80vh",borderRadius:"12px",overflow:"auto",backgroundColor:"#ffffff"});const n=document.createElement("button");n.type="button",n.innerHTML='<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1l12 12M13 1L1 13" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>',n.setAttribute("aria-label","Close"),Object.assign(n.style,{position:"absolute",top:"10px",right:"10px",zIndex:"10",border:"none",backgroundColor:"transparent",color:"#999",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",width:"24px",height:"24px",padding:"0"}),n.addEventListener("mouseenter",()=>{n.style.color="#666"}),n.addEventListener("mouseleave",()=>{n.style.color="#999"}),n.addEventListener("click",()=>this.handleCancel()),this.iframe=document.createElement("iframe"),this.iframe.src=t,this.iframe.setAttribute("allow",""),this.iframe.setAttribute("sandbox","allow-scripts allow-same-origin allow-popups allow-forms"),this.iframe.setAttribute("scrolling","no"),Object.assign(this.iframe.style,{width:"100%",border:"none",display:"block",height:"420px",overflow:"hidden",transition:"height 0.15s ease"}),s.appendChild(n),s.appendChild(this.iframe);const d=document.createElement("div");Object.assign(d.style,{display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"12px 0"});const u=document.createElement("span");u.textContent="Powered by",Object.assign(u.style,{fontFamily:"Inter, system-ui, -apple-system, sans-serif",fontSize:"12px",lineHeight:"16px",color:"#ffffff"});const a=document.createElement("img");a.alt="Moment",a.src=`${this.liveBaseUrl}/brand/moment-text-white.png`,Object.assign(a.style,{height:"auto",width:"67px"}),d.appendChild(u),d.appendChild(a),r.appendChild(s),r.appendChild(d),this.overlay.appendChild(r),document.body.appendChild(this.overlay);const m=l=>{if(l.key!=="Tab")return;const c=s.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(c.length===0){l.preventDefault(),s.focus();return}const p=c[0],v=c[c.length-1],b=document.activeElement;l.shiftKey&&b===p?(l.preventDefault(),v.focus()):!l.shiftKey&&b===v&&(l.preventDefault(),p.focus())};s.addEventListener("keydown",m),n.focus(),this.previousBodyOverflow=document.body.style.overflow,document.body.style.overflow="hidden",this.didManageBodyOverflow=!0,this.setupMessageListener(),this.overlay._escHandler=i,this.overlay._focusTrapHandler=m}buildIframeUrl(e){const t=new URLSearchParams;return t.set("teamSlug",e.teamSlug),e.momentSlug&&t.set("momentSlug",e.momentSlug),e.listSlug&&t.set("listSlug",e.listSlug),t.set("triggerType",e.triggerType),e.ids?.length&&t.set("ids",e.ids.join(",")),e.calendar&&t.set("calendar",e.calendar),t.set("returnOrigin",window.location.origin),t.set("embed","1"),`${this.liveBaseUrl}/en/embed/sync?${t.toString()}`}setupMessageListener(){this.messageHandler=e=>{if(e.origin!==this.liveOrigin||e.source!==this.iframe?.contentWindow)return;const t=e.data;if(!(!t||typeof t!="object")){if(t.source==="moment-live-embed"&&t.type==="moment.embed.oauth.start"){const i=t;this.emitAnalytics("oauth.start",{provider:i.provider,teamSlug:i.teamSlug}),this.handleOAuthStart(i);return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.resize"){const i=typeof t.height=="number"?t.height:0;if(i>0&&this.iframe){const r=Math.round(window.innerHeight*.8);this.iframe.style.height=`${Math.min(i,r)}px`}return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.open.url"){const{url:i}=t;i&&typeof i=="string"&&i.startsWith("webcal://")&&window.open(i,"_blank");return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.result"){const i=t;this.handleResult(i)}}},window.addEventListener("message",this.messageHandler)}handleOAuthStart(e){this.popupBridge&&(this.popupBridge.cleanup(),this.popupBridge=null),this.popupBridge=new y({liveBaseUrl:this.liveBaseUrl,liveOrigin:this.liveOrigin,iframeWindow:this.iframe?.contentWindow??null,onResult:t=>{this.handleResult(t)},onPopupBlocked:()=>{this.emitAnalytics("oauth.popup.blocked",{provider:e.provider})},onPopupClosed:()=>{this.emitAnalytics("oauth.popup.closed",{provider:e.provider})}}),this.popupBridge.open(e)}handleResult(e){if(e.result==="success")this.emitAnalytics("subscribe.success",{provider:e.provider,triggerType:e.triggerType,momentIds:e.momentIds}),this.opts.onSuccess?.(e);else if(e.result==="error")this.emitAnalytics("subscribe.error",{provider:e.provider,triggerType:e.triggerType,momentIds:e.momentIds}),this.opts.onError?.(e);else if(e.result==="cancelled")return;this.opts.onClose?.(e),this.emitAnalytics("embed.close"),this.closeTimer=setTimeout(()=>this.cleanup(),1500)}handleCancel(){this.emitAnalytics("embed.close");const t={source:"moment-live-embed",type:"moment.embed.result",result:"cancelled",triggerType:this.activePayload?.triggerType??"moment",momentIds:this.activePayload?.ids??[]};this.opts.onClose?.(t),this.cleanup()}cleanup(){if(this.closeTimer&&(clearTimeout(this.closeTimer),this.closeTimer=null),this.popupBridge&&(this.popupBridge.cleanup(),this.popupBridge=null),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.overlay){const{_escHandler:e,_focusTrapHandler:t}=this.overlay;e&&document.removeEventListener("keydown",e);const i=this.overlay.firstElementChild;i&&t&&i.removeEventListener("keydown",t),this.overlay.remove(),this.overlay=null}this.iframe=null,this.activePayload=null,this.didManageBodyOverflow&&(document.body.style.overflow=this.previousBodyOverflow,this.didManageBodyOverflow=!1),this.previousFocusedElement&&typeof this.previousFocusedElement.focus=="function"&&this.previousFocusedElement.focus(),this.previousFocusedElement=null}emitAnalytics(e,t){this.opts.onAnalytics?.({event:e,timestamp:Date.now(),...t})}}function f(o){const e=document.createElement("button");return e.type="button",e.classList.add("moment-sync-trigger"),o.className&&o.className.split(" ").forEach(t=>{t&&e.classList.add(t)}),Object.assign(e.style,{backgroundColor:"#1c1917",color:"#ffffff",border:"1px solid #292524",borderRadius:"4px",padding:"8px 16px",fontSize:"14px",fontWeight:"500",cursor:"pointer",lineHeight:"1.4"}),e.setAttribute("data-moment-team-slug",o.teamSlug),o.momentSlug&&e.setAttribute("data-moment-slug",o.momentSlug),o.listSlug&&e.setAttribute("data-moment-list-slug",o.listSlug),o.triggerType&&e.setAttribute("data-moment-trigger-type",o.triggerType),o.ids?.length&&e.setAttribute("data-moment-ids",o.ids.join(",")),o.calendar&&e.setAttribute("data-moment-calendar",o.calendar),e.textContent=o.label??"Add to Calendar",e}if(typeof window<"u"){const o=window;o.MomentSdk=g,o.createMomentButton=f}h.MomentSdk=g,h.createMomentButton=f,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})})(this.MomentSdk=this.MomentSdk||{});
1
+ (function(f){"use strict";class w{popup=null;pollTimer=null;messageHandler=null;resultReceived=!1;opts;constructor(e){this.opts=e}open(e){this.cleanup(),this.resultReceived=!1;const t=this.buildPopupUrl(e),i=Math.round(window.screenX+(window.outerWidth-500)/2),r=Math.round(window.screenY+(window.outerHeight-700)/2);if(this.popup=window.open(t,"moment-oauth-popup",`width=500,height=700,left=${i},top=${r},menubar=no,toolbar=no,location=yes,status=no`),!this.popup||this.popup.closed){this.sendStatusToIframe("popup-blocked"),this.opts.onPopupBlocked();return}this.sendStatusToIframe("popup-opened"),this.startPolling(),this.messageHandler=n=>{if(n.origin!==this.opts.liveOrigin||n.source!==this.popup)return;const o=n.data;!o||typeof o!="object"||o.source!=="moment-live-embed"||o.type!=="moment.embed.result"||(this.resultReceived=!0,this.sendStatusToIframe("completed"),this.opts.iframeWindow&&this.opts.iframeWindow.postMessage(o,this.opts.liveOrigin),this.opts.onResult(o),this.cleanup())},window.addEventListener("message",this.messageHandler)}cleanup(){if(this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.popup&&!this.popup.closed)try{this.popup.close()}catch{}this.popup=null}buildPopupUrl(e){const t=window.location.origin,i=new URLSearchParams({provider:e.provider,teamSlug:e.teamSlug,ids:e.ids.join(","),triggerType:e.triggerType,returnOrigin:t});return e.subscriptionType&&i.set("subscriptionType",e.subscriptionType),`${this.opts.liveBaseUrl}/en/embed/oauth-popup?${i.toString()}`}startPolling(){this.pollTimer=setInterval(()=>{(!this.popup||this.popup.closed)&&(this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.resultReceived||(this.sendStatusToIframe("popup-closed"),this.opts.onPopupClosed()),this.cleanup())},500)}sendStatusToIframe(e){if(!this.opts.iframeWindow)return;const t={source:"moment-sdk",type:"moment.embed.oauth.status",status:e};this.opts.iframeWindow.postMessage(t,this.opts.liveOrigin)}}const v="moment-sdk-trigger-styles",T=`
2
+ :where(.moment-sync-trigger) {
3
+ background-color: #1c1917;
4
+ color: #ffffff;
5
+ border: 1px solid #292524;
6
+ border-radius: 4px;
7
+ padding: 8px 16px;
8
+ font-size: 14px;
9
+ font-weight: 500;
10
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
11
+ line-height: 1.4;
12
+ cursor: pointer;
13
+ appearance: none;
14
+ -webkit-appearance: none;
15
+ }
16
+
17
+ :where(.moment-sync-trigger:hover) {
18
+ background-color: #292524;
19
+ }
20
+
21
+ :where(.moment-sync-trigger:focus-visible) {
22
+ outline: 2px solid #1c1917;
23
+ outline-offset: 2px;
24
+ }
25
+ `;function S(){if(typeof document>"u"||document.getElementById(v))return;const s=document.createElement("style");s.id=v,s.textContent=T,document.head.appendChild(s)}const E=".moment-sync-trigger",I="https://live.dev.momentco.ai";class b{opts;liveBaseUrl;liveOrigin;overlay=null;iframe=null;popupBridge=null;messageHandler=null;boundClickHandlers=new Map;activePayload=null;previousFocusedElement=null;previousBodyOverflow="";didManageBodyOverflow=!1;closeTimer=null;constructor(e){this.opts={triggerSelector:E,...e},this.liveBaseUrl=I;try{this.liveOrigin=new URL(this.liveBaseUrl).origin}catch{throw new Error(`[MomentSdk] Invalid VITE_LIVE_BASE_URL: "${this.liveBaseUrl}"`)}S(),this.bindTriggers(),this.emitAnalytics("embed.init")}open(e){this.emitAnalytics("embed.open",{teamSlug:e.teamSlug,triggerType:e.triggerType}),this.createModal(e)}close(){this.handleCancel()}rebind(){this.unbindTriggers(),this.bindTriggers()}destroy(){this.cleanup(),this.unbindTriggers()}bindTriggers(){document.querySelectorAll(this.opts.triggerSelector).forEach(t=>{const i=n=>{n.preventDefault(),this.handleTriggerClick(t)},r=this.boundClickHandlers.get(t);r&&t.removeEventListener("click",r),t.addEventListener("click",i),this.boundClickHandlers.set(t,i)})}unbindTriggers(){this.boundClickHandlers.forEach((e,t)=>{t.removeEventListener("click",e)}),this.boundClickHandlers.clear()}handleTriggerClick(e){const t=e.getAttribute("data-moment-team-slug")??"",i=e.getAttribute("data-moment-slug")??void 0,r=e.getAttribute("data-moment-list-slug")??void 0,n=e.getAttribute("data-moment-trigger-type");let o="moment";n!=null&&n!==""&&(n==="moment"||n==="list"||n==="team"?o=n:console.warn("[MomentSdk] Invalid data-moment-trigger-type, falling back to 'moment':",n));const d=e.getAttribute("data-moment-ids")??e.getAttribute("data-moment-game-id")??"",u=d?d.split(",").filter(Boolean):[],a=e.getAttribute("data-moment-calendar");let m;a!=null&&a!==""&&(a==="google"||a==="outlook"?m=a:console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:",a));const l=e.getAttribute("data-api-source-id")??void 0,c=e.getAttribute("data-external-event-id")??void 0;if(!t){console.warn("[MomentSdk] Missing data-moment-team-slug on trigger element");return}const h=o==="team"?void 0:i,g=o==="team"?void 0:r,p=o==="team"?[]:u;this.emitAnalytics("embed.trigger.click",{teamSlug:t,triggerType:o,momentIds:p}),this.open({teamSlug:t,momentSlug:h,listSlug:g,triggerType:o,ids:p,calendar:m??void 0,apiSourceId:l,externalEventId:c})}createModal(e){this.cleanup(),this.previousFocusedElement=document.activeElement||null,this.activePayload=e;const t=this.buildIframeUrl(e);this.overlay=document.createElement("div"),this.overlay.setAttribute("role","presentation"),Object.assign(this.overlay.style,{position:"fixed",inset:"0",zIndex:"999999",display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"rgba(0, 0, 0, 0.5)",backdropFilter:"blur(2px)",padding:"16px"}),this.overlay.addEventListener("click",l=>{l.target===this.overlay&&this.handleCancel()});const i=l=>{l.key==="Escape"&&this.handleCancel()};document.addEventListener("keydown",i);const r=document.createElement("div");Object.assign(r.style,{position:"relative",width:"100%",maxWidth:"380px",borderRadius:"16px",overflow:"hidden",backgroundColor:"#000000",boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.25)",display:"flex",flexDirection:"column"});const n=document.createElement("div");n.setAttribute("role","dialog"),n.setAttribute("aria-modal","true"),n.setAttribute("aria-label","Calendar sync modal"),n.tabIndex=-1,Object.assign(n.style,{position:"relative",width:"100%",maxHeight:"80vh",borderRadius:"12px",overflow:"auto",backgroundColor:"#ffffff"});const o=document.createElement("button");o.type="button",o.innerHTML='<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1l12 12M13 1L1 13" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>',o.setAttribute("aria-label","Close"),Object.assign(o.style,{position:"absolute",top:"10px",right:"10px",zIndex:"10",border:"none",backgroundColor:"transparent",color:"#999",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",width:"24px",height:"24px",padding:"0"}),o.addEventListener("mouseenter",()=>{o.style.color="#666"}),o.addEventListener("mouseleave",()=>{o.style.color="#999"}),o.addEventListener("click",()=>this.handleCancel()),this.iframe=document.createElement("iframe"),this.iframe.src=t,this.iframe.setAttribute("allow",""),this.iframe.setAttribute("sandbox","allow-scripts allow-same-origin allow-popups allow-forms"),this.iframe.setAttribute("scrolling","no"),Object.assign(this.iframe.style,{width:"100%",border:"none",display:"block",height:"420px",overflow:"hidden",transition:"height 0.15s ease"}),n.appendChild(o),n.appendChild(this.iframe);const d=document.createElement("div");Object.assign(d.style,{display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"12px 0"});const u=document.createElement("span");u.textContent="Powered by",Object.assign(u.style,{fontFamily:"Inter, system-ui, -apple-system, sans-serif",fontSize:"12px",lineHeight:"16px",color:"#ffffff"});const a=document.createElement("img");a.alt="Moment",a.src=`${this.liveBaseUrl}/brand/moment-text-white.png`,Object.assign(a.style,{height:"auto",width:"67px"}),d.appendChild(u),d.appendChild(a),r.appendChild(n),r.appendChild(d),this.overlay.appendChild(r),document.body.appendChild(this.overlay);const m=l=>{if(l.key!=="Tab")return;const c=n.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(c.length===0){l.preventDefault(),n.focus();return}const h=c[0],g=c[c.length-1],p=document.activeElement;l.shiftKey&&p===h?(l.preventDefault(),g.focus()):!l.shiftKey&&p===g&&(l.preventDefault(),h.focus())};n.addEventListener("keydown",m),o.focus(),this.previousBodyOverflow=document.body.style.overflow,document.body.style.overflow="hidden",this.didManageBodyOverflow=!0,this.setupMessageListener(),this.overlay._escHandler=i,this.overlay._focusTrapHandler=m}buildIframeUrl(e){const t=new URLSearchParams;return t.set("teamSlug",e.teamSlug),e.momentSlug&&t.set("momentSlug",e.momentSlug),e.listSlug&&t.set("listSlug",e.listSlug),t.set("triggerType",e.triggerType),e.ids?.length&&t.set("ids",e.ids.join(",")),e.calendar&&t.set("calendar",e.calendar),e.apiSourceId&&t.set("subscriptionId",e.apiSourceId),e.externalEventId&&t.set("externalId",e.externalEventId),t.set("returnOrigin",window.location.origin),t.set("embed","1"),`${this.liveBaseUrl}/en/embed/sync?${t.toString()}`}setupMessageListener(){this.messageHandler=e=>{if(e.origin!==this.liveOrigin||e.source!==this.iframe?.contentWindow)return;const t=e.data;if(!(!t||typeof t!="object")){if(t.source==="moment-live-embed"&&t.type==="moment.embed.oauth.start"){const i=t;this.emitAnalytics("oauth.start",{provider:i.provider,teamSlug:i.teamSlug}),this.handleOAuthStart(i);return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.resize"){const i=typeof t.height=="number"?t.height:0;if(i>0&&this.iframe){const r=Math.round(window.innerHeight*.8);this.iframe.style.height=`${Math.min(i,r)}px`}return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.open.url"){const{url:i}=t;i&&typeof i=="string"&&i.startsWith("webcal://")&&window.open(i,"_blank");return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.result"){const i=t;this.handleResult(i)}}},window.addEventListener("message",this.messageHandler)}handleOAuthStart(e){this.popupBridge&&(this.popupBridge.cleanup(),this.popupBridge=null),this.popupBridge=new w({liveBaseUrl:this.liveBaseUrl,liveOrigin:this.liveOrigin,iframeWindow:this.iframe?.contentWindow??null,onResult:t=>{this.handleResult(t)},onPopupBlocked:()=>{this.emitAnalytics("oauth.popup.blocked",{provider:e.provider})},onPopupClosed:()=>{this.emitAnalytics("oauth.popup.closed",{provider:e.provider})}}),this.popupBridge.open(e)}handleResult(e){if(e.result==="success")this.emitAnalytics("subscribe.success",{provider:e.provider,triggerType:e.triggerType,momentIds:e.momentIds}),this.opts.onSuccess?.(e);else if(e.result==="error")this.emitAnalytics("subscribe.error",{provider:e.provider,triggerType:e.triggerType,momentIds:e.momentIds}),this.opts.onError?.(e);else if(e.result==="cancelled")return;this.opts.onClose?.(e),this.emitAnalytics("embed.close"),this.closeTimer=setTimeout(()=>this.cleanup(),1500)}handleCancel(){this.emitAnalytics("embed.close");const t={source:"moment-live-embed",type:"moment.embed.result",result:"cancelled",triggerType:this.activePayload?.triggerType??"moment",momentIds:this.activePayload?.ids??[]};this.opts.onClose?.(t),this.cleanup()}cleanup(){if(this.closeTimer&&(clearTimeout(this.closeTimer),this.closeTimer=null),this.popupBridge&&(this.popupBridge.cleanup(),this.popupBridge=null),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.overlay){const{_escHandler:e,_focusTrapHandler:t}=this.overlay;e&&document.removeEventListener("keydown",e);const i=this.overlay.firstElementChild;i&&t&&i.removeEventListener("keydown",t),this.overlay.remove(),this.overlay=null}this.iframe=null,this.activePayload=null,this.didManageBodyOverflow&&(document.body.style.overflow=this.previousBodyOverflow,this.didManageBodyOverflow=!1),this.previousFocusedElement&&typeof this.previousFocusedElement.focus=="function"&&this.previousFocusedElement.focus(),this.previousFocusedElement=null}emitAnalytics(e,t){this.opts.onAnalytics?.({event:e,timestamp:Date.now(),...t})}}function y(s){const e=document.createElement("button");return e.type="button",e.classList.add("moment-sync-trigger"),s.className&&s.className.split(" ").forEach(t=>{t&&e.classList.add(t)}),e.setAttribute("data-moment-team-slug",s.teamSlug),s.momentSlug&&e.setAttribute("data-moment-slug",s.momentSlug),s.listSlug&&e.setAttribute("data-moment-list-slug",s.listSlug),s.triggerType&&e.setAttribute("data-moment-trigger-type",s.triggerType),s.ids?.length&&e.setAttribute("data-moment-ids",s.ids.join(",")),s.calendar&&e.setAttribute("data-moment-calendar",s.calendar),s.apiSourceId&&e.setAttribute("data-api-source-id",s.apiSourceId),s.externalEventId&&e.setAttribute("data-external-event-id",s.externalEventId),e.textContent=s.label??"Add to Calendar",e}if(typeof window<"u"){const s=window;s.MomentSdk=b,s.createMomentButton=y}f.MomentSdk=b,f.createMomentButton=y,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})})(this.MomentSdk=this.MomentSdk||{});
@@ -1,4 +1,4 @@
1
- class f {
1
+ class v {
2
2
  popup = null;
3
3
  pollTimer = null;
4
4
  messageHandler = null;
@@ -12,19 +12,19 @@ class f {
12
12
  */
13
13
  open(e) {
14
14
  this.cleanup(), this.resultReceived = !1;
15
- const t = this.buildPopupUrl(e), i = Math.round(window.screenX + (window.outerWidth - 500) / 2), r = Math.round(window.screenY + (window.outerHeight - 700) / 2);
15
+ const t = this.buildPopupUrl(e), i = Math.round(window.screenX + (window.outerWidth - 500) / 2), o = Math.round(window.screenY + (window.outerHeight - 700) / 2);
16
16
  if (this.popup = window.open(
17
17
  t,
18
18
  "moment-oauth-popup",
19
- `width=500,height=700,left=${i},top=${r},menubar=no,toolbar=no,location=yes,status=no`
19
+ `width=500,height=700,left=${i},top=${o},menubar=no,toolbar=no,location=yes,status=no`
20
20
  ), !this.popup || this.popup.closed) {
21
21
  this.sendStatusToIframe("popup-blocked"), this.opts.onPopupBlocked();
22
22
  return;
23
23
  }
24
- this.sendStatusToIframe("popup-opened"), this.startPolling(), this.messageHandler = (s) => {
25
- if (s.origin !== this.opts.liveOrigin || s.source !== this.popup) return;
26
- const n = s.data;
27
- !n || typeof n != "object" || n.source !== "moment-live-embed" || n.type !== "moment.embed.result" || (this.resultReceived = !0, this.sendStatusToIframe("completed"), this.opts.iframeWindow && this.opts.iframeWindow.postMessage(n, this.opts.liveOrigin), this.opts.onResult(n), this.cleanup());
24
+ this.sendStatusToIframe("popup-opened"), this.startPolling(), this.messageHandler = (n) => {
25
+ if (n.origin !== this.opts.liveOrigin || n.source !== this.popup) return;
26
+ const r = n.data;
27
+ !r || typeof r != "object" || r.source !== "moment-live-embed" || r.type !== "moment.embed.result" || (this.resultReceived = !0, this.sendStatusToIframe("completed"), this.opts.iframeWindow && this.opts.iframeWindow.postMessage(r, this.opts.liveOrigin), this.opts.onResult(r), this.cleanup());
28
28
  }, window.addEventListener("message", this.messageHandler);
29
29
  }
30
30
  /**
@@ -63,8 +63,38 @@ class f {
63
63
  this.opts.iframeWindow.postMessage(t, this.opts.liveOrigin);
64
64
  }
65
65
  }
66
- const v = ".moment-sync-trigger", b = "https://live.momentco.ai";
67
- class y {
66
+ const f = "moment-sdk-trigger-styles", b = `
67
+ :where(.moment-sync-trigger) {
68
+ background-color: #1c1917;
69
+ color: #ffffff;
70
+ border: 1px solid #292524;
71
+ border-radius: 4px;
72
+ padding: 8px 16px;
73
+ font-size: 14px;
74
+ font-weight: 500;
75
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
76
+ line-height: 1.4;
77
+ cursor: pointer;
78
+ appearance: none;
79
+ -webkit-appearance: none;
80
+ }
81
+
82
+ :where(.moment-sync-trigger:hover) {
83
+ background-color: #292524;
84
+ }
85
+
86
+ :where(.moment-sync-trigger:focus-visible) {
87
+ outline: 2px solid #1c1917;
88
+ outline-offset: 2px;
89
+ }
90
+ `;
91
+ function y() {
92
+ if (typeof document > "u" || document.getElementById(f)) return;
93
+ const s = document.createElement("style");
94
+ s.id = f, s.textContent = b, document.head.appendChild(s);
95
+ }
96
+ const w = ".moment-sync-trigger", T = "https://live.dev.momentco.ai";
97
+ class E {
68
98
  opts;
69
99
  liveBaseUrl;
70
100
  liveOrigin;
@@ -80,15 +110,15 @@ class y {
80
110
  closeTimer = null;
81
111
  constructor(e) {
82
112
  this.opts = {
83
- triggerSelector: v,
113
+ triggerSelector: w,
84
114
  ...e
85
- }, this.liveBaseUrl = b;
115
+ }, this.liveBaseUrl = T;
86
116
  try {
87
117
  this.liveOrigin = new URL(this.liveBaseUrl).origin;
88
118
  } catch {
89
119
  throw new Error(`[MomentSdk] Invalid VITE_LIVE_BASE_URL: "${this.liveBaseUrl}"`);
90
120
  }
91
- this.bindTriggers(), this.emitAnalytics("embed.init");
121
+ y(), this.bindTriggers(), this.emitAnalytics("embed.init");
92
122
  }
93
123
  /**
94
124
  * Programmatically open the sync modal.
@@ -120,10 +150,10 @@ class y {
120
150
  // ── Private: trigger binding ──────────────────────────────────────
121
151
  bindTriggers() {
122
152
  document.querySelectorAll(this.opts.triggerSelector).forEach((t) => {
123
- const i = (s) => {
124
- s.preventDefault(), this.handleTriggerClick(t);
125
- }, r = this.boundClickHandlers.get(t);
126
- r && t.removeEventListener("click", r), t.addEventListener("click", i), this.boundClickHandlers.set(t, i);
153
+ const i = (n) => {
154
+ n.preventDefault(), this.handleTriggerClick(t);
155
+ }, o = this.boundClickHandlers.get(t);
156
+ o && t.removeEventListener("click", o), t.addEventListener("click", i), this.boundClickHandlers.set(t, i);
127
157
  });
128
158
  }
129
159
  unbindTriggers() {
@@ -132,30 +162,34 @@ class y {
132
162
  }), this.boundClickHandlers.clear();
133
163
  }
134
164
  handleTriggerClick(e) {
135
- const t = e.getAttribute("data-moment-team-slug") ?? "", i = e.getAttribute("data-moment-slug") ?? void 0, r = e.getAttribute("data-moment-list-slug") ?? void 0, s = e.getAttribute("data-moment-trigger-type");
136
- let n = "moment";
137
- s != null && s !== "" && (s === "moment" || s === "list" || s === "team" ? n = s : console.warn(
165
+ const t = e.getAttribute("data-moment-team-slug") ?? "", i = e.getAttribute("data-moment-slug") ?? void 0, o = e.getAttribute("data-moment-list-slug") ?? void 0, n = e.getAttribute("data-moment-trigger-type");
166
+ let r = "moment";
167
+ n != null && n !== "" && (n === "moment" || n === "list" || n === "team" ? r = n : console.warn(
138
168
  "[MomentSdk] Invalid data-moment-trigger-type, falling back to 'moment':",
139
- s
169
+ n
140
170
  ));
141
171
  const d = e.getAttribute("data-moment-ids") ?? e.getAttribute("data-moment-game-id") ?? "", u = d ? d.split(",").filter(Boolean) : [], a = e.getAttribute("data-moment-calendar");
142
172
  let m;
143
- if (a != null && a !== "" && (a === "google" || a === "outlook" ? m = a : console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:", a)), !t) {
173
+ a != null && a !== "" && (a === "google" || a === "outlook" ? m = a : console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:", a));
174
+ const l = e.getAttribute("data-api-source-id") ?? void 0, c = e.getAttribute("data-external-event-id") ?? void 0;
175
+ if (!t) {
144
176
  console.warn("[MomentSdk] Missing data-moment-team-slug on trigger element");
145
177
  return;
146
178
  }
147
- const l = n === "team" ? void 0 : i, c = n === "team" ? void 0 : r, p = n === "team" ? [] : u;
179
+ const h = r === "team" ? void 0 : i, g = r === "team" ? void 0 : o, p = r === "team" ? [] : u;
148
180
  this.emitAnalytics("embed.trigger.click", {
149
181
  teamSlug: t,
150
- triggerType: n,
182
+ triggerType: r,
151
183
  momentIds: p
152
184
  }), this.open({
153
185
  teamSlug: t,
154
- momentSlug: l,
155
- listSlug: c,
156
- triggerType: n,
186
+ momentSlug: h,
187
+ listSlug: g,
188
+ triggerType: r,
157
189
  ids: p,
158
- calendar: m ?? void 0
190
+ calendar: m ?? void 0,
191
+ apiSourceId: l,
192
+ externalEventId: c
159
193
  });
160
194
  }
161
195
  // ── Private: modal creation ───────────────────────────────────────
@@ -179,8 +213,8 @@ class y {
179
213
  l.key === "Escape" && this.handleCancel();
180
214
  };
181
215
  document.addEventListener("keydown", i);
182
- const r = document.createElement("div");
183
- Object.assign(r.style, {
216
+ const o = document.createElement("div");
217
+ Object.assign(o.style, {
184
218
  position: "relative",
185
219
  width: "100%",
186
220
  maxWidth: "380px",
@@ -191,8 +225,8 @@ class y {
191
225
  display: "flex",
192
226
  flexDirection: "column"
193
227
  });
194
- const s = document.createElement("div");
195
- s.setAttribute("role", "dialog"), s.setAttribute("aria-modal", "true"), s.setAttribute("aria-label", "Calendar sync modal"), s.tabIndex = -1, Object.assign(s.style, {
228
+ const n = document.createElement("div");
229
+ n.setAttribute("role", "dialog"), n.setAttribute("aria-modal", "true"), n.setAttribute("aria-label", "Calendar sync modal"), n.tabIndex = -1, Object.assign(n.style, {
196
230
  position: "relative",
197
231
  width: "100%",
198
232
  maxHeight: "80vh",
@@ -200,8 +234,8 @@ class y {
200
234
  overflow: "auto",
201
235
  backgroundColor: "#ffffff"
202
236
  });
203
- const n = document.createElement("button");
204
- n.type = "button", n.innerHTML = '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1l12 12M13 1L1 13" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>', n.setAttribute("aria-label", "Close"), Object.assign(n.style, {
237
+ const r = document.createElement("button");
238
+ r.type = "button", r.innerHTML = '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1l12 12M13 1L1 13" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>', r.setAttribute("aria-label", "Close"), Object.assign(r.style, {
205
239
  position: "absolute",
206
240
  top: "10px",
207
241
  right: "10px",
@@ -216,18 +250,18 @@ class y {
216
250
  width: "24px",
217
251
  height: "24px",
218
252
  padding: "0"
219
- }), n.addEventListener("mouseenter", () => {
220
- n.style.color = "#666";
221
- }), n.addEventListener("mouseleave", () => {
222
- n.style.color = "#999";
223
- }), n.addEventListener("click", () => this.handleCancel()), this.iframe = document.createElement("iframe"), this.iframe.src = t, this.iframe.setAttribute("allow", ""), this.iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-popups allow-forms"), this.iframe.setAttribute("scrolling", "no"), Object.assign(this.iframe.style, {
253
+ }), r.addEventListener("mouseenter", () => {
254
+ r.style.color = "#666";
255
+ }), r.addEventListener("mouseleave", () => {
256
+ r.style.color = "#999";
257
+ }), r.addEventListener("click", () => this.handleCancel()), this.iframe = document.createElement("iframe"), this.iframe.src = t, this.iframe.setAttribute("allow", ""), this.iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-popups allow-forms"), this.iframe.setAttribute("scrolling", "no"), Object.assign(this.iframe.style, {
224
258
  width: "100%",
225
259
  border: "none",
226
260
  display: "block",
227
261
  height: "420px",
228
262
  overflow: "hidden",
229
263
  transition: "height 0.15s ease"
230
- }), s.appendChild(n), s.appendChild(this.iframe);
264
+ }), n.appendChild(r), n.appendChild(this.iframe);
231
265
  const d = document.createElement("div");
232
266
  Object.assign(d.style, {
233
267
  display: "flex",
@@ -247,24 +281,24 @@ class y {
247
281
  a.alt = "Moment", a.src = `${this.liveBaseUrl}/brand/moment-text-white.png`, Object.assign(a.style, {
248
282
  height: "auto",
249
283
  width: "67px"
250
- }), d.appendChild(u), d.appendChild(a), r.appendChild(s), r.appendChild(d), this.overlay.appendChild(r), document.body.appendChild(this.overlay);
284
+ }), d.appendChild(u), d.appendChild(a), o.appendChild(n), o.appendChild(d), this.overlay.appendChild(o), document.body.appendChild(this.overlay);
251
285
  const m = (l) => {
252
286
  if (l.key !== "Tab") return;
253
- const c = s.querySelectorAll(
287
+ const c = n.querySelectorAll(
254
288
  'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
255
289
  );
256
290
  if (c.length === 0) {
257
- l.preventDefault(), s.focus();
291
+ l.preventDefault(), n.focus();
258
292
  return;
259
293
  }
260
- const p = c[0], h = c[c.length - 1], g = document.activeElement;
261
- l.shiftKey && g === p ? (l.preventDefault(), h.focus()) : !l.shiftKey && g === h && (l.preventDefault(), p.focus());
294
+ const h = c[0], g = c[c.length - 1], p = document.activeElement;
295
+ l.shiftKey && p === h ? (l.preventDefault(), g.focus()) : !l.shiftKey && p === g && (l.preventDefault(), h.focus());
262
296
  };
263
- s.addEventListener("keydown", m), n.focus(), this.previousBodyOverflow = document.body.style.overflow, document.body.style.overflow = "hidden", this.didManageBodyOverflow = !0, this.setupMessageListener(), this.overlay._escHandler = i, this.overlay._focusTrapHandler = m;
297
+ n.addEventListener("keydown", m), r.focus(), this.previousBodyOverflow = document.body.style.overflow, document.body.style.overflow = "hidden", this.didManageBodyOverflow = !0, this.setupMessageListener(), this.overlay._escHandler = i, this.overlay._focusTrapHandler = m;
264
298
  }
265
299
  buildIframeUrl(e) {
266
300
  const t = new URLSearchParams();
267
- return t.set("teamSlug", e.teamSlug), e.momentSlug && t.set("momentSlug", e.momentSlug), e.listSlug && t.set("listSlug", e.listSlug), t.set("triggerType", e.triggerType), e.ids?.length && t.set("ids", e.ids.join(",")), e.calendar && t.set("calendar", e.calendar), t.set("returnOrigin", window.location.origin), t.set("embed", "1"), `${this.liveBaseUrl}/en/embed/sync?${t.toString()}`;
301
+ return t.set("teamSlug", e.teamSlug), e.momentSlug && t.set("momentSlug", e.momentSlug), e.listSlug && t.set("listSlug", e.listSlug), t.set("triggerType", e.triggerType), e.ids?.length && t.set("ids", e.ids.join(",")), e.calendar && t.set("calendar", e.calendar), e.apiSourceId && t.set("subscriptionId", e.apiSourceId), e.externalEventId && t.set("externalId", e.externalEventId), t.set("returnOrigin", window.location.origin), t.set("embed", "1"), `${this.liveBaseUrl}/en/embed/sync?${t.toString()}`;
268
302
  }
269
303
  // ── Private: message handling ─────────────────────────────────────
270
304
  setupMessageListener() {
@@ -283,8 +317,8 @@ class y {
283
317
  if (t.source === "moment-live-embed" && t.type === "moment.embed.resize") {
284
318
  const i = typeof t.height == "number" ? t.height : 0;
285
319
  if (i > 0 && this.iframe) {
286
- const r = Math.round(window.innerHeight * 0.8);
287
- this.iframe.style.height = `${Math.min(i, r)}px`;
320
+ const o = Math.round(window.innerHeight * 0.8);
321
+ this.iframe.style.height = `${Math.min(i, o)}px`;
288
322
  }
289
323
  return;
290
324
  }
@@ -301,7 +335,7 @@ class y {
301
335
  }, window.addEventListener("message", this.messageHandler);
302
336
  }
303
337
  handleOAuthStart(e) {
304
- this.popupBridge && (this.popupBridge.cleanup(), this.popupBridge = null), this.popupBridge = new f({
338
+ this.popupBridge && (this.popupBridge.cleanup(), this.popupBridge = null), this.popupBridge = new v({
305
339
  liveBaseUrl: this.liveBaseUrl,
306
340
  liveOrigin: this.liveOrigin,
307
341
  iframeWindow: this.iframe?.contentWindow ?? null,
@@ -367,27 +401,17 @@ class y {
367
401
  });
368
402
  }
369
403
  }
370
- function w(o) {
404
+ function S(s) {
371
405
  const e = document.createElement("button");
372
- return e.type = "button", e.classList.add("moment-sync-trigger"), o.className && o.className.split(" ").forEach((t) => {
406
+ return e.type = "button", e.classList.add("moment-sync-trigger"), s.className && s.className.split(" ").forEach((t) => {
373
407
  t && e.classList.add(t);
374
- }), Object.assign(e.style, {
375
- backgroundColor: "#1c1917",
376
- color: "#ffffff",
377
- border: "1px solid #292524",
378
- borderRadius: "4px",
379
- padding: "8px 16px",
380
- fontSize: "14px",
381
- fontWeight: "500",
382
- cursor: "pointer",
383
- lineHeight: "1.4"
384
- }), e.setAttribute("data-moment-team-slug", o.teamSlug), o.momentSlug && e.setAttribute("data-moment-slug", o.momentSlug), o.listSlug && e.setAttribute("data-moment-list-slug", o.listSlug), o.triggerType && e.setAttribute("data-moment-trigger-type", o.triggerType), o.ids?.length && e.setAttribute("data-moment-ids", o.ids.join(",")), o.calendar && e.setAttribute("data-moment-calendar", o.calendar), e.textContent = o.label ?? "Add to Calendar", e;
408
+ }), e.setAttribute("data-moment-team-slug", s.teamSlug), s.momentSlug && e.setAttribute("data-moment-slug", s.momentSlug), s.listSlug && e.setAttribute("data-moment-list-slug", s.listSlug), s.triggerType && e.setAttribute("data-moment-trigger-type", s.triggerType), s.ids?.length && e.setAttribute("data-moment-ids", s.ids.join(",")), s.calendar && e.setAttribute("data-moment-calendar", s.calendar), s.apiSourceId && e.setAttribute("data-api-source-id", s.apiSourceId), s.externalEventId && e.setAttribute("data-external-event-id", s.externalEventId), e.textContent = s.label ?? "Add to Calendar", e;
385
409
  }
386
410
  if (typeof window < "u") {
387
- const o = window;
388
- o.MomentSdk = y, o.createMomentButton = w;
411
+ const s = window;
412
+ s.MomentSdk = E, s.createMomentButton = S;
389
413
  }
390
414
  export {
391
- y as MomentSdk,
392
- w as createMomentButton
415
+ E as MomentSdk,
416
+ S as createMomentButton
393
417
  };
@@ -11,6 +11,10 @@ export declare function createMomentButton(options: {
11
11
  triggerType?: MomentTriggerType;
12
12
  ids?: string[];
13
13
  calendar?: CalendarProvider;
14
+ /** Sync subscription source id; pairs with `externalEventId` for server-side resolution. */
15
+ apiSourceId?: string;
16
+ /** External event identifier resolved against `apiSourceId`. */
17
+ externalEventId?: string;
14
18
  label?: string;
15
19
  className?: string;
16
20
  }): HTMLButtonElement;
@@ -0,0 +1,3 @@
1
+ export declare const TRIGGER_STYLE_ELEMENT_ID = "moment-sdk-trigger-styles";
2
+ /** Inject default trigger button styles once per page. */
3
+ export declare function injectTriggerStyles(): void;
@@ -40,6 +40,19 @@ export interface MomentSdkOpenPayload {
40
40
  triggerType: MomentTriggerType;
41
41
  ids?: string[];
42
42
  calendar?: CalendarProvider;
43
+ /**
44
+ * Sync subscription source identifier (the publisher's sync-subscription id).
45
+ * When provided together with `externalEventId`, the embed resolves the moment
46
+ * server-side from the source + external event identifier instead of a slug.
47
+ * Forwarded to the Live embed as the `subscriptionId` query param.
48
+ */
49
+ apiSourceId?: string;
50
+ /**
51
+ * External event identifier emitted by the publisher's source feed (e.g. the
52
+ * provider's native event id). Resolved against `apiSourceId` to a moment.
53
+ * Forwarded to the Live embed as the `externalId` query param.
54
+ */
55
+ externalEventId?: string;
43
56
  }
44
57
  /** Backend subscription resource type that the embed will create */
45
58
  export type MomentSubscriptionType = 'moment' | 'list' | 'team';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momentco-ai/moment-sdk",
3
- "version": "0.2.0",
3
+ "version": "0.2.2-dev.17",
4
4
  "type": "module",
5
5
  "description": "Embeddable calendar sync widget for external team websites",
6
6
  "author": "Moment Co. <support@momentco.ai> (https://momentco.ai)",