Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make carousel events work inside an iframe #455

Closed
1 task done
Tracked by #321
slpy9 opened this issue Apr 13, 2023 · 20 comments · Fixed by #475
Closed
1 task done
Tracked by #321

Make carousel events work inside an iframe #455

slpy9 opened this issue Apr 13, 2023 · 20 comments · Fixed by #475
Labels
feature request New feature or request resolved This issue is resolved

Comments

@slpy9
Copy link

slpy9 commented Apr 13, 2023

Feature request is related to

  • embla-carousel (core package)

Is your feature request related to an issue?

Describe the solution you'd like

  • As described in the blog post linked above, replace usage of the document property with ownerDocument.

Describe alternatives you've considered

  • Replacing the drag handler via the Embla engine.

Additional context

I've been developing a WordPress plugin using Embla Carousel, dragging is broken in the site editor due to the blocks being loaded in an iframe.

I was able to fix the issue by modifying the line below to use rootNode.ownerDocument.

const node = isMouse ? document : rootNode

@slpy9 slpy9 added the feature request New feature or request label Apr 13, 2023
@davidjerleke
Copy link
Owner

davidjerleke commented Apr 13, 2023

Hi @slpy9,

Thank you for your question. Is the site editor rendering the carousel inside an iframe?

Best,
David

@slpy9
Copy link
Author

slpy9 commented Apr 13, 2023

Hey David,

Yes, I believe that's the core issue.. the link I've posted above goes into better detail than I am able to explain myself. I wasn't really sure if I should post this issue as a bug or a feature request.

Thanks for your time.

@davidjerleke
Copy link
Owner

Thanks @slpy9. @M-Joyce created a discussion for this here:

He also linked to a possible solution to the problem in the same discussion. I would like to implement this but I need someone to test it. If you’re willing to test it I will investigate this further.

Best,
David

@slpy9
Copy link
Author

slpy9 commented Apr 13, 2023

I'd be happy to give it a try, just let me know what you require from me.

I've read through the discussion you linked, and the proposed solution is effectively the same as what the WordPress dev's have suggested, replacing instances of document with ownerDocument.

I've made these changes in my local dev environment, and that has fixed the issue I was experiencing with dragging behaviour in the site editor.

@davidjerleke
Copy link
Owner

Hi @slpy9,

Thank you for your response! Yeah, they’re almost the same but I think the is iframe check is important. Because just changing document to ownerDocument is a more “naive” (in lack of a better term) approach and could have other implications that were missing.

We wouldn’t want to introduce a critical bug to thousands of users. Unless you have a more robust source that proves that this is safe. If that’s the case, please share 🙂.

Best,
David

@davidjerleke
Copy link
Owner

davidjerleke commented Apr 13, 2023

@slpy9 do you have any objections to renaming this issue title to something along these lines:

Make Embla Carousel events work inside an iframe?

?

Best,
David

@slpy9
Copy link
Author

slpy9 commented Apr 13, 2023

Hey David,

Thank you for your response! Yeah, they’re almost the same but I think the is iframe check is important. Because just changing document to ownerDocument is a more “naive” (in lack of a better term) approach and could have other implications that were missing.

I understand your concerns and it is no doubt better to err on the side of caution.

do you have any objections to renaming this issue

Not at all, go for it!

@davidjerleke davidjerleke changed the title Compatibility with the WordPress site editor Make carousel events work inside an iframe Apr 13, 2023
@davidjerleke davidjerleke mentioned this issue Apr 13, 2023
37 tasks
@davidjerleke davidjerleke added upcoming A feature or bug fix is on its way for this issue investigating Issue is being looked into and removed upcoming A feature or bug fix is on its way for this issue labels Apr 20, 2023
@davidjerleke
Copy link
Owner

davidjerleke commented Apr 23, 2023

Hi @slpy9,

I've read through the discussion you linked, and the proposed solution is effectively the same as what the WordPress dev's have suggested, replacing instances of document with ownerDocument.

I've made these changes in my local dev environment, and that has fixed the issue I was experiencing with dragging behaviour in the site editor.

I started looking into this today and wasn't sure about what you replaced in your code? All document's are easy to replace but did you also do something similar to all window. calls? Because if I'm not mistaken, window also refers to the top window (not the iframe but its parent) unless it's targeted differently?

Thanks in advance.

Best,
David

@slpy9
Copy link
Author

slpy9 commented Apr 23, 2023

Hey David,

You are correct, initially I did not make any changes to window calls as I thought the DragHandler was the only problem, but have since noticed some issues with resizing. The window calls also need updating to use ownerDocument.defaultView.

Thanks for looking into this!

-edit-

I'm not certain whether you need to update all window calls, as I've only experienced issues with event listeners in an iframe.

@davidjerleke
Copy link
Owner

Thanks for the prompt answer @slpy9 👍.

I'm not certain whether you need to update all window calls, as I've only experienced issues with event listeners in an iframe.

I guess it makes sense that any document and window reference should point to the iframe itself in case it's an iframe. Although this isn't technically advanced to implement, we need to initialize them and pass them around in many places in the code. I'll look into it when possible.

Cheers,
David

@deysan
Copy link

deysan commented May 3, 2023

Hello @slpy9. I have also faced this problem. How can the proposed solution be implemented locally?

@davidjerleke Let me know if you need help with testing 🙄

@slpy9
Copy link
Author

slpy9 commented May 4, 2023

Hey @deysan,

Are you using React? as a temporary fix, I've edited the source under node_modules/embla-carousel, and created a patch using patch-package.

Though it's not ideal and I'd recommend waiting for an official patch if you can.

@davidjerleke
Copy link
Owner

davidjerleke commented May 17, 2023

Hi @slpy9 and @deysan,

Please try this script and see if it's working as intended in an iframe:

embla-carousel

