@sincpro/mobile-ui 0.3.0 → 0.4.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.
- package/dist/Dialog/BottomSheet/BottomSheet.Root.d.ts +2 -2
- package/dist/Dialog/BottomSheet/BottomSheet.Root.js +2 -2
- package/dist/Dialog/Dialog.Confirmation.js +5 -1
- package/dist/Dialog/Dialog.EditValue.js +1 -1
- package/dist/Display/Display.GradientSurface.d.ts +116 -0
- package/dist/Display/Display.GradientSurface.js +62 -0
- package/dist/Display/Display.KeyValue.js +1 -1
- package/dist/Display/Display.ListItem.d.ts +5 -1
- package/dist/Display/Display.ListItem.js +6 -2
- package/dist/Display/Display.Monetary.js +1 -1
- package/dist/Display/Display.Pattern.d.ts +26 -0
- package/dist/Display/Display.Pattern.js +27 -0
- package/dist/Display/Display.PriceTag.js +3 -3
- package/dist/Display/Display.Stat.js +1 -1
- package/dist/Display/Display.StatCard.js +1 -1
- package/dist/Display/index.d.ts +4 -0
- package/dist/Display/index.js +4 -0
- package/dist/Feedback/Feedback.DomainSplashScreen.js +3 -2
- package/dist/Feedback/Feedback.Loading.d.ts +6 -0
- package/dist/Feedback/Feedback.Loading.js +7 -1
- package/dist/Feedback/Feedback.Spinner.js +2 -1
- package/dist/Feedback/Feedback.Splash.d.ts +7 -1
- package/dist/Feedback/Feedback.Splash.js +11 -2
- package/dist/Feedback/Toast.context.d.ts +8 -1
- package/dist/Feedback/Toast.context.js +25 -23
- package/dist/Form/Form.Button.d.ts +4 -4
- package/dist/Form/Form.Button.js +19 -19
- package/dist/Form/Form.Checkbox.js +1 -1
- package/dist/Form/Form.Input.js +1 -1
- package/dist/Form/Form.InputField.js +1 -1
- package/dist/Form/Form.Switch.js +1 -1
- package/dist/Navigation/Navigation.AppBar.d.ts +18 -2
- package/dist/Navigation/Navigation.AppBar.js +48 -9
- package/dist/Navigation/Navigation.BottomNav.d.ts +33 -5
- package/dist/Navigation/Navigation.BottomNav.js +90 -17
- package/dist/Navigation/Navigation.SearchBar.js +7 -1
- package/dist/Navigation/Navigation.TabIcon.d.ts +4 -0
- package/dist/Navigation/Navigation.TabIcon.js +4 -0
- package/dist/Navigation/Navigation.TabItem.d.ts +5 -0
- package/dist/Navigation/Navigation.TabItem.js +5 -0
- package/dist/Navigation/index.d.ts +2 -2
- package/dist/Typography/Typography.Text.d.ts +1 -1
- package/dist/Typography/Typography.Text.js +16 -6
- package/dist/icons/OdooIcon.d.ts +5 -0
- package/dist/icons/OdooIcon.js +5 -0
- package/dist/icons/PrinterIcon.d.ts +5 -0
- package/dist/icons/PrinterIcon.js +5 -0
- package/dist/layouts/AuthContainer.js +2 -2
- package/dist/theme/dark.d.ts +3 -3
- package/dist/theme/dark.js +54 -53
- package/dist/theme/default.js +1 -0
- package/dist/theme/index.d.ts +1 -0
- package/dist/theme/index.js +1 -0
- package/dist/theme/types.d.ts +1 -0
- package/dist/theme/typography.d.ts +117 -60
- package/dist/theme/typography.js +115 -29
- package/dist/utils/timezone.d.ts +5 -0
- package/dist/views/FormViewV2.d.ts +2 -1
- package/dist/views/FormViewV2.js +8 -4
- package/dist/views/ListViewV2.context.d.ts +5 -1
- package/dist/views/ListViewV2.context.js +3 -1
- package/dist/views/ListViewV2.d.ts +7 -2
- package/dist/views/ListViewV2.js +18 -20
- package/dist/widgets/GeoPermissionCard.d.ts +5 -0
- package/dist/widgets/GeoPermissionCard.js +8 -3
- package/dist/widgets/JSONViewer.js +3 -6
- package/dist/widgets/TimeZoneSelector.d.ts +5 -0
- package/dist/widgets/TimeZoneSelector.js +6 -1
- package/dist/widgets/TimeZoneSelectorModal.d.ts +5 -0
- package/dist/widgets/TimeZoneSelectorModal.js +8 -3
- package/package.json +12 -7
|
@@ -251,7 +251,7 @@ export interface FooterProps {
|
|
|
251
251
|
* @example Status footer
|
|
252
252
|
* ```tsx
|
|
253
253
|
* <BottomSheet.Footer>
|
|
254
|
-
* <Text className="text-
|
|
254
|
+
* <Text className="text-text-secondary text-sm">
|
|
255
255
|
* Last updated: 5 minutes ago
|
|
256
256
|
* </Text>
|
|
257
257
|
* </BottomSheet.Footer>
|
|
@@ -262,7 +262,7 @@ export interface FooterProps {
|
|
|
262
262
|
* <BottomSheet.Footer>
|
|
263
263
|
* <View className="flex-row items-center">
|
|
264
264
|
* <Icon name="info" size={16} />
|
|
265
|
-
* <Text className="ml-2 text-
|
|
265
|
+
* <Text className="ml-2 text-text-secondary">Swipe down to dismiss</Text>
|
|
266
266
|
* </View>
|
|
267
267
|
* </BottomSheet.Footer>
|
|
268
268
|
* ```
|
|
@@ -310,7 +310,7 @@ function Actions({ children, layout = "auto" }) {
|
|
|
310
310
|
* @example Status footer
|
|
311
311
|
* ```tsx
|
|
312
312
|
* <BottomSheet.Footer>
|
|
313
|
-
* <Text className="text-
|
|
313
|
+
* <Text className="text-text-secondary text-sm">
|
|
314
314
|
* Last updated: 5 minutes ago
|
|
315
315
|
* </Text>
|
|
316
316
|
* </BottomSheet.Footer>
|
|
@@ -321,7 +321,7 @@ function Actions({ children, layout = "auto" }) {
|
|
|
321
321
|
* <BottomSheet.Footer>
|
|
322
322
|
* <View className="flex-row items-center">
|
|
323
323
|
* <Icon name="info" size={16} />
|
|
324
|
-
* <Text className="ml-2 text-
|
|
324
|
+
* <Text className="ml-2 text-text-secondary">Swipe down to dismiss</Text>
|
|
325
325
|
* </View>
|
|
326
326
|
* </BottomSheet.Footer>
|
|
327
327
|
* ```
|
|
@@ -4,6 +4,10 @@ import { theme } from "../theme";
|
|
|
4
4
|
import Typography from "../Typography/Typography.Text";
|
|
5
5
|
import { Modal, TouchableWithoutFeedback, View } from "react-native";
|
|
6
6
|
const ConfirmationDialog = ({ visible, onCancel, onConfirm, auxTitle = "cambios", subtitle = "¿Estás seguro de que quieres descartar los cambios realizados?", confirmButtonText = "Sí", cancelButtonText = "No, continuar aquí", }) => {
|
|
7
|
-
return (_jsx(Modal, { animationType: "fade", onRequestClose: onCancel, transparent: true, visible: visible, children: _jsx(TouchableWithoutFeedback, { onPress: onCancel, children: _jsx(View, { className: "flex-1 justify-center items-center p-6 bg-black/50", children: _jsx(TouchableWithoutFeedback, { children: _jsxs(View, { className: "
|
|
7
|
+
return (_jsx(Modal, { animationType: "fade", onRequestClose: onCancel, transparent: true, visible: visible, children: _jsx(TouchableWithoutFeedback, { onPress: onCancel, children: _jsx(View, { className: "flex-1 justify-center items-center p-6 bg-black/50", children: _jsx(TouchableWithoutFeedback, { children: _jsxs(View, { className: "p-3 w-full max-w-xs mx-auto", style: {
|
|
8
|
+
borderRadius: 22,
|
|
9
|
+
backgroundColor: theme.bg.popover,
|
|
10
|
+
...theme.shadow.md,
|
|
11
|
+
}, children: [_jsx(Typography, { 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" })] })] }) }) }) }) }));
|
|
8
12
|
};
|
|
9
13
|
export default ConfirmationDialog;
|
|
@@ -11,6 +11,6 @@ function EditableValueModal({ visible, title, value, onChangeValue, onConfirm, o
|
|
|
11
11
|
return () => clearTimeout(t);
|
|
12
12
|
}
|
|
13
13
|
}, [visible, autoFocus]);
|
|
14
|
-
return (_jsx(Modal, { animationType: "fade", onRequestClose: onCancel, transparent: true, visible: visible, children: _jsx(View, { className: "flex-1 justify-center p-6 bg-black/40", children: _jsxs(View, { className: "
|
|
14
|
+
return (_jsx(Modal, { animationType: "fade", onRequestClose: onCancel, transparent: true, visible: visible, children: _jsx(View, { className: "flex-1 justify-center p-6 bg-black/40", children: _jsxs(View, { className: "p-4", style: { borderRadius: 22, 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, { className: "flex-1 border border-input rounded-lg p-2.5 text-lg text-text-primary", keyboardType: keyboardType, onChangeText: onChangeValue, onSubmitEditing: onConfirm, placeholder: placeholder, ref: inputRef, returnKeyType: "done", 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 }) })] })] }) }) }));
|
|
15
15
|
}
|
|
16
16
|
export default EditableValueModal;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { type VariantProps } from "../theme/tw";
|
|
2
|
+
import { type LinearGradientPoint } from "expo-linear-gradient";
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
import { type ViewStyle } from "react-native";
|
|
5
|
+
/**
|
|
6
|
+
* Decorative gradient presets (2026 art direction). `brand` is themeable (reads
|
|
7
|
+
* `theme.gradient.primary`); the rest are intentional design constants for heroes/splash.
|
|
8
|
+
* Each is [from, …, to].
|
|
9
|
+
*/
|
|
10
|
+
declare const GRADIENT_PRESETS: {
|
|
11
|
+
readonly "neon-teal": {
|
|
12
|
+
readonly colors: readonly ["#22E584", "#0FB8A0"];
|
|
13
|
+
readonly start: {
|
|
14
|
+
readonly x: 0;
|
|
15
|
+
readonly y: 0;
|
|
16
|
+
};
|
|
17
|
+
readonly end: {
|
|
18
|
+
readonly x: 1;
|
|
19
|
+
readonly y: 1;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
readonly "night-green": {
|
|
23
|
+
readonly colors: readonly ["#0B1410", "#0E2A1E", "#08120D"];
|
|
24
|
+
readonly start: {
|
|
25
|
+
readonly x: 0;
|
|
26
|
+
readonly y: 0;
|
|
27
|
+
};
|
|
28
|
+
readonly end: {
|
|
29
|
+
readonly x: 1;
|
|
30
|
+
readonly y: 1;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
readonly mesh: {
|
|
34
|
+
readonly colors: readonly ["#0B1410", "#10B981", "#0B1410", "#1E1B8A"];
|
|
35
|
+
readonly start: {
|
|
36
|
+
readonly x: 0;
|
|
37
|
+
readonly y: 0;
|
|
38
|
+
};
|
|
39
|
+
readonly end: {
|
|
40
|
+
readonly x: 1;
|
|
41
|
+
readonly y: 1;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
readonly emerald: {
|
|
45
|
+
readonly colors: readonly ["#00C357", "#00A862"];
|
|
46
|
+
readonly start: {
|
|
47
|
+
readonly x: 0;
|
|
48
|
+
readonly y: 0;
|
|
49
|
+
};
|
|
50
|
+
readonly end: {
|
|
51
|
+
readonly x: 1;
|
|
52
|
+
readonly y: 1;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
export type GradientPreset = keyof typeof GRADIENT_PRESETS | "brand";
|
|
57
|
+
declare const surface: import("tailwind-variants").TVReturnType<{
|
|
58
|
+
radius: {
|
|
59
|
+
none: string;
|
|
60
|
+
md: string;
|
|
61
|
+
lg: string;
|
|
62
|
+
full: string;
|
|
63
|
+
};
|
|
64
|
+
padding: {
|
|
65
|
+
none: string;
|
|
66
|
+
sm: string;
|
|
67
|
+
md: string;
|
|
68
|
+
lg: string;
|
|
69
|
+
};
|
|
70
|
+
}, undefined, undefined, {
|
|
71
|
+
radius: {
|
|
72
|
+
none: string;
|
|
73
|
+
md: string;
|
|
74
|
+
lg: string;
|
|
75
|
+
full: string;
|
|
76
|
+
};
|
|
77
|
+
padding: {
|
|
78
|
+
none: string;
|
|
79
|
+
sm: string;
|
|
80
|
+
md: string;
|
|
81
|
+
lg: string;
|
|
82
|
+
};
|
|
83
|
+
}, undefined, import("tailwind-variants").TVReturnType<{
|
|
84
|
+
radius: {
|
|
85
|
+
none: string;
|
|
86
|
+
md: string;
|
|
87
|
+
lg: string;
|
|
88
|
+
full: string;
|
|
89
|
+
};
|
|
90
|
+
padding: {
|
|
91
|
+
none: string;
|
|
92
|
+
sm: string;
|
|
93
|
+
md: string;
|
|
94
|
+
lg: string;
|
|
95
|
+
};
|
|
96
|
+
}, undefined, undefined, unknown, unknown, undefined>>;
|
|
97
|
+
export interface GradientSurfaceProps extends VariantProps<typeof surface> {
|
|
98
|
+
/** Named brand preset. Ignored if `colors` is provided. */
|
|
99
|
+
preset?: GradientPreset;
|
|
100
|
+
/** Custom gradient stops (overrides `preset`). */
|
|
101
|
+
colors?: readonly [string, string, ...string[]];
|
|
102
|
+
start?: LinearGradientPoint;
|
|
103
|
+
end?: LinearGradientPoint;
|
|
104
|
+
children?: ReactNode;
|
|
105
|
+
className?: string;
|
|
106
|
+
style?: ViewStyle;
|
|
107
|
+
testID?: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Modern gradient surface (delivery/fintech 2026 look). Wraps `expo-linear-gradient` with
|
|
111
|
+
* named brand presets + tokenized radius/padding. iOS + Android (no native dep beyond the
|
|
112
|
+
* already-peer `expo-linear-gradient`). Replaces the legacy `GradientContainer`.
|
|
113
|
+
*/
|
|
114
|
+
declare function GradientSurface({ preset, colors, start, end, radius, padding, children, className, style, testID, }: GradientSurfaceProps): import("react").JSX.Element;
|
|
115
|
+
export default GradientSurface;
|
|
116
|
+
export { GRADIENT_PRESETS, GradientSurface };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import { theme } from "../theme";
|
|
3
|
+
import { cn, tv } from "../theme/tw";
|
|
4
|
+
import { LinearGradient } from "expo-linear-gradient";
|
|
5
|
+
import { View } from "react-native";
|
|
6
|
+
/**
|
|
7
|
+
* Decorative gradient presets (2026 art direction). `brand` is themeable (reads
|
|
8
|
+
* `theme.gradient.primary`); the rest are intentional design constants for heroes/splash.
|
|
9
|
+
* Each is [from, …, to].
|
|
10
|
+
*/
|
|
11
|
+
const GRADIENT_PRESETS = {
|
|
12
|
+
"neon-teal": {
|
|
13
|
+
colors: ["#22E584", "#0FB8A0"],
|
|
14
|
+
start: { x: 0, y: 0 },
|
|
15
|
+
end: { x: 1, y: 1 },
|
|
16
|
+
},
|
|
17
|
+
"night-green": {
|
|
18
|
+
colors: ["#0B1410", "#0E2A1E", "#08120D"],
|
|
19
|
+
start: { x: 0, y: 0 },
|
|
20
|
+
end: { x: 1, y: 1 },
|
|
21
|
+
},
|
|
22
|
+
mesh: {
|
|
23
|
+
colors: ["#0B1410", "#10B981", "#0B1410", "#1E1B8A"],
|
|
24
|
+
start: { x: 0, y: 0 },
|
|
25
|
+
end: { x: 1, y: 1 },
|
|
26
|
+
},
|
|
27
|
+
emerald: {
|
|
28
|
+
colors: ["#00C357", "#00A862"],
|
|
29
|
+
start: { x: 0, y: 0 },
|
|
30
|
+
end: { x: 1, y: 1 },
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
const surface = tv({
|
|
34
|
+
variants: {
|
|
35
|
+
radius: {
|
|
36
|
+
none: "rounded-none",
|
|
37
|
+
md: "rounded-xl",
|
|
38
|
+
lg: "rounded-2xl",
|
|
39
|
+
full: "rounded-full",
|
|
40
|
+
},
|
|
41
|
+
padding: {
|
|
42
|
+
none: "p-0",
|
|
43
|
+
sm: "p-3",
|
|
44
|
+
md: "p-4",
|
|
45
|
+
lg: "p-6",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
defaultVariants: { radius: "lg", padding: "none" },
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* Modern gradient surface (delivery/fintech 2026 look). Wraps `expo-linear-gradient` with
|
|
52
|
+
* named brand presets + tokenized radius/padding. iOS + Android (no native dep beyond the
|
|
53
|
+
* already-peer `expo-linear-gradient`). Replaces the legacy `GradientContainer`.
|
|
54
|
+
*/
|
|
55
|
+
function GradientSurface({ preset = "neon-teal", colors, start, end, radius, padding, children, className, style, testID, }) {
|
|
56
|
+
const p = preset === "brand" ? GRADIENT_PRESETS["neon-teal"] : GRADIENT_PRESETS[preset];
|
|
57
|
+
const presetColors = preset === "brand" ? theme.gradient.primary : p.colors;
|
|
58
|
+
const resolvedColors = (colors ?? presetColors);
|
|
59
|
+
return (_jsxs(View, { className: cn("overflow-hidden", surface({ radius })), style: style, testID: testID, children: [_jsx(LinearGradient, { colors: [...resolvedColors], end: end ?? p.end, start: start ?? p.start, style: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0 } }), _jsx(View, { className: cn(surface({ padding }), className), children: children })] }));
|
|
60
|
+
}
|
|
61
|
+
export default GradientSurface;
|
|
62
|
+
export { GRADIENT_PRESETS, GradientSurface };
|
|
@@ -4,6 +4,6 @@ import { Typography } from "../Typography";
|
|
|
4
4
|
import { View } from "react-native";
|
|
5
5
|
function KeyValue({ label, value, align = "row", className, testID }) {
|
|
6
6
|
const isRow = align === "row";
|
|
7
|
-
return (_jsxs(View, { className: cn(isRow ? "flex-row items-center justify-between gap-3" : "gap-0.5", "py-2", className), testID: testID, children: [_jsx(Typography.Text, { className: "text-text-secondary", variant: "
|
|
7
|
+
return (_jsxs(View, { className: cn(isRow ? "flex-row items-center justify-between gap-3" : "gap-0.5", "py-2", className), testID: testID, children: [_jsx(Typography.Text, { className: "text-text-secondary", variant: "caption", children: label }), typeof value === "string" || typeof value === "number" ? (_jsx(Typography.Text, { className: cn("text-text-primary", isRow && "text-right"), semibold: isRow, children: value })) : (value)] }));
|
|
8
8
|
}
|
|
9
9
|
export default KeyValue;
|
|
@@ -2,12 +2,16 @@ import type { ReactNode } from "react";
|
|
|
2
2
|
export interface ListItemProps {
|
|
3
3
|
title: string;
|
|
4
4
|
subtitle?: string;
|
|
5
|
+
/** Leading slot — icon, avatar, status dot. */
|
|
5
6
|
leading?: ReactNode;
|
|
7
|
+
/** Trailing slot — value text, toggle, badge. Overrides the auto `chevron`. */
|
|
6
8
|
trailing?: ReactNode;
|
|
9
|
+
/** Show a forward chevron on the right (navigational row). Ignored if `trailing` is set. */
|
|
10
|
+
chevron?: boolean;
|
|
7
11
|
onPress?: () => void;
|
|
8
12
|
showDivider?: boolean;
|
|
9
13
|
className?: string;
|
|
10
14
|
testID?: string;
|
|
11
15
|
}
|
|
12
|
-
declare function ListItem({ title, subtitle, leading, trailing, onPress, showDivider, className, testID, }: ListItemProps): import("react").JSX.Element;
|
|
16
|
+
declare function ListItem({ title, subtitle, leading, trailing, chevron, onPress, showDivider, className, testID, }: ListItemProps): import("react").JSX.Element;
|
|
13
17
|
export default ListItem;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "nativewind/jsx-runtime";
|
|
2
|
+
import Icon from "../Display/Display.Icon";
|
|
2
3
|
import Pressable from "../primitives/Pressable";
|
|
4
|
+
import { theme } from "../theme";
|
|
3
5
|
import { cn } from "../theme/tw";
|
|
4
6
|
import { Typography } from "../Typography";
|
|
5
7
|
import { View } from "react-native";
|
|
6
|
-
function ListItem({ title, subtitle, leading, trailing, onPress, showDivider = true, className, testID, }) {
|
|
7
|
-
const
|
|
8
|
+
function ListItem({ title, subtitle, leading, trailing, chevron = false, onPress, showDivider = true, className, testID, }) {
|
|
9
|
+
const right = trailing ??
|
|
10
|
+
(chevron ? _jsx(Icon, { color: theme.icon.tertiary, name: "chevron-forward", size: 18 }) : null);
|
|
11
|
+
const content = (_jsxs(_Fragment, { children: [leading ? _jsx(View, { className: "mr-3 justify-center", children: leading }) : null, _jsxs(View, { className: "flex-1 gap-0.5", 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] }), right ? _jsx(View, { className: "ml-3 justify-center", children: right }) : null] }));
|
|
8
12
|
const base = cn("flex-row items-center py-3 px-4 bg-bg-card", showDivider && "border-b border-border-default", className);
|
|
9
13
|
if (onPress) {
|
|
10
14
|
return (_jsx(Pressable, { className: base, onPress: onPress, testID: testID, children: content }));
|
|
@@ -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 = "
|
|
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 };
|
|
@@ -3,9 +3,9 @@ import { cn } from "../theme/tw";
|
|
|
3
3
|
import { Typography } from "../Typography";
|
|
4
4
|
import { View } from "react-native";
|
|
5
5
|
const sizeMap = {
|
|
6
|
-
sm: { price: "
|
|
7
|
-
md: { price: "
|
|
8
|
-
lg: { price: "
|
|
6
|
+
sm: { price: "data", original: "captionSmall" },
|
|
7
|
+
md: { price: "data", original: "caption" },
|
|
8
|
+
lg: { price: "dataLarge", original: "data" },
|
|
9
9
|
};
|
|
10
10
|
function format(amount, currency) {
|
|
11
11
|
const formatted = amount.toLocaleString("es-BO", {
|
|
@@ -3,7 +3,7 @@ import { cn } from "../theme/tw";
|
|
|
3
3
|
import { Typography } from "../Typography";
|
|
4
4
|
import { View } from "react-native";
|
|
5
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",
|
|
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
7
|
}
|
|
8
8
|
export default Stat;
|
|
9
9
|
export { Stat };
|
|
@@ -8,6 +8,6 @@ function StatCard({ label, value, icon, delta, deltaSuffix = "%", hint, trailing
|
|
|
8
8
|
const hasDelta = typeof delta === "number";
|
|
9
9
|
const up = hasDelta && delta >= 0;
|
|
10
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: "
|
|
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
12
|
}
|
|
13
13
|
export default StatCard;
|
package/dist/Display/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import CountRecords from "../Display/Display.CountRecords";
|
|
|
7
7
|
import DataTable from "../Display/Display.DataTable";
|
|
8
8
|
import Date from "../Display/Display.Date";
|
|
9
9
|
import Divider from "../Display/Display.Divider";
|
|
10
|
+
import GradientSurface from "../Display/Display.GradientSurface";
|
|
10
11
|
import IconBadge from "../Display/Display.IconBadge";
|
|
11
12
|
import DisplayImage from "../Display/Display.Image";
|
|
12
13
|
import KeyValue from "../Display/Display.KeyValue";
|
|
@@ -15,6 +16,7 @@ import MediaCard from "../Display/Display.MediaCard";
|
|
|
15
16
|
import MediaEmbed from "../Display/Display.MediaEmbed";
|
|
16
17
|
import MenuButton from "../Display/Display.MenuButton";
|
|
17
18
|
import Monetary from "../Display/Display.Monetary";
|
|
19
|
+
import Pattern from "../Display/Display.Pattern";
|
|
18
20
|
import PriceTag from "../Display/Display.PriceTag";
|
|
19
21
|
import ProductCard from "../Display/Display.ProductCard";
|
|
20
22
|
import Rating from "../Display/Display.Rating";
|
|
@@ -78,11 +80,13 @@ export declare const Display: {
|
|
|
78
80
|
CopyableText: typeof CopyableText;
|
|
79
81
|
Date: typeof Date;
|
|
80
82
|
Divider: typeof Divider;
|
|
83
|
+
GradientSurface: typeof GradientSurface;
|
|
81
84
|
Icon: import("react").FC<import("../Display/Display.Icon").IconProps>;
|
|
82
85
|
CountRecords: typeof CountRecords;
|
|
83
86
|
Logo: import("react").FC<import("../Display/Display.Logo").LogoProps>;
|
|
84
87
|
MenuButton: typeof MenuButton;
|
|
85
88
|
Monetary: typeof Monetary;
|
|
89
|
+
Pattern: typeof Pattern;
|
|
86
90
|
};
|
|
87
91
|
export { type BadgeProps, BadgeVariants };
|
|
88
92
|
export default Display;
|
package/dist/Display/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import CountRecords from "../Display/Display.CountRecords";
|
|
|
10
10
|
import DataTable from "../Display/Display.DataTable";
|
|
11
11
|
import Date from "../Display/Display.Date";
|
|
12
12
|
import Divider from "../Display/Display.Divider";
|
|
13
|
+
import GradientSurface from "../Display/Display.GradientSurface";
|
|
13
14
|
import Icon from "../Display/Display.Icon";
|
|
14
15
|
import IconBadge from "../Display/Display.IconBadge";
|
|
15
16
|
import DisplayImage from "../Display/Display.Image";
|
|
@@ -20,6 +21,7 @@ import MediaCard from "../Display/Display.MediaCard";
|
|
|
20
21
|
import MediaEmbed from "../Display/Display.MediaEmbed";
|
|
21
22
|
import MenuButton from "../Display/Display.MenuButton";
|
|
22
23
|
import Monetary from "../Display/Display.Monetary";
|
|
24
|
+
import Pattern from "../Display/Display.Pattern";
|
|
23
25
|
import PriceTag from "../Display/Display.PriceTag";
|
|
24
26
|
import ProductCard from "../Display/Display.ProductCard";
|
|
25
27
|
import Rating from "../Display/Display.Rating";
|
|
@@ -69,11 +71,13 @@ export const Display = {
|
|
|
69
71
|
CopyableText,
|
|
70
72
|
Date,
|
|
71
73
|
Divider,
|
|
74
|
+
GradientSurface,
|
|
72
75
|
Icon,
|
|
73
76
|
CountRecords,
|
|
74
77
|
Logo,
|
|
75
78
|
MenuButton,
|
|
76
79
|
Monetary,
|
|
80
|
+
Pattern,
|
|
77
81
|
};
|
|
78
82
|
export { BadgeVariants };
|
|
79
83
|
export default Display;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
-
import
|
|
2
|
+
import GradientSurface from "../Display/Display.GradientSurface";
|
|
3
|
+
import Pattern from "../Display/Display.Pattern";
|
|
3
4
|
import { Typography } from "../Typography";
|
|
4
5
|
import { useCallback, useEffect, useState } from "react";
|
|
5
6
|
import { StyleSheet, View } from "react-native";
|
|
@@ -57,7 +58,7 @@ function DomainSplashScreen({ domainName, isLoading, children, onComplete, minDu
|
|
|
57
58
|
const splashStyle = useAnimatedStyle(() => ({
|
|
58
59
|
opacity: opacityValue.value,
|
|
59
60
|
}));
|
|
60
|
-
return (_jsxs(View, { style: styles.container, children: [children, _jsx(Animated.View, { pointerEvents: isLoading ? "auto" : "none", style: [StyleSheet.absoluteFill, splashStyle], children: _jsx(
|
|
61
|
+
return (_jsxs(View, { style: styles.container, children: [children, _jsx(Animated.View, { pointerEvents: isLoading ? "auto" : "none", style: [StyleSheet.absoluteFill, splashStyle], children: _jsxs(GradientSurface, { preset: "night-green", radius: "none", style: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0 }, children: [_jsx(Pattern, { color: "#22E584", kind: "dots", opacity: 0.14, size: 26 }), _jsx(View, { className: "flex-1 justify-center items-center px-8", children: _jsxs(View, { className: "w-full items-center gap-5", children: [_jsx(Typography.Text, { bold: true, style: { color: "#FFFFFF", fontSize: 24, letterSpacing: 0.5 }, children: isComplete ? "¡Listo!" : `Cargando ${domainName}` }), !isComplete && (_jsx(View, { className: "w-full rounded-full h-1.5 overflow-hidden", style: { backgroundColor: "rgba(255,255,255,0.18)" }, children: _jsx(Animated.View, { className: "rounded-full h-1.5", style: [{ backgroundColor: "#22E584" }, progressBarStyle] }) })), isComplete && (_jsxs(Typography.Text, { style: { color: "rgba(255,255,255,0.8)", fontSize: 13 }, children: ["Ya puedes comenzar a usar ", domainName, "."] }))] }) })] }) })] }));
|
|
61
62
|
}
|
|
62
63
|
const styles = StyleSheet.create({
|
|
63
64
|
container: {
|
|
@@ -5,5 +5,11 @@ interface LoadingStateProps {
|
|
|
5
5
|
style?: object;
|
|
6
6
|
className?: string;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Full-screen centered loading state. Thin layout convenience over `Spinner` (the atom):
|
|
10
|
+
* `Spinner` is the inline indicator (ActivityIndicator + optional text); `LoadingState`
|
|
11
|
+
* is `Spinner` centered with `flex-1` for an empty screen/section. Use `Spinner` directly
|
|
12
|
+
* when you need an inline/footer indicator (e.g. pagination), `LoadingState` for a blank view.
|
|
13
|
+
*/
|
|
8
14
|
declare function LoadingState({ message, size, style, className, }: LoadingStateProps): React.JSX.Element;
|
|
9
15
|
export default LoadingState;
|
|
@@ -2,7 +2,13 @@ import { jsx as _jsx } from "nativewind/jsx-runtime";
|
|
|
2
2
|
import Spinner from "../Feedback/Feedback.Spinner";
|
|
3
3
|
import { cn } from "../theme/tw";
|
|
4
4
|
import { View } from "react-native";
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Full-screen centered loading state. Thin layout convenience over `Spinner` (the atom):
|
|
7
|
+
* `Spinner` is the inline indicator (ActivityIndicator + optional text); `LoadingState`
|
|
8
|
+
* is `Spinner` centered with `flex-1` for an empty screen/section. Use `Spinner` directly
|
|
9
|
+
* when you need an inline/footer indicator (e.g. pagination), `LoadingState` for a blank view.
|
|
10
|
+
*/
|
|
11
|
+
function LoadingState({ message = "Cargando…", size = "small", style = {}, className, }) {
|
|
6
12
|
return (_jsx(View, { className: cn("flex-1 justify-center items-center", className), style: style, children: _jsx(Spinner, { className: "mb-5", size: size, text: message }) }));
|
|
7
13
|
}
|
|
8
14
|
export default LoadingState;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import { theme } from "../theme";
|
|
2
3
|
import { cn } from "../theme/tw";
|
|
3
4
|
import { Typography } from "../Typography";
|
|
4
5
|
import { ActivityIndicator, View } from "react-native";
|
|
5
|
-
const Spinner = ({ size = "large", color =
|
|
6
|
+
const Spinner = ({ size = "large", color = theme.primary, text, style, className, }) => {
|
|
6
7
|
return (_jsxs(View, { className: cn("items-center justify-center", className), style: style, children: [_jsx(ActivityIndicator, { color: color, size: size }), text && (_jsx(Typography.Text, { className: "mt-2.5 text-base", variant: "body", children: text }))] }));
|
|
7
8
|
};
|
|
8
9
|
export default Spinner;
|
|
@@ -5,7 +5,13 @@ interface SplashScreenProps {
|
|
|
5
5
|
logo?: ImageSourcePropType;
|
|
6
6
|
minDuration?: number;
|
|
7
7
|
message?: string;
|
|
8
|
+
/** `default` keeps the legacy look; `hero` is the modern dark gradient + dotted texture. */
|
|
9
|
+
variant?: "default" | "hero";
|
|
10
|
+
/** Brand name shown under the logo on `hero`. */
|
|
11
|
+
title?: string;
|
|
12
|
+
/** Small caption under the title on `hero` (e.g. "gestión · v2.0"). */
|
|
13
|
+
subtitle?: string;
|
|
8
14
|
children?: ReactNode;
|
|
9
15
|
}
|
|
10
|
-
declare function Splash({ isReady, logo, minDuration, message, children, }: SplashScreenProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
16
|
+
declare function Splash({ isReady, logo, minDuration, message, variant, title, subtitle, children, }: SplashScreenProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
11
17
|
export default Splash;
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import GradientSurface from "../Display/Display.GradientSurface";
|
|
3
|
+
import Pattern from "../Display/Display.Pattern";
|
|
2
4
|
import Loading from "../Feedback/Feedback.Loading";
|
|
3
5
|
import GradientContainer from "../layouts/GradientContainer";
|
|
6
|
+
import { Typography } from "../Typography";
|
|
4
7
|
import { useEffect, useRef, useState } from "react";
|
|
5
|
-
import { Image, View } from "react-native";
|
|
8
|
+
import { ActivityIndicator, Image, View } from "react-native";
|
|
6
9
|
function renderLogo(logo) {
|
|
7
10
|
if (!logo) {
|
|
8
11
|
return null;
|
|
9
12
|
}
|
|
10
13
|
return _jsx(Image, { className: "w-[250px] h-[200px] mb-12", resizeMode: "contain", source: logo });
|
|
11
14
|
}
|
|
12
|
-
function
|
|
15
|
+
function HeroSplash({ logo, message, title, subtitle, }) {
|
|
16
|
+
return (_jsxs(GradientSurface, { className: "flex-1 items-center justify-center", preset: "night-green", radius: "none", children: [_jsx(Pattern, { color: "#22E584", kind: "dots", opacity: 0.16, size: 26 }), _jsxs(View, { className: "items-center", children: [logo ? (_jsx(Image, { className: "w-28 h-28 mb-7", resizeMode: "contain", source: logo, style: { shadowColor: "#22E584", shadowOpacity: 0.7, shadowRadius: 28 } })) : null, title ? (_jsx(Typography.Text, { bold: true, style: { color: "#FFFFFF", fontSize: 28, letterSpacing: 1 }, children: title })) : null, subtitle ? (_jsx(Typography.Text, { style: { color: "rgba(255,255,255,0.6)", fontSize: 13, marginTop: 6 }, children: subtitle })) : null, _jsx(View, { className: "mt-10", children: _jsx(ActivityIndicator, { accessibilityLabel: message, color: "#22E584", size: "small" }) })] })] }));
|
|
17
|
+
}
|
|
18
|
+
function Splash({ isReady, logo, minDuration = 800, message = "Inicializando...", variant = "default", title, subtitle, children, }) {
|
|
13
19
|
const [showContent, setShowContent] = useState(false);
|
|
14
20
|
const minDurationTimeoutRef = useRef(null);
|
|
15
21
|
useEffect(() => {
|
|
@@ -30,6 +36,9 @@ function Splash({ isReady, logo, minDuration = 800, message = "Inicializando..."
|
|
|
30
36
|
};
|
|
31
37
|
}, [isReady, minDuration]);
|
|
32
38
|
if (!showContent) {
|
|
39
|
+
if (variant === "hero") {
|
|
40
|
+
return _jsx(HeroSplash, { logo: logo, message: message, subtitle: subtitle, title: title });
|
|
41
|
+
}
|
|
33
42
|
return (_jsx(GradientContainer, { className: "flex-1", children: _jsxs(View, { className: "flex-1 justify-center items-center", children: [renderLogo(logo), _jsx(Loading, { message: message, size: "large" })] }) }));
|
|
34
43
|
}
|
|
35
44
|
return children;
|
|
@@ -10,6 +10,12 @@ export interface ToastOptions {
|
|
|
10
10
|
variant?: ToastVariant;
|
|
11
11
|
duration?: number;
|
|
12
12
|
action?: ToastAction;
|
|
13
|
+
/** Stable id: calling show()/info()/… again with the same id updates the existing toast
|
|
14
|
+
* (and resets its timer) instead of stacking a duplicate. */
|
|
15
|
+
id?: string;
|
|
16
|
+
/** Render a close (✕) button. Defaults to true for persistent toasts (duration 0 / loading),
|
|
17
|
+
* false for auto-dismissing ones. */
|
|
18
|
+
dismissible?: boolean;
|
|
13
19
|
}
|
|
14
20
|
type MessageOrFn<T> = string | ((value: T) => string);
|
|
15
21
|
export interface ToastPromiseMessages<T> {
|
|
@@ -28,8 +34,9 @@ export interface ToastContextValue {
|
|
|
28
34
|
loading: (message: string, options?: Omit<ToastOptions, "message" | "variant">) => string;
|
|
29
35
|
promise: <T>(promise: Promise<T>, messages: ToastPromiseMessages<T>) => Promise<T>;
|
|
30
36
|
}
|
|
31
|
-
export declare function ToastProvider({ children }: {
|
|
37
|
+
export declare function ToastProvider({ children, position, }: {
|
|
32
38
|
children: ReactNode;
|
|
39
|
+
position?: "top" | "bottom";
|
|
33
40
|
}): import("react").JSX.Element;
|
|
34
41
|
export declare function useToast(): ToastContextValue;
|
|
35
42
|
export {};
|