@sincpro/mobile-ui 2.0.1 → 3.0.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 (198) hide show
  1. package/README.md +7 -2
  2. package/dist/Actions/Actions.Button.d.ts +2 -1
  3. package/dist/Actions/Actions.Button.js +31 -37
  4. package/dist/Actions/Actions.Dock.d.ts +6 -6
  5. package/dist/Actions/Actions.Dock.js +14 -72
  6. package/dist/Actions/Actions.FAB.d.ts +2 -1
  7. package/dist/Actions/Actions.FilterButton.js +1 -1
  8. package/dist/Actions/Actions.IconButton.d.ts +3 -4
  9. package/dist/Actions/Actions.IconButton.js +2 -2
  10. package/dist/Dialog/Confirmation.context.d.ts +5 -14
  11. package/dist/Dialog/Confirmation.context.js +11 -51
  12. package/dist/Dialog/Dialog.ActionSheet.d.ts +8 -7
  13. package/dist/Dialog/Dialog.ActionSheet.js +45 -19
  14. package/dist/Dialog/Dialog.Confirmation.d.ts +14 -11
  15. package/dist/Dialog/Dialog.Confirmation.js +38 -14
  16. package/dist/Dialog/Dialog.EditValue.d.ts +21 -16
  17. package/dist/Dialog/Dialog.EditValue.js +73 -14
  18. package/dist/Dialog/Dialog.Sheet.d.ts +8 -24
  19. package/dist/Dialog/Dialog.Sheet.js +15 -60
  20. package/dist/Dialog/index.d.ts +14 -14
  21. package/dist/Dialog/index.js +5 -3
  22. package/dist/Dialog/requestConfirmation.d.ts +3 -0
  23. package/dist/Dialog/requestConfirmation.js +13 -0
  24. package/dist/Display/Display.Accordion.js +1 -1
  25. package/dist/Display/Display.Avatar.d.ts +6 -6
  26. package/dist/Display/Display.Avatar.js +2 -2
  27. package/dist/Display/Display.Badge.js +4 -4
  28. package/dist/Display/Display.Card.js +5 -2
  29. package/dist/Display/Display.Carousel.js +1 -1
  30. package/dist/Display/Display.CircleButton.d.ts +3 -8
  31. package/dist/Display/Display.CircleButton.js +2 -2
  32. package/dist/Display/Display.CopyableText.js +1 -5
  33. package/dist/Display/Display.Date.d.ts +3 -2
  34. package/dist/Display/Display.Date.js +3 -3
  35. package/dist/Display/Display.GradientSurface.d.ts +52 -9
  36. package/dist/Display/Display.GradientSurface.js +9 -14
  37. package/dist/Display/Display.Icon.d.ts +7 -11
  38. package/dist/Display/Display.Icon.js +15 -30
  39. package/dist/Display/Display.Image.d.ts +2 -1
  40. package/dist/Display/Display.Image.js +1 -1
  41. package/dist/Display/Display.KeyValue.js +1 -1
  42. package/dist/Display/Display.ListItem.js +1 -1
  43. package/dist/Display/Display.MenuButton.js +4 -4
  44. package/dist/Display/Display.MenuCard.d.ts +3 -8
  45. package/dist/Display/Display.MenuCard.js +2 -2
  46. package/dist/Display/Display.MenuGrid.d.ts +2 -7
  47. package/dist/Display/Display.MenuGrid.js +1 -1
  48. package/dist/Display/Display.Monetary.d.ts +2 -6
  49. package/dist/Display/Display.Monetary.js +2 -2
  50. package/dist/Display/Display.PriceTag.js +1 -1
  51. package/dist/Display/Display.Rating.js +1 -1
  52. package/dist/Display/Display.SearchHistory.d.ts +2 -1
  53. package/dist/Display/Display.SearchHistory.js +1 -1
  54. package/dist/Display/Display.StatCard.d.ts +2 -1
  55. package/dist/Display/Display.StatCard.js +1 -1
  56. package/dist/Display/Display.StoryViewer.js +10 -6
  57. package/dist/Display/Display.SwipeableRow.d.ts +2 -1
  58. package/dist/Display/Display.Timeline.js +1 -1
  59. package/dist/Display/icon-map.d.ts +344 -0
  60. package/dist/Display/icon-map.js +86 -0
  61. package/dist/Display/index.d.ts +2 -0
  62. package/dist/Display/index.js +1 -0
  63. package/dist/Feedback/Feedback.Banner.js +13 -12
  64. package/dist/Feedback/Feedback.Empty.js +1 -1
  65. package/dist/Feedback/Feedback.EmptyState.d.ts +2 -1
  66. package/dist/Feedback/Feedback.EmptyState.js +1 -1
  67. package/dist/Feedback/Feedback.Error.js +1 -1
  68. package/dist/Feedback/Feedback.PermissionCard.d.ts +2 -1
  69. package/dist/Feedback/Feedback.PermissionCard.js +2 -2
  70. package/dist/Feedback/Toast.context.js +3 -3
  71. package/dist/Form/Form.ControlledDropdown.d.ts +5 -11
  72. package/dist/Form/Form.ControlledDropdown.js +5 -2
  73. package/dist/Form/Form.DatePicker.d.ts +5 -9
  74. package/dist/Form/Form.DatePicker.js +116 -21
  75. package/dist/Form/Form.Dropdown.d.ts +11 -16
  76. package/dist/Form/Form.Dropdown.js +54 -90
  77. package/dist/Form/Form.FractionalQuantityInput.js +4 -11
  78. package/dist/Form/Form.Input.d.ts +3 -3
  79. package/dist/Form/Form.KeyboardForm.d.ts +2 -2
  80. package/dist/Form/Form.KeyboardForm.js +2 -2
  81. package/dist/Form/Form.KeyboardToolbar.d.ts +2 -1
  82. package/dist/Form/Form.KeyboardToolbar.js +3 -7
  83. package/dist/Form/Form.PasswordInput.js +1 -1
  84. package/dist/Form/Form.QuantitySelector.js +1 -1
  85. package/dist/Form/Form.Select.d.ts +12 -8
  86. package/dist/Form/Form.Select.js +64 -31
  87. package/dist/Form/Form.Slider.d.ts +4 -7
  88. package/dist/Form/Form.Slider.js +11 -10
  89. package/dist/Form/Form.Switch.js +2 -1
  90. package/dist/Form/index.d.ts +6 -14
  91. package/dist/Form/index.js +0 -11
  92. package/dist/Navigation/Navigation.AppBar.d.ts +2 -1
  93. package/dist/Navigation/Navigation.AppBar.js +2 -2
  94. package/dist/Navigation/Navigation.BottomNav.d.ts +4 -8
  95. package/dist/Navigation/Navigation.BottomNav.js +2 -2
  96. package/dist/Navigation/Navigation.CollapsingHeader.js +3 -2
  97. package/dist/Navigation/Navigation.Menu.d.ts +16 -11
  98. package/dist/Navigation/Navigation.Menu.js +97 -42
  99. package/dist/Navigation/Navigation.Search.js +2 -2
  100. package/dist/Navigation/Navigation.SearchBar.js +3 -4
  101. package/dist/Navigation/Navigation.SegmentedControl.d.ts +7 -25
  102. package/dist/Navigation/Navigation.SegmentedControl.js +18 -39
  103. package/dist/Navigation/Navigation.Steps.js +1 -1
  104. package/dist/Navigation/Navigation.Tabs.d.ts +2 -1
  105. package/dist/Navigation/index.d.ts +0 -6
  106. package/dist/Navigation/index.js +0 -8
  107. package/dist/Typography/Typography.SelectableText.js +3 -7
  108. package/dist/Typography/Typography.Text.d.ts +1 -6
  109. package/dist/Typography/Typography.Text.js +3 -6
  110. package/dist/index.d.ts +1 -4
  111. package/dist/index.js +1 -4
  112. package/dist/layouts/AuthContainer.d.ts +4 -2
  113. package/dist/layouts/AuthContainer.js +3 -4
  114. package/dist/layouts/Container.d.ts +0 -4
  115. package/dist/layouts/Container.js +3 -4
  116. package/dist/layouts/ScrollContainer.d.ts +7 -3
  117. package/dist/layouts/ScrollContainer.js +5 -4
  118. package/dist/primitives/BaseButton.d.ts +2 -1
  119. package/dist/theme/build.js +0 -4
  120. package/dist/theme/css-vars.js +0 -4
  121. package/dist/theme/dark.js +2 -6
  122. package/dist/theme/default.js +1 -5
  123. package/dist/theme/index.d.ts +1 -1
  124. package/dist/theme/index.js +1 -1
  125. package/dist/theme/types.d.ts +0 -11
  126. package/dist/theme/typography.d.ts +8 -7
  127. package/dist/theme/typography.js +25 -4
  128. package/dist/utils/timezone.d.ts +0 -5
  129. package/dist/views/AuthFormView.d.ts +3 -1
  130. package/dist/views/AuthFormView.js +2 -2
  131. package/dist/views/FormViewV2.d.ts +6 -13
  132. package/dist/views/FormViewV2.js +29 -25
  133. package/dist/views/ListViewV2.context.d.ts +5 -5
  134. package/dist/views/ListViewV2.d.ts +23 -18
  135. package/dist/views/ListViewV2.js +45 -48
  136. package/dist/views/types/IListView.d.ts +5 -4
  137. package/dist/views/types/IListView.js +18 -15
  138. package/dist/widgets/CollectionOptions.d.ts +2 -2
  139. package/dist/widgets/CollectionOptions.js +92 -65
  140. package/dist/widgets/FilterBar.js +1 -1
  141. package/dist/widgets/PromoModal.js +10 -4
  142. package/dist/widgets/QuickActions.d.ts +2 -7
  143. package/dist/widgets/QuickActions.js +1 -1
  144. package/dist/widgets/ReorderableList.js +3 -3
  145. package/dist/widgets/TimeZoneSelectorModal.d.ts +1 -6
  146. package/dist/widgets/TimeZoneSelectorModal.js +17 -12
  147. package/dist/widgets/index.d.ts +0 -11
  148. package/dist/widgets/index.js +0 -7
  149. package/package.json +35 -38
  150. package/tailwind.preset.js +0 -4
  151. package/dist/Dialog/BottomSheet/BottomSheet.Root.d.ts +0 -324
  152. package/dist/Dialog/BottomSheet/BottomSheet.Root.js +0 -373
  153. package/dist/Dialog/BottomSheet/index.d.ts +0 -1
  154. package/dist/Dialog/BottomSheet/index.js +0 -1
  155. package/dist/Dialog/Dialog.NativeSheet.d.ts +0 -10
  156. package/dist/Dialog/Dialog.NativeSheet.js +0 -21
  157. package/dist/Form/Form.Button.d.ts +0 -3
  158. package/dist/Form/Form.Button.js +0 -1
  159. package/dist/Form/Form.FAB.d.ts +0 -3
  160. package/dist/Form/Form.FAB.js +0 -1
  161. package/dist/Form/Form.FilterButton.d.ts +0 -3
  162. package/dist/Form/Form.FilterButton.js +0 -1
  163. package/dist/Form/Form.IconButton.d.ts +0 -3
  164. package/dist/Form/Form.IconButton.js +0 -1
  165. package/dist/Form/Form.SearchBar.d.ts +0 -13
  166. package/dist/Form/Form.SearchBar.js +0 -26
  167. package/dist/Navigation/Navigation.Header.d.ts +0 -16
  168. package/dist/Navigation/Navigation.Header.js +0 -17
  169. package/dist/Navigation/Navigation.HeaderToolbar.d.ts +0 -15
  170. package/dist/Navigation/Navigation.HeaderToolbar.js +0 -18
  171. package/dist/Navigation/Navigation.TabIcon.d.ts +0 -18
  172. package/dist/Navigation/Navigation.TabIcon.js +0 -12
  173. package/dist/Navigation/Navigation.TabItem.d.ts +0 -19
  174. package/dist/Navigation/Navigation.TabItem.js +0 -13
  175. package/dist/icons/OdooIcon.d.ts +0 -11
  176. package/dist/icons/OdooIcon.js +0 -11
  177. package/dist/icons/PrinterIcon.d.ts +0 -9
  178. package/dist/icons/PrinterIcon.js +0 -9
  179. package/dist/layouts/TabNavigatorLayout.d.ts +0 -26
  180. package/dist/layouts/TabNavigatorLayout.js +0 -60
  181. package/dist/utils/icon.d.ts +0 -1
  182. package/dist/utils/icon.js +0 -1
  183. package/dist/widgets/CircleButton.d.ts +0 -3
  184. package/dist/widgets/CircleButton.js +0 -1
  185. package/dist/widgets/GeoPermissionCard.d.ts +0 -13
  186. package/dist/widgets/GeoPermissionCard.js +0 -24
  187. package/dist/widgets/HomeHeader.d.ts +0 -15
  188. package/dist/widgets/HomeHeader.js +0 -13
  189. package/dist/widgets/MenuCard.d.ts +0 -3
  190. package/dist/widgets/MenuCard.js +0 -1
  191. package/dist/widgets/MenuGrid.d.ts +0 -5
  192. package/dist/widgets/MenuGrid.js +0 -1
  193. package/dist/widgets/MenuSection.d.ts +0 -3
  194. package/dist/widgets/MenuSection.js +0 -1
  195. package/dist/widgets/ScreenHeader.d.ts +0 -25
  196. package/dist/widgets/ScreenHeader.js +0 -32
  197. package/dist/widgets/TimeZoneSelector.d.ts +0 -12
  198. package/dist/widgets/TimeZoneSelector.js +0 -24
