@medway-ui/native 1.6.1 → 1.7.0
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/README.md +27 -2
- package/lib/commonjs/components/Alert.js +3 -1
- package/lib/commonjs/components/Alert.js.map +1 -1
- package/lib/commonjs/components/AlertDialog.js +5 -2
- package/lib/commonjs/components/AlertDialog.js.map +1 -1
- package/lib/commonjs/components/Badge.js +37 -2
- package/lib/commonjs/components/Badge.js.map +1 -1
- package/lib/commonjs/components/Button.js +32 -1
- package/lib/commonjs/components/Button.js.map +1 -1
- package/lib/commonjs/components/Carousel.js +12 -2
- package/lib/commonjs/components/Carousel.js.map +1 -1
- package/lib/commonjs/components/Checkbox.js +2 -0
- package/lib/commonjs/components/Checkbox.js.map +1 -1
- package/lib/commonjs/components/Chip.js +208 -0
- package/lib/commonjs/components/Chip.js.map +1 -0
- package/lib/commonjs/components/Choice.js +116 -0
- package/lib/commonjs/components/Choice.js.map +1 -0
- package/lib/commonjs/components/Dialog.js +27 -16
- package/lib/commonjs/components/Dialog.js.map +1 -1
- package/lib/commonjs/components/DropdownMenu.js +73 -57
- package/lib/commonjs/components/DropdownMenu.js.map +1 -1
- package/lib/commonjs/components/EmptyState.js +9 -2
- package/lib/commonjs/components/EmptyState.js.map +1 -1
- package/lib/commonjs/components/Feed.js +7 -3
- package/lib/commonjs/components/Feed.js.map +1 -1
- package/lib/commonjs/components/Feedback.js +77 -0
- package/lib/commonjs/components/Feedback.js.map +1 -0
- package/lib/commonjs/components/Filter.js +93 -0
- package/lib/commonjs/components/Filter.js.map +1 -0
- package/lib/commonjs/components/IndexLevel.js +4 -3
- package/lib/commonjs/components/IndexLevel.js.map +1 -1
- package/lib/commonjs/components/Input.js +149 -45
- package/lib/commonjs/components/Input.js.map +1 -1
- package/lib/commonjs/components/InvitePopover.js +4 -1
- package/lib/commonjs/components/InvitePopover.js.map +1 -1
- package/lib/commonjs/components/MemberRow.js +3 -4
- package/lib/commonjs/components/MemberRow.js.map +1 -1
- package/lib/commonjs/components/PostForm.js +18 -8
- package/lib/commonjs/components/PostForm.js.map +1 -1
- package/lib/commonjs/components/PrizeCollection.js +1 -1
- package/lib/commonjs/components/RadioGroup.js +7 -0
- package/lib/commonjs/components/RadioGroup.js.map +1 -1
- package/lib/commonjs/components/Select.js +1 -1
- package/lib/commonjs/components/Sheet.js +4 -1
- package/lib/commonjs/components/Sheet.js.map +1 -1
- package/lib/commonjs/components/Skeleton.js +55 -4
- package/lib/commonjs/components/Skeleton.js.map +1 -1
- package/lib/commonjs/components/Switch.js +2 -0
- package/lib/commonjs/components/Switch.js.map +1 -1
- package/lib/commonjs/components/Tabs.js +2 -0
- package/lib/commonjs/components/Tabs.js.map +1 -1
- package/lib/commonjs/components/Toast.js +355 -79
- package/lib/commonjs/components/Toast.js.map +1 -1
- package/lib/commonjs/editor/NoteEditor.js +36 -11
- package/lib/commonjs/editor/NoteEditor.js.map +1 -1
- package/lib/commonjs/editor/editorHtml.generated.js +1 -1
- package/lib/commonjs/editor/editorHtml.generated.js.map +1 -1
- package/lib/commonjs/hooks/useThemeColor.js +693 -65
- package/lib/commonjs/hooks/useThemeColor.js.map +1 -1
- package/lib/commonjs/hooks/useTrackedText.js +21 -0
- package/lib/commonjs/hooks/useTrackedText.js.map +1 -0
- package/lib/commonjs/index.js +46 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/lib/optional-deps.js +20 -0
- package/lib/commonjs/lib/optional-deps.js.map +1 -0
- package/lib/commonjs/lib/touch-target.js +19 -0
- package/lib/commonjs/lib/touch-target.js.map +1 -0
- package/lib/module/components/Alert.js +3 -1
- package/lib/module/components/Alert.js.map +1 -1
- package/lib/module/components/AlertDialog.js +5 -2
- package/lib/module/components/AlertDialog.js.map +1 -1
- package/lib/module/components/Badge.js +36 -2
- package/lib/module/components/Badge.js.map +1 -1
- package/lib/module/components/Button.js +32 -1
- package/lib/module/components/Button.js.map +1 -1
- package/lib/module/components/Carousel.js +12 -2
- package/lib/module/components/Carousel.js.map +1 -1
- package/lib/module/components/Checkbox.js +2 -0
- package/lib/module/components/Checkbox.js.map +1 -1
- package/lib/module/components/Chip.js +204 -0
- package/lib/module/components/Chip.js.map +1 -0
- package/lib/module/components/Choice.js +112 -0
- package/lib/module/components/Choice.js.map +1 -0
- package/lib/module/components/Dialog.js +28 -17
- package/lib/module/components/Dialog.js.map +1 -1
- package/lib/module/components/DropdownMenu.js +74 -58
- package/lib/module/components/DropdownMenu.js.map +1 -1
- package/lib/module/components/EmptyState.js +9 -2
- package/lib/module/components/EmptyState.js.map +1 -1
- package/lib/module/components/Feed.js +7 -3
- package/lib/module/components/Feed.js.map +1 -1
- package/lib/module/components/Feedback.js +74 -0
- package/lib/module/components/Feedback.js.map +1 -0
- package/lib/module/components/Filter.js +89 -0
- package/lib/module/components/Filter.js.map +1 -0
- package/lib/module/components/IndexLevel.js +4 -3
- package/lib/module/components/IndexLevel.js.map +1 -1
- package/lib/module/components/Input.js +149 -45
- package/lib/module/components/Input.js.map +1 -1
- package/lib/module/components/InvitePopover.js +4 -1
- package/lib/module/components/InvitePopover.js.map +1 -1
- package/lib/module/components/MemberRow.js +3 -4
- package/lib/module/components/MemberRow.js.map +1 -1
- package/lib/module/components/PostForm.js +18 -8
- package/lib/module/components/PostForm.js.map +1 -1
- package/lib/module/components/PrizeCollection.js +1 -1
- package/lib/module/components/RadioGroup.js +7 -0
- package/lib/module/components/RadioGroup.js.map +1 -1
- package/lib/module/components/Select.js +1 -1
- package/lib/module/components/Sheet.js +4 -1
- package/lib/module/components/Sheet.js.map +1 -1
- package/lib/module/components/Skeleton.js +56 -5
- package/lib/module/components/Skeleton.js.map +1 -1
- package/lib/module/components/Switch.js +2 -0
- package/lib/module/components/Switch.js.map +1 -1
- package/lib/module/components/Tabs.js +2 -0
- package/lib/module/components/Tabs.js.map +1 -1
- package/lib/module/components/Toast.js +360 -84
- package/lib/module/components/Toast.js.map +1 -1
- package/lib/module/editor/NoteEditor.js +36 -11
- package/lib/module/editor/NoteEditor.js.map +1 -1
- package/lib/module/editor/editorHtml.generated.js +1 -1
- package/lib/module/editor/editorHtml.generated.js.map +1 -1
- package/lib/module/hooks/useThemeColor.js +693 -65
- package/lib/module/hooks/useThemeColor.js.map +1 -1
- package/lib/module/hooks/useTrackedText.js +18 -0
- package/lib/module/hooks/useTrackedText.js.map +1 -0
- package/lib/module/index.js +8 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/lib/optional-deps.js +16 -0
- package/lib/module/lib/optional-deps.js.map +1 -0
- package/lib/module/lib/touch-target.js +15 -0
- package/lib/module/lib/touch-target.js.map +1 -0
- package/lib/typescript/components/Alert.d.ts.map +1 -1
- package/lib/typescript/components/AlertDialog.d.ts.map +1 -1
- package/lib/typescript/components/Badge.d.ts +1 -1
- package/lib/typescript/components/Badge.d.ts.map +1 -1
- package/lib/typescript/components/Button.d.ts.map +1 -1
- package/lib/typescript/components/Carousel.d.ts +1 -1
- package/lib/typescript/components/Carousel.d.ts.map +1 -1
- package/lib/typescript/components/Checkbox.d.ts.map +1 -1
- package/lib/typescript/components/Chip.d.ts +30 -0
- package/lib/typescript/components/Chip.d.ts.map +1 -0
- package/lib/typescript/components/Choice.d.ts +17 -0
- package/lib/typescript/components/Choice.d.ts.map +1 -0
- package/lib/typescript/components/Dialog.d.ts.map +1 -1
- package/lib/typescript/components/DropdownMenu.d.ts +0 -7
- package/lib/typescript/components/DropdownMenu.d.ts.map +1 -1
- package/lib/typescript/components/EmptyState.d.ts +3 -2
- package/lib/typescript/components/EmptyState.d.ts.map +1 -1
- package/lib/typescript/components/Feed.d.ts.map +1 -1
- package/lib/typescript/components/Feedback.d.ts +17 -0
- package/lib/typescript/components/Feedback.d.ts.map +1 -0
- package/lib/typescript/components/Filter.d.ts +17 -0
- package/lib/typescript/components/Filter.d.ts.map +1 -0
- package/lib/typescript/components/IndexLevel.d.ts.map +1 -1
- package/lib/typescript/components/Input.d.ts +3 -3
- package/lib/typescript/components/Input.d.ts.map +1 -1
- package/lib/typescript/components/InvitePopover.d.ts.map +1 -1
- package/lib/typescript/components/MemberRow.d.ts.map +1 -1
- package/lib/typescript/components/PostForm.d.ts.map +1 -1
- package/lib/typescript/components/RadioGroup.d.ts.map +1 -1
- package/lib/typescript/components/Sheet.d.ts.map +1 -1
- package/lib/typescript/components/Skeleton.d.ts +1 -1
- package/lib/typescript/components/Skeleton.d.ts.map +1 -1
- package/lib/typescript/components/Switch.d.ts.map +1 -1
- package/lib/typescript/components/Tabs.d.ts.map +1 -1
- package/lib/typescript/components/Tag.d.ts +2 -2
- package/lib/typescript/components/ThemedIcon.d.ts +1 -1
- package/lib/typescript/components/ThemedIcon.d.ts.map +1 -1
- package/lib/typescript/components/Toast.d.ts +24 -13
- package/lib/typescript/components/Toast.d.ts.map +1 -1
- package/lib/typescript/editor/NoteEditor.d.ts.map +1 -1
- package/lib/typescript/editor/editorHtml.generated.d.ts.map +1 -1
- package/lib/typescript/hooks/useThemeColor.d.ts +0 -10
- package/lib/typescript/hooks/useThemeColor.d.ts.map +1 -1
- package/lib/typescript/hooks/useTrackedText.d.ts +6 -0
- package/lib/typescript/hooks/useTrackedText.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +9 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/lib/optional-deps.d.ts +23 -0
- package/lib/typescript/lib/optional-deps.d.ts.map +1 -0
- package/lib/typescript/lib/touch-target.d.ts +5 -0
- package/lib/typescript/lib/touch-target.d.ts.map +1 -0
- package/package.json +6 -1
- package/setup/createMedwayUiNavigator.tsx +4 -7
- package/setup/metro.js +12 -3
- package/src/components/Alert.tsx +3 -1
- package/src/components/AlertDialog.tsx +8 -3
- package/src/components/Badge.tsx +51 -3
- package/src/components/Button.tsx +39 -1
- package/src/components/Carousel.tsx +17 -3
- package/src/components/Checkbox.tsx +2 -0
- package/src/components/Chip.tsx +227 -0
- package/src/components/Choice.tsx +139 -0
- package/src/components/Dialog.tsx +39 -23
- package/src/components/DropdownMenu.tsx +99 -87
- package/src/components/EmptyState.tsx +18 -3
- package/src/components/Feed.tsx +4 -3
- package/src/components/Feedback.tsx +111 -0
- package/src/components/Filter.tsx +106 -0
- package/src/components/IndexLevel.tsx +8 -10
- package/src/components/Input.tsx +142 -54
- package/src/components/InvitePopover.tsx +5 -1
- package/src/components/MemberRow.tsx +3 -5
- package/src/components/PostForm.tsx +16 -9
- package/src/components/PrizeCollection.tsx +1 -1
- package/src/components/RadioGroup.tsx +8 -0
- package/src/components/Select.tsx +1 -1
- package/src/components/Sheet.tsx +4 -1
- package/src/components/Skeleton.tsx +47 -6
- package/src/components/Switch.tsx +2 -0
- package/src/components/Tabs.tsx +2 -0
- package/src/components/ThemedIcon.tsx +1 -1
- package/src/components/Toast.tsx +489 -87
- package/src/editor/NoteEditor.tsx +47 -10
- package/src/editor/editorHtml.generated.ts +1 -1
- package/src/hooks/useThemeColor.ts +757 -64
- package/src/hooks/useTrackedText.ts +20 -0
- package/src/index.ts +36 -1
- package/src/lib/optional-deps.ts +27 -0
- package/src/lib/touch-target.ts +12 -0
- package/setup/index.tsx +0 -42
package/src/components/Toast.tsx
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext,
|
|
4
|
+
useState,
|
|
5
|
+
useEffect,
|
|
6
|
+
useRef,
|
|
7
|
+
type ReactElement,
|
|
8
|
+
type ReactNode,
|
|
9
|
+
} from "react";
|
|
10
|
+
import {
|
|
11
|
+
View,
|
|
12
|
+
Pressable,
|
|
13
|
+
StyleSheet,
|
|
14
|
+
type ViewProps,
|
|
15
|
+
type StyleProp,
|
|
16
|
+
type ViewStyle,
|
|
17
|
+
} from "react-native";
|
|
18
|
+
import { useUnstableNativeVariable } from "nativewind";
|
|
19
|
+
import { SafeAreaInsetsContext } from "react-native-safe-area-context";
|
|
3
20
|
|
|
4
21
|
import { Text } from "@/components/Text";
|
|
5
22
|
import { cva } from "class-variance-authority";
|
|
@@ -7,22 +24,41 @@ import Animated, {
|
|
|
7
24
|
useSharedValue,
|
|
8
25
|
useAnimatedStyle,
|
|
9
26
|
withTiming,
|
|
10
|
-
withDelay,
|
|
11
27
|
runOnJS,
|
|
12
28
|
} from "react-native-reanimated";
|
|
13
29
|
import { cn } from "@/lib/utils";
|
|
30
|
+
import { loadLinearGradient } from "@/lib/optional-deps";
|
|
14
31
|
import {
|
|
15
32
|
CircleCheck,
|
|
16
33
|
CloseMd,
|
|
17
34
|
Info,
|
|
18
35
|
OctagonWarning,
|
|
36
|
+
Rocket,
|
|
19
37
|
TriangleWarning,
|
|
20
38
|
} from "@medway-ui/icons/native";
|
|
21
39
|
import { Button, type ButtonProps } from "@/components/Button";
|
|
40
|
+
import { Loading } from "@/components/Loading";
|
|
22
41
|
import { useToast } from "@/hooks/use-toast";
|
|
23
42
|
import { useThemeColor } from "@/hooks/useThemeColor";
|
|
24
43
|
|
|
25
|
-
|
|
44
|
+
const GRADIENT_VARIANTS = [
|
|
45
|
+
"green-gradient",
|
|
46
|
+
"gold-gradient",
|
|
47
|
+
"silver-gradient",
|
|
48
|
+
"bronze-gradient",
|
|
49
|
+
] as const;
|
|
50
|
+
|
|
51
|
+
type ToastGradientVariant = (typeof GRADIENT_VARIANTS)[number];
|
|
52
|
+
|
|
53
|
+
type ToastSolidVariant =
|
|
54
|
+
| "primary"
|
|
55
|
+
| "secondary"
|
|
56
|
+
| "success"
|
|
57
|
+
| "warning"
|
|
58
|
+
| "error";
|
|
59
|
+
|
|
60
|
+
type ToastVariant = ToastSolidVariant | ToastGradientVariant;
|
|
61
|
+
|
|
26
62
|
type ToastActionVariant = ToastVariant;
|
|
27
63
|
|
|
28
64
|
type ToastActionElement = ReactElement<typeof ToastAction>;
|
|
@@ -33,55 +69,174 @@ interface ToastProps extends ViewProps {
|
|
|
33
69
|
duration?: number;
|
|
34
70
|
open?: boolean;
|
|
35
71
|
onOpenChange?: (open: boolean) => void;
|
|
72
|
+
icon?: ReactNode;
|
|
36
73
|
children?: ReactNode;
|
|
37
74
|
}
|
|
38
75
|
|
|
39
76
|
interface ToastActionProps extends Omit<ButtonProps, "variant"> {
|
|
40
77
|
variant?: ToastActionVariant;
|
|
41
78
|
altText?: string;
|
|
42
|
-
onPress?: () => void;
|
|
43
79
|
}
|
|
44
80
|
|
|
45
|
-
interface ToastCloseProps extends Omit<
|
|
46
|
-
onPress?: () => void;
|
|
81
|
+
interface ToastCloseProps extends Omit<ButtonProps, "variant" | "children"> {
|
|
47
82
|
label?: string;
|
|
83
|
+
variant?: ToastVariant;
|
|
48
84
|
}
|
|
49
85
|
|
|
86
|
+
type GradientStyle = {
|
|
87
|
+
/** Design tokens for LinearGradient color stops (aligned with web/Figma). */
|
|
88
|
+
colorTokens: [string, string];
|
|
89
|
+
locations: [number, number];
|
|
90
|
+
angleDeg: number;
|
|
91
|
+
textClassName: string;
|
|
92
|
+
pressedClassName: string;
|
|
93
|
+
iconToken: string;
|
|
94
|
+
solidFallbackClassName: string;
|
|
95
|
+
/** Optional solid layer under the gradient (green uses white underlay on web). */
|
|
96
|
+
underlayClassName?: string;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/** Podium / green gradient visuals — stops & angles match `@medway-ui/core` Toast. */
|
|
100
|
+
const GRADIENT_STYLES: Record<ToastGradientVariant, GradientStyle> = {
|
|
101
|
+
"green-gradient": {
|
|
102
|
+
colorTokens: ["secondary", "secondary-12"],
|
|
103
|
+
locations: [0.29, 1],
|
|
104
|
+
angleDeg: 124,
|
|
105
|
+
textClassName: "text-secondary-darken-4",
|
|
106
|
+
pressedClassName: "active:bg-black-8",
|
|
107
|
+
iconToken: "secondary-darken-4",
|
|
108
|
+
solidFallbackClassName: "bg-secondary",
|
|
109
|
+
underlayClassName: "bg-white",
|
|
110
|
+
},
|
|
111
|
+
"gold-gradient": {
|
|
112
|
+
// Literal hex from Figma replaced by podium tokens on web (#72)
|
|
113
|
+
colorTokens: ["gold", "gold-lighten-6"],
|
|
114
|
+
locations: [0.29, 1],
|
|
115
|
+
angleDeg: 124,
|
|
116
|
+
textClassName: "text-gold-foreground-onfill",
|
|
117
|
+
pressedClassName: "active:bg-black-8",
|
|
118
|
+
iconToken: "gold-foreground-onfill",
|
|
119
|
+
solidFallbackClassName: "bg-gold",
|
|
120
|
+
},
|
|
121
|
+
"silver-gradient": {
|
|
122
|
+
colorTokens: ["silver-darken-4", "silver"],
|
|
123
|
+
locations: [0.05, 1],
|
|
124
|
+
angleDeg: 100,
|
|
125
|
+
textClassName: "text-white",
|
|
126
|
+
pressedClassName: "active:bg-white-16",
|
|
127
|
+
iconToken: "white",
|
|
128
|
+
solidFallbackClassName: "bg-silver-darken-4",
|
|
129
|
+
},
|
|
130
|
+
"bronze-gradient": {
|
|
131
|
+
colorTokens: ["bronze-darken-2", "bronze"],
|
|
132
|
+
locations: [0.02, 1],
|
|
133
|
+
angleDeg: 100,
|
|
134
|
+
textClassName: "text-white",
|
|
135
|
+
pressedClassName: "active:bg-white-16",
|
|
136
|
+
iconToken: "white",
|
|
137
|
+
solidFallbackClassName: "bg-bronze",
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
type ToastContextValue = {
|
|
142
|
+
variant: ToastVariant;
|
|
143
|
+
onOpenChange?: (open: boolean) => void;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const ToastContext = createContext<ToastContextValue>({
|
|
147
|
+
variant: "primary",
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
function useToastContext(override?: ToastVariant): ToastContextValue {
|
|
151
|
+
const ctx = useContext(ToastContext);
|
|
152
|
+
return {
|
|
153
|
+
variant: override ?? ctx.variant,
|
|
154
|
+
onOpenChange: ctx.onOpenChange,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const isGradientVariant = (v: ToastVariant): v is ToastGradientVariant =>
|
|
159
|
+
(GRADIENT_VARIANTS as readonly string[]).includes(v);
|
|
160
|
+
|
|
161
|
+
/** CSS angle (0deg = up, clockwise) → expo-linear-gradient start/end. */
|
|
162
|
+
function cssAngleToPoints(angleDeg: number) {
|
|
163
|
+
const rad = (angleDeg * Math.PI) / 180;
|
|
164
|
+
const dx = Math.sin(rad);
|
|
165
|
+
const dy = -Math.cos(rad);
|
|
166
|
+
return {
|
|
167
|
+
start: { x: 0.5 - dx / 2, y: 0.5 - dy / 2 },
|
|
168
|
+
end: { x: 0.5 + dx / 2, y: 0.5 + dy / 2 },
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const RADIUS_LG_FALLBACK = 16;
|
|
173
|
+
|
|
174
|
+
function useRadiusLg(): number {
|
|
175
|
+
const value = useUnstableNativeVariable("--radius-lg");
|
|
176
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
177
|
+
if (typeof value === "string") {
|
|
178
|
+
const parsed = Number.parseFloat(value);
|
|
179
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
180
|
+
}
|
|
181
|
+
return RADIUS_LG_FALLBACK;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** Mirrors web `toastVariants` solid/gradient chrome (minus Radix animation attrs). */
|
|
50
185
|
const toastVariants = cva(
|
|
51
|
-
"flex-row items-center gap-
|
|
186
|
+
"flex-row items-center justify-between gap-4 w-full overflow-hidden shadow-lg",
|
|
52
187
|
{
|
|
53
188
|
variants: {
|
|
189
|
+
appearance: {
|
|
190
|
+
solid: "rounded-md bg-surface-elevated p-2 pl-4",
|
|
191
|
+
gradient: "rounded-lg p-4",
|
|
192
|
+
},
|
|
54
193
|
variant: {
|
|
55
|
-
primary: "
|
|
56
|
-
secondary: "
|
|
57
|
-
success: "
|
|
58
|
-
warning: "
|
|
59
|
-
error: "
|
|
194
|
+
primary: "",
|
|
195
|
+
secondary: "",
|
|
196
|
+
success: "",
|
|
197
|
+
warning: "",
|
|
198
|
+
error: "",
|
|
199
|
+
"green-gradient": "",
|
|
200
|
+
"gold-gradient": "",
|
|
201
|
+
"silver-gradient": "",
|
|
202
|
+
"bronze-gradient": "",
|
|
60
203
|
},
|
|
61
204
|
},
|
|
62
|
-
defaultVariants: { variant: "primary" },
|
|
205
|
+
defaultVariants: { appearance: "solid", variant: "primary" },
|
|
63
206
|
}
|
|
64
207
|
);
|
|
65
208
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
defaultVariants: { variant: "primary" },
|
|
77
|
-
});
|
|
209
|
+
/** Solid title/description colors — web inherits from the root; RN Text does not. */
|
|
210
|
+
const toastSolidTextClassName: Record<ToastSolidVariant, string> = {
|
|
211
|
+
primary: "text-primary-foreground",
|
|
212
|
+
secondary: "text-secondary-foreground",
|
|
213
|
+
success: "text-feedback-success-foreground",
|
|
214
|
+
warning: "text-feedback-warning-foreground",
|
|
215
|
+
error: "text-feedback-error-foreground",
|
|
216
|
+
};
|
|
78
217
|
|
|
79
|
-
|
|
218
|
+
/** Soft fills for solid icons — approximates web `fill-*-background-soft` on SVG. */
|
|
219
|
+
const toastIconSoftFillClassName: Record<ToastSolidVariant, string> = {
|
|
220
|
+
primary: "bg-primary-background-soft",
|
|
221
|
+
secondary: "bg-secondary-background-soft",
|
|
222
|
+
success: "bg-feedback-success-background-soft",
|
|
223
|
+
warning: "bg-feedback-warning-background-soft",
|
|
224
|
+
error: "bg-feedback-error-background-soft",
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const toastActionButtonVariantMap: Record<
|
|
228
|
+
ToastActionVariant,
|
|
229
|
+
ButtonProps["variant"]
|
|
230
|
+
> = {
|
|
80
231
|
primary: "regular-soft",
|
|
81
232
|
secondary: "emphasis-soft",
|
|
82
233
|
success: "success-soft",
|
|
83
234
|
warning: "warning-soft",
|
|
84
235
|
error: "error-soft",
|
|
236
|
+
"green-gradient": "regular-basic",
|
|
237
|
+
"gold-gradient": "regular-basic",
|
|
238
|
+
"silver-gradient": "regular-basic",
|
|
239
|
+
"bronze-gradient": "regular-basic",
|
|
85
240
|
};
|
|
86
241
|
|
|
87
242
|
const toastIconColorTokens: Record<ToastVariant, string> = {
|
|
@@ -90,6 +245,10 @@ const toastIconColorTokens: Record<ToastVariant, string> = {
|
|
|
90
245
|
success: "feedback-success-foreground",
|
|
91
246
|
warning: "feedback-warning-foreground",
|
|
92
247
|
error: "feedback-error-foreground",
|
|
248
|
+
"green-gradient": GRADIENT_STYLES["green-gradient"].iconToken,
|
|
249
|
+
"gold-gradient": GRADIENT_STYLES["gold-gradient"].iconToken,
|
|
250
|
+
"silver-gradient": GRADIENT_STYLES["silver-gradient"].iconToken,
|
|
251
|
+
"bronze-gradient": GRADIENT_STYLES["bronze-gradient"].iconToken,
|
|
93
252
|
};
|
|
94
253
|
|
|
95
254
|
const variantIcons = {
|
|
@@ -98,61 +257,190 @@ const variantIcons = {
|
|
|
98
257
|
success: CircleCheck,
|
|
99
258
|
warning: TriangleWarning,
|
|
100
259
|
error: OctagonWarning,
|
|
260
|
+
"green-gradient": Rocket,
|
|
261
|
+
"gold-gradient": Rocket,
|
|
262
|
+
"silver-gradient": Rocket,
|
|
263
|
+
"bronze-gradient": Rocket,
|
|
101
264
|
} as const;
|
|
102
265
|
|
|
266
|
+
const ACTION_SIZE_CLASSES: Record<"sm" | "md" | "lg" | "xl", string> = {
|
|
267
|
+
sm: "min-h-8 min-w-8 px-3 py-1",
|
|
268
|
+
md: "min-h-10 min-w-10 px-3.5 py-2",
|
|
269
|
+
lg: "min-h-12 min-w-12 px-4 py-3",
|
|
270
|
+
xl: "min-h-14 min-w-14 px-[18px] py-3.5",
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
const ACTION_TEXT_SIZE: Record<"sm" | "md" | "lg" | "xl", string> = {
|
|
274
|
+
sm: "text-xs",
|
|
275
|
+
md: "text-sm",
|
|
276
|
+
lg: "text-md",
|
|
277
|
+
xl: "text-lg",
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
const DEFAULT_TOAST_DURATION = 5000;
|
|
281
|
+
const TOAST_ENTER_MS = 300;
|
|
282
|
+
const TOAST_EXIT_MS = 400;
|
|
283
|
+
|
|
284
|
+
function ToastClose({
|
|
285
|
+
className,
|
|
286
|
+
onPress,
|
|
287
|
+
label = "Fechar",
|
|
288
|
+
variant: variantProp,
|
|
289
|
+
...props
|
|
290
|
+
}: ToastCloseProps) {
|
|
291
|
+
const { variant, onOpenChange } = useToastContext(variantProp);
|
|
292
|
+
const gradient = isGradientVariant(variant) ? GRADIENT_STYLES[variant] : null;
|
|
293
|
+
// Web solid close uses `regular-basic` → primary-foreground (not gray).
|
|
294
|
+
const closeIconColor = useThemeColor(
|
|
295
|
+
gradient ? gradient.iconToken : "primary-foreground"
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
return (
|
|
299
|
+
<Button
|
|
300
|
+
onPress={onPress ?? (() => onOpenChange?.(false))}
|
|
301
|
+
accessibilityLabel={label}
|
|
302
|
+
size="sm"
|
|
303
|
+
variant="regular-basic"
|
|
304
|
+
iconLeft={
|
|
305
|
+
closeIconColor ? (
|
|
306
|
+
<CloseMd width={16} height={16} color={closeIconColor} />
|
|
307
|
+
) : undefined
|
|
308
|
+
}
|
|
309
|
+
className={cn(
|
|
310
|
+
"shrink-0",
|
|
311
|
+
// Match web `gradientActionClassName` (fixed text + pressed bg on gradients).
|
|
312
|
+
gradient?.textClassName,
|
|
313
|
+
gradient?.pressedClassName,
|
|
314
|
+
className
|
|
315
|
+
)}
|
|
316
|
+
{...props}
|
|
317
|
+
/>
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function ToastGradientFill({ variant }: { variant: ToastGradientVariant }) {
|
|
322
|
+
const style = GRADIENT_STYLES[variant];
|
|
323
|
+
const LinearGradient = loadLinearGradient();
|
|
324
|
+
const borderRadius = useRadiusLg();
|
|
325
|
+
const color0 = useThemeColor(style.colorTokens[0]);
|
|
326
|
+
const color1 = useThemeColor(style.colorTokens[1]);
|
|
327
|
+
const { start, end } = cssAngleToPoints(style.angleDeg);
|
|
328
|
+
|
|
329
|
+
if (!LinearGradient || !color0 || !color1) {
|
|
330
|
+
return (
|
|
331
|
+
<View
|
|
332
|
+
pointerEvents="none"
|
|
333
|
+
className={style.solidFallbackClassName}
|
|
334
|
+
style={[StyleSheet.absoluteFill, { borderRadius }]}
|
|
335
|
+
/>
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return (
|
|
340
|
+
<>
|
|
341
|
+
{style.underlayClassName ? (
|
|
342
|
+
<View
|
|
343
|
+
pointerEvents="none"
|
|
344
|
+
className={style.underlayClassName}
|
|
345
|
+
style={[StyleSheet.absoluteFill, { borderRadius }]}
|
|
346
|
+
/>
|
|
347
|
+
) : null}
|
|
348
|
+
<LinearGradient
|
|
349
|
+
colors={[color0, color1]}
|
|
350
|
+
locations={style.locations}
|
|
351
|
+
start={start}
|
|
352
|
+
end={end}
|
|
353
|
+
pointerEvents="none"
|
|
354
|
+
style={[StyleSheet.absoluteFill, { borderRadius }]}
|
|
355
|
+
/>
|
|
356
|
+
</>
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function ToastDefaultIcon({ variant }: { variant: ToastVariant }) {
|
|
361
|
+
const IconComponent = variantIcons[variant];
|
|
362
|
+
const iconColor = useThemeColor(toastIconColorTokens[variant]);
|
|
363
|
+
if (!iconColor) return null;
|
|
364
|
+
|
|
365
|
+
const softFill = !isGradientVariant(variant)
|
|
366
|
+
? toastIconSoftFillClassName[variant]
|
|
367
|
+
: null;
|
|
368
|
+
|
|
369
|
+
return (
|
|
370
|
+
<View className="size-6 shrink-0 items-center justify-center">
|
|
371
|
+
{softFill ? (
|
|
372
|
+
<View
|
|
373
|
+
className={cn("absolute h-[18px] w-[18px] rounded-full", softFill)}
|
|
374
|
+
/>
|
|
375
|
+
) : null}
|
|
376
|
+
<IconComponent width={24} height={24} color={iconColor} />
|
|
377
|
+
</View>
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
|
|
103
381
|
function ToastItem({
|
|
104
382
|
className,
|
|
105
383
|
variant = "primary",
|
|
106
384
|
showIcon = true,
|
|
385
|
+
duration = DEFAULT_TOAST_DURATION,
|
|
107
386
|
open = true,
|
|
108
387
|
onOpenChange,
|
|
388
|
+
icon,
|
|
109
389
|
children,
|
|
110
390
|
...props
|
|
111
391
|
}: ToastProps) {
|
|
112
392
|
const [visible, setVisible] = useState(open);
|
|
393
|
+
const onOpenChangeRef = useRef(onOpenChange);
|
|
394
|
+
onOpenChangeRef.current = onOpenChange;
|
|
113
395
|
const translateY = useSharedValue(open ? 0 : -80);
|
|
114
396
|
const opacity = useSharedValue(open ? 1 : 0);
|
|
397
|
+
const gradient = isGradientVariant(variant);
|
|
115
398
|
|
|
116
399
|
const animatedStyle = useAnimatedStyle(() => ({
|
|
117
400
|
transform: [{ translateY: translateY.value }],
|
|
118
401
|
opacity: opacity.value,
|
|
119
402
|
}));
|
|
120
|
-
const iconColor = useThemeColor(toastIconColorTokens[variant]);
|
|
121
|
-
const closeIconColor = useThemeColor("gray-foreground");
|
|
122
403
|
|
|
123
404
|
useEffect(() => {
|
|
124
405
|
if (open) {
|
|
125
406
|
setVisible(true);
|
|
126
|
-
translateY.value = withTiming(0, { duration:
|
|
127
|
-
opacity.value = withTiming(1, { duration:
|
|
407
|
+
translateY.value = withTiming(0, { duration: TOAST_ENTER_MS });
|
|
408
|
+
opacity.value = withTiming(1, { duration: TOAST_ENTER_MS });
|
|
128
409
|
} else {
|
|
129
|
-
translateY.value =
|
|
130
|
-
opacity.value = withTiming(0, { duration:
|
|
410
|
+
translateY.value = withTiming(-80, { duration: TOAST_EXIT_MS });
|
|
411
|
+
opacity.value = withTiming(0, { duration: TOAST_EXIT_MS }, (finished) => {
|
|
131
412
|
if (finished) runOnJS(setVisible)(false);
|
|
132
413
|
});
|
|
133
414
|
}
|
|
134
415
|
}, [open]);
|
|
135
416
|
|
|
417
|
+
useEffect(() => {
|
|
418
|
+
if (!open || !Number.isFinite(duration) || duration <= 0) return;
|
|
419
|
+
|
|
420
|
+
const timeout = setTimeout(() => onOpenChangeRef.current?.(false), duration);
|
|
421
|
+
return () => clearTimeout(timeout);
|
|
422
|
+
}, [open, duration]);
|
|
423
|
+
|
|
136
424
|
if (!visible) return null;
|
|
137
425
|
|
|
138
|
-
const
|
|
426
|
+
const resolvedIcon = icon ?? <ToastDefaultIcon variant={variant} />;
|
|
427
|
+
const appearance = gradient ? "gradient" : "solid";
|
|
428
|
+
const containerClassName = cn(
|
|
429
|
+
toastVariants({ appearance, variant }),
|
|
430
|
+
className
|
|
431
|
+
);
|
|
139
432
|
|
|
140
433
|
return (
|
|
141
434
|
<Animated.View style={animatedStyle}>
|
|
142
|
-
<
|
|
143
|
-
{
|
|
144
|
-
<
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
435
|
+
<ToastContext.Provider value={{ variant, onOpenChange }}>
|
|
436
|
+
<View className={containerClassName} {...props}>
|
|
437
|
+
{gradient ? <ToastGradientFill variant={variant} /> : null}
|
|
438
|
+
{showIcon && resolvedIcon}
|
|
439
|
+
<View className="min-w-0 flex-1 flex-row items-center justify-between gap-4">
|
|
440
|
+
{children}
|
|
441
|
+
</View>
|
|
148
442
|
</View>
|
|
149
|
-
|
|
150
|
-
onPress={() => onOpenChange?.(false)}
|
|
151
|
-
className="rounded-pill p-1 active:bg-gray-background-soft"
|
|
152
|
-
>
|
|
153
|
-
{closeIconColor && <CloseMd width={16} height={16} color={closeIconColor} />}
|
|
154
|
-
</Pressable>
|
|
155
|
-
</View>
|
|
443
|
+
</ToastContext.Provider>
|
|
156
444
|
</Animated.View>
|
|
157
445
|
);
|
|
158
446
|
}
|
|
@@ -163,6 +451,7 @@ function Toast({
|
|
|
163
451
|
duration,
|
|
164
452
|
open,
|
|
165
453
|
onOpenChange,
|
|
454
|
+
icon,
|
|
166
455
|
children,
|
|
167
456
|
...props
|
|
168
457
|
}: ToastProps) {
|
|
@@ -173,6 +462,7 @@ function Toast({
|
|
|
173
462
|
duration={duration}
|
|
174
463
|
open={open}
|
|
175
464
|
onOpenChange={onOpenChange}
|
|
465
|
+
icon={icon}
|
|
176
466
|
{...props}
|
|
177
467
|
>
|
|
178
468
|
{children}
|
|
@@ -182,17 +472,73 @@ function Toast({
|
|
|
182
472
|
|
|
183
473
|
function ToastAction({
|
|
184
474
|
className,
|
|
185
|
-
variant
|
|
475
|
+
variant: variantProp,
|
|
186
476
|
size = "sm",
|
|
187
|
-
altText,
|
|
477
|
+
altText = "Toast action",
|
|
188
478
|
children,
|
|
479
|
+
loading,
|
|
480
|
+
iconLeft,
|
|
481
|
+
iconRight,
|
|
482
|
+
disabled,
|
|
483
|
+
containerStyle: _containerStyle,
|
|
484
|
+
badge: _badge,
|
|
485
|
+
alert: _alert,
|
|
189
486
|
...props
|
|
190
487
|
}: ToastActionProps) {
|
|
488
|
+
const { variant } = useToastContext(variantProp);
|
|
489
|
+
const resolvedSize = size ?? "sm";
|
|
490
|
+
|
|
491
|
+
if (isGradientVariant(variant)) {
|
|
492
|
+
const gradient = GRADIENT_STYLES[variant];
|
|
493
|
+
const isDisabled = Boolean(disabled || loading);
|
|
494
|
+
|
|
495
|
+
return (
|
|
496
|
+
<Pressable
|
|
497
|
+
accessibilityLabel={altText}
|
|
498
|
+
accessibilityRole="button"
|
|
499
|
+
accessibilityState={{ disabled: isDisabled, busy: Boolean(loading) }}
|
|
500
|
+
disabled={isDisabled}
|
|
501
|
+
className={cn(
|
|
502
|
+
"flex-row items-center justify-center gap-2 rounded-pill",
|
|
503
|
+
ACTION_SIZE_CLASSES[resolvedSize],
|
|
504
|
+
gradient.pressedClassName,
|
|
505
|
+
className
|
|
506
|
+
)}
|
|
507
|
+
{...props}
|
|
508
|
+
>
|
|
509
|
+
{loading ? (
|
|
510
|
+
<Loading size={resolvedSize === "sm" ? 16 : 20} />
|
|
511
|
+
) : (
|
|
512
|
+
<>
|
|
513
|
+
{iconLeft}
|
|
514
|
+
{children != null && (
|
|
515
|
+
<Text
|
|
516
|
+
className={cn(
|
|
517
|
+
"font-semibold shrink-0",
|
|
518
|
+
ACTION_TEXT_SIZE[resolvedSize],
|
|
519
|
+
gradient.textClassName
|
|
520
|
+
)}
|
|
521
|
+
>
|
|
522
|
+
{children as ReactNode}
|
|
523
|
+
</Text>
|
|
524
|
+
)}
|
|
525
|
+
{iconRight}
|
|
526
|
+
</>
|
|
527
|
+
)}
|
|
528
|
+
</Pressable>
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
|
|
191
532
|
return (
|
|
192
533
|
<Button
|
|
193
534
|
size={size}
|
|
194
535
|
variant={toastActionButtonVariantMap[variant]}
|
|
195
536
|
className={cn(className)}
|
|
537
|
+
loading={loading}
|
|
538
|
+
iconLeft={iconLeft}
|
|
539
|
+
iconRight={iconRight}
|
|
540
|
+
disabled={disabled}
|
|
541
|
+
accessibilityLabel={altText}
|
|
196
542
|
{...props}
|
|
197
543
|
>
|
|
198
544
|
{children as ReactNode}
|
|
@@ -200,27 +546,53 @@ function ToastAction({
|
|
|
200
546
|
);
|
|
201
547
|
}
|
|
202
548
|
|
|
203
|
-
function ToastTitle({
|
|
549
|
+
function ToastTitle({
|
|
550
|
+
className,
|
|
551
|
+
children,
|
|
552
|
+
}: ViewProps & { children?: ReactNode }) {
|
|
553
|
+
const { variant } = useToastContext();
|
|
554
|
+
const textClassName = isGradientVariant(variant)
|
|
555
|
+
? GRADIENT_STYLES[variant].textClassName
|
|
556
|
+
: toastSolidTextClassName[variant];
|
|
557
|
+
|
|
204
558
|
return (
|
|
205
|
-
<Text
|
|
559
|
+
<Text
|
|
560
|
+
className={cn("text-md font-semibold flex-1", textClassName, className)}
|
|
561
|
+
>
|
|
206
562
|
{children}
|
|
207
563
|
</Text>
|
|
208
564
|
);
|
|
209
565
|
}
|
|
210
566
|
|
|
211
|
-
function ToastDescription({
|
|
567
|
+
function ToastDescription({
|
|
568
|
+
className,
|
|
569
|
+
children,
|
|
570
|
+
}: ViewProps & { children?: ReactNode }) {
|
|
571
|
+
const { variant } = useToastContext();
|
|
572
|
+
const textClassName = isGradientVariant(variant)
|
|
573
|
+
? GRADIENT_STYLES[variant].textClassName
|
|
574
|
+
: toastSolidTextClassName[variant];
|
|
575
|
+
|
|
212
576
|
return (
|
|
213
|
-
<Text className={cn("text-xs
|
|
577
|
+
<Text className={cn("text-xs font-medium", textClassName, className)}>
|
|
214
578
|
{children}
|
|
215
579
|
</Text>
|
|
216
580
|
);
|
|
217
581
|
}
|
|
218
582
|
|
|
219
|
-
|
|
583
|
+
const TOAST_VIEWPORT_EXTRA_TOP_GAP = 8;
|
|
584
|
+
/** Matches previous `pt-12` (48) when SafeAreaProvider is absent: 40 + 8. */
|
|
585
|
+
const TOAST_VIEWPORT_FALLBACK_TOP = 40;
|
|
586
|
+
|
|
587
|
+
function ToastViewport({
|
|
588
|
+
className,
|
|
589
|
+
children,
|
|
590
|
+
...props
|
|
591
|
+
}: ViewProps & { children?: ReactNode }) {
|
|
220
592
|
return (
|
|
221
593
|
<View
|
|
222
594
|
pointerEvents="box-none"
|
|
223
|
-
className={cn("absolute top-0 left-0 right-0 z-50 px-4
|
|
595
|
+
className={cn("absolute top-0 left-0 right-0 z-50 px-4 gap-2", className)}
|
|
224
596
|
{...props}
|
|
225
597
|
>
|
|
226
598
|
{children}
|
|
@@ -228,41 +600,62 @@ function ToastViewport({ className, children, ...props }: ViewProps & { children
|
|
|
228
600
|
);
|
|
229
601
|
}
|
|
230
602
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
accessibilityLabel={label}
|
|
238
|
-
className={cn("rounded-pill p-1 active:bg-gray-background-soft", className)}
|
|
239
|
-
{...props}
|
|
240
|
-
>
|
|
241
|
-
{closeIconColor && <CloseMd width={16} height={16} color={closeIconColor} />}
|
|
242
|
-
</Pressable>
|
|
243
|
-
);
|
|
244
|
-
}
|
|
603
|
+
type ToastProviderProps = {
|
|
604
|
+
/** Extra gap below the top safe-area inset (default: 8). */
|
|
605
|
+
topOffset?: number;
|
|
606
|
+
style?: StyleProp<ViewStyle>;
|
|
607
|
+
className?: string;
|
|
608
|
+
};
|
|
245
609
|
|
|
246
|
-
function ToastProvider(
|
|
610
|
+
function ToastProvider({
|
|
611
|
+
topOffset = TOAST_VIEWPORT_EXTRA_TOP_GAP,
|
|
612
|
+
style,
|
|
613
|
+
className,
|
|
614
|
+
}: ToastProviderProps = {}) {
|
|
247
615
|
const { toasts, dismiss } = useToast();
|
|
616
|
+
// Soft read: does not throw without SafeAreaProvider (keeps prior pt-12 fallback).
|
|
617
|
+
const insets = useContext(SafeAreaInsetsContext);
|
|
618
|
+
const paddingTop = (insets?.top ?? TOAST_VIEWPORT_FALLBACK_TOP) + topOffset;
|
|
248
619
|
|
|
249
620
|
return (
|
|
250
|
-
<ToastViewport
|
|
251
|
-
{
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
621
|
+
<ToastViewport
|
|
622
|
+
className={className}
|
|
623
|
+
style={[{ paddingTop }, style]}
|
|
624
|
+
>
|
|
625
|
+
{toasts.map(
|
|
626
|
+
({
|
|
627
|
+
id,
|
|
628
|
+
title,
|
|
629
|
+
description,
|
|
630
|
+
action,
|
|
631
|
+
open = true,
|
|
632
|
+
variant = "primary",
|
|
633
|
+
showIcon,
|
|
634
|
+
icon,
|
|
635
|
+
duration,
|
|
636
|
+
}) => (
|
|
637
|
+
<Toast
|
|
638
|
+
key={id}
|
|
639
|
+
variant={variant}
|
|
640
|
+
showIcon={showIcon}
|
|
641
|
+
icon={icon}
|
|
642
|
+
duration={duration}
|
|
643
|
+
open={open}
|
|
644
|
+
onOpenChange={(isOpen) => !isOpen && dismiss(id)}
|
|
645
|
+
>
|
|
646
|
+
<View className="min-w-0 flex-1 flex-col">
|
|
647
|
+
{title && <ToastTitle>{title}</ToastTitle>}
|
|
648
|
+
{description && (
|
|
649
|
+
<ToastDescription>{description}</ToastDescription>
|
|
650
|
+
)}
|
|
651
|
+
</View>
|
|
652
|
+
<View className="flex-row items-center gap-2">
|
|
653
|
+
{action}
|
|
654
|
+
<ToastClose variant={variant} />
|
|
655
|
+
</View>
|
|
656
|
+
</Toast>
|
|
657
|
+
)
|
|
658
|
+
)}
|
|
266
659
|
</ToastViewport>
|
|
267
660
|
);
|
|
268
661
|
}
|
|
@@ -277,4 +670,13 @@ export {
|
|
|
277
670
|
ToastViewport,
|
|
278
671
|
toastVariants,
|
|
279
672
|
};
|
|
280
|
-
export type {
|
|
673
|
+
export type {
|
|
674
|
+
ToastActionElement,
|
|
675
|
+
ToastActionProps,
|
|
676
|
+
ToastActionVariant,
|
|
677
|
+
ToastCloseProps,
|
|
678
|
+
ToastGradientVariant,
|
|
679
|
+
ToastProps,
|
|
680
|
+
ToastProviderProps,
|
|
681
|
+
ToastVariant,
|
|
682
|
+
};
|