use-snap-slider 0.0.5 → 0.0.6

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.
@@ -1,2 +1,2 @@
1
1
  "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const q=(f,u)=>{let h,r,a;return function(){const v=this,p=arguments;h?(clearTimeout(r),r=setTimeout(()=>{Date.now()-a>=u&&(f.apply(v,p),a=Date.now())},Math.max(u-(Date.now()-a),0))):(f.apply(v,p),a=Date.now(),h=!0)}};function C({element:f,count:u=1,countDelta:h,index:r=0,circular:a,indexDelta:v,initalSubscriptionPublish:p=!0,itemSelector:A=":scope > *"}){let T=r,c={index:r,indexDelta:v||r,count:u,countDelta:h||u},m=r,i=1,D=[],b=!1,x=0,n;function W(){if(n){const t=n.scrollLeft,{indexDelta:e}=c;if(x=e*(n.offsetWidth/i),m!==e){const o=Math.abs(t-x),l=n.offsetWidth*2;m=e,b=!0;const s=o>l?"instant":"smooth";n.scroll({left:x,top:0,behavior:s})}else T&&(b=!0,n.scroll({left:x,top:0,behavior:"instant"}),T=void 0)}}let P=!1,d=[];const O=t=>(d.push(t),n&&(P||p)&&t(S()),()=>{d=d.filter(e=>e!==t),d.length<1&&I()});function R(){d.forEach(t=>{t(S())})}const S=()=>{const{indexDelta:t,countDelta:e}=c;return{...c,prevEnabled:a||t>0,nextEnabled:a||e-i>t}};function g(t){let e=!1,o=!1;Object.keys(t).forEach(s=>{c[s]!==t[s]&&(c[s]=Number(t[s]),e=!0,s==="indexDelta"&&(o=!0))}),e&&(P=d.length===0,R(),o&&W())}function y(t){const{index:e,indexDelta:o}=t,{countDelta:l,count:s}=c,L=l-i;return{index:o<L?e:s-1,indexDelta:o}}function M(){if(n){let t=0,e=0;D=[],n.querySelectorAll(A).forEach(N=>{D.push(t),t+=N.clientWidth,e=N.clientWidth}),i=Math.round(n.offsetWidth/e);const o=D.length,l=Math.ceil(o/i),{index:s}=c,L=s+1>l?{index:0,indexDelta:0}:{};g({count:l,countDelta:o,...L})}}let E=!1;function B(){if(!E&&n){const t=n.scrollLeft;window.requestAnimationFrame(()=>{if(b)Math.abs(x-t)<2&&(b=!1);else{const e=D.reduce((l,s)=>Math.abs(s-t)<Math.abs(l-t)?s:l),o=D.findIndex(l=>l===e);m=o,g(y({index:Math.floor(o/i),indexDelta:o}))}E=!1}),E=!0}}const F=q(B,200),j=q(M,500);function z(t){n&&I(),n=t,W(),M(),n==null||n.addEventListener("scroll",F),window.addEventListener("resize",j)}f&&z(f);const w=function(t,e){e!==void 0&&g(y({index:Math.floor(e/i),indexDelta:e})),t!==void 0&&g(y({index:t,indexDelta:t*i}))},I=()=>{n==null||n.removeEventListener("scroll",F),window.removeEventListener("resize",j)};return{destroy:I,getState:S,subscribe:O,jumpTo:w,setElement:z,calculate:M,goNext:()=>{const{countDelta:t,indexDelta:e}=c,o=t-i,l=e+i<=o?e+i:a&&e===o?0:o;w(void 0,l)},goPrev:()=>{const{indexDelta:t,countDelta:e}=c,o=e-i,l=t-i>=0?t-i:a&&t===0?o:0;w(void 0,l)}}}exports.createSnapSlider=C;