!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(n="undefined"!=typeof globalThis?globalThis:n||self).EmblaCarousel=t()}(this,(function(){"use strict";function n(n){return"number"==typeof n}function t(n){return"string"==typeof n}function e(n){return"boolean"==typeof n}function r(n){return"[object Object]"===Object.prototype.toString.call(n)}function o(n){return Math.abs(n)}function i(n){return Math.sign(n)}function c(n,t){return o(n-t)}function u(n){return l(n).map(Number)}function s(n){return n[a(n)]}function a(n){return Math.max(0,n.length-1)}function l(n){return Object.keys(n)}function d(n,t){return[n,t].reduce(((n,t)=>(l(t).forEach((e=>{const o=n[e],i=t[e],c=r(o)&&r(i);n[e]=c?d(o,i):i})),n)),{})}function f(n,t){return void 0!==t.MouseEvent&&n instanceof t.MouseEvent}function p(t,e){const r={start:function(){return 0},center:function(n){return o(n)/2},end:o};function o(n){return e-n}return{measure:function(o){return n(t)?e*Number(t):r[t](o)}}}function m(n,t){const e=o(n-t);function r(t){return t<n}function i(n){return n>t}function c(n){return r(n)||i(n)}return{length:e,max:t,min:n,constrain:function(e){return c(e)?r(e)?n:t:e},reachedAny:c,reachedMax:i,reachedMin:r,removeOffset:function(n){return e?n-e*Math.ceil((n-t)/e):n}}}function g(n,t,e){const{constrain:r}=m(0,n),i=n+1;let c=u(t);function u(n){return e?o((i+n)%i):r(n)}function s(){return c}function a(n){return c=u(n),l}const l={get:s,set:a,add:function(n){return a(s()+n)},clone:function(){return g(n,s(),e)}};return l}function h(){let n=[];const t={add:function(e,r,o,i={passive:!0}){return e.addEventListener(r,o,i),n.push((()=>e.removeEventListener(r,o,i))),t},clear:function(){n=n.filter((n=>n()))}};return t}function x(n,t,r,u,s,a,l,d,p,g,x,y,v,b,S,w,E,D,M){const{cross:A}=n,I=["INPUT","SELECT","TEXTAREA"],O={passive:!1},P=h(),T=h(),L=m(50,225).constrain(S.measure(20)),z={mouse:300,touch:400},B={mouse:500,touch:600},k=w?43:25;let F=!1,H=0,N=0,C=!1,R=!1,V=!1,j=!1;function q(n){const e=l.readPoint(n),r=l.readPoint(n,A),o=c(e,H),i=c(r,N);if(!R&&!j){if(!n.cancelable)return U(n);if(R=o>i,!R)return U(n)}const u=l.pointerMove(n);o>E&&(V=!0),x.useFriction(.3).useDuration(1),p.start(),a.add(t.apply(u)),n.preventDefault()}function U(n){const e=y.byDistance(0,!1).index!==v.get(),r=l.pointerUp(n)*(w?B:z)[j?"mouse":"touch"],u=function(n,t){const e=v.clone().add(-1*i(n)),r=y.byDistance(n,!w).distance;return w||o(n)<L?r:D&&t?.5*r:y.byIndex(e.get(),0).distance}(t.apply(r),e),s=function(n,t){if(0===n||0===t)return 0;if(o(n)<=o(t))return 0;const e=c(o(n),o(t));return o(e/n)}(r,u),a=k-10*s,d=M+s/50;R=!1,C=!1,T.clear(),x.useDuration(a).useFriction(d),g.distance(u,!w),j=!1,b.emit("pointerUp")}function W(n){V&&(n.stopPropagation(),n.preventDefault())}return{init:function(n,t){if(!t)return;function o(o){(e(t)||t(n,o))&&function(n){const t=f(n,s);if(j=t,t&&0!==n.button)return;if(function(n){const t=n.nodeName||"";return I.includes(t)}(n.target))return;V=w&&t&&!n.buttons&&F,F=c(a.get(),d.get())>=2,C=!0,l.pointerDown(n),x.useFriction(0).useDuration(0),a.set(d),function(){const n=j?u:r;T.add(n,"touchmove",q,O).add(n,"touchend",U).add(n,"mousemove",q,O).add(n,"mouseup",U)}(),H=l.readPoint(n),N=l.readPoint(n,A),b.emit("pointerDown")}(o)}const i=r;P.add(i,"dragstart",(n=>n.preventDefault()),O).add(i,"touchmove",(()=>{}),O).add(i,"touchend",(()=>{})).add(i,"touchstart",o).add(i,"mousedown",o).add(i,"touchcancel",U).add(i,"contextmenu",U).add(i,"click",W,!0)},pointerDown:function(){return C},destroy:function(){P.clear(),T.clear()}}}function y(n,t){let e,r;function i(n){return n.timeStamp}function c(e,r){const o="client"+("x"===(r||n.scroll)?"X":"Y");return(f(e,t)?e:e.touches[0])[o]}return{pointerDown:function(n){return e=n,r=n,c(n)},pointerMove:function(n){const t=c(n)-c(r),o=i(n)-i(e)>170;return r=n,o&&(e=n),t},pointerUp:function(n){if(!e||!r)return 0;const t=c(r)-c(e),u=i(n)-i(e),s=i(n)-i(r)>170,a=t/u;return u&&!s&&o(a)>.1?a:0},readPoint:c}}function v(n,t,r,o){let i,c,u=[],s=!1;function a(n){return r.measureSize(n.getBoundingClientRect())}return{init:function(r,l){if(!l)return;c=a(n),u=t.map(a),i=new ResizeObserver((i=>{s||(e(l)||l(r,i))&&function(e){for(const i of e){const e=i.target===n,s=t.indexOf(i.target);if((e?c:u[s])!==a(e?n:t[s])){r.reInit(),o.emit("resize");break}}}(i)})),[n].concat(t).forEach((n=>i.observe(n)))},destroy:function(){i&&i.disconnect(),s=!0}}}function b(n,t,e,r,i){const c=i.measure(10),u=i.measure(50),s=m(.1,.99);let a=!1;return{constrain:function(i){if(a||!n.reachedAny(e.get())||!n.reachedAny(t.get()))return;const l=n.reachedMin(t.get())?"min":"max",d=o(n[l]-t.get()),f=e.get()-t.get(),p=s.constrain(d/u);e.subtract(f*p),!i&&o(f)<c&&(e.set(n.constrain(e.get())),r.useDuration(25).useBaseFriction())},toggleActive:function(n){a=!n}}}function S(n,t,e,r){const o=m(-t+n,e[0]),i=e.map(o.constrain);return{snapsContained:function(){if(t<=n)return[o.max];if("keepSnaps"===r)return i;const{min:e,max:c}=function(){const n=i[0],t=s(i),e=i.lastIndexOf(n),r=i.indexOf(t)+1;return m(e,r)}();return i.slice(e,c)}()}}function w(n,t,e,r){const o=t.min+.1,i=t.max+.1,{reachedMin:c,reachedMax:u}=m(o,i);return{loop:function(t){if(!function(n){return 1===n?u(e.get()):-1===n&&c(e.get())}(t))return;const o=n*(-1*t);r.forEach((n=>n.add(o)))}}}function E(n){const{max:t,length:e}=n;return{get:function(n){return(n-t)/-e}}}function D(n,t,e,r,c){const{reachedAny:u,removeOffset:s,constrain:a}=r;function l(n){return n.concat().sort(((n,t)=>o(n)-o(t)))[0]}function d(t,r){const o=[t,t+e,t-e];if(!n)return o[0];if(!r)return l(o);return l(o.filter((n=>i(n)===r)))}return{byDistance:function(e,r){const i=c.get()+e,{index:l,distance:f}=function(e){const r=n?s(e):a(e),i=t.map((n=>n-r)).map((n=>d(n,0))).map(((n,t)=>({diff:n,index:t}))).sort(((n,t)=>o(n.diff)-o(t.diff))),{index:c}=i[0];return{index:c,distance:r}}(i),p=!n&&u(i);return!r||p?{index:l,distance:e}:{index:l,distance:e+d(t[l]-f,0)}},byIndex:function(n,e){return{index:n,distance:d(t[n]-c.get(),e)}},shortcut:d}}function M(t){let e=t;function r(t){return n(t)?t:t.get()}return{get:function(){return e},set:function(n){e=r(n)},add:function(n){e+=r(n)},subtract:function(n){e-=r(n)}}}function A(n,t,e){const r="x"===n.scroll?function(n){return`translate3d(${n}px,0px,0px)`}:function(n){return`translate3d(0px,${n}px,0px)`},o=e.style;let i=!1;return{clear:function(){i||(o.transform="",e.getAttribute("style")||e.removeAttribute("style"))},to:function(n){i||(o.transform=r(t.apply(n)))},toggleActive:function(n){i=!n}}}function I(n,t,e,r,o,i,c,s,a){const l=u(o),d=u(o).reverse(),f=function(){const n=i[0]-1;return g(m(d,n),"end")}().concat(function(){const n=e-i[0]-1;return g(m(l,n),"start")}());function p(n,t){return n.reduce(((n,t)=>n-o[t]),t)}function m(n,t){return n.reduce(((n,e)=>p(n,t)>0?n.concat([e]):n),[])}function g(e,o){const i="start"===o,u=i?-r:r,l=c.findSlideBounds([u]);return e.map((e=>{const o=i?0:-r,c=i?r:0,u=l.filter((n=>n.index===e))[0][i?"end":"start"],d=M(-1),f=A(n,t,a[e]);return{index:e,location:d,translate:f,target:()=>s.get()>u?o:c}}))}return{canLoop:function(){return f.every((({index:n})=>p(l.filter((t=>t!==n)),e)<=.1))},clear:function(){f.forEach((n=>n.translate.clear()))},loop:function(){f.forEach((n=>{const{target:t,translate:e,location:r}=n,o=t();o!==r.get()&&(e.to(o),r.set(o))}))},loopPoints:f}}function O(n,t){let r,o=!1;return{init:function(i,c){c&&(r=new MutationObserver((n=>{o||(e(c)||c(i,n))&&function(n){for(const e of n)if("childList"===e.type){i.reInit(),t.emit("slidesChanged");break}}(n)})),r.observe(n,{childList:!0}))},destroy:function(){r&&r.disconnect(),o=!0}}}function P(n,t,e,r,o,i,c){const{removeOffset:u,constrain:s}=o,a=i?[0,t,-t]:[0],l=d(a,c);function d(t,o){const i=t||a,c=function(n){const t=n||0;return e.map((n=>m(.5,n-.5).constrain(n*t)))}(o);return i.reduce(((t,o)=>{const i=r.map(((t,r)=>({start:t-e[r]+c[r]+o,end:t+n-c[r]+o,index:r})));return t.concat(i)}),[])}return{check:function(n,t){const e=i?u(n):s(n);return(t||l).reduce(((n,t)=>{const{index:r,start:o,end:i}=t;return!n.includes(r)&&(o<e&&i>e)?n.concat([r]):n}),[])},findSlideBounds:d}}function T(t,e,r){const o=n(r);return{groupSlides:function(n){return o?function(n,t){return u(n).filter((n=>n%t==0)).map((e=>n.slice(e,e+t)))}(n,r):function(n){return u(n).reduce(((n,r)=>{const o=e.slice(s(n),r+1).reduce(((n,t)=>n+t),0);return!r||o>t?n.concat(r):n}),[]).map(((t,e,r)=>n.slice(t,r[e+1])))}(n)}}}function L(n,t,e,r,c,l,d,f){const{align:L,axis:z,direction:B,startIndex:k,inViewThreshold:F,loop:H,duration:N,dragFree:C,dragThreshold:R,slidesToScroll:V,skipSnaps:j,containScroll:q}=l,U=t.getBoundingClientRect(),W=e.map((n=>n.getBoundingClientRect())),$=function(n){const t="rtl"===n?-1:1;return{apply:function(n){return n*t}}}(B),G=function(n,t){const e="y"===n?"y":"x";return{scroll:e,cross:"y"===n?"x":"y",startEdge:"y"===e?"top":"rtl"===t?"right":"left",endEdge:"y"===e?"bottom":"rtl"===t?"left":"right",measureSize:function(n){const{width:t,height:r}=n;return"x"===e?t:r}}}(z,B),Q=G.measureSize(U),X=function(n){return{measure:function(t){return n*(t/100)}}}(Q),Y=p(L,Q),J=!H&&!!q,K=H||!!q,{slideSizes:Z,slideSizesWithGaps:_}=function(n,t,e,r,i,c){const{measureSize:u,startEdge:l,endEdge:d}=n,f=e[0]&&i,p=function(){if(!f)return 0;const n=e[0];return o(t[l]-n[l])}(),m=function(){if(!f)return 0;const n=c.getComputedStyle(s(r));return parseFloat(n.getPropertyValue(`margin-${d}`))}(),g=e.map(u),h=e.map(((n,t,e)=>{const r=!t,o=t===a(e);return r?g[t]+p:o?g[t]+m:e[t+1][l]-n[l]})).map(o);return{slideSizes:g,slideSizesWithGaps:h}}(G,U,W,e,K,c),nn=T(Q,_,V),{snaps:tn,snapsAligned:en}=function(n,t,e,r,i,c,u){const{startEdge:l,endEdge:d}=n,{groupSlides:f}=c,p=f(r).map((n=>s(n)[d]-n[0][l])).map(o).map(t.measure),m=r.map((n=>e[l]-n[l])).map((n=>-o(n))),g=function(){const n=s(m)-s(i);return f(m).map((n=>n[0])).map(((t,e,r)=>{const o=!e,i=e===a(r);return u&&o?0:u&&i?n:t+p[e]}))}();return{snaps:m,snapsAligned:g}}(G,Y,U,W,_,nn,J),rn=-s(tn)+s(_),{snapsContained:on}=S(Q,rn,en,q),cn=J?on:en,{limit:un}=function(n,t,e){return{limit:function(){const r=t[0];return m(e?r-n:s(t),r)}()}}(rn,cn,H),sn=g(a(cn),k,H),an=sn.clone(),ln=u(e),dn={update:()=>(({dragHandler:n,scrollBody:t,scrollBounds:e,scrollLooper:r,slideLooper:o,eventHandler:i,animation:c,options:{loop:u}})=>{const s=n.pointerDown();u||e.constrain(s);const a=t.seek().settled();a&&!s&&(c.stop(),i.emit("settle")),a||i.emit("scroll"),u&&(r.loop(t.direction()),o.loop())})(vn),render:n=>(({scrollBody:n,translate:t,location:e},r)=>{const o=n.velocity(),i=e.get()-o+o*r;t.to(i)})(vn,n),start:()=>f.start(vn),stop:()=>f.stop(vn)},fn=cn[sn.get()],pn=M(fn),mn=M(fn),gn=function(n,t,e,r){let c=!0,u=0,s=0,a=e,l=r;function d(n){return a=n,p}function f(n){return l=n,p}const p={direction:function(){return s},seek:function(){const e=t.get()-n.get();return l&&a?(u+=e/a,u*=l,n.add(u)):(u=0,n.set(t)),s=i(u||e),c=o(e)<.001,p},settled:function(){return c&&n.set(t),c},useBaseFriction:function(){return f(r)},useBaseDuration:function(){return d(e)},useFriction:f,useDuration:d,velocity:function(){return u}};return p}(pn,mn,N,.68),hn=D(H,cn,rn,un,mn),xn=function(n,t,e,r,o,i){function c(r){const c=r.distance,u=r.index!==t.get();c&&(n.start(),o.add(c)),u&&(e.set(t.get()),t.set(r.index),i.emit("select"))}return{distance:function(n,t){c(r.byDistance(n,t))},index:function(n,e){const o=t.clone().set(n);c(r.byIndex(o.get(),e))}}}(dn,sn,an,hn,mn,d),yn=P(Q,rn,Z,tn,un,H,F),vn={ownerDocument:r,ownerWindow:c,eventHandler:d,containerRect:U,slideRects:W,animation:dn,axis:G,direction:$,dragHandler:x(G,$,n,r,c,mn,y(G,c),pn,dn,xn,gn,hn,sn,d,X,C,R,j,.68),eventStore:h(),percentOfView:X,index:sn,indexPrevious:an,limit:un,location:pn,options:l,resizeHandler:v(t,e,G,d),scrollBody:gn,scrollBounds:b(un,pn,mn,gn,X),scrollLooper:w(rn,un,pn,[pn,mn]),scrollProgress:E(un),scrollSnaps:cn,scrollTarget:hn,scrollTo:xn,slideLooper:I(G,$,Q,rn,_,cn,yn,pn,e),slidesHandler:O(t,d),slidesInView:yn,slideIndexes:ln,slidesToScroll:nn,target:mn,translate:A(G,$,t)};return vn}const z={align:"center",axis:"x",container:null,slides:null,containScroll:null,direction:"ltr",slidesToScroll:1,breakpoints:{},dragFree:!1,dragThreshold:10,inViewThreshold:0,loop:!1,skipSnaps:!1,duration:25,startIndex:0,active:!0,watchDrag:!0,watchResize:!0,watchSlides:!0};function B(n){function t(n,t){return d(n,t||{})}const e={mergeOptions:t,optionsAtMedia:function(e){const r=e.breakpoints||{},o=l(r).filter((t=>n.matchMedia(t).matches)).map((n=>r[n])).reduce(((n,e)=>t(n,e)),{});return t(e,o)},optionsMediaQueries:function(t){return t.map((n=>l(n.breakpoints||{}))).reduce(((n,t)=>n.concat(t)),[]).map(n.matchMedia)}};return e}function k(n,e,r){const i=n.ownerDocument,c=i.defaultView,u=B(c),s=function(n){let t=[];return{init:function(e,r){return t=e.filter((({options:t})=>!1!==n.optionsAtMedia(t).active)),t.forEach((t=>t.init(r,n))),e.reduce(((n,t)=>Object.assign(n,{[t.name]:t})),{})},destroy:function(){t=t.filter((n=>n.destroy()))}}}(u),a=h(),l=h(),d=function(){const n={};let t;function e(t){return n[t]||[]}const r={init:function(n){t=n},emit:function(n){return e(n).forEach((e=>e(t,n))),r},off:function(t,o){return n[t]=e(t).filter((n=>n!==o)),r},on:function(t,o){return n[t]=e(t).concat([o]),r}};return r}(),{animationsList:f}=k,{mergeOptions:p,optionsAtMedia:m,optionsMediaQueries:g}=u,{on:x,off:y,emit:v}=d,b=T;let S,w,E,D,M=!1,A=p(z,k.globalOptions),I=p(A),O=[];function P(e,r){if(M)return;const u=f.find((n=>n.window===c)),h=u||function(n){const t=1e3/60;let e=[],r=null,i=0,c=0;function u(s){r||(r=s);const a=s-r;for(r=s,i+=a;i>=t;)e.forEach((({animation:n})=>n.update())),i-=t;const l=o(i/t);e.forEach((({animation:n})=>n.render(l))),c&&n.requestAnimationFrame(u)}return{start:function(t){e.includes(t)||e.push(t),c||(c=n.requestAnimationFrame(u))},stop:function(t){e=e.filter((n=>n!==t)),e.length||(n.cancelAnimationFrame(c),r=null,i=0,c=0)},reset:function(){r=null,i=0},window:n}}(c);if(u||f.push(h),A=p(A,e),I=m(A),function(){const{container:e,slides:r}=I,o=t(e)?n.querySelector(e):e;E=o||n.children[0];const i=t(r)?E.querySelectorAll(r):r;D=[].slice.call(i||E.children)}(),S=L(n,E,D,i,c,I,d,h),!I.active)return F();if(S.translate.to(S.location.get()),O=r||O,w=s.init(O,R),g([A,...O.map((({options:n})=>n))]).forEach((n=>a.add(n,"change",T))),S.eventHandler.init(R),S.resizeHandler.init(R,I.watchResize),S.slidesHandler.init(R,I.watchSlides),l.add(i,"visibilitychange",(()=>{i.hidden&&h.reset()})),I.loop){if(!S.slideLooper.canLoop())return F(),P({loop:!1},r),void(A=p(A,{loop:!0}));S.slideLooper.loop()}E.offsetParent&&D.length&&S.dragHandler.init(R,I.watchDrag)}function T(n,t){const e=C();F(),P(p({startIndex:e},n),t),d.emit("reInit")}function F(){S.dragHandler.destroy(),S.animation.stop(),S.eventStore.clear(),S.translate.clear(),S.slideLooper.clear(),S.resizeHandler.destroy(),S.slidesHandler.destroy(),s.destroy(),a.clear(),l.clear()}function H(n){const t=S[n?"target":"location"].get(),e=I.loop?"removeOffset":"constrain";return S.slidesInView.check(S.limit[e](t))}function N(n,t,e){I.active&&!M&&(S.scrollBody.useBaseFriction().useDuration(t?0:I.duration),S.scrollTo.index(n,e||0))}function C(){return S.index.get()}const R={canScrollNext:function(){return S.index.clone().add(1).get()!==C()},canScrollPrev:function(){return S.index.clone().add(-1).get()!==C()},containerNode:function(){return E},internalEngine:function(){return S},destroy:function(){M||(M=!0,a.clear(),F(),d.emit("destroy"))},off:y,on:x,emit:v,plugins:function(){return w},previousScrollSnap:function(){return S.indexPrevious.get()},reInit:b,rootNode:function(){return n},scrollNext:function(n){N(S.index.clone().add(1).get(),!0===n,-1)},scrollPrev:function(n){N(S.index.clone().add(-1).get(),!0===n,1)},scrollProgress:function(){return S.scrollProgress.get(S.location.get())},scrollSnapList:function(){return S.scrollSnaps.map(S.scrollProgress.get)},scrollTo:N,selectedScrollSnap:C,slideNodes:function(){return D},slidesInView:H,slidesNotInView:function(n){const t=H(n);return S.slideIndexes.filter((n=>!t.includes(n)))}};return P(e,r),setTimeout((()=>d.emit("init")),0),R}return k.animationsList=[],k.globalOptions=void 0,k}));

