@useatlas/react 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +95 -0
  2. package/dist/chunk-2WFDP7G5.js +231 -0
  3. package/dist/chunk-2WFDP7G5.js.map +1 -0
  4. package/dist/chunk-44HBZYKP.js +224 -0
  5. package/dist/chunk-44HBZYKP.js.map +1 -0
  6. package/dist/chunk-5SEVKHS5.cjs +229 -0
  7. package/dist/chunk-5SEVKHS5.cjs.map +1 -0
  8. package/dist/chunk-UIRB6L36.cjs +249 -0
  9. package/dist/chunk-UIRB6L36.cjs.map +1 -0
  10. package/dist/hooks.cjs +251 -0
  11. package/dist/hooks.cjs.map +1 -0
  12. package/dist/hooks.d.cts +132 -0
  13. package/dist/hooks.d.ts +132 -0
  14. package/dist/hooks.js +237 -0
  15. package/dist/hooks.js.map +1 -0
  16. package/dist/index.cjs +2976 -0
  17. package/dist/index.cjs.map +1 -0
  18. package/dist/index.d.cts +69 -0
  19. package/dist/index.d.ts +69 -0
  20. package/dist/index.js +2926 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/result-chart-NFAJ4IQ5.js +398 -0
  23. package/dist/result-chart-NFAJ4IQ5.js.map +1 -0
  24. package/dist/result-chart-YLCKBNV4.cjs +400 -0
  25. package/dist/result-chart-YLCKBNV4.cjs.map +1 -0
  26. package/dist/styles.css +59 -0
  27. package/dist/use-dark-mode-rFxawUv1.d.cts +123 -0
  28. package/dist/use-dark-mode-rFxawUv1.d.ts +123 -0
  29. package/dist/widget.css +2 -0
  30. package/dist/widget.js +445 -0
  31. package/package.json +113 -0
  32. package/src/components/__tests__/tool-renderers.test.tsx +239 -0
  33. package/src/components/actions/action-approval-card.tsx +296 -0
  34. package/src/components/actions/action-status-badge.tsx +50 -0
  35. package/src/components/admin/change-password-dialog.tsx +128 -0
  36. package/src/components/atlas-chat.tsx +656 -0
  37. package/src/components/chart/chart-detection.ts +318 -0
  38. package/src/components/chart/result-chart.tsx +590 -0
  39. package/src/components/chat/api-key-bar.tsx +66 -0
  40. package/src/components/chat/copy-button.tsx +25 -0
  41. package/src/components/chat/data-table.tsx +104 -0
  42. package/src/components/chat/error-banner.tsx +32 -0
  43. package/src/components/chat/explore-card.tsx +41 -0
  44. package/src/components/chat/follow-up-chips.tsx +29 -0
  45. package/src/components/chat/loading-card.tsx +10 -0
  46. package/src/components/chat/managed-auth-card.tsx +116 -0
  47. package/src/components/chat/markdown.tsx +146 -0
  48. package/src/components/chat/python-result-card.tsx +245 -0
  49. package/src/components/chat/sql-block.tsx +54 -0
  50. package/src/components/chat/sql-result-card.tsx +163 -0
  51. package/src/components/chat/starter-prompts.ts +6 -0
  52. package/src/components/chat/tool-part.tsx +106 -0
  53. package/src/components/chat/typing-indicator.tsx +22 -0
  54. package/src/components/conversations/conversation-item.tsx +135 -0
  55. package/src/components/conversations/conversation-list.tsx +69 -0
  56. package/src/components/conversations/conversation-sidebar.tsx +113 -0
  57. package/src/components/conversations/delete-confirmation.tsx +27 -0
  58. package/src/components/schema-explorer/schema-explorer.tsx +517 -0
  59. package/src/components/ui/alert-dialog.tsx +196 -0
  60. package/src/components/ui/badge.tsx +48 -0
  61. package/src/components/ui/button.tsx +64 -0
  62. package/src/components/ui/card.tsx +92 -0
  63. package/src/components/ui/dialog.tsx +158 -0
  64. package/src/components/ui/dropdown-menu.tsx +257 -0
  65. package/src/components/ui/input.tsx +21 -0
  66. package/src/components/ui/label.tsx +24 -0
  67. package/src/components/ui/scroll-area.tsx +62 -0
  68. package/src/components/ui/separator.tsx +28 -0
  69. package/src/components/ui/sheet.tsx +143 -0
  70. package/src/components/ui/table.tsx +116 -0
  71. package/src/components/ui/toggle-group.tsx +83 -0
  72. package/src/components/ui/toggle.tsx +47 -0
  73. package/src/context.tsx +85 -0
  74. package/src/env.d.ts +9 -0
  75. package/src/hooks/__tests__/provider.test.tsx +83 -0
  76. package/src/hooks/__tests__/use-atlas-auth.test.tsx +283 -0
  77. package/src/hooks/__tests__/use-atlas-chat.test.tsx +157 -0
  78. package/src/hooks/__tests__/use-atlas-conversations.test.tsx +159 -0
  79. package/src/hooks/__tests__/use-atlas-theme.test.tsx +56 -0
  80. package/src/hooks/index.ts +47 -0
  81. package/src/hooks/provider.tsx +77 -0
  82. package/src/hooks/theme-init-script.ts +17 -0
  83. package/src/hooks/use-atlas-auth.ts +131 -0
  84. package/src/hooks/use-atlas-chat.ts +102 -0
  85. package/src/hooks/use-atlas-conversations.ts +61 -0
  86. package/src/hooks/use-atlas-theme.ts +34 -0
  87. package/src/hooks/use-conversations.ts +189 -0
  88. package/src/hooks/use-dark-mode.ts +150 -0
  89. package/src/index.ts +36 -0
  90. package/src/lib/action-types.ts +11 -0
  91. package/src/lib/helpers.ts +198 -0
  92. package/src/lib/tool-renderer-types.ts +76 -0
  93. package/src/lib/types.ts +29 -0
  94. package/src/lib/utils.ts +6 -0
  95. package/src/styles.css +59 -0
  96. package/src/test-setup.ts +55 -0
  97. package/src/widget-entry.ts +20 -0
  98. package/src/widget.css +12 -0
