@campxdev/react-native-blueprint 0.1.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.
Files changed (178) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +358 -0
  3. package/lib/module/app/_layout.js +23 -0
  4. package/lib/module/app/_layout.js.map +1 -0
  5. package/lib/module/assets/icons/weather_icons/drizzle.png +0 -0
  6. package/lib/module/assets/icons/weather_icons/foggy.png +0 -0
  7. package/lib/module/assets/icons/weather_icons/freezing_rain.png +0 -0
  8. package/lib/module/assets/icons/weather_icons/partly_cloudy.png +0 -0
  9. package/lib/module/assets/icons/weather_icons/rainy.png +0 -0
  10. package/lib/module/assets/icons/weather_icons/showers.png +0 -0
  11. package/lib/module/assets/icons/weather_icons/sunny_weather.png +0 -0
  12. package/lib/module/assets/icons/weather_icons/thunderstorm.png +0 -0
  13. package/lib/module/assets/icons/weather_icons/thunderstorm_hail.png +0 -0
  14. package/lib/module/components/theme-config.js +265 -0
  15. package/lib/module/components/theme-config.js.map +1 -0
  16. package/lib/module/components/ui/Accordion.js +228 -0
  17. package/lib/module/components/ui/Accordion.js.map +1 -0
  18. package/lib/module/components/ui/Alert-Dialog.js +266 -0
  19. package/lib/module/components/ui/Alert-Dialog.js.map +1 -0
  20. package/lib/module/components/ui/Alert.js +107 -0
  21. package/lib/module/components/ui/Alert.js.map +1 -0
  22. package/lib/module/components/ui/AppBar.js +403 -0
  23. package/lib/module/components/ui/AppBar.js.map +1 -0
  24. package/lib/module/components/ui/Aspect-Ratio.js +27 -0
  25. package/lib/module/components/ui/Aspect-Ratio.js.map +1 -0
  26. package/lib/module/components/ui/Avatar.js +97 -0
  27. package/lib/module/components/ui/Avatar.js.map +1 -0
  28. package/lib/module/components/ui/Badge.js +127 -0
  29. package/lib/module/components/ui/Badge.js.map +1 -0
  30. package/lib/module/components/ui/Bottom-Sheet.js +144 -0
  31. package/lib/module/components/ui/Bottom-Sheet.js.map +1 -0
  32. package/lib/module/components/ui/Button.js +88 -0
  33. package/lib/module/components/ui/Button.js.map +1 -0
  34. package/lib/module/components/ui/Card.js +176 -0
  35. package/lib/module/components/ui/Card.js.map +1 -0
  36. package/lib/module/components/ui/Checkbox.js +65 -0
  37. package/lib/module/components/ui/Checkbox.js.map +1 -0
  38. package/lib/module/components/ui/Collapsible.js +42 -0
  39. package/lib/module/components/ui/Collapsible.js.map +1 -0
  40. package/lib/module/components/ui/Context-Menu.js +287 -0
  41. package/lib/module/components/ui/Context-Menu.js.map +1 -0
  42. package/lib/module/components/ui/Custom-Card.js +202 -0
  43. package/lib/module/components/ui/Custom-Card.js.map +1 -0
  44. package/lib/module/components/ui/Dialog.js +202 -0
  45. package/lib/module/components/ui/Dialog.js.map +1 -0
  46. package/lib/module/components/ui/Dropdown-Menu.js +421 -0
  47. package/lib/module/components/ui/Dropdown-Menu.js.map +1 -0
  48. package/lib/module/components/ui/Floating-Action.js +50 -0
  49. package/lib/module/components/ui/Floating-Action.js.map +1 -0
  50. package/lib/module/components/ui/Greeting-Card.js +392 -0
  51. package/lib/module/components/ui/Greeting-Card.js.map +1 -0
  52. package/lib/module/components/ui/Hover-Card.js +96 -0
  53. package/lib/module/components/ui/Hover-Card.js.map +1 -0
  54. package/lib/module/components/ui/Icon.js +73 -0
  55. package/lib/module/components/ui/Icon.js.map +1 -0
  56. package/lib/module/components/ui/Input.js +74 -0
  57. package/lib/module/components/ui/Input.js.map +1 -0
  58. package/lib/module/components/ui/Label.js +44 -0
  59. package/lib/module/components/ui/Label.js.map +1 -0
  60. package/lib/module/components/ui/Menubar.js +375 -0
  61. package/lib/module/components/ui/Menubar.js.map +1 -0
  62. package/lib/module/components/ui/Native-Only-Animated-View.js +41 -0
  63. package/lib/module/components/ui/Native-Only-Animated-View.js.map +1 -0
  64. package/lib/module/components/ui/NavBar.js +352 -0
  65. package/lib/module/components/ui/NavBar.js.map +1 -0
  66. package/lib/module/components/ui/Popover.js +101 -0
  67. package/lib/module/components/ui/Popover.js.map +1 -0
  68. package/lib/module/components/ui/Progress.js +124 -0
  69. package/lib/module/components/ui/Progress.js.map +1 -0
  70. package/lib/module/components/ui/Radio-Group.js +75 -0
  71. package/lib/module/components/ui/Radio-Group.js.map +1 -0
  72. package/lib/module/components/ui/Select.js +269 -0
  73. package/lib/module/components/ui/Select.js.map +1 -0
  74. package/lib/module/components/ui/Separator.js +58 -0
  75. package/lib/module/components/ui/Separator.js.map +1 -0
  76. package/lib/module/components/ui/SizedBox.js +101 -0
  77. package/lib/module/components/ui/SizedBox.js.map +1 -0
  78. package/lib/module/components/ui/Skeleton.js +57 -0
  79. package/lib/module/components/ui/Skeleton.js.map +1 -0
  80. package/lib/module/components/ui/Slider.js +169 -0
  81. package/lib/module/components/ui/Slider.js.map +1 -0
  82. package/lib/module/components/ui/Switch.js +55 -0
  83. package/lib/module/components/ui/Switch.js.map +1 -0
  84. package/lib/module/components/ui/Table.js +150 -0
  85. package/lib/module/components/ui/Table.js.map +1 -0
  86. package/lib/module/components/ui/Tabs.js +106 -0
  87. package/lib/module/components/ui/Tabs.js.map +1 -0
  88. package/lib/module/components/ui/Text.js +69 -0
  89. package/lib/module/components/ui/Text.js.map +1 -0
  90. package/lib/module/components/ui/Textarea.js +88 -0
  91. package/lib/module/components/ui/Textarea.js.map +1 -0
  92. package/lib/module/components/ui/Theme-Toggle.js +156 -0
  93. package/lib/module/components/ui/Theme-Toggle.js.map +1 -0
  94. package/lib/module/components/ui/Toast.js +101 -0
  95. package/lib/module/components/ui/Toast.js.map +1 -0
  96. package/lib/module/components/ui/Toggle-Group.js +129 -0
  97. package/lib/module/components/ui/Toggle-Group.js.map +1 -0
  98. package/lib/module/components/ui/Toggle.js +106 -0
  99. package/lib/module/components/ui/Toggle.js.map +1 -0
  100. package/lib/module/components/ui/Tooltip.js +106 -0
  101. package/lib/module/components/ui/Tooltip.js.map +1 -0
  102. package/lib/module/components/ui/index.js +45 -0
  103. package/lib/module/components/ui/index.js.map +1 -0
  104. package/lib/module/index.js +19 -0
  105. package/lib/module/index.js.map +1 -0
  106. package/lib/module/lib/ThemeProvider.js +173 -0
  107. package/lib/module/lib/ThemeProvider.js.map +1 -0
  108. package/lib/module/lib/cornerRadius.js +164 -0
  109. package/lib/module/lib/cornerRadius.js.map +1 -0
  110. package/lib/module/lib/fonts.js +25 -0
  111. package/lib/module/lib/fonts.js.map +1 -0
  112. package/lib/module/lib/theme.js +212 -0
  113. package/lib/module/lib/theme.js.map +1 -0
  114. package/lib/module/lib/utils.js +137 -0
  115. package/lib/module/lib/utils.js.map +1 -0
  116. package/lib/module/package.json +1 -0
  117. package/package.json +208 -0
  118. package/src/app/_layout.tsx +25 -0
  119. package/src/assets/icons/weather_icons/drizzle.png +0 -0
  120. package/src/assets/icons/weather_icons/foggy.png +0 -0
  121. package/src/assets/icons/weather_icons/freezing_rain.png +0 -0
  122. package/src/assets/icons/weather_icons/partly_cloudy.png +0 -0
  123. package/src/assets/icons/weather_icons/rainy.png +0 -0
  124. package/src/assets/icons/weather_icons/showers.png +0 -0
  125. package/src/assets/icons/weather_icons/sunny_weather.png +0 -0
  126. package/src/assets/icons/weather_icons/thunderstorm.png +0 -0
  127. package/src/assets/icons/weather_icons/thunderstorm_hail.png +0 -0
  128. package/src/components/theme-config.ts +331 -0
  129. package/src/components/ui/Accordion.tsx +253 -0
  130. package/src/components/ui/Alert-Dialog.tsx +295 -0
  131. package/src/components/ui/Alert.tsx +137 -0
  132. package/src/components/ui/AppBar.tsx +551 -0
  133. package/src/components/ui/Aspect-Ratio.tsx +25 -0
  134. package/src/components/ui/Avatar.tsx +103 -0
  135. package/src/components/ui/Badge.tsx +121 -0
  136. package/src/components/ui/Bottom-Sheet.tsx +224 -0
  137. package/src/components/ui/Button.tsx +100 -0
  138. package/src/components/ui/Card.tsx +185 -0
  139. package/src/components/ui/Checkbox.tsx +81 -0
  140. package/src/components/ui/Collapsible.tsx +40 -0
  141. package/src/components/ui/Context-Menu.tsx +407 -0
  142. package/src/components/ui/Custom-Card.tsx +226 -0
  143. package/src/components/ui/Dialog.tsx +240 -0
  144. package/src/components/ui/Dropdown-Menu.tsx +544 -0
  145. package/src/components/ui/Floating-Action.tsx +54 -0
  146. package/src/components/ui/Greeting-Card.tsx +471 -0
  147. package/src/components/ui/Hover-Card.tsx +101 -0
  148. package/src/components/ui/Icon.tsx +75 -0
  149. package/src/components/ui/Input.tsx +90 -0
  150. package/src/components/ui/Label.tsx +48 -0
  151. package/src/components/ui/Menubar.tsx +509 -0
  152. package/src/components/ui/Native-Only-Animated-View.tsx +37 -0
  153. package/src/components/ui/NavBar.tsx +397 -0
  154. package/src/components/ui/Popover.tsx +110 -0
  155. package/src/components/ui/Progress.tsx +138 -0
  156. package/src/components/ui/Radio-Group.tsx +79 -0
  157. package/src/components/ui/Select.tsx +344 -0
  158. package/src/components/ui/Separator.tsx +68 -0
  159. package/src/components/ui/SizedBox.tsx +116 -0
  160. package/src/components/ui/Skeleton.tsx +55 -0
  161. package/src/components/ui/Slider.tsx +222 -0
  162. package/src/components/ui/Switch.tsx +67 -0
  163. package/src/components/ui/Table.tsx +170 -0
  164. package/src/components/ui/Tabs.tsx +119 -0
  165. package/src/components/ui/Text.tsx +73 -0
  166. package/src/components/ui/Textarea.tsx +93 -0
  167. package/src/components/ui/Theme-Toggle.tsx +204 -0
  168. package/src/components/ui/Toast.tsx +127 -0
  169. package/src/components/ui/Toggle-Group.tsx +160 -0
  170. package/src/components/ui/Toggle.tsx +122 -0
  171. package/src/components/ui/Tooltip.tsx +117 -0
  172. package/src/components/ui/index.ts +42 -0
  173. package/src/index.tsx +24 -0
  174. package/src/lib/ThemeProvider.tsx +204 -0
  175. package/src/lib/cornerRadius.ts +160 -0
  176. package/src/lib/fonts.ts +28 -0
  177. package/src/lib/theme.ts +151 -0
  178. package/src/lib/utils.ts +146 -0
