@xaui/native 0.0.16 → 0.0.18

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 (62) hide show
  1. package/dist/accordion/index.cjs +1 -1
  2. package/dist/accordion/index.js +5 -4
  3. package/dist/alert/index.js +352 -3
  4. package/dist/autocomplete/index.cjs +5 -11
  5. package/dist/autocomplete/index.js +1122 -5
  6. package/dist/avatar/index.js +276 -4
  7. package/dist/badge/index.js +193 -3
  8. package/dist/bottom-sheet/index.cjs +9 -20
  9. package/dist/bottom-sheet/index.js +364 -3
  10. package/dist/button/index.js +3 -2
  11. package/dist/card/index.cjs +429 -0
  12. package/dist/card/index.d.cts +186 -0
  13. package/dist/card/index.d.ts +186 -0
  14. package/dist/card/index.js +336 -0
  15. package/dist/carousel/index.cjs +458 -0
  16. package/dist/carousel/index.d.cts +147 -0
  17. package/dist/carousel/index.d.ts +147 -0
  18. package/dist/carousel/index.js +381 -0
  19. package/dist/checkbox/index.js +2 -1
  20. package/dist/chip/index.cjs +2 -8
  21. package/dist/chip/index.js +497 -5
  22. package/dist/chunk-DXXNBF5P.js +7 -0
  23. package/dist/{chunk-MKHBEJLO.js → chunk-F7WH4DMG.js} +1 -1
  24. package/dist/{chunk-II4QINLG.js → chunk-JEGEPGVU.js} +2 -2
  25. package/dist/{chunk-NBRASCX4.js → chunk-LTKYHG5V.js} +6 -13
  26. package/dist/{chunk-GNJIET26.js → chunk-LUBWRVI2.js} +1 -1
  27. package/dist/core/index.cjs +1 -1
  28. package/dist/core/index.js +5 -3
  29. package/dist/datepicker/index.js +1623 -3
  30. package/dist/divider/index.js +3 -2
  31. package/dist/fab/index.js +4 -3
  32. package/dist/fab-menu/index.cjs +4 -13
  33. package/dist/fab-menu/index.js +325 -6
  34. package/dist/index.cjs +0 -5709
  35. package/dist/index.d.cts +2 -17
  36. package/dist/index.d.ts +2 -17
  37. package/dist/index.js +0 -62
  38. package/dist/indicator/index.js +3 -2
  39. package/dist/menu/index.cjs +8 -7
  40. package/dist/menu/index.js +15 -9
  41. package/dist/progress/index.js +2 -1
  42. package/dist/segment-button/index.cjs +492 -0
  43. package/dist/segment-button/index.d.cts +141 -0
  44. package/dist/segment-button/index.d.ts +141 -0
  45. package/dist/segment-button/index.js +405 -0
  46. package/dist/select/index.js +2 -1
  47. package/dist/switch/index.js +2 -1
  48. package/dist/typography/index.js +146 -3
  49. package/dist/view/index.cjs +153 -78
  50. package/dist/view/index.d.cts +77 -1
  51. package/dist/view/index.d.ts +77 -1
  52. package/dist/view/index.js +125 -52
  53. package/package.json +16 -1
  54. package/dist/chunk-2T6FKPJW.js +0 -356
  55. package/dist/chunk-4LFRYVSR.js +0 -281
  56. package/dist/chunk-7OFTYKK4.js +0 -1627
  57. package/dist/chunk-EI5OMBFE.js +0 -338
  58. package/dist/chunk-GAOI4KIV.js +0 -379
  59. package/dist/chunk-NMZUPH3R.js +0 -1133
  60. package/dist/chunk-QLEQYKG5.js +0 -509
  61. package/dist/chunk-XJKA22BK.js +0 -197
  62. package/dist/chunk-ZYTBRHLJ.js +0 -150
