use-snap-slider 0.1.4 → 1.0.0
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/dist/snap-slider.cjs +64 -31
- package/dist/snap-slider.cjs.map +1 -1
- package/dist/snap-slider.d.ts +10 -5
- package/dist/snap-slider.es.js +64 -31
- package/dist/snap-slider.es.js.map +1 -1
- package/dist/use-snap-slider.cjs +2 -3
- package/dist/use-snap-slider.cjs.map +1 -1
- package/dist/use-snap-slider.d.ts +3 -3
- package/dist/use-snap-slider.es.js +2 -3
- package/dist/use-snap-slider.es.js.map +1 -1
- package/package.json +22 -20
package/dist/snap-slider.cjs
CHANGED
|
@@ -31,7 +31,10 @@ function createSnapSlider({
|
|
|
31
31
|
indexDelta,
|
|
32
32
|
initalSubscriptionPublish = true,
|
|
33
33
|
itemSelector = ":scope > *",
|
|
34
|
-
debug
|
|
34
|
+
debug,
|
|
35
|
+
scrollTimeThrottle = 500,
|
|
36
|
+
resizeTimeThrottle = 500,
|
|
37
|
+
scrollListenerThreshold = 2
|
|
35
38
|
}) {
|
|
36
39
|
let initalIndex = index;
|
|
37
40
|
let state = {
|
|
@@ -175,40 +178,42 @@ function createSnapSlider({
|
|
|
175
178
|
}
|
|
176
179
|
}
|
|
177
180
|
}
|
|
178
|
-
let ticking = false;
|
|
179
181
|
function onScroll() {
|
|
180
|
-
if (
|
|
182
|
+
if (element) {
|
|
181
183
|
const scrollLeft = element.scrollLeft;
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
if (muteScrollListner) {
|
|
185
|
+
const leftToScroll = Math.abs(left - scrollLeft);
|
|
186
|
+
if (leftToScroll < 2) {
|
|
187
|
+
muteScrollListner = false;
|
|
188
|
+
}
|
|
189
|
+
} else {
|
|
190
|
+
const positionItem = itemPositions.reduce((prev, curr) => {
|
|
191
|
+
return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft) ? curr : prev;
|
|
192
|
+
});
|
|
193
|
+
const indexDelta2 = itemPositions.findIndex((x) => x === positionItem);
|
|
194
|
+
const pxLeftScrolling = Math.abs(scrollLeft - positionItem);
|
|
195
|
+
prevIndexDelta = indexDelta2;
|
|
196
|
+
debug && console.log("onScroll", {
|
|
197
|
+
pxLeftScrolling,
|
|
198
|
+
indexDelta: indexDelta2,
|
|
199
|
+
scrollLeft,
|
|
200
|
+
positionItem,
|
|
201
|
+
itemPositions
|
|
202
|
+
});
|
|
203
|
+
if (pxLeftScrolling < scrollListenerThreshold) {
|
|
204
|
+
update({
|
|
205
|
+
event: "scroll",
|
|
206
|
+
...fixIndex({
|
|
207
|
+
index: Math.floor(indexDelta2 / slidesPerPage),
|
|
208
|
+
indexDelta: indexDelta2
|
|
209
|
+
})
|
|
191
210
|
});
|
|
192
|
-
const indexDelta2 = itemPositions.findIndex((x) => x === positionItem);
|
|
193
|
-
const pxLeftScrolling = Math.abs(scrollLeft - positionItem);
|
|
194
|
-
prevIndexDelta = indexDelta2;
|
|
195
|
-
if (pxLeftScrolling < 2) {
|
|
196
|
-
update({
|
|
197
|
-
event: "scroll",
|
|
198
|
-
...fixIndex({
|
|
199
|
-
index: Math.floor(indexDelta2 / slidesPerPage),
|
|
200
|
-
indexDelta: indexDelta2
|
|
201
|
-
})
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
211
|
}
|
|
205
|
-
|
|
206
|
-
});
|
|
207
|
-
ticking = true;
|
|
212
|
+
}
|
|
208
213
|
}
|
|
209
214
|
}
|
|
210
|
-
const onScrollFn = throttle(onScroll,
|
|
211
|
-
const onResizeFn = throttle(calculate,
|
|
215
|
+
const onScrollFn = throttle(onScroll, scrollTimeThrottle);
|
|
216
|
+
const onResizeFn = throttle(calculate, resizeTimeThrottle);
|
|
212
217
|
function setElement(_el) {
|
|
213
218
|
if (element) {
|
|
214
219
|
destroy();
|
|
@@ -216,7 +221,35 @@ function createSnapSlider({
|
|
|
216
221
|
element = _el;
|
|
217
222
|
updateIndexDelta();
|
|
218
223
|
calculate();
|
|
219
|
-
|
|
224
|
+
if ("onscrollend" in window) {
|
|
225
|
+
element?.addEventListener("scrollend", (event) => {
|
|
226
|
+
if (element) {
|
|
227
|
+
const scrollLeft = element.scrollLeft;
|
|
228
|
+
const positionItem = itemPositions.reduce((prev, curr) => {
|
|
229
|
+
return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft) ? curr : prev;
|
|
230
|
+
});
|
|
231
|
+
const indexDelta2 = itemPositions.findIndex((x) => x === positionItem);
|
|
232
|
+
const pxLeftScrolling = Math.abs(scrollLeft - positionItem);
|
|
233
|
+
prevIndexDelta = indexDelta2;
|
|
234
|
+
debug && console.log("onScrollEnd", {
|
|
235
|
+
pxLeftScrolling,
|
|
236
|
+
indexDelta: indexDelta2,
|
|
237
|
+
scrollLeft,
|
|
238
|
+
positionItem,
|
|
239
|
+
itemPositions
|
|
240
|
+
});
|
|
241
|
+
update({
|
|
242
|
+
event: "scroll",
|
|
243
|
+
...fixIndex({
|
|
244
|
+
index: Math.floor(indexDelta2 / slidesPerPage),
|
|
245
|
+
indexDelta: indexDelta2
|
|
246
|
+
})
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
} else {
|
|
251
|
+
element?.addEventListener("scroll", onScrollFn);
|
|
252
|
+
}
|
|
220
253
|
window.addEventListener("resize", onResizeFn);
|
|
221
254
|
}
|
|
222
255
|
_element && setElement(_element);
|
|
@@ -241,7 +274,7 @@ function createSnapSlider({
|
|
|
241
274
|
}
|
|
242
275
|
};
|
|
243
276
|
const destroy = () => {
|
|
244
|
-
element
|
|
277
|
+
element?.removeEventListener("scroll", onScrollFn);
|
|
245
278
|
window.removeEventListener("resize", onResizeFn);
|
|
246
279
|
};
|
|
247
280
|
const goNext = () => {
|
package/dist/snap-slider.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snap-slider.cjs","sources":["../lib/throttle.ts","../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 type TSnapListnerEvent = 'scroll' | 'click' | 'inital' | 'goto'\n\nexport interface TSnapListnerStateIndex {\n index: number\n indexDelta: number\n}\n\nexport interface TSnapSliderState extends TSnapListnerStateIndex {\n count: number\n countDelta: number\n event: TSnapListnerEvent\n}\n\ninterface TSnapSliderStateUpdate {\n index?: number\n indexDelta?: number\n count?: number\n countDelta?: number\n event: TSnapListnerEvent\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\n extends Omit<TSnapSliderStateUpdate, 'event'> {\n element: HTMLElement | null\n itemSelector?: string\n initalSubscriptionPublish?: boolean\n circular?: boolean\n debug?: boolean\n}\n\nexport type TSnapSliderJumpToFn = (\n index?: number,\n indexDelta?: number,\n event?: TSnapListnerEvent\n) => 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 debug,\n}: TSnapSliderParams): TSnapSlider {\n let initalIndex: number | undefined = index\n let state: TSnapSliderState = {\n index,\n indexDelta: indexDelta || index,\n event: 'inital',\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, event } = 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 const behavior: ScrollBehavior =\n distance > limitInstantScroll || event === 'click'\n ? 'instant'\n : '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 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 state['event'] = params['event']\n keys.forEach((key) => {\n if (key !== 'event' && 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 const slides = element.querySelectorAll<HTMLDivElement>(itemSelector)\n slides.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\n if (!isNaN(count)) {\n // if element not mounted / hidden not update\n update({\n event: 'inital',\n count,\n countDelta,\n ...resetIndexMayby,\n })\n debug &&\n console.log('update count', {\n count,\n countDelta,\n itemPositions,\n slidesPerPage,\n clientWidth: element.clientWidth,\n offsetWidth: element.offsetWidth,\n itemSelector,\n slides,\n })\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 const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n if (pxLeftScrolling < 2) {\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n }\n ticking = false\n })\n ticking = true\n }\n }\n const onScrollFn = throttle(onScroll, 500)\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 (\n index,\n indexDelta,\n event = 'goto'\n ) {\n if (indexDelta !== undefined) {\n update({\n event,\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n if (index !== undefined) {\n update({\n event,\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":["indexDelta","countDelta","index","count"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"snap-slider.cjs","sources":["../lib/throttle.ts","../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 type TSnapListnerEvent = 'scroll' | 'click' | 'inital' | 'goto'\n\nexport interface TSnapListnerStateIndex {\n index: number\n indexDelta: number\n}\n\nexport interface TSnapSliderState extends TSnapListnerStateIndex {\n count: number\n countDelta: number\n event: TSnapListnerEvent\n}\n\ninterface TSnapSliderStateUpdate {\n index?: number\n indexDelta?: number\n count?: number\n countDelta?: number\n event: TSnapListnerEvent\n}\n\nexport interface TSnapSliderStateFull extends TSnapSliderState {\n prevEnabled: boolean\n nextEnabled: boolean\n}\n\nexport type TSnapListner = (params: TSnapSliderStateFull) => void\n\nexport type TSnapSliderOptions = {\n circular?: boolean\n debug?: boolean\n scrollTimeThrottle?: number\n resizeTimeThrottle?: number\n scrollListenerThreshold?: number\n}\n\nexport type TSnapSliderParams = Omit<TSnapSliderStateUpdate, 'event'> &\n TSnapSliderOptions & {\n element: HTMLElement | null\n itemSelector?: string\n initalSubscriptionPublish?: boolean\n }\n\nexport type TSnapSliderJumpToFn = (\n index?: number,\n indexDelta?: number,\n event?: TSnapListnerEvent\n) => 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 debug,\n scrollTimeThrottle = 500,\n resizeTimeThrottle = 500,\n scrollListenerThreshold = 2,\n}: TSnapSliderParams): TSnapSlider {\n let initalIndex: number | undefined = index\n let state: TSnapSliderState = {\n index,\n indexDelta: indexDelta || index,\n event: 'inital',\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, event } = 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 const behavior: ScrollBehavior =\n distance > limitInstantScroll || event === 'click'\n ? 'instant'\n : '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 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 state['event'] = params['event']\n keys.forEach((key) => {\n if (key !== 'event' && 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 const slides = element.querySelectorAll<HTMLDivElement>(itemSelector)\n slides.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\n if (!isNaN(count)) {\n // if element not mounted / hidden not update\n update({\n event: 'inital',\n count,\n countDelta,\n ...resetIndexMayby,\n })\n debug &&\n console.log('update count', {\n count,\n countDelta,\n itemPositions,\n slidesPerPage,\n clientWidth: element.clientWidth,\n offsetWidth: element.offsetWidth,\n itemSelector,\n slides,\n })\n }\n }\n }\n\n function onScroll() {\n if (element) {\n const scrollLeft = element.scrollLeft\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 const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScroll', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n if (pxLeftScrolling < scrollListenerThreshold) {\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n }\n }\n }\n const onScrollFn = throttle(onScroll, scrollTimeThrottle)\n const onResizeFn = throttle(calculate, resizeTimeThrottle)\n function setElement(_el: HTMLElement) {\n if (element) {\n destroy()\n }\n element = _el\n updateIndexDelta()\n calculate()\n\n if ('onscrollend' in window) {\n element?.addEventListener('scrollend', (event) => {\n if (element) {\n const scrollLeft = element.scrollLeft\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 const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScrollEnd', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n })\n } else {\n element?.addEventListener('scroll', onScrollFn)\n }\n window.addEventListener('resize', onResizeFn)\n }\n _element && setElement(_element)\n const jumpTo: TSnapSliderJumpToFn = function (\n index,\n indexDelta,\n event = 'goto'\n ) {\n if (indexDelta !== undefined) {\n update({\n event,\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n if (index !== undefined) {\n update({\n event,\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":["indexDelta","countDelta","index","count"],"mappings":"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"}
|
package/dist/snap-slider.d.ts
CHANGED
|
@@ -20,13 +20,18 @@ export interface TSnapSliderStateFull extends TSnapSliderState {
|
|
|
20
20
|
nextEnabled: boolean;
|
|
21
21
|
}
|
|
22
22
|
export type TSnapListner = (params: TSnapSliderStateFull) => void;
|
|
23
|
-
export
|
|
23
|
+
export type TSnapSliderOptions = {
|
|
24
|
+
circular?: boolean;
|
|
25
|
+
debug?: boolean;
|
|
26
|
+
scrollTimeThrottle?: number;
|
|
27
|
+
resizeTimeThrottle?: number;
|
|
28
|
+
scrollListenerThreshold?: number;
|
|
29
|
+
};
|
|
30
|
+
export type TSnapSliderParams = Omit<TSnapSliderStateUpdate, 'event'> & TSnapSliderOptions & {
|
|
24
31
|
element: HTMLElement | null;
|
|
25
32
|
itemSelector?: string;
|
|
26
33
|
initalSubscriptionPublish?: boolean;
|
|
27
|
-
|
|
28
|
-
debug?: boolean;
|
|
29
|
-
}
|
|
34
|
+
};
|
|
30
35
|
export type TSnapSliderJumpToFn = (index?: number, indexDelta?: number, event?: TSnapListnerEvent) => void;
|
|
31
36
|
export interface TSnapSlider {
|
|
32
37
|
destroy: () => void;
|
|
@@ -38,5 +43,5 @@ export interface TSnapSlider {
|
|
|
38
43
|
setElement: (el: HTMLElement) => void;
|
|
39
44
|
calculate: () => void;
|
|
40
45
|
}
|
|
41
|
-
export declare function createSnapSlider({ element: _element, count, countDelta, index, circular, indexDelta, initalSubscriptionPublish, itemSelector, debug, }: TSnapSliderParams): TSnapSlider;
|
|
46
|
+
export declare function createSnapSlider({ element: _element, count, countDelta, index, circular, indexDelta, initalSubscriptionPublish, itemSelector, debug, scrollTimeThrottle, resizeTimeThrottle, scrollListenerThreshold, }: TSnapSliderParams): TSnapSlider;
|
|
42
47
|
export {};
|
package/dist/snap-slider.es.js
CHANGED
|
@@ -29,7 +29,10 @@ function createSnapSlider({
|
|
|
29
29
|
indexDelta,
|
|
30
30
|
initalSubscriptionPublish = true,
|
|
31
31
|
itemSelector = ":scope > *",
|
|
32
|
-
debug
|
|
32
|
+
debug,
|
|
33
|
+
scrollTimeThrottle = 500,
|
|
34
|
+
resizeTimeThrottle = 500,
|
|
35
|
+
scrollListenerThreshold = 2
|
|
33
36
|
}) {
|
|
34
37
|
let initalIndex = index;
|
|
35
38
|
let state = {
|
|
@@ -173,40 +176,42 @@ function createSnapSlider({
|
|
|
173
176
|
}
|
|
174
177
|
}
|
|
175
178
|
}
|
|
176
|
-
let ticking = false;
|
|
177
179
|
function onScroll() {
|
|
178
|
-
if (
|
|
180
|
+
if (element) {
|
|
179
181
|
const scrollLeft = element.scrollLeft;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
if (muteScrollListner) {
|
|
183
|
+
const leftToScroll = Math.abs(left - scrollLeft);
|
|
184
|
+
if (leftToScroll < 2) {
|
|
185
|
+
muteScrollListner = false;
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
const positionItem = itemPositions.reduce((prev, curr) => {
|
|
189
|
+
return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft) ? curr : prev;
|
|
190
|
+
});
|
|
191
|
+
const indexDelta2 = itemPositions.findIndex((x) => x === positionItem);
|
|
192
|
+
const pxLeftScrolling = Math.abs(scrollLeft - positionItem);
|
|
193
|
+
prevIndexDelta = indexDelta2;
|
|
194
|
+
debug && console.log("onScroll", {
|
|
195
|
+
pxLeftScrolling,
|
|
196
|
+
indexDelta: indexDelta2,
|
|
197
|
+
scrollLeft,
|
|
198
|
+
positionItem,
|
|
199
|
+
itemPositions
|
|
200
|
+
});
|
|
201
|
+
if (pxLeftScrolling < scrollListenerThreshold) {
|
|
202
|
+
update({
|
|
203
|
+
event: "scroll",
|
|
204
|
+
...fixIndex({
|
|
205
|
+
index: Math.floor(indexDelta2 / slidesPerPage),
|
|
206
|
+
indexDelta: indexDelta2
|
|
207
|
+
})
|
|
189
208
|
});
|
|
190
|
-
const indexDelta2 = itemPositions.findIndex((x) => x === positionItem);
|
|
191
|
-
const pxLeftScrolling = Math.abs(scrollLeft - positionItem);
|
|
192
|
-
prevIndexDelta = indexDelta2;
|
|
193
|
-
if (pxLeftScrolling < 2) {
|
|
194
|
-
update({
|
|
195
|
-
event: "scroll",
|
|
196
|
-
...fixIndex({
|
|
197
|
-
index: Math.floor(indexDelta2 / slidesPerPage),
|
|
198
|
-
indexDelta: indexDelta2
|
|
199
|
-
})
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
209
|
}
|
|
203
|
-
|
|
204
|
-
});
|
|
205
|
-
ticking = true;
|
|
210
|
+
}
|
|
206
211
|
}
|
|
207
212
|
}
|
|
208
|
-
const onScrollFn = throttle(onScroll,
|
|
209
|
-
const onResizeFn = throttle(calculate,
|
|
213
|
+
const onScrollFn = throttle(onScroll, scrollTimeThrottle);
|
|
214
|
+
const onResizeFn = throttle(calculate, resizeTimeThrottle);
|
|
210
215
|
function setElement(_el) {
|
|
211
216
|
if (element) {
|
|
212
217
|
destroy();
|
|
@@ -214,7 +219,35 @@ function createSnapSlider({
|
|
|
214
219
|
element = _el;
|
|
215
220
|
updateIndexDelta();
|
|
216
221
|
calculate();
|
|
217
|
-
|
|
222
|
+
if ("onscrollend" in window) {
|
|
223
|
+
element?.addEventListener("scrollend", (event) => {
|
|
224
|
+
if (element) {
|
|
225
|
+
const scrollLeft = element.scrollLeft;
|
|
226
|
+
const positionItem = itemPositions.reduce((prev, curr) => {
|
|
227
|
+
return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft) ? curr : prev;
|
|
228
|
+
});
|
|
229
|
+
const indexDelta2 = itemPositions.findIndex((x) => x === positionItem);
|
|
230
|
+
const pxLeftScrolling = Math.abs(scrollLeft - positionItem);
|
|
231
|
+
prevIndexDelta = indexDelta2;
|
|
232
|
+
debug && console.log("onScrollEnd", {
|
|
233
|
+
pxLeftScrolling,
|
|
234
|
+
indexDelta: indexDelta2,
|
|
235
|
+
scrollLeft,
|
|
236
|
+
positionItem,
|
|
237
|
+
itemPositions
|
|
238
|
+
});
|
|
239
|
+
update({
|
|
240
|
+
event: "scroll",
|
|
241
|
+
...fixIndex({
|
|
242
|
+
index: Math.floor(indexDelta2 / slidesPerPage),
|
|
243
|
+
indexDelta: indexDelta2
|
|
244
|
+
})
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
} else {
|
|
249
|
+
element?.addEventListener("scroll", onScrollFn);
|
|
250
|
+
}
|
|
218
251
|
window.addEventListener("resize", onResizeFn);
|
|
219
252
|
}
|
|
220
253
|
_element && setElement(_element);
|
|
@@ -239,7 +272,7 @@ function createSnapSlider({
|
|
|
239
272
|
}
|
|
240
273
|
};
|
|
241
274
|
const destroy = () => {
|
|
242
|
-
element
|
|
275
|
+
element?.removeEventListener("scroll", onScrollFn);
|
|
243
276
|
window.removeEventListener("resize", onResizeFn);
|
|
244
277
|
};
|
|
245
278
|
const goNext = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snap-slider.es.js","sources":["../lib/throttle.ts","../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 type TSnapListnerEvent = 'scroll' | 'click' | 'inital' | 'goto'\n\nexport interface TSnapListnerStateIndex {\n index: number\n indexDelta: number\n}\n\nexport interface TSnapSliderState extends TSnapListnerStateIndex {\n count: number\n countDelta: number\n event: TSnapListnerEvent\n}\n\ninterface TSnapSliderStateUpdate {\n index?: number\n indexDelta?: number\n count?: number\n countDelta?: number\n event: TSnapListnerEvent\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\n extends Omit<TSnapSliderStateUpdate, 'event'> {\n element: HTMLElement | null\n itemSelector?: string\n initalSubscriptionPublish?: boolean\n circular?: boolean\n debug?: boolean\n}\n\nexport type TSnapSliderJumpToFn = (\n index?: number,\n indexDelta?: number,\n event?: TSnapListnerEvent\n) => 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 debug,\n}: TSnapSliderParams): TSnapSlider {\n let initalIndex: number | undefined = index\n let state: TSnapSliderState = {\n index,\n indexDelta: indexDelta || index,\n event: 'inital',\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, event } = 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 const behavior: ScrollBehavior =\n distance > limitInstantScroll || event === 'click'\n ? 'instant'\n : '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 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 state['event'] = params['event']\n keys.forEach((key) => {\n if (key !== 'event' && 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 const slides = element.querySelectorAll<HTMLDivElement>(itemSelector)\n slides.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\n if (!isNaN(count)) {\n // if element not mounted / hidden not update\n update({\n event: 'inital',\n count,\n countDelta,\n ...resetIndexMayby,\n })\n debug &&\n console.log('update count', {\n count,\n countDelta,\n itemPositions,\n slidesPerPage,\n clientWidth: element.clientWidth,\n offsetWidth: element.offsetWidth,\n itemSelector,\n slides,\n })\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 const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n if (pxLeftScrolling < 2) {\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n }\n ticking = false\n })\n ticking = true\n }\n }\n const onScrollFn = throttle(onScroll, 500)\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 (\n index,\n indexDelta,\n event = 'goto'\n ) {\n if (indexDelta !== undefined) {\n update({\n event,\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n if (index !== undefined) {\n update({\n event,\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":["indexDelta","countDelta","index","count"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"snap-slider.es.js","sources":["../lib/throttle.ts","../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 type TSnapListnerEvent = 'scroll' | 'click' | 'inital' | 'goto'\n\nexport interface TSnapListnerStateIndex {\n index: number\n indexDelta: number\n}\n\nexport interface TSnapSliderState extends TSnapListnerStateIndex {\n count: number\n countDelta: number\n event: TSnapListnerEvent\n}\n\ninterface TSnapSliderStateUpdate {\n index?: number\n indexDelta?: number\n count?: number\n countDelta?: number\n event: TSnapListnerEvent\n}\n\nexport interface TSnapSliderStateFull extends TSnapSliderState {\n prevEnabled: boolean\n nextEnabled: boolean\n}\n\nexport type TSnapListner = (params: TSnapSliderStateFull) => void\n\nexport type TSnapSliderOptions = {\n circular?: boolean\n debug?: boolean\n scrollTimeThrottle?: number\n resizeTimeThrottle?: number\n scrollListenerThreshold?: number\n}\n\nexport type TSnapSliderParams = Omit<TSnapSliderStateUpdate, 'event'> &\n TSnapSliderOptions & {\n element: HTMLElement | null\n itemSelector?: string\n initalSubscriptionPublish?: boolean\n }\n\nexport type TSnapSliderJumpToFn = (\n index?: number,\n indexDelta?: number,\n event?: TSnapListnerEvent\n) => 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 debug,\n scrollTimeThrottle = 500,\n resizeTimeThrottle = 500,\n scrollListenerThreshold = 2,\n}: TSnapSliderParams): TSnapSlider {\n let initalIndex: number | undefined = index\n let state: TSnapSliderState = {\n index,\n indexDelta: indexDelta || index,\n event: 'inital',\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, event } = 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 const behavior: ScrollBehavior =\n distance > limitInstantScroll || event === 'click'\n ? 'instant'\n : '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 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 state['event'] = params['event']\n keys.forEach((key) => {\n if (key !== 'event' && 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 const slides = element.querySelectorAll<HTMLDivElement>(itemSelector)\n slides.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\n if (!isNaN(count)) {\n // if element not mounted / hidden not update\n update({\n event: 'inital',\n count,\n countDelta,\n ...resetIndexMayby,\n })\n debug &&\n console.log('update count', {\n count,\n countDelta,\n itemPositions,\n slidesPerPage,\n clientWidth: element.clientWidth,\n offsetWidth: element.offsetWidth,\n itemSelector,\n slides,\n })\n }\n }\n }\n\n function onScroll() {\n if (element) {\n const scrollLeft = element.scrollLeft\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 const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScroll', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n if (pxLeftScrolling < scrollListenerThreshold) {\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n }\n }\n }\n const onScrollFn = throttle(onScroll, scrollTimeThrottle)\n const onResizeFn = throttle(calculate, resizeTimeThrottle)\n function setElement(_el: HTMLElement) {\n if (element) {\n destroy()\n }\n element = _el\n updateIndexDelta()\n calculate()\n\n if ('onscrollend' in window) {\n element?.addEventListener('scrollend', (event) => {\n if (element) {\n const scrollLeft = element.scrollLeft\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 const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScrollEnd', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n })\n } else {\n element?.addEventListener('scroll', onScrollFn)\n }\n window.addEventListener('resize', onResizeFn)\n }\n _element && setElement(_element)\n const jumpTo: TSnapSliderJumpToFn = function (\n index,\n indexDelta,\n event = 'goto'\n ) {\n if (indexDelta !== undefined) {\n update({\n event,\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n if (index !== undefined) {\n update({\n event,\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":["indexDelta","countDelta","index","count"],"mappings":"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"}
|
package/dist/use-snap-slider.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const react = require("react");
|
|
4
4
|
const snapSlider = require("./snap-slider.cjs");
|
|
5
|
-
function useSnapSlider(ref, count = 1, index = 0,
|
|
5
|
+
function useSnapSlider(ref, count = 1, index = 0, countHash, options) {
|
|
6
6
|
const [, forceUpdate] = react.useState(0);
|
|
7
7
|
const mountedRef = react.useRef(false);
|
|
8
8
|
react.useRef(false);
|
|
@@ -11,9 +11,8 @@ function useSnapSlider(ref, count = 1, index = 0, circular = false, countHash, d
|
|
|
11
11
|
element: ref.current,
|
|
12
12
|
count,
|
|
13
13
|
index,
|
|
14
|
-
circular,
|
|
15
14
|
initalSubscriptionPublish: false,
|
|
16
|
-
|
|
15
|
+
...options
|
|
17
16
|
})
|
|
18
17
|
);
|
|
19
18
|
const result = observer.getState();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-snap-slider.cjs","sources":["../lib/use-snap-slider.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"use-snap-slider.cjs","sources":["../lib/use-snap-slider.ts"],"sourcesContent":["import { RefObject, useEffect, useRef, useState } from 'react'\nimport {\n createSnapSlider,\n TSnapSliderJumpToFn,\n TSnapSliderOptions,\n type TSnapSliderStateFull,\n} from './snap-slider'\n\nexport interface TUseSnapSlider extends TSnapSliderStateFull {\n jumpTo: TSnapSliderJumpToFn\n goNext: () => void\n goPrev: () => void\n}\n\nexport function useSnapSlider(\n ref: RefObject<HTMLDivElement | null>,\n count: number = 1,\n index: number = 0,\n countHash?: string | number,\n options?: TSnapSliderOptions\n): TUseSnapSlider {\n const [, forceUpdate] = useState<number>(0)\n const mountedRef = useRef<boolean>(false)\n const initRef = useRef<boolean>(false)\n const [observer] = useState(() =>\n createSnapSlider({\n element: ref.current,\n count,\n index,\n initalSubscriptionPublish: false,\n ...options,\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":["useState","useRef","createSnapSlider","useEffect"],"mappings":";;;;AAcO,SAAS,cACd,KACA,QAAgB,GAChB,QAAgB,GAChB,WACA,SACgB;AAChB,QAAM,GAAG,WAAW,IAAIA,MAAAA,SAAiB,CAAC;AAC1C,QAAM,aAAaC,MAAAA,OAAgB,KAAK;AACxBA,QAAAA,OAAgB,KAAK;AACrC,QAAM,CAAC,QAAQ,IAAID,MAAAA;AAAAA,IAAS,MAC1BE,4BAAiB;AAAA,MACf,SAAS,IAAI;AAAA,MACb;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,MAC3B,GAAG;AAAA,IAAA,CACJ;AAAA,EAAA;AAEH,QAAM,SAAS,SAAS,SAAA;AACxBC,QAAAA,UAAU,MAAM;AACd,QAAI,WAAW,SAAS;AACtB,eAAS,OAAO,CAAC;AACjB,eAAS,UAAA;AAAA,IACX;AAAA,EACF,GAAG,CAAC,OAAO,WAAW,QAAQ,CAAC;AAC/BA,QAAAA,UAAU,MAAM;AACd,eAAW,UAAU;AACrB,QAAI,WAAW,SAAS,WAAW,IAAI,OAAO;AAC9C,UAAM,cAAc,SAAS,UAAU,MAAM;AAC3C,UAAI,WAAW,SAAS;AACtB,oBAAY,CAAC,MAAM,IAAI,CAAC;AAAA,MAC1B;AAAA,IACF,CAAC;AAED,WAAO,MAAM;AACX,iBAAW,UAAU;AACrB,kBAAA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,UAAU,WAAW,CAAC;AAC1B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,SAAS;AAAA,IACjB,QAAQ,SAAS;AAAA,IACjB,QAAQ,SAAS;AAAA,EAAA;AAErB;;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { TSnapSliderJumpToFn, TSnapSliderStateFull } from './snap-slider';
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
import { TSnapSliderJumpToFn, TSnapSliderOptions, TSnapSliderStateFull } from './snap-slider';
|
|
3
3
|
export interface TUseSnapSlider extends TSnapSliderStateFull {
|
|
4
4
|
jumpTo: TSnapSliderJumpToFn;
|
|
5
5
|
goNext: () => void;
|
|
6
6
|
goPrev: () => void;
|
|
7
7
|
}
|
|
8
|
-
export declare function useSnapSlider(ref:
|
|
8
|
+
export declare function useSnapSlider(ref: RefObject<HTMLDivElement | null>, count?: number, index?: number, countHash?: string | number, options?: TSnapSliderOptions): TUseSnapSlider;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useState, useRef, useEffect } from "react";
|
|
2
2
|
import { createSnapSlider } from "./snap-slider.es.js";
|
|
3
|
-
function useSnapSlider(ref, count = 1, index = 0,
|
|
3
|
+
function useSnapSlider(ref, count = 1, index = 0, countHash, options) {
|
|
4
4
|
const [, forceUpdate] = useState(0);
|
|
5
5
|
const mountedRef = useRef(false);
|
|
6
6
|
useRef(false);
|
|
@@ -9,9 +9,8 @@ function useSnapSlider(ref, count = 1, index = 0, circular = false, countHash, d
|
|
|
9
9
|
element: ref.current,
|
|
10
10
|
count,
|
|
11
11
|
index,
|
|
12
|
-
circular,
|
|
13
12
|
initalSubscriptionPublish: false,
|
|
14
|
-
|
|
13
|
+
...options
|
|
15
14
|
})
|
|
16
15
|
);
|
|
17
16
|
const result = observer.getState();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-snap-slider.es.js","sources":["../lib/use-snap-slider.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"use-snap-slider.es.js","sources":["../lib/use-snap-slider.ts"],"sourcesContent":["import { RefObject, useEffect, useRef, useState } from 'react'\nimport {\n createSnapSlider,\n TSnapSliderJumpToFn,\n TSnapSliderOptions,\n type TSnapSliderStateFull,\n} from './snap-slider'\n\nexport interface TUseSnapSlider extends TSnapSliderStateFull {\n jumpTo: TSnapSliderJumpToFn\n goNext: () => void\n goPrev: () => void\n}\n\nexport function useSnapSlider(\n ref: RefObject<HTMLDivElement | null>,\n count: number = 1,\n index: number = 0,\n countHash?: string | number,\n options?: TSnapSliderOptions\n): TUseSnapSlider {\n const [, forceUpdate] = useState<number>(0)\n const mountedRef = useRef<boolean>(false)\n const initRef = useRef<boolean>(false)\n const [observer] = useState(() =>\n createSnapSlider({\n element: ref.current,\n count,\n index,\n initalSubscriptionPublish: false,\n ...options,\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":[],"mappings":";;AAcO,SAAS,cACd,KACA,QAAgB,GAChB,QAAgB,GAChB,WACA,SACgB;AAChB,QAAM,GAAG,WAAW,IAAI,SAAiB,CAAC;AAC1C,QAAM,aAAa,OAAgB,KAAK;AACxB,SAAgB,KAAK;AACrC,QAAM,CAAC,QAAQ,IAAI;AAAA,IAAS,MAC1B,iBAAiB;AAAA,MACf,SAAS,IAAI;AAAA,MACb;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,MAC3B,GAAG;AAAA,IAAA,CACJ;AAAA,EAAA;AAEH,QAAM,SAAS,SAAS,SAAA;AACxB,YAAU,MAAM;AACd,QAAI,WAAW,SAAS;AACtB,eAAS,OAAO,CAAC;AACjB,eAAS,UAAA;AAAA,IACX;AAAA,EACF,GAAG,CAAC,OAAO,WAAW,QAAQ,CAAC;AAC/B,YAAU,MAAM;AACd,eAAW,UAAU;AACrB,QAAI,WAAW,SAAS,WAAW,IAAI,OAAO;AAC9C,UAAM,cAAc,SAAS,UAAU,MAAM;AAC3C,UAAI,WAAW,SAAS;AACtB,oBAAY,CAAC,MAAM,IAAI,CAAC;AAAA,MAC1B;AAAA,IACF,CAAC;AAED,WAAO,MAAM;AACX,iBAAW,UAAU;AACrB,kBAAA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,UAAU,WAAW,CAAC;AAC1B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,SAAS;AAAA,IACjB,QAAQ,SAAS;AAAA,IACjB,QAAQ,SAAS;AAAA,EAAA;AAErB;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "use-snap-slider",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "React hook to manage css snap sliders",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/use-snap-slider.cjs",
|
|
@@ -53,25 +53,27 @@
|
|
|
53
53
|
"singleQuote": true
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@
|
|
57
|
-
"@testing-library/
|
|
58
|
-
"@
|
|
59
|
-
"@types/
|
|
60
|
-
"@types/
|
|
61
|
-
"@types/react
|
|
62
|
-
"@
|
|
63
|
-
"
|
|
56
|
+
"@tailwindcss/postcss": "^4.1.17",
|
|
57
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
58
|
+
"@testing-library/react": "^16.3.0",
|
|
59
|
+
"@types/jest": "^30.0.0",
|
|
60
|
+
"@types/node": "^24.10.1",
|
|
61
|
+
"@types/react": "^19.2.6",
|
|
62
|
+
"@types/react-dom": "^19.2.3",
|
|
63
|
+
"@vitejs/plugin-react": "^5.1.1",
|
|
64
|
+
"autoprefixer": "^10.4.22",
|
|
64
65
|
"classnames": "^2.5.1",
|
|
65
|
-
"jest": "^
|
|
66
|
-
"jest-environment-jsdom": "^
|
|
67
|
-
"postcss": "^8.
|
|
68
|
-
"react": "^
|
|
69
|
-
"react-dom": "^
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"vite
|
|
66
|
+
"jest": "^30.2.0",
|
|
67
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
68
|
+
"postcss": "^8.5.6",
|
|
69
|
+
"react": "^19.2.0",
|
|
70
|
+
"react-dom": "^19.2.0",
|
|
71
|
+
"react-router": "^7.9.6",
|
|
72
|
+
"rimraf": "^6.1.2",
|
|
73
|
+
"tailwindcss": "^4.1.16",
|
|
74
|
+
"ts-jest": "^29.4.5",
|
|
75
|
+
"typescript": "^5.9.3",
|
|
76
|
+
"vite": "^7.2.4",
|
|
77
|
+
"vite-plugin-dts": "^4.5.4"
|
|
76
78
|
}
|
|
77
79
|
}
|