@xaui/native 0.0.16 → 0.0.17

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 (59) hide show
  1. package/dist/accordion/index.cjs +1 -1
  2. package/dist/accordion/index.js +5 -4
  3. package/dist/alert/index.js +3 -2
  4. package/dist/autocomplete/index.cjs +5 -11
  5. package/dist/autocomplete/index.js +3 -2
  6. package/dist/avatar/index.js +3 -2
  7. package/dist/badge/index.js +3 -2
  8. package/dist/bottom-sheet/index.cjs +9 -20
  9. package/dist/bottom-sheet/index.js +3 -2
  10. package/dist/button/index.js +3 -2
  11. package/dist/carousel/index.cjs +458 -0
  12. package/dist/carousel/index.d.cts +147 -0
  13. package/dist/carousel/index.d.ts +147 -0
  14. package/dist/carousel/index.js +7 -0
  15. package/dist/checkbox/index.js +2 -1
  16. package/dist/chip/index.cjs +2 -8
  17. package/dist/chip/index.js +3 -2
  18. package/dist/{chunk-QLEQYKG5.js → chunk-6PXMB5CH.js} +3 -9
  19. package/dist/{chunk-EI5OMBFE.js → chunk-DBKVHMSA.js} +6 -15
  20. package/dist/chunk-DXXNBF5P.js +7 -0
  21. package/dist/chunk-EW5YLICE.js +382 -0
  22. package/dist/{chunk-7OFTYKK4.js → chunk-JJOVGRNI.js} +1 -1
  23. package/dist/{chunk-4LFRYVSR.js → chunk-K2HSVISE.js} +1 -1
  24. package/dist/{chunk-NBRASCX4.js → chunk-MZL77KV5.js} +5 -12
  25. package/dist/{chunk-2T6FKPJW.js → chunk-OXVIVNIJ.js} +1 -1
  26. package/dist/{chunk-ZYTBRHLJ.js → chunk-PWCUULAL.js} +1 -1
  27. package/dist/{chunk-GNJIET26.js → chunk-RIVFFZRO.js} +1 -1
  28. package/dist/{chunk-GAOI4KIV.js → chunk-S3MGBM3G.js} +10 -21
  29. package/dist/chunk-STUNTRKJ.js +405 -0
  30. package/dist/{chunk-II4QINLG.js → chunk-TJ2FPLLZ.js} +2 -2
  31. package/dist/{chunk-XJKA22BK.js → chunk-UGDGCMGC.js} +1 -1
  32. package/dist/{chunk-MKHBEJLO.js → chunk-VUVE6PK7.js} +1 -1
  33. package/dist/{chunk-NMZUPH3R.js → chunk-XUYIAA3A.js} +3 -9
  34. package/dist/core/index.js +5 -3
  35. package/dist/datepicker/index.js +3 -2
  36. package/dist/divider/index.js +3 -2
  37. package/dist/fab/index.js +4 -3
  38. package/dist/fab-menu/index.cjs +4 -13
  39. package/dist/fab-menu/index.js +5 -4
  40. package/dist/index.cjs +994 -257
  41. package/dist/index.d.cts +2 -0
  42. package/dist/index.d.ts +2 -0
  43. package/dist/index.js +24 -13
  44. package/dist/indicator/index.js +3 -2
  45. package/dist/menu/index.cjs +8 -7
  46. package/dist/menu/index.js +15 -9
  47. package/dist/progress/index.js +2 -1
  48. package/dist/segment-button/index.cjs +492 -0
  49. package/dist/segment-button/index.d.cts +141 -0
  50. package/dist/segment-button/index.d.ts +141 -0
  51. package/dist/segment-button/index.js +10 -0
  52. package/dist/select/index.js +2 -1
  53. package/dist/switch/index.js +2 -1
  54. package/dist/typography/index.js +3 -2
  55. package/dist/view/index.cjs +153 -78
  56. package/dist/view/index.d.cts +77 -1
  57. package/dist/view/index.d.ts +77 -1
  58. package/dist/view/index.js +125 -52
  59. package/package.json +11 -1
