@revenuecat/purchases-ui-js 4.8.8 → 4.8.9
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.
|
@@ -22,7 +22,12 @@
|
|
|
22
22
|
} from "../../utils/base-utils";
|
|
23
23
|
import { getActiveStateProps } from "../../utils/style-utils";
|
|
24
24
|
import { onMount } from "svelte";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
clamp,
|
|
27
|
+
getSwipeTargetPage,
|
|
28
|
+
getTranslation,
|
|
29
|
+
mapPageAlignment,
|
|
30
|
+
} from "./carousel-utils";
|
|
26
31
|
import CarouselPage from "./CarouselPage.svelte";
|
|
27
32
|
import PageControl from "./PageControl.svelte";
|
|
28
33
|
|
|
@@ -220,19 +225,35 @@
|
|
|
220
225
|
|
|
221
226
|
let startTranslation = $state(0);
|
|
222
227
|
|
|
228
|
+
let lastClientX = 0;
|
|
229
|
+
|
|
223
230
|
function onpointerdown(event: PointerEvent) {
|
|
224
231
|
const target = event.currentTarget as HTMLElement;
|
|
225
232
|
target.setPointerCapture(event.pointerId);
|
|
226
233
|
startTranslation = getTranslation(slider);
|
|
227
234
|
gestureStartPage = currentPage;
|
|
235
|
+
lastClientX = event.clientX;
|
|
228
236
|
}
|
|
229
237
|
|
|
230
238
|
function onpointerup(event: PointerEvent) {
|
|
231
239
|
const target = event.currentTarget as HTMLElement;
|
|
232
|
-
target.
|
|
240
|
+
if (target.hasPointerCapture(event.pointerId)) {
|
|
241
|
+
target.releasePointerCapture(event.pointerId);
|
|
242
|
+
}
|
|
233
243
|
|
|
234
244
|
const translation = getTranslation(slider);
|
|
235
|
-
|
|
245
|
+
|
|
246
|
+
// Advance at most one page from where the gesture started, based on how
|
|
247
|
+
// far the finger travelled relative to a page's width (see
|
|
248
|
+
// getSwipeTargetPage).
|
|
249
|
+
const page = getSwipeTargetPage({
|
|
250
|
+
startPage: gestureStartPage ?? getPageFromTranslation(translation),
|
|
251
|
+
dragDistance: translation - startTranslation,
|
|
252
|
+
pageWidth,
|
|
253
|
+
pageCount: pages.length,
|
|
254
|
+
loop: carouselPagingLoop,
|
|
255
|
+
});
|
|
256
|
+
|
|
236
257
|
const destinationPage = normalizePageIndex(page);
|
|
237
258
|
|
|
238
259
|
if (gestureStartPage !== null && gestureStartPage !== destinationPage) {
|
|
@@ -249,6 +270,7 @@
|
|
|
249
270
|
}
|
|
250
271
|
|
|
251
272
|
gestureStartPage = null;
|
|
273
|
+
currentPage = destinationPage;
|
|
252
274
|
startTransition(false, 500);
|
|
253
275
|
moveTo(page);
|
|
254
276
|
}
|
|
@@ -259,11 +281,17 @@
|
|
|
259
281
|
return;
|
|
260
282
|
}
|
|
261
283
|
|
|
284
|
+
// Track movement from clientX instead of event.movementX: movementX is 0
|
|
285
|
+
// for touch-derived pointer events in Safari and device-pixel scaled in
|
|
286
|
+
// some Chrome configurations.
|
|
287
|
+
const deltaX = event.clientX - lastClientX;
|
|
288
|
+
lastClientX = event.clientX;
|
|
289
|
+
|
|
262
290
|
const [min, max] = carouselPagingLoop
|
|
263
291
|
? [startTranslation - carouselWidth, startTranslation + carouselWidth]
|
|
264
292
|
: [-(pages.length - 1) * pageWidth, 0];
|
|
265
293
|
const translation = getTranslation(slider);
|
|
266
|
-
const newTranslation = clamp(translation +
|
|
294
|
+
const newTranslation = clamp(translation + deltaX, min, max);
|
|
267
295
|
|
|
268
296
|
const page = getPageFromTranslation(newTranslation);
|
|
269
297
|
currentPage = (page + pages.length) % pages.length;
|
|
@@ -1,4 +1,35 @@
|
|
|
1
1
|
import type { VerticalAlignment } from "../../types/alignment";
|
|
2
2
|
export declare function mapPageAlignment(alignment: VerticalAlignment): string;
|
|
3
3
|
export declare function clamp(value: number, min: number, max: number): number;
|
|
4
|
+
/**
|
|
5
|
+
* Advance one page when the drag passed this fraction of a page's width,
|
|
6
|
+
* matching the iOS SDK carousel. A shorter drag snaps back to the page the
|
|
7
|
+
* gesture started on.
|
|
8
|
+
*/
|
|
9
|
+
export declare const PAGE_ADVANCE_THRESHOLD = 0.2;
|
|
10
|
+
/**
|
|
11
|
+
* Decides which page a swipe settles on when the pointer is released.
|
|
12
|
+
*
|
|
13
|
+
* Distance-based (not velocity-based), mirroring the iOS SDK's `handleDragEnd`:
|
|
14
|
+
* a drag past `PAGE_ADVANCE_THRESHOLD` of a page's width advances exactly one
|
|
15
|
+
* page in the swipe direction regardless of speed; a shorter drag stays put.
|
|
16
|
+
* Non-loop carousels clamp at their first and last page; loop carousels may
|
|
17
|
+
* return an index just outside `[0, pageCount)` so the caller can animate into
|
|
18
|
+
* a clone before normalizing.
|
|
19
|
+
*
|
|
20
|
+
* @param startPage Page the gesture started on.
|
|
21
|
+
* @param dragDistance Signed change in slider translation (negative = finger
|
|
22
|
+
* moved left / next page).
|
|
23
|
+
* @param pageWidth Width of a single page in px.
|
|
24
|
+
* @param pageCount Total number of real pages.
|
|
25
|
+
* @param loop Whether the carousel loops.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getSwipeTargetPage({ startPage, dragDistance, pageWidth, pageCount, loop, advanceThreshold, }: {
|
|
28
|
+
startPage: number;
|
|
29
|
+
dragDistance: number;
|
|
30
|
+
pageWidth: number;
|
|
31
|
+
pageCount: number;
|
|
32
|
+
loop: boolean;
|
|
33
|
+
advanceThreshold?: number;
|
|
34
|
+
}): number;
|
|
4
35
|
export declare function getTranslation(element: HTMLElement | null): number;
|
|
@@ -11,6 +11,42 @@ export function mapPageAlignment(alignment) {
|
|
|
11
11
|
export function clamp(value, min, max) {
|
|
12
12
|
return Math.max(min, Math.min(value, max));
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Advance one page when the drag passed this fraction of a page's width,
|
|
16
|
+
* matching the iOS SDK carousel. A shorter drag snaps back to the page the
|
|
17
|
+
* gesture started on.
|
|
18
|
+
*/
|
|
19
|
+
export const PAGE_ADVANCE_THRESHOLD = 0.2;
|
|
20
|
+
/**
|
|
21
|
+
* Decides which page a swipe settles on when the pointer is released.
|
|
22
|
+
*
|
|
23
|
+
* Distance-based (not velocity-based), mirroring the iOS SDK's `handleDragEnd`:
|
|
24
|
+
* a drag past `PAGE_ADVANCE_THRESHOLD` of a page's width advances exactly one
|
|
25
|
+
* page in the swipe direction regardless of speed; a shorter drag stays put.
|
|
26
|
+
* Non-loop carousels clamp at their first and last page; loop carousels may
|
|
27
|
+
* return an index just outside `[0, pageCount)` so the caller can animate into
|
|
28
|
+
* a clone before normalizing.
|
|
29
|
+
*
|
|
30
|
+
* @param startPage Page the gesture started on.
|
|
31
|
+
* @param dragDistance Signed change in slider translation (negative = finger
|
|
32
|
+
* moved left / next page).
|
|
33
|
+
* @param pageWidth Width of a single page in px.
|
|
34
|
+
* @param pageCount Total number of real pages.
|
|
35
|
+
* @param loop Whether the carousel loops.
|
|
36
|
+
*/
|
|
37
|
+
export function getSwipeTargetPage({ startPage, dragDistance, pageWidth, pageCount, loop, advanceThreshold = PAGE_ADVANCE_THRESHOLD, }) {
|
|
38
|
+
const threshold = pageWidth * advanceThreshold;
|
|
39
|
+
let page = startPage;
|
|
40
|
+
if (dragDistance < -threshold) {
|
|
41
|
+
// Finger moved left, content shifts left: next page.
|
|
42
|
+
page += 1;
|
|
43
|
+
}
|
|
44
|
+
else if (dragDistance > threshold) {
|
|
45
|
+
// Finger moved right: previous page.
|
|
46
|
+
page -= 1;
|
|
47
|
+
}
|
|
48
|
+
return loop ? page : clamp(page, 0, pageCount - 1);
|
|
49
|
+
}
|
|
14
50
|
export function getTranslation(element) {
|
|
15
51
|
if (element === null) {
|
|
16
52
|
return 0;
|