@seakoi/native-ui 1.0.0 → 1.1.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +559 -265
  2. package/dist/commonjs/components/base/carousel/carousel-item.js +21 -0
  3. package/dist/commonjs/components/base/carousel/carousel.js +489 -0
  4. package/dist/commonjs/components/base/carousel/index.js +36 -0
  5. package/dist/commonjs/components/base/carousel/style/index.js +47 -0
  6. package/dist/commonjs/components/base/carousel/types.js +5 -0
  7. package/dist/commonjs/components/base/carousel/utils.js +27 -0
  8. package/dist/commonjs/components/base/index.js +34 -23
  9. package/dist/module/components/base/carousel/carousel-item.js +16 -0
  10. package/dist/module/components/base/carousel/carousel.js +484 -0
  11. package/dist/module/components/base/carousel/index.js +9 -0
  12. package/dist/module/components/base/carousel/style/index.js +43 -0
  13. package/dist/module/components/base/carousel/types.js +3 -0
  14. package/dist/module/components/base/carousel/utils.js +20 -0
  15. package/dist/module/components/base/index.js +1 -0
  16. package/dist/typescript/commonjs/src/components/base/carousel/carousel-item.d.ts +4 -0
  17. package/dist/typescript/commonjs/src/components/base/carousel/carousel-item.d.ts.map +1 -0
  18. package/dist/typescript/commonjs/src/components/base/carousel/carousel.d.ts +7 -0
  19. package/dist/typescript/commonjs/src/components/base/carousel/carousel.d.ts.map +1 -0
  20. package/dist/typescript/commonjs/src/components/base/carousel/index.d.ts +7 -0
  21. package/dist/typescript/commonjs/src/components/base/carousel/index.d.ts.map +1 -0
  22. package/dist/typescript/commonjs/src/components/base/carousel/style/index.d.ts +41 -0
  23. package/dist/typescript/commonjs/src/components/base/carousel/style/index.d.ts.map +1 -0
  24. package/dist/typescript/commonjs/src/components/base/carousel/types.d.ts +113 -0
  25. package/dist/typescript/commonjs/src/components/base/carousel/types.d.ts.map +1 -0
  26. package/dist/typescript/commonjs/src/components/base/carousel/utils.d.ts +6 -0
  27. package/dist/typescript/commonjs/src/components/base/carousel/utils.d.ts.map +1 -0
  28. package/dist/typescript/commonjs/src/components/base/index.d.ts +1 -0
  29. package/dist/typescript/commonjs/src/components/base/index.d.ts.map +1 -1
  30. package/dist/typescript/module/src/components/base/carousel/carousel-item.d.ts +4 -0
  31. package/dist/typescript/module/src/components/base/carousel/carousel-item.d.ts.map +1 -0
  32. package/dist/typescript/module/src/components/base/carousel/carousel.d.ts +7 -0
  33. package/dist/typescript/module/src/components/base/carousel/carousel.d.ts.map +1 -0
  34. package/dist/typescript/module/src/components/base/carousel/index.d.ts +7 -0
  35. package/dist/typescript/module/src/components/base/carousel/index.d.ts.map +1 -0
  36. package/dist/typescript/module/src/components/base/carousel/style/index.d.ts +41 -0
  37. package/dist/typescript/module/src/components/base/carousel/style/index.d.ts.map +1 -0
  38. package/dist/typescript/module/src/components/base/carousel/types.d.ts +113 -0
  39. package/dist/typescript/module/src/components/base/carousel/types.d.ts.map +1 -0
  40. package/dist/typescript/module/src/components/base/carousel/utils.d.ts +6 -0
  41. package/dist/typescript/module/src/components/base/carousel/utils.d.ts.map +1 -0
  42. package/dist/typescript/module/src/components/base/index.d.ts +1 -0
  43. package/dist/typescript/module/src/components/base/index.d.ts.map +1 -1
  44. package/package.json +3 -2
  45. package/src/components/base/carousel/carousel-item.tsx +11 -0
  46. package/src/components/base/carousel/carousel.tsx +691 -0
  47. package/src/components/base/carousel/index.ts +8 -0
  48. package/src/components/base/carousel/style/index.ts +42 -0
  49. package/src/components/base/carousel/types.ts +134 -0
  50. package/src/components/base/carousel/utils.ts +26 -0
  51. package/src/components/base/index.ts +1 -0
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.CarouselItem = void 0;
7
+ var _reactNative = require("react-native");
8
+ var _jsxRuntime = require("react/jsx-runtime");
9
+ const CarouselItem = ({
10
+ children,
11
+ style
12
+ }) => {
13
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
14
+ style: [{
15
+ height: '100%',
16
+ width: '100%'
17
+ }, style],
18
+ children: children
19
+ });
20
+ };
21
+ exports.CarouselItem = CarouselItem;
@@ -0,0 +1,489 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Carousel = void 0;
7
+ var _lodashEs = require("lodash-es");
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _reactNative = require("react-native");
10
+ var _utils = require("./utils.js");
11
+ var _index = require("../../../native-provider/index.js");
12
+ var _index2 = require("./style/index.js");
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
15
+ const getBoundaryIndexRange = ({
16
+ total,
17
+ slideSize,
18
+ trackOffset,
19
+ stuckAtBoundary
20
+ }) => {
21
+ if (total <= 0) return {
22
+ min: 0,
23
+ max: 0
24
+ };
25
+ if (!stuckAtBoundary) return {
26
+ min: 0,
27
+ max: total - 1
28
+ };
29
+ const slideRatio = slideSize / 100;
30
+ const offsetRatio = trackOffset / 100;
31
+ const min = 0 + offsetRatio / (slideRatio || 1);
32
+ const max = total - 1 - (1 - slideRatio - offsetRatio) / (slideRatio || 1);
33
+ return {
34
+ min,
35
+ max
36
+ };
37
+ };
38
+ /**
39
+ * 轮播图
40
+ */
41
+ const Carousel = exports.Carousel = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
42
+ const {
43
+ defaultIndex = 0,
44
+ allowTouchMove = true,
45
+ autoplay = false,
46
+ autoplayInterval = 3000,
47
+ loop = false,
48
+ direction = 'horizontal',
49
+ onIndexChange,
50
+ indicatorProps,
51
+ indicator,
52
+ slideSize = 100,
53
+ trackOffset = 0,
54
+ stuckAtBoundary = true,
55
+ rubberband = true,
56
+ virtualOverscan = 2,
57
+ total: totalProp,
58
+ children,
59
+ style
60
+ } = props;
61
+ const styles = (0, _index2.useCarouselStyles)();
62
+ const theme = (0, _index.useTheme)();
63
+ const [layout, setLayout] = (0, _react.useState)({
64
+ width: 0,
65
+ height: 0
66
+ });
67
+ const [dragging, setDragging] = (0, _react.useState)(false);
68
+ const [animating, setAnimating] = (0, _react.useState)(false);
69
+ const [current, setCurrent] = (0, _react.useState)(0);
70
+ const position = (0, _react.useRef)(new _reactNative.Animated.Value(0));
71
+ const positionValueRef = (0, _react.useRef)(0);
72
+ const normalizedSlideSize = (0, _react.useMemo)(() => {
73
+ if (!Number.isFinite(slideSize)) return 100;
74
+ return (0, _lodashEs.clamp)(slideSize, 0, 100);
75
+ }, [slideSize]);
76
+ const normalizedTrackOffset = (0, _react.useMemo)(() => {
77
+ if (stuckAtBoundary) {
78
+ return 100 - normalizedSlideSize;
79
+ }
80
+ if (!Number.isFinite(trackOffset)) return 0;
81
+ return (0, _lodashEs.clamp)(trackOffset, 0, 100 - normalizedSlideSize);
82
+ }, [normalizedSlideSize, trackOffset, stuckAtBoundary]);
83
+ const total = (0, _react.useMemo)(() => {
84
+ const normalizedDefault = (0, _utils.getDefaultTotal)(children);
85
+ return totalProp ?? normalizedDefault;
86
+ }, [children, totalProp]);
87
+ const loopEnabled = loop && total > 1;
88
+ // 若是非全屏的轮播项,则在循环播放开启的情况下,则会在下一轮展示第一项时看见下一项为空白(或闪烁),这需要额外渲染更多的项(与offset、slideSize相关)
89
+ const clonesBefore = loopEnabled ? Math.max(1, normalizedSlideSize > 0 ? Math.ceil(normalizedTrackOffset / normalizedSlideSize) + 1 : 1) : 0;
90
+ const clonesAfter = loopEnabled ? Math.max(1, normalizedSlideSize > 0 ? Math.ceil((100 - normalizedTrackOffset - normalizedSlideSize) / normalizedSlideSize) + 1 : 1) : 0;
91
+ const extTotal = loopEnabled ? total + clonesBefore + clonesAfter : total;
92
+ const slidePixels = (0, _react.useMemo)(() => {
93
+ const trackSize = direction === 'horizontal' ? layout.width : layout.height;
94
+ if (trackSize <= 0) return 0;
95
+ return trackSize * (normalizedSlideSize / 100);
96
+ }, [direction, layout.height, layout.width, normalizedSlideSize]);
97
+ const trackOffsetPixels = (0, _react.useMemo)(() => {
98
+ const trackSize = direction === 'horizontal' ? layout.width : layout.height;
99
+ if (trackSize <= 0) return 0;
100
+ return trackSize * (normalizedTrackOffset / 100);
101
+ }, [direction, layout.height, layout.width, normalizedTrackOffset]);
102
+ const extIndexRef = (0, _react.useRef)(0);
103
+ const reportIndexRef = (0, _react.useRef)(null);
104
+ const staticSlides = (0, _react.useMemo)(() => {
105
+ if ((0, _utils.isRenderPropChildren)(children)) return [];
106
+ return (0, _utils.normalizeChildren)(children, total);
107
+ }, [children, total]);
108
+ const updateCurrent = (0, _react.useCallback)(next => {
109
+ const normalized = total > 0 ? (0, _lodashEs.clamp)(next, 0, total - 1) : 0;
110
+ setCurrent(normalized);
111
+ }, [total]);
112
+ const maybeReportIndex = (0, _react.useCallback)(index => {
113
+ if (!onIndexChange) return;
114
+ if (reportIndexRef.current === index) return;
115
+ reportIndexRef.current = index;
116
+ onIndexChange(index);
117
+ }, [onIndexChange]);
118
+ const getExtIndexFromIndex = (0, _react.useCallback)(index => {
119
+ if (!loopEnabled) return index;
120
+ return (0, _lodashEs.clamp)(index, 0, total - 1) + clonesBefore;
121
+ }, [clonesBefore, loopEnabled, total]);
122
+ const getIndexFromExtIndex = (0, _react.useCallback)(extIndex => {
123
+ if (!loopEnabled) return (0, _lodashEs.clamp)(extIndex, 0, total - 1);
124
+ if (extIndex < clonesBefore) {
125
+ return ((extIndex - clonesBefore) % total + total) % total;
126
+ }
127
+ if (extIndex >= clonesBefore + total) {
128
+ return (extIndex - clonesBefore - total) % total;
129
+ }
130
+ return extIndex - clonesBefore;
131
+ }, [clonesBefore, loopEnabled, total]);
132
+ const getTargetExtIndexForIndex = (0, _react.useCallback)(targetIndex => {
133
+ if (!loopEnabled) return (0, _lodashEs.clamp)(targetIndex, 0, total - 1);
134
+ const currentExt = extIndexRef.current;
135
+ const normalizedTarget = (0, _lodashEs.clamp)(targetIndex, 0, total - 1);
136
+ const targetExt = normalizedTarget + clonesBefore;
137
+ if (currentExt === clonesBefore && normalizedTarget === total - 1) return clonesBefore - 1;
138
+ if (currentExt === clonesBefore + total - 1 && normalizedTarget === 0) return clonesBefore + total;
139
+ return targetExt;
140
+ }, [clonesBefore, loopEnabled, total]);
141
+ const getBoundedPosition = (0, _react.useCallback)(nextPosition => {
142
+ if (loopEnabled) return nextPosition;
143
+ if (slidePixels <= 0) return nextPosition;
144
+ if (total <= 0) return 0;
145
+ const {
146
+ min,
147
+ max
148
+ } = getBoundaryIndexRange({
149
+ total,
150
+ slideSize: normalizedSlideSize,
151
+ trackOffset: normalizedTrackOffset,
152
+ stuckAtBoundary
153
+ });
154
+ const minPos = min * slidePixels;
155
+ const maxPos = max * slidePixels;
156
+ if (nextPosition < minPos) {
157
+ if (!rubberband) return minPos;
158
+ return minPos - (minPos - nextPosition) * 0.35;
159
+ }
160
+ if (nextPosition > maxPos) {
161
+ if (!rubberband) return maxPos;
162
+ return maxPos + (nextPosition - maxPos) * 0.35;
163
+ }
164
+ return nextPosition;
165
+ }, [loopEnabled, rubberband, slidePixels, normalizedSlideSize, stuckAtBoundary, total, normalizedTrackOffset]);
166
+ const animateTo = (0, _react.useCallback)((toValue, onFinished) => {
167
+ const listenerId = position.current.addListener(({
168
+ value
169
+ }) => {
170
+ positionValueRef.current = value;
171
+ });
172
+ _reactNative.Animated.timing(position.current, {
173
+ toValue,
174
+ duration: 300,
175
+ easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
176
+ useNativeDriver: true
177
+ }).start(({
178
+ finished
179
+ }) => {
180
+ position.current.removeListener(listenerId);
181
+ if (finished) {
182
+ positionValueRef.current = toValue;
183
+ onFinished?.();
184
+ }
185
+ });
186
+ }, []);
187
+ const setPositionImmediate = (0, _react.useCallback)(toValue => {
188
+ position.current.stopAnimation();
189
+ position.current.setValue(toValue);
190
+ positionValueRef.current = toValue;
191
+ }, []);
192
+ const finalizeLoopJumpIfNeeded = (0, _react.useCallback)(() => {
193
+ if (!loopEnabled) return;
194
+ const currentExt = extIndexRef.current;
195
+ if (currentExt < clonesBefore) {
196
+ const targetExt = currentExt + total;
197
+ extIndexRef.current = targetExt;
198
+ if (slidePixels > 0) setPositionImmediate(targetExt * slidePixels);
199
+ return;
200
+ }
201
+ if (currentExt >= clonesBefore + total) {
202
+ const targetExt = currentExt - total;
203
+ extIndexRef.current = targetExt;
204
+ if (slidePixels > 0) setPositionImmediate(targetExt * slidePixels);
205
+ }
206
+ }, [clonesBefore, loopEnabled, setPositionImmediate, slidePixels, total]);
207
+ const swipeToExtIndex = (0, _react.useCallback)(targetExtIndex => {
208
+ if (total <= 0) return;
209
+ if (slidePixels <= 0) {
210
+ extIndexRef.current = (0, _lodashEs.clamp)(targetExtIndex, 0, extTotal - 1);
211
+ setAnimating(false);
212
+ updateCurrent(getIndexFromExtIndex(extIndexRef.current));
213
+ return;
214
+ }
215
+ const boundedExtIndex = (0, _lodashEs.clamp)(targetExtIndex, 0, extTotal - 1);
216
+ extIndexRef.current = boundedExtIndex;
217
+ const nextIndex = getIndexFromExtIndex(boundedExtIndex);
218
+ updateCurrent(nextIndex);
219
+ const rawPosition = boundedExtIndex * slidePixels;
220
+ const toPosition = getBoundedPosition(rawPosition);
221
+ setAnimating(true);
222
+ animateTo(toPosition, () => {
223
+ finalizeLoopJumpIfNeeded();
224
+ const normalizedIndex = getIndexFromExtIndex(extIndexRef.current);
225
+ updateCurrent(normalizedIndex);
226
+ maybeReportIndex(normalizedIndex);
227
+ setAnimating(false);
228
+ });
229
+ }, [animateTo, extTotal, finalizeLoopJumpIfNeeded, getBoundedPosition, getIndexFromExtIndex, maybeReportIndex, slidePixels, total, updateCurrent]);
230
+ const swipeTo = (0, _react.useCallback)(index => {
231
+ if (total <= 0) return;
232
+ const targetIndex = (0, _lodashEs.clamp)(Math.round(index), 0, total - 1);
233
+ const targetExtIndex = getTargetExtIndexForIndex(targetIndex);
234
+ swipeToExtIndex(targetExtIndex);
235
+ }, [getTargetExtIndexForIndex, swipeToExtIndex, total]);
236
+ const swipeNext = (0, _react.useCallback)(() => {
237
+ if (total <= 1) return;
238
+ let currentExt = extIndexRef.current;
239
+ // 若当前处于 after-clone 区域(快速连击导致 finalizeLoopJumpIfNeeded 尚未执行),
240
+ // 立即将位置平移回真实 item 区域(视觉内容相同,不可感知),再继续前进
241
+ if (clonesBefore > 0 && currentExt >= clonesBefore + total) {
242
+ currentExt -= total;
243
+ extIndexRef.current = currentExt;
244
+ if (slidePixels > 0) setPositionImmediate(currentExt * slidePixels);
245
+ }
246
+ swipeToExtIndex(currentExt + 1);
247
+ }, [clonesBefore, setPositionImmediate, slidePixels, swipeToExtIndex, total]);
248
+ const swipePrev = (0, _react.useCallback)(() => {
249
+ if (total <= 1) return;
250
+ let currentExt = extIndexRef.current;
251
+ // 若当前处于 before-clone 区域(快速连击导致 finalizeLoopJumpIfNeeded 尚未执行),
252
+ // 立即将位置平移回真实 item 区域(视觉内容相同,不可感知),再继续后退
253
+ if (clonesBefore > 0 && currentExt < clonesBefore) {
254
+ currentExt += total;
255
+ extIndexRef.current = currentExt;
256
+ if (slidePixels > 0) setPositionImmediate(currentExt * slidePixels);
257
+ }
258
+ swipeToExtIndex(currentExt - 1);
259
+ }, [clonesBefore, setPositionImmediate, slidePixels, swipeToExtIndex, total]);
260
+ (0, _react.useImperativeHandle)(ref, () => ({
261
+ swipeTo,
262
+ swipeNext,
263
+ swipePrev
264
+ }), [swipeNext, swipePrev, swipeTo]);
265
+ (0, _react.useEffect)(() => {
266
+ if (total <= 0) {
267
+ updateCurrent(0);
268
+ reportIndexRef.current = null;
269
+ extIndexRef.current = 0;
270
+ setPositionImmediate(0);
271
+ return;
272
+ }
273
+ const normalizedDefault = (0, _lodashEs.clamp)(Math.round(defaultIndex), 0, total - 1);
274
+ updateCurrent(normalizedDefault);
275
+ reportIndexRef.current = normalizedDefault;
276
+ const extIndex = getExtIndexFromIndex(normalizedDefault);
277
+ extIndexRef.current = extIndex;
278
+ if (slidePixels > 0) {
279
+ setPositionImmediate(getBoundedPosition(extIndex * slidePixels));
280
+ }
281
+ }, [defaultIndex, getExtIndexFromIndex, getBoundedPosition, setPositionImmediate, slidePixels, total, updateCurrent]);
282
+ (0, _react.useEffect)(() => {
283
+ if (slidePixels <= 0) return;
284
+ const extIndex = extIndexRef.current;
285
+ setPositionImmediate(getBoundedPosition(extIndex * slidePixels));
286
+ }, [getBoundedPosition, setPositionImmediate, slidePixels]);
287
+
288
+ // 每当 current 变化时,若允许自动轮播 且 开启了自动轮播,则执行轮播
289
+ (0, _react.useEffect)(() => {
290
+ if (!autoplay) return;
291
+ if (total <= 1) return;
292
+ if (dragging) return;
293
+ if (autoplayInterval <= 0) return;
294
+ const timer = setTimeout(() => {
295
+ if (autoplay === 'reverse') swipePrev();else swipeNext();
296
+ }, autoplayInterval);
297
+ return () => {
298
+ clearTimeout(timer);
299
+ };
300
+ }, [autoplay, autoplayInterval, dragging, swipeNext, swipePrev, total, current]);
301
+ const onLayoutTrack = (0, _react.useCallback)(e => {
302
+ const {
303
+ width,
304
+ height
305
+ } = e.nativeEvent.layout;
306
+ setLayout(prev => {
307
+ if (prev.width === width && prev.height === height) return prev;
308
+ return {
309
+ width,
310
+ height
311
+ };
312
+ });
313
+ }, []);
314
+ const panResponder = (0, _react.useMemo)(() => {
315
+ if (!allowTouchMove) return null;
316
+ if (total <= 1) return null;
317
+ if (slidePixels <= 0) return null;
318
+ let startPosition = 0;
319
+ const axis = direction === 'horizontal' ? 'x' : 'y';
320
+ const shouldSet = (_, gestureState) => {
321
+ const primary = axis === 'x' ? gestureState.dx : gestureState.dy;
322
+ // const secondary = axis === 'x' ? gestureState.dy : gestureState.dx;
323
+ if (Math.abs(primary) < 5) return false;
324
+ // return Math.abs(primary) >= Math.abs(secondary);
325
+ return true;
326
+ };
327
+ return _reactNative.PanResponder.create({
328
+ onMoveShouldSetPanResponder: shouldSet,
329
+ onPanResponderGrant: () => {
330
+ setDragging(true);
331
+ setAnimating(false);
332
+ position.current.stopAnimation();
333
+ startPosition = positionValueRef.current;
334
+ },
335
+ onPanResponderMove: (_evt, gestureState) => {
336
+ const delta = axis === 'x' ? gestureState.dx : gestureState.dy;
337
+ let nextPosition = startPosition - delta;
338
+
339
+ // loop 开启时,拖动到最外层有效克隆中心之外则循环偏移,保证视口内始终有内容
340
+ // minPos/maxPos 是 outermost before/after clone 的中心位置,由 clonesBefore 公式保证此范围内视口始终被覆盖
341
+ if (extTotal > total && slidePixels > 0) {
342
+ const totalPixels = total * slidePixels;
343
+ const minPos = (clonesBefore - 1) * slidePixels;
344
+ const maxPos = (clonesBefore + total) * slidePixels;
345
+ while (nextPosition < minPos) {
346
+ nextPosition += totalPixels;
347
+ startPosition += totalPixels;
348
+ }
349
+ while (nextPosition > maxPos) {
350
+ nextPosition -= totalPixels;
351
+ startPosition -= totalPixels;
352
+ }
353
+ }
354
+ const bounded = getBoundedPosition(nextPosition);
355
+ position.current.setValue(bounded);
356
+ positionValueRef.current = bounded;
357
+ const nextExtIndex = (0, _lodashEs.clamp)(Math.round(bounded / slidePixels), 0, extTotal - 1);
358
+ extIndexRef.current = nextExtIndex;
359
+ updateCurrent(getIndexFromExtIndex(nextExtIndex));
360
+ },
361
+ onPanResponderRelease: (_evt, gestureState) => {
362
+ setDragging(false);
363
+ const velocity = axis === 'x' ? gestureState.vx : gestureState.vy;
364
+ position.current.stopAnimation(value => {
365
+ const baseIndex = value / slidePixels;
366
+ const projectedIndex = (value - velocity * 2000) / slidePixels;
367
+ const minAdj = Math.floor(baseIndex);
368
+ const maxAdj = minAdj + 1;
369
+ const rounded = Math.round(projectedIndex);
370
+ const adjacent = (0, _lodashEs.clamp)(rounded, minAdj, maxAdj);
371
+ swipeToExtIndex(adjacent);
372
+ });
373
+ },
374
+ onPanResponderTerminate: () => {
375
+ setDragging(false);
376
+ swipeToExtIndex(extIndexRef.current);
377
+ },
378
+ onPanResponderTerminationRequest: () => false,
379
+ onShouldBlockNativeResponder: () => true
380
+ });
381
+ }, [allowTouchMove, clonesBefore, direction, extTotal, getBoundedPosition, getIndexFromExtIndex, slidePixels, swipeToExtIndex, total, updateCurrent]);
382
+ const trackTransformStyle = (0, _react.useMemo)(() => {
383
+ const translate = _reactNative.Animated.add(_reactNative.Animated.multiply(position.current, -1), trackOffsetPixels);
384
+ return direction === 'horizontal' ? {
385
+ transform: [{
386
+ translateX: translate
387
+ }]
388
+ } : {
389
+ transform: [{
390
+ translateY: translate
391
+ }]
392
+ };
393
+ }, [direction, trackOffsetPixels]);
394
+ const renderSlides = (0, _react.useCallback)(() => {
395
+ if (total <= 0) return null;
396
+ if (slidePixels <= 0) return null;
397
+ const isVirtual = (0, _utils.isRenderPropChildren)(children) && typeof totalProp === 'number';
398
+ const effectiveOverscan = isVirtual ? Math.max(virtualOverscan, dragging || animating ? 1 : 0) : virtualOverscan;
399
+ const currentExtIndex = extIndexRef.current;
400
+ const start = isVirtual ? (0, _lodashEs.clamp)(currentExtIndex - effectiveOverscan, 0, extTotal - 1) : 0;
401
+ const end = isVirtual ? (0, _lodashEs.clamp)(currentExtIndex + effectiveOverscan, 0, extTotal - 1) : extTotal - 1;
402
+ const leadingSize = start * slidePixels;
403
+ const trailingSize = (extTotal - end - 1) * slidePixels;
404
+ const leadSpacerStyle = direction === 'horizontal' ? {
405
+ width: leadingSize
406
+ } : {
407
+ height: leadingSize
408
+ };
409
+ const trailSpacerStyle = direction === 'horizontal' ? {
410
+ width: trailingSize
411
+ } : {
412
+ height: trailingSize
413
+ };
414
+ const slideWrapperBaseStyle = direction === 'horizontal' ? {
415
+ width: slidePixels,
416
+ height: '100%'
417
+ } : {
418
+ height: slidePixels,
419
+ width: '100%'
420
+ };
421
+ const getElementForExtIndex = extIndex => {
422
+ const logicalIndex = loopEnabled ? getIndexFromExtIndex(extIndex) : (0, _lodashEs.clamp)(extIndex, 0, total - 1);
423
+ if ((0, _utils.isRenderPropChildren)(children)) return children(logicalIndex);
424
+ return staticSlides[logicalIndex];
425
+ };
426
+ const slideElements = [];
427
+ for (let extIndex = start; extIndex <= end; extIndex += 1) {
428
+ const element = getElementForExtIndex(extIndex);
429
+ if (!element) continue;
430
+ slideElements.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
431
+ style: [styles.slide, slideWrapperBaseStyle],
432
+ children: element
433
+ }, extIndex));
434
+ }
435
+ const leadSpacer = isVirtual && leadingSize > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
436
+ style: leadSpacerStyle
437
+ }) : null;
438
+ const trailSpacer = isVirtual && trailingSize > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
439
+ style: trailSpacerStyle
440
+ }) : null;
441
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
442
+ children: [leadSpacer, slideElements, trailSpacer]
443
+ });
444
+ }, [children, direction, extTotal, getIndexFromExtIndex, dragging, animating, loopEnabled, slidePixels, staticSlides, styles.slide, total, totalProp, virtualOverscan]);
445
+ const renderIndicator = (0, _react.useCallback)(() => {
446
+ if (indicator === false) return null;
447
+ if (total <= 1) return null;
448
+ if (typeof indicator === 'function') {
449
+ return indicator(total, current);
450
+ }
451
+ const activeColor = indicatorProps?.color ?? theme.palette.brand7;
452
+ const inactiveColor = theme.palette.fontGray5;
453
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
454
+ style: _reactNative.StyleSheet.flatten([styles.indicatorContainer, indicatorProps?.style]),
455
+ children: Array.from({
456
+ length: total
457
+ }, (_, i) => {
458
+ const isActive = i === current;
459
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
460
+ style: _reactNative.StyleSheet.flatten([styles.indicatorDot, {
461
+ backgroundColor: isActive ? activeColor : inactiveColor
462
+ }, isActive && styles.indicatorDotActive])
463
+ }, i);
464
+ })
465
+ });
466
+ }, [current, indicator, indicatorProps?.color, indicatorProps?.style, styles.indicatorContainer, styles.indicatorDot, styles.indicatorDotActive, theme.palette.brand7, theme.palette.fontGray5, total]);
467
+ const trackInnerStyle = (0, _react.useMemo)(() => {
468
+ return direction === 'horizontal' ? {
469
+ flexDirection: 'row',
470
+ height: '100%'
471
+ } : {
472
+ flexDirection: 'column',
473
+ width: '100%'
474
+ };
475
+ }, [direction]);
476
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
477
+ style: _reactNative.StyleSheet.flatten([styles.container, style]),
478
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
479
+ style: styles.track,
480
+ onLayout: onLayoutTrack,
481
+ ...panResponder?.panHandlers,
482
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
483
+ style: _reactNative.StyleSheet.flatten([styles.trackInner, trackInnerStyle, trackTransformStyle]),
484
+ children: renderSlides()
485
+ }), renderIndicator()]
486
+ })
487
+ });
488
+ });
489
+ Carousel.displayName = 'Carousel';
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _exportNames = {
7
+ Carousel: true
8
+ };
9
+ exports.Carousel = void 0;
10
+ var _carousel = require("./carousel.js");
11
+ Object.keys(_carousel).forEach(function (key) {
12
+ if (key === "default" || key === "__esModule") return;
13
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
14
+ if (key in exports && exports[key] === _carousel[key]) return;
15
+ Object.defineProperty(exports, key, {
16
+ enumerable: true,
17
+ get: function () {
18
+ return _carousel[key];
19
+ }
20
+ });
21
+ });
22
+ var _carouselItem = require("./carousel-item.js");
23
+ Object.keys(_carouselItem).forEach(function (key) {
24
+ if (key === "default" || key === "__esModule") return;
25
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
26
+ if (key in exports && exports[key] === _carouselItem[key]) return;
27
+ Object.defineProperty(exports, key, {
28
+ enumerable: true,
29
+ get: function () {
30
+ return _carouselItem[key];
31
+ }
32
+ });
33
+ });
34
+ const Carousel = exports.Carousel = Object.assign(_carousel.Carousel, {
35
+ Item: _carouselItem.CarouselItem
36
+ });
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useCarouselStyles = void 0;
7
+ var _index = require("../../../../native-provider/index.js");
8
+ const useCarouselStyles = exports.useCarouselStyles = (0, _index.createThemedStyles)(theme => ({
9
+ container: {
10
+ overflow: 'hidden',
11
+ height: '100%',
12
+ width: '100%'
13
+ },
14
+ track: {
15
+ flex: 1,
16
+ overflow: 'hidden'
17
+ },
18
+ trackInner: {
19
+ flexGrow: 0,
20
+ flexShrink: 0
21
+ },
22
+ slide: {
23
+ flexGrow: 0,
24
+ flexShrink: 0,
25
+ overflow: 'hidden'
26
+ },
27
+ indicatorContainer: {
28
+ position: 'absolute',
29
+ left: 0,
30
+ right: 0,
31
+ bottom: 8,
32
+ flexDirection: 'row',
33
+ justifyContent: 'center',
34
+ alignItems: 'center',
35
+ gap: 6
36
+ },
37
+ indicatorDot: {
38
+ width: 6,
39
+ height: 6,
40
+ borderRadius: theme.roundness.full,
41
+ backgroundColor: theme.palette.fontGray5,
42
+ opacity: 0.6
43
+ },
44
+ indicatorDotActive: {
45
+ opacity: 1
46
+ }
47
+ }));
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.normalizeChildren = exports.isRenderPropChildren = exports.getDefaultTotal = void 0;
7
+ var _react = require("react");
8
+ const isRenderPropChildren = children => {
9
+ return typeof children === 'function';
10
+ };
11
+ exports.isRenderPropChildren = isRenderPropChildren;
12
+ const normalizeChildren = (children, total) => {
13
+ if (!children) return [];
14
+ if (isRenderPropChildren(children)) {
15
+ return Array.from({
16
+ length: total
17
+ }, (_, i) => children(i));
18
+ }
19
+ return _react.Children.toArray(children);
20
+ };
21
+ exports.normalizeChildren = normalizeChildren;
22
+ const getDefaultTotal = children => {
23
+ if (!children) return 0;
24
+ if (isRenderPropChildren(children)) return 0;
25
+ return Array.isArray(children) ? children.length : 1;
26
+ };
27
+ exports.getDefaultTotal = getDefaultTotal;