@@ -0,0 +1,295 @@
1
+ import { buttonTextVariants, buttonVariants } from './Button';
2
+ import { NativeOnlyAnimatedView } from './Native-Only-Animated-View';
3
+ import { TextClassContext } from './Text';
4
+ import { cn } from '../../lib/utils';
5
+ import * as AlertDialogPrimitive from '@rn-primitives/alert-dialog';
6
+ import * as React from 'react';
7
+ import { Platform, View, type ViewProps } from 'react-native';
8
+ import { cssInterop } from 'nativewind';
9
+ import { FadeIn, FadeOut } from 'react-native-reanimated';
10
+ import { FullWindowOverlay as RNFullWindowOverlay } from 'react-native-screens';
11
+
12
+ cssInterop(View, { className: 'style' });
13
+
14
+ /**
15
+ * Root alert dialog container
16
+ *
17
+ * A modal dialog that interrupts the user with important content and expects a response.
18
+ * Use for critical actions that require user confirmation before proceeding.
19
+ *
20
+ * @component
21
+ * @example
22
+ * ```tsx
23
+ * <AlertDialog>
24
+ * <AlertDialogTrigger asChild>
25
+ * <Button variant="destructive"><Text>Delete Account</Text></Button>
26
+ * </AlertDialogTrigger>
27
+ * <AlertDialogContent>
28
+ * <AlertDialogHeader>
29
+ * <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
30
+ * <AlertDialogDescription>
31
+ * This action cannot be undone.
32
+ * </AlertDialogDescription>
33
+ * </AlertDialogHeader>
34
+ * <AlertDialogFooter>
35
+ * <AlertDialogCancel><Text>Cancel</Text></AlertDialogCancel>
36
+ * <AlertDialogAction><Text>Continue</Text></AlertDialogAction>
37
+ * </AlertDialogFooter>
38
+ * </AlertDialogContent>
39
+ * </AlertDialog>
40
+ * ```
41
+ *
42
+ * @accessibility
43
+ * - Traps focus within dialog when open
44
+ * - Closes on Escape key press
45
+ * - Returns focus to trigger on close
46
+ * - Uses appropriate ARIA attributes
47
+ */
48
+ const AlertDialog = AlertDialogPrimitive.Root;
49
+
50
+ /**
51
+ * Trigger button that opens the alert dialog
52
+ *
53
+ * @component
54
+ * @example
55
+ * ```tsx
56
+ * <AlertDialogTrigger asChild>
57
+ * <Button><Text>Open Dialog</Text></Button>
58
+ * </AlertDialogTrigger>
59
+ * ```
60
+ */
61
+ const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
62
+
63
+ /**
64
+ * Portal component for rendering dialog content outside the DOM hierarchy
65
+ */
66
+ const AlertDialogPortal = AlertDialogPrimitive.Portal;
67
+
68
+ const FullWindowOverlay =
69
+ Platform.OS === 'ios' ? RNFullWindowOverlay : React.Fragment;
70
+
71
+ /**
72
+ * Semi-transparent overlay behind the alert dialog
73
+ *
74
+ * Provides backdrop that dims background content and handles click-outside behavior.
75
+ * Uses platform-specific full window overlay on iOS for proper z-index layering.
76
+ *
77
+ * @component
78
+ * @example
79
+ * ```tsx
80
+ * <AlertDialogOverlay>
81
+ * <AlertDialogContent>...</AlertDialogContent>
82
+ * </AlertDialogOverlay>
83
+ * ```
84
+ */
85
+ function AlertDialogOverlay({
86
+ className,
87
+ children,
88
+ ...props
89
+ }: Omit<AlertDialogPrimitive.OverlayProps, 'asChild'> &
90
+ React.RefAttributes<AlertDialogPrimitive.OverlayRef> & {
91
+ children?: React.ReactNode;
92
+ }) {
93
+ return (
94
+ <FullWindowOverlay>
95
+ <AlertDialogPrimitive.Overlay
96
+ className={cn(
97
+ 'absolute bottom-0 left-0 right-0 top-0 z-50 flex items-center justify-center bg-black/50 p-2',
98
+ Platform.select({
99
+ web: 'animate-in fade-in-0 fixed',
100
+ }),
101
+ className
102
+ )}
103
+ {...props}
104
+ >
105
+ <NativeOnlyAnimatedView
106
+ entering={FadeIn.duration(200).delay(50)}
107
+ exiting={FadeOut.duration(150)}
108
+ >
109
+ <>{children}</>
110
+ </NativeOnlyAnimatedView>
111
+ </AlertDialogPrimitive.Overlay>
112
+ </FullWindowOverlay>
113
+ );
114
+ }
115
+
116
+ /**
117
+ * Main alert dialog content container
118
+ *
119
+ * Contains the dialog's title, description, and action buttons. Automatically centered
120
+ * on screen with smooth entrance animations.
121
+ *
122
+ * @component
123
+ * @example
124
+ * ```tsx
125
+ * <AlertDialogContent>
126
+ * <AlertDialogHeader>
127
+ * <AlertDialogTitle>Confirm Action</AlertDialogTitle>
128
+ * <AlertDialogDescription>Description here</AlertDialogDescription>
129
+ * </AlertDialogHeader>
130
+ * <AlertDialogFooter>
131
+ * <AlertDialogCancel><Text>Cancel</Text></AlertDialogCancel>
132
+ * <AlertDialogAction><Text>Continue</Text></AlertDialogAction>
133
+ * </AlertDialogFooter>
134
+ * </AlertDialogContent>
135
+ * ```
136
+ */
137
+ function AlertDialogContent({
138
+ className,
139
+ portalHost,
140
+ ...props
141
+ }: AlertDialogPrimitive.ContentProps &
142
+ React.RefAttributes<AlertDialogPrimitive.ContentRef> & {
143
+ portalHost?: string;
144
+ }) {
145
+ return (
146
+ <AlertDialogPortal hostName={portalHost}>
147
+ <AlertDialogOverlay>
148
+ <AlertDialogPrimitive.Content
149
+ className={cn(
150
+ 'bg-background border-border z-50 flex w-full max-w-[calc(100%-2rem)] flex-col gap-4 rounded-lg border p-6 shadow-lg shadow-black/5 sm:max-w-lg',
151
+ Platform.select({
152
+ web: 'animate-in fade-in-0 zoom-in-95 duration-200',
153
+ }),
154
+ className
155
+ )}
156
+ {...props}
157
+ />
158
+ </AlertDialogOverlay>
159
+ </AlertDialogPortal>
160
+ );
161
+ }
162
+
163
+ /**
164
+ * Header section for alert dialog content
165
+ *
166
+ * Groups the title and description with proper spacing and text alignment.
167
+ *
168
+ * @component
169
+ */
170
+ function AlertDialogHeader({ className, ...props }: ViewProps) {
171
+ return (
172
+ <TextClassContext.Provider value="text-center sm:text-left">
173
+ <View className={cn('flex flex-col gap-2', className)} {...props} />
174
+ </TextClassContext.Provider>
175
+ );
176
+ }
177
+
178
+ /**
179
+ * Footer section for alert dialog action buttons
180
+ *
181
+ * Contains cancel and action buttons with responsive layout (stacked on mobile, row on desktop).
182
+ *
183
+ * @component
184
+ */
185
+ function AlertDialogFooter({ className, ...props }: ViewProps) {
186
+ return (
187
+ <View
188
+ className={cn(
189
+ 'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',
190
+ className
191
+ )}
192
+ {...props}
193
+ />
194
+ );
195
+ }
196
+
197
+ /**
198
+ * Title text for the alert dialog
199
+ *
200
+ * Prominently displays the main heading with large, semibold text.
201
+ *
202
+ * @component
203
+ */
204
+ function AlertDialogTitle({
205
+ className,
206
+ ...props
207
+ }: AlertDialogPrimitive.TitleProps &
208
+ React.RefAttributes<AlertDialogPrimitive.TitleRef>) {
209
+ return (
210
+ <AlertDialogPrimitive.Title
211
+ className={cn('text-foreground text-lg font-semibold', className)}
212
+ {...props}
213
+ />
214
+ );
215
+ }
216
+
217
+ /**
218
+ * Description text for the alert dialog
219
+ *
220
+ * Provides additional context below the title with muted styling.
221
+ *
222
+ * @component
223
+ */
224
+ function AlertDialogDescription({
225
+ className,
226
+ ...props
227
+ }: AlertDialogPrimitive.DescriptionProps &
228
+ React.RefAttributes<AlertDialogPrimitive.DescriptionRef>) {
229
+ return (
230
+ <AlertDialogPrimitive.Description
231
+ className={cn('text-muted-foreground text-sm', className)}
232
+ {...props}
233
+ />
234
+ );
235
+ }
236
+
237
+ /**
238
+ * Primary action button that confirms the alert dialog action
239
+ *
240
+ * Styled as a primary button. Automatically closes dialog on press.
241
+ *
242
+ * @component
243
+ */
244
+ function AlertDialogAction({
245
+ className,
246
+ ...props
247
+ }: AlertDialogPrimitive.ActionProps &
248
+ React.RefAttributes<AlertDialogPrimitive.ActionRef>) {
249
+ return (
250
+ <TextClassContext.Provider value={buttonTextVariants({ className })}>
251
+ <AlertDialogPrimitive.Action
252
+ className={cn(buttonVariants(), className)}
253
+ {...props}
254
+ />
255
+ </TextClassContext.Provider>
256
+ );
257
+ }
258
+
259
+ /**
260
+ * Cancel button that dismisses the alert dialog
261
+ *
262
+ * Styled as an outline button. Automatically closes dialog on press without performing action.
263
+ *
264
+ * @component
265
+ */
266
+ function AlertDialogCancel({
267
+ className,
268
+ ...props
269
+ }: AlertDialogPrimitive.CancelProps &
270
+ React.RefAttributes<AlertDialogPrimitive.CancelRef>) {
271
+ return (
272
+ <TextClassContext.Provider
273
+ value={buttonTextVariants({ className, variant: 'outline' })}
274
+ >
275
+ <AlertDialogPrimitive.Cancel
276
+ className={cn(buttonVariants({ variant: 'outline' }), className)}
277
+ {...props}
278
+ />
279
+ </TextClassContext.Provider>
280
+ );
281
+ }
282
+
283
+ export {
284
+ AlertDialog,
285
+ AlertDialogAction,
286
+ AlertDialogCancel,
287
+ AlertDialogContent,
288
+ AlertDialogDescription,
289
+ AlertDialogFooter,
290
+ AlertDialogHeader,
291
+ AlertDialogOverlay,
292
+ AlertDialogPortal,
293
+ AlertDialogTitle,
294
+ AlertDialogTrigger,
295
+ };
@@ -0,0 +1,137 @@
1
+ import { Icon } from './Icon';
2
+ import { Text, TextClassContext } from './Text';
3
+ import { cn } from '../../lib/utils';
4
+ import type { LucideIcon } from 'lucide-react-native';
5
+ import * as React from 'react';
6
+ import { View, type ViewProps } from 'react-native';
7
+ import { cssInterop } from 'nativewind';
8
+
9
+ cssInterop(View, { className: 'style' });
10
+
11
+ /**
12
+ * Alert component for displaying important messages or notifications
13
+ *
14
+ * Features an icon on the left side with title and description.
15
+ * Supports default and destructive variants for different severity levels.
16
+ *
17
+ * @component
18
+ * @example
19
+ * ```tsx
20
+ * <Alert icon={AlertCircle} variant="default">
21
+ * <AlertTitle><Text>Heads up!</Text></AlertTitle>
22
+ * <AlertDescription>
23
+ * <Text>You can add components to your app using the cli.</Text>
24
+ * </AlertDescription>
25
+ * </Alert>
26
+ *
27
+ * // Destructive variant
28
+ * <Alert icon={AlertTriangle} variant="destructive">
29
+ * <AlertTitle><Text>Error</Text></AlertTitle>
30
+ * <AlertDescription>
31
+ * <Text>Your session has expired. Please login again.</Text>
32
+ * </AlertDescription>
33
+ * </Alert>
34
+ * ```
35
+ *
36
+ * @param {LucideIcon} icon - Icon component to display
37
+ * @param {'default' | 'destructive'} [variant='default'] - Alert style variant
38
+ * @param {string} [iconClassName] - Additional classes for the icon
39
+ * @param {string} [className] - Additional classes for the container
40
+ *
41
+ * @accessibility Sets role="alert" for screen reader announcement
42
+ */
43
+ function Alert({
44
+ className,
45
+ variant,
46
+ children,
47
+ icon,
48
+ iconClassName,
49
+ ...props
50
+ }: ViewProps &
51
+ React.RefAttributes<View> & {
52
+ icon: LucideIcon;
53
+ variant?: 'default' | 'destructive';
54
+ iconClassName?: string;
55
+ }) {
56
+ return (
57
+ <TextClassContext.Provider
58
+ value={cn(
59
+ 'text-sm text-foreground dark:text-foreground',
60
+ variant === 'destructive' && 'text-destructive dark:text-destructive',
61
+ className
62
+ )}
63
+ >
64
+ <View
65
+ role="alert"
66
+ className={cn(
67
+ 'bg-card dark:bg-card border-border dark:border-border relative w-full rounded-lg border px-4 pb-2 pt-3.5',
68
+ className
69
+ )}
70
+ {...props}
71
+ >
72
+ <View className="absolute left-3.5 top-3">
73
+ <Icon
74
+ as={icon}
75
+ className={cn(
76
+ 'size-4 text-foreground dark:text-foreground',
77
+ variant === 'destructive' &&
78
+ 'text-destructive dark:text-destructive',
79
+ iconClassName
80
+ )}
81
+ />
82
+ </View>
83
+ {children}
84
+ </View>
85
+ </TextClassContext.Provider>
86
+ );
87
+ }
88
+
89
+ /**
90
+ * AlertTitle - Title text for the alert
91
+ *
92
+ * Displays as a medium-weight heading with appropriate spacing from the icon.
93
+ *
94
+ * @param {string} [className] - Additional Tailwind classes
95
+ */
96
+ function AlertTitle({
97
+ className,
98
+ ...props
99
+ }: React.ComponentProps<typeof Text> & React.RefAttributes<Text>) {
100
+ return (
101
+ <Text
102
+ className={cn(
103
+ 'mb-1 ml-0.5 min-h-4 pl-6 font-medium leading-none tracking-tight',
104
+ className
105
+ )}
106
+ {...props}
107
+ />
108
+ );
109
+ }
110
+
111
+ /**
112
+ * AlertDescription - Description text for the alert
113
+ *
114
+ * Displays detailed message content with muted styling and appropriate spacing.
115
+ * Automatically adjusts color for destructive variants.
116
+ *
117
+ * @param {string} [className] - Additional Tailwind classes
118
+ */
119
+ function AlertDescription({
120
+ className,
121
+ ...props
122
+ }: React.ComponentProps<typeof Text> & React.RefAttributes<Text>) {
123
+ const textClass = React.useContext(TextClassContext);
124
+ return (
125
+ <Text
126
+ className={cn(
127
+ 'text-muted-foreground dark:text-muted-foreground ml-0.5 pb-1.5 pl-6 text-sm leading-relaxed',
128
+ textClass?.includes('text-destructive') &&
129
+ 'text-destructive/90 dark:text-destructive/90',
130
+ className
131
+ )}
132
+ {...props}
133
+ />
134
+ );
135
+ }
136
+
137
+ export { Alert, AlertDescription, AlertTitle };