@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
@@ -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-LUBWRVI2.js";
4
+ import "../chunk-DXXNBF5P.js";
4
5
  import {
5
6
  useXUIPalette,
6
7
  useXUITheme
7
- } from "../chunk-NBRASCX4.js";
8
+ } from "../chunk-LTKYHG5V.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,356 @@
1
+ import "../chunk-DXXNBF5P.js";
1
2
  import {
2
- Alert
3
- } from "../chunk-2T6FKPJW.js";
4
- import "../chunk-NBRASCX4.js";
3
+ useBorderRadiusStyles,
4
+ useXUITheme
5
+ } from "../chunk-LTKYHG5V.js";
6
+
7
+ // src/components/alert/alert.tsx
8
+ import React2, {
9
+ cloneElement,
10
+ isValidElement,
11
+ useCallback,
12
+ useEffect,
13
+ useMemo as useMemo2,
14
+ useState
15
+ } from "react";
16
+ import { Pressable, Text, View } from "react-native";
17
+ import Animated, {
18
+ useSharedValue,
19
+ useAnimatedStyle,
20
+ withTiming,
21
+ runOnJS
22
+ } from "react-native-reanimated";
23
+
24
+ // src/components/alert/alert.style.ts
25
+ import { StyleSheet } from "react-native";
26
+ var styles = StyleSheet.create({
27
+ container: {
28
+ flexDirection: "row",
29
+ alignItems: "center",
30
+ width: "100%",
31
+ gap: 12
32
+ },
33
+ mainWrapper: {
34
+ flex: 1,
35
+ justifyContent: "center",
36
+ gap: 2
37
+ },
38
+ title: {
39
+ fontWeight: "600"
40
+ },
41
+ description: {
42
+ fontWeight: "400"
43
+ },
44
+ iconWrapper: {
45
+ width: 36,
46
+ height: 36,
47
+ borderRadius: 18,
48
+ alignItems: "center",
49
+ justifyContent: "center"
50
+ },
51
+ iconText: {
52
+ fontWeight: "600"
53
+ },
54
+ closeButton: {
55
+ alignSelf: "flex-start",
56
+ padding: 4
57
+ },
58
+ extraContent: {
59
+ marginTop: 4
60
+ }
61
+ });
62
+
63
+ // src/components/alert/alert.hook.ts
64
+ import { useMemo } from "react";
65
+ import { getSafeThemeColor, withOpacity } from "@xaui/core";
66
+ var useAlertColorScheme = (themeColor) => {
67
+ const theme = useXUITheme();
68
+ const safeThemeColor = getSafeThemeColor(themeColor);
69
+ return {
70
+ theme,
71
+ colorScheme: theme.colors[safeThemeColor],
72
+ isDefault: safeThemeColor === "default"
73
+ };
74
+ };
75
+ var useAlertContainerStyles = (themeColor, variant) => {
76
+ const { theme, colorScheme, isDefault } = useAlertColorScheme(themeColor);
77
+ const containerStyles = useMemo(() => {
78
+ const backgroundColor = variant === "solid" ? colorScheme.main : variant === "flat" ? colorScheme.background : variant === "faded" ? withOpacity(colorScheme.background, 0.75) : "transparent";
79
+ const borderWidth = variant === "bordered" || variant === "faded" ? theme.borderWidth.md : 0;
80
+ const borderColor = variant === "bordered" ? withOpacity(colorScheme.main, 0.75) : variant === "faded" ? withOpacity(isDefault ? theme.colors.foreground : colorScheme.main, 0.25) : "transparent";
81
+ return {
82
+ backgroundColor,
83
+ borderColor,
84
+ borderWidth,
85
+ paddingVertical: theme.spacing.sm,
86
+ paddingHorizontal: theme.spacing.md
87
+ };
88
+ }, [colorScheme, isDefault, theme, variant]);
89
+ return containerStyles;
90
+ };
91
+ var useAlertIconWrapperStyles = (themeColor, variant) => {
92
+ const { theme, colorScheme, isDefault } = useAlertColorScheme(themeColor);
93
+ const iconWrapperStyles = useMemo(() => {
94
+ const backgroundColor = variant === "solid" ? withOpacity(colorScheme.foreground, 0.16) : withOpacity(isDefault ? theme.colors.foreground : colorScheme.main, 0.12);
95
+ const borderWidth = variant === "bordered" || variant === "faded" ? theme.borderWidth.xs : 0;
96
+ const borderColor = withOpacity(
97
+ isDefault ? theme.colors.foreground : colorScheme.main,
98
+ 0.2
99
+ );
100
+ return {
101
+ backgroundColor,
102
+ borderColor,
103
+ borderWidth
104
+ };
105
+ }, [colorScheme, isDefault, theme, variant]);
106
+ return iconWrapperStyles;
107
+ };
108
+ var useAlertTextStyles = (themeColor, variant) => {
109
+ const { theme, colorScheme, isDefault } = useAlertColorScheme(themeColor);
110
+ const textStyles = useMemo(() => {
111
+ const baseTextColor = variant === "solid" ? colorScheme.foreground : isDefault ? theme.colors.foreground : colorScheme.main;
112
+ return {
113
+ titleStyles: {
114
+ color: baseTextColor,
115
+ fontSize: theme.fontSizes.sm,
116
+ fontWeight: theme.fontWeights.semibold
117
+ },
118
+ descriptionStyles: {
119
+ color: withOpacity(baseTextColor, 0.75),
120
+ fontSize: theme.fontSizes.xs,
121
+ fontWeight: theme.fontWeights.normal
122
+ },
123
+ iconColor: baseTextColor,
124
+ closeButtonColor: baseTextColor
125
+ };
126
+ }, [colorScheme, isDefault, theme, variant]);
127
+ return textStyles;
128
+ };
129
+
130
+ // src/components/alert/alert-icons.tsx
131
+ import React from "react";
132
+ import Svg, { Circle, Line, Path } from "react-native-svg";
133
+ function InfoIcon({ color, size }) {
134
+ return /* @__PURE__ */ React.createElement(Svg, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React.createElement(Circle, { cx: 12, cy: 12, r: 10, stroke: color, strokeWidth: 2 }), /* @__PURE__ */ React.createElement(
135
+ Line,
136
+ {
137
+ x1: 12,
138
+ y1: 10,
139
+ x2: 12,
140
+ y2: 16,
141
+ stroke: color,
142
+ strokeWidth: 2,
143
+ strokeLinecap: "round"
144
+ }
145
+ ), /* @__PURE__ */ React.createElement(Circle, { cx: 12, cy: 7, r: 1, fill: color }));
146
+ }
147
+ function SuccessIcon({ color, size }) {
148
+ return /* @__PURE__ */ React.createElement(Svg, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React.createElement(Circle, { cx: 12, cy: 12, r: 10, stroke: color, strokeWidth: 2 }), /* @__PURE__ */ React.createElement(
149
+ Path,
150
+ {
151
+ d: "M7 12.5L10.2 15.5L17 9",
152
+ stroke: color,
153
+ strokeWidth: 2,
154
+ strokeLinecap: "round",
155
+ strokeLinejoin: "round"
156
+ }
157
+ ));
158
+ }
159
+ function WarningIcon({ color, size }) {
160
+ return /* @__PURE__ */ React.createElement(Svg, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React.createElement(
161
+ Path,
162
+ {
163
+ d: "M12 3L22 20H2L12 3Z",
164
+ stroke: color,
165
+ strokeWidth: 2,
166
+ strokeLinejoin: "round"
167
+ }
168
+ ), /* @__PURE__ */ React.createElement(
169
+ Line,
170
+ {
171
+ x1: 12,
172
+ y1: 9,
173
+ x2: 12,
174
+ y2: 14,
175
+ stroke: color,
176
+ strokeWidth: 2,
177
+ strokeLinecap: "round"
178
+ }
179
+ ), /* @__PURE__ */ React.createElement(Circle, { cx: 12, cy: 17, r: 1, fill: color }));
180
+ }
181
+ function DangerIcon({ color, size }) {
182
+ return /* @__PURE__ */ React.createElement(Svg, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React.createElement(Circle, { cx: 12, cy: 12, r: 10, stroke: color, strokeWidth: 2 }), /* @__PURE__ */ React.createElement(
183
+ Line,
184
+ {
185
+ x1: 9,
186
+ y1: 9,
187
+ x2: 15,
188
+ y2: 15,
189
+ stroke: color,
190
+ strokeWidth: 2,
191
+ strokeLinecap: "round"
192
+ }
193
+ ), /* @__PURE__ */ React.createElement(
194
+ Line,
195
+ {
196
+ x1: 15,
197
+ y1: 9,
198
+ x2: 9,
199
+ y2: 15,
200
+ stroke: color,
201
+ strokeWidth: 2,
202
+ strokeLinecap: "round"
203
+ }
204
+ ));
205
+ }
206
+
207
+ // src/components/alert/alert.tsx
208
+ import { CloseIcon } from "@xaui/icons";
209
+ var iconMap = {
210
+ default: InfoIcon,
211
+ primary: InfoIcon,
212
+ secondary: InfoIcon,
213
+ tertiary: InfoIcon,
214
+ success: SuccessIcon,
215
+ warning: WarningIcon,
216
+ danger: DangerIcon
217
+ };
218
+ var Alert = ({
219
+ title,
220
+ description,
221
+ icon,
222
+ themeColor = "default",
223
+ variant = "flat",
224
+ radius = "md",
225
+ isClosable = false,
226
+ hideIcon = false,
227
+ closeButton,
228
+ isVisible,
229
+ customAppearance,
230
+ children,
231
+ onClose,
232
+ onVisibleChange
233
+ }) => {
234
+ const [internalVisible, setInternalVisible] = useState(isVisible ?? true);
235
+ const [shouldRender, setShouldRender] = useState(isVisible ?? true);
236
+ const isControlled = typeof isVisible === "boolean";
237
+ const visible = isControlled ? isVisible : internalVisible;
238
+ const opacity = useSharedValue(1);
239
+ const scale = useSharedValue(1);
240
+ const radiusStyles = useBorderRadiusStyles(radius);
241
+ const containerStyles = useAlertContainerStyles(themeColor, variant);
242
+ const iconWrapperStyles = useAlertIconWrapperStyles(themeColor, variant);
243
+ const { titleStyles, descriptionStyles, iconColor, closeButtonColor } = useAlertTextStyles(themeColor, variant);
244
+ const finishClosing = useCallback(() => {
245
+ setShouldRender(false);
246
+ if (!isControlled) {
247
+ setInternalVisible(false);
248
+ }
249
+ onVisibleChange?.(false);
250
+ onClose?.();
251
+ }, [isControlled, onClose, onVisibleChange]);
252
+ const handleClose = useCallback(() => {
253
+ if (!visible) return;
254
+ opacity.value = withTiming(0, { duration: 250 });
255
+ scale.value = withTiming(0.95, { duration: 250 }, (finished) => {
256
+ if (finished) {
257
+ runOnJS(finishClosing)();
258
+ }
259
+ });
260
+ }, [finishClosing, opacity, scale, visible]);
261
+ useEffect(() => {
262
+ if (visible && !shouldRender) {
263
+ setShouldRender(true);
264
+ opacity.value = 0;
265
+ scale.value = 0.95;
266
+ opacity.value = withTiming(1, { duration: 250 });
267
+ scale.value = withTiming(1, { duration: 250 });
268
+ return;
269
+ }
270
+ if (!visible && shouldRender) {
271
+ handleClose();
272
+ }
273
+ }, [visible, shouldRender, opacity, scale, handleClose]);
274
+ const animatedStyle = useAnimatedStyle(() => ({
275
+ opacity: opacity.value,
276
+ transform: [{ scale: scale.value }]
277
+ }));
278
+ const IconComponent = iconMap[themeColor] ?? InfoIcon;
279
+ const shouldShowClose = Boolean(closeButton || isClosable || onClose);
280
+ const renderIcon = () => {
281
+ if (hideIcon) return null;
282
+ if (icon && isValidElement(icon)) {
283
+ return cloneElement(icon, { color: iconColor, size: 22 });
284
+ }
285
+ if (icon) {
286
+ return /* @__PURE__ */ React2.createElement(Text, { style: [styles.iconText, { color: iconColor }] }, icon);
287
+ }
288
+ return /* @__PURE__ */ React2.createElement(IconComponent, { color: iconColor, size: 22 });
289
+ };
290
+ const renderContentText = (content) => {
291
+ if (content === null || content === void 0) return null;
292
+ if (typeof content === "string" || typeof content === "number") {
293
+ return /* @__PURE__ */ React2.createElement(
294
+ Text,
295
+ {
296
+ style: [
297
+ styles.description,
298
+ descriptionStyles,
299
+ customAppearance?.description
300
+ ]
301
+ },
302
+ content
303
+ );
304
+ }
305
+ return content;
306
+ };
307
+ const titleNode = useMemo2(() => {
308
+ if (title === null || title === void 0) return null;
309
+ if (typeof title === "string" || typeof title === "number") {
310
+ return /* @__PURE__ */ React2.createElement(Text, { style: [styles.title, titleStyles, customAppearance?.title] }, title);
311
+ }
312
+ return title;
313
+ }, [title, customAppearance?.title, titleStyles]);
314
+ const descriptionNode = renderContentText(description);
315
+ const childrenNode = renderContentText(children);
316
+ const closeButtonNode = useMemo2(() => {
317
+ if (!closeButton) return null;
318
+ if (!isValidElement(closeButton)) return closeButton;
319
+ const existingOnPress = closeButton.props.onPress;
320
+ return cloneElement(closeButton, {
321
+ onPress: (event) => {
322
+ existingOnPress?.(event);
323
+ handleClose();
324
+ }
325
+ });
326
+ }, [closeButton, handleClose]);
327
+ if (!shouldRender) return null;
328
+ return /* @__PURE__ */ React2.createElement(
329
+ Animated.View,
330
+ {
331
+ accessibilityRole: "alert",
332
+ style: [
333
+ styles.container,
334
+ containerStyles,
335
+ radiusStyles,
336
+ customAppearance?.container,
337
+ animatedStyle
338
+ ]
339
+ },
340
+ !hideIcon && /* @__PURE__ */ React2.createElement(View, { style: [styles.iconWrapper, iconWrapperStyles] }, renderIcon()),
341
+ /* @__PURE__ */ React2.createElement(View, { style: styles.mainWrapper }, titleNode, descriptionNode, childrenNode && /* @__PURE__ */ React2.createElement(View, { style: styles.extraContent }, childrenNode)),
342
+ shouldShowClose && /* @__PURE__ */ React2.createElement(View, null, closeButtonNode ?? /* @__PURE__ */ React2.createElement(
343
+ Pressable,
344
+ {
345
+ accessibilityRole: "button",
346
+ accessibilityLabel: "Close",
347
+ onPress: handleClose,
348
+ style: styles.closeButton
349
+ },
350
+ /* @__PURE__ */ React2.createElement(CloseIcon, { size: 20, color: closeButtonColor })
351
+ ))
352
+ );
353
+ };
5
354
  export {
6
355
  Alert
7
356
  };
@@ -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") {