@@ -0,0 +1,147 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { ViewStyle } from 'react-native';
3
+ import { R as Radius } from '../index-BOw6tbkc.js';
4
+
5
+ /**
6
+ * Carousel layout variants
7
+ * - multi-browse: Shows multiple items with the main item centered
8
+ * - uncontained: Items can be scrolled freely without constraints
9
+ * - hero: Single large item display
10
+ * - full-screen: Items take the full width of the screen
11
+ */
12
+ type CarouselLayout = 'multi-browse' | 'uncontained' | 'hero' | 'full-screen';
13
+ /**
14
+ * Custom appearance styles for carousel components
15
+ */
16
+ type CarouselCustomAppearance = {
17
+ /**
18
+ * Custom style for the carousel container
19
+ */
20
+ container?: ViewStyle;
21
+ /**
22
+ * Custom style for each carousel item
23
+ */
24
+ item?: ViewStyle;
25
+ /**
26
+ * Custom style for the indicator container
27
+ */
28
+ indicatorContainer?: ViewStyle;
29
+ /**
30
+ * Custom style for inactive indicators
31
+ */
32
+ indicator?: ViewStyle;
33
+ /**
34
+ * Custom style for the active indicator
35
+ */
36
+ activeIndicator?: ViewStyle;
37
+ };
38
+ type CarouselProps<T> = {
39
+ /**
40
+ * Array of data items to be displayed in the carousel
41
+ */
42
+ data: T[];
43
+ /**
44
+ * Function to render each carousel item
45
+ */
46
+ renderItem: (info: {
47
+ item: T;
48
+ index: number;
49
+ }) => ReactNode;
50
+ /**
51
+ * Function to extract unique keys for each item
52
+ */
53
+ keyExtractor?: (item: T, index: number) => string;
54
+ /**
55
+ * The layout variant of the carousel
56
+ * @default 'multi-browse'
57
+ */
58
+ layout?: CarouselLayout;
59
+ /**
60
+ * Width of each carousel item in pixels
61
+ */
62
+ itemWidth?: number;
63
+ /**
64
+ * Height of each carousel item in pixels
65
+ */
66
+ itemHeight?: number;
67
+ /**
68
+ * Spacing between carousel items in pixels
69
+ * @default 4 for 'multi-browse', 8 for other layouts
70
+ */
71
+ itemSpacing?: number;
72
+ /**
73
+ * Padding around the carousel content in pixels
74
+ * @default 16
75
+ */
76
+ contentPadding?: number;
77
+ /**
78
+ * Border radius of carousel items
79
+ * @default 'md'
80
+ */
81
+ radius?: Radius;
82
+ /**
83
+ * Whether to show the indicator dots below the carousel
84
+ * @default true
85
+ */
86
+ showIndicator?: boolean;
87
+ /**
88
+ * Whether to enable auto-play functionality
89
+ * @default false
90
+ */
91
+ autoPlay?: boolean;
92
+ /**
93
+ * Interval in milliseconds between auto-play transitions
94
+ * @default 3000
95
+ */
96
+ autoPlayInterval?: number;
97
+ /**
98
+ * Initial index to display when the carousel mounts
99
+ * @default 0
100
+ */
101
+ initialIndex?: number;
102
+ /**
103
+ * Callback fired when the active item changes
104
+ */
105
+ onActiveItemChange?: (index: number) => void;
106
+ /**
107
+ * Custom appearance styles for carousel components
108
+ */
109
+ customAppearance?: CarouselCustomAppearance;
110
+ };
111
+ /**
112
+ * Props for individual carousel item wrapper
113
+ */
114
+ type CarouselItemProps = {
115
+ /**
116
+ * Content to be displayed inside the carousel item
117
+ */
118
+ children: ReactNode;
119
+ /**
120
+ * Width of the carousel item in pixels
121
+ */
122
+ width: number;
123
+ /**
124
+ * Height of the carousel item in pixels
125
+ */
126
+ height: number;
127
+ /**
128
+ * Border radius of the carousel item in pixels
129
+ */
130
+ radius: number;
131
+ /**
132
+ * Spacing to apply after the item (margin right)
133
+ */
134
+ spacing: number;
135
+ /**
136
+ * Whether this is the last item in the carousel
137
+ */
138
+ isLast: boolean;
139
+ /**
140
+ * Custom style to be applied to the item container
141
+ */
142
+ customStyle?: ViewStyle;
143
+ };
144
+
145
+ declare function Carousel<T>({ data, renderItem, keyExtractor, layout, itemWidth, itemHeight, itemSpacing, contentPadding, radius, showIndicator, autoPlay, autoPlayInterval, initialIndex, onActiveItemChange, customAppearance, }: CarouselProps<T>): React.JSX.Element;
146
+
147
+ export { Carousel, type CarouselCustomAppearance, type CarouselItemProps, type CarouselLayout, type CarouselProps };
@@ -0,0 +1,381 @@
1
+ import {
2
+ useBorderRadiusStyles
3
+ } from "../chunk-LTKYHG5V.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
+ export {
380
+ Carousel
381
+ };
@@ -1,6 +1,7 @@
1
+ import "../chunk-DXXNBF5P.js";
1
2
  import {
2
3
  useXUITheme
3
- } from "../chunk-NBRASCX4.js";
4
+ } from "../chunk-LTKYHG5V.js";
4
5
 
5
6
  // src/components/checkbox/checkbox.tsx
6
7
  import React2, { useEffect as useEffect2, useRef as useRef2, useState } from "react";
@@ -278,10 +278,7 @@ var Chip = ({
278
278
  ]);
279
279
  const animatedBackgroundColor = colorProgress.interpolate({
280
280
  inputRange: [0, 1],
281
- outputRange: [
282
- previousColorsRef.current.backgroundColor,
283
- targetBackgroundColor
284
- ]
281
+ outputRange: [previousColorsRef.current.backgroundColor, targetBackgroundColor]
285
282
  });
286
283
  const animatedBorderColor = colorProgress.interpolate({
287
284
  inputRange: [0, 1],
@@ -461,10 +458,7 @@ function useChipGroupSelection(selectMode, selectedValues, defaultSelectedValues
461
458
  },
462
459
  [currentValues, isControlled, onSelectionChange, selectMode]
463
460
  );
464
- return (0, import_react9.useMemo)(
465
- () => ({ currentValues, onToggle }),
466
- [currentValues, onToggle]
467
- );
461
+ return (0, import_react9.useMemo)(() => ({ currentValues, onToggle }), [currentValues, onToggle]);
468
462
  }
469
463
 
470
464
  // src/components/chip/chip-group.tsx