@srcroot/ui 0.0.54 → 0.0.56

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 (107) hide show
  1. package/README.md +151 -151
  2. package/dist/index.d.ts +0 -0
  3. package/dist/index.js +55 -1
  4. package/package.json +7 -2
  5. package/src/registry/analytics/google-analytics.tsx +36 -39
  6. package/src/registry/analytics/google-tag-manager.tsx +62 -65
  7. package/src/registry/analytics/meta-pixel.tsx +44 -47
  8. package/src/registry/analytics/microsoft-clarity.tsx +31 -34
  9. package/src/registry/analytics/tiktok-pixel.tsx +34 -37
  10. package/src/registry/lib/utils.ts +0 -0
  11. package/src/registry/themes/v3/blue.css +157 -157
  12. package/src/registry/themes/v3/glass.css +153 -153
  13. package/src/registry/themes/v3/gray.css +157 -157
  14. package/src/registry/themes/v3/green.css +157 -157
  15. package/src/registry/themes/v3/neutral.css +157 -157
  16. package/src/registry/themes/v3/orange.css +157 -157
  17. package/src/registry/themes/v3/rose.css +157 -157
  18. package/src/registry/themes/v3/slate.css +157 -157
  19. package/src/registry/themes/v3/stone.css +157 -157
  20. package/src/registry/themes/v3/violet.css +186 -186
  21. package/src/registry/themes/v3/zinc.css +157 -157
  22. package/src/registry/themes/v4/blue.css +184 -184
  23. package/src/registry/themes/v4/glass.css +180 -180
  24. package/src/registry/themes/v4/gray.css +184 -184
  25. package/src/registry/themes/v4/green.css +184 -184
  26. package/src/registry/themes/v4/neutral.css +184 -184
  27. package/src/registry/themes/v4/orange.css +184 -184
  28. package/src/registry/themes/v4/rose.css +184 -184
  29. package/src/registry/themes/v4/slate.css +184 -184
  30. package/src/registry/themes/v4/stone.css +184 -184
  31. package/src/registry/themes/v4/violet.css +184 -184
  32. package/src/registry/themes/v4/zinc.css +184 -184
  33. package/src/registry/ui/accordion.tsx +164 -165
  34. package/src/registry/ui/alert-dialog.tsx +213 -214
  35. package/src/registry/ui/alert.tsx +73 -76
  36. package/src/registry/ui/aspect-ratio.tsx +44 -47
  37. package/src/registry/ui/avatar.tsx +96 -97
  38. package/src/registry/ui/badge.tsx +52 -55
  39. package/src/registry/ui/breadcrumb.tsx +147 -150
  40. package/src/registry/ui/button-group.tsx +64 -67
  41. package/src/registry/ui/button.tsx +71 -72
  42. package/src/registry/ui/calendar.tsx +514 -515
  43. package/src/registry/ui/card.tsx +88 -91
  44. package/src/registry/ui/carousel.tsx +214 -214
  45. package/src/registry/ui/chart.tsx +373 -373
  46. package/src/registry/ui/chatbot.tsx +86 -13
  47. package/src/registry/ui/checkbox.tsx +93 -94
  48. package/src/registry/ui/collapsible.tsx +107 -108
  49. package/src/registry/ui/combobox.tsx +171 -171
  50. package/src/registry/ui/command.tsx +300 -300
  51. package/src/registry/ui/container.tsx +44 -47
  52. package/src/registry/ui/context-menu.tsx +221 -221
  53. package/src/registry/ui/date-picker.tsx +228 -228
  54. package/src/registry/ui/dialog.tsx +269 -270
  55. package/src/registry/ui/drawer.tsx +10 -4
  56. package/src/registry/ui/dropdown-menu.tsx +529 -530
  57. package/src/registry/ui/empty-state.tsx +0 -2
  58. package/src/registry/ui/file-upload.tsx +0 -0
  59. package/src/registry/ui/floating-dock.tsx +0 -0
  60. package/src/registry/ui/form-field.tsx +91 -94
  61. package/src/registry/ui/google-analytics.tsx +38 -0
  62. package/src/registry/ui/google-tag-manager.tsx +64 -0
  63. package/src/registry/ui/hover-card.tsx +223 -223
  64. package/src/registry/ui/image.tsx +144 -147
  65. package/src/registry/ui/input-group.tsx +82 -85
  66. package/src/registry/ui/input.tsx +125 -125
  67. package/src/registry/ui/kbd.tsx +60 -63
  68. package/src/registry/ui/label.tsx +36 -37
  69. package/src/registry/ui/loading-spinner.tsx +108 -111
  70. package/src/registry/ui/map.tsx +0 -0
  71. package/src/registry/ui/marquee.tsx +2 -0
  72. package/src/registry/ui/menubar.tsx +246 -246
  73. package/src/registry/ui/meta-pixel.tsx +46 -0
  74. package/src/registry/ui/microsoft-clarity.tsx +33 -0
  75. package/src/registry/ui/native-select.tsx +49 -52
  76. package/src/registry/ui/otp-input.tsx +152 -155
  77. package/src/registry/ui/pagination.tsx +149 -152
  78. package/src/registry/ui/patterns.tsx +28 -0
  79. package/src/registry/ui/popover.tsx +226 -227
  80. package/src/registry/ui/progress.tsx +51 -52
  81. package/src/registry/ui/radio.tsx +99 -102
  82. package/src/registry/ui/resizable.tsx +314 -314
  83. package/src/registry/ui/scroll-animation.tsx +45 -0
  84. package/src/registry/ui/scroll-area.tsx +121 -122
  85. package/src/registry/ui/scroll-to-top.tsx +0 -0
  86. package/src/registry/ui/search.tsx +147 -150
  87. package/src/registry/ui/select.tsx +292 -293
  88. package/src/registry/ui/separator.tsx +46 -47
  89. package/src/registry/ui/sheet.tsx +6 -3
  90. package/src/registry/ui/sidebar.tsx +628 -628
  91. package/src/registry/ui/skeleton.tsx +26 -29
  92. package/src/registry/ui/slider.tsx +196 -197
  93. package/src/registry/ui/slot.tsx +69 -72
  94. package/src/registry/ui/star-rating.tsx +131 -134
  95. package/src/registry/ui/switch.tsx +72 -73
  96. package/src/registry/ui/table-of-contents.tsx +96 -96
  97. package/src/registry/ui/table.tsx +138 -139
  98. package/src/registry/ui/tabs.tsx +124 -125
  99. package/src/registry/ui/text.tsx +61 -64
  100. package/src/registry/ui/textarea.tsx +41 -42
  101. package/src/registry/ui/theme-switcher.tsx +66 -66
  102. package/src/registry/ui/tiktok-pixel.tsx +36 -0
  103. package/src/registry/ui/toast.tsx +97 -98
  104. package/src/registry/ui/toggle-group.tsx +129 -129
  105. package/src/registry/ui/toggle.tsx +72 -72
  106. package/src/registry/ui/tooltip.tsx +143 -144
  107. package/src/registry/ui/whatsapp.tsx +0 -0