@@ -1,15 +1,39 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import { BaseButton } from "../primitives/BaseButton.js";
3
- import { theme } from "../theme/index.js";
4
- import Typography from "../Typography/Typography.Text.js";
5
- import { useReducedMotion } from "../utils/useReducedMotion.js";
6
- import { Modal, TouchableWithoutFeedback, View } from "react-native";
7
- const ConfirmationDialog = ({ visible, onCancel, onConfirm, auxTitle = "Descartar cambios", subtitle = "¿Quieres descartar los cambios realizados?", confirmButtonText = "Descartar cambios", cancelButtonText = "Seguir editando", }) => {
8
- const reducedMotion = useReducedMotion();
9
- return (_jsx(Modal, { animationType: reducedMotion ? "none" : "fade", onRequestClose: onCancel, presentationStyle: "overFullScreen", transparent: true, visible: visible, children: _jsxs(View, { className: "flex-1 justify-center items-center p-6 bg-black/50", children: [_jsx(TouchableWithoutFeedback, { accessible: false, onPress: onCancel, children: _jsx(View, { className: "absolute inset-0" }) }), _jsxs(View, { accessibilityViewIsModal: true, className: "p-3 w-full max-w-xs mx-auto", onAccessibilityEscape: onCancel, style: {
10
- borderRadius: 16,
11
- backgroundColor: theme.bg.popover,
12
- ...theme.shadow.md,
13
- }, children: [_jsx(Typography, { accessibilityRole: "header", className: "mb-1.5 text-sm", variant: "body", children: _jsx(Typography, { semibold: true, variant: "body", children: auxTitle }) }), _jsx(Typography, { className: "mb-3 text-xs leading-tight", variant: "body", children: subtitle }), _jsxs(View, { className: "flex-row gap-2", children: [_jsx(BaseButton, { className: "flex-1", onPress: onCancel, size: "small", title: cancelButtonText, variant: "outlineBlack" }), _jsx(BaseButton, { className: "flex-1", onPress: onConfirm, size: "small", title: confirmButtonText, variant: "primary" })] })] })] }) }));
14
- };
15
- export default ConfirmationDialog;
2
+ import { Actions } from "../Actions/index.js";
3
+ import Sheet from "./Dialog.Sheet.js";
4
+ import { Typography } from "../Typography/index.js";
5
+ import { useRef, useState } from "react";
6
+ import { View } from "react-native";
7
+ function Confirmation({ visible, onClose, onConfirm, title = "Descartar cambios", message = "¿Quieres descartar los cambios realizados?", confirmText = "Descartar cambios", cancelText = "Seguir editando", destructive = true, children, testID, }) {
8
+ const saving = useRef(false);
9
+ const [pending, setPending] = useState(false);
10
+ const [error, setError] = useState();
11
+ const close = () => {
12
+ if (saving.current)
13
+ return;
14
+ setError(undefined);
15
+ onClose();
16
+ };
17
+ const confirm = async () => {
18
+ if (saving.current)
19
+ return;
20
+ saving.current = true;
21
+ setPending(true);
22
+ setError(undefined);
23
+ try {
24
+ await onConfirm();
25
+ onClose();
26
+ }
27
+ catch (cause) {
28
+ setError(cause instanceof Error && cause.message.trim()
29
+ ? cause.message
30
+ : "No se pudo completar la operación. Vuelve a intentarlo.");
31
+ }
32
+ finally {
33
+ saving.current = false;
34
+ setPending(false);
35
+ }
36
+ };
37
+ return (_jsxs(Sheet, { dismissible: !pending, footer: _jsxs(View, { className: "gap-2", children: [_jsx(Actions.Button, { disabled: pending, onPress: close, title: cancelText, variant: "outline" }), _jsx(Actions.Button, { disabled: pending, loading: pending, onPress: () => void confirm(), title: confirmText, variant: destructive ? "outlineDanger" : "primary" })] }), onClose: close, testID: testID, title: title, visible: visible, children: [_jsx(Typography.Text, { className: "text-text-secondary", selectable: true, children: message }), children, error ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", accessibilityRole: "alert", className: "pt-3 text-danger", selectable: true, children: error })) : null] }));
38
+ }
39
+ export default Confirmation;
@@ -1,25 +1,30 @@
1
- import React from "react";
2
- export interface EditableValueModalChip {
3
- key?: string;
1
+ import { type ReactNode } from "react";
2
+ import { type TextInputProps } from "react-native";
3
+ export type EditValueOption = {
4
+ key: string;
4
5
  label: string;
5
- onPress: () => void;
6
- }
7
- export interface EditableValueModalProps {
6
+ value: string;
7
+ disabled?: boolean;
8
+ };
9
+ export type EditValueProps = {
8
10
  visible: boolean;
9
11
  title: string;
10
12
  value: string;
11
- onChangeValue: (text: string) => void;
12
- onConfirm: () => void;
13
- onCancel: () => void;
13
+ onChange?: (value: string) => void;
14
+ onConfirm: (value: string) => void | Promise<void>;
15
+ onClose: () => void;
14
16
  placeholder?: string;
15
- helperText?: string | React.ReactNode;
16
- chips?: EditableValueModalChip[];
17
- keyboardType?: "default" | "numeric" | "decimal-pad";
18
- rightAdornment?: React.ReactNode;
17
+ helperText?: ReactNode;
18
+ options?: readonly EditValueOption[];
19
+ keyboardType?: TextInputProps["keyboardType"];
20
+ rightAdornment?: ReactNode;
21
+ footerAdornment?: ReactNode;
19
22
  confirmLabel?: string;
20
23
  cancelLabel?: string;
21
24
  autoFocus?: boolean;
25
+ disabled?: boolean;
26
+ readOnly?: boolean;
22
27
  testID?: string;
23
- }
24
- declare function EditableValueModal({ visible, title, value, onChangeValue, onConfirm, onCancel, placeholder, helperText, chips, keyboardType, rightAdornment, confirmLabel, cancelLabel, autoFocus, testID, }: EditableValueModalProps): React.JSX.Element;
25
- export default EditableValueModal;
28
+ };
29
+ declare function EditValue(props: EditValueProps): import("react").JSX.Element;
30
+ export default EditValue;
@@ -1,18 +1,77 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import { theme } from "../theme/index.js";
2
+ import { FlashList } from "@shopify/flash-list";
3
+ import { Actions } from "../Actions/index.js";
4
+ import Sheet from "./Dialog.Sheet.js";
5
+ import Pressable from "../primitives/Pressable.js";
6
+ import { fontFamilies, useTheme } from "../theme/index.js";
3
7
  import { Typography } from "../Typography/index.js";
4
- import { useReducedMotion } from "../utils/useReducedMotion.js";
5
- import { useEffect, useRef } from "react";
6
- import { FlatList, Modal, TextInput, TouchableOpacity, View, } from "react-native";
7
- function EditableValueModal({ visible, title, value, onChangeValue, onConfirm, onCancel, placeholder, helperText, chips, keyboardType = "decimal-pad", rightAdornment, confirmLabel = "Aplicar", cancelLabel = "Cancelar", autoFocus = true, testID, }) {
8
- const inputRef = useRef(null);
9
- const reducedMotion = useReducedMotion();
10
- useEffect(() => {
11
- if (visible && autoFocus) {
12
- const t = setTimeout(() => inputRef.current?.focus(), 60);
13
- return () => clearTimeout(t);
8
+ import { useRef, useState } from "react";
9
+ import { Keyboard, TextInput, View } from "react-native";
10
+ function EditValueEditor({ title, value, onChange, onConfirm, onClose, placeholder, helperText, options = [], keyboardType = "decimal-pad", rightAdornment, footerAdornment, confirmLabel = "Aplicar", cancelLabel = "Cancelar", autoFocus = true, disabled = false, readOnly = false, onPendingChange, }) {
11
+ const theme = useTheme();
12
+ const saving = useRef(false);
13
+ const [localDraft, setLocalDraft] = useState(value);
14
+ const [pending, setPending] = useState(false);
15
+ const [error, setError] = useState();
16
+ const draft = onChange ? value : localDraft;
17
+ const blocked = disabled || readOnly || pending;
18
+ const updateDraft = (next) => {
19
+ if (blocked || saving.current)
20
+ return;
21
+ if (onChange)
22
+ onChange(next);
23
+ else
24
+ setLocalDraft(next);
25
+ setError(undefined);
26
+ };
27
+ const close = () => {
28
+ if (saving.current)
29
+ return;
30
+ Keyboard.dismiss();
31
+ onClose();
32
+ };
33
+ const save = async () => {
34
+ if (disabled || readOnly || saving.current)
35
+ return;
36
+ saving.current = true;
37
+ setPending(true);
38
+ onPendingChange(true);
39
+ setError(undefined);
40
+ try {
41
+ await onConfirm(draft);
42
+ Keyboard.dismiss();
43
+ onClose();
14
44
  }
15
- }, [visible, autoFocus]);
16
- return (_jsx(Modal, { animationType: reducedMotion ? "none" : "fade", onRequestClose: onCancel, presentationStyle: "overFullScreen", transparent: true, visible: visible, children: _jsx(View, { className: "flex-1 justify-center p-6 bg-black/40", children: _jsxs(View, { accessibilityViewIsModal: true, className: "p-4", onAccessibilityEscape: onCancel, style: { borderRadius: 16, backgroundColor: theme.bg.popover, ...theme.shadow.md }, testID: testID, children: [_jsx(Typography.Text, { className: "mb-3", semibold: true, variant: "h6", children: title }), _jsxs(View, { className: "flex-row items-center", children: [_jsx(TextInput, { accessibilityLabel: title, className: "flex-1 border border-input rounded-lg p-2.5 text-lg text-text-primary", keyboardType: keyboardType, onChangeText: onChangeValue, onSubmitEditing: onConfirm, placeholder: placeholder, placeholderTextColor: theme.text.tertiary, ref: inputRef, returnKeyType: "done", selectionColor: theme.primary, underlineColorAndroid: "transparent", value: value }), rightAdornment && _jsx(View, { className: "ml-2", children: rightAdornment })] }), helperText ? (_jsx(View, { className: "mt-2", children: typeof helperText === "string" ? (_jsx(Typography.Text, { className: "opacity-70", variant: "bodySmall", children: helperText })) : (helperText) })) : null, chips && chips.length > 0 && (_jsx(FlatList, { contentContainerClassName: "gap-2 py-3", data: chips, horizontal: true, keyExtractor: (c, i) => c.key || `${c.label}-${i}`, renderItem: ({ item }) => (_jsx(TouchableOpacity, { className: "px-3 py-1.5 bg-accent/10 rounded-2xl border border-accent/30", onPress: item.onPress, children: _jsx(Typography.Text, { semibold: true, variant: "bodySmall", children: item.label }) })) })), _jsxs(View, { className: "flex-row justify-end gap-3", children: [_jsx(TouchableOpacity, { className: "px-4 py-2.5 rounded-lg bg-bg-hover", onPress: onCancel, children: _jsx(Typography.Text, { semibold: true, variant: "body", children: cancelLabel }) }), _jsx(TouchableOpacity, { className: "px-4 py-2.5 rounded-lg bg-accent", onPress: onConfirm, children: _jsx(Typography.Text, { className: "text-text-inverse", semibold: true, variant: "body", children: confirmLabel }) })] })] }) }) }));
45
+ catch (cause) {
46
+ setError(cause instanceof Error && cause.message.trim()
47
+ ? cause.message
48
+ : "No se pudo guardar. Conservamos el valor para reintentar.");
49
+ }
50
+ finally {
51
+ saving.current = false;
52
+ setPending(false);
53
+ onPendingChange(false);
54
+ }
55
+ };
56
+ return (_jsxs(View, { style: { flex: 1, minHeight: 0 }, children: [_jsxs(View, { className: "flex-row items-center gap-2", children: [_jsx(TextInput, { accessibilityLabel: title, accessibilityState: { disabled: blocked }, autoFocus: autoFocus && !blocked, className: "flex-1 border border-input rounded-lg p-3 text-text-primary", editable: !blocked, keyboardType: keyboardType, onChangeText: updateDraft, onSubmitEditing: () => void save(), placeholder: placeholder, placeholderTextColor: theme.text.tertiary, readOnly: readOnly, returnKeyType: "done", selectionColor: theme.primary, style: { minHeight: 48, fontFamily: fontFamilies.regular, fontSize: 18 }, underlineColorAndroid: "transparent", value: draft }), rightAdornment] }), helperText ? (typeof helperText === "string" ? (_jsx(Typography.Text, { className: "pt-2 text-text-secondary", children: helperText })) : (helperText)) : null, _jsx(View, { style: { flex: 1, minHeight: 0 }, children: _jsx(FlashList, { contentContainerStyle: { paddingVertical: 12 }, data: options, keyboardShouldPersistTaps: "handled", keyExtractor: (option) => option.key, renderItem: ({ item }) => (_jsx(Pressable, { accessibilityLabel: item.label, accessibilityRole: "radio", accessibilityState: {
57
+ disabled: blocked || !!item.disabled,
58
+ selected: item.value === draft,
59
+ }, className: "border-b border-border-light py-3", disabled: blocked || item.disabled, onPress: () => {
60
+ if (!item.disabled)
61
+ updateDraft(item.value);
62
+ }, style: { minWidth: 48, minHeight: 48 }, children: _jsx(Typography.Text, { className: item.disabled ? "text-text-disabled" : "text-text-primary", semibold: item.value === draft, children: item.label }) })) }) }), error ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", accessibilityRole: "alert", className: "pb-3 text-danger", selectable: true, children: error })) : null, _jsxs(View, { className: "gap-2 border-t border-border-light py-3", children: [footerAdornment ? (_jsx(View, { accessibilityElementsHidden: blocked, importantForAccessibility: blocked ? "no-hide-descendants" : "auto", pointerEvents: blocked ? "none" : "auto", children: footerAdornment })) : null, _jsx(Actions.Button, { disabled: pending, onPress: close, title: cancelLabel, variant: "secondary" }), _jsx(Actions.Button, { disabled: blocked, loading: pending, onPress: () => void save(), title: confirmLabel })] })] }));
63
+ }
64
+ function EditValue(props) {
65
+ const busy = useRef(false);
66
+ const [pending, setPending] = useState(false);
67
+ return (_jsx(Sheet, { dismissible: !pending, onClose: () => {
68
+ if (!busy.current) {
69
+ Keyboard.dismiss();
70
+ props.onClose();
71
+ }
72
+ }, scrollable: false, testID: props.testID, title: props.title, visible: props.visible, children: props.visible ? (_jsx(EditValueEditor, { ...props, onPendingChange: (next) => {
73
+ busy.current = next;
74
+ setPending(next);
75
+ } })) : null }));
17
76
  }
18
- export default EditableValueModal;
77
+ export default EditValue;
@@ -1,30 +1,14 @@
1
- import { type ReactNode } from "react";
2
- /**
3
- * @deprecated A provider is no longer required. `SheetProvider` is a no-op passthrough
4
- * kept to avoid breaking prior wiring. Remove it when you can.
5
- */
6
- export declare function SheetProvider({ children }: {
7
- children: ReactNode;
8
- }): import("react").JSX.Element;
9
- export interface SheetProps {
1
+ import type { ReactNode } from "react";
2
+ export type SheetProps = {
10
3
  visible: boolean;
11
4
  onClose: () => void;
5
+ title?: string;
12
6
  children: ReactNode;
13
7
  footer?: ReactNode;
14
- footerClassName?: string;
15
- title?: string;
16
- /** Max sheet height (fraction of the screen). Default 0.9. */
17
- maxHeightRatio?: number;
18
- /** Allow closing by tapping the dim backdrop. Default `false` (handle/button only). */
19
- dismissOnBackdrop?: boolean;
20
- /** Show a visible close button in the sheet header. */
21
- showCloseButton?: boolean;
8
+ snapPoints?: (string | number)[];
9
+ scrollable?: boolean;
10
+ dismissible?: boolean;
22
11
  testID?: string;
23
- }
24
- /**
25
- * Bottom sheet on RN's native `Modal`: bottom-anchored, dim backdrop, handle with
26
- * **swipe-down to close** (handle only). By default it does NOT close on backdrop tap
27
- * (`dismissOnBackdrop`). No provider or native deps. Import via subpath `Dialog/Sheet`.
28
- */
29
- declare function Sheet({ visible, onClose, children, footer, footerClassName, title, maxHeightRatio, dismissOnBackdrop, showCloseButton, testID, }: SheetProps): import("react").JSX.Element;
12
+ };
13
+ declare function Sheet({ visible, onClose, title, children, footer, snapPoints, scrollable, dismissible, testID, }: SheetProps): import("react").JSX.Element;
30
14
  export default Sheet;
@@ -1,67 +1,22 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- /* eslint-disable react-hooks/refs */
3
- // This file uses the canonical RN patterns: useRef(new Animated.Value()).current and PanResponder
4
- // created inside useState. Those hooks rules warn — they're not bugs here. Documented at the
5
- // eslint config level (see eslint.config.js:30-33).
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import BottomSheet, { BottomSheetView } from "@expo/ui/community/bottom-sheet";
6
3
  import Pressable from "../primitives/Pressable.js";
7
4
  import { themeToVars, useTheme } from "../theme/index.js";
8
5
  import { Typography } from "../Typography/index.js";
9
- import { useSheetTranslation } from "../utils/useSheetTranslation.js";
10
6
  import { vars } from "nativewind";
11
- import { useRef, useState } from "react";
12
- import { Animated, Modal, PanResponder, ScrollView, View } from "react-native";
13
- import { useSafeAreaInsets } from "react-native-safe-area-context";
14
- /**
15
- * @deprecated A provider is no longer required. `SheetProvider` is a no-op passthrough
16
- * kept to avoid breaking prior wiring. Remove it when you can.
17
- */
18
- export function SheetProvider({ children }) {
19
- return _jsx(_Fragment, { children: children });
20
- }
21
- /**
22
- * Bottom sheet on RN's native `Modal`: bottom-anchored, dim backdrop, handle with
23
- * **swipe-down to close** (handle only). By default it does NOT close on backdrop tap
24
- * (`dismissOnBackdrop`). No provider or native deps. Import via subpath `Dialog/Sheet`.
25
- */
26
- function Sheet({ visible, onClose, children, footer, footerClassName, title, maxHeightRatio = 0.9, dismissOnBackdrop = false, showCloseButton = false, testID, }) {
7
+ import { ScrollView, View } from "react-native";
8
+ const SNAP_POINTS = ["60%", "90%"];
9
+ function Sheet({ visible, onClose, title, children, footer, snapPoints = SNAP_POINTS, scrollable = true, dismissible = true, testID, }) {
27
10
  const theme = useTheme();
28
- const insets = useSafeAreaInsets();
29
- const { translateY, reducedMotion } = useSheetTranslation(visible);
30
- const gesture = useRef({ onClose, reducedMotion });
31
- gesture.current = { onClose, reducedMotion };
32
- const [pan] = useState(() => PanResponder.create({
33
- onStartShouldSetPanResponder: () => true,
34
- onMoveShouldSetPanResponder: (_, g) => g.dy > 2,
35
- onPanResponderGrant: () => translateY.stopAnimation(),
36
- onPanResponderMove: (_, g) => {
37
- if (g.dy > 0)
38
- translateY.setValue(g.dy);
39
- },
40
- onPanResponderRelease: (_, g) => {
41
- if (g.dy > 100 || g.vy > 0.5) {
42
- translateY.stopAnimation();
43
- gesture.current.onClose();
44
- }
45
- else {
46
- if (gesture.current.reducedMotion)
47
- translateY.setValue(0);
48
- else
49
- Animated.spring(translateY, { toValue: 0, useNativeDriver: true }).start();
50
- }
51
- },
52
- }));
53
- return (_jsx(Modal, { animationType: "none", onRequestClose: onClose, presentationStyle: "overFullScreen", transparent: true, visible: visible, children: _jsxs(View, { className: "flex-1 justify-end", testID: testID, children: [_jsx(View, { className: "absolute inset-0 bg-black/50", onResponderRelease: dismissOnBackdrop ? onClose : undefined, onStartShouldSetResponder: () => dismissOnBackdrop }), _jsxs(Animated.View, { accessibilityViewIsModal: true, className: "rounded-t-3xl", importantForAccessibility: "yes", onAccessibilityEscape: onClose, style: [
54
- vars(themeToVars(theme)),
55
- {
56
- backgroundColor: theme.bg.card,
57
- paddingBottom: insets.bottom + 12,
58
- maxHeight: `${Math.round(maxHeightRatio * 100)}%`,
59
- transform: [{ translateY }],
60
- },
61
- ], children: [_jsx(View, { accessibilityElementsHidden: true, className: "items-center pt-3 pb-2", ...pan.panHandlers, children: _jsx(View, { className: "w-12 h-1.5 rounded-full bg-border-strong" }) }), title || showCloseButton ? (_jsxs(View, { className: "flex-row items-center px-4 pb-1", children: [title ? (_jsx(Typography.Text, { accessibilityRole: "header", className: "flex-1 text-text-primary", semibold: true, variant: "subtitle", children: title })) : null, showCloseButton ? (_jsx(Pressable, { accessibilityLabel: "Cerrar", accessibilityRole: "button", className: "items-center justify-center rounded-lg", hitSlop: 8, onPress: onClose, style: { minWidth: 48, minHeight: 48 }, children: _jsx(Typography.Text, { className: "text-text-accent", variant: "bodySmall", children: "Cerrar" }) })) : null] })) : null, _jsx(ScrollView, { contentContainerStyle: {
62
- paddingHorizontal: 16,
63
- paddingTop: 4,
64
- paddingBottom: footer ? 12 : 0,
65
- }, style: { flexShrink: 1 }, children: children }), footer ? (_jsx(View, { className: `border-t border-border-light px-4 pt-3 ${footerClassName ?? ""}`, children: footer })) : null] })] }) }));
11
+ const close = () => {
12
+ if (visible && dismissible)
13
+ onClose();
14
+ };
15
+ return (_jsx(BottomSheet, { backgroundStyle: { backgroundColor: theme.bg.card }, enablePanDownToClose: dismissible, index: visible ? 0 : -1, onClose: close, snapPoints: snapPoints, children: _jsx(BottomSheetView, { style: { flex: 1 }, children: _jsxs(View, { accessibilityViewIsModal: true, importantForAccessibility: "yes", onAccessibilityEscape: close, style: [vars(themeToVars(theme)), { flex: 1, minHeight: 0 }], testID: testID, children: [_jsxs(View, { className: "flex-row items-center gap-3 px-4 pb-2", children: [title ? (_jsx(Typography.Text, { accessibilityRole: "header", className: "flex-1 text-text-primary", semibold: true, variant: "subtitle", children: title })) : (_jsx(View, { className: "flex-1" })), _jsx(Pressable, { accessibilityLabel: "Cerrar", accessibilityRole: "button", accessibilityState: { disabled: !dismissible }, disabled: !dismissible, onPress: close, style: {
16
+ minHeight: 48,
17
+ minWidth: 48,
18
+ alignItems: "center",
19
+ justifyContent: "center",
20
+ }, children: _jsx(Typography.Text, { className: dismissible ? "text-text-accent" : "text-text-disabled", variant: "bodySmall", children: "Cerrar" }) })] }), scrollable ? (_jsx(ScrollView, { contentContainerStyle: { paddingHorizontal: 16, paddingBottom: 16 }, keyboardDismissMode: "on-drag", keyboardShouldPersistTaps: "handled", style: { flex: 1, minHeight: 0 }, children: children })) : (_jsx(View, { style: { flex: 1, minHeight: 0, paddingHorizontal: 16 }, children: children })), footer ? (_jsx(View, { className: "border-t border-border-light px-4 py-3", children: footer })) : null] }) }) }));
66
21
  }
67
22
  export default Sheet;
@@ -1,21 +1,21 @@
1
- import { BottomSheet } from "./BottomSheet/index.js";
2
1
  import { ConfirmationProvider, useConfirmationContext } from "./Confirmation.context.js";
3
2
  import ActionSheet from "./Dialog.ActionSheet.js";
4
- import EditValue, { type EditableValueModalChip, type EditableValueModalProps } from "./Dialog.EditValue.js";
3
+ import Confirmation from "./Dialog.Confirmation.js";
4
+ import EditValue from "./Dialog.EditValue.js";
5
+ import Sheet from "./Dialog.Sheet.js";
6
+ import { requestConfirmation } from "./requestConfirmation.js";
5
7
  export declare const Dialog: {
6
- Confirmation: import("react").FC<import("./Dialog.Confirmation.js").Props>;
7
- BottomSheet: {
8
- Root: ({ visible, onClose, size, dismissible, children }: import("./BottomSheet/BottomSheet.Root").RootProps) => import("react").JSX.Element;
9
- Handle: ({ children }: import("./BottomSheet/BottomSheet.Root").HandleProps) => import("react").JSX.Element;
10
- Header: ({ children }: import("./BottomSheet/BottomSheet.Root").HeaderProps) => import("react").JSX.Element;
11
- Title: ({ children, subtitle }: import("./BottomSheet/BottomSheet.Root").TitleProps) => import("react").JSX.Element;
12
- Content: ({ children, scrollable }: import("./BottomSheet/BottomSheet.Root").ContentProps) => import("react").JSX.Element;
13
- Actions: ({ children, layout }: import("./BottomSheet/BottomSheet.Root").ActionsProps) => import("react").JSX.Element;
14
- Footer: ({ children }: import("./BottomSheet/BottomSheet.Root").FooterProps) => import("react").JSX.Element;
15
- useBottomSheet: () => import("./BottomSheet/BottomSheet.Root").BottomSheetContextValue;
16
- };
8
+ Confirmation: typeof Confirmation;
9
+ Sheet: typeof Sheet;
17
10
  EditValue: typeof EditValue;
18
11
  ActionSheet: typeof ActionSheet;
12
+ requestConfirmation: typeof requestConfirmation;
19
13
  };
20
- export { BottomSheet, ConfirmationProvider, type EditableValueModalChip, type EditableValueModalProps, useConfirmationContext, };
14
+ export { ConfirmationProvider, requestConfirmation, Sheet, useConfirmationContext };
15
+ export type { ConfirmationOptions } from "./Confirmation.context.js";
16
+ export type { ActionSheetAction, ActionSheetProps, } from "./Dialog.ActionSheet.js";
17
+ export type { ConfirmationProps } from "./Dialog.Confirmation.js";
18
+ export type { EditValueOption, EditValueProps, } from "./Dialog.EditValue.js";
19
+ export type { SheetProps } from "./Dialog.Sheet.js";
20
+ export type { NativeConfirmationOptions } from "./requestConfirmation.js";
21
21
  export default Dialog;
@@ -1,13 +1,15 @@
1
- import { BottomSheet } from "./BottomSheet/index.js";
2
1
  import { ConfirmationProvider, useConfirmationContext, } from "./Confirmation.context.js";
3
2
  import ActionSheet from "./Dialog.ActionSheet.js";
4
3
  import Confirmation from "./Dialog.Confirmation.js";
5
4
  import EditValue from "./Dialog.EditValue.js";
5
+ import Sheet from "./Dialog.Sheet.js";
6
+ import { requestConfirmation } from "./requestConfirmation.js";
6
7
  export const Dialog = {
7
8
  Confirmation,
8
- BottomSheet,
9
+ Sheet,
9
10
  EditValue,
10
11
  ActionSheet,
12
+ requestConfirmation,
11
13
  };
12
- export { BottomSheet, ConfirmationProvider, useConfirmationContext, };
14
+ export { ConfirmationProvider, requestConfirmation, Sheet, useConfirmationContext };
13
15
  export default Dialog;
@@ -0,0 +1,3 @@
1
+ import type { ConfirmationProps } from "./Dialog.Confirmation.js";
2
+ export type NativeConfirmationOptions = Pick<ConfirmationProps, "title" | "message" | "confirmText" | "cancelText" | "destructive">;
3
+ export declare function requestConfirmation({ title, message, confirmText, cancelText, destructive, }?: NativeConfirmationOptions): Promise<boolean>;
@@ -0,0 +1,13 @@
1
+ import { Alert } from "react-native";
2
+ export function requestConfirmation({ title = "Confirmación", message = "¿Estás seguro de que quieres continuar?", confirmText = "Confirmar", cancelText = "Cancelar", destructive = false, } = {}) {
3
+ return new Promise((resolve) => {
4
+ Alert.alert(title, message, [
5
+ { text: cancelText, style: "cancel", onPress: () => resolve(false) },
6
+ {
7
+ text: confirmText,
8
+ style: destructive ? "destructive" : "default",
9
+ onPress: () => resolve(true),
10
+ },
11
+ ], { cancelable: true, onDismiss: () => resolve(false) });
12
+ });
13
+ }
@@ -16,7 +16,7 @@ function AccordionItem({ title, children, defaultOpen = false, className, testID
16
16
  LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
17
17
  setOpen((prev) => !prev);
18
18
  };
19
- return (_jsxs(View, { className: cn("border-b border-border-default", className), testID: testID, children: [_jsxs(Pressable, { accessibilityLabel: title, accessibilityRole: "button", accessibilityState: { expanded: open }, className: "flex-row items-center justify-between py-3", onPress: toggle, style: { minHeight: 48 }, children: [_jsx(Typography.Text, { className: "flex-1 text-text-primary", semibold: true, children: title }), _jsx(View, { style: { transform: [{ rotate: open ? "180deg" : "0deg" }] }, children: _jsx(Icon, { color: theme.icon.secondary, name: "chevron-down", size: 18 }) })] }), open ? _jsx(View, { className: "pb-3", children: children }) : null] }));
19
+ return (_jsxs(View, { className: cn("border-b border-border-default", className), testID: testID, children: [_jsxs(Pressable, { accessibilityLabel: title, accessibilityRole: "button", accessibilityState: { expanded: open }, className: "flex-row items-center justify-between py-3", onPress: toggle, style: { minHeight: 48 }, children: [_jsx(Typography.Text, { className: "flex-1 text-text-primary", semibold: true, children: title }), _jsx(View, { style: { transform: [{ rotate: open ? "180deg" : "0deg" }] }, children: _jsx(Icon, { color: theme.icon.secondary, name: "expand", size: 18 }) })] }), open ? _jsx(View, { className: "pb-3", children: children }) : null] }));
20
20
  }
21
21
  function AccordionRoot({ children, className }) {
22
22
  return _jsx(View, { className: cn("bg-bg-card rounded-lg", className), children: children });
@@ -11,8 +11,8 @@ declare const avatar: import("tailwind-variants").TVReturnType<{
11
11
  default: "bg-bg-hover";
12
12
  primary: "bg-primary/20";
13
13
  secondary: "bg-secondary/20";
14
- success: "bg-success-light";
15
- warning: "bg-warning-light";
14
+ success: "bg-container-success";
15
+ warning: "bg-container-warning";
16
16
  };
17
17
  }, undefined, "justify-center items-center rounded-full shadow-sm", {
18
18
  size: {
@@ -25,8 +25,8 @@ declare const avatar: import("tailwind-variants").TVReturnType<{
25
25
  default: "bg-bg-hover";
26
26
  primary: "bg-primary/20";
27
27
  secondary: "bg-secondary/20";
28
- success: "bg-success-light";
29
- warning: "bg-warning-light";
28
+ success: "bg-container-success";
29
+ warning: "bg-container-warning";
30
30
  };
31
31
  }, undefined, import("tailwind-variants").TVReturnTypeLike<{
32
32
  size: {
@@ -39,8 +39,8 @@ declare const avatar: import("tailwind-variants").TVReturnType<{
39
39
  default: "bg-bg-hover";
40
40
  primary: "bg-primary/20";
41
41
  secondary: "bg-secondary/20";
42
- success: "bg-success-light";
43
- warning: "bg-warning-light";
42
+ success: "bg-container-success";
43
+ warning: "bg-container-warning";
44
44
  };
45
45
  }, undefined>>;
46
46
  export interface AvatarProps extends Omit<VariantProps<typeof avatar>, "size"> {
@@ -15,8 +15,8 @@ const avatar = tv({
15
15
  default: "bg-bg-hover",
16
16
  primary: "bg-primary/20",
17
17
  secondary: "bg-secondary/20",
18
- success: "bg-success-light",
19
- warning: "bg-warning-light",
18
+ success: "bg-container-success",
19
+ warning: "bg-container-warning",
20
20
  },
21
21
  },
22
22
  defaultVariants: {
@@ -9,7 +9,7 @@ const badge = tv({
9
9
  variants: {
10
10
  variant: {
11
11
  info: {
12
- root: "bg-info-light",
12
+ root: "bg-container-info",
13
13
  text: "text-info",
14
14
  },
15
15
  infoDark: {
@@ -17,11 +17,11 @@ const badge = tv({
17
17
  text: "text-text-on-primary",
18
18
  },
19
19
  warning: {
20
- root: "bg-warning-light",
20
+ root: "bg-container-warning",
21
21
  text: "text-warning",
22
22
  },
23
23
  success: {
24
- root: "bg-success-light",
24
+ root: "bg-container-success",
25
25
  text: "text-success",
26
26
  },
27
27
  successDark: {
@@ -29,7 +29,7 @@ const badge = tv({
29
29
  text: "text-text-on-primary",
30
30
  },
31
31
  danger: {
32
- root: "bg-danger-light",
32
+ root: "bg-container-danger",
33
33
  text: "text-danger",
34
34
  },
35
35
  },
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "nativewind/jsx-runtime";
2
2
  import Pressable from "../primitives/Pressable.js";
3
- import { theme } from "../theme/index.js";
3
+ import { useTheme } from "../theme/index.js";
4
4
  import { cn, tv } from "../theme/tw.js";
5
5
  import { Typography } from "../Typography/index.js";
6
6
  import { View } from "react-native";
@@ -19,7 +19,10 @@ const card = tv({
19
19
  },
20
20
  });
21
21
  function Card({ padding = "md", elevation = "sm", onPress, className, children, testID, }) {
22
- const shadow = elevation === "none" ? undefined : theme.shadow[elevation];
22
+ const theme = useTheme();
23
+ const shadow = elevation === "none"
24
+ ? { borderCurve: "continuous" }
25
+ : { ...theme.shadow[elevation], borderCurve: "continuous" };
23
26
  if (onPress) {
24
27
  return (_jsx(Pressable, { className: card({ padding, className }), onPress: onPress, style: shadow, testID: testID, children: children }));
25
28
  }
@@ -114,6 +114,6 @@ function Carousel({ data, renderItem, keyExtractor, itemWidth, gap = 12, showDot
114
114
  },
115
115
  dotStyle,
116
116
  index === current ? activeDotStyle : undefined,
117
- ] }, keys[index]))) })) : null, data.length > 1 ? (renderControls ? (renderControls(controls)) : (_jsxs(View, { className: controlsClassName ?? "flex-row items-center justify-center gap-3 mt-2", children: [_jsx(IconButton, { accessibilityLabel: previousAccessibilityLabel, disabled: !controls.canPrevious, icon: "chevron-left", onPress: controls.previous }), _jsx(Typography.Text, { ...paginationTextProps, accessibilityLiveRegion: "polite", children: formatPageLabel(current, data.length) }), _jsx(IconButton, { accessibilityLabel: nextAccessibilityLabel, disabled: !controls.canNext, icon: "chevron-right", onPress: controls.next })] }))) : null] }));
117
+ ] }, keys[index]))) })) : null, data.length > 1 ? (renderControls ? (renderControls(controls)) : (_jsxs(View, { className: controlsClassName ?? "flex-row items-center justify-center gap-3 mt-2", children: [_jsx(IconButton, { accessibilityLabel: previousAccessibilityLabel, disabled: !controls.canPrevious, icon: "back", onPress: controls.previous }), _jsx(Typography.Text, { ...paginationTextProps, accessibilityLiveRegion: "polite", children: formatPageLabel(current, data.length) }), _jsx(IconButton, { accessibilityLabel: nextAccessibilityLabel, disabled: !controls.canNext, icon: "next", onPress: controls.next })] }))) : null] }));
118
118
  }
