@xaui/native 0.0.17 → 0.0.19

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 (52) hide show
  1. package/dist/accordion/index.js +2 -2
  2. package/dist/alert/index.js +352 -4
  3. package/dist/autocomplete/index.js +1121 -5
  4. package/dist/avatar/index.js +276 -5
  5. package/dist/badge/index.js +193 -4
  6. package/dist/bottom-sheet/index.js +364 -4
  7. package/dist/button/index.js +2 -2
  8. package/dist/card/index.cjs +429 -0
  9. package/dist/card/index.d.cts +186 -0
  10. package/dist/card/index.d.ts +186 -0
  11. package/dist/card/index.js +336 -0
  12. package/dist/carousel/index.js +377 -3
  13. package/dist/checkbox/index.js +1 -1
  14. package/dist/chip/index.js +497 -6
  15. package/dist/{chunk-VUVE6PK7.js → chunk-F7WH4DMG.js} +1 -1
  16. package/dist/{chunk-TJ2FPLLZ.js → chunk-JEGEPGVU.js} +2 -2
  17. package/dist/{chunk-MZL77KV5.js → chunk-LTKYHG5V.js} +1 -1
  18. package/dist/{chunk-RIVFFZRO.js → chunk-LUBWRVI2.js} +1 -1
  19. package/dist/core/index.cjs +1 -1
  20. package/dist/core/index.js +1 -1
  21. package/dist/datepicker/index.js +1623 -4
  22. package/dist/divider/index.js +2 -2
  23. package/dist/fab/index.js +3 -3
  24. package/dist/fab-menu/index.js +324 -6
  25. package/dist/index.cjs +0 -6446
  26. package/dist/index.d.cts +2 -19
  27. package/dist/index.d.ts +2 -19
  28. package/dist/index.js +0 -73
  29. package/dist/indicator/index.js +2 -2
  30. package/dist/menu/index.js +1 -1
  31. package/dist/progress/index.js +1 -1
  32. package/dist/segment-button/index.cjs +2 -2
  33. package/dist/segment-button/index.js +400 -5
  34. package/dist/select/index.js +1 -1
  35. package/dist/skeleton/index.cjs +160 -0
  36. package/dist/skeleton/index.d.cts +45 -0
  37. package/dist/skeleton/index.d.ts +45 -0
  38. package/dist/skeleton/index.js +89 -0
  39. package/dist/switch/index.js +1 -1
  40. package/dist/typography/index.js +146 -4
  41. package/package.json +11 -1
  42. package/dist/chunk-6PXMB5CH.js +0 -503
  43. package/dist/chunk-DBKVHMSA.js +0 -329
  44. package/dist/chunk-EW5YLICE.js +0 -382
  45. package/dist/chunk-JJOVGRNI.js +0 -1627
  46. package/dist/chunk-K2HSVISE.js +0 -281
  47. package/dist/chunk-OXVIVNIJ.js +0 -356
  48. package/dist/chunk-PWCUULAL.js +0 -150
  49. package/dist/chunk-S3MGBM3G.js +0 -368
  50. package/dist/chunk-STUNTRKJ.js +0 -405
  51. package/dist/chunk-UGDGCMGC.js +0 -197
  52. package/dist/chunk-XUYIAA3A.js +0 -1127
