@sigx/lynx-gestures 0.4.0 → 0.4.2
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/README.md +42 -0
- package/dist/components/Draggable.js +378 -0
- package/dist/components/Draggable.js.map +1 -0
- package/dist/components/Pressable.d.ts +5 -4
- package/dist/components/Pressable.d.ts.map +1 -1
- package/dist/components/Pressable.js +157 -0
- package/dist/components/Pressable.js.map +1 -0
- package/dist/components/ScrollView.js +85 -0
- package/dist/components/ScrollView.js.map +1 -0
- package/dist/components/Swipeable.js +165 -0
- package/dist/components/Swipeable.js.map +1 -0
- package/dist/components/Swiper.d.ts +65 -0
- package/dist/components/Swiper.d.ts.map +1 -0
- package/dist/components/Swiper.js +124 -0
- package/dist/components/Swiper.js.map +1 -0
- package/dist/index.d.ts +17 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -404
- package/dist/index.js.map +1 -1
- package/dist/scroll-context.js +3 -0
- package/dist/scroll-context.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/use-pinch.d.ts +1 -1
- package/dist/use-pinch.d.ts.map +1 -1
- package/dist/use-pinch.js +106 -0
- package/dist/use-pinch.js.map +1 -0
- package/dist/use-rotation.d.ts +1 -1
- package/dist/use-rotation.d.ts.map +1 -1
- package/dist/use-rotation.js +117 -0
- package/dist/use-rotation.js.map +1 -0
- package/dist/use-swiper-dot-progress.d.ts +129 -0
- package/dist/use-swiper-dot-progress.d.ts.map +1 -0
- package/dist/use-swiper-dot-progress.js +141 -0
- package/dist/use-swiper-dot-progress.js.map +1 -0
- package/dist/utils.js +25 -0
- package/dist/utils.js.map +1 -0
- package/package.json +10 -9
- package/src/components/Draggable.tsx +1 -1
- package/src/components/Pressable.tsx +44 -18
- package/src/components/ScrollView.tsx +1 -1
- package/src/components/Swipeable.tsx +1 -1
- package/src/components/Swiper.tsx +204 -0
- package/src/index.ts +27 -13
- package/src/use-pinch.ts +2 -2
- package/src/use-rotation.ts +2 -2
- package/src/use-swiper-dot-progress.ts +231 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pressable.js","sourceRoot":"","sources":["../../src/components/Pressable.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { jsx as _jsx } from "@sigx/lynx/jsx-runtime";
|
|
2
|
+
import { component, signal, useSharedValue, useMainThreadRef, defineProvide, } from '@sigx/lynx';
|
|
3
|
+
import { useScrollContext } from '../scroll-context.js';
|
|
4
|
+
/**
|
|
5
|
+
* MT-thread `<scroll-view>` wrapper that mirrors scroll position into a
|
|
6
|
+
* `SharedValue`. Pair with `useAnimatedStyle` for parallax / fade / scale
|
|
7
|
+
* effects driven by scroll, all running on MT with zero per-frame thread
|
|
8
|
+
* crossings.
|
|
9
|
+
*
|
|
10
|
+
* The component is the API; the inline `'main thread'` worklet, the
|
|
11
|
+
* `__FlushElementTree()` trigger, and the runtime registration are all
|
|
12
|
+
* internal. Users just pass a `SharedValue<number>` for the axis they care
|
|
13
|
+
* about — same shape as `<Draggable translateX={tx}>`.
|
|
14
|
+
*
|
|
15
|
+
* @example Parallax header
|
|
16
|
+
* ```tsx
|
|
17
|
+
* const scrollY = useSharedValue(0);
|
|
18
|
+
* const headerRef = useMainThreadRef<MainThread.Element | null>(null);
|
|
19
|
+
*
|
|
20
|
+
* useAnimatedStyle(headerRef, scrollY, 'translateY', {
|
|
21
|
+
* inputRange: [0, 300], outputRange: [0, -150], extrapolate: 'clamp',
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* <ScrollView offsetY={scrollY}>
|
|
25
|
+
* <view main-thread:ref={headerRef}><image src={hero} /></view>
|
|
26
|
+
* <text>Body…</text>
|
|
27
|
+
* </ScrollView>
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example BG-reactive scroll readout
|
|
31
|
+
* ```tsx
|
|
32
|
+
* const scrollY = useSharedValue(0);
|
|
33
|
+
* <ScrollView offsetY={scrollY}>...</ScrollView>
|
|
34
|
+
* <text>Scrolled: {scrollY.value.toFixed(0)}px</text>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export const ScrollView = component(({ props, slots }) => {
|
|
38
|
+
// Always allocate fallback SharedValues — hooks must run unconditionally.
|
|
39
|
+
// The render closure picks between own/external; the worklet always sees
|
|
40
|
+
// a defined SharedValue in its `_c` capture.
|
|
41
|
+
const ownX = useSharedValue(0);
|
|
42
|
+
const ownY = useSharedValue(0);
|
|
43
|
+
// Phase 2.12 ScrollView ↔ child-gesture coordination. Descendant
|
|
44
|
+
// `<Draggable>` / `<Swipeable>` flip this signal during their drag so the
|
|
45
|
+
// UIKit `panGestureRecognizer` (which doesn't participate in the new
|
|
46
|
+
// gesture arena) yields the touch. See `scroll-context.ts` for the why.
|
|
47
|
+
const dragging = signal(false);
|
|
48
|
+
// Phase 2.13: publish the scroll-view's element ref through the context so
|
|
49
|
+
// descendants can drive scroll directly from worklets (e.g. <Draggable
|
|
50
|
+
// edgeScroll>). Captured at setup so the worklet `_c` map sees a stable
|
|
51
|
+
// ref identity.
|
|
52
|
+
const scrollViewRef = useMainThreadRef(null);
|
|
53
|
+
// Pick the axis SVs once; the same identity is shared with descendants via
|
|
54
|
+
// the context (so they can read live scroll position) and used at render
|
|
55
|
+
// time for the bindscroll worklet's `_c` capture.
|
|
56
|
+
const x = props.offsetX ?? ownX;
|
|
57
|
+
const y = props.offsetY ?? ownY;
|
|
58
|
+
const scrollOrientation = props['scroll-orientation'] ?? 'vertical';
|
|
59
|
+
defineProvide(useScrollContext, () => ({
|
|
60
|
+
dragging,
|
|
61
|
+
scrollViewRef,
|
|
62
|
+
offsetX: x,
|
|
63
|
+
offsetY: y,
|
|
64
|
+
scrollOrientation,
|
|
65
|
+
}));
|
|
66
|
+
return () => {
|
|
67
|
+
// Compose user-passed enable-scroll with the descendant-driven flag:
|
|
68
|
+
// both must be true. User can still force-lock by passing `false`.
|
|
69
|
+
const userEnableScroll = props['enable-scroll'] ?? true;
|
|
70
|
+
const enableScroll = userEnableScroll && !dragging.value;
|
|
71
|
+
return (_jsx("scroll-view", { "main-thread:ref": scrollViewRef, "scroll-orientation": scrollOrientation, "enable-scroll": enableScroll, class: props.class, style: props.style, "main-thread-bindscroll": (e) => {
|
|
72
|
+
'main thread';
|
|
73
|
+
y.current.value = e.detail.scrollTop;
|
|
74
|
+
x.current.value = e.detail.scrollLeft;
|
|
75
|
+
// Apply useAnimatedStyle bindings on the same frame. Inlined
|
|
76
|
+
// (rather than calling a helper) because plain function imports
|
|
77
|
+
// don't survive worklet `_c` capture across the MT bundle —
|
|
78
|
+
// same constraint @sigx/lynx-motion's `animate()` documents.
|
|
79
|
+
const __flush = globalThis['__FlushElementTree'];
|
|
80
|
+
if (__flush)
|
|
81
|
+
__flush();
|
|
82
|
+
}, children: slots.default?.() }));
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=ScrollView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollView.js","sourceRoot":"","sources":["../../src/components/ScrollView.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,SAAS,EACT,MAAM,EACN,cAAc,EACd,gBAAgB,EAChB,aAAa,GAId,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAiBxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAkB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;IACxE,0EAA0E;IAC1E,yEAAyE;IACzE,6CAA6C;IAC7C,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;IAE/B,iEAAiE;IACjE,0EAA0E;IAC1E,qEAAqE;IACrE,wEAAwE;IACxE,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE/B,2EAA2E;IAC3E,uEAAuE;IACvE,wEAAwE;IACxE,gBAAgB;IAChB,MAAM,aAAa,GAAG,gBAAgB,CAA4B,IAAI,CAAC,CAAC;IAExE,2EAA2E;IAC3E,yEAAyE;IACzE,kDAAkD;IAClD,MAAM,CAAC,GAAwB,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC;IACrD,MAAM,CAAC,GAAwB,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC;IACrD,MAAM,iBAAiB,GAAG,KAAK,CAAC,oBAAoB,CAAC,IAAI,UAAU,CAAC;IAEpE,aAAa,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;QACrC,QAAQ;QACR,aAAa;QACb,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,iBAAiB;KAClB,CAAC,CAAC,CAAC;IAEJ,OAAO,GAAG,EAAE;QACV,qEAAqE;QACrE,mEAAmE;QACnE,MAAM,gBAAgB,GAAG,KAAK,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC;QACxD,MAAM,YAAY,GAAG,gBAAgB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACzD,OAAO,CACL,yCACmB,aAAa,wBACV,iBAAiB,mBACtB,YAAY,EAC3B,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,KAAK,EAAE,KAAK,CAAC,KAAK,4BACM,CAAC,CAAM,EAAE,EAAE;gBACjC,aAAa,CAAC;gBACd,CAAC,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;gBACrC,CAAC,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;gBACtC,6DAA6D;gBAC7D,gEAAgE;gBAChE,4DAA4D;gBAC5D,6DAA6D;gBAC7D,MAAM,OAAO,GAAI,UAAsC,CAAC,oBAAoB,CAA6B,CAAC;gBAC1G,IAAI,OAAO;oBAAE,OAAO,EAAE,CAAC;YACzB,CAAC,YAEA,KAAK,CAAC,OAAO,EAAE,EAAE,GACN,CACf,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@sigx/lynx/jsx-runtime";
|
|
2
|
+
import { component, useMainThreadRef, useSharedValue, useAnimatedStyle, runOnBackground, Gesture, useGestureDetector, } from '@sigx/lynx';
|
|
3
|
+
import { useScrollContext } from '../scroll-context.js';
|
|
4
|
+
/**
|
|
5
|
+
* Horizontal swipe-to-reveal container, built on the native gesture arena
|
|
6
|
+
* via `Gesture.Pan().axis('x')`. The foreground is dragged horizontally on
|
|
7
|
+
* the MT thread; on release it snaps to one of three resting positions
|
|
8
|
+
* (closed / open-left / open-right) using `MTElementWrapper.animate()`.
|
|
9
|
+
* Open and close events are dispatched to BG via `runOnBackground`.
|
|
10
|
+
*
|
|
11
|
+
* Migrated from a 4-`bindtouch*`-worklet implementation to a single
|
|
12
|
+
* `Gesture.Pan()` (Phase 2.12). Carries the same Phase 2.11 quirks:
|
|
13
|
+
* - `.onBegin(() => {})` no-op is load-bearing on iOS Pan to gate
|
|
14
|
+
* `_isInvokedBegin` open so onStart/onEnd fire.
|
|
15
|
+
* - `e.params.pageX` (not `e.pageX`) — Lynx pan event nests the touch
|
|
16
|
+
* payload under `params`.
|
|
17
|
+
*
|
|
18
|
+
* Supply `leftActions` and/or `rightActions` as render-prop functions:
|
|
19
|
+
*
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <Swipeable
|
|
22
|
+
* rightActions={() => <view><text>Delete</text></view>}
|
|
23
|
+
* onSwipeOpen={(e) => console.log('opened', e.side)}
|
|
24
|
+
* >
|
|
25
|
+
* <view><text>Row content</text></view>
|
|
26
|
+
* </Swipeable>
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* **Scroll composition** (Phase 2.12.3): nesting `<Swipeable>` inside
|
|
30
|
+
* `<ScrollView>` is automatic — `useScrollContext` is read at setup and
|
|
31
|
+
* the BG-side onStart/onEnd handlers flip `scrollCtx.dragging` so the
|
|
32
|
+
* parent yields its UIKit pan for the duration of the swipe. No consumer
|
|
33
|
+
* wiring required.
|
|
34
|
+
*/
|
|
35
|
+
export const Swipeable = component(({ props, slots, emit }) => {
|
|
36
|
+
const fgRef = useMainThreadRef(null);
|
|
37
|
+
// Drive the foreground transform via a SharedValue so external animations
|
|
38
|
+
// could compose if we ever wanted spring snaps. For now we still call
|
|
39
|
+
// `.animate()` on the element directly for the snap; the SV is only the
|
|
40
|
+
// intermediate write target during the drag.
|
|
41
|
+
const tx = useSharedValue(0);
|
|
42
|
+
useAnimatedStyle(fgRef, tx, 'translateX');
|
|
43
|
+
const drag = useMainThreadRef({
|
|
44
|
+
startPageX: 0,
|
|
45
|
+
offsetX: 0,
|
|
46
|
+
currentX: 0,
|
|
47
|
+
});
|
|
48
|
+
// Coordinate with the parent <ScrollView> (Phase 2.12.3) — see Draggable
|
|
49
|
+
// for the why. Null when no ancestor ScrollView.
|
|
50
|
+
const scrollCtx = useScrollContext();
|
|
51
|
+
const leftWidth = props.leftActionsWidth ?? 100;
|
|
52
|
+
const rightWidth = props.rightActionsWidth ?? 100;
|
|
53
|
+
const snapThreshold = props.snapThreshold ?? 60;
|
|
54
|
+
const snapDuration = props.snapDuration ?? 200;
|
|
55
|
+
const hasLeft = !!props.leftActions;
|
|
56
|
+
const hasRight = !!props.rightActions;
|
|
57
|
+
const upper = hasLeft ? leftWidth : 0;
|
|
58
|
+
const lower = hasRight ? -rightWidth : 0;
|
|
59
|
+
const pan = Gesture.Pan()
|
|
60
|
+
.axis('x')
|
|
61
|
+
// Empty onBegin gates `_isInvokedBegin` open on iOS so onStart/onEnd fire.
|
|
62
|
+
.onBegin(() => {
|
|
63
|
+
'main thread';
|
|
64
|
+
})
|
|
65
|
+
.onStart((e) => {
|
|
66
|
+
'main thread';
|
|
67
|
+
const p = e && e.params;
|
|
68
|
+
drag.current.startPageX = (p && p.pageX) || 0;
|
|
69
|
+
drag.current.offsetX = drag.current.currentX;
|
|
70
|
+
// Tell the parent ScrollView (if any) we own the touch.
|
|
71
|
+
runOnBackground(() => {
|
|
72
|
+
if (scrollCtx)
|
|
73
|
+
scrollCtx.dragging.value = true;
|
|
74
|
+
})();
|
|
75
|
+
})
|
|
76
|
+
.onUpdate((e) => {
|
|
77
|
+
'main thread';
|
|
78
|
+
const p = e && e.params;
|
|
79
|
+
const pageX = (p && p.pageX) || 0;
|
|
80
|
+
let x = drag.current.offsetX + (pageX - drag.current.startPageX);
|
|
81
|
+
if (x > upper)
|
|
82
|
+
x = upper;
|
|
83
|
+
if (x < lower)
|
|
84
|
+
x = lower;
|
|
85
|
+
tx.current.value = x;
|
|
86
|
+
// Bridge the binding on the same frame so the foreground tracks the
|
|
87
|
+
// finger without a vsync delay (same trick as Draggable).
|
|
88
|
+
const __flush = globalThis['__FlushElementTree'];
|
|
89
|
+
if (__flush)
|
|
90
|
+
__flush();
|
|
91
|
+
})
|
|
92
|
+
.onEnd(() => {
|
|
93
|
+
'main thread';
|
|
94
|
+
const x = tx.current.value;
|
|
95
|
+
// Snap to closest resting position.
|
|
96
|
+
let target = 0;
|
|
97
|
+
if (hasLeft && x > snapThreshold)
|
|
98
|
+
target = leftWidth;
|
|
99
|
+
else if (hasRight && x < -snapThreshold)
|
|
100
|
+
target = -rightWidth;
|
|
101
|
+
fgRef.current?.animate([
|
|
102
|
+
{ transform: 'translateX(' + x + 'px)' },
|
|
103
|
+
{ transform: 'translateX(' + target + 'px)' },
|
|
104
|
+
], { duration: snapDuration, fill: 'forwards', easing: 'cubic-bezier(0.2, 0.8, 0.2, 1)' })?.play();
|
|
105
|
+
// Keep the SV in sync with the snap target so subsequent drags don't
|
|
106
|
+
// jump back to the pre-animate position.
|
|
107
|
+
tx.current.value = target;
|
|
108
|
+
const wasOpen = drag.current.currentX !== 0;
|
|
109
|
+
const nowOpen = target !== 0;
|
|
110
|
+
drag.current.currentX = target;
|
|
111
|
+
// Always release the parent ScrollView's claim, regardless of snap.
|
|
112
|
+
// Bundled into the same runOnBackground call as the emit so we only
|
|
113
|
+
// pay one cross-thread hop.
|
|
114
|
+
if (nowOpen) {
|
|
115
|
+
const side = target > 0 ? 'left' : 'right';
|
|
116
|
+
runOnBackground((s) => {
|
|
117
|
+
if (scrollCtx)
|
|
118
|
+
scrollCtx.dragging.value = false;
|
|
119
|
+
emit('swipeOpen', { side: s });
|
|
120
|
+
})(side);
|
|
121
|
+
}
|
|
122
|
+
else if (wasOpen) {
|
|
123
|
+
runOnBackground(() => {
|
|
124
|
+
if (scrollCtx)
|
|
125
|
+
scrollCtx.dragging.value = false;
|
|
126
|
+
emit('swipeClose');
|
|
127
|
+
})();
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// Closed→closed: still need to release the ScrollView claim.
|
|
131
|
+
runOnBackground(() => {
|
|
132
|
+
if (scrollCtx)
|
|
133
|
+
scrollCtx.dragging.value = false;
|
|
134
|
+
})();
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
useGestureDetector(fgRef, pan);
|
|
138
|
+
return () => (_jsxs("view", { class: props.class, style: {
|
|
139
|
+
position: 'relative',
|
|
140
|
+
overflow: 'hidden',
|
|
141
|
+
...(props.style || {}),
|
|
142
|
+
}, children: [hasLeft ? (_jsx("view", { style: {
|
|
143
|
+
position: 'absolute',
|
|
144
|
+
left: '0',
|
|
145
|
+
top: '0',
|
|
146
|
+
bottom: '0',
|
|
147
|
+
width: leftWidth + 'px',
|
|
148
|
+
display: 'flex',
|
|
149
|
+
alignItems: 'center',
|
|
150
|
+
justifyContent: 'center',
|
|
151
|
+
}, children: props.leftActions() })) : null, hasRight ? (_jsx("view", { style: {
|
|
152
|
+
position: 'absolute',
|
|
153
|
+
right: '0',
|
|
154
|
+
top: '0',
|
|
155
|
+
bottom: '0',
|
|
156
|
+
width: rightWidth + 'px',
|
|
157
|
+
display: 'flex',
|
|
158
|
+
alignItems: 'center',
|
|
159
|
+
justifyContent: 'center',
|
|
160
|
+
}, children: props.rightActions() })) : null, _jsx("view", { "main-thread:ref": fgRef, style: {
|
|
161
|
+
position: 'relative',
|
|
162
|
+
...(props.foregroundStyle || {}),
|
|
163
|
+
}, children: slots.default?.() })] }));
|
|
164
|
+
});
|
|
165
|
+
//# sourceMappingURL=Swipeable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Swipeable.js","sourceRoot":"","sources":["../../src/components/Swipeable.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type SharedValue, type Define } from '@sigx/lynx';
|
|
2
|
+
import type { PrimitiveSignal } from '@sigx/reactivity';
|
|
3
|
+
export type SwiperProps<T = unknown> =
|
|
4
|
+
/**
|
|
5
|
+
* The items to render — one page per item. Switched from slot-based
|
|
6
|
+
* children because horizontal `<scroll-view>` children need explicit
|
|
7
|
+
* pixel widths (Lynx doesn't resolve `width: 100%` against the viewport
|
|
8
|
+
* in a horizontal scroller), so the Swiper has to own the page wrapper.
|
|
9
|
+
*/
|
|
10
|
+
Define.Prop<'items', readonly T[], true>
|
|
11
|
+
/** Per-item renderer. Output is wrapped in a page-width sized `<view>`. */
|
|
12
|
+
& Define.Prop<'renderItem', (item: T, index: number) => unknown, true>
|
|
13
|
+
/** Optional key extractor — defaults to the item's array index. */
|
|
14
|
+
& Define.Prop<'keyExtractor', (item: T, index: number) => string | number, false>
|
|
15
|
+
/**
|
|
16
|
+
* Page width in CSS pixels. Defaults to the Swiper's own measured
|
|
17
|
+
* container width via `useElementLayout`, falling back to
|
|
18
|
+
* `lynx.SystemInfo.pixelWidth / pixelRatio` before the first layout
|
|
19
|
+
* pass.
|
|
20
|
+
*/
|
|
21
|
+
& Define.Prop<'width', number, false>
|
|
22
|
+
/** Page height in CSS pixels — applied to each page wrapper. */
|
|
23
|
+
& Define.Prop<'height', number | string, false>
|
|
24
|
+
/**
|
|
25
|
+
* Externally-observable current page (whole units). Updated from
|
|
26
|
+
* `bindscroll` as the user pans. Writes from outside (e.g.
|
|
27
|
+
* `idx.value = 2`) glide the swiper to that page via the native
|
|
28
|
+
* `<scroll-view>.scrollTo` UI method.
|
|
29
|
+
*/
|
|
30
|
+
& Define.Prop<'index', PrimitiveSignal<number>, false>
|
|
31
|
+
/** Page to render first (uncontrolled-initial). */
|
|
32
|
+
& Define.Prop<'initialIndex', number, false>
|
|
33
|
+
/**
|
|
34
|
+
* MT-thread live pixel offset, updated every scroll frame from the
|
|
35
|
+
* native scroll-view's `scrollLeft`.
|
|
36
|
+
*/
|
|
37
|
+
& Define.Prop<'offset', SharedValue<number>, false> & Define.Prop<'class', string, false> & Define.Prop<'style', Record<string, string | number>, false>
|
|
38
|
+
/** Emitted (BG) when the page-rounded `scrollLeft / width` changes. */
|
|
39
|
+
& Define.Event<'pageChange', {
|
|
40
|
+
index: number;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Paged horizontal carousel built on Lynx's native `<scroll-view
|
|
44
|
+
* paging-enabled>` — native snap, no MTS pan handling required for the
|
|
45
|
+
* happy path. Items are rendered into page-sized `<view>` wrappers (the
|
|
46
|
+
* Swiper owns the sizing so Lynx's horizontal scroller has explicit
|
|
47
|
+
* widths to lay out against; `width: 100%` does NOT resolve to the
|
|
48
|
+
* viewport for `<scroll-view scroll-orientation="horizontal">` children).
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* const idx = signal(0);
|
|
53
|
+
* const offset = useSharedValue(0);
|
|
54
|
+
* <Swiper
|
|
55
|
+
* items={photos}
|
|
56
|
+
* index={idx}
|
|
57
|
+
* offset={offset}
|
|
58
|
+
* renderItem={(src) => (
|
|
59
|
+
* <image src={src} mode="aspectFit" style={{ width: '100%', height: '100%' }} />
|
|
60
|
+
* )}
|
|
61
|
+
* />
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare const Swiper: <T>(props: SwiperProps<T>) => unknown;
|
|
65
|
+
//# sourceMappingURL=Swiper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Swiper.d.ts","sourceRoot":"","sources":["../../src/components/Swiper.tsx"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,WAAW,EAChB,KAAK,MAAM,EAEZ,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAkCxD,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO;AACjC;;;;;GAKG;AACD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC;AAC1C,2EAA2E;GACzE,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,IAAI,CAAC;AACtE,mEAAmE;GACjE,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,EAAE,KAAK,CAAC;AACjF;;;;;GAKG;GACD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;AACrC,gEAAgE;GAC9D,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,CAAC;AAC/C;;;;;GAKG;GACD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC;AACtD,mDAAmD;GACjD,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC;AAC5C;;;GAGG;GACD,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,GACjD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,GACnC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC;AAC9D,uEAAuE;GACrE,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,MAAM,EA+Fb,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { jsx as _jsx } from "@sigx/lynx/jsx-runtime";
|
|
2
|
+
import { component, effect, runOnMainThread, signal, useElementLayout, useMainThreadRef, useSharedValue, } from '@sigx/lynx';
|
|
3
|
+
const SCREEN_WIDTH_FALLBACK = (() => {
|
|
4
|
+
try {
|
|
5
|
+
const info = typeof lynx !== 'undefined' ? lynx?.SystemInfo : undefined;
|
|
6
|
+
const px = info?.pixelWidth;
|
|
7
|
+
const pr = info?.pixelRatio || 1;
|
|
8
|
+
if (typeof px === 'number' && px > 0)
|
|
9
|
+
return Math.round(px / pr);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
/* ignore */
|
|
13
|
+
}
|
|
14
|
+
return 400;
|
|
15
|
+
})();
|
|
16
|
+
const SCREEN_HEIGHT_FALLBACK = (() => {
|
|
17
|
+
try {
|
|
18
|
+
const info = typeof lynx !== 'undefined' ? lynx?.SystemInfo : undefined;
|
|
19
|
+
const px = info?.pixelHeight;
|
|
20
|
+
const pr = info?.pixelRatio || 1;
|
|
21
|
+
if (typeof px === 'number' && px > 0)
|
|
22
|
+
return Math.round(px / pr);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
/* ignore */
|
|
26
|
+
}
|
|
27
|
+
return 800;
|
|
28
|
+
})();
|
|
29
|
+
/**
|
|
30
|
+
* Paged horizontal carousel built on Lynx's native `<scroll-view
|
|
31
|
+
* paging-enabled>` — native snap, no MTS pan handling required for the
|
|
32
|
+
* happy path. Items are rendered into page-sized `<view>` wrappers (the
|
|
33
|
+
* Swiper owns the sizing so Lynx's horizontal scroller has explicit
|
|
34
|
+
* widths to lay out against; `width: 100%` does NOT resolve to the
|
|
35
|
+
* viewport for `<scroll-view scroll-orientation="horizontal">` children).
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* const idx = signal(0);
|
|
40
|
+
* const offset = useSharedValue(0);
|
|
41
|
+
* <Swiper
|
|
42
|
+
* items={photos}
|
|
43
|
+
* index={idx}
|
|
44
|
+
* offset={offset}
|
|
45
|
+
* renderItem={(src) => (
|
|
46
|
+
* <image src={src} mode="aspectFit" style={{ width: '100%', height: '100%' }} />
|
|
47
|
+
* )}
|
|
48
|
+
* />
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export const Swiper = component(({ props, emit }) => {
|
|
52
|
+
const ownOffset = useSharedValue(0);
|
|
53
|
+
const ownIndex = signal(props.initialIndex ?? 0);
|
|
54
|
+
const { layout, onLayoutChange } = useElementLayout();
|
|
55
|
+
const scrollRef = useMainThreadRef(null);
|
|
56
|
+
// Resolve the controlled-vs-uncontrolled signal/offset once at setup so the
|
|
57
|
+
// BG→MT reactive bridge below and the render closure share the same instance.
|
|
58
|
+
const offset = props.offset ?? ownOffset;
|
|
59
|
+
const idx = props.index ?? ownIndex;
|
|
60
|
+
// BG→MT bridge: when external code (or a dot tap) writes `idx.value = N`,
|
|
61
|
+
// we invoke the native `<scroll-view>.scrollTo` UI method on MT so the
|
|
62
|
+
// animation runs with platform physics (the same easing the user gets when
|
|
63
|
+
// they fling-snap). The dedup runs MT-side against the live scroll offset
|
|
64
|
+
// so we don't re-invoke for writes that just mirror a finished snap.
|
|
65
|
+
const scrollOnMT = runOnMainThread((index, pageW) => {
|
|
66
|
+
'main thread';
|
|
67
|
+
const el = scrollRef.current;
|
|
68
|
+
if (!el || pageW <= 0)
|
|
69
|
+
return;
|
|
70
|
+
const target = index * pageW;
|
|
71
|
+
const current = offset.current.value;
|
|
72
|
+
if (Math.abs(current - target) < 0.5)
|
|
73
|
+
return;
|
|
74
|
+
el.invoke('scrollTo', { index, smooth: true });
|
|
75
|
+
});
|
|
76
|
+
effect(() => {
|
|
77
|
+
const v = idx.value;
|
|
78
|
+
if (typeof v !== 'number')
|
|
79
|
+
return;
|
|
80
|
+
const pw = props.width
|
|
81
|
+
?? (layout.value && layout.value.width > 0 ? layout.value.width : undefined)
|
|
82
|
+
?? SCREEN_WIDTH_FALLBACK;
|
|
83
|
+
scrollOnMT(v, pw);
|
|
84
|
+
});
|
|
85
|
+
return () => {
|
|
86
|
+
const pageWidth = props.width
|
|
87
|
+
?? (layout.value && layout.value.width > 0 ? layout.value.width : undefined)
|
|
88
|
+
?? SCREEN_WIDTH_FALLBACK;
|
|
89
|
+
// Lynx horizontal `<scroll-view>` doesn't resolve `height: 100%` on
|
|
90
|
+
// children (same constraint as width), so the page wrapper needs a
|
|
91
|
+
// pixel value. Use the measured layout height when available; the
|
|
92
|
+
// screen-height fallback covers the first paint. Guard against the
|
|
93
|
+
// `0 ?? fallback` gotcha — a zero-sized layout report (e.g. before
|
|
94
|
+
// first paint) must fall through to the fallback.
|
|
95
|
+
const measuredHeight = layout.value && layout.value.height > 0 ? layout.value.height : undefined;
|
|
96
|
+
const pageHeight = props.height
|
|
97
|
+
?? measuredHeight
|
|
98
|
+
?? SCREEN_HEIGHT_FALLBACK;
|
|
99
|
+
const initialScrollLeft = (props.initialIndex ?? 0) * pageWidth;
|
|
100
|
+
const items = props.items;
|
|
101
|
+
const keyOf = props.keyExtractor;
|
|
102
|
+
return (_jsx("scroll-view", { "main-thread:ref": scrollRef, "scroll-orientation": "horizontal", "paging-enabled": true, "show-scrollbar": false, bounces: true, "scroll-left": initialScrollLeft, class: props.class, style: { width: '100%', ...(props.style || {}) }, bindlayoutchange: onLayoutChange, "main-thread-bindscroll": (e) => {
|
|
103
|
+
'main thread';
|
|
104
|
+
offset.current.value = e.detail.scrollLeft;
|
|
105
|
+
const __flush = globalThis['__FlushElementTree'];
|
|
106
|
+
if (__flush)
|
|
107
|
+
__flush();
|
|
108
|
+
}, bindscroll: (e) => {
|
|
109
|
+
if (pageWidth <= 0)
|
|
110
|
+
return;
|
|
111
|
+
const next = Math.round(e.detail.scrollLeft / pageWidth);
|
|
112
|
+
if (next !== idx.value) {
|
|
113
|
+
idx.value = next;
|
|
114
|
+
emit('pageChange', { index: next });
|
|
115
|
+
}
|
|
116
|
+
}, children: items.map((item, i) => (_jsx("view", { style: {
|
|
117
|
+
width: pageWidth + 'px',
|
|
118
|
+
height: typeof pageHeight === 'number' ? pageHeight + 'px' : pageHeight,
|
|
119
|
+
flexShrink: 0,
|
|
120
|
+
flexGrow: 0,
|
|
121
|
+
}, children: props.renderItem(item, i) }, keyOf ? String(keyOf(item, i)) : String(i)))) }));
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=Swiper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Swiper.js","sourceRoot":"","sources":["../../src/components/Swiper.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
export { usePinch } from './use-pinch';
|
|
2
|
-
export { useRotation } from './use-rotation';
|
|
1
|
+
export { usePinch } from './use-pinch.js';
|
|
2
|
+
export { useRotation } from './use-rotation.js';
|
|
3
3
|
export { useSharedValue, SharedValue, useAnimatedValue, AnimatedValue, useAnimatedStyle, resetAnimatedStyleBindingIds, } from '@sigx/lynx';
|
|
4
4
|
export type { SharedValueState, AnimatedValueState, BuiltinMapperName, MapperParams, } from '@sigx/lynx';
|
|
5
|
-
export { Pressable } from './components/Pressable';
|
|
6
|
-
export type { PressableProps } from './components/Pressable';
|
|
7
|
-
export { Draggable } from './components/Draggable';
|
|
8
|
-
export type { DraggableProps, DragEndDetail } from './components/Draggable';
|
|
9
|
-
export { Swipeable } from './components/Swipeable';
|
|
10
|
-
export type { SwipeableProps, SwipeSide } from './components/Swipeable';
|
|
11
|
-
export { ScrollView } from './components/ScrollView';
|
|
12
|
-
export type { ScrollViewProps } from './components/ScrollView';
|
|
13
|
-
export {
|
|
14
|
-
export type {
|
|
15
|
-
export
|
|
5
|
+
export { Pressable } from './components/Pressable.js';
|
|
6
|
+
export type { PressableProps } from './components/Pressable.js';
|
|
7
|
+
export { Draggable } from './components/Draggable.js';
|
|
8
|
+
export type { DraggableProps, DragEndDetail } from './components/Draggable.js';
|
|
9
|
+
export { Swipeable } from './components/Swipeable.js';
|
|
10
|
+
export type { SwipeableProps, SwipeSide } from './components/Swipeable.js';
|
|
11
|
+
export { ScrollView } from './components/ScrollView.js';
|
|
12
|
+
export type { ScrollViewProps } from './components/ScrollView.js';
|
|
13
|
+
export { Swiper } from './components/Swiper.js';
|
|
14
|
+
export type { SwiperProps } from './components/Swiper.js';
|
|
15
|
+
export { useSwiperDotProgress, useSwiperDotScale, useSwiperDotGrowX, useSwiperDotWidth, useSwiperDotTranslate, } from './use-swiper-dot-progress.js';
|
|
16
|
+
export type { SwiperDotHookInputs, UseSwiperDotProgressOptions, UseSwiperDotTranslateOptions, } from './use-swiper-dot-progress.js';
|
|
17
|
+
export { useScrollContext } from './scroll-context.js';
|
|
18
|
+
export type { ScrollContext } from './scroll-context.js';
|
|
19
|
+
export type { TouchPoint, TouchEvent, GesturePhase, GestureHandlers, PinchState, UsePinchOptions, UsePinchReturn, RotationState, UseRotationOptions, UseRotationReturn, } from './types.js';
|
|
16
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOhD,OAAO,EACL,cAAc,EACd,WAAW,EAEX,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,4BAA4B,GAC7B,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,gBAAgB,EAEhB,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,mBAAmB,EACnB,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,8BAA8B,CAAC;AAKtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD,YAAY,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,eAAe,EACf,UAAU,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|