119
119
  export default Carousel;
@@ -1,15 +1,10 @@
1
- import { IconType } from "../utils/icon.js";
2
- import { ComponentType } from "react";
1
+ import type { IconName } from "./index.js";
3
2
  export interface CircleButtonProps {
4
- iconType?: IconType;
5
3
  size?: "sm" | "md" | "lg";
6
4
  color?: string;
7
5
  variant?: "primary" | "secondary" | "accent" | "success" | "danger" | "warning";
8
6
  className?: string;
9
- customIcon?: ComponentType<{
10
- size?: number;
11
- color?: string;
12
- }>;
7
+ icon: IconName;
13
8
  }
14
- export declare function CircleButton({ iconType, size, color, variant, className, customIcon, }: CircleButtonProps): import("react").JSX.Element;
9
+ export declare function CircleButton({ size, color, variant, className, icon, }: CircleButtonProps): import("react").JSX.Element;
15
10
  export default CircleButton;
@@ -31,9 +31,9 @@ const SIZE_MAP = {
31
31
  md: { icon: 30 },
32
32
  lg: { icon: 40 },
33
33
  };
34
- export function CircleButton({ iconType = "ionicons", size = "md", color, variant = "accent", className, customIcon, }) {
34
+ export function CircleButton({ size = "md", color, variant = "accent", className, icon, }) {
35
35
  const theme = useTheme();
36
36
  const iconColor = color ?? theme.text.inverse;
37
- return (_jsx(View, { className: cn(circleButtonVariants({ size, variant }), className), children: _jsx(Icon, { color: iconColor, customIcon: customIcon, size: SIZE_MAP[size].icon, type: iconType }) }));
37
+ return (_jsx(View, { className: cn(circleButtonVariants({ size, variant }), className), children: _jsx(Icon, { color: iconColor, name: icon, size: SIZE_MAP[size].icon }) }));
38
38
  }
39
39
  export default CircleButton;
@@ -73,10 +73,6 @@ function CopyableText({ value, getValue, label, className, accessibilityLabel, t
73
73
  justifyContent: selectable ? "center" : "flex-start",
74
74
  gap: 8,
75
75
  flexShrink: selectable ? 0 : 1,
76
- }, testID: testID, children: [!selectable ? (_jsx(Typography.Text, { className: className, style: { flexShrink: 1 }, variant: "body", children: displayText })) : null, _jsx(View, { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", style: { width: 24, alignItems: "center" }, children: status === "copying" ? (_jsx(ActivityIndicator, { color: theme.text.accent, size: "small" })) : (_jsx(Icon, { color: isCopied ? theme.success : theme.text.accent, name: isCopied
77
- ? "checkmark"
78
- : status === "error"
79
- ? "alert-circle-outline"
80
- : "copy-outline", size: 20 })) })] })] }), status === "error" ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", className: "text-danger", variant: "bodySmall", children: "No se pudo copiar. Toca para reintentar." })) : null] }));
76
+ }, testID: testID, children: [!selectable ? (_jsx(Typography.Text, { className: className, style: { flexShrink: 1 }, variant: "body", children: displayText })) : null, _jsx(View, { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", style: { width: 24, alignItems: "center" }, children: status === "copying" ? (_jsx(ActivityIndicator, { color: theme.text.accent, size: "small" })) : (_jsx(Icon, { color: isCopied ? theme.success : theme.text.accent, name: isCopied ? "check" : status === "error" ? "error" : "copy", size: 20 })) })] })] }), status === "error" ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", className: "text-danger", variant: "bodySmall", children: "No se pudo copiar. Toca para reintentar." })) : null] }));
81
77
  }
