@sincpro/mobile-ui 0.2.1 → 0.3.1

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 (263) hide show
  1. package/README.md +75 -20
  2. package/dist/Dialog/BottomSheet/BottomSheet.Root.d.ts +13 -9
  3. package/dist/Dialog/BottomSheet/BottomSheet.Root.js +6 -2
  4. package/dist/Dialog/Confirmation.context.d.ts +1 -1
  5. package/dist/Dialog/Dialog.ActionSheet.d.ts +17 -0
  6. package/dist/Dialog/Dialog.ActionSheet.js +16 -0
  7. package/dist/Dialog/Dialog.Confirmation.js +5 -1
  8. package/dist/Dialog/Dialog.EditValue.d.ts +1 -1
  9. package/dist/Dialog/Dialog.EditValue.js +1 -1
  10. package/dist/Dialog/Dialog.Sheet.d.ts +26 -0
  11. package/dist/Dialog/Dialog.Sheet.js +55 -0
  12. package/dist/Dialog/index.d.ts +9 -7
  13. package/dist/Dialog/index.js +2 -0
  14. package/dist/Display/Display.Accordion.d.ts +18 -0
  15. package/dist/Display/Display.Accordion.js +22 -0
  16. package/dist/Display/Display.AvatarGroup.d.ts +12 -0
  17. package/dist/Display/Display.AvatarGroup.js +23 -0
  18. package/dist/Display/Display.Badge.d.ts +1 -1
  19. package/dist/Display/Display.Card.d.ts +46 -0
  20. package/dist/Display/Display.Card.js +36 -0
  21. package/dist/Display/Display.Carousel.d.ts +13 -0
  22. package/dist/Display/Display.Carousel.js +19 -0
  23. package/dist/Display/Display.Chip.d.ts +105 -0
  24. package/dist/Display/Display.Chip.js +45 -0
  25. package/dist/Display/Display.CopyableText.d.ts +1 -1
  26. package/dist/Display/Display.CountRecords.d.ts +1 -1
  27. package/dist/Display/Display.DataTable.d.ts +19 -0
  28. package/dist/Display/Display.DataTable.js +22 -0
  29. package/dist/Display/Display.Date.d.ts +15 -2
  30. package/dist/Display/Display.Date.js +34 -4
  31. package/dist/Display/Display.Divider.d.ts +1 -1
  32. package/dist/Display/Display.GradientSurface.d.ts +116 -0
  33. package/dist/Display/Display.GradientSurface.js +62 -0
  34. package/dist/Display/Display.IconBadge.d.ts +13 -0
  35. package/dist/Display/Display.IconBadge.js +30 -0
  36. package/dist/Display/Display.Image.d.ts +15 -0
  37. package/dist/Display/Display.Image.js +17 -0
  38. package/dist/Display/Display.KeyValue.d.ts +10 -0
  39. package/dist/Display/Display.KeyValue.js +9 -0
  40. package/dist/Display/Display.ListItem.d.ts +17 -0
  41. package/dist/Display/Display.ListItem.js +18 -0
  42. package/dist/Display/Display.Logo.js +3 -1
  43. package/dist/Display/Display.MediaCard.d.ts +17 -0
  44. package/dist/Display/Display.MediaCard.js +12 -0
  45. package/dist/Display/Display.MediaEmbed.d.ts +19 -0
  46. package/dist/Display/Display.MediaEmbed.js +39 -0
  47. package/dist/Display/Display.MenuButton.d.ts +1 -1
  48. package/dist/Display/Display.Monetary.d.ts +1 -1
  49. package/dist/Display/Display.Monetary.js +1 -1
  50. package/dist/Display/Display.Pattern.d.ts +26 -0
  51. package/dist/Display/Display.Pattern.js +27 -0
  52. package/dist/Display/Display.PriceTag.d.ts +10 -0
  53. package/dist/Display/Display.PriceTag.js +23 -0
  54. package/dist/Display/Display.ProductCard.d.ts +17 -0
  55. package/dist/Display/Display.ProductCard.js +13 -0
  56. package/dist/Display/Display.Rating.d.ts +11 -0
  57. package/dist/Display/Display.Rating.js +16 -0
  58. package/dist/Display/Display.SearchHistory.d.ts +12 -0
  59. package/dist/Display/Display.SearchHistory.js +13 -0
  60. package/dist/Display/Display.SectionHeader.d.ts +13 -0
  61. package/dist/Display/Display.SectionHeader.js +9 -0
  62. package/dist/Display/Display.Stat.d.ts +10 -0
  63. package/dist/Display/Display.Stat.js +9 -0
  64. package/dist/Display/Display.StatCard.d.ts +14 -0
  65. package/dist/Display/Display.StatCard.js +13 -0
  66. package/dist/Display/Display.StatusDot.d.ts +11 -0
  67. package/dist/Display/Display.StatusDot.js +28 -0
  68. package/dist/Display/Display.Story.d.ts +15 -0
  69. package/dist/Display/Display.Story.js +43 -0
  70. package/dist/Display/Display.StoryTray.d.ts +26 -0
  71. package/dist/Display/Display.StoryTray.js +43 -0
  72. package/dist/Display/Display.StoryViewer.d.ts +26 -0
  73. package/dist/Display/Display.StoryViewer.js +79 -0
  74. package/dist/Display/Display.SwipeableRow.d.ts +15 -0
  75. package/dist/Display/Display.SwipeableRow.js +28 -0
  76. package/dist/Display/Display.Tag.d.ts +11 -0
  77. package/dist/Display/Display.Tag.js +9 -0
  78. package/dist/Display/Display.Timeline.d.ts +13 -0
  79. package/dist/Display/Display.Timeline.js +19 -0
  80. package/dist/Display/Display.Tooltip.d.ts +10 -0
  81. package/dist/Display/Display.Tooltip.js +24 -0
  82. package/dist/Display/index.d.ts +70 -0
  83. package/dist/Display/index.js +58 -0
  84. package/dist/Feedback/ErrorBoundary.d.ts +1 -1
  85. package/dist/Feedback/Feedback.Banner.d.ts +82 -0
  86. package/dist/Feedback/Feedback.Banner.js +35 -0
  87. package/dist/Feedback/Feedback.DomainSplashScreen.d.ts +2 -1
  88. package/dist/Feedback/Feedback.DomainSplashScreen.js +3 -2
  89. package/dist/Feedback/Feedback.Empty.d.ts +1 -1
  90. package/dist/Feedback/Feedback.EmptyState.d.ts +15 -0
  91. package/dist/Feedback/Feedback.EmptyState.js +11 -0
  92. package/dist/Feedback/Feedback.Error.d.ts +1 -1
  93. package/dist/Feedback/Feedback.Loading.d.ts +8 -1
  94. package/dist/Feedback/Feedback.Loading.js +7 -1
  95. package/dist/Feedback/Feedback.PermissionCard.d.ts +15 -0
  96. package/dist/Feedback/Feedback.PermissionCard.js +11 -0
  97. package/dist/Feedback/Feedback.Progress.d.ts +9 -0
  98. package/dist/Feedback/Feedback.Progress.js +35 -0
  99. package/dist/Feedback/Feedback.ProgressCircle.d.ts +12 -0
  100. package/dist/Feedback/Feedback.ProgressCircle.js +15 -0
  101. package/dist/Feedback/Feedback.Skeleton.d.ts +11 -0
  102. package/dist/Feedback/Feedback.Skeleton.js +29 -0
  103. package/dist/Feedback/Feedback.Spinner.js +2 -1
  104. package/dist/Feedback/Feedback.Splash.d.ts +7 -1
  105. package/dist/Feedback/Feedback.Splash.js +11 -2
  106. package/dist/Feedback/Toast.context.d.ts +42 -0
  107. package/dist/Feedback/Toast.context.js +121 -0
  108. package/dist/Feedback/index.d.ts +15 -0
  109. package/dist/Feedback/index.js +15 -0
  110. package/dist/Form/Form.Button.d.ts +10 -4
  111. package/dist/Form/Form.Button.js +27 -16
  112. package/dist/Form/Form.Checkbox.d.ts +1 -1
  113. package/dist/Form/Form.Checkbox.js +1 -1
  114. package/dist/Form/Form.ControlledCheckbox.d.ts +1 -1
  115. package/dist/Form/Form.ControlledInput.d.ts +1 -1
  116. package/dist/Form/Form.ControlledMonetaryInput.d.ts +1 -1
  117. package/dist/Form/Form.ControlledRadioButton.d.ts +1 -1
  118. package/dist/Form/Form.DatePicker.d.ts +20 -0
  119. package/dist/Form/Form.DatePicker.js +38 -0
  120. package/dist/Form/Form.Dropdown.d.ts +1 -1
  121. package/dist/Form/Form.FAB.d.ts +10 -0
  122. package/dist/Form/Form.FAB.js +17 -0
  123. package/dist/Form/Form.FilterButton.d.ts +1 -1
  124. package/dist/Form/Form.FractionalQuantityInput.d.ts +1 -1
  125. package/dist/Form/Form.IconButton.d.ts +1 -1
  126. package/dist/Form/Form.Input.d.ts +2 -1
  127. package/dist/Form/Form.Input.js +1 -1
  128. package/dist/Form/Form.InputField.js +1 -1
  129. package/dist/Form/Form.MonetaryInput.d.ts +1 -1
  130. package/dist/Form/Form.PinInput.d.ts +12 -0
  131. package/dist/Form/Form.PinInput.js +23 -0
  132. package/dist/Form/Form.QuantitySelector.d.ts +2 -1
  133. package/dist/Form/Form.QuantitySelector.js +1 -1
  134. package/dist/Form/Form.RadioButton.d.ts +1 -1
  135. package/dist/Form/Form.SearchBar.d.ts +6 -1
  136. package/dist/Form/Form.SearchBar.js +4 -0
  137. package/dist/Form/Form.Select.d.ts +17 -0
  138. package/dist/Form/Form.Select.js +26 -0
  139. package/dist/Form/Form.Slider.d.ts +20 -0
  140. package/dist/Form/Form.Slider.js +16 -0
  141. package/dist/Form/Form.Switch.d.ts +10 -0
  142. package/dist/Form/Form.Switch.js +9 -0
  143. package/dist/Form/index.d.ts +12 -0
  144. package/dist/Form/index.js +12 -0
  145. package/dist/Navigation/Navigation.AppBar.d.ts +57 -0
  146. package/dist/Navigation/Navigation.AppBar.js +72 -0
  147. package/dist/Navigation/Navigation.BottomNav.d.ts +57 -0
  148. package/dist/Navigation/Navigation.BottomNav.js +108 -0
  149. package/dist/Navigation/Navigation.CollapsingHeader.d.ts +34 -0
  150. package/dist/Navigation/Navigation.CollapsingHeader.js +47 -0
  151. package/dist/Navigation/Navigation.FloatingBar.d.ts +15 -0
  152. package/dist/Navigation/Navigation.FloatingBar.js +21 -0
  153. package/dist/Navigation/Navigation.Header.d.ts +6 -2
  154. package/dist/Navigation/Navigation.Header.js +4 -0
  155. package/dist/Navigation/Navigation.HeaderToolbar.d.ts +1 -1
  156. package/dist/Navigation/Navigation.Menu.d.ts +21 -0
  157. package/dist/Navigation/Navigation.Menu.js +42 -0
  158. package/dist/Navigation/Navigation.RowItem.d.ts +1 -1
  159. package/dist/Navigation/Navigation.SearchBar.d.ts +18 -0
  160. package/dist/Navigation/Navigation.SearchBar.js +28 -0
  161. package/dist/Navigation/Navigation.SegmentedControl.d.ts +14 -0
  162. package/dist/Navigation/Navigation.SegmentedControl.js +13 -0
  163. package/dist/Navigation/Navigation.Steps.d.ts +8 -0
  164. package/dist/Navigation/Navigation.Steps.js +17 -0
  165. package/dist/Navigation/Navigation.TabIcon.d.ts +5 -1
  166. package/dist/Navigation/Navigation.TabIcon.js +4 -0
  167. package/dist/Navigation/Navigation.TabItem.d.ts +5 -0
  168. package/dist/Navigation/Navigation.TabItem.js +5 -0
  169. package/dist/Navigation/Navigation.Tabs.d.ts +28 -0
  170. package/dist/Navigation/Navigation.Tabs.js +45 -0
  171. package/dist/Navigation/index.d.ts +32 -1
  172. package/dist/Navigation/index.js +18 -0
  173. package/dist/Typography/Typography.Text.d.ts +3 -2
  174. package/dist/Typography/Typography.Text.js +16 -6
  175. package/dist/branding.d.ts +6 -0
  176. package/dist/branding.js +7 -0
  177. package/dist/icons/ArrowDownIcon.d.ts +2 -1
  178. package/dist/icons/ArrowUpIcon.d.ts +2 -1
  179. package/dist/icons/CreditIcon.d.ts +1 -1
  180. package/dist/icons/OdooIcon.d.ts +6 -1
  181. package/dist/icons/OdooIcon.js +5 -0
  182. package/dist/icons/PrinterIcon.d.ts +5 -0
  183. package/dist/icons/PrinterIcon.js +5 -0
  184. package/dist/index.d.ts +1 -0
  185. package/dist/index.js +2 -0
  186. package/dist/layouts/AuthContainer.d.ts +1 -1
  187. package/dist/layouts/AuthContainer.js +2 -2
  188. package/dist/layouts/Container.d.ts +1 -0
  189. package/dist/layouts/Container.js +2 -3
  190. package/dist/layouts/GradientContainer.d.ts +1 -1
  191. package/dist/layouts/PlainLayout.d.ts +1 -1
  192. package/dist/layouts/ScrollContainer.d.ts +2 -2
  193. package/dist/layouts/ScrollContainer.js +1 -1
  194. package/dist/layouts/TabNavigatorLayout.d.ts +2 -2
  195. package/dist/layouts/TabNavigatorLayout.js +4 -0
  196. package/dist/primitives/AspectRatio.d.ts +10 -0
  197. package/dist/primitives/AspectRatio.js +8 -0
  198. package/dist/primitives/Box.d.ts +1 -1
  199. package/dist/primitives/Pressable.d.ts +10 -0
  200. package/dist/primitives/Pressable.js +9 -0
  201. package/dist/primitives/Row.d.ts +1 -1
  202. package/dist/primitives/Spacer.d.ts +8 -0
  203. package/dist/primitives/Spacer.js +9 -0
  204. package/dist/primitives/Stack.d.ts +1 -1
  205. package/dist/primitives/index.d.ts +3 -0
  206. package/dist/primitives/index.js +3 -0
  207. package/dist/theme/active.d.ts +2 -0
  208. package/dist/theme/active.js +13 -0
  209. package/dist/theme/components/ThemedActivityIndicator.d.ts +1 -1
  210. package/dist/theme/components/index.d.ts +1 -1
  211. package/dist/theme/components/index.js +1 -1
  212. package/dist/theme/dark.d.ts +7 -0
  213. package/dist/theme/dark.js +85 -0
  214. package/dist/theme/default.js +1 -0
  215. package/dist/theme/define.d.ts +5 -5
  216. package/dist/theme/define.js +5 -5
  217. package/dist/theme/index.d.ts +4 -1
  218. package/dist/theme/index.js +4 -1
  219. package/dist/theme/theme.d.ts +1 -1
  220. package/dist/theme/theme.js +1 -1
  221. package/dist/theme/types.d.ts +15 -14
  222. package/dist/theme/types.js +2 -2
  223. package/dist/theme/typography.d.ts +117 -60
  224. package/dist/theme/typography.js +115 -29
  225. package/dist/theme/useTheme.d.ts +3 -1
  226. package/dist/theme/useTheme.js +6 -1
  227. package/dist/tokens/index.d.ts +2 -0
  228. package/dist/tokens/index.js +2 -0
  229. package/dist/tokens/motion.d.ts +71 -0
  230. package/dist/tokens/motion.js +25 -0
  231. package/dist/utils/date.d.ts +33 -33
  232. package/dist/utils/date.js +39 -39
  233. package/dist/utils/timezone.d.ts +5 -0
  234. package/dist/views/AuthFormView.d.ts +1 -1
  235. package/dist/views/FormViewV2.context.d.ts +1 -1
  236. package/dist/views/FormViewV2.d.ts +12 -11
  237. package/dist/views/FormViewV2.js +8 -4
  238. package/dist/views/ListViewV2.context.d.ts +6 -2
  239. package/dist/views/ListViewV2.context.js +3 -1
  240. package/dist/views/ListViewV2.d.ts +26 -21
  241. package/dist/views/ListViewV2.js +18 -20
  242. package/dist/views/Wizard/Wizard.context.d.ts +1 -1
  243. package/dist/widgets/CircleButton.d.ts +6 -2
  244. package/dist/widgets/CircleButton.js +4 -0
  245. package/dist/widgets/GeoPermissionCard.d.ts +6 -1
  246. package/dist/widgets/GeoPermissionCard.js +8 -3
  247. package/dist/widgets/HomeHeader.d.ts +4 -0
  248. package/dist/widgets/HomeHeader.js +4 -0
  249. package/dist/widgets/JSONViewer.d.ts +2 -1
  250. package/dist/widgets/JSONViewer.js +9 -12
  251. package/dist/widgets/MenuCard.d.ts +1 -1
  252. package/dist/widgets/ScreenHeader.d.ts +5 -1
  253. package/dist/widgets/ScreenHeader.js +4 -0
  254. package/dist/widgets/TimeZoneSelector.d.ts +6 -1
  255. package/dist/widgets/TimeZoneSelector.js +6 -1
  256. package/dist/widgets/TimeZoneSelectorModal.d.ts +6 -1
  257. package/dist/widgets/TimeZoneSelectorModal.js +8 -3
  258. package/package.json +41 -23
  259. package/tailwind.preset.js +14 -0
  260. package/dist/notifications/index.d.ts +0 -1
  261. package/dist/notifications/index.js +0 -1
  262. package/dist/providers/index.d.ts +0 -1
  263. package/dist/providers/index.js +0 -2
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx } from "nativewind/jsx-runtime";
2
+ import { getBrandingLogo } from "../branding";
2
3
  import { tv } from "../theme/tw";