@@ -290,7 +290,7 @@ var useBaseStyles = (variant, isDisabled) => {
290
290
  const base = { overflow: "hidden" };
291
291
  if (variant === "splitted") {
292
292
  base.paddingHorizontal = theme.spacing.md;
293
- base.backgroundColor = (0, import_core3.addOpacityToColor)(theme.colors.default.background, 0.5);
293
+ base.backgroundColor = (0, import_core3.withOpacity)(theme.colors.default.background, 0.5);
294
294
  base.borderRadius = theme.borderRadius.md;
295
295
  base.marginBottom = theme.spacing.xs;
296
296
  } else if (variant === "bordered") {
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  Divider
3
- } from "../chunk-GNJIET26.js";
3
+ } from "../chunk-RIVFFZRO.js";
4
+ import "../chunk-DXXNBF5P.js";
4
5
  import {
5
6
  useXUIPalette,
6
7
  useXUITheme
7
- } from "../chunk-NBRASCX4.js";
8
+ } from "../chunk-MZL77KV5.js";
8
9
 
9
10
  // src/components/accordion/accordion.tsx
10
11
  import React4 from "react";
@@ -139,7 +140,7 @@ import {
139
140
  Easing
140
141
  } from "react-native";
141
142
  import { colors as palette } from "@xaui/core/palette";