2
- //# sourceMappingURL=snap-slider.cjs.js.map
2
+ //# sourceMappingURL=snap-slider.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snap-slider.cjs","sources":["../src/lib/throttle.ts","../src/lib/snap-slider.ts"],"sourcesContent":["export const throttle = (fn: Function, wait: number) => {\n let inThrottle: boolean\n let lastFn: ReturnType<typeof setTimeout>\n let lastTime: number\n return function (this: any) {\n const context = this\n const args = arguments\n if (!inThrottle) {\n fn.apply(context, args)\n lastTime = Date.now()\n inThrottle = true\n } else {\n clearTimeout(lastFn)\n lastFn = setTimeout(() => {\n if (Date.now() - lastTime >= wait) {\n fn.apply(context, args)\n lastTime = Date.now()\n }\n }, Math.max(wait - (Date.now() - lastTime), 0))\n }\n }\n}\n","import { throttle } from './throttle'\n\nexport interface TSnapListnerStateIndex {\n index: number\n indexDelta: number\n}\n\nexport interface TSnapSliderState extends TSnapListnerStateIndex {\n count: number\n countDelta: number\n}\n\ninterface TSnapSliderStateUpdate {\n index?: number\n indexDelta?: number\n count?: number\n countDelta?: number\n}\n\nexport interface TSnapSliderStateFull extends TSnapSliderState {\n prevEnabled: boolean\n nextEnabled: boolean\n}\n\nexport type TSnapListner = (params: TSnapSliderStateFull) => void\n\nexport interface TSnapSliderParams extends TSnapSliderStateUpdate {\n element: HTMLElement | null\n itemSelector?: string\n initalSubscriptionPublish?: boolean\n circular?: boolean\n}\n\nexport type TSnapSliderJumpToFn = (index?: number, indexDelta?: number) => void\n\nexport interface TSnapSlider {\n destroy: () => void\n getState: () => TSnapSliderStateFull\n jumpTo: TSnapSliderJumpToFn\n goNext: () => void\n goPrev: () => void\n subscribe: (fn: TSnapListner) => () => void\n setElement: (el: HTMLElement) => void\n calculate: () => void\n}\n\nexport function createSnapSlider({\n element: _element,\n count = 1,\n countDelta,\n index = 0,\n circular,\n indexDelta,\n initalSubscriptionPublish = true,\n itemSelector = ':scope > *',\n}: TSnapSliderParams): TSnapSlider {\n let initalIndex: number | undefined = index\n let state: TSnapSliderState = {\n index,\n indexDelta: indexDelta || index,\n count,\n countDelta: countDelta || count,\n }\n let prevIndexDelta: number = index\n let slidesPerPage: number = 1\n let itemPositions: number[] = []\n let muteScrollListner: boolean = false\n let left: number = 0\n let element: HTMLElement | null\n function updateIndexDelta() {\n if (element) {\n const prev = element.scrollLeft\n const { indexDelta } = state\n left = indexDelta * (element.offsetWidth / slidesPerPage)\n if (prevIndexDelta !== indexDelta) {\n const distance = Math.abs(prev - left)\n const limitInstantScroll = element.offsetWidth * 2\n prevIndexDelta = indexDelta\n muteScrollListner = true\n // @ts-expect-error [mildly irritated message]\n const behavior: ScrollBehavior =\n distance > limitInstantScroll ? 'instant' : 'smooth'\n element.scroll({\n left,\n top: 0,\n behavior,\n })\n } else {\n if (initalIndex) {\n muteScrollListner = true\n element.scroll({\n left,\n top: 0,\n // @ts-expect-error [mildly irritated message]\n behavior: 'instant',\n })\n initalIndex = undefined\n }\n }\n }\n }\n\n let publishDirty = false\n let listeners: TSnapListner[] = []\n const subscribe = (callback: TSnapListner) => {\n listeners.push(callback)\n if (element && (publishDirty || initalSubscriptionPublish)) {\n callback(getState())\n }\n return () => {\n listeners = listeners.filter((x) => x !== callback)\n if (listeners.length < 1) {\n destroy()\n }\n }\n }\n function notify() {\n listeners.forEach((callback) => {\n callback(getState())\n })\n }\n const getState = (): TSnapSliderStateFull => {\n const { indexDelta, countDelta } = state\n return {\n ...state,\n prevEnabled: circular || indexDelta > 0,\n nextEnabled: circular || countDelta - slidesPerPage > indexDelta,\n }\n }\n function update(params: TSnapSliderStateUpdate) {\n let dirty = false\n let indexDeltaDirty = false\n type TSnapSliderStateUpdateKey = keyof typeof params\n const keys: TSnapSliderStateUpdateKey[] = Object.keys(\n params\n ) as Array<TSnapSliderStateUpdateKey>\n keys.forEach((key) => {\n if (state[key] !== params[key]) {\n state[key] = Number(params[key])\n dirty = true\n if (key === 'indexDelta') {\n indexDeltaDirty = true\n }\n }\n })\n if (dirty) {\n publishDirty = listeners.length === 0\n notify()\n if (indexDeltaDirty) {\n updateIndexDelta()\n }\n }\n }\n function fixIndex(nextIndex: TSnapListnerStateIndex): TSnapListnerStateIndex {\n const { index, indexDelta } = nextIndex\n const { countDelta, count } = state\n const last = countDelta - slidesPerPage\n return {\n index: indexDelta < last ? index : count - 1,\n indexDelta,\n }\n }\n function calculate() {\n if (element) {\n let contentWidth = 0\n let itemWidth = 0\n itemPositions = []\n element.querySelectorAll(itemSelector).forEach((slide) => {\n itemPositions.push(contentWidth)\n contentWidth += slide.clientWidth\n itemWidth = slide.clientWidth\n })\n slidesPerPage = Math.round(element.offsetWidth / itemWidth)\n const countDelta = itemPositions.length\n const count = Math.ceil(countDelta / slidesPerPage)\n const { index } = state\n const resetIndexMayby =\n index + 1 > count\n ? {\n index: 0,\n indexDelta: 0,\n }\n : {}\n update({\n count,\n countDelta,\n ...resetIndexMayby,\n })\n }\n }\n\n let ticking = false\n function onScroll() {\n if (!ticking && element) {\n const scrollLeft = element.scrollLeft\n window.requestAnimationFrame(() => {\n if (muteScrollListner) {\n const leftToScroll = Math.abs(left - scrollLeft)\n if (leftToScroll < 2) {\n muteScrollListner = false\n }\n } else {\n const positionItem = itemPositions.reduce((prev, curr) => {\n return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft)\n ? curr\n : prev\n })\n const indexDelta = itemPositions.findIndex((x) => x === positionItem)\n prevIndexDelta = indexDelta\n update(\n fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n })\n )\n }\n ticking = false\n })\n ticking = true\n }\n }\n const onScrollFn = throttle(onScroll, 200)\n const onResizeFn = throttle(calculate, 500)\n function setElement(_el: HTMLElement) {\n if (element) {\n destroy()\n }\n element = _el\n updateIndexDelta()\n calculate()\n element?.addEventListener('scroll', onScrollFn)\n window.addEventListener('resize', onResizeFn)\n }\n _element && setElement(_element)\n const jumpTo: TSnapSliderJumpToFn = function (index, indexDelta) {\n if (indexDelta !== undefined) {\n update(\n fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n })\n )\n }\n if (index !== undefined) {\n update(\n fixIndex({\n index,\n indexDelta: index * slidesPerPage,\n })\n )\n }\n }\n const destroy = () => {\n element?.removeEventListener('scroll', onScrollFn)\n window.removeEventListener('resize', onResizeFn)\n }\n const goNext = () => {\n const { countDelta, indexDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta + slidesPerPage <= last\n ? indexDelta + slidesPerPage\n : circular && indexDelta === last\n ? 0\n : last\n jumpTo(undefined, next)\n }\n const goPrev = () => {\n const { indexDelta, countDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta - slidesPerPage >= 0\n ? indexDelta - slidesPerPage\n : circular && indexDelta === 0\n ? last\n : 0\n jumpTo(undefined, next)\n }\n return {\n destroy,\n getState,\n subscribe,\n jumpTo,\n setElement,\n calculate,\n goNext,\n goPrev,\n }\n}\n"],"names":["throttle","fn","wait","inThrottle","lastFn","lastTime","context","args","createSnapSlider","_element","count","countDelta","index","circular","indexDelta","initalSubscriptionPublish","itemSelector","initalIndex","state","prevIndexDelta","slidesPerPage","itemPositions","muteScrollListner","left","element","updateIndexDelta","prev","distance","limitInstantScroll","behavior","publishDirty","listeners","subscribe","callback","getState","x","destroy","notify","update","params","dirty","indexDeltaDirty","key","fixIndex","nextIndex","last","calculate","contentWidth","itemWidth","slide","resetIndexMayby","ticking","onScroll","scrollLeft","positionItem","curr","onScrollFn","onResizeFn","setElement","_el","jumpTo","next"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),f=require("./snap-slider.cjs");function p(u,n=1,c=0,o=!1,i){const[,s]=t.useState(0),r=t.useRef(),[e]=t.useState(()=>f.createSnapSlider({element:u.current,count:n,index:c,circular:o,initalSubscriptionPublish:!1})),a=e.getState();return t.useEffect(()=>{r.current&&(e.jumpTo(0),e.calculate())},[n,i,e]),t.useEffect(()=>{r.current=!0,u.current&&e.setElement(u.current);const l=e.subscribe(()=>{r.current&&s(S=>S+1)});return()=>{r.current=!1,l()}},[e,s]),{...a,jumpTo:e.jumpTo,goNext:e.goNext,goPrev:e.goPrev}}exports.useSnapSlider=p;
2
+ //# sourceMappingURL=use-snap-slider.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-snap-slider.cjs","sources":["../src/lib/use-snap-slider.ts"],"sourcesContent":["import { MutableRefObject, useEffect, useRef, useState } from 'react'\nimport { createSnapSlider, TSnapSliderStateFull } from './snap-slider'\n\nexport interface TUseSnapSlider extends TSnapSliderStateFull {\n jumpTo: (index: number) => void\n goNext: () => void\n goPrev: () => void\n}\n\nexport function useSnapSlider(\n ref: MutableRefObject<HTMLDivElement | null>,\n count: number = 1,\n index: number = 0,\n circular = false,\n countHash?: string | number\n): TUseSnapSlider {\n const [, forceUpdate] = useState<number>(0)\n const mountedRef = useRef<boolean>()\n const [observer] = useState(() =>\n createSnapSlider({\n element: ref.current,\n count,\n index,\n circular,\n initalSubscriptionPublish: false,\n })\n )\n const result = observer.getState()\n useEffect(() => {\n if (mountedRef.current) {\n observer.jumpTo(0)\n observer.calculate()\n }\n }, [count, countHash, observer])\n useEffect(() => {\n mountedRef.current = true\n ref.current && observer.setElement(ref.current)\n const unsubscribe = observer.subscribe(() => {\n if (mountedRef.current) {\n forceUpdate((x) => x + 1)\n }\n })\n\n return () => {\n mountedRef.current = false\n unsubscribe()\n }\n }, [observer, forceUpdate])\n return {\n ...result,\n jumpTo: observer.jumpTo,\n goNext: observer.goNext,\n goPrev: observer.goPrev,\n }\n}\n"],"names":["useSnapSlider","ref","count","index","circular","countHash","forceUpdate","useState","mountedRef","useRef","observer","createSnapSlider","result","useEffect","unsubscribe","x"],"mappings":"wIASgB,SAAAA,EACdC,EACAC,EAAgB,EAChBC,EAAgB,EAChBC,EAAW,GACXC,EACgB,CAChB,KAAM,EAAGC,CAAW,EAAIC,WAAiB,CAAC,EACpCC,EAAaC,EAAAA,SACb,CAACC,CAAQ,EAAIH,EAAA,SAAS,IAC1BI,mBAAiB,CACf,QAASV,EAAI,QACb,MAAAC,EACA,MAAAC,EACA,SAAAC,EACA,0BAA2B,EAAA,CAC5B,CAAA,EAEGQ,EAASF,EAAS,WACxBG,OAAAA,EAAAA,UAAU,IAAM,CACVL,EAAW,UACbE,EAAS,OAAO,CAAC,EACjBA,EAAS,UAAU,EAEpB,EAAA,CAACR,EAAOG,EAAWK,CAAQ,CAAC,EAC/BG,EAAAA,UAAU,IAAM,CACdL,EAAW,QAAU,GACrBP,EAAI,SAAWS,EAAS,WAAWT,EAAI,OAAO,EACxC,MAAAa,EAAcJ,EAAS,UAAU,IAAM,CACvCF,EAAW,SACDF,EAACS,GAAMA,EAAI,CAAC,CAC1B,CACD,EAED,MAAO,IAAM,CACXP,EAAW,QAAU,GACTM,GAAA,CACd,EACC,CAACJ,EAAUJ,CAAW,CAAC,EACnB,CACL,GAAGM,EACH,OAAQF,EAAS,OACjB,OAAQA,EAAS,OACjB,OAAQA,EAAS,MAAA,CAErB"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "use-snap-slider",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "React hook to manage css snap sliders",
5
5
  "type": "module",