82
78
  export default CopyableText;
@@ -1,3 +1,4 @@
1
+ import type { IconName } from "./index.js";
1
2
  import { typographyVariants } from "../theme/typography.js";
2
3
  import { type StyleProp, type TextStyle } from "react-native";
3
4
  type DateFormat = "short" | "long" | "numeric";
@@ -22,8 +23,8 @@ interface DateFieldProps {
22
23
  timezone?: string;
23
24
  /** App-like layout. Default `inline` (no visual change vs. previous version). */
24
25
  variant?: DateVariant;
25
- /** Override the leading icon (ionicons). Defaults: calendar, or clock if `showTime`. */
26
- icon?: string;
26
+ /** Override the semantic icon. Defaults: calendar, or time if `showTime`. */
27
+ icon?: IconName;
27
28
  /** Show relative time ("hace 2 h") instead of the absolute date. */
28
29
  relative?: boolean;
29
30
  }
@@ -30,10 +30,10 @@ function DateField({ value, format = "short", prefix = "", textVariant = "body",
30
30
  : formatDateWithDefaultTimezone(value, { showTime, locale });
31
31
  const formatted = value && relative ? relativeTime(value) : absolute;
32
32
  const text = prefix ? `${prefix}${formatted}` : formatted;
33
- const iconName = icon ?? (showTime && !relative ? "time-outline" : "calendar-outline");
34
- const label = (_jsx(Typography.Text, { bold: bold, color: color, semibold: semibold && !bold, style: style, variant: textVariant, children: text }));
33
+ const iconName = icon ?? (showTime && !relative ? "time" : "calendar");
34
+ const label = (_jsx(Typography.Text, { bold: bold, semibold: semibold && !bold, style: [{ color }, style], variant: textVariant, children: text }));
35
35
  if (variant === "inline") {
36
- return (_jsx(Typography.Text, { bold: bold, className: className, color: color, semibold: semibold && !bold, style: style, variant: textVariant, children: text }));
36
+ return (_jsx(Typography.Text, { bold: bold, className: className, semibold: semibold && !bold, style: [{ color }, style], variant: textVariant, children: text }));
37
37
  }
38
38
  if (variant === "pill") {
39
39
  return (_jsxs(View, { className: cn("flex-row items-center self-start gap-1.5 rounded-full bg-bg-muted px-2.5 py-1", className), children: [_jsx(Icon, { color: color ?? theme.icon.secondary, name: iconName, size: 14 }), label] }));