142
- import { addOpacityToColor } from "@xaui/core";
143
+ import { withOpacity } from "@xaui/core";
143
144
  var useAccordionItemState = (itemKey) => {
144
145
  const context = useAccordionContext();
145
146
  const resolvedItemKey = itemKey ?? "";
@@ -219,7 +220,7 @@ var useBaseStyles = (variant, isDisabled) => {
219
220
  const base = { overflow: "hidden" };
220
221
  if (variant === "splitted") {
221
222
  base.paddingHorizontal = theme.spacing.md;
222
- base.backgroundColor = addOpacityToColor(theme.colors.default.background, 0.5);
223
+ base.backgroundColor = withOpacity(theme.colors.default.background, 0.5);
223
224
  base.borderRadius = theme.borderRadius.md;
224
225
  base.marginBottom = theme.spacing.xs;
225
226
  } else if (variant === "bordered") {
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  Alert
3
- } from "../chunk-2T6FKPJW.js";
4
- import "../chunk-NBRASCX4.js";
3
+ } from "../chunk-OXVIVNIJ.js";
4
+ import "../chunk-DXXNBF5P.js";
5
+ import "../chunk-MZL77KV5.js";
5
6
  export {
6
7
  Alert
7
8
  };
@@ -508,13 +508,7 @@ var styles2 = import_react_native5.StyleSheet.create({
508
508
  });
509
509
 
510
510
  // src/components/dialogs/autocomplete-dialog/autocomplete-dialog-header.tsx
511
- var addOpacityToColor = (color, opacity) => {
512
- const hex = color.replace("#", "");
513
- const r = parseInt(hex.substring(0, 2), 16);
514
- const g = parseInt(hex.substring(2, 4), 16);
515
- const b = parseInt(hex.substring(4, 6), 16);
516
- return `rgba(${r}, ${g}, ${b}, ${opacity})`;
517
- };
511
+ var import_core4 = require("@xaui/core");
518
512
  var AutocompleteDialogHeader = ({
519
513
  title,
520
514
  inputValue,
@@ -545,7 +539,7 @@ var AutocompleteDialogHeader = ({
545
539
  value: inputValue,
546
540
  onChangeText: onInputChange,
547
541
  placeholder,
548
- placeholderTextColor: addOpacityToColor(theme.colors.foreground, 0.5),
542
+ placeholderTextColor: (0, import_core4.withOpacity)(theme.colors.foreground, 0.5),
549
543
  style: [
550
544
  styles2.input,
551
545
  {
@@ -1073,7 +1067,7 @@ var styles3 = import_react_native11.StyleSheet.create({
1073
1067
 
1074
1068
  // src/components/autocomplete/autocomplete-item.hook.ts
1075
1069
  var import_react15 = require("react");
1076
- var import_core6 = require("@xaui/core");
1070
+ var import_core7 = require("@xaui/core");
1077
1071
  var useAutocompleteItemSizeStyles = (size) => {
1078
1072
  const theme = useXUITheme();
1079
1073
  return (0, import_react15.useMemo)(() => {
@@ -1108,7 +1102,7 @@ var useAutocompleteItemSizeStyles = (size) => {
1108
1102
  };
1109
1103
  var useAutocompleteItemBackgroundColor = (themeColor, isSelected) => {
1110
1104
  const theme = useXUITheme();
1111
- const safeThemeColor = (0, import_core6.getSafeThemeColor)(themeColor);
1105
+ const safeThemeColor = (0, import_core7.getSafeThemeColor)(themeColor);
1112
1106
  const colorScheme = theme.colors[safeThemeColor];
1113
1107
  return (0, import_react15.useMemo)(() => {
1114
1108
  return "transparent";
@@ -1125,7 +1119,7 @@ var useAutocompleteItemTextColors = () => {
1125
1119
  };
1126
1120
  var useAutocompleteItemCheckmarkColor = (themeColor) => {
1127
1121
  const theme = useXUITheme();
1128
- const safeThemeColor = (0, import_core6.getSafeThemeColor)(themeColor);
1122
+ const safeThemeColor = (0, import_core7.getSafeThemeColor)(themeColor);
1129
1123
  const colorScheme = theme.colors[safeThemeColor];
1130
1124
  return (0, import_react15.useMemo)(() => {
1131
1125
  if (themeColor === "default") {
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  Autocomplete,
3
3
  AutocompleteItem
4
- } from "../chunk-NMZUPH3R.js";
4
+ } from "../chunk-XUYIAA3A.js";
5
5
  import "../chunk-GBHQCAKW.js";
6
- import "../chunk-NBRASCX4.js";
6
+ import "../chunk-DXXNBF5P.js";
7
+ import "../chunk-MZL77KV5.js";
7
8
  export {
8
9
  Autocomplete,
9
10
  AutocompleteItem
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  Avatar,
3
3
  AvatarGroup
4
- } from "../chunk-4LFRYVSR.js";
5
- import "../chunk-NBRASCX4.js";
4
+ } from "../chunk-K2HSVISE.js";
5
+ import "../chunk-DXXNBF5P.js";
6
+ import "../chunk-MZL77KV5.js";
6
7
  export {
7
8
  Avatar,
8
9
  AvatarGroup
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  Badge
3
- } from "../chunk-XJKA22BK.js";
4
- import "../chunk-NBRASCX4.js";
3
+ } from "../chunk-UGDGCMGC.js";
4
+ import "../chunk-DXXNBF5P.js";
5
+ import "../chunk-MZL77KV5.js";
5
6
  export {
6
7
  Badge
7
8
  };
@@ -242,7 +242,13 @@ var useBottomSheetAnimation = ({
242
242
  snapTranslateValues[clampedIndex]
243
243
  );
244
244
  },
245
- [sortedSnapPoints, snapTranslateValues, disableAnimation, translateY, onSnapChange]
245
+ [
246
+ sortedSnapPoints,
247
+ snapTranslateValues,
248
+ disableAnimation,
249
+ translateY,
250
+ onSnapChange
251
+ ]
246
252
  );
247
253
  (0, import_react6.useEffect)(() => {
248
254
  if (isOpen) {
@@ -417,19 +423,7 @@ var BottomSheet = ({
417
423
  close();
418
424
  }
419
425
  };
420
- return /* @__PURE__ */ import_react7.default.createElement(Portal, null, showBackdrop && /* @__PURE__ */ import_react7.default.createElement(
421
- import_react_native7.Animated.View,
422
- {
423
- style: [styles.backdrop, { opacity: backdropOpacity }]
424
- },
425
- /* @__PURE__ */ import_react7.default.createElement(
426
- import_react_native7.Pressable,
427
- {
428
- style: styles.backdrop,
429
- onPress: handleBackdropPress
430
- }
431
- )
432
- ), /* @__PURE__ */ import_react7.default.createElement(
426
+ return /* @__PURE__ */ import_react7.default.createElement(Portal, null, showBackdrop && /* @__PURE__ */ import_react7.default.createElement(import_react_native7.Animated.View, { style: [styles.backdrop, { opacity: backdropOpacity }] }, /* @__PURE__ */ import_react7.default.createElement(import_react_native7.Pressable, { style: styles.backdrop, onPress: handleBackdropPress })), /* @__PURE__ */ import_react7.default.createElement(
433
427
  import_react_native7.Animated.View,
434
428
  {
435
429
  style: [
@@ -443,12 +437,7 @@ var BottomSheet = ({
443
437
  /* @__PURE__ */ import_react7.default.createElement(
444
438
  import_react_native7.View,
445
439
  {
446
- style: [
447
- styles.sheet,
448
- { height: screenHeight },
449
- sheetStyles,
450
- style
451
- ],
440
+ style: [styles.sheet, { height: screenHeight }, sheetStyles, style],
452
441
  ...panResponder.panHandlers
453
442
  },
454
443
  showHandle && /* @__PURE__ */ import_react7.default.createElement(import_react_native7.View, { style: styles.handle }, handleContent ?? /* @__PURE__ */ import_react7.default.createElement(
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  BottomSheet
3
- } from "../chunk-GAOI4KIV.js";
4
- import "../chunk-NBRASCX4.js";
3
+ } from "../chunk-S3MGBM3G.js";
4
+ import "../chunk-DXXNBF5P.js";
5
+ import "../chunk-MZL77KV5.js";
5
6
  export {
6
7
  BottomSheet
7
8
  };
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  ActivityIndicator
3
- } from "../chunk-MKHBEJLO.js";
3
+ } from "../chunk-VUVE6PK7.js";
4
+ import "../chunk-DXXNBF5P.js";
4
5
  import {
5
6
  useBorderRadiusStyles,
6
7
  useXUITheme
7
- } from "../chunk-NBRASCX4.js";
8
+ } from "../chunk-MZL77KV5.js";
8
9
 
9
10
  // src/components/button/button.tsx
10
11
  import React from "react";
@@ -0,0 +1,458 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/components/carousel/index.ts
31
+ var carousel_exports = {};
32
+ __export(carousel_exports, {
33
+ Carousel: () => Carousel
34
+ });
35
+ module.exports = __toCommonJS(carousel_exports);
36
+
37
+ // src/components/carousel/carousel.tsx
38
+ var import_react9 = __toESM(require("react"), 1);
39
+ var import_react_native6 = require("react-native");
40
+ var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"), 1);
41
+
42
+ // src/components/carousel/carousel.style.ts
43
+ var import_react_native = require("react-native");
44
+ var styles = import_react_native.StyleSheet.create({
45
+ scrollContent: {
46
+ flexDirection: "row",
47
+ alignItems: "center"
48
+ },
49
+ item: {
50
+ overflow: "hidden"
51
+ },
52
+ indicatorContainer: {
53
+ flexDirection: "row",
54
+ justifyContent: "center",
55
+ alignItems: "center",
56
+ paddingVertical: 12,
57
+ gap: 8
58
+ },
59
+ indicator: {
60
+ width: 8,
61
+ height: 8,
62
+ borderRadius: 4,
63
+ backgroundColor: "#CAC4D0"
64
+ },
65
+ activeIndicator: {
66
+ width: 24,
67
+ borderRadius: 4,
68
+ backgroundColor: "#49454F"
69
+ }
70
+ });
71
+
72
+ // src/components/carousel/carousel.hook.ts
73
+ var import_react = require("react");
74
+ var HERO_PEEK_WIDTH = 56;
75
+ function computeMultiBrowseLayout(config) {
76
+ const { preferredItemWidth, itemSpacing } = config;
77
+ return {
78
+ computedItemWidth: preferredItemWidth,
79
+ snapInterval: preferredItemWidth + itemSpacing,
80
+ pagingEnabled: false
81
+ };
82
+ }
83
+ function computeUncontainedLayout(config) {
84
+ const { preferredItemWidth, itemSpacing } = config;
85
+ return {
86
+ computedItemWidth: preferredItemWidth,
87
+ snapInterval: preferredItemWidth + itemSpacing,
88
+ pagingEnabled: false
89
+ };
90
+ }
91
+ function computeHeroLayout(config) {
92
+ const { containerWidth, contentPadding, itemSpacing } = config;
93
+ const availableWidth = containerWidth - 2 * contentPadding;
94
+ const largeItemWidth = availableWidth - HERO_PEEK_WIDTH - itemSpacing;
95
+ return {
96
+ computedItemWidth: Math.max(largeItemWidth, 0),
97
+ snapInterval: Math.max(largeItemWidth + itemSpacing, 1),
98
+ pagingEnabled: false
99
+ };
100
+ }
101
+ function computeFullScreenLayout(config) {
102
+ const { containerWidth } = config;
103
+ return {
104
+ computedItemWidth: containerWidth,
105
+ snapInterval: containerWidth,
106
+ pagingEnabled: true
107
+ };
108
+ }
109
+ function useCarouselLayout(config) {
110
+ return (0, import_react.useMemo)(() => {
111
+ const layoutMap = {
112
+ "multi-browse": computeMultiBrowseLayout,
113
+ uncontained: computeUncontainedLayout,
114
+ hero: computeHeroLayout,
115
+ "full-screen": computeFullScreenLayout
116
+ };
117
+ const compute = layoutMap[config.layout] ?? computeMultiBrowseLayout;
118
+ return compute(config);
119
+ }, [
120
+ config.layout,
121
+ config.containerWidth,
122
+ config.preferredItemWidth,
123
+ config.itemSpacing,
124
+ config.contentPadding
125
+ ]);
126
+ }
127
+
128
+ // src/components/carousel/carousel-item.tsx
129
+ var import_react2 = __toESM(require("react"), 1);
130
+ var import_react_native2 = require("react-native");
131
+ var CarouselItem = ({
132
+ children,
133
+ width,
134
+ height,
135
+ radius,
136
+ spacing,
137
+ isLast,
138
+ customStyle
139
+ }) => /* @__PURE__ */ import_react2.default.createElement(
140
+ import_react_native2.View,
141
+ {
142
+ style: [
143
+ styles.item,
144
+ {
145
+ width,
146
+ height,
147
+ borderRadius: radius,
148
+ marginRight: isLast ? 0 : spacing
149
+ },
150
+ customStyle
151
+ ]
152
+ },
153
+ children
154
+ );
155
+
156
+ // src/components/carousel/animated-carousel-item.tsx
157
+ var import_react3 = __toESM(require("react"), 1);
158
+ var import_react_native_reanimated = __toESM(require("react-native-reanimated"), 1);
159
+ var AnimatedCarouselItem = ({
160
+ children,
161
+ index,
162
+ scrollX,
163
+ width,
164
+ height,
165
+ radius,
166
+ spacing,
167
+ isLast,
168
+ customStyle,
169
+ layout,
170
+ snapInterval,
171
+ containerWidth,
172
+ contentPadding
173
+ }) => {
174
+ const animatedStyle = (0, import_react_native_reanimated.useAnimatedStyle)(() => {
175
+ const inputRange = [
176
+ (index - 1) * snapInterval,
177
+ index * snapInterval,
178
+ (index + 1) * snapInterval
179
+ ];
180
+ if (layout === "multi-browse") {
181
+ const scale = (0, import_react_native_reanimated.interpolate)(
182
+ scrollX.value,
183
+ inputRange,
184
+ [0.85, 1, 0.85],
185
+ import_react_native_reanimated.Extrapolation.CLAMP
186
+ );
187
+ const opacity = (0, import_react_native_reanimated.interpolate)(
188
+ scrollX.value,
189
+ inputRange,
190
+ [0.6, 1, 0.6],
191
+ import_react_native_reanimated.Extrapolation.CLAMP
192
+ );
193
+ return {
194
+ transform: [{ scale }],
195
+ opacity
196
+ };
197
+ }
198
+ if (layout === "hero") {
199
+ const centerOffset = containerWidth / 2 - contentPadding - width / 2;
200
+ const itemPosition = index * snapInterval + contentPadding;
201
+ const inputRangeHero = [
202
+ itemPosition - centerOffset - snapInterval,
203
+ itemPosition - centerOffset,
204
+ itemPosition - centerOffset + snapInterval
205
+ ];
206
+ const scale = (0, import_react_native_reanimated.interpolate)(
207
+ scrollX.value,
208
+ inputRangeHero,
209
+ [0.9, 1, 0.9],
210
+ import_react_native_reanimated.Extrapolation.CLAMP
211
+ );
212
+ const opacity = (0, import_react_native_reanimated.interpolate)(
213
+ scrollX.value,
214
+ inputRangeHero,
215
+ [0.5, 1, 0.5],
216
+ import_react_native_reanimated.Extrapolation.CLAMP
217
+ );
218
+ const translateX = (0, import_react_native_reanimated.interpolate)(
219
+ scrollX.value,
220
+ inputRangeHero,
221
+ [-10, 0, 10],
222
+ import_react_native_reanimated.Extrapolation.CLAMP
223
+ );
224
+ return {
225
+ transform: [{ scale }, { translateX }],
226
+ opacity
227
+ };
228
+ }
229
+ return {};
230
+ }, [index, snapInterval, layout, containerWidth, contentPadding, width]);
231
+ return /* @__PURE__ */ import_react3.default.createElement(
232
+ import_react_native_reanimated.default.View,
233
+ {
234
+ style: [
235
+ styles.item,
236
+ {
237
+ width,
238
+ height,
239
+ borderRadius: radius,
240
+ marginRight: isLast ? 0 : spacing
241
+ },
242
+ customStyle,
243
+ animatedStyle
244
+ ]
245
+ },
246
+ children
247
+ );
248
+ };
249
+
250
+ // src/core/theme-hooks.ts
251
+ var import_react8 = require("react");
252
+ var import_react_native5 = require("react-native");
253
+
254
+ // src/core/theme-context.tsx
255
+ var import_react7 = __toESM(require("react"), 1);
256
+ var import_react_native4 = require("react-native");
257
+ var import_theme = require("@xaui/core/theme");
258
+ var import_palette = require("@xaui/core/palette");
259
+
260
+ // src/core/portal/portal.tsx
261
+ var import_react5 = require("react");
262
+
263
+ // src/core/portal/portal-context.ts
264
+ var import_react4 = require("react");
265
+ var PortalContext = (0, import_react4.createContext)(null);
266
+
267
+ // src/core/portal/portal-host.tsx
268
+ var import_react6 = __toESM(require("react"), 1);
269
+ var import_react_native3 = require("react-native");
270
+ var hostStyles = import_react_native3.StyleSheet.create({
271
+ container: {
272
+ flex: 1
273
+ }
274
+ });
275
+
276
+ // src/core/theme-context.tsx
277
+ var XUIThemeContext = (0, import_react7.createContext)(null);
278
+
279
+ // src/core/theme-hooks.ts
280
+ function useXUITheme() {
281
+ const theme = (0, import_react8.useContext)(XUIThemeContext);
282
+ if (!theme) {
283
+ throw new Error("useXUITheme must be used within XUIProvider");
284
+ }
285
+ return theme;
286
+ }
287
+ function useBorderRadiusStyles(radius) {
288
+ const theme = useXUITheme();
289
+ const borderRadius = (0, import_react8.useMemo)(() => {
290
+ const radiusMap = {
291
+ none: theme.borderRadius.none,
292
+ sm: theme.borderRadius.sm,
293
+ md: theme.borderRadius.md,
294
+ lg: theme.borderRadius.lg,
295
+ full: theme.borderRadius.full
296
+ };
297
+ return { borderRadius: radiusMap[radius] };
298
+ }, [radius, theme]);
299
+ return borderRadius;
300
+ }
301
+
302
+ // src/components/carousel/carousel.tsx
303
+ var DEFAULT_ITEM_WIDTH = 196;
304
+ var DEFAULT_ITEM_HEIGHT = 205;
305
+ var DEFAULT_ITEM_SPACING = 8;
306
+ var DEFAULT_ITEM_SPACING_MULTI_BROWSE = 4;
307
+ var DEFAULT_CONTENT_PADDING = 16;
308
+ var DEFAULT_AUTO_PLAY_INTERVAL = 3e3;
309
+ function Carousel({
310
+ data,
311
+ renderItem,
312
+ keyExtractor,
313
+ layout = "multi-browse",
314
+ itemWidth = DEFAULT_ITEM_WIDTH,
315
+ itemHeight = DEFAULT_ITEM_HEIGHT,
316
+ itemSpacing,
317
+ contentPadding = DEFAULT_CONTENT_PADDING,
318
+ radius = "lg",
319
+ showIndicator = false,
320
+ autoPlay = false,
321
+ autoPlayInterval = DEFAULT_AUTO_PLAY_INTERVAL,
322
+ initialIndex = 0,
323
+ onActiveItemChange,
324
+ customAppearance
325
+ }) {
326
+ const [containerWidth, setContainerWidth] = (0, import_react9.useState)(0);
327
+ const [activeIndex, setActiveIndex] = (0, import_react9.useState)(initialIndex);
328
+ const scrollRef = (0, import_react_native_reanimated2.useAnimatedRef)();
329
+ const onActiveItemChangeRef = (0, import_react9.useRef)(onActiveItemChange);
330
+ onActiveItemChangeRef.current = onActiveItemChange;
331
+ const scrollX = (0, import_react_native_reanimated2.useSharedValue)(0);
332
+ const { borderRadius } = useBorderRadiusStyles(radius);
333
+ const defaultSpacing = layout === "multi-browse" ? DEFAULT_ITEM_SPACING_MULTI_BROWSE : DEFAULT_ITEM_SPACING;
334
+ const resolvedSpacing = itemSpacing ?? defaultSpacing;
335
+ const isFullScreen = layout === "full-screen";
336
+ const effectivePadding = isFullScreen ? 0 : contentPadding;
337
+ const effectiveSpacing = isFullScreen ? 0 : resolvedSpacing;
338
+ const { computedItemWidth, snapInterval, pagingEnabled } = useCarouselLayout({
339
+ layout,
340
+ containerWidth,
341
+ preferredItemWidth: itemWidth,
342
+ itemSpacing: effectiveSpacing,
343
+ contentPadding: effectivePadding
344
+ });
345
+ const handleLayout = (0, import_react9.useCallback)((event) => {
346
+ setContainerWidth(event.nativeEvent.layout.width);
347
+ }, []);
348
+ const scrollHandler = (0, import_react_native_reanimated2.useAnimatedScrollHandler)({
349
+ onScroll: (event) => {
350
+ scrollX.value = event.contentOffset.x;
351
+ }
352
+ });
353
+ const handleMomentumScrollEnd = (0, import_react9.useCallback)(
354
+ (event) => {
355
+ if (snapInterval <= 0) return;
356
+ const offsetX = event.nativeEvent.contentOffset.x;
357
+ const newIndex = Math.round(offsetX / snapInterval);
358
+ const clampedIndex = Math.max(0, Math.min(newIndex, data.length - 1));
359
+ setActiveIndex(clampedIndex);
360
+ onActiveItemChangeRef.current?.(clampedIndex);
361
+ },
362
+ [snapInterval, data.length]
363
+ );
364
+ (0, import_react9.useEffect)(() => {
365
+ if (!autoPlay || data.length <= 1) return;
366
+ if (containerWidth <= 0 || snapInterval <= 0) return;
367
+ const timer = setInterval(() => {
368
+ setActiveIndex((prev) => {
369
+ const nextIndex = (prev + 1) % data.length;
370
+ scrollRef.current?.scrollTo({ x: nextIndex * snapInterval, animated: true });
371
+ onActiveItemChangeRef.current?.(nextIndex);
372
+ return nextIndex;
373
+ });
374
+ }, autoPlayInterval);
375
+ return () => clearInterval(timer);
376
+ }, [autoPlay, autoPlayInterval, data.length, snapInterval, containerWidth]);
377
+ if (containerWidth <= 0) {
378
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_native6.View, { style: customAppearance?.container, onLayout: handleLayout });
379
+ }
380
+ const shouldAnimate = layout === "multi-browse" || layout === "hero";
381
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_native6.View, { style: customAppearance?.container, onLayout: handleLayout }, /* @__PURE__ */ import_react9.default.createElement(
382
+ import_react_native_reanimated2.default.ScrollView,
383
+ {
384
+ ref: scrollRef,
385
+ horizontal: true,
386
+ showsHorizontalScrollIndicator: false,
387
+ snapToInterval: pagingEnabled ? void 0 : snapInterval,
388
+ pagingEnabled,
389
+ decelerationRate: "fast",
390
+ contentContainerStyle: [
391
+ styles.scrollContent,
392
+ { paddingHorizontal: effectivePadding }
393
+ ],
394
+ onScroll: scrollHandler,
395
+ scrollEventThrottle: 16,
396
+ onMomentumScrollEnd: handleMomentumScrollEnd,
397
+ contentOffset: { x: initialIndex * snapInterval, y: 0 }
398
+ },
399
+ data.map((item, index) => {
400
+ const content = renderItem({ item, index });
401
+ if (shouldAnimate) {
402
+ return /* @__PURE__ */ import_react9.default.createElement(
403
+ AnimatedCarouselItem,
404
+ {
405
+ key: keyExtractor ? keyExtractor(item, index) : String(index),
406
+ index,
407
+ scrollX,
408
+ width: computedItemWidth,
409
+ height: itemHeight,
410
+ radius: borderRadius,
411
+ spacing: effectiveSpacing,
412
+ isLast: index === data.length - 1,
413
+ customStyle: customAppearance?.item,
414
+ layout,
415
+ snapInterval,
416
+ containerWidth,
417
+ contentPadding: effectivePadding
418
+ },
419
+ content
420
+ );
421
+ }
422
+ return /* @__PURE__ */ import_react9.default.createElement(
423
+ CarouselItem,
424
+ {
425
+ key: keyExtractor ? keyExtractor(item, index) : String(index),
426
+ width: computedItemWidth,
427
+ height: itemHeight,
428
+ radius: borderRadius,
429
+ spacing: effectiveSpacing,
430
+ isLast: index === data.length - 1,
431
+ customStyle: customAppearance?.item
432
+ },
433
+ content
434
+ );
435
+ })
436
+ ), showIndicator && data.length > 1 && /* @__PURE__ */ import_react9.default.createElement(
437
+ import_react_native6.View,
438
+ {
439
+ style: [styles.indicatorContainer, customAppearance?.indicatorContainer]
440
+ },
441
+ data.map((_, index) => /* @__PURE__ */ import_react9.default.createElement(
442
+ import_react_native6.View,
443
+ {
444
+ key: `indicator-${String(index)}`,
445
+ style: [
446
+ styles.indicator,
447
+ customAppearance?.indicator,
448
+ activeIndex === index && styles.activeIndicator,
449
+ activeIndex === index && customAppearance?.activeIndicator
450
+ ]
451
+ }
452
+ ))
453
+ ));
454
+ }
455
+ // Annotate the CommonJS export names for ESM import in node:
456
+ 0 && (module.exports = {
457
+ Carousel
458
+ });