embla-carousel-react

!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):(n="undefined"!=typeof globalThis?globalThis:n||self).EmblaCarouselReact=t(n.React)}(this,(function(n){"use strict";function t(n){return function(n){return"[object Object]"===Object.prototype.toString.call(n)}(n)||Array.isArray(n)}function e(n,r){const o=Object.keys(n),i=Object.keys(r);if(o.length!==i.length)return!1;return JSON.stringify(Object.keys(n.breakpoints||{}))===JSON.stringify(Object.keys(r.breakpoints||{}))&&o.every((o=>{const i=n[o],c=r[o];return"function"==typeof i?`${i}`==`${c}`:t(i)&&t(c)?e(i,c):i===c}))}function r(n){return n.concat().sort(((n,t)=>n.name>t.name?1:-1)).map((n=>n.options))}function o(n){return"number"==typeof n}function i(n){return"string"==typeof n}function c(n){return"boolean"==typeof n}function u(n){return"[object Object]"===Object.prototype.toString.call(n)}function s(n){return Math.abs(n)}function a(n){return Math.sign(n)}function l(n,t){return s(n-t)}function d(n){return m(n).map(Number)}function f(n){return n[p(n)]}function p(n){return Math.max(0,n.length-1)}function m(n){return Object.keys(n)}function g(n,t){return[n,t].reduce(((n,t)=>(m(t).forEach((e=>{const r=n[e],o=t[e],i=u(r)&&u(o);n[e]=i?g(r,o):o})),n)),{})}function h(n,t){return void 0!==t.MouseEvent&&n instanceof t.MouseEvent}function y(n,t){const e={start:function(){return 0},center:function(n){return r(n)/2},end:r};function r(n){return t-n}return{measure:function(r){return o(n)?t*Number(n):e[n](r)}}}function x(n,t){const e=s(n-t);function r(t){return t<n}function o(n){return n>t}function i(n){return r(n)||o(n)}return{length:e,max:t,min:n,constrain:function(e){return i(e)?r(e)?n:t:e},reachedAny:i,reachedMax:o,reachedMin:r,removeOffset:function(n){return e?n-e*Math.ceil((n-t)/e):n}}}function b(n,t,e){const{constrain:r}=x(0,n),o=n+1;let i=c(t);function c(n){return e?s((o+n)%o):r(n)}function u(){return i}function a(n){return i=c(n),l}const l={get:u,set:a,add:function(n){return a(u()+n)},clone:function(){return b(n,u(),e)}};return l}function v(){let n=[];const t={add:function(e,r,o,i={passive:!0}){return e.addEventListener(r,o,i),n.push((()=>e.removeEventListener(r,o,i))),t},clear:function(){n=n.filter((n=>n()))}};return t}function S(n,t,e,r,o,i,u,d,f,p,m,g,y,b,S,w,E,O,D){const{cross:k}=n,A=["INPUT","SELECT","TEXTAREA"],M={passive:!1},I=v(),P=v(),T=x(50,225).constrain(S.measure(20)),L={mouse:300,touch:400},z={mouse:500,touch:600},B=w?43:25;let j=!1,F=0,H=0,R=!1,N=!1,C=!1,V=!1;function q(n){const e=u.readPoint(n),r=u.readPoint(n,k),o=l(e,F),c=l(r,H);if(!N&&!V){if(!n.cancelable)return $(n);if(N=o>c,!N)return $(n)}const s=u.pointerMove(n);o>E&&(C=!0),m.useFriction(.3).useDuration(1),f.start(),i.add(t.apply(s)),n.preventDefault()}function $(n){const e=g.byDistance(0,!1).index!==y.get(),r=u.pointerUp(n)*(w?z:L)[V?"mouse":"touch"],o=function(n,t){const e=y.clone().add(-1*a(n)),r=g.byDistance(n,!w).distance;return w||s(n)<T?r:O&&t?.5*r:g.byIndex(e.get(),0).distance}(t.apply(r),e),i=function(n,t){if(0===n||0===t)return 0;if(s(n)<=s(t))return 0;const e=l(s(n),s(t));return s(e/n)}(r,o),c=B-10*i,d=D+i/50;N=!1,R=!1,P.clear(),m.useDuration(c).useFriction(d),p.distance(o,!w),V=!1,b.emit("pointerUp")}function U(n){C&&(n.stopPropagation(),n.preventDefault())}return{init:function(n,t){if(!t)return;function s(s){(c(t)||t(n,s))&&function(n){const t=h(n,o);if(V=t,t&&0!==n.button)return;if(function(n){const t=n.nodeName||"";return A.includes(t)}(n.target))return;C=w&&t&&!n.buttons&&j,j=l(i.get(),d.get())>=2,R=!0,u.pointerDown(n),m.useFriction(0).useDuration(0),i.set(d),function(){const n=V?r:e;P.add(n,"touchmove",q,M).add(n,"touchend",$).add(n,"mousemove",q,M).add(n,"mouseup",$)}(),F=u.readPoint(n),H=u.readPoint(n,k),b.emit("pointerDown")}(s)}const a=e;I.add(a,"dragstart",(n=>n.preventDefault()),M).add(a,"touchmove",(()=>{}),M).add(a,"touchend",(()=>{})).add(a,"touchstart",s).add(a,"mousedown",s).add(a,"touchcancel",$).add(a,"contextmenu",$).add(a,"click",U,!0)},pointerDown:function(){return R},destroy:function(){I.clear(),P.clear()}}}function w(n,t){let e,r;function o(n){return n.timeStamp}function i(e,r){const o="client"+("x"===(r||n.scroll)?"X":"Y");return(h(e,t)?e:e.touches[0])[o]}return{pointerDown:function(n){return e=n,r=n,i(n)},pointerMove:function(n){const t=i(n)-i(r),c=o(n)-o(e)>170;return r=n,c&&(e=n),t},pointerUp:function(n){if(!e||!r)return 0;const t=i(r)-i(e),c=o(n)-o(e),u=o(n)-o(r)>170,a=t/c;return c&&!u&&s(a)>.1?a:0},readPoint:i}}function E(n,t,e,r){let o,i,u=[],s=!1;function a(n){return e.measureSize(n.getBoundingClientRect())}return{init:function(e,l){if(!l)return;i=a(n),u=t.map(a),o=new ResizeObserver((o=>{s||(c(l)||l(e,o))&&function(o){for(const c of o){const o=c.target===n,s=t.indexOf(c.target);if((o?i:u[s])!==a(o?n:t[s])){e.reInit(),r.emit("resize");break}}}(o)})),[n].concat(t).forEach((n=>o.observe(n)))},destroy:function(){o&&o.disconnect(),s=!0}}}function O(n,t,e,r,o){const i=o.measure(10),c=o.measure(50),u=x(.1,.99);let a=!1;return{constrain:function(o){if(a||!n.reachedAny(e.get())||!n.reachedAny(t.get()))return;const l=n.reachedMin(t.get())?"min":"max",d=s(n[l]-t.get()),f=e.get()-t.get(),p=u.constrain(d/c);e.subtract(f*p),!o&&s(f)<i&&(e.set(n.constrain(e.get())),r.useDuration(25).useBaseFriction())},toggleActive:function(n){a=!n}}}function D(n,t,e,r){const o=x(-t+n,e[0]),i=e.map(o.constrain);return{snapsContained:function(){if(t<=n)return[o.max];if("keepSnaps"===r)return i;const{min:e,max:c}=function(){const n=i[0],t=f(i),e=i.lastIndexOf(n),r=i.indexOf(t)+1;return x(e,r)}();return i.slice(e,c)}()}}function k(n,t,e,r){const o=t.min+.1,i=t.max+.1,{reachedMin:c,reachedMax:u}=x(o,i);return{loop:function(t){if(!function(n){return 1===n?u(e.get()):-1===n&&c(e.get())}(t))return;const o=n*(-1*t);r.forEach((n=>n.add(o)))}}}function A(n){const{max:t,length:e}=n;return{get:function(n){return(n-t)/-e}}}function M(n,t,e,r,o){const{reachedAny:i,removeOffset:c,constrain:u}=r;function l(n){return n.concat().sort(((n,t)=>s(n)-s(t)))[0]}function d(t,r){const o=[t,t+e,t-e];if(!n)return o[0];if(!r)return l(o);return l(o.filter((n=>a(n)===r)))}return{byDistance:function(e,r){const a=o.get()+e,{index:l,distance:f}=function(e){const r=n?c(e):u(e),o=t.map((n=>n-r)).map((n=>d(n,0))).map(((n,t)=>({diff:n,index:t}))).sort(((n,t)=>s(n.diff)-s(t.diff))),{index:i}=o[0];return{index:i,distance:r}}(a),p=!n&&i(a);return!r||p?{index:l,distance:e}:{index:l,distance:e+d(t[l]-f,0)}},byIndex:function(n,e){return{index:n,distance:d(t[n]-o.get(),e)}},shortcut:d}}function I(n){let t=n;function e(n){return o(n)?n:n.get()}return{get:function(){return t},set:function(n){t=e(n)},add:function(n){t+=e(n)},subtract:function(n){t-=e(n)}}}function P(n,t,e){const r="x"===n.scroll?function(n){return`translate3d(${n}px,0px,0px)`}:function(n){return`translate3d(0px,${n}px,0px)`},o=e.style;let i=!1;return{clear:function(){i||(o.transform="",e.getAttribute("style")||e.removeAttribute("style"))},to:function(n){i||(o.transform=r(t.apply(n)))},toggleActive:function(n){i=!n}}}function T(n,t,e,r,o,i,c,u,s){const a=d(o),l=d(o).reverse(),f=function(){const n=i[0]-1;return g(m(l,n),"end")}().concat(function(){const n=e-i[0]-1;return g(m(a,n),"start")}());function p(n,t){return n.reduce(((n,t)=>n-o[t]),t)}function m(n,t){return n.reduce(((n,e)=>p(n,t)>0?n.concat([e]):n),[])}function g(e,o){const i="start"===o,a=i?-r:r,l=c.findSlideBounds([a]);return e.map((e=>{const o=i?0:-r,c=i?r:0,a=l.filter((n=>n.index===e))[0][i?"end":"start"],d=I(-1),f=P(n,t,s[e]);return{index:e,location:d,translate:f,target:()=>u.get()>a?o:c}}))}return{canLoop:function(){return f.every((({index:n})=>p(a.filter((t=>t!==n)),e)<=.1))},clear:function(){f.forEach((n=>n.translate.clear()))},loop:function(){f.forEach((n=>{const{target:t,translate:e,location:r}=n,o=t();o!==r.get()&&(e.to(o),r.set(o))}))},loopPoints:f}}function L(n,t){let e,r=!1;return{init:function(o,i){i&&(e=new MutationObserver((n=>{r||(c(i)||i(o,n))&&function(n){for(const e of n)if("childList"===e.type){o.reInit(),t.emit("slidesChanged");break}}(n)})),e.observe(n,{childList:!0}))},destroy:function(){e&&e.disconnect(),r=!0}}}function z(n,t,e,r,o,i,c){const{removeOffset:u,constrain:s}=o,a=i?[0,t,-t]:[0],l=d(a,c);function d(t,o){const i=t||a,c=function(n){const t=n||0;return e.map((n=>x(.5,n-.5).constrain(n*t)))}(o);return i.reduce(((t,o)=>{const i=r.map(((t,r)=>({start:t-e[r]+c[r]+o,end:t+n-c[r]+o,index:r})));return t.concat(i)}),[])}return{check:function(n,t){const e=i?u(n):s(n);return(t||l).reduce(((n,t)=>{const{index:r,start:o,end:i}=t;return!n.includes(r)&&(o<e&&i>e)?n.concat([r]):n}),[])},findSlideBounds:d}}function B(n,t,e){const r=o(e);return{groupSlides:function(o){return r?function(n,t){return d(n).filter((n=>n%t==0)).map((e=>n.slice(e,e+t)))}(o,e):function(e){return d(e).reduce(((e,r)=>{const o=t.slice(f(e),r+1).reduce(((n,t)=>n+t),0);return!r||o>n?e.concat(r):e}),[]).map(((n,t,r)=>e.slice(n,r[t+1])))}(o)}}}function j(n,t,e,r,o,i,c,u){const{align:l,axis:m,direction:g,startIndex:h,inViewThreshold:j,loop:F,duration:H,dragFree:R,dragThreshold:N,slidesToScroll:C,skipSnaps:V,containScroll:q}=i,$=t.getBoundingClientRect(),U=e.map((n=>n.getBoundingClientRect())),W=function(n){const t="rtl"===n?-1:1;return{apply:function(n){return n*t}}}(g),G=function(n,t){const e="y"===n?"y":"x";return{scroll:e,cross:"y"===n?"x":"y",startEdge:"y"===e?"top":"rtl"===t?"right":"left",endEdge:"y"===e?"bottom":"rtl"===t?"left":"right",measureSize:function(n){const{width:t,height:r}=n;return"x"===e?t:r}}}(m,g),J=G.measureSize($),Q=function(n){return{measure:function(t){return n*(t/100)}}}(J),X=y(l,J),Y=!F&&!!q,K=F||!!q,{slideSizes:Z,slideSizesWithGaps:_}=function(n,t,e,r,o,i){const{measureSize:c,startEdge:u,endEdge:a}=n,l=e[0]&&o,d=function(){if(!l)return 0;const n=e[0];return s(t[u]-n[u])}(),m=function(){if(!l)return 0;const n=i.getComputedStyle(f(r));return parseFloat(n.getPropertyValue(`margin-${a}`))}(),g=e.map(c),h=e.map(((n,t,e)=>{const r=!t,o=t===p(e);return r?g[t]+d:o?g[t]+m:e[t+1][u]-n[u]})).map(s);return{slideSizes:g,slideSizesWithGaps:h}}(G,$,U,e,K,o),nn=B(J,_,C),{snaps:tn,snapsAligned:en}=function(n,t,e,r,o,i,c){const{startEdge:u,endEdge:a}=n,{groupSlides:l}=i,d=l(r).map((n=>f(n)[a]-n[0][u])).map(s).map(t.measure),m=r.map((n=>e[u]-n[u])).map((n=>-s(n))),g=function(){const n=f(m)-f(o);return l(m).map((n=>n[0])).map(((t,e,r)=>{const o=!e,i=e===p(r);return c&&o?0:c&&i?n:t+d[e]}))}();return{snaps:m,snapsAligned:g}}(G,X,$,U,_,nn,Y),rn=-f(tn)+f(_),{snapsContained:on}=D(J,rn,en,q),cn=Y?on:en,{limit:un}=function(n,t,e){return{limit:function(){const r=t[0];return x(e?r-n:f(t),r)}()}}(rn,cn,F),sn=b(p(cn),h,F),an=sn.clone(),ln=d(e),dn={update:()=>(({dragHandler:n,scrollBody:t,scrollBounds:e,scrollLooper:r,slideLooper:o,eventHandler:i,animation:c,options:{loop:u}})=>{const s=n.pointerDown();u||e.constrain(s);const a=t.seek().settled();a&&!s&&(c.stop(),i.emit("settle")),a||i.emit("scroll"),u&&(r.loop(t.direction()),o.loop())})(bn),render:n=>(({scrollBody:n,translate:t,location:e},r)=>{const o=n.velocity(),i=e.get()-o+o*r;t.to(i)})(bn,n),start:()=>u.start(bn),stop:()=>u.stop(bn)},fn=cn[sn.get()],pn=I(fn),mn=I(fn),gn=function(n,t,e,r){let o=!0,i=0,c=0,u=e,l=r;function d(n){return u=n,p}function f(n){return l=n,p}const p={direction:function(){return c},seek:function(){const e=t.get()-n.get();return l&&u?(i+=e/u,i*=l,n.add(i)):(i=0,n.set(t)),c=a(i||e),o=s(e)<.001,p},settled:function(){return o&&n.set(t),o},useBaseFriction:function(){return f(r)},useBaseDuration:function(){return d(e)},useFriction:f,useDuration:d,velocity:function(){return i}};return p}(pn,mn,H,.68),hn=M(F,cn,rn,un,mn),yn=function(n,t,e,r,o,i){function c(r){const c=r.distance,u=r.index!==t.get();c&&(n.start(),o.add(c)),u&&(e.set(t.get()),t.set(r.index),i.emit("select"))}return{distance:function(n,t){c(r.byDistance(n,t))},index:function(n,e){const o=t.clone().set(n);c(r.byIndex(o.get(),e))}}}(dn,sn,an,hn,mn,c),xn=z(J,rn,Z,tn,un,F,j),bn={ownerDocument:r,ownerWindow:o,eventHandler:c,containerRect:$,slideRects:U,animation:dn,axis:G,direction:W,dragHandler:S(G,W,n,r,o,mn,w(G,o),pn,dn,yn,gn,hn,sn,c,Q,R,N,V,.68),eventStore:v(),percentOfView:Q,index:sn,indexPrevious:an,limit:un,location:pn,options:i,resizeHandler:E(t,e,G,c),scrollBody:gn,scrollBounds:O(un,pn,mn,gn,Q),scrollLooper:k(rn,un,pn,[pn,mn]),scrollProgress:A(un),scrollSnaps:cn,scrollTarget:hn,scrollTo:yn,slideLooper:T(G,W,J,rn,_,cn,xn,pn,e),slidesHandler:L(t,c),slidesInView:xn,slideIndexes:ln,slidesToScroll:nn,target:mn,translate:P(G,W,t)};return bn}const F={align:"center",axis:"x",container:null,slides:null,containScroll:null,direction:"ltr",slidesToScroll:1,breakpoints:{},dragFree:!1,dragThreshold:10,inViewThreshold:0,loop:!1,skipSnaps:!1,duration:25,startIndex:0,active:!0,watchDrag:!0,watchResize:!0,watchSlides:!0};function H(n){function t(n,t){return g(n,t||{})}const e={mergeOptions:t,optionsAtMedia:function(e){const r=e.breakpoints||{},o=m(r).filter((t=>n.matchMedia(t).matches)).map((n=>r[n])).reduce(((n,e)=>t(n,e)),{});return t(e,o)},optionsMediaQueries:function(t){return t.map((n=>m(n.breakpoints||{}))).reduce(((n,t)=>n.concat(t)),[]).map(n.matchMedia)}};return e}function R(n,t,e){const r=n.ownerDocument,o=r.defaultView,c=H(o),u=function(n){let t=[];return{init:function(e,r){return t=e.filter((({options:t})=>!1!==n.optionsAtMedia(t).active)),t.forEach((t=>t.init(r,n))),e.reduce(((n,t)=>Object.assign(n,{[t.name]:t})),{})},destroy:function(){t=t.filter((n=>n.destroy()))}}}(c),a=v(),l=v(),d=function(){const n={};let t;function e(t){return n[t]||[]}const r={init:function(n){t=n},emit:function(n){return e(n).forEach((e=>e(t,n))),r},off:function(t,o){return n[t]=e(t).filter((n=>n!==o)),r},on:function(t,o){return n[t]=e(t).concat([o]),r}};return r}(),{animationsList:f}=R,{mergeOptions:p,optionsAtMedia:m,optionsMediaQueries:g}=c,{on:h,off:y,emit:x}=d,b=P;let S,w,E,O,D=!1,k=p(F,R.globalOptions),A=p(k),M=[];function I(t,e){if(D)return;const c=f.find((n=>n.window===o)),h=c||function(n){const t=1e3/60;let e=[],r=null,o=0,i=0;function c(u){r||(r=u);const a=u-r;for(r=u,o+=a;o>=t;)e.forEach((({animation:n})=>n.update())),o-=t;const l=s(o/t);e.forEach((({animation:n})=>n.render(l))),i&&n.requestAnimationFrame(c)}return{start:function(t){e.includes(t)||e.push(t),i||(i=n.requestAnimationFrame(c))},stop:function(t){e=e.filter((n=>n!==t)),e.length||(n.cancelAnimationFrame(i),r=null,o=0,i=0)},reset:function(){r=null,o=0},window:n}}(o);if(c||f.push(h),k=p(k,t),A=m(k),function(){const{container:t,slides:e}=A,r=i(t)?n.querySelector(t):t;E=r||n.children[0];const o=i(e)?E.querySelectorAll(e):e;O=[].slice.call(o||E.children)}(),S=j(n,E,O,r,o,A,d,h),!A.active)return T();if(S.translate.to(S.location.get()),M=e||M,w=u.init(M,N),g([k,...M.map((({options:n})=>n))]).forEach((n=>a.add(n,"change",P))),S.eventHandler.init(N),S.resizeHandler.init(N,A.watchResize),S.slidesHandler.init(N,A.watchSlides),l.add(r,"visibilitychange",(()=>{r.hidden&&h.reset()})),A.loop){if(!S.slideLooper.canLoop())return T(),I({loop:!1},e),void(k=p(k,{loop:!0}));S.slideLooper.loop()}E.offsetParent&&O.length&&S.dragHandler.init(N,A.watchDrag)}function P(n,t){const e=B();T(),I(p({startIndex:e},n),t),d.emit("reInit")}function T(){S.dragHandler.destroy(),S.animation.stop(),S.eventStore.clear(),S.translate.clear(),S.slideLooper.clear(),S.resizeHandler.destroy(),S.slidesHandler.destroy(),u.destroy(),a.clear(),l.clear()}function L(n){const t=S[n?"target":"location"].get(),e=A.loop?"removeOffset":"constrain";return S.slidesInView.check(S.limit[e](t))}function z(n,t,e){A.active&&!D&&(S.scrollBody.useBaseFriction().useDuration(t?0:A.duration),S.scrollTo.index(n,e||0))}function B(){return S.index.get()}const N={canScrollNext:function(){return S.index.clone().add(1).get()!==B()},canScrollPrev:function(){return S.index.clone().add(-1).get()!==B()},containerNode:function(){return E},internalEngine:function(){return S},destroy:function(){D||(D=!0,a.clear(),T(),d.emit("destroy"))},off:y,on:h,emit:x,plugins:function(){return w},previousScrollSnap:function(){return S.indexPrevious.get()},reInit:b,rootNode:function(){return n},scrollNext:function(n){z(S.index.clone().add(1).get(),!0===n,-1)},scrollPrev:function(n){z(S.index.clone().add(-1).get(),!0===n,1)},scrollProgress:function(){return S.scrollProgress.get(S.location.get())},scrollSnapList:function(){return S.scrollSnaps.map(S.scrollProgress.get)},scrollTo:z,selectedScrollSnap:B,slideNodes:function(){return O},slidesInView:L,slidesNotInView:function(n){const t=L(n);return S.slideIndexes.filter((n=>!t.includes(n)))}};return I(t,e),setTimeout((()=>d.emit("init")),0),N}function N(t={},o=[]){const i=n.useRef(t),c=n.useRef(o),[u,s]=n.useState(),[a,l]=n.useState(),d=n.useCallback((()=>{u&&u.reInit(i.current,c.current)}),[u]);return n.useEffect((()=>{if("undefined"!=typeof window&&window.document&&window.document.createElement&&a){R.globalOptions=N.globalOptions;const n=R(a,i.current,c.current);return s(n),()=>n.destroy()}s(void 0)}),[a,s]),n.useEffect((()=>{e(i.current,t)||(i.current=t,d())}),[t,d]),n.useEffect((()=>{(function(n,t){if(n.length!==t.length)return!1;const o=r(n),i=r(t);return o.every(((n,t)=>e(n,i[t])))})(c.current,o)||(c.current=o,d())}),[o,d]),[l,u]}return R.animationsList=[],R.globalOptions=void 0,N.globalOptions=void 0,N}));