@@ -1,214 +1,213 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { createPortal } from "react-dom"
5
- import { cn } from "@/lib/utils"
6
- import { Slot } from "@/components/ui/slot"
7
-
8
- interface AlertDialogContextValue {
9
- open: boolean
10
- onOpenChange: (open: boolean) => void
11
- }
12
-
13
- const AlertDialogContext = React.createContext<AlertDialogContextValue | null>(null)
14
-
15
- interface AlertDialogProps {
16
- children: React.ReactNode
17
- open?: boolean
18
- onOpenChange?: (open: boolean) => void
19
- defaultOpen?: boolean
20
- }
21
-
22
- /**
23
- * AlertDialog for confirmation actions
24
- * Unlike Dialog, it requires explicit action to close (no click-outside dismiss)
25
- *
26
- * @example
27
- * <AlertDialog>
28
- * <AlertDialogTrigger asChild>
29
- * <Button variant="destructive">Delete</Button>
30
- * </AlertDialogTrigger>
31
- * <AlertDialogContent>
32
- * <AlertDialogHeader>
33
- * <AlertDialogTitle>Are you sure?</AlertDialogTitle>
34
- * <AlertDialogDescription>This action cannot be undone.</AlertDialogDescription>
35
- * </AlertDialogHeader>
36
- * <AlertDialogFooter>
37
- * <AlertDialogCancel>Cancel</AlertDialogCancel>
38
- * <AlertDialogAction>Continue</AlertDialogAction>
39
- * </AlertDialogFooter>
40
- * </AlertDialogContent>
41
- * </AlertDialog>
42
- */
43
- function AlertDialog({ children, open: controlledOpen, onOpenChange, defaultOpen = false }: AlertDialogProps) {
44
- const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen)
45
-
46
- const open = controlledOpen !== undefined ? controlledOpen : uncontrolledOpen
47
- const setOpen = onOpenChange || setUncontrolledOpen
48
-
49
- return (
50
- <AlertDialogContext.Provider value={{ open, onOpenChange: setOpen }}>
51
- {children}
52
- </AlertDialogContext.Provider>
53
- )
54
- }
55
-
56
- interface AlertDialogTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
57
- asChild?: boolean
58
- }
59
-
60
- const AlertDialogTrigger = React.forwardRef<HTMLButtonElement, AlertDialogTriggerProps>(
61
- ({ onClick, asChild, children, ...props }, ref) => {
62
- const context = React.useContext(AlertDialogContext)
63
- if (!context) throw new Error("AlertDialogTrigger must be used within AlertDialog")
64
-
65
- const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
66
- onClick?.(e)
67
- context.onOpenChange(true)
68
- }
69
-
70
- const Comp = asChild ? Slot : "button"
71
-
72
- return (
73
- <Comp ref={ref} onClick={handleClick} {...props}>
74
- {children}
75
- </Comp>
76
- )
77
- }
78
- )
79
- AlertDialogTrigger.displayName = "AlertDialogTrigger"
80
-
81
- const AlertDialogContent = React.forwardRef<
82
- HTMLDivElement,
83
- React.HTMLAttributes<HTMLDivElement>
84
- >(({ className, children, ...props }, ref) => {
85
- const context = React.useContext(AlertDialogContext)
86
- if (!context) throw new Error("AlertDialogContent must be used within AlertDialog")
87
-
88
- React.useEffect(() => {
89
- if (context.open) {
90
- document.body.style.overflow = "hidden"
91
- }
92
- return () => {
93
- document.body.style.overflow = ""
94
- }
95
- }, [context.open])
96
-
97
- const [mounted, setMounted] = React.useState(false)
98
-
99
- React.useEffect(() => {
100
- setMounted(true)
101
- }, [])
102
-
103
- if (!context.open) return null
104
- if (!mounted) return null
105
-
106
- return createPortal(
107
- <>
108
- <div className="fixed inset-0 z-50 bg-black/80" />
109
- <div
110
- ref={ref}
111
- role="alertdialog"
112
- aria-modal="true"
113
- className={cn(
114
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg",
115
- className
116
- )}
117
- {...props}
118
- >
119
- {children}
120
- </div>
121
- </>,
122
- document.body
123
- )
124
- })
125
- AlertDialogContent.displayName = "AlertDialogContent"
126
-
127
- const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
128
- <div className={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...props} />
129
- )
130
- AlertDialogHeader.displayName = "AlertDialogHeader"
131
-
132
- const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
133
- <div className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)} {...props} />
134
- )
135
- AlertDialogFooter.displayName = "AlertDialogFooter"
136
-
137
- const AlertDialogTitle = React.forwardRef<
138
- HTMLHeadingElement,
139
- React.HTMLAttributes<HTMLHeadingElement>
140
- >(({ className, ...props }, ref) => (
141
- <h2 ref={ref} className={cn("text-lg font-semibold", className)} {...props} />
142
- ))
143
- AlertDialogTitle.displayName = "AlertDialogTitle"
144
-
145
- const AlertDialogDescription = React.forwardRef<
146
- HTMLParagraphElement,
147
- React.HTMLAttributes<HTMLParagraphElement>
148
- >(({ className, ...props }, ref) => (
149
- <p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
150
- ))
151
- AlertDialogDescription.displayName = "AlertDialogDescription"
152
-
153
- const AlertDialogAction = React.forwardRef<
154
- HTMLButtonElement,
155
- React.ButtonHTMLAttributes<HTMLButtonElement>
156
- >(({ className, onClick, ...props }, ref) => {
157
- const context = React.useContext(AlertDialogContext)
158
-
159
- const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
160
- onClick?.(e)
161
- context?.onOpenChange(false)
162
- }
163
-
164
- return (
165
- <button
166
- ref={ref}
167
- className={cn(
168
- "inline-flex h-10 items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
169
- className
170
- )}
171
- onClick={handleClick}
172
- {...props}
173
- />
174
- )
175
- })
176
- AlertDialogAction.displayName = "AlertDialogAction"
177
-
178
- const AlertDialogCancel = React.forwardRef<
179
- HTMLButtonElement,
180
- React.ButtonHTMLAttributes<HTMLButtonElement>
181
- >(({ className, onClick, ...props }, ref) => {
182
- const context = React.useContext(AlertDialogContext)
183
-
184
- const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
185
- onClick?.(e)
186
- context?.onOpenChange(false)
187
- }
188
-
189
- return (
190
- <button
191
- ref={ref}
192
- className={cn(
193
- "mt-2 inline-flex h-10 items-center justify-center rounded-md border border-input bg-transparent px-4 py-2 text-sm font-semibold transition-colors hover:bg-accent hover:text-accent-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 sm:mt-0",
194
- className
195
- )}
196
- onClick={handleClick}
197
- {...props}
198
- />
199
- )
200
- })
201
- AlertDialogCancel.displayName = "AlertDialogCancel"
202
-
203
- export {
204
- AlertDialog,
205
- AlertDialogTrigger,
206
- AlertDialogContent,
207
- AlertDialogHeader,
208
- AlertDialogFooter,
209
- AlertDialogTitle,
210
- AlertDialogDescription,
211
- AlertDialogAction,
212
- AlertDialogCancel,
213
- }
214
-
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { createPortal } from "react-dom"
5
+ import { cn } from "@/lib/utils"
6
+ import { Slot } from "@/components/ui/slot"
7
+
8
+ interface AlertDialogContextValue {
9
+ open: boolean
10
+ onOpenChange: (open: boolean) => void
11
+ }
12
+
13
+ const AlertDialogContext = React.createContext<AlertDialogContextValue | null>(null)
14
+
15
+ interface AlertDialogProps {
16
+ children: React.ReactNode
17
+ open?: boolean
18
+ onOpenChange?: (open: boolean) => void
19
+ defaultOpen?: boolean
20
+ }
21
+
22
+ /**
23
+ * AlertDialog for confirmation actions
24
+ * Unlike Dialog, it requires explicit action to close (no click-outside dismiss)
25
+ *
26
+ * @example
27
+ * <AlertDialog>
28
+ * <AlertDialogTrigger asChild>
29
+ * <Button variant="destructive">Delete</Button>
30
+ * </AlertDialogTrigger>
31
+ * <AlertDialogContent>
32
+ * <AlertDialogHeader>
33
+ * <AlertDialogTitle>Are you sure?</AlertDialogTitle>
34
+ * <AlertDialogDescription>This action cannot be undone.</AlertDialogDescription>
35
+ * </AlertDialogHeader>
36
+ * <AlertDialogFooter>
37
+ * <AlertDialogCancel>Cancel</AlertDialogCancel>
38
+ * <AlertDialogAction>Continue</AlertDialogAction>
39
+ * </AlertDialogFooter>
40
+ * </AlertDialogContent>
41
+ * </AlertDialog>
42
+ */
43
+ function AlertDialog({ children, open: controlledOpen, onOpenChange, defaultOpen = false }: AlertDialogProps) {
44
+ const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen)
45
+
46
+ const open = controlledOpen !== undefined ? controlledOpen : uncontrolledOpen
47
+ const setOpen = onOpenChange || setUncontrolledOpen
48
+
49
+ return (
50
+ <AlertDialogContext.Provider value={{ open, onOpenChange: setOpen }}>
51
+ {children}
52
+ </AlertDialogContext.Provider>
53
+ )
54
+ }
55
+
56
+ interface AlertDialogTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
57
+ asChild?: boolean
58
+ }
59
+
60
+ const AlertDialogTrigger = React.forwardRef<HTMLButtonElement, AlertDialogTriggerProps>(
61
+ ({ onClick, asChild, children, ...props }, ref) => {
62
+ const context = React.useContext(AlertDialogContext)
63
+ if (!context) throw new Error("AlertDialogTrigger must be used within AlertDialog")
64
+
65
+ const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
66
+ onClick?.(e)
67
+ context.onOpenChange(true)
68
+ }
69
+
70
+ const Comp = asChild ? Slot : "button"
71
+
72
+ return (
73
+ <Comp ref={ref} onClick={handleClick} {...props}>
74
+ {children}
75
+ </Comp>
76
+ )
77
+ }
78
+ )
79
+ AlertDialogTrigger.displayName = "AlertDialogTrigger"
80
+
81
+ const AlertDialogContent = React.forwardRef<
82
+ HTMLDivElement,
83
+ React.HTMLAttributes<HTMLDivElement>
84
+ >(({ className, children, ...props }, ref) => {
85
+ const context = React.useContext(AlertDialogContext)
86
+ if (!context) throw new Error("AlertDialogContent must be used within AlertDialog")
87
+
88
+ React.useEffect(() => {
89
+ if (context.open) {
90
+ document.body.style.overflow = "hidden"
91
+ }
92
+ return () => {
93
+ document.body.style.overflow = ""
94
+ }
95
+ }, [context.open])
96
+
97
+ const [mounted, setMounted] = React.useState(false)
98
+
99
+ React.useEffect(() => {
100
+ setMounted(true)
101
+ }, [])
102
+
103
+ if (!context.open) return null
104
+ if (!mounted) return null
105
+
106
+ return createPortal(
107
+ <>
108
+ <div className="fixed inset-0 z-50 bg-black/80" />
109
+ <div
110
+ ref={ref}
111
+ role="alertdialog"
112
+ aria-modal="true"
113
+ className={cn(
114
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg",
115
+ className
116
+ )}
117
+ {...props}
118
+ >
119
+ {children}
120
+ </div>
121
+ </>,
122
+ document.body
123
+ )
124
+ })
125
+ AlertDialogContent.displayName = "AlertDialogContent"
126
+
127
+ const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
128
+ <div className={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...props} />
129
+ )
130
+ AlertDialogHeader.displayName = "AlertDialogHeader"
131
+
132
+ const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
133
+ <div className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)} {...props} />
134
+ )
135
+ AlertDialogFooter.displayName = "AlertDialogFooter"
136
+
137
+ const AlertDialogTitle = React.forwardRef<
138
+ HTMLHeadingElement,
139
+ React.HTMLAttributes<HTMLHeadingElement>
140
+ >(({ className, ...props }, ref) => (
141
+ <h2 ref={ref} className={cn("text-lg font-semibold", className)} {...props} />
142
+ ))
143
+ AlertDialogTitle.displayName = "AlertDialogTitle"
144
+
145
+ const AlertDialogDescription = React.forwardRef<
146
+ HTMLParagraphElement,
147
+ React.HTMLAttributes<HTMLParagraphElement>
148
+ >(({ className, ...props }, ref) => (
149
+ <p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
150
+ ))
151
+ AlertDialogDescription.displayName = "AlertDialogDescription"
152
+
153
+ const AlertDialogAction = React.forwardRef<
154
+ HTMLButtonElement,
155
+ React.ButtonHTMLAttributes<HTMLButtonElement>
156
+ >(({ className, onClick, ...props }, ref) => {
157
+ const context = React.useContext(AlertDialogContext)
158
+
159
+ const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
160
+ onClick?.(e)
161
+ context?.onOpenChange(false)
162
+ }
163
+
164
+ return (
165
+ <button
166
+ ref={ref}
167
+ className={cn(
168
+ "inline-flex h-10 items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
169
+ className
170
+ )}
171
+ onClick={handleClick}
172
+ {...props}
173
+ />
174
+ )
175
+ })
176
+ AlertDialogAction.displayName = "AlertDialogAction"
177
+
178
+ const AlertDialogCancel = React.forwardRef<
179
+ HTMLButtonElement,
180
+ React.ButtonHTMLAttributes<HTMLButtonElement>
181
+ >(({ className, onClick, ...props }, ref) => {
182
+ const context = React.useContext(AlertDialogContext)
183
+
184
+ const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
185
+ onClick?.(e)
186
+ context?.onOpenChange(false)
187
+ }
188
+
189
+ return (
190
+ <button
191
+ ref={ref}
192
+ className={cn(
193
+ "mt-2 inline-flex h-10 items-center justify-center rounded-md border border-input bg-transparent px-4 py-2 text-sm font-semibold transition-colors hover:bg-accent hover:text-accent-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 sm:mt-0",
194
+ className
195
+ )}
196
+ onClick={handleClick}
197
+ {...props}
198
+ />
199
+ )
200
+ })
201
+ AlertDialogCancel.displayName = "AlertDialogCancel"
202
+
203
+ export {
204
+ AlertDialog,
205
+ AlertDialogTrigger,
206
+ AlertDialogContent,
207
+ AlertDialogHeader,
208
+ AlertDialogFooter,
209
+ AlertDialogTitle,
210
+ AlertDialogDescription,
211
+ AlertDialogAction,
212
+ AlertDialogCancel,
213
+ }
@@ -1,76 +1,73 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { cva, type VariantProps } from "class-variance-authority"
5
- import { cn } from "@/lib/utils"
6
-
7
- const alertVariants = cva(
8
- "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
9
- {
10
- variants: {
11
- variant: {
12
- default: "bg-background text-foreground",
13
- destructive:
14
- "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
15
- },
16
- },
17
- defaultVariants: {
18
- variant: "default",
19
- },
20
- }
21
- )
22
-
23
- /**
24
- * Alert component for inline feedback
25
- *
26
- * @example
27
- * <Alert>
28
- * <AlertTitle>Note</AlertTitle>
29
- * <AlertDescription>This is an informational message.</AlertDescription>
30
- * </Alert>
31
- *
32
- * @example
33
- * <Alert variant="destructive">
34
- * <AlertTitle>Error</AlertTitle>
35
- * <AlertDescription>Something went wrong.</AlertDescription>
36
- * </Alert>
37
- */
38
- const Alert = React.forwardRef<
39
- HTMLDivElement,
40
- React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
41
- >(({ className, variant, ...props }, ref) => (
42
- <div
43
- ref={ref}
44
- role="alert"
45
- className={cn(alertVariants({ variant }), className)}
46
- {...props}
47
- />
48
- ))
49
- Alert.displayName = "Alert"
50
-
51
- const AlertTitle = React.forwardRef<
52
- HTMLParagraphElement,
53
- React.HTMLAttributes<HTMLHeadingElement>
54
- >(({ className, ...props }, ref) => (
55
- <h5
56
- ref={ref}
57
- className={cn("mb-1 font-medium leading-none tracking-tight", className)}
58
- {...props}
59
- />
60
- ))
61
- AlertTitle.displayName = "AlertTitle"
62
-
63
- const AlertDescription = React.forwardRef<
64
- HTMLParagraphElement,
65
- React.HTMLAttributes<HTMLParagraphElement>
66
- >(({ className, ...props }, ref) => (
67
- <div
68
- ref={ref}
69
- className={cn("text-sm [&_p]:leading-relaxed", className)}
70
- {...props}
71
- />
72
- ))
73
- AlertDescription.displayName = "AlertDescription"
74
-
75
- export { Alert, AlertTitle, AlertDescription }
76
-
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const alertVariants = cva(
6
+ "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
7
+ {
8
+ variants: {
9
+ variant: {
10
+ default: "bg-background text-foreground",
11
+ destructive:
12
+ "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
13
+ },
14
+ },
15
+ defaultVariants: {
16
+ variant: "default",
17
+ },
18
+ }
19
+ )
20
+
21
+ /**
22
+ * Alert component for inline feedback
23
+ *
24
+ * @example
25
+ * <Alert>
26
+ * <AlertTitle>Note</AlertTitle>
27
+ * <AlertDescription>This is an informational message.</AlertDescription>
28
+ * </Alert>
29
+ *
30
+ * @example
31
+ * <Alert variant="destructive">
32
+ * <AlertTitle>Error</AlertTitle>
33
+ * <AlertDescription>Something went wrong.</AlertDescription>
34
+ * </Alert>
35
+ */
36
+ const Alert = React.forwardRef<
37
+ HTMLDivElement,
38
+ React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
39
+ >(({ className, variant, ...props }, ref) => (
40
+ <div
41
+ ref={ref}
42
+ role="alert"
43
+ className={cn(alertVariants({ variant }), className)}
44
+ {...props}
45
+ />
46
+ ))
47
+ Alert.displayName = "Alert"
48
+
49
+ const AlertTitle = React.forwardRef<
50
+ HTMLParagraphElement,
51
+ React.HTMLAttributes<HTMLHeadingElement>
52
+ >(({ className, ...props }, ref) => (
53
+ <h5
54
+ ref={ref}
55
+ className={cn("mb-1 font-medium leading-none tracking-tight", className)}
56
+ {...props}
57
+ />
58
+ ))
59
+ AlertTitle.displayName = "AlertTitle"
60
+
61
+ const AlertDescription = React.forwardRef<
62
+ HTMLParagraphElement,
63
+ React.HTMLAttributes<HTMLParagraphElement>
64
+ >(({ className, ...props }, ref) => (
65
+ <div
66
+ ref={ref}
67
+ className={cn("text-sm [&_p]:leading-relaxed", className)}
68
+ {...props}
69
+ />
70
+ ))
71
+ AlertDescription.displayName = "AlertDescription"
72
+
73
+ export { Alert, AlertTitle, AlertDescription }