@@ -0,0 +1,196 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { AlertDialog as AlertDialogPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "../../lib/utils"
7
+ import { Button } from "./button"
8
+
9
+ function AlertDialog({
10
+ ...props
11
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
12
+ return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />
13
+ }
14
+
15
+ function AlertDialogTrigger({
16
+ ...props
17
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
18
+ return (
19
+ <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
20
+ )
21
+ }
22
+
23
+ function AlertDialogPortal({
24
+ ...props
25
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
26
+ return (
27
+ <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
28
+ )
29
+ }
30
+
31
+ function AlertDialogOverlay({
32
+ className,
33
+ ...props
34
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
35
+ return (
36
+ <AlertDialogPrimitive.Overlay
37
+ data-slot="alert-dialog-overlay"
38
+ className={cn(
39
+ "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
40
+ className
41
+ )}
42
+ {...props}
43
+ />
44
+ )
45
+ }
46
+
47
+ function AlertDialogContent({
48
+ className,
49
+ size = "default",
50
+ ...props
51
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Content> & {
52
+ size?: "default" | "sm"
53
+ }) {
54
+ return (
55
+ <AlertDialogPortal>
56
+ <AlertDialogOverlay />
57
+ <AlertDialogPrimitive.Content
58
+ data-slot="alert-dialog-content"
59
+ data-size={size}
60
+ className={cn(
61
+ "group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[size=sm]:max-w-xs data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[size=default]:sm:max-w-lg",
62
+ className
63
+ )}
64
+ {...props}
65
+ />
66
+ </AlertDialogPortal>
67
+ )
68
+ }
69
+
70
+ function AlertDialogHeader({
71
+ className,
72
+ ...props
73
+ }: React.ComponentProps<"div">) {
74
+ return (
75
+ <div
76
+ data-slot="alert-dialog-header"
77
+ className={cn(
78
+ "grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",
79
+ className
80
+ )}
81
+ {...props}
82
+ />
83
+ )
84
+ }
85
+
86
+ function AlertDialogFooter({
87
+ className,
88
+ ...props
89
+ }: React.ComponentProps<"div">) {
90
+ return (
91
+ <div
92
+ data-slot="alert-dialog-footer"
93
+ className={cn(
94
+ "flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",
95
+ className
96
+ )}
97
+ {...props}
98
+ />
99
+ )
100
+ }
101
+
102
+ function AlertDialogTitle({
103
+ className,
104
+ ...props
105
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
106
+ return (
107
+ <AlertDialogPrimitive.Title
108
+ data-slot="alert-dialog-title"
109
+ className={cn(
110
+ "text-lg font-semibold sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
111
+ className
112
+ )}
113
+ {...props}
114
+ />
115
+ )
116
+ }
117
+
118
+ function AlertDialogDescription({
119
+ className,
120
+ ...props
121
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
122
+ return (
123
+ <AlertDialogPrimitive.Description
124
+ data-slot="alert-dialog-description"
125
+ className={cn("text-sm text-muted-foreground", className)}
126
+ {...props}
127
+ />
128
+ )
129
+ }
130
+
131
+ function AlertDialogMedia({
132
+ className,
133
+ ...props
134
+ }: React.ComponentProps<"div">) {
135
+ return (
136
+ <div
137
+ data-slot="alert-dialog-media"
138
+ className={cn(
139
+ "mb-2 inline-flex size-16 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-8",
140
+ className
141
+ )}
142
+ {...props}
143
+ />
144
+ )
145
+ }
146
+
147
+ function AlertDialogAction({
148
+ className,
149
+ variant = "default",
150
+ size = "default",
151
+ ...props
152
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Action> &
153
+ Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
154
+ return (
155
+ <Button variant={variant} size={size} asChild>
156
+ <AlertDialogPrimitive.Action
157
+ data-slot="alert-dialog-action"
158
+ className={cn(className)}
159
+ {...props}
160
+ />
161
+ </Button>
162
+ )
163
+ }
164
+
165
+ function AlertDialogCancel({
166
+ className,
167
+ variant = "outline",
168
+ size = "default",
169
+ ...props
170
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel> &
171
+ Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
172
+ return (
173
+ <Button variant={variant} size={size} asChild>
174
+ <AlertDialogPrimitive.Cancel
175
+ data-slot="alert-dialog-cancel"
176
+ className={cn(className)}
177
+ {...props}
178
+ />
179
+ </Button>
180
+ )
181
+ }
182
+
183
+ export {
184
+ AlertDialog,
185
+ AlertDialogAction,
186
+ AlertDialogCancel,
187
+ AlertDialogContent,
188
+ AlertDialogDescription,
189
+ AlertDialogFooter,
190
+ AlertDialogHeader,
191
+ AlertDialogMedia,
192
+ AlertDialogOverlay,
193
+ AlertDialogPortal,
194
+ AlertDialogTitle,
195
+ AlertDialogTrigger,
196
+ }
@@ -0,0 +1,48 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { Slot } from "radix-ui"
4
+
5
+ import { cn } from "../../lib/utils"
6
+
7
+ const badgeVariants = cva(
8
+ "inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
13
+ secondary:
14
+ "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
15
+ destructive:
16
+ "bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90",
17
+ outline:
18
+ "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
19
+ ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
20
+ link: "text-primary underline-offset-4 [a&]:hover:underline",
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ variant: "default",
25
+ },
26
+ }
27
+ )
28
+
29
+ function Badge({
30
+ className,
31
+ variant = "default",
32
+ asChild = false,
33
+ ...props
34
+ }: React.ComponentProps<"span"> &
35
+ VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
36
+ const Comp = asChild ? Slot.Root : "span"
37
+
38
+ return (
39
+ <Comp
40
+ data-slot="badge"
41
+ data-variant={variant}
42
+ className={cn(badgeVariants({ variant }), className)}
43
+ {...props}
44
+ />
45
+ )
46
+ }
47
+
48
+ export { Badge, badgeVariants }
@@ -0,0 +1,64 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { Slot } from "radix-ui"
4
+
5
+ import { cn } from "../../lib/utils"
6
+
7
+ const buttonVariants = cva(
8
+ "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
13
+ destructive:
14
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
15
+ outline:
16
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
17
+ secondary:
18
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19
+ ghost:
20
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
21
+ link: "text-primary underline-offset-4 hover:underline",
22
+ },
23
+ size: {
24
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
25
+ xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
26
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
27
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
28
+ icon: "size-9",
29
+ "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
30
+ "icon-sm": "size-8",
31
+ "icon-lg": "size-10",
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ variant: "default",
36
+ size: "default",
37
+ },
38
+ }
39
+ )
40
+
41
+ function Button({
42
+ className,
43
+ variant = "default",
44
+ size = "default",
45
+ asChild = false,
46
+ ...props
47
+ }: React.ComponentProps<"button"> &
48
+ VariantProps<typeof buttonVariants> & {
49
+ asChild?: boolean
50
+ }) {
51
+ const Comp = asChild ? Slot.Root : "button"
52
+
53
+ return (
54
+ <Comp
55
+ data-slot="button"
56
+ data-variant={variant}
57
+ data-size={size}
58
+ className={cn(buttonVariants({ variant, size, className }))}
59
+ {...props}
60
+ />
61
+ )
62
+ }
63
+
64
+ export { Button, buttonVariants }
@@ -0,0 +1,92 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "../../lib/utils"
4
+
5
+ function Card({ className, ...props }: React.ComponentProps<"div">) {
6
+ return (
7
+ <div
8
+ data-slot="card"
9
+ className={cn(
10
+ "flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-sm",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
19
+ return (
20
+ <div
21
+ data-slot="card-header"
22
+ className={cn(
23
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
24
+ className
25
+ )}
26
+ {...props}
27
+ />
28
+ )
29
+ }
30
+
31
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
32
+ return (
33
+ <div
34
+ data-slot="card-title"
35
+ className={cn("leading-none font-semibold", className)}
36
+ {...props}
37
+ />
38
+ )
39
+ }
40
+
41
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
42
+ return (
43
+ <div
44
+ data-slot="card-description"
45
+ className={cn("text-sm text-muted-foreground", className)}
46
+ {...props}
47
+ />
48
+ )
49
+ }
50
+
51
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
52
+ return (
53
+ <div
54
+ data-slot="card-action"
55
+ className={cn(
56
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
57
+ className
58
+ )}
59
+ {...props}
60
+ />
61
+ )
62
+ }
63
+
64
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
65
+ return (
66
+ <div
67
+ data-slot="card-content"
68
+ className={cn("px-6", className)}
69
+ {...props}
70
+ />
71
+ )
72
+ }
73
+
74
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
75
+ return (
76
+ <div
77
+ data-slot="card-footer"
78
+ className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ export {
85
+ Card,
86
+ CardHeader,
87
+ CardFooter,
88
+ CardTitle,
89
+ CardAction,
90
+ CardDescription,
91
+ CardContent,
92
+ }
@@ -0,0 +1,158 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { XIcon } from "lucide-react"
5
+ import { Dialog as DialogPrimitive } from "radix-ui"
6
+
7
+ import { cn } from "../../lib/utils"
8
+ import { Button } from "./button"
9
+
10
+ function Dialog({
11
+ ...props
12
+ }: React.ComponentProps<typeof DialogPrimitive.Root>) {
13
+ return <DialogPrimitive.Root data-slot="dialog" {...props} />
14
+ }
15
+
16
+ function DialogTrigger({
17
+ ...props
18
+ }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
19
+ return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
20
+ }
21
+
22
+ function DialogPortal({
23
+ ...props
24
+ }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
25
+ return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
26
+ }
27
+
28
+ function DialogClose({
29
+ ...props
30
+ }: React.ComponentProps<typeof DialogPrimitive.Close>) {
31
+ return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
32
+ }
33
+
34
+ function DialogOverlay({
35
+ className,
36
+ ...props
37
+ }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
38
+ return (
39
+ <DialogPrimitive.Overlay
40
+ data-slot="dialog-overlay"
41
+ className={cn(
42
+ "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
43
+ className
44
+ )}
45
+ {...props}
46
+ />
47
+ )
48
+ }
49
+
50
+ function DialogContent({
51
+ className,
52
+ children,
53
+ showCloseButton = true,
54
+ ...props
55
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
56
+ showCloseButton?: boolean
57
+ }) {
58
+ return (
59
+ <DialogPortal data-slot="dialog-portal">
60
+ <DialogOverlay />
61
+ <DialogPrimitive.Content
62
+ data-slot="dialog-content"
63
+ className={cn(
64
+ "fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg",
65
+ className
66
+ )}
67
+ {...props}
68
+ >
69
+ {children}
70
+ {showCloseButton && (
71
+ <DialogPrimitive.Close
72
+ data-slot="dialog-close"
73
+ className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
74
+ >
75
+ <XIcon />
76
+ <span className="sr-only">Close</span>
77
+ </DialogPrimitive.Close>
78
+ )}
79
+ </DialogPrimitive.Content>
80
+ </DialogPortal>
81
+ )
82
+ }
83
+
84
+ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
85
+ return (
86
+ <div
87
+ data-slot="dialog-header"
88
+ className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
89
+ {...props}
90
+ />
91
+ )
92
+ }
93
+
94
+ function DialogFooter({
95
+ className,
96
+ showCloseButton = false,
97
+ children,
98
+ ...props
99
+ }: React.ComponentProps<"div"> & {
100
+ showCloseButton?: boolean
101
+ }) {
102
+ return (
103
+ <div
104
+ data-slot="dialog-footer"
105
+ className={cn(
106
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
107
+ className
108
+ )}
109
+ {...props}
110
+ >
111
+ {children}
112
+ {showCloseButton && (
113
+ <DialogPrimitive.Close asChild>
114
+ <Button variant="outline">Close</Button>
115
+ </DialogPrimitive.Close>
116
+ )}
117
+ </div>
118
+ )
119
+ }
120
+
121
+ function DialogTitle({
122
+ className,
123
+ ...props
124
+ }: React.ComponentProps<typeof DialogPrimitive.Title>) {
125
+ return (
126
+ <DialogPrimitive.Title
127
+ data-slot="dialog-title"
128
+ className={cn("text-lg leading-none font-semibold", className)}
129
+ {...props}
130
+ />
131
+ )
132
+ }
133
+
134
+ function DialogDescription({
135
+ className,
136
+ ...props
137
+ }: React.ComponentProps<typeof DialogPrimitive.Description>) {
138
+ return (
139
+ <DialogPrimitive.Description
140
+ data-slot="dialog-description"
141
+ className={cn("text-sm text-muted-foreground", className)}
142
+ {...props}
143
+ />
144
+ )
145
+ }
146
+
147
+ export {
148
+ Dialog,
149
+ DialogClose,
150
+ DialogContent,
151
+ DialogDescription,
152
+ DialogFooter,
153
+ DialogHeader,
154
+ DialogOverlay,
155
+ DialogPortal,
156
+ DialogTitle,
157
+ DialogTrigger,
158
+ }