@beemafrica/ui 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.
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@beemafrica/ui",
3
+ "version": "0.1.0",
4
+ "description": "Shared Beem UI components built on shadcn/Radix",
5
+ "type": "module",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "scripts": {
10
+ "typecheck": "tsc --noEmit",
11
+ "pack:local": "npm pack"
12
+ },
13
+ "files": [
14
+ "src",
15
+ "postcss.config.mjs"
16
+ ],
17
+ "peerDependencies": {
18
+ "react": ">=18",
19
+ "react-dom": ">=18"
20
+ },
21
+ "dependencies": {
22
+ "@tanstack/react-table": "^9.1.2",
23
+ "class-variance-authority": "^0.7.1",
24
+ "clsx": "^2.1.1",
25
+ "lucide-react": "^1.31.0",
26
+ "next-themes": "^0.4.6",
27
+ "radix-ui": "^1.6.7",
28
+ "shadcn": "^4.16.2",
29
+ "tailwind-merge": "^3.6.0",
30
+ "tailwind-scrollbar": "^4.0.2",
31
+ "tw-animate-css": "^1.4.0",
32
+ "zod": "^4.4.3"
33
+ },
34
+ "devDependencies": {
35
+ "@tailwindcss/postcss": "^4",
36
+ "@turbo/gen": "^2.9.15",
37
+ "@types/node": "^20",
38
+ "@types/react": "^19",
39
+ "@types/react-dom": "^19",
40
+ "@workspace/typescript-config": "*",
41
+ "react": "19.2.4",
42
+ "react-dom": "19.2.4",
43
+ "tailwindcss": "^4",
44
+ "typescript": "^5"
45
+ },
46
+ "exports": {
47
+ "./globals.css": {
48
+ "style": "./src/styles/globals.css",
49
+ "default": "./src/styles/globals.css"
50
+ },
51
+ "./theme.css": {
52
+ "style": "./src/styles/theme/beem.css",
53
+ "default": "./src/styles/theme/beem.css"
54
+ },
55
+ "./semantic.css": {
56
+ "style": "./src/styles/theme/semantic.css",
57
+ "default": "./src/styles/theme/semantic.css"
58
+ },
59
+ "./tailwind-theme.css": {
60
+ "style": "./src/styles/tailwind-theme.css",
61
+ "default": "./src/styles/tailwind-theme.css"
62
+ },
63
+ "./postcss.config": "./postcss.config.mjs",
64
+ "./lib/*": {
65
+ "types": "./src/lib/*.ts",
66
+ "default": "./src/lib/*.ts"
67
+ },
68
+ "./components/*": {
69
+ "types": "./src/components/*.tsx",
70
+ "default": "./src/components/*.tsx"
71
+ },
72
+ "./hooks/*": {
73
+ "types": "./src/hooks/*.ts",
74
+ "default": "./src/hooks/*.ts"
75
+ }
76
+ }
77
+ }
@@ -0,0 +1,6 @@
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: { "@tailwindcss/postcss": {} },
4
+ }
5
+
6
+ export default config
File without changes
@@ -0,0 +1,86 @@
1
+ "use client"
2
+
3
+ import { cn } from "@beem/ui/lib/utils"
4
+ import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"
5
+ import { Accordion as AccordionPrimitive } from "radix-ui"
6
+ import type * as React from "react"
7
+
8
+ function Accordion({
9
+ className,
10
+ ...props
11
+ }: React.ComponentProps<typeof AccordionPrimitive.Root>) {
12
+ return (
13
+ <AccordionPrimitive.Root
14
+ data-slot="accordion"
15
+ className={cn("flex w-full flex-col", className)}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ function AccordionItem({
22
+ className,
23
+ ...props
24
+ }: React.ComponentProps<typeof AccordionPrimitive.Item>) {
25
+ return (
26
+ <AccordionPrimitive.Item
27
+ data-slot="accordion-item"
28
+ className={cn("not-last:border-b", className)}
29
+ {...props}
30
+ />
31
+ )
32
+ }
33
+
34
+ function AccordionTrigger({
35
+ className,
36
+ children,
37
+ ...props
38
+ }: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
39
+ return (
40
+ <AccordionPrimitive.Header className="flex">
41
+ <AccordionPrimitive.Trigger
42
+ data-slot="accordion-trigger"
43
+ className={cn(
44
+ "group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-start text-sm font-medium transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ms-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground",
45
+ className
46
+ )}
47
+ {...props}
48
+ >
49
+ {children}
50
+ <ChevronDownIcon
51
+ data-slot="accordion-trigger-icon"
52
+ className="pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
53
+ />
54
+ <ChevronUpIcon
55
+ data-slot="accordion-trigger-icon"
56
+ className="pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
57
+ />
58
+ </AccordionPrimitive.Trigger>
59
+ </AccordionPrimitive.Header>
60
+ )
61
+ }
62
+
63
+ function AccordionContent({
64
+ className,
65
+ children,
66
+ ...props
67
+ }: React.ComponentProps<typeof AccordionPrimitive.Content>) {
68
+ return (
69
+ <AccordionPrimitive.Content
70
+ data-slot="accordion-content"
71
+ className="overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
72
+ {...props}
73
+ >
74
+ <div
75
+ className={cn(
76
+ "h-(--radix-accordion-content-height) pt-0 pb-2.5 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
77
+ className
78
+ )}
79
+ >
80
+ {children}
81
+ </div>
82
+ </AccordionPrimitive.Content>
83
+ )
84
+ }
85
+
86
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger }
@@ -0,0 +1,111 @@
1
+ "use client"
2
+
3
+ import { cn } from "@beem/ui/lib/utils"
4
+ import { Avatar as AvatarPrimitive } from "radix-ui"
5
+ import type * as React from "react"
6
+
7
+ function Avatar({
8
+ className,
9
+ size = "default",
10
+ ...props
11
+ }: React.ComponentProps<typeof AvatarPrimitive.Root> & {
12
+ size?: "default" | "sm" | "lg"
13
+ }) {
14
+ return (
15
+ <AvatarPrimitive.Root
16
+ data-slot="avatar"
17
+ data-size={size}
18
+ className={cn(
19
+ "group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten",
20
+ className
21
+ )}
22
+ {...props}
23
+ />
24
+ )
25
+ }
26
+
27
+ function AvatarImage({
28
+ className,
29
+ ...props
30
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
31
+ return (
32
+ <AvatarPrimitive.Image
33
+ data-slot="avatar-image"
34
+ className={cn(
35
+ "aspect-square size-full rounded-full object-cover",
36
+ className
37
+ )}
38
+ {...props}
39
+ />
40
+ )
41
+ }
42
+
43
+ function AvatarFallback({
44
+ className,
45
+ ...props
46
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
47
+ return (
48
+ <AvatarPrimitive.Fallback
49
+ data-slot="avatar-fallback"
50
+ className={cn(
51
+ "flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs",
52
+ className
53
+ )}
54
+ {...props}
55
+ />
56
+ )
57
+ }
58
+
59
+ function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
60
+ return (
61
+ <span
62
+ data-slot="avatar-badge"
63
+ className={cn(
64
+ "absolute end-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none",
65
+ "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
66
+ "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
67
+ "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
68
+ className
69
+ )}
70
+ {...props}
71
+ />
72
+ )
73
+ }
74
+
75
+ function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
76
+ return (
77
+ <div
78
+ data-slot="avatar-group"
79
+ className={cn(
80
+ "group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background",
81
+ className
82
+ )}
83
+ {...props}
84
+ />
85
+ )
86
+ }
87
+
88
+ function AvatarGroupCount({
89
+ className,
90
+ ...props
91
+ }: React.ComponentProps<"div">) {
92
+ return (
93
+ <div
94
+ data-slot="avatar-group-count"
95
+ className={cn(
96
+ "relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
97
+ className
98
+ )}
99
+ {...props}
100
+ />
101
+ )
102
+ }
103
+
104
+ export {
105
+ Avatar,
106
+ AvatarBadge,
107
+ AvatarFallback,
108
+ AvatarGroup,
109
+ AvatarGroupCount,
110
+ AvatarImage,
111
+ }
@@ -0,0 +1,67 @@
1
+ import { cn } from "@beem/ui/lib/utils"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { Slot } from "radix-ui"
4
+ import type * as React from "react"
5
+
6
+ const buttonVariants = cva(
7
+ "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: "bg-primary text-accent hover:bg-secondary-brand/80",
12
+ primary: "bg-primary text-primary-foreground hover:bg-primary/80",
13
+ outline:
14
+ "bg-muted hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
15
+ secondary:
16
+ "bg-secondary text-primary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
17
+ ghost:
18
+ "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
19
+ destructive:
20
+ "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
21
+ link: "text-primary underline-offset-4 hover:underline",
22
+ },
23
+ size: {
24
+ default:
25
+ "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2",
26
+ xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3",
27
+ sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3.5",
28
+ lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2",
29
+ icon: "size-8",
30
+ "icon-xs":
31
+ "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
32
+ "icon-sm":
33
+ "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
34
+ "icon-lg": "size-9",
35
+ },
36
+ },
37
+ defaultVariants: {
38
+ variant: "default",
39
+ size: "default",
40
+ },
41
+ }
42
+ )
43
+
44
+ function Button({
45
+ className,
46
+ variant = "default",
47
+ size = "default",
48
+ asChild = false,
49
+ ...props
50
+ }: React.ComponentProps<"button"> &
51
+ VariantProps<typeof buttonVariants> & {
52
+ asChild?: boolean
53
+ }) {
54
+ const Comp = asChild ? Slot.Root : "button"
55
+
56
+ return (
57
+ <Comp
58
+ data-slot="button"
59
+ data-variant={variant}
60
+ data-size={size}
61
+ className={cn(buttonVariants({ variant, size, className }))}
62
+ {...props}
63
+ />
64
+ )
65
+ }
66
+
67
+ export { Button, buttonVariants }
@@ -0,0 +1,102 @@
1
+ import { cn } from "@beem/ui/lib/utils"
2
+ import type * as React from "react"
3
+
4
+ function Card({
5
+ className,
6
+ size = "default",
7
+ ...props
8
+ }: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
9
+ return (
10
+ <div
11
+ data-slot="card"
12
+ data-size={size}
13
+ className={cn(
14
+ "group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
15
+ className
16
+ )}
17
+ {...props}
18
+ />
19
+ )
20
+ }
21
+
22
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
23
+ return (
24
+ <div
25
+ data-slot="card-header"
26
+ className={cn(
27
+ "group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)",
28
+ className
29
+ )}
30
+ {...props}
31
+ />
32
+ )
33
+ }
34
+
35
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
36
+ return (
37
+ <div
38
+ data-slot="card-title"
39
+ className={cn(
40
+ "font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
41
+ className
42
+ )}
43
+ {...props}
44
+ />
45
+ )
46
+ }
47
+
48
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
49
+ return (
50
+ <div
51
+ data-slot="card-description"
52
+ className={cn("text-sm text-muted-foreground", className)}
53
+ {...props}
54
+ />
55
+ )
56
+ }
57
+
58
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
59
+ return (
60
+ <div
61
+ data-slot="card-action"
62
+ className={cn(
63
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
64
+ className
65
+ )}
66
+ {...props}
67
+ />
68
+ )
69
+ }
70
+
71
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
72
+ return (
73
+ <div
74
+ data-slot="card-content"
75
+ className={cn("px-(--card-spacing)", className)}
76
+ {...props}
77
+ />
78
+ )
79
+ }
80
+
81
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
82
+ return (
83
+ <div
84
+ data-slot="card-footer"
85
+ className={cn(
86
+ "flex items-center rounded-b-xl border-t bg-muted/50 p-(--card-spacing)",
87
+ className
88
+ )}
89
+ {...props}
90
+ />
91
+ )
92
+ }
93
+
94
+ export {
95
+ Card,
96
+ CardAction,
97
+ CardContent,
98
+ CardDescription,
99
+ CardFooter,
100
+ CardHeader,
101
+ CardTitle,
102
+ }
@@ -0,0 +1,33 @@
1
+ "use client"
2
+
3
+ import { Collapsible as CollapsiblePrimitive } from "radix-ui"
4
+
5
+ function Collapsible({
6
+ ...props
7
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
8
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />
9
+ }
10
+
11
+ function CollapsibleTrigger({
12
+ ...props
13
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
14
+ return (
15
+ <CollapsiblePrimitive.CollapsibleTrigger
16
+ data-slot="collapsible-trigger"
17
+ {...props}
18
+ />
19
+ )
20
+ }
21
+
22
+ function CollapsibleContent({
23
+ ...props
24
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
25
+ return (
26
+ <CollapsiblePrimitive.CollapsibleContent
27
+ data-slot="collapsible-content"
28
+ {...props}
29
+ />
30
+ )
31
+ }
32
+
33
+ export { Collapsible, CollapsibleContent, CollapsibleTrigger }
@@ -0,0 +1,169 @@
1
+ "use client"
2
+
3
+ import { Button } from "@beem/ui/components/button"
4
+ import { cn } from "@beem/ui/lib/utils"
5
+ import { XIcon } from "lucide-react"
6
+ import { Dialog as DialogPrimitive } from "radix-ui"
7
+ import type * as React from "react"
8
+
9
+ function Dialog({
10
+ ...props
11
+ }: React.ComponentProps<typeof DialogPrimitive.Root>) {
12
+ return <DialogPrimitive.Root data-slot="dialog" {...props} />
13
+ }
14
+
15
+ function DialogTrigger({
16
+ ...props
17
+ }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
18
+ return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
19
+ }
20
+
21
+ function DialogPortal({
22
+ ...props
23
+ }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
24
+ return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
25
+ }
26
+
27
+ function DialogClose({
28
+ ...props
29
+ }: React.ComponentProps<typeof DialogPrimitive.Close>) {
30
+ return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
31
+ }
32
+
33
+ function DialogOverlay({
34
+ className,
35
+ ...props
36
+ }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
37
+ return (
38
+ <DialogPrimitive.Overlay
39
+ data-slot="dialog-overlay"
40
+ className={cn(
41
+ "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
42
+ className
43
+ )}
44
+ {...props}
45
+ />
46
+ )
47
+ }
48
+
49
+ function DialogContent({
50
+ className,
51
+ children,
52
+ showCloseButton = true,
53
+ ...props
54
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
55
+ showCloseButton?: boolean
56
+ }) {
57
+ return (
58
+ <DialogPortal>
59
+ <DialogOverlay />
60
+ <DialogPrimitive.Content
61
+ data-slot="dialog-content"
62
+ className={cn(
63
+ "fixed top-1/2 inset-s-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 rtl:translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover px-12 py-6 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
64
+ className
65
+ )}
66
+ {...props}
67
+ >
68
+ {children}
69
+ {showCloseButton && (
70
+ <DialogPrimitive.Close data-slot="dialog-close" asChild>
71
+ <Button
72
+ variant="ghost"
73
+ className="absolute top-2 inset-e-2"
74
+ size="icon-sm"
75
+ >
76
+ <XIcon />
77
+ <span className="sr-only">Close</span>
78
+ </Button>
79
+ </DialogPrimitive.Close>
80
+ )}
81
+ </DialogPrimitive.Content>
82
+ </DialogPortal>
83
+ )
84
+ }
85
+
86
+ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
87
+ return (
88
+ <div
89
+ data-slot="dialog-header"
90
+ className={cn(
91
+ "flex flex-col gap-2 -mx-12 -mt-12 font-semibold border-b-[0.00005px] border-[#d5dee6] px-8 pt-12 pb-4",
92
+ className
93
+ )}
94
+ {...props}
95
+ />
96
+ )
97
+ }
98
+
99
+ function DialogFooter({
100
+ className,
101
+ showCloseButton = false,
102
+ children,
103
+ ...props
104
+ }: React.ComponentProps<"div"> & {
105
+ showCloseButton?: boolean
106
+ }) {
107
+ return (
108
+ <div
109
+ data-slot="dialog-footer"
110
+ className={cn(
111
+ "-mx-12 -mb-12 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 px-12 pb-12 pt-4 sm:flex-row sm:justify-end",
112
+ className
113
+ )}
114
+ {...props}
115
+ >
116
+ {children}
117
+ {showCloseButton && (
118
+ <DialogPrimitive.Close asChild>
119
+ <Button variant="outline">Close</Button>
120
+ </DialogPrimitive.Close>
121
+ )}
122
+ </div>
123
+ )
124
+ }
125
+
126
+ function DialogTitle({
127
+ className,
128
+ ...props
129
+ }: React.ComponentProps<typeof DialogPrimitive.Title>) {
130
+ return (
131
+ <DialogPrimitive.Title
132
+ data-slot="dialog-title"
133
+ className={cn(
134
+ "font-heading text-lg leading-none text-brand-primary font-semibold",
135
+ className
136
+ )}
137
+ {...props}
138
+ />
139
+ )
140
+ }
141
+
142
+ function DialogDescription({
143
+ className,
144
+ ...props
145
+ }: React.ComponentProps<typeof DialogPrimitive.Description>) {
146
+ return (
147
+ <DialogPrimitive.Description
148
+ data-slot="dialog-description"
149
+ className={cn(
150
+ "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
151
+ className
152
+ )}
153
+ {...props}
154
+ />
155
+ )
156
+ }
157
+
158
+ export {
159
+ Dialog,
160
+ DialogClose,
161
+ DialogContent,
162
+ DialogDescription,
163
+ DialogFooter,
164
+ DialogHeader,
165
+ DialogOverlay,
166
+ DialogPortal,
167
+ DialogTitle,
168
+ DialogTrigger,
169
+ }