@@ -1,329 +0,0 @@
1
- import {
2
- Fab
3
- } from "./chunk-TJ2FPLLZ.js";
4
- import {
5
- Portal,
6
- useXUITheme
7
- } from "./chunk-MZL77KV5.js";
8
-
9
- // src/components/fab-menu/fab-menu.tsx
10
- import React from "react";
11
- import { Pressable, View, Animated as Animated2 } from "react-native";
12
-
13
- // src/components/fab-menu/fab-menu.style.ts
14
- import { StyleSheet } from "react-native";
15
- var styles = StyleSheet.create({
16
- container: {
17
- position: "relative",
18
- alignItems: "flex-end"
19
- },
20
- portalRoot: {
21
- ...StyleSheet.absoluteFillObject
22
- },
23
- overlay: {
24
- ...StyleSheet.absoluteFillObject
25
- },
26
- overlayPressable: {
27
- flex: 1
28
- },
29
- portalContent: {
30
- ...StyleSheet.absoluteFillObject,
31
- justifyContent: "flex-end",
32
- alignItems: "flex-end",
33
- padding: 16
34
- },
35
- menuContainer: {
36
- alignItems: "flex-end",
37
- marginBottom: 16
38
- },
39
- menuItem: {
40
- marginBottom: 12
41
- },
42
- menuItemChip: {
43
- flexDirection: "row",
44
- alignItems: "center",
45
- paddingVertical: 12,
46
- paddingLeft: 16,
47
- paddingRight: 20,
48
- gap: 8
49
- },
50
- menuItemLabel: {
51
- fontWeight: "500"
52
- },
53
- disabled: {
54
- opacity: 0.5
55
- }
56
- });
57
-
58
- // src/components/fab-menu/fab-menu.hook.ts
59
- import { useMemo, useState, useCallback } from "react";
60
- import { getSafeThemeColor } from "@xaui/core";
61
- function useFabMenuState(controlledExpanded, onToggle) {
62
- const [internalExpanded, setInternalExpanded] = useState(false);
63
- const isControlled = controlledExpanded !== void 0;
64
- const expanded = isControlled ? controlledExpanded : internalExpanded;
65
- const toggle = useCallback(() => {
66
- const next = !expanded;
67
- if (!isControlled) {
68
- setInternalExpanded(next);
69
- }
70
- onToggle?.(next);
71
- }, [expanded, isControlled, onToggle]);
72
- const close = useCallback(() => {
73
- if (!isControlled) {
74
- setInternalExpanded(false);
75
- }
76
- onToggle?.(false);
77
- }, [isControlled, onToggle]);
78
- return { expanded, toggle, close };
79
- }
80
- function useFabMenuItemStyles(themeColor) {
81
- const theme = useXUITheme();
82
- const safeThemeColor = getSafeThemeColor(themeColor);
83
- const colorScheme = theme.colors[safeThemeColor];
84
- const itemStyles = useMemo(() => {
85
- const chipStyles = {
86
- backgroundColor: colorScheme.background,
87
- borderRadius: theme.borderRadius.full,
88
- color: colorScheme.main,
89
- fontSize: theme.fontSizes.md
90
- };
91
- const iconColor = colorScheme.main;
92
- return { chipStyles, iconColor };
93
- }, [colorScheme, theme]);
94
- return itemStyles;
95
- }
96
- function useFabMenuOverlayColor() {
97
- const theme = useXUITheme();
98
- return useMemo(() => {
99
- return theme.mode === "dark" ? "rgba(0, 0, 0, 0.5)" : "rgba(0, 0, 0, 0.3)";
100
- }, [theme.mode]);
101
- }
102
-
103
- // src/components/fab-menu/fab-menu.animation.ts
104
- import { Animated } from "react-native";
105
- var runMenuExpandAnimation = (overlayOpacity, itemAnimations) => {
106
- const itemSequence = itemAnimations.map(
107
- (anim, index) => Animated.timing(anim, {
108
- toValue: 1,
109
- duration: 150,
110
- delay: index * 50,
111
- useNativeDriver: true
112
- })
113
- );
114
- Animated.parallel([
115
- Animated.timing(overlayOpacity, {
116
- toValue: 1,
117
- duration: 200,
118
- useNativeDriver: true
119
- }),
120
- Animated.stagger(50, itemSequence)
121
- ]).start();
122
- };
123
- var runMenuCollapseAnimation = (overlayOpacity, itemAnimations, onComplete) => {
124
- const reversed = [...itemAnimations].reverse();
125
- const itemSequence = reversed.map(
126
- (anim, index) => Animated.timing(anim, {
127
- toValue: 0,
128
- duration: 120,
129
- delay: index * 30,
130
- useNativeDriver: true
131
- })
132
- );
133
- Animated.parallel([
134
- Animated.timing(overlayOpacity, {
135
- toValue: 0,
136
- duration: 200,
137
- useNativeDriver: true
138
- }),
139
- Animated.stagger(30, itemSequence)
140
- ]).start(onComplete);
141
- };
142
- var runFabRotateAnimation = (rotateValue, toExpanded) => {
143
- Animated.spring(rotateValue, {
144
- toValue: toExpanded ? 1 : 0,
145
- useNativeDriver: true,
146
- speed: 20,
147
- bounciness: 0
148
- }).start();
149
- };
150
-
151
- // src/components/fab-menu/fab-menu.tsx
152
- var FabMenu = ({
153
- icon,
154
- label,
155
- expandedIcon,
156
- children,
157
- themeColor = "primary",
158
- variant = "solid",
159
- size = "md",
160
- radius,
161
- elevation = 0,
162
- isExpanded: controlledExpanded,
163
- onToggle,
164
- showOverlay = true,
165
- customAppearance
166
- }) => {
167
- const { expanded, toggle, close } = useFabMenuState(controlledExpanded, onToggle);
168
- const overlayColor = useFabMenuOverlayColor();
169
- const [isPortalVisible, setIsPortalVisible] = React.useState(expanded);
170
- const childArray = React.Children.toArray(children);
171
- const overlayOpacity = React.useRef(new Animated2.Value(expanded ? 1 : 0)).current;
172
- const rotateValue = React.useRef(new Animated2.Value(expanded ? 1 : 0)).current;
173
- const itemAnimationsRef = React.useRef(childArray.map(() => new Animated2.Value(0)));
174
- const itemAnimations = itemAnimationsRef.current;
175
- const prevExpanded = React.useRef(expanded);
176
- React.useEffect(() => {
177
- if (itemAnimations.length === childArray.length) return;
178
- itemAnimationsRef.current = childArray.map(
179
- (_, index) => itemAnimations[index] ?? new Animated2.Value(expanded ? 1 : 0)
180
- );
181
- }, [expanded, itemAnimations, childArray]);
182
- React.useEffect(() => {
183
- if (prevExpanded.current === expanded) return;
184
- prevExpanded.current = expanded;
185
- if (expanded) {
186
- setIsPortalVisible(true);
187
- runMenuExpandAnimation(overlayOpacity, itemAnimations);
188
- runFabRotateAnimation(rotateValue, true);
189
- } else {
190
- runMenuCollapseAnimation(overlayOpacity, itemAnimations, () => {
191
- setIsPortalVisible(false);
192
- });
193
- runFabRotateAnimation(rotateValue, false);
194
- }
195
- }, [expanded, overlayOpacity, itemAnimations, rotateValue]);
196
- const rotation = rotateValue.interpolate({
197
- inputRange: [0, 1],
198
- outputRange: ["0deg", "45deg"]
199
- });
200
- const currentIcon = expanded && expandedIcon ? expandedIcon : icon;
201
- const renderFabToggle = () => /* @__PURE__ */ React.createElement(
202
- Animated2.View,
203
- {
204
- style: {
205
- alignSelf: "flex-end",
206
- transform: [{ rotate: expandedIcon ? "0deg" : rotation }]
207
- }
208
- },
209
- /* @__PURE__ */ React.createElement(
210
- Fab,
211
- {
212
- icon: currentIcon,
213
- label,
214
- themeColor,
215
- variant,
216
- size,
217
- radius,
218
- elevation,
219
- onPress: toggle,
220
- customAppearance: { fab: customAppearance?.fab }
221
- }
222
- )
223
- );
224
- const renderMenuItems = () => /* @__PURE__ */ React.createElement(View, { style: [styles.menuContainer, customAppearance?.menuContainer] }, childArray.map((child, index) => {
225
- const childElement = child;
226
- const isDisabled = childElement.props?.isDisabled;
227
- return /* @__PURE__ */ React.createElement(
228
- Animated2.View,
229
- {
230
- key: childElement.key ?? index,
231
- style: [
232
- styles.menuItem,
233
- isDisabled && styles.disabled,
234
- {
235
- opacity: itemAnimations[index],
236
- transform: [
237
- {
238
- translateY: itemAnimations[index].interpolate({
239
- inputRange: [0, 1],
240
- outputRange: [20, 0]
241
- })
242
- },
243
- {
244
- scale: itemAnimations[index].interpolate({
245
- inputRange: [0, 1],
246
- outputRange: [0.8, 1]
247
- })
248
- }
249
- ]
250
- },
251
- customAppearance?.menuItem
252
- ]
253
- },
254
- React.cloneElement(childElement, {
255
- _onClose: close,
256
- themeColor: childElement.props?.themeColor ?? themeColor
257
- })
258
- );
259
- }));
260
- return /* @__PURE__ */ React.createElement(View, { style: [styles.container, customAppearance?.container] }, isPortalVisible && /* @__PURE__ */ React.createElement(Portal, null, /* @__PURE__ */ React.createElement(View, { style: styles.portalRoot }, showOverlay && /* @__PURE__ */ React.createElement(
261
- Animated2.View,
262
- {
263
- style: [
264
- styles.overlay,
265
- { backgroundColor: overlayColor, opacity: overlayOpacity },
266
- customAppearance?.overlay
267
- ]
268
- },
269
- /* @__PURE__ */ React.createElement(Pressable, { style: styles.overlayPressable, onPress: close })
270
- ), /* @__PURE__ */ React.createElement(View, { style: styles.portalContent }, renderMenuItems(), renderFabToggle()))), !isPortalVisible && renderFabToggle());
271
- };
272
-
273
- // src/components/fab-menu/fab-menu-item.tsx
274
- import React2 from "react";
275
- import { Pressable as Pressable2, Text } from "react-native";
276
- var FabMenuItem = ({
277
- icon,
278
- label,
279
- themeColor = "primary",
280
- onPress,
281
- isDisabled,
282
- _onClose
283
- }) => {
284
- const itemStyles = useFabMenuItemStyles(themeColor);
285
- const renderIcon = (menuIcon) => {
286
- if (!React2.isValidElement(menuIcon)) return menuIcon;
287
- return React2.cloneElement(
288
- menuIcon,
289
- { color: itemStyles.iconColor }
290
- );
291
- };
292
- return /* @__PURE__ */ React2.createElement(
293
- Pressable2,
294
- {
295
- style: [
296
- styles.menuItemChip,
297
- {
298
- backgroundColor: itemStyles.chipStyles.backgroundColor,
299
- borderRadius: itemStyles.chipStyles.borderRadius
300
- }
301
- ],
302
- onPress: (event) => {
303
- if (isDisabled) return;
304
- onPress?.(event);
305
- _onClose?.();
306
- },
307
- disabled: isDisabled
308
- },
309
- renderIcon(icon),
310
- /* @__PURE__ */ React2.createElement(
311
- Text,
312
- {
313
- style: [
314
- styles.menuItemLabel,
315
- {
316
- color: itemStyles.chipStyles.color,
317
- fontSize: itemStyles.chipStyles.fontSize
318
- }
319
- ]
320
- },
321
- label
322
- )
323
- );
324
- };
325
-
326
- export {
327
- FabMenu,
328
- FabMenuItem
329
- };
@@ -1,382 +0,0 @@
1
- import {
2
- useBorderRadiusStyles
3
- } from "./chunk-MZL77KV5.js";
4
-
5
- // src/components/carousel/carousel.tsx
6
- import React3, { useState, useRef, useCallback, useEffect } from "react";
7
- import { View as View2 } from "react-native";
8
- import Animated2, {
9
- useAnimatedScrollHandler,
10
- useSharedValue,
11
- useAnimatedRef
12
- } from "react-native-reanimated";
13
-
14
- // src/components/carousel/carousel.style.ts
15
- import { StyleSheet } from "react-native";
16
- var styles = StyleSheet.create({
17
- scrollContent: {
18
- flexDirection: "row",
19
- alignItems: "center"
20
- },
21
- item: {
22
- overflow: "hidden"
23
- },
24
- indicatorContainer: {
25
- flexDirection: "row",
26
- justifyContent: "center",
27
- alignItems: "center",
28
- paddingVertical: 12,
29
- gap: 8
30
- },
31
- indicator: {
32
- width: 8,
33
- height: 8,
34
- borderRadius: 4,
35
- backgroundColor: "#CAC4D0"
36
- },
37
- activeIndicator: {
38
- width: 24,
39
- borderRadius: 4,
40
- backgroundColor: "#49454F"
41
- }
42
- });
43
-
44
- // src/components/carousel/carousel.hook.ts
45
- import { useMemo } from "react";
46
- var HERO_PEEK_WIDTH = 56;
47
- function computeMultiBrowseLayout(config) {
48
- const { preferredItemWidth, itemSpacing } = config;
49
- return {
50
- computedItemWidth: preferredItemWidth,
51
- snapInterval: preferredItemWidth + itemSpacing,
52
- pagingEnabled: false
53
- };
54
- }
55
- function computeUncontainedLayout(config) {
56
- const { preferredItemWidth, itemSpacing } = config;
57
- return {
58
- computedItemWidth: preferredItemWidth,
59
- snapInterval: preferredItemWidth + itemSpacing,
60
- pagingEnabled: false
61
- };
62
- }
63
- function computeHeroLayout(config) {
64
- const { containerWidth, contentPadding, itemSpacing } = config;
65
- const availableWidth = containerWidth - 2 * contentPadding;
66
- const largeItemWidth = availableWidth - HERO_PEEK_WIDTH - itemSpacing;
67
- return {
68
- computedItemWidth: Math.max(largeItemWidth, 0),
69
- snapInterval: Math.max(largeItemWidth + itemSpacing, 1),
70
- pagingEnabled: false
71
- };
72
- }
73
- function computeFullScreenLayout(config) {
74
- const { containerWidth } = config;
75
- return {
76
- computedItemWidth: containerWidth,
77
- snapInterval: containerWidth,
78
- pagingEnabled: true
79
- };
80
- }
81
- function useCarouselLayout(config) {
82
- return useMemo(() => {
83
- const layoutMap = {
84
- "multi-browse": computeMultiBrowseLayout,
85
- uncontained: computeUncontainedLayout,
86
- hero: computeHeroLayout,
87
- "full-screen": computeFullScreenLayout
88
- };
89
- const compute = layoutMap[config.layout] ?? computeMultiBrowseLayout;
90
- return compute(config);
91
- }, [
92
- config.layout,
93
- config.containerWidth,
94
- config.preferredItemWidth,
95
- config.itemSpacing,
96
- config.contentPadding
97
- ]);
98
- }
99
-
100
- // src/components/carousel/carousel-item.tsx
101
- import React from "react";
102
- import { View } from "react-native";
103
- var CarouselItem = ({
104
- children,
105
- width,
106
- height,
107
- radius,
108
- spacing,
109
- isLast,
110
- customStyle
111
- }) => /* @__PURE__ */ React.createElement(
112
- View,
113
- {
114
- style: [
115
- styles.item,
116
- {
117
- width,
118
- height,
119
- borderRadius: radius,
120
- marginRight: isLast ? 0 : spacing
121
- },
122
- customStyle
123
- ]
124
- },
125
- children
126
- );
127
-
128
- // src/components/carousel/animated-carousel-item.tsx
129
- import React2 from "react";
130
- import Animated, {
131
- useAnimatedStyle,
132
- interpolate,
133
- Extrapolation
134
- } from "react-native-reanimated";
135
- var AnimatedCarouselItem = ({
136
- children,
137
- index,
138
- scrollX,
139
- width,
140
- height,
141
- radius,
142
- spacing,
143
- isLast,
144
- customStyle,
145
- layout,
146
- snapInterval,
147
- containerWidth,
148
- contentPadding
149
- }) => {
150
- const animatedStyle = useAnimatedStyle(() => {
151
- const inputRange = [
152
- (index - 1) * snapInterval,
153
- index * snapInterval,
154
- (index + 1) * snapInterval
155
- ];
156
- if (layout === "multi-browse") {
157
- const scale = interpolate(
158
- scrollX.value,
159
- inputRange,
160
- [0.85, 1, 0.85],
161
- Extrapolation.CLAMP
162
- );
163
- const opacity = interpolate(
164
- scrollX.value,
165
- inputRange,
166
- [0.6, 1, 0.6],
167
- Extrapolation.CLAMP
168
- );
169
- return {
170
- transform: [{ scale }],
171
- opacity
172
- };
173
- }
174
- if (layout === "hero") {
175
- const centerOffset = containerWidth / 2 - contentPadding - width / 2;
176
- const itemPosition = index * snapInterval + contentPadding;
177
- const inputRangeHero = [
178
- itemPosition - centerOffset - snapInterval,
179
- itemPosition - centerOffset,
180
- itemPosition - centerOffset + snapInterval
181
- ];
182
- const scale = interpolate(
183
- scrollX.value,
184
- inputRangeHero,
185
- [0.9, 1, 0.9],
186
- Extrapolation.CLAMP
187
- );
188
- const opacity = interpolate(
189
- scrollX.value,
190
- inputRangeHero,
191
- [0.5, 1, 0.5],
192
- Extrapolation.CLAMP
193
- );
194
- const translateX = interpolate(
195
- scrollX.value,
196
- inputRangeHero,
197
- [-10, 0, 10],
198
- Extrapolation.CLAMP
199
- );
200
- return {
201
- transform: [{ scale }, { translateX }],
202
- opacity
203
- };
204
- }
205
- return {};
206
- }, [index, snapInterval, layout, containerWidth, contentPadding, width]);
207
- return /* @__PURE__ */ React2.createElement(
208
- Animated.View,
209
- {
210
- style: [
211
- styles.item,
212
- {
213
- width,
214
- height,
215
- borderRadius: radius,
216
- marginRight: isLast ? 0 : spacing
217
- },
218
- customStyle,
219
- animatedStyle
220
- ]
221
- },
222
- children
223
- );
224
- };
225
-
226
- // src/components/carousel/carousel.tsx
227
- var DEFAULT_ITEM_WIDTH = 196;
228
- var DEFAULT_ITEM_HEIGHT = 205;
229
- var DEFAULT_ITEM_SPACING = 8;
230
- var DEFAULT_ITEM_SPACING_MULTI_BROWSE = 4;
231
- var DEFAULT_CONTENT_PADDING = 16;
232
- var DEFAULT_AUTO_PLAY_INTERVAL = 3e3;
233
- function Carousel({
234
- data,
235
- renderItem,
236
- keyExtractor,
237
- layout = "multi-browse",
238
- itemWidth = DEFAULT_ITEM_WIDTH,
239
- itemHeight = DEFAULT_ITEM_HEIGHT,
240
- itemSpacing,
241
- contentPadding = DEFAULT_CONTENT_PADDING,
242
- radius = "lg",
243
- showIndicator = false,
244
- autoPlay = false,
245
- autoPlayInterval = DEFAULT_AUTO_PLAY_INTERVAL,
246
- initialIndex = 0,
247
- onActiveItemChange,
248
- customAppearance
249
- }) {
250
- const [containerWidth, setContainerWidth] = useState(0);
251
- const [activeIndex, setActiveIndex] = useState(initialIndex);
252
- const scrollRef = useAnimatedRef();
253
- const onActiveItemChangeRef = useRef(onActiveItemChange);
254
- onActiveItemChangeRef.current = onActiveItemChange;
255
- const scrollX = useSharedValue(0);
256
- const { borderRadius } = useBorderRadiusStyles(radius);
257
- const defaultSpacing = layout === "multi-browse" ? DEFAULT_ITEM_SPACING_MULTI_BROWSE : DEFAULT_ITEM_SPACING;
258
- const resolvedSpacing = itemSpacing ?? defaultSpacing;
259
- const isFullScreen = layout === "full-screen";
260
- const effectivePadding = isFullScreen ? 0 : contentPadding;
261
- const effectiveSpacing = isFullScreen ? 0 : resolvedSpacing;
262
- const { computedItemWidth, snapInterval, pagingEnabled } = useCarouselLayout({
263
- layout,
264
- containerWidth,
265
- preferredItemWidth: itemWidth,
266
- itemSpacing: effectiveSpacing,
267
- contentPadding: effectivePadding
268
- });
269
- const handleLayout = useCallback((event) => {
270
- setContainerWidth(event.nativeEvent.layout.width);
271
- }, []);
272
- const scrollHandler = useAnimatedScrollHandler({
273
- onScroll: (event) => {
274
- scrollX.value = event.contentOffset.x;
275
- }
276
- });
277
- const handleMomentumScrollEnd = useCallback(
278
- (event) => {
279
- if (snapInterval <= 0) return;
280
- const offsetX = event.nativeEvent.contentOffset.x;
281
- const newIndex = Math.round(offsetX / snapInterval);
282
- const clampedIndex = Math.max(0, Math.min(newIndex, data.length - 1));
283
- setActiveIndex(clampedIndex);
284
- onActiveItemChangeRef.current?.(clampedIndex);
285
- },
286
- [snapInterval, data.length]
287
- );
288
- useEffect(() => {
289
- if (!autoPlay || data.length <= 1) return;
290
- if (containerWidth <= 0 || snapInterval <= 0) return;
291
- const timer = setInterval(() => {
292
- setActiveIndex((prev) => {
293
- const nextIndex = (prev + 1) % data.length;
294
- scrollRef.current?.scrollTo({ x: nextIndex * snapInterval, animated: true });
295
- onActiveItemChangeRef.current?.(nextIndex);
296
- return nextIndex;
297
- });
298
- }, autoPlayInterval);
299
- return () => clearInterval(timer);
300
- }, [autoPlay, autoPlayInterval, data.length, snapInterval, containerWidth]);
301
- if (containerWidth <= 0) {
302
- return /* @__PURE__ */ React3.createElement(View2, { style: customAppearance?.container, onLayout: handleLayout });
303
- }
304
- const shouldAnimate = layout === "multi-browse" || layout === "hero";
305
- return /* @__PURE__ */ React3.createElement(View2, { style: customAppearance?.container, onLayout: handleLayout }, /* @__PURE__ */ React3.createElement(
306
- Animated2.ScrollView,
307
- {
308
- ref: scrollRef,
309
- horizontal: true,
310
- showsHorizontalScrollIndicator: false,
311
- snapToInterval: pagingEnabled ? void 0 : snapInterval,
312
- pagingEnabled,
313
- decelerationRate: "fast",
314
- contentContainerStyle: [
315
- styles.scrollContent,
316
- { paddingHorizontal: effectivePadding }
317
- ],
318
- onScroll: scrollHandler,
319
- scrollEventThrottle: 16,
320
- onMomentumScrollEnd: handleMomentumScrollEnd,
321
- contentOffset: { x: initialIndex * snapInterval, y: 0 }
322
- },
323
- data.map((item, index) => {
324
- const content = renderItem({ item, index });
325
- if (shouldAnimate) {
326
- return /* @__PURE__ */ React3.createElement(
327
- AnimatedCarouselItem,
328
- {
329
- key: keyExtractor ? keyExtractor(item, index) : String(index),
330
- index,
331
- scrollX,
332
- width: computedItemWidth,
333
- height: itemHeight,
334
- radius: borderRadius,
335
- spacing: effectiveSpacing,
336
- isLast: index === data.length - 1,
337
- customStyle: customAppearance?.item,
338
- layout,
339
- snapInterval,
340
- containerWidth,
341
- contentPadding: effectivePadding
342
- },
343
- content
344
- );
345
- }
346
- return /* @__PURE__ */ React3.createElement(
347
- CarouselItem,
348
- {
349
- key: keyExtractor ? keyExtractor(item, index) : String(index),
350
- width: computedItemWidth,
351
- height: itemHeight,
352
- radius: borderRadius,
353
- spacing: effectiveSpacing,
354
- isLast: index === data.length - 1,
355
- customStyle: customAppearance?.item
356
- },
357
- content
358
- );
359
- })
360
- ), showIndicator && data.length > 1 && /* @__PURE__ */ React3.createElement(
361
- View2,
362
- {
363
- style: [styles.indicatorContainer, customAppearance?.indicatorContainer]
364
- },
365
- data.map((_, index) => /* @__PURE__ */ React3.createElement(
366
- View2,
367
- {
368
- key: `indicator-${String(index)}`,
369
- style: [
370
- styles.indicator,
371
- customAppearance?.indicator,
372
- activeIndex === index && styles.activeIndicator,
373
- activeIndex === index && customAppearance?.activeIndicator
374
- ]
375
- }
376
- ))
377
- ));
378
- }
379
-
380
- export {
381
- Carousel
382
- };