6
- "main": "./dist/use-snap-slider.cjs.js",
6
+ "main": "./dist/use-snap-slider.cjs",
7
7
  "module": "./dist/use-snap-slider.es.js",
8
8
  "types": "./dist/use-snap-slider.d.ts",
9
9
  "files": [
@@ -1 +0,0 @@
1
- {"version":3,"file":"snap-slider.cjs.js","sources":["../src/lib/throttle.ts","../src/lib/snap-slider.ts"],"sourcesContent":["export const throttle = (fn: Function, wait: number) => {\n let inThrottle: boolean\n let lastFn: ReturnType<typeof setTimeout>\n let lastTime: number\n return function (this: any) {\n const context = this\n const args = arguments\n if (!inThrottle) {\n fn.apply(context, args)\n lastTime = Date.now()\n inThrottle = true\n } else {\n clearTimeout(lastFn)\n lastFn = setTimeout(() => {\n if (Date.now() - lastTime >= wait) {\n fn.apply(context, args)\n lastTime = Date.now()\n }\n }, Math.max(wait - (Date.now() - lastTime), 0))\n }\n }\n}\n","import { throttle } from './throttle'\n\nexport interface TSnapListnerStateIndex {\n index: number\n indexDelta: number\n}\n\nexport interface TSnapSliderState extends TSnapListnerStateIndex {\n count: number\n countDelta: number\n}\n\ninterface TSnapSliderStateUpdate {\n index?: number\n indexDelta?: number\n count?: number\n countDelta?: number\n}\n\nexport interface TSnapSliderStateFull extends TSnapSliderState {\n prevEnabled: boolean\n nextEnabled: boolean\n}\n\nexport type TSnapListner = (params: TSnapSliderStateFull) => void\n\nexport interface TSnapSliderParams extends TSnapSliderStateUpdate {\n element: HTMLElement | null\n itemSelector?: string\n initalSubscriptionPublish?: boolean\n circular?: boolean\n}\n\nexport type TSnapSliderJumpToFn = (index?: number, indexDelta?: number) => void\n\nexport interface TSnapSlider {\n destroy: () => void\n getState: () => TSnapSliderStateFull\n jumpTo: TSnapSliderJumpToFn\n goNext: () => void\n goPrev: () => void\n subscribe: (fn: TSnapListner) => () => void\n setElement: (el: HTMLElement) => void\n calculate: () => void\n}\n\nexport function createSnapSlider({\n element: _element,\n count = 1,\n countDelta,\n index = 0,\n circular,\n indexDelta,\n initalSubscriptionPublish = true,\n itemSelector = ':scope > *',\n}: TSnapSliderParams): TSnapSlider {\n let initalIndex: number | undefined = index\n let state: TSnapSliderState = {\n index,\n indexDelta: indexDelta || index,\n count,\n countDelta: countDelta || count,\n }\n let prevIndexDelta: number = index\n let slidesPerPage: number = 1\n let itemPositions: number[] = []\n let muteScrollListner: boolean = false\n let left: number = 0\n let element: HTMLElement | null\n function updateIndexDelta() {\n if (element) {\n const prev = element.scrollLeft\n const { indexDelta } = state\n left = indexDelta * (element.offsetWidth / slidesPerPage)\n if (prevIndexDelta !== indexDelta) {\n const distance = Math.abs(prev - left)\n const limitInstantScroll = element.offsetWidth * 2\n prevIndexDelta = indexDelta\n muteScrollListner = true\n // @ts-expect-error [mildly irritated message]\n const behavior: ScrollBehavior =\n distance > limitInstantScroll ? 'instant' : 'smooth'\n element.scroll({\n left,\n top: 0,\n behavior,\n })\n } else {\n if (initalIndex) {\n muteScrollListner = true\n element.scroll({\n left,\n top: 0,\n // @ts-expect-error [mildly irritated message]\n behavior: 'instant',\n })\n initalIndex = undefined\n }\n }\n }\n }\n\n let publishDirty = false\n let listeners: TSnapListner[] = []\n const subscribe = (callback: TSnapListner) => {\n listeners.push(callback)\n if (element && (publishDirty || initalSubscriptionPublish)) {\n callback(getState())\n }\n return () => {\n listeners = listeners.filter((x) => x !== callback)\n if (listeners.length < 1) {\n destroy()\n }\n }\n }\n function notify() {\n listeners.forEach((callback) => {\n callback(getState())\n })\n }\n const getState = (): TSnapSliderStateFull => {\n const { indexDelta, countDelta } = state\n return {\n ...state,\n prevEnabled: circular || indexDelta > 0,\n nextEnabled: circular || countDelta - slidesPerPage > indexDelta,\n }\n }\n function update(params: TSnapSliderStateUpdate) {\n let dirty = false\n let indexDeltaDirty = false\n type TSnapSliderStateUpdateKey = keyof typeof params\n const keys: TSnapSliderStateUpdateKey[] = Object.keys(\n params\n ) as Array<TSnapSliderStateUpdateKey>\n keys.forEach((key) => {\n if (state[key] !== params[key]) {\n state[key] = Number(params[key])\n dirty = true\n if (key === 'indexDelta') {\n indexDeltaDirty = true\n }\n }\n })\n if (dirty) {\n publishDirty = listeners.length === 0\n notify()\n if (indexDeltaDirty) {\n updateIndexDelta()\n }\n }\n }\n function fixIndex(nextIndex: TSnapListnerStateIndex): TSnapListnerStateIndex {\n const { index, indexDelta } = nextIndex\n const { countDelta, count } = state\n const last = countDelta - slidesPerPage\n return {\n index: indexDelta < last ? index : count - 1,\n indexDelta,\n }\n }\n function calculate() {\n if (element) {\n let contentWidth = 0\n let itemWidth = 0\n itemPositions = []\n element.querySelectorAll(itemSelector).forEach((slide) => {\n itemPositions.push(contentWidth)\n contentWidth += slide.clientWidth\n itemWidth = slide.clientWidth\n })\n slidesPerPage = Math.round(element.offsetWidth / itemWidth)\n const countDelta = itemPositions.length\n const count = Math.ceil(countDelta / slidesPerPage)\n const { index } = state\n const resetIndexMayby =\n index + 1 > count\n ? {\n index: 0,\n indexDelta: 0,\n }\n : {}\n update({\n count,\n countDelta,\n ...resetIndexMayby,\n })\n }\n }\n\n let ticking = false\n function onScroll() {\n if (!ticking && element) {\n const scrollLeft = element.scrollLeft\n window.requestAnimationFrame(() => {\n if (muteScrollListner) {\n const leftToScroll = Math.abs(left - scrollLeft)\n if (leftToScroll < 2) {\n muteScrollListner = false\n }\n } else {\n const positionItem = itemPositions.reduce((prev, curr) => {\n return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft)\n ? curr\n : prev\n })\n const indexDelta = itemPositions.findIndex((x) => x === positionItem)\n prevIndexDelta = indexDelta\n update(\n fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n })\n )\n }\n ticking = false\n })\n ticking = true\n }\n }\n const onScrollFn = throttle(onScroll, 200)\n const onResizeFn = throttle(calculate, 500)\n function setElement(_el: HTMLElement) {\n if (element) {\n destroy()\n }\n element = _el\n updateIndexDelta()\n calculate()\n element?.addEventListener('scroll', onScrollFn)\n window.addEventListener('resize', onResizeFn)\n }\n _element && setElement(_element)\n const jumpTo: TSnapSliderJumpToFn = function (index, indexDelta) {\n if (indexDelta !== undefined) {\n update(\n fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n })\n )\n }\n if (index !== undefined) {\n update(\n fixIndex({\n index,\n indexDelta: index * slidesPerPage,\n })\n )\n }\n }\n const destroy = () => {\n element?.removeEventListener('scroll', onScrollFn)\n window.removeEventListener('resize', onResizeFn)\n }\n const goNext = () => {\n const { countDelta, indexDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta + slidesPerPage <= last\n ? indexDelta + slidesPerPage\n : circular && indexDelta === last\n ? 0\n : last\n jumpTo(undefined, next)\n }\n const goPrev = () => {\n const { indexDelta, countDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta - slidesPerPage >= 0\n ? indexDelta - slidesPerPage\n : circular && indexDelta === 0\n ? last\n : 0\n jumpTo(undefined, next)\n }\n return {\n destroy,\n getState,\n subscribe,\n jumpTo,\n setElement,\n calculate,\n goNext,\n goPrev,\n }\n}\n"],"names":["throttle","fn","wait","inThrottle","lastFn","lastTime","context","args","createSnapSlider","_element","count","countDelta","index","circular","indexDelta","initalSubscriptionPublish","itemSelector","initalIndex","state","prevIndexDelta","slidesPerPage","itemPositions","muteScrollListner","left","element","updateIndexDelta","prev","distance","limitInstantScroll","behavior","publishDirty","listeners","subscribe","callback","getState","x","destroy","notify","update","params","dirty","indexDeltaDirty","key","fixIndex","nextIndex","last","calculate","contentWidth","itemWidth","slide","resetIndexMayby","ticking","onScroll","scrollLeft","positionItem","curr","onScrollFn","onResizeFn","setElement","_el","jumpTo","next"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),f=require("./snap-slider.cjs.js");function p(u,n=1,c=0,o=!1,i){const[,s]=t.useState(0),r=t.useRef(),[e]=t.useState(()=>f.createSnapSlider({element:u.current,count:n,index:c,circular:o,initalSubscriptionPublish:!1})),a=e.getState();return t.useEffect(()=>{r.current&&(e.jumpTo(0),e.calculate())},[n,i,e]),t.useEffect(()=>{r.current=!0,u.current&&e.setElement(u.current);const l=e.subscribe(()=>{r.current&&s(S=>S+1)});return()=>{r.current=!1,l()}},[e,s]),{...a,jumpTo:e.jumpTo,goNext:e.goNext,goPrev:e.goPrev}}exports.useSnapSlider=p;
2
- //# sourceMappingURL=use-snap-slider.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-snap-slider.cjs.js","sources":["../src/lib/use-snap-slider.ts"],"sourcesContent":["import { MutableRefObject, useEffect, useRef, useState } from 'react'\nimport { createSnapSlider, TSnapSliderStateFull } from './snap-slider'\n\nexport interface TUseSnapSlider extends TSnapSliderStateFull {\n jumpTo: (index: number) => void\n goNext: () => void\n goPrev: () => void\n}\n\nexport function useSnapSlider(\n ref: MutableRefObject<HTMLDivElement | null>,\n count: number = 1,\n index: number = 0,\n circular = false,\n countHash?: string | number\n): TUseSnapSlider {\n const [, forceUpdate] = useState<number>(0)\n const mountedRef = useRef<boolean>()\n const [observer] = useState(() =>\n createSnapSlider({\n element: ref.current,\n count,\n index,\n circular,\n initalSubscriptionPublish: false,\n })\n )\n const result = observer.getState()\n useEffect(() => {\n if (mountedRef.current) {\n observer.jumpTo(0)\n observer.calculate()\n }\n }, [count, countHash, observer])\n useEffect(() => {\n mountedRef.current = true\n ref.current && observer.setElement(ref.current)\n const unsubscribe = observer.subscribe(() => {\n if (mountedRef.current) {\n forceUpdate((x) => x + 1)\n }\n })\n\n return () => {\n mountedRef.current = false\n unsubscribe()\n }\n }, [observer, forceUpdate])\n return {\n ...result,\n jumpTo: observer.jumpTo,\n goNext: observer.goNext,\n goPrev: observer.goPrev,\n }\n}\n"],"names":["useSnapSlider","ref","count","index","circular","countHash","forceUpdate","useState","mountedRef","useRef","observer","createSnapSlider","result","useEffect","unsubscribe","x"],"mappings":"2IASgB,SAAAA,EACdC,EACAC,EAAgB,EAChBC,EAAgB,EAChBC,EAAW,GACXC,EACgB,CAChB,KAAM,EAAGC,CAAW,EAAIC,WAAiB,CAAC,EACpCC,EAAaC,EAAAA,SACb,CAACC,CAAQ,EAAIH,EAAA,SAAS,IAC1BI,mBAAiB,CACf,QAASV,EAAI,QACb,MAAAC,EACA,MAAAC,EACA,SAAAC,EACA,0BAA2B,EAAA,CAC5B,CAAA,EAEGQ,EAASF,EAAS,WACxBG,OAAAA,EAAAA,UAAU,IAAM,CACVL,EAAW,UACbE,EAAS,OAAO,CAAC,EACjBA,EAAS,UAAU,EAEpB,EAAA,CAACR,EAAOG,EAAWK,CAAQ,CAAC,EAC/BG,EAAAA,UAAU,IAAM,CACdL,EAAW,QAAU,GACrBP,EAAI,SAAWS,EAAS,WAAWT,EAAI,OAAO,EACxC,MAAAa,EAAcJ,EAAS,UAAU,IAAM,CACvCF,EAAW,SACDF,EAACS,GAAMA,EAAI,CAAC,CAC1B,CACD,EAED,MAAO,IAAM,CACXP,EAAW,QAAU,GACTM,GAAA,CACd,EACC,CAACJ,EAAUJ,CAAW,CAAC,EACnB,CACL,GAAGM,EACH,OAAQF,EAAS,OACjB,OAAQA,EAAS,OACjB,OAAQA,EAAS,MAAA,CAErB"}