UNPKG

@blossom-carousel/vue

Version:

A native-scroll-first carousel component for Vue.

1 lines 11.4 kB
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("vue")):typeof define==`function`&&define.amd?define([`exports`,`vue`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.BlossomCarousel={},e.Vue))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function n(e){return getComputedStyle(e).direction===`rtl`}function r(e,t){return t?-e.scrollLeft:e.scrollLeft}function i(e){if(!e||e===`none`)return`none`;let t=e.trim().split(/\s+/),n=t.length===2?t[1]:t[0];return n===`center`||n===`end`?n:`start`}function a(e){let t=i(e);return t===`none`?`start`:t}function o(e,t,n,i,a,o,s,c=getComputedStyle(t)){let l=t.getBoundingClientRect(),u=(s?i.right-l.right:l.left-i.left)+r(e,s),d=parseFloat(c.scrollMarginInlineStart)||0,f=parseFloat(c.scrollMarginInlineEnd)||0,p=u-d,m=u+t.clientWidth+f,h=e.clientWidth;switch(n){case`end`:return m-h+o;case`center`:return(p+m)/2-h/2;default:return p-a}}function s(e){return e.map(e=>({el:e,align:a(getComputedStyle(e).scrollSnapAlign)}))}function c(e){let t=e.getBoundingClientRect(),n=getComputedStyle(e),r=n.direction===`rtl`,a=parseFloat(n.scrollPaddingInlineStart)||0,s=parseFloat(n.scrollPaddingInlineEnd)||0,c=Math.max(e.scrollWidth-e.clientWidth,0),l=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),u=[],d=l.nextNode();for(;d;){let n=d,f=getComputedStyle(n),p=i(f.scrollSnapAlign);if(p!==`none`){let i=o(e,n,p,t,a,s,r,f);u.push({el:n,align:p,x:Math.min(Math.max(i,0),c)})}d=l.nextNode()}return u.sort((e,t)=>e.x-t.x),u.reduce((e,t)=>((e.length===0||Math.abs(e[e.length-1].x-t.x)>1)&&e.push(t),e),[])}var l=new WeakMap;function u(e,t){l.set(e,t)}function d(e){return l.get(e)}function f(e){l.delete(e)}var p=.85,m=1;function h(e,t){let n=Math.max(e.scrollWidth-e.clientWidth,0),r=Math.abs(e.scrollLeft);return t===`prev`?r>m:r<n-m}function g(e,t,n){if(n===`next`){for(let n=0;n<e.length;n++)if(e[n].x>t+m&&e[n].el.isConnected)return e[n]}else for(let n=e.length-1;n>=0;n--)if(e[n].x<t-m&&e[n].el.isConnected)return e[n];return null}function _(e,t){let i=d(e),a=i?.pages??c(e),o=i?.rtl??n(e);if(a.length){let n=g(a,r(e,o),t);if(!n)return;n.el.scrollIntoView({block:`nearest`,inline:n.align,behavior:`smooth`});return}let s=e.clientWidth*p*(t===`next`?1:-1);e.scrollBy({left:o?-s:s,behavior:`smooth`})}var v=`[data-blossom-slide]`,y=1;function b(e){return Array.from(e.querySelectorAll(v))}function x(e,t){let n=e.clientWidth,r=e.scrollWidth-n,a=e.getBoundingClientRect(),s=getComputedStyle(e),c=s.direction===`rtl`,l=parseFloat(s.scrollPaddingInlineStart)||0,u=parseFloat(s.scrollPaddingInlineEnd)||0,d=t.map(t=>{let n=getComputedStyle(t),r=i(n.scrollSnapAlign);return o(e,t,r===`none`?`start`:r,a,l,u,c,n)});if(r>0){let e=Math.min(n/8,r/2),t=d.filter(t=>t<e);if(t.length>0){let n=Math.min(...t),r=e-n;if(r>0)for(let t=0;t<d.length;t++)d[t]<e&&(d[t]=(d[t]-n)/r*e)}let i=r-e,a=d.filter(e=>e>i);if(a.length>0){let t=Math.max(...a)-i;if(t>0)for(let n=0;n<d.length;n++)d[n]>i&&(d[n]=(d[n]-i)/t*e+i)}}return d}function S(e,t,n,r=[...e].sort((e,t)=>e-t)){if(e.length===0)return-1;if(e.length===1)return 0;let i=n/2,a=null;for(let e=0;e<r.length;e++){let n=r[e],o=e>0?r[e-1]:-1/0;(n<=t+y||o<t-i&&n<t+i)&&(a=n)}a===null&&(a=r[0]);for(let t=0;t<e.length;t++)if(Math.abs(e[t]-a)<=y)return t;return 0}function C(e,t,i){if(t.length===0)return-1;if(t.length===1)return 0;let a=e.clientWidth;if(e.scrollWidth-a<=0)return 0;let o=i?.rtl??n(e);return S(i?.activePositions??x(e,t),r(e,o),a,i?.sortedActivePositions)}var w=`--blossom-`,T={prev:`${w}prev`,next:`${w}next`,gotoPrefix:`${w}goto-`},E=Symbol.for(`blossom-carousel.navigation.registry`);function D(e,t){if(t===T.prev)_(e,`prev`);else if(t===T.next)_(e,`next`);else if(t.startsWith(T.gotoPrefix)){let n=Number.parseInt(t.slice(T.gotoPrefix.length),10);if(Number.isNaN(n)||n<0)return;let r=d(e)?.markers[n],i=r?.el.isConnected?r:void 0,o=i?.el??b(e)[n];if(!o)return;let s=i?.align??a(getComputedStyle(o).scrollSnapAlign);o.scrollIntoView({block:`nearest`,inline:s,behavior:`smooth`})}}function O(e){j();let t=e,n=t[E];if(n)return n.count++,()=>k(t);let r=t=>{let n=t.command??t.detail?.command;typeof n==`string`&&n.startsWith(w)&&D(e,n)};return e.addEventListener(`command`,r),t[E]={count:1,handler:r},()=>k(t)}function k(e){let t=e[E];t&&(t.count--,t.count<=0&&(e.removeEventListener(`command`,t.handler),delete e[E]))}var A=!1;function j(){A||typeof document>`u`||(A=!0,!(typeof HTMLButtonElement<`u`&&`commandForElement`in HTMLButtonElement.prototype)&&document.addEventListener(`click`,e=>{let t=e.target?.closest?.(`button[commandfor]`);if(!t)return;let n=t.getAttribute(`commandfor`),r=t.getAttribute(`command`);!n||!r||document.getElementById(n)?.dispatchEvent(new CustomEvent(`command`,{bubbles:!1,detail:{command:r}}))}))}function ee(e){let t=d(e),n=t?.targets??b(e);return{count:n.length,activeIndex:C(e,n,t),canPrev:h(e,`prev`),canNext:h(e,`next`)}}function M(e){let t=b(e),r=x(e,t);u(e,{targets:t,markers:s(t),pages:c(e),activePositions:r,sortedActivePositions:[...r].sort((e,t)=>e-t),rtl:n(e)})}var N=Symbol.for(`blossom-carousel.navigation.observers`);function P(e){let t=new Set,n=0,r=!0,i=()=>{cancelAnimationFrame(n),n=requestAnimationFrame(()=>{r&&(r=!1,M(e));let n=ee(e);for(let e of t)e(n)})},a=()=>i(),o=()=>{r=!0,i()};e.addEventListener(`scroll`,a,{passive:!0}),e.addEventListener(`scrollend`,a,{passive:!0});let s=new ResizeObserver(o);s.observe(e);let c=new MutationObserver(o);return c.observe(e,{childList:!0,subtree:!0}),{subscribers:t,flush:i,teardown:()=>{cancelAnimationFrame(n),e.removeEventListener(`scroll`,a),e.removeEventListener(`scrollend`,a),s.disconnect(),c.disconnect(),f(e)}}}function F(e,t){let n=e,r=n[N]??P(e);return n[N]=r,r.subscribers.add(t),r.flush(),()=>{let e=n[N];e&&(e.subscribers.delete(t),e.subscribers.size===0&&(e.teardown(),delete n[N]))}}var I=Symbol.for(`blossom-carousel.slideCounts`);function L(e){let t=e;return t[I]||(t[I]=new Map),t[I]}function R(e,t,n){L(e).set(t,n)}function z(e,t){return t?L(e).get(t)??0:0}var B={activeIndex:-1,count:0,canPrev:!1,canNext:!1};function V(e){let n=(0,t.getCurrentInstance)()?.appContext.app;function r(e){let t=n?z(n,e):0;return{...B,count:t}}let i=(0,t.ref)(r(e.value)),a=null,o=!1;function s(){a?.(),a=null}function c(e){if(s(),i.value=r(e),!e||typeof document>`u`)return;let t=document.getElementById(e);if(!t)return;let n=O(t),o=F(t,e=>{i.value=e});a=()=>{n(),o()}}return(0,t.watch)(e,e=>{if(o){c(e);return}i.value=r(e)},{flush:`sync`}),(0,t.onMounted)(()=>{o=!0,c(e.value)}),(0,t.onBeforeUnmount)(s),i}function H(e){return e?`data-blossom-slide`in e||`dataBlossomSlide`in e:!1}function U(e){let{children:n}=e;if(!n)return[];if(Array.isArray(n))return n.filter(t.isVNode);if(typeof n==`object`&&`default`in n){let e=n.default;if(typeof e==`function`)return e().filter(t.isVNode)}return[]}function W(e){let n=0;for(let r of e)!(0,t.isVNode)(r)||r.type===t.Comment||(H(r.props)&&n++,(r.type===t.Fragment||r.children)&&(n+=W(U(r))));return n}function G(e){return W(e)}var K=(0,t.defineComponent)({__name:`BlossomCarousel`,props:{as:{type:String,default:`div`},repeat:{type:Boolean,default:!1},load:{type:String,default:`conditional`}},setup(e,{expose:n}){let r=e,i=null,a=(0,t.shallowRef)(null),o=(0,t.useAttrs)(),s=(0,t.useSlots)(),c=(0,t.getCurrentInstance)().appContext.app;return(0,t.watchEffect)(()=>{let e=o.id;if(!e)return;let t=s.default?.()??[];R(c,e,G(t))}),n({el:a,prev:()=>i?.prev({align:`center`}),next:()=>i?.next({align:`center`})}),(0,t.onMounted)(async()=>{if(!window.matchMedia(`(hover: hover) and (pointer: fine)`).matches&&r.load!==`always`)return;let{Blossom:e}=await import(`@blossom-carousel/core`);a.value&&(i=e(a.value,{repeat:r.repeat}),i.init())}),(0,t.onBeforeUnmount)(()=>{i?.destroy()}),(n,r)=>((0,t.openBlock)(),(0,t.createBlock)((0,t.resolveDynamicComponent)(e.as),{ref_key:`root`,ref:a,"blossom-carousel":`true`},{default:(0,t.withCtx)(()=>[(0,t.renderSlot)(n.$slots,`default`)]),_:3},512))}}),q=[`command`,`commandfor`,`disabled`,`aria-controls`],J=(0,t.defineComponent)({__name:`BlossomPrev`,props:{for:{}},setup(e){let n=e,r=T.prev,i=V((0,t.toRef)(n,`for`));return(e,a)=>((0,t.openBlock)(),(0,t.createElementBlock)(`button`,{"blossom-prev":``,type:`button`,command:(0,t.unref)(r),commandfor:n.for,disabled:!(0,t.unref)(i).canPrev,"aria-controls":n.for,"aria-label":`Previous slide`},[(0,t.renderSlot)(e.$slots,`default`,{},()=>[a[0]||=(0,t.createTextVNode)(`‹`,-1)],!0)],8,q))}}),Y=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},X=Y(J,[[`__scopeId`,`data-v-9ec68549`]]),Z=[`command`,`commandfor`,`disabled`,`aria-controls`],Q=Y((0,t.defineComponent)({__name:`BlossomNext`,props:{for:{}},setup(e){let n=e,r=T.next,i=V((0,t.toRef)(n,`for`));return(e,a)=>((0,t.openBlock)(),(0,t.createElementBlock)(`button`,{"blossom-next":``,type:`button`,command:(0,t.unref)(r),commandfor:n.for,disabled:!(0,t.unref)(i).canNext,"aria-controls":n.for,"aria-label":`Next slide`},[(0,t.renderSlot)(e.$slots,`default`,{},()=>[a[0]||=(0,t.createTextVNode)(`›`,-1)],!0)],8,Z))}}),[[`__scopeId`,`data-v-a15f52e2`]]),$=Symbol(`blossom-dot`),te=(0,t.defineComponent)({__name:`DotScope`,props:{index:{},active:{type:Boolean},forId:{}},setup(e){return(0,t.provide)($,e),(e,n)=>(0,t.renderSlot)(e.$slots,`default`)}}),ne=[`command`,`commandfor`,`aria-controls`,`aria-current`,`aria-label`],re=(0,t.defineComponent)({inheritAttrs:!1,__name:`BlossomDots`,props:{for:{}},setup(e){let n=e,r=(0,t.useSlots)(),i=T.gotoPrefix,a=V((0,t.toRef)(n,`for`));function o(){return(r.default?.({index:0,active:!1})??[]).some(e=>e.type!==t.Comment)}return(e,r)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,(0,t.mergeProps)({"data-blossom-dots":``,role:`group`,"aria-label":`Choose slide to display`},e.$attrs),[o()?((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,{key:0},(0,t.renderList)((0,t.unref)(a).count,(r,i)=>((0,t.openBlock)(),(0,t.createBlock)(te,{key:`dot-${i}`,index:i,active:(0,t.unref)(a).activeIndex===i,"for-id":n.for},{default:(0,t.withCtx)(()=>[(0,t.renderSlot)(e.$slots,`default`,{index:i,active:(0,t.unref)(a).activeIndex===i})]),_:2},1032,[`index`,`active`,`for-id`]))),128)):((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,{key:1},(0,t.renderList)((0,t.unref)(a).count,(e,o)=>((0,t.openBlock)(),(0,t.createElementBlock)(`button`,{key:`dot-${o}`,type:`button`,"data-blossom-dot":``,command:`${(0,t.unref)(i)}${o}`,commandfor:n.for,"aria-controls":n.for,"aria-current":(0,t.unref)(a).activeIndex===o,"aria-label":`Go to slide ${o+1}`},[...r[0]||=[(0,t.createElementVNode)(`span`,{"data-blossom-dot-marker":``},null,-1)]],8,ne))),128))],16))}}),ie=[`command`,`commandfor`,`aria-controls`,`aria-current`,`aria-label`],ae=(0,t.defineComponent)({inheritAttrs:!1,__name:`BlossomDot`,setup(e){let n=(0,t.inject)($);return n||console.warn(`[BlossomDot] Must be used inside a BlossomDots slot.`),(e,r)=>((0,t.openBlock)(),(0,t.createElementBlock)(`button`,(0,t.mergeProps)({type:`button`,"data-blossom-dot":``,command:`${(0,t.unref)(T).gotoPrefix}${(0,t.unref)(n)?.index??0}`,commandfor:(0,t.unref)(n)?.forId??``,"aria-controls":(0,t.unref)(n)?.forId,"aria-current":(0,t.unref)(n)?.active??!1,"aria-label":(0,t.unref)(n)?`Go to slide ${(0,t.unref)(n).index+1}`:void 0},e.$attrs),[(0,t.renderSlot)(e.$slots,`default`)],16,ie))}});e.BlossomCarousel=K,e.BlossomDot=ae,e.BlossomDots=re,e.BlossomNext=Q,e.BlossomPrev=X});