3
4
  import { Image, View } from "react-native";
4
5
  const logo = tv({
@@ -31,6 +32,7 @@ function renderImage(imageClassName, source) {
31
32
  }
32
33
  const Logo = ({ source, size = "medium", className }) => {
33
34
  const styles = logo({ size });
34
- return (_jsx(View, { className: styles.container({ className }), children: renderImage(styles.image(), source) }));
35
+ const resolvedSource = source ?? getBrandingLogo();
36
+ return (_jsx(View, { className: styles.container({ className }), children: renderImage(styles.image(), resolvedSource) }));
35
37
  };
36
38
  export default Logo;
@@ -0,0 +1,17 @@
1
+ import type { ReactNode } from "react";
2
+ import { type ImageSourcePropType } from "react-native";
3
+ export interface MediaCardProps {
4
+ image: ImageSourcePropType;
5
+ title?: string;
6
+ subtitle?: string;
7
+ badge?: ReactNode;
8
+ overlay?: ReactNode;
9
+ aspectRatio?: number;
10
+ height?: number;
11
+ radius?: number;
12
+ onPress?: () => void;
13
+ className?: string;
14
+ testID?: string;
15
+ }
16
+ declare function MediaCard({ image, title, subtitle, badge, overlay, aspectRatio, height, radius, onPress, className, testID, }: MediaCardProps): import("react").JSX.Element;
17
+ export default MediaCard;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import DisplayImage from "../Display/Display.Image";
3
+ import Pressable from "../primitives/Pressable";
4
+ import { cn } from "../theme/tw";
5
+ import { Typography } from "../Typography";
6
+ import { LinearGradient } from "expo-linear-gradient";
7
+ import { View } from "react-native";
8
+ function MediaCard({ image, title, subtitle, badge, overlay, aspectRatio = 16 / 9, height, radius = 16, onPress, className, testID, }) {
9
+ const Wrapper = onPress ? Pressable : View;
10
+ return (_jsxs(Wrapper, { accessibilityLabel: title, accessibilityRole: onPress ? "button" : undefined, className: cn("overflow-hidden", className), onPress: onPress, style: { borderRadius: radius }, testID: testID, children: [_jsx(DisplayImage, { aspectRatio: height ? undefined : aspectRatio, height: height, radius: radius, source: image }), badge ? _jsx(View, { className: "absolute top-3 left-3", children: badge }) : null, title || subtitle || overlay ? (_jsxs(LinearGradient, { colors: ["transparent", "rgba(0,0,0,0.75)"], style: { position: "absolute", left: 0, right: 0, bottom: 0, padding: 12 }, children: [overlay, title ? (_jsx(Typography.Text, { className: "text-white", numberOfLines: 1, semibold: true, variant: "subtitle", children: title })) : null, subtitle ? (_jsx(Typography.Text, { className: "text-white/80", numberOfLines: 1, variant: "bodySmall", children: subtitle })) : null] })) : null] }));
11
+ }
12
+ export default MediaCard;
@@ -0,0 +1,19 @@
1
+ import type { ReactNode } from "react";
2
+ import { type ImageSourcePropType } from "react-native";
3
+ export interface MediaEmbedProps {
4
+ thumbnail: ImageSourcePropType;
5
+ onPress: () => void;
6
+ duration?: string;
7
+ title?: string;
8
+ source?: ReactNode;
9
+ aspectRatio?: number;
10
+ className?: string;
11
+ testID?: string;
12
+ }
13
+ /**
14
+ * Linkable short-video card (Short/TikTok/Reel): thumbnail + play + duration.
15
+ * Opens the content on press (onPress). True inline embedding needs WebView (optional
16
+ * peer) — this is the lightweight/portable piece; wrap it with your player if needed.
17
+ */
18
+ declare function MediaEmbed({ thumbnail, onPress, duration, title, source, aspectRatio, className, testID, }: MediaEmbedProps): import("react").JSX.Element;
19
+ export default MediaEmbed;
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import Icon from "../Display/Display.Icon";
3
+ import DisplayImage from "../Display/Display.Image";
4
+ import Pressable from "../primitives/Pressable";
5
+ import { theme } from "../theme";
6
+ import { cn } from "../theme/tw";
7
+ import { Typography } from "../Typography";
8
+ import { View } from "react-native";
9
+ /**
10
+ * Linkable short-video card (Short/TikTok/Reel): thumbnail + play + duration.
11
+ * Opens the content on press (onPress). True inline embedding needs WebView (optional
12
+ * peer) — this is the lightweight/portable piece; wrap it with your player if needed.
13
+ */
14
+ function MediaEmbed({ thumbnail, onPress, duration, title, source, aspectRatio = 9 / 16, className, testID, }) {
15
+ return (_jsxs(Pressable, { accessibilityLabel: title ?? "Reproducir video", accessibilityRole: "button", className: cn("overflow-hidden rounded-xl", className), onPress: onPress, testID: testID, children: [_jsx(DisplayImage, { aspectRatio: aspectRatio, radius: 12, source: thumbnail }), _jsx(View, { style: {
16
+ position: "absolute",
17
+ top: 0,
18
+ left: 0,
19
+ right: 0,
20
+ bottom: 0,
21
+ alignItems: "center",
22
+ justifyContent: "center",
23
+ }, children: _jsx(View, { style: {
24
+ width: 44,
25
+ height: 44,
26
+ borderRadius: 22,
27
+ backgroundColor: "rgba(0,0,0,0.55)",
28
+ alignItems: "center",
29
+ justifyContent: "center",
30
+ }, children: _jsx(Icon, { color: theme.text.inverse, name: "play", size: 22 }) }) }), duration ? (_jsx(View, { className: "rounded", style: {
31
+ position: "absolute",
32
+ bottom: 8,
33
+ right: 8,
34
+ backgroundColor: "rgba(0,0,0,0.7)",
35
+ paddingHorizontal: 6,
36
+ paddingVertical: 2,
37
+ }, children: _jsx(Typography.Text, { className: "text-white", variant: "caption", children: duration }) })) : null, source ? (_jsx(View, { style: { position: "absolute", top: 8, left: 8 }, children: source })) : null, title ? (_jsx(View, { style: { position: "absolute", left: 8, right: 8, bottom: 8 }, children: _jsx(Typography.Text, { className: "text-white", numberOfLines: 2, variant: "bodySmall", children: title }) })) : null] }));
38
+ }
39
+ export default MediaEmbed;
@@ -99,5 +99,5 @@ interface MenuButtonProps extends VariantProps<typeof menuButton> {
99
99
  rightComponent?: ReactNode;
100
100
  className?: string;
101
101
  }
102
- declare function MenuButton({ icon: Icon, label, description, onPress, rightComponent, showDivider, variant, disabled, className, }: MenuButtonProps): import("react/jsx-runtime").JSX.Element;
102
+ declare function MenuButton({ icon: Icon, label, description, onPress, rightComponent, showDivider, variant, disabled, className, }: MenuButtonProps): import("react").JSX.Element;
103
103
  export default MenuButton;
@@ -15,5 +15,5 @@ interface MonetaryFieldProps {
15
15
  bold?: boolean;
16
16
  className?: string;
17
17
  }
18
- declare function MonetaryField({ value, currencySymbol, prefix, color, textVariant, style, symbolColor, semibold, bold, className, }: MonetaryFieldProps): import("react/jsx-runtime").JSX.Element;
18
+ declare function MonetaryField({ value, currencySymbol, prefix, color, textVariant, style, symbolColor, semibold, bold, className, }: MonetaryFieldProps): import("react").JSX.Element;
19
19
  export default MonetaryField;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
2
  import { Typography } from "../Typography";
3
3
  import { formatTwoDecimals } from "../utils/monetary";
4
- function MonetaryField({ value, currencySymbol = "₡", prefix = "", color, textVariant = "body", style = {}, symbolColor, semibold = true, bold = false, className, }) {
4
+ function MonetaryField({ value, currencySymbol = "₡", prefix = "", color, textVariant = "data", style = {}, symbolColor, semibold = true, bold = false, className, }) {
5
5
  const isEmptyValue = value === null || value === undefined || value === "";
6
6
  const formatted = isEmptyValue ? "0.00" : formatTwoDecimals(value);
7
7
  return (_jsxs(Typography.Text, { bold: bold, className: className, color: color, semibold: semibold && !bold, style: style, variant: textVariant, children: [_jsx(Typography.Text, { className: className, color: symbolColor || color, variant: textVariant, children: currencySymbol }), " ", prefix && `${prefix} `, formatted] }));
@@ -0,0 +1,26 @@
1
+ import { type ViewStyle } from "react-native";
2
+ export type PatternKind = "dots" | "grid" | "diagonals";
3
+ export interface PatternProps {
4
+ /** Texture kind (img: puntos / grilla / diagonales). */
5
+ kind?: PatternKind;
6
+ /** Line/dot color (any color string; use a token value for theming). */
7
+ color?: string;
8
+ /** Stroke/dot opacity (0–1). Default 0.12. */
9
+ opacity?: number;
10
+ /** Tile size in px (texture density). Default 22. */
11
+ size?: number;
12
+ /** Absolute-fill the parent as a background layer. Default true. */
13
+ absoluteFill?: boolean;
14
+ className?: string;
15
+ style?: ViewStyle;
16
+ testID?: string;
17
+ }
18
+ /**
19
+ * Decorative SVG texture (dots / grid / diagonals) used as a background layer behind heroes,
20
+ * splash, empty states. Tiles to any size via an SVG `<Pattern>`. Pure SVG — iOS + Android,
21
+ * no native dep beyond `react-native-svg` (already a peer). Drop inside a relative/overflow
22
+ * container (e.g. a `GradientSurface`).
23
+ */
24
+ declare function Pattern({ kind, color, opacity, size, absoluteFill, className, style, testID, }: PatternProps): import("react").JSX.Element;
25
+ export default Pattern;
26
+ export { Pattern };
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import { cn } from "../theme/tw";
3
+ import { StyleSheet, View } from "react-native";
4
+ import Svg, { Circle, Defs, Line, Pattern as SvgPattern, Rect } from "react-native-svg";
5
+ /**
6
+ * Decorative SVG texture (dots / grid / diagonals) used as a background layer behind heroes,
7
+ * splash, empty states. Tiles to any size via an SVG `<Pattern>`. Pure SVG — iOS + Android,
8
+ * no native dep beyond `react-native-svg` (already a peer). Drop inside a relative/overflow
9
+ * container (e.g. a `GradientSurface`).
10
+ */
11
+ function Pattern({ kind = "dots", color = "#FFFFFF", opacity = 0.12, size = 22, absoluteFill = true, className, style, testID, }) {
12
+ const id = `pat-${kind}-${size}`;
13
+ const tile = (() => {
14
+ switch (kind) {
15
+ case "grid":
16
+ return (_jsxs(_Fragment, { children: [_jsx(Line, { stroke: color, strokeWidth: 1, x1: 0, x2: size, y1: 0, y2: 0 }), _jsx(Line, { stroke: color, strokeWidth: 1, x1: 0, x2: 0, y1: 0, y2: size })] }));
17
+ case "diagonals":
18
+ return _jsx(Line, { stroke: color, strokeWidth: 1.5, x1: 0, x2: size, y1: size, y2: 0 });
19
+ case "dots":
20
+ default:
21
+ return _jsx(Circle, { cx: size / 2, cy: size / 2, fill: color, r: 1.4 });
22
+ }
23
+ })();
24
+ return (_jsx(View, { className: cn(className), pointerEvents: "none", style: [absoluteFill ? StyleSheet.absoluteFill : undefined, { opacity }, style], testID: testID, children: _jsxs(Svg, { height: "100%", width: "100%", children: [_jsx(Defs, { children: _jsx(SvgPattern, { height: size, id: id, patternUnits: "userSpaceOnUse", width: size, x: 0, y: 0, children: tile }) }), _jsx(Rect, { fill: `url(#${id})`, height: "100%", width: "100%" })] }) }));
25
+ }
26
+ export default Pattern;
27
+ export { Pattern };
@@ -0,0 +1,10 @@
1
+ export interface PriceTagProps {
2
+ amount: number;
3
+ originalAmount?: number;
4
+ currency?: string;
5
+ size?: "sm" | "md" | "lg";
6
+ className?: string;
7
+ testID?: string;
8
+ }
9
+ declare function PriceTag({ amount, originalAmount, currency, size, className, testID, }: PriceTagProps): import("react").JSX.Element;
10
+ export default PriceTag;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "nativewind/jsx-runtime";
2
+ import { cn } from "../theme/tw";
3
+ import { Typography } from "../Typography";
4
+ import { View } from "react-native";
5
+ const sizeMap = {
6
+ sm: { price: "data", original: "captionSmall" },
7
+ md: { price: "data", original: "caption" },
8
+ lg: { price: "dataLarge", original: "data" },
9
+ };
10
+ function format(amount, currency) {
11
+ const formatted = amount.toLocaleString("es-BO", {
12
+ minimumFractionDigits: 2,
13
+ maximumFractionDigits: 2,
14
+ });
15
+ return `${currency} ${formatted}`;
16
+ }
17
+ function PriceTag({ amount, originalAmount, currency = "Bs", size = "md", className, testID, }) {
18
+ const variants = sizeMap[size];
19
+ const hasDiscount = typeof originalAmount === "number" && originalAmount > amount;
20
+ const off = hasDiscount ? Math.round((1 - amount / originalAmount) * 100) : 0;
21
+ return (_jsxs(View, { className: cn("flex-row items-baseline gap-2", className), testID: testID, children: [_jsx(Typography.Text, { className: "text-text-primary", semibold: true, variant: variants.price, children: format(amount, currency) }), hasDiscount ? (_jsxs(_Fragment, { children: [_jsx(Typography.Text, { className: "text-text-tertiary", style: { textDecorationLine: "line-through" }, variant: variants.original, children: format(originalAmount, currency) }), _jsx(View, { className: "bg-danger-light rounded px-1.5 py-0.5", children: _jsxs(Typography.Text, { className: "text-danger font-semibold", variant: "caption", children: ["-", off, "%"] }) })] })) : null] }));
22
+ }
23
+ export default PriceTag;
@@ -0,0 +1,17 @@
1
+ import type { ReactNode } from "react";
2
+ import { type ImageSourcePropType } from "react-native";
3
+ export interface ProductCardProps {
4
+ title: string;
5
+ image: ImageSourcePropType;
6
+ price: number;
7
+ originalPrice?: number;
8
+ currency?: string;
9
+ subtitle?: string;
10
+ rating?: number;
11
+ badge?: ReactNode;
12
+ onPress?: () => void;
13
+ className?: string;
14
+ testID?: string;
15
+ }
16
+ declare function ProductCard({ title, image, price, originalPrice, currency, subtitle, rating, badge, onPress, className, testID, }: ProductCardProps): import("react").JSX.Element;
17
+ export default ProductCard;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import DisplayImage from "../Display/Display.Image";
3
+ import PriceTag from "../Display/Display.PriceTag";
4
+ import Rating from "../Display/Display.Rating";
5
+ import Pressable from "../primitives/Pressable";
6
+ import { theme } from "../theme";
7
+ import { cn } from "../theme/tw";
8
+ import { Typography } from "../Typography";
9
+ import { View } from "react-native";
10
+ function ProductCard({ title, image, price, originalPrice, currency, subtitle, rating, badge, onPress, className, testID, }) {
11
+ return (_jsxs(Pressable, { accessibilityLabel: title, className: cn("bg-bg-card rounded-xl overflow-hidden border border-border-light", className), onPress: onPress, style: theme.shadow.sm, testID: testID, children: [_jsxs(View, { children: [_jsx(DisplayImage, { aspectRatio: 1, radius: 0, source: image }), badge ? _jsx(View, { className: "absolute top-2 left-2", children: badge }) : null] }), _jsxs(View, { className: "p-3 gap-1", children: [_jsx(Typography.Text, { className: "text-text-primary", numberOfLines: 1, semibold: true, variant: "body", children: title }), subtitle ? (_jsx(Typography.Text, { className: "text-text-secondary", numberOfLines: 1, variant: "bodySmall", children: subtitle })) : null, typeof rating === "number" ? _jsx(Rating, { readOnly: true, size: 14, value: rating }) : null, _jsx(View, { className: "mt-1", children: _jsx(PriceTag, { amount: price, currency: currency, originalAmount: originalPrice, size: "sm" }) })] })] }));
12
+ }
13
+ export default ProductCard;
@@ -0,0 +1,11 @@
1
+ export interface RatingProps {
2
+ value: number;
3
+ max?: number;
4
+ size?: number;
5
+ onChange?: (value: number) => void;
6
+ readOnly?: boolean;
7
+ className?: string;
8
+ testID?: string;
9
+ }
10
+ declare function Rating({ value, max, size, onChange, readOnly, className, testID, }: RatingProps): import("react").JSX.Element;
11
+ export default Rating;
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "nativewind/jsx-runtime";
2
+ import Icon from "../Display/Display.Icon";
3
+ import Pressable from "../primitives/Pressable";
4
+ import { theme } from "../theme";
5
+ import { View } from "react-native";
6
+ function Rating({ value, max = 5, size = 24, onChange, readOnly = false, className, testID, }) {
7
+ const interactive = !readOnly && !!onChange;
8
+ return (_jsx(View, { accessibilityLabel: `Calificación ${value} de ${max}`, accessibilityRole: interactive ? "adjustable" : "image", className: className, style: { flexDirection: "row", gap: 4 }, testID: testID, children: Array.from({ length: max }).map((_, index) => {
9
+ const filled = index < Math.round(value);
10
+ const star = (_jsx(Icon, { color: filled ? theme.warning : theme.icon.disabled, name: filled ? "star" : "star-outline", size: size }));
11
+ if (!interactive)
12
+ return _jsx(View, { children: star }, index);
13
+ return (_jsx(Pressable, { accessibilityLabel: `${index + 1} estrellas`, hitSlop: 6, onPress: () => onChange?.(index + 1), children: star }, index));
14
+ }) }));
15
+ }
16
+ export default Rating;
@@ -0,0 +1,12 @@
1
+ export interface SearchHistoryProps {
2
+ items: string[];
3
+ onSelect: (value: string) => void;
4
+ onRemove: (value: string) => void;
5
+ onClearAll?: () => void;
6
+ title?: string;
7
+ icon?: string;
8
+ className?: string;
9
+ testID?: string;
10
+ }
11
+ declare function SearchHistory({ items, onSelect, onRemove, onClearAll, title, icon, className, testID, }: SearchHistoryProps): import("react").JSX.Element | null;
12
+ export default SearchHistory;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import Icon from "../Display/Display.Icon";
3
+ import Pressable from "../primitives/Pressable";
4
+ import { theme } from "../theme";
5
+ import { cn } from "../theme/tw";
6
+ import { Typography } from "../Typography";
7
+ import { View } from "react-native";
8
+ function SearchHistory({ items, onSelect, onRemove, onClearAll, title = "Búsquedas recientes", icon = "time-outline", className, testID, }) {
9
+ if (items.length === 0)
10
+ return null;
11
+ return (_jsxs(View, { className: cn("gap-1", className), testID: testID, children: [_jsxs(View, { className: "flex-row items-center justify-between px-4 py-1", children: [_jsx(Typography.Text, { className: "text-text-secondary", semibold: true, variant: "bodySmall", children: title }), onClearAll ? (_jsx(Pressable, { accessibilityLabel: "Borrar todo", hitSlop: 8, onPress: onClearAll, children: _jsx(Typography.Text, { className: "text-primary", variant: "bodySmall", children: "Borrar todo" }) })) : null] }), items.map((value) => (_jsxs(Pressable, { accessibilityLabel: value, className: "flex-row items-center gap-3 px-4 py-2.5", onPress: () => onSelect(value), children: [_jsx(Icon, { color: theme.icon.tertiary, name: icon, size: 18 }), _jsx(Typography.Text, { className: "flex-1 text-text-primary", numberOfLines: 1, children: value }), _jsx(Pressable, { accessibilityLabel: `Quitar ${value}`, hitSlop: 10, onPress: () => onRemove(value), children: _jsx(Icon, { color: theme.icon.tertiary, name: "close", size: 16 }) })] }, value)))] }));
12
+ }
13
+ export default SearchHistory;
@@ -0,0 +1,13 @@
1
+ export interface SectionHeaderAction {
2
+ label: string;
3
+ onPress: () => void;
4
+ }
5
+ export interface SectionHeaderProps {
6
+ title: string;
7
+ subtitle?: string;
8
+ action?: SectionHeaderAction;
9
+ className?: string;
10
+ testID?: string;
11
+ }
12
+ declare function SectionHeader({ title, subtitle, action, className, testID }: SectionHeaderProps): import("react").JSX.Element;
13
+ export default SectionHeader;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import Pressable from "../primitives/Pressable";
3
+ import { cn } from "../theme/tw";
4
+ import { Typography } from "../Typography";
5
+ import { View } from "react-native";
6
+ function SectionHeader({ title, subtitle, action, className, testID }) {
7
+ return (_jsxs(View, { className: cn("flex-row items-center justify-between px-4 py-2", className), testID: testID, children: [_jsxs(View, { className: "flex-1", children: [_jsx(Typography.Text, { className: "text-text-primary", semibold: true, variant: "subtitle", children: title }), subtitle ? (_jsx(Typography.Text, { className: "text-text-secondary", variant: "bodySmall", children: subtitle })) : null] }), action ? (_jsx(Pressable, { accessibilityRole: "button", hitSlop: 8, onPress: action.onPress, children: _jsx(Typography.Text, { className: "text-primary text-sm font-semibold", children: action.label }) })) : null] }));
8
+ }
9
+ export default SectionHeader;
@@ -0,0 +1,10 @@
1
+ export interface StatProps {
2
+ value: string | number;
3
+ label: string;
4
+ align?: "center" | "start";
5
+ className?: string;
6
+ testID?: string;
7
+ }
8
+ declare function Stat({ value, label, align, className, testID }: StatProps): import("react").JSX.Element;
9
+ export default Stat;
10
+ export { Stat };
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import { cn } from "../theme/tw";
3
+ import { Typography } from "../Typography";
4
+ import { View } from "react-native";
5
+ function Stat({ value, label, align = "center", className, testID }) {
6
+ return (_jsxs(View, { className: cn(align === "center" ? "items-center" : "items-start", className), testID: testID, children: [_jsx(Typography.Text, { className: "text-text-primary", variant: "dataLarge", children: value }), _jsx(Typography.Text, { className: "text-text-secondary", variant: "caption", children: label })] }));
7
+ }
8
+ export default Stat;
9
+ export { Stat };
@@ -0,0 +1,14 @@
1
+ import type { ReactNode } from "react";
2
+ export interface StatCardProps {
3
+ label: string;
4
+ value: string | number;
5
+ icon?: string;
6
+ delta?: number;
7
+ deltaSuffix?: string;
8
+ hint?: string;
9
+ trailing?: ReactNode;
10
+ className?: string;
11
+ testID?: string;
12
+ }
13
+ declare function StatCard({ label, value, icon, delta, deltaSuffix, hint, trailing, className, testID, }: StatCardProps): import("react").JSX.Element;
14
+ export default StatCard;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "nativewind/jsx-runtime";
2
+ import Icon from "../Display/Display.Icon";
3
+ import { theme } from "../theme";
4
+ import { cn } from "../theme/tw";
5
+ import { Typography } from "../Typography";
6
+ import { View } from "react-native";
7
+ function StatCard({ label, value, icon, delta, deltaSuffix = "%", hint, trailing, className, testID, }) {
8
+ const hasDelta = typeof delta === "number";
9
+ const up = hasDelta && delta >= 0;
10
+ const deltaColor = up ? theme.success : theme.danger;
11
+ return (_jsxs(View, { className: cn("bg-bg-card rounded-lg border border-border-light p-4 gap-1", className), style: theme.shadow.sm, testID: testID, children: [_jsxs(View, { className: "flex-row items-center justify-between", children: [_jsx(Typography.Text, { className: "text-text-secondary", variant: "caption", children: label }), icon ? _jsx(Icon, { color: theme.icon.secondary, name: icon, size: 18 }) : null, trailing] }), _jsx(Typography.Text, { className: "text-text-primary", semibold: true, variant: "h3", children: value }), hasDelta || hint ? (_jsxs(View, { className: "flex-row items-center gap-1", children: [hasDelta ? (_jsxs(_Fragment, { children: [_jsx(Icon, { color: deltaColor, name: up ? "arrow-up" : "arrow-down", size: 14 }), _jsxs(Typography.Text, { style: { color: deltaColor }, variant: "caption", children: [Math.abs(delta), deltaSuffix] })] })) : null, hint ? (_jsx(Typography.Text, { className: "text-text-tertiary", variant: "caption", children: hint })) : null] })) : null] }));
12
+ }
13
+ export default StatCard;
@@ -0,0 +1,11 @@
1
+ export type StatusKind = "online" | "offline" | "busy" | "away";
2
+ export interface StatusDotProps {
3
+ status?: StatusKind;
4
+ label?: string;
5
+ size?: number;
6
+ color?: string;
7
+ className?: string;
8
+ testID?: string;
9
+ }
10
+ declare function StatusDot({ status, label, size, color, className, testID, }: StatusDotProps): import("react").JSX.Element;
11
+ export default StatusDot;
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import { theme } from "../theme";
3
+ import { cn } from "../theme/tw";
4
+ import { Typography } from "../Typography";
5
+ import { View } from "react-native";
6
+ const statusColor = {
7
+ online: theme.success,
8
+ offline: theme.icon.disabled,
9
+ busy: theme.danger,
10
+ away: theme.warning,
11
+ };
12
+ const statusLabel = {
13
+ online: "En línea",
14
+ offline: "Desconectado",
15
+ busy: "Ocupado",
16
+ away: "Ausente",
17
+ };
18
+ function StatusDot({ status = "online", label, size = 8, color, className, testID, }) {
19
+ const dotColor = color ?? statusColor[status];
20
+ const text = label ?? statusLabel[status];
21
+ return (_jsxs(View, { accessibilityLabel: text, className: cn("flex-row items-center gap-1.5", className), testID: testID, children: [_jsx(View, { style: {
22
+ width: size,
23
+ height: size,
24
+ borderRadius: size / 2,
25
+ backgroundColor: dotColor,
26
+ } }), text ? (_jsx(Typography.Text, { className: "text-text-secondary", variant: "bodySmall", children: text })) : null] }));
27
+ }
28
+ export default StatusDot;
@@ -0,0 +1,15 @@
1
+ import { type ImageSourcePropType } from "react-native";
2
+ export interface StoryProps {
3
+ image: ImageSourcePropType;
4
+ label?: string;
5
+ seen?: boolean;
6
+ variant?: "circle" | "card";
7
+ size?: number;
8
+ avatar?: ImageSourcePropType;
9
+ /** Mostrar el círculo del autor en la card. `false` = card de historia sin avatar. */
10
+ showAvatar?: boolean;
11
+ onPress?: () => void;
12
+ testID?: string;
13
+ }
14
+ declare function Story({ image, label, seen, variant, size, avatar, showAvatar, onPress, testID, }: StoryProps): import("react").JSX.Element;
15
+ export default Story;
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import Pressable from "../primitives/Pressable";
3
+ import { theme } from "../theme";
4
+ import { Typography } from "../Typography";
5
+ import { LinearGradient } from "expo-linear-gradient";
6
+ import { Image, View } from "react-native";
7
+ const RING = ["#F58529", "#DD2A7B"];
8
+ function Story({ image, label, seen = false, variant = "circle", size = 68, avatar, showAvatar = true, onPress, testID, }) {
9
+ if (variant === "card") {
10
+ return (_jsxs(Pressable, { accessibilityLabel: label, accessibilityRole: "button", onPress: onPress, style: { width: size * 1.6, borderRadius: 14, overflow: "hidden" }, testID: testID, children: [_jsx(Image, { source: image, style: { width: "100%", height: size * 2.6 } }), showAvatar ? (_jsx(View, { style: {
11
+ position: "absolute",
12
+ top: 8,
13
+ left: 8,
14
+ borderRadius: 999,
15
+ borderWidth: 3,
16
+ borderColor: seen ? theme.border.strong : theme.primary,
17
+ }, children: _jsx(Image, { source: avatar ?? image, style: { width: 34, height: 34, borderRadius: 17 } }) })) : null, label ? (_jsx(LinearGradient, { colors: ["transparent", "rgba(0,0,0,0.7)"], style: {
18
+ position: "absolute",
19
+ left: 0,
20
+ right: 0,
21
+ bottom: 0,
22
+ padding: 8,
23
+ paddingTop: 24,
24
+ }, children: _jsx(Typography.Text, { className: "text-white", numberOfLines: 2, semibold: true, variant: "caption", children: label }) })) : null] }));
25
+ }
26
+ const ringPadding = 3;
27
+ const innerSize = size - ringPadding * 2 - 4;
28
+ return (_jsxs(Pressable, { accessibilityLabel: label, accessibilityRole: "button", onPress: onPress, style: { alignItems: "center", width: size + 8, gap: 4 }, testID: testID, children: [_jsx(LinearGradient, { colors: seen ? [theme.border.strong, theme.border.strong] : RING, style: {
29
+ width: size,
30
+ height: size,
31
+ borderRadius: size / 2,
32
+ alignItems: "center",
33
+ justifyContent: "center",
34
+ }, children: _jsx(View, { style: {
35
+ width: innerSize + 4,
36
+ height: innerSize + 4,
37
+ borderRadius: (innerSize + 4) / 2,
38
+ backgroundColor: theme.bg.card,
39
+ alignItems: "center",
40
+ justifyContent: "center",
41
+ }, children: _jsx(Image, { source: image, style: { width: innerSize, height: innerSize, borderRadius: innerSize / 2 } }) }) }), label ? (_jsx(Typography.Text, { className: "text-text-secondary", numberOfLines: 1, style: { maxWidth: size + 6 }, variant: "caption", children: label })) : null] }));
42
+ }
43
+ export default Story;
@@ -0,0 +1,26 @@
1
+ import { type ImageSourcePropType } from "react-native";
2
+ export interface StoryTrayItem {
3
+ id: string;
4
+ image: ImageSourcePropType;
5
+ label?: string;
6
+ avatar?: ImageSourcePropType;
7
+ seen?: boolean;
8
+ }
9
+ export interface StoryTrayCreate {
10
+ label?: string;
11
+ image?: ImageSourcePropType;
12
+ onPress: () => void;
13
+ }
14
+ export interface StoryTrayProps {
15
+ stories: StoryTrayItem[];
16
+ onStoryPress?: (item: StoryTrayItem) => void;
17
+ create?: StoryTrayCreate;
18
+ variant?: "circle" | "card";
19
+ size?: number;
20
+ /** Mostrar el avatar del autor en cada card (solo variant="card"). */
21
+ showAvatar?: boolean;
22
+ className?: string;
23
+ testID?: string;
24
+ }
25
+ declare function StoryTray({ stories, onStoryPress, create, variant, size, showAvatar, className, testID, }: StoryTrayProps): import("react").JSX.Element;
26
+ export default StoryTray;
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import Icon from "../Display/Display.Icon";
3
+ import Story from "../Display/Display.Story";
4
+ import Pressable from "../primitives/Pressable";
5
+ import { theme } from "../theme";
6
+ import { Typography } from "../Typography";
7
+ import { Image, ScrollView, View } from "react-native";
8
+ function CreateCard({ create, size }) {
9
+ const w = size * 1.6;
10
+ return (_jsxs(Pressable, { accessibilityLabel: create.label ?? "Crear historia", accessibilityRole: "button", onPress: create.onPress, style: {
11
+ width: w,
12
+ borderRadius: 14,
13
+ overflow: "hidden",
14
+ backgroundColor: theme.bg.card,
15
+ borderWidth: 1,
16
+ borderColor: theme.border.light,
17
+ }, children: [create.image ? (_jsx(Image, { source: create.image, style: { width: "100%", height: size * 1.7 } })) : (_jsx(View, { style: { width: "100%", height: size * 1.7, backgroundColor: theme.bg.muted } })), _jsxs(View, { style: { alignItems: "center", paddingVertical: 14 }, children: [_jsx(View, { style: {
18
+ position: "absolute",
19
+ top: -16,
20
+ width: 32,
21
+ height: 32,
22
+ borderRadius: 16,
23
+ backgroundColor: theme.primary,
24
+ alignItems: "center",
25
+ justifyContent: "center",
26
+ borderWidth: 3,
27
+ borderColor: theme.bg.card,
28
+ }, children: _jsx(Icon, { color: theme.text.inverse, name: "add", size: 20 }) }), _jsx(Typography.Text, { className: "text-text-primary mt-2", semibold: true, variant: "caption", children: create.label ?? "Crear historia" })] })] }));
29
+ }
30
+ function CreateCircle({ create, size }) {
31
+ return (_jsxs(Pressable, { accessibilityLabel: create.label ?? "Crear historia", accessibilityRole: "button", onPress: create.onPress, style: { alignItems: "center", width: size + 8, gap: 4 }, children: [_jsx(View, { style: {
32
+ width: size,
33
+ height: size,
34
+ borderRadius: size / 2,
35
+ backgroundColor: theme.bg.muted,
36
+ alignItems: "center",
37
+ justifyContent: "center",
38
+ }, children: _jsx(Icon, { color: theme.primary, name: "add-circle", size: size * 0.5 }) }), _jsx(Typography.Text, { className: "text-text-secondary", numberOfLines: 1, style: { maxWidth: size + 6 }, variant: "caption", children: create.label ?? "Crear" })] }));
39
+ }
40
+ function StoryTray({ stories, onStoryPress, create, variant = "card", size = 68, showAvatar = true, className, testID, }) {
41
+ return (_jsxs(ScrollView, { className: className, contentContainerStyle: { gap: 8, paddingHorizontal: 12, paddingVertical: 4 }, horizontal: true, showsHorizontalScrollIndicator: false, testID: testID, children: [create ? (variant === "card" ? (_jsx(CreateCard, { create: create, size: size })) : (_jsx(CreateCircle, { create: create, size: size }))) : null, stories.map((item) => (_jsx(Story, { avatar: item.avatar, image: item.image, label: item.label, onPress: () => onStoryPress?.(item), seen: item.seen, showAvatar: showAvatar, size: size, variant: variant }, item.id)))] }));
42
+ }
43
+ export default StoryTray;
@@ -0,0 +1,26 @@
1
+ import type { ReactNode } from "react";
2
+ import { type ImageSourcePropType } from "react-native";
3
+ export interface StoryViewerSlide {
4
+ image: ImageSourcePropType;
5
+ }
6
+ export interface StoryViewerProps {
7
+ visible: boolean;
8
+ slides: StoryViewerSlide[];
9
+ index: number;
10
+ onIndexChange: (index: number) => void;
11
+ onClose: () => void;
12
+ title: string;
13
+ subtitle?: string;
14
+ time?: string;
15
+ avatar?: ImageSourcePropType;
16
+ progress?: number;
17
+ muted?: boolean;
18
+ paused?: boolean;
19
+ onToggleMute?: () => void;
20
+ onTogglePause?: () => void;
21
+ onMore?: () => void;
22
+ footer?: ReactNode;
23
+ testID?: string;
24
+ }
25
+ declare function StoryViewer({ visible, slides, index, onIndexChange, onClose, title, subtitle, time, avatar, progress, muted, paused, onToggleMute, onTogglePause, onMore, footer, testID, }: StoryViewerProps): import("react").JSX.Element | null;
26
+ export default StoryViewer;