I would very much appreciate if you could test the following cases:

  • Drag events.
  • Resize events and options using breakpoints as demonstrated here.
  • Try the above in different browsers.
  • Any other things to test that you can can think of that's relevant.

Best,
David

@slpy9
Copy link
Author

slpy9 commented May 17, 2023

Hey @davidjerleke,

I am using React on the backend, and plain JavaScript (CDN) on the frontend. The iframe only exists on the backend side of things as it's part of the WordPress site editor.

Are you able to provide some React compatible code?

Thankyou.

@davidjerleke
Copy link
Owner

@slpy9 sure, I updated my previous comment and added embla-carousel-react. Just toggle open the script.

@slpy9
Copy link
Author

slpy9 commented May 18, 2023

Thanks David,

I encountered a bug when trying to drag:

export function isMouseEvent(evt: PointerEventType): evt is MouseEvent {
return typeof MouseEvent !== 'undefined' && evt instanceof MouseEvent

This was returning false, so my mouse interactions were being treated as touch events and causing a script error. Reading through the MDN docs, instanceof appears to have issues with iframe's too and they recommend the familiar workaround of ownerDocument.defaultView.

Other than that.. I've done some testing in Chrome & Firefox, dragging, resizing and breakpoint options all appear to be working as intended.

@davidjerleke
Copy link
Owner

Hi again @slpy9,

Thanks a lot fot pointing me to the problem. That's very helpful. I've updated both scripts with the workaround now so please give it a go and see if the script error is gone.

@deysan are you intending to test the scripts too?

Best,
David

@davidjerleke
Copy link
Owner

davidjerleke commented May 19, 2023

Specification

  • Refactor Embla to work properly in different realms - iframes/windows.
  • At the time of writing, each carousel starts a separate animation loop by calling requestAnimationFrame.
  • All carousels within the same realm should share the same animation loop.

@davidjerleke davidjerleke linked a pull request May 19, 2023 that will close this issue
@slpy9
Copy link
Author

slpy9 commented May 19, 2023

It's working great on my end @davidjerleke, appreciate all the work you've been putting into this and looking forward to your next release, thanks!

@davidjerleke davidjerleke added upcoming A feature or bug fix is on its way for this issue and removed investigating Issue is being looked into labels May 19, 2023
davidjerleke added a commit that referenced this issue May 20, 2023
Add support for multiple realms
@davidjerleke davidjerleke added resolved This issue is resolved and removed upcoming A feature or bug fix is on its way for this issue labels May 20, 2023
@davidjerleke
Copy link
Owner

@slpy9, I just released this feature with v8.0.0-rc04. Thanks a bunch for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request resolved This issue is resolved
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants