create-deesse-app 0.3.0 → 0.4.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 (100) hide show
  1. package/dist/src/copy.d.ts.map +1 -1
  2. package/dist/src/copy.js +41 -66
  3. package/dist/src/copy.js.map +1 -1
  4. package/dist/tsconfig.tsbuildinfo +1 -1
  5. package/package.json +4 -5
  6. package/templates/default/.agents/skills/shadcn/SKILL.md +242 -0
  7. package/templates/default/.agents/skills/shadcn/agents/openai.yml +5 -0
  8. package/templates/default/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
  9. package/templates/default/.agents/skills/shadcn/assets/shadcn.png +0 -0
  10. package/templates/default/.agents/skills/shadcn/cli.md +257 -0
  11. package/templates/default/.agents/skills/shadcn/customization.md +202 -0
  12. package/templates/default/.agents/skills/shadcn/evals/evals.json +47 -0
  13. package/templates/default/.agents/skills/shadcn/mcp.md +94 -0
  14. package/templates/default/.agents/skills/shadcn/rules/base-vs-radix.md +306 -0
  15. package/templates/default/.agents/skills/shadcn/rules/composition.md +195 -0
  16. package/templates/default/.agents/skills/shadcn/rules/forms.md +192 -0
  17. package/templates/default/.agents/skills/shadcn/rules/icons.md +101 -0
  18. package/templates/default/.agents/skills/shadcn/rules/styling.md +162 -0
  19. package/templates/default/AGENTS.md +5 -0
  20. package/templates/default/CLAUDE.md +1 -0
  21. package/templates/default/README.md +28 -0
  22. package/templates/default/components.json +25 -0
  23. package/templates/default/eslint.config.mjs +18 -0
  24. package/templates/default/next.config.ts +7 -0
  25. package/templates/default/package.json +50 -0
  26. package/templates/default/postcss.config.mjs +7 -0
  27. package/templates/default/public/file.svg +1 -0
  28. package/templates/default/public/globe.svg +1 -0
  29. package/templates/default/public/nesalia.svg +50 -0
  30. package/templates/default/public/window.svg +1 -0
  31. package/templates/default/skills-lock.json +10 -0
  32. package/templates/default/src/app/(deesse)/admin/[[...slug]]/page.tsx +20 -0
  33. package/templates/default/src/app/(deesse)/admin/layout.tsx +7 -0
  34. package/templates/default/src/app/(frontend)/page.tsx +50 -0
  35. package/templates/default/src/app/globals.css +130 -0
  36. package/templates/default/src/app/icon.svg +109 -0
  37. package/templates/default/src/app/layout.tsx +33 -0
  38. package/templates/default/src/app/page.tsx +50 -0
  39. package/templates/default/src/components/providers/index.tsx +9 -0
  40. package/templates/default/src/components/providers/theme-provider.tsx +11 -0
  41. package/templates/default/src/components/ui/accordion.tsx +81 -0
  42. package/templates/default/src/components/ui/alert-dialog.tsx +199 -0
  43. package/templates/default/src/components/ui/alert.tsx +76 -0
  44. package/templates/default/src/components/ui/aspect-ratio.tsx +11 -0
  45. package/templates/default/src/components/ui/avatar.tsx +112 -0
  46. package/templates/default/src/components/ui/badge.tsx +49 -0
  47. package/templates/default/src/components/ui/breadcrumb.tsx +122 -0
  48. package/templates/default/src/components/ui/button-group.tsx +83 -0
  49. package/templates/default/src/components/ui/button.tsx +67 -0
  50. package/templates/default/src/components/ui/calendar.tsx +222 -0
  51. package/templates/default/src/components/ui/card.tsx +103 -0
  52. package/templates/default/src/components/ui/carousel.tsx +242 -0
  53. package/templates/default/src/components/ui/chart.tsx +373 -0
  54. package/templates/default/src/components/ui/checkbox.tsx +33 -0
  55. package/templates/default/src/components/ui/collapsible.tsx +33 -0
  56. package/templates/default/src/components/ui/combobox.tsx +299 -0
  57. package/templates/default/src/components/ui/command.tsx +195 -0
  58. package/templates/default/src/components/ui/context-menu.tsx +263 -0
  59. package/templates/default/src/components/ui/dialog.tsx +168 -0
  60. package/templates/default/src/components/ui/direction.tsx +22 -0
  61. package/templates/default/src/components/ui/drawer.tsx +134 -0
  62. package/templates/default/src/components/ui/dropdown-menu.tsx +269 -0
  63. package/templates/default/src/components/ui/empty.tsx +104 -0
  64. package/templates/default/src/components/ui/field.tsx +238 -0
  65. package/templates/default/src/components/ui/hover-card.tsx +44 -0
  66. package/templates/default/src/components/ui/input-group.tsx +156 -0
  67. package/templates/default/src/components/ui/input-otp.tsx +87 -0
  68. package/templates/default/src/components/ui/input.tsx +19 -0
  69. package/templates/default/src/components/ui/item.tsx +196 -0
  70. package/templates/default/src/components/ui/kbd.tsx +26 -0
  71. package/templates/default/src/components/ui/label.tsx +24 -0
  72. package/templates/default/src/components/ui/menubar.tsx +280 -0
  73. package/templates/default/src/components/ui/native-select.tsx +52 -0
  74. package/templates/default/src/components/ui/navigation-menu.tsx +164 -0
  75. package/templates/default/src/components/ui/pagination.tsx +129 -0
  76. package/templates/default/src/components/ui/popover.tsx +89 -0
  77. package/templates/default/src/components/ui/progress.tsx +31 -0
  78. package/templates/default/src/components/ui/radio-group.tsx +44 -0
  79. package/templates/default/src/components/ui/resizable.tsx +50 -0
  80. package/templates/default/src/components/ui/scroll-area.tsx +55 -0
  81. package/templates/default/src/components/ui/select.tsx +192 -0
  82. package/templates/default/src/components/ui/separator.tsx +28 -0
  83. package/templates/default/src/components/ui/sheet.tsx +147 -0
  84. package/templates/default/src/components/ui/sidebar.tsx +702 -0
  85. package/templates/default/src/components/ui/skeleton.tsx +13 -0
  86. package/templates/default/src/components/ui/slider.tsx +59 -0
  87. package/templates/default/src/components/ui/sonner.tsx +49 -0
  88. package/templates/default/src/components/ui/spinner.tsx +10 -0
  89. package/templates/default/src/components/ui/switch.tsx +33 -0
  90. package/templates/default/src/components/ui/table.tsx +116 -0
  91. package/templates/default/src/components/ui/tabs.tsx +90 -0
  92. package/templates/default/src/components/ui/textarea.tsx +18 -0
  93. package/templates/default/src/components/ui/toggle-group.tsx +89 -0
  94. package/templates/default/src/components/ui/toggle.tsx +46 -0
  95. package/templates/default/src/components/ui/tooltip.tsx +57 -0
  96. package/templates/default/src/deesse.config.ts +11 -0
  97. package/templates/default/src/hooks/use-mobile.ts +19 -0
  98. package/templates/default/src/lib/utils.ts +6 -0
  99. package/templates/default/tsconfig.json +35 -0
  100. package/templates/minimal/.gitkeep +0 -0
@@ -0,0 +1,81 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Accordion as AccordionPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"
8
+
9
+ function Accordion({
10
+ className,
11
+ ...props
12
+ }: React.ComponentProps<typeof AccordionPrimitive.Root>) {
13
+ return (
14
+ <AccordionPrimitive.Root
15
+ data-slot="accordion"
16
+ className={cn("flex w-full flex-col", className)}
17
+ {...props}
18
+ />
19
+ )
20
+ }
21
+
22
+ function AccordionItem({
23
+ className,
24
+ ...props
25
+ }: React.ComponentProps<typeof AccordionPrimitive.Item>) {
26
+ return (
27
+ <AccordionPrimitive.Item
28
+ data-slot="accordion-item"
29
+ className={cn("not-last:border-b", className)}
30
+ {...props}
31
+ />
32
+ )
33
+ }
34
+
35
+ function AccordionTrigger({
36
+ className,
37
+ children,
38
+ ...props
39
+ }: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
40
+ return (
41
+ <AccordionPrimitive.Header className="flex">
42
+ <AccordionPrimitive.Trigger
43
+ data-slot="accordion-trigger"
44
+ className={cn(
45
+ "group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left 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]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground",
46
+ className
47
+ )}
48
+ {...props}
49
+ >
50
+ {children}
51
+ <ChevronDownIcon data-slot="accordion-trigger-icon" className="pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden" />
52
+ <ChevronUpIcon data-slot="accordion-trigger-icon" className="pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline" />
53
+ </AccordionPrimitive.Trigger>
54
+ </AccordionPrimitive.Header>
55
+ )
56
+ }
57
+
58
+ function AccordionContent({
59
+ className,
60
+ children,
61
+ ...props
62
+ }: React.ComponentProps<typeof AccordionPrimitive.Content>) {
63
+ return (
64
+ <AccordionPrimitive.Content
65
+ data-slot="accordion-content"
66
+ className="overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
67
+ {...props}
68
+ >
69
+ <div
70
+ className={cn(
71
+ "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",
72
+ className
73
+ )}
74
+ >
75
+ {children}
76
+ </div>
77
+ </AccordionPrimitive.Content>
78
+ )
79
+ }
80
+
81
+ export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
@@ -0,0 +1,199 @@
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 "@/components/ui/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/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",
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-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]: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",
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-4 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
+ "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 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 AlertDialogMedia({
103
+ className,
104
+ ...props
105
+ }: React.ComponentProps<"div">) {
106
+ return (
107
+ <div
108
+ data-slot="alert-dialog-media"
109
+ className={cn(
110
+ "mb-2 inline-flex size-10 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6",
111
+ className
112
+ )}
113
+ {...props}
114
+ />
115
+ )
116
+ }
117
+
118
+ function AlertDialogTitle({
119
+ className,
120
+ ...props
121
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
122
+ return (
123
+ <AlertDialogPrimitive.Title
124
+ data-slot="alert-dialog-title"
125
+ className={cn(
126
+ "font-heading text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
127
+ className
128
+ )}
129
+ {...props}
130
+ />
131
+ )
132
+ }
133
+
134
+ function AlertDialogDescription({
135
+ className,
136
+ ...props
137
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
138
+ return (
139
+ <AlertDialogPrimitive.Description
140
+ data-slot="alert-dialog-description"
141
+ className={cn(
142
+ "text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
143
+ className
144
+ )}
145
+ {...props}
146
+ />
147
+ )
148
+ }
149
+
150
+ function AlertDialogAction({
151
+ className,
152
+ variant = "default",
153
+ size = "default",
154
+ ...props
155
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Action> &
156
+ Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
157
+ return (
158
+ <Button variant={variant} size={size} asChild>
159
+ <AlertDialogPrimitive.Action
160
+ data-slot="alert-dialog-action"
161
+ className={cn(className)}
162
+ {...props}
163
+ />
164
+ </Button>
165
+ )
166
+ }
167
+
168
+ function AlertDialogCancel({
169
+ className,
170
+ variant = "outline",
171
+ size = "default",
172
+ ...props
173
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel> &
174
+ Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
175
+ return (
176
+ <Button variant={variant} size={size} asChild>
177
+ <AlertDialogPrimitive.Cancel
178
+ data-slot="alert-dialog-cancel"
179
+ className={cn(className)}
180
+ {...props}
181
+ />
182
+ </Button>
183
+ )
184
+ }
185
+
186
+ export {
187
+ AlertDialog,
188
+ AlertDialogAction,
189
+ AlertDialogCancel,
190
+ AlertDialogContent,
191
+ AlertDialogDescription,
192
+ AlertDialogFooter,
193
+ AlertDialogHeader,
194
+ AlertDialogMedia,
195
+ AlertDialogOverlay,
196
+ AlertDialogPortal,
197
+ AlertDialogTitle,
198
+ AlertDialogTrigger,
199
+ }
@@ -0,0 +1,76 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const alertVariants = cva(
7
+ "group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: "bg-card text-card-foreground",
12
+ destructive:
13
+ "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current",
14
+ },
15
+ },
16
+ defaultVariants: {
17
+ variant: "default",
18
+ },
19
+ }
20
+ )
21
+
22
+ function Alert({
23
+ className,
24
+ variant,
25
+ ...props
26
+ }: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
27
+ return (
28
+ <div
29
+ data-slot="alert"
30
+ role="alert"
31
+ className={cn(alertVariants({ variant }), className)}
32
+ {...props}
33
+ />
34
+ )
35
+ }
36
+
37
+ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
38
+ return (
39
+ <div
40
+ data-slot="alert-title"
41
+ className={cn(
42
+ "font-heading font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
43
+ className
44
+ )}
45
+ {...props}
46
+ />
47
+ )
48
+ }
49
+
50
+ function AlertDescription({
51
+ className,
52
+ ...props
53
+ }: React.ComponentProps<"div">) {
54
+ return (
55
+ <div
56
+ data-slot="alert-description"
57
+ className={cn(
58
+ "text-sm text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
59
+ className
60
+ )}
61
+ {...props}
62
+ />
63
+ )
64
+ }
65
+
66
+ function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
67
+ return (
68
+ <div
69
+ data-slot="alert-action"
70
+ className={cn("absolute top-2 right-2", className)}
71
+ {...props}
72
+ />
73
+ )
74
+ }
75
+
76
+ export { Alert, AlertTitle, AlertDescription, AlertAction }
@@ -0,0 +1,11 @@
1
+ "use client"
2
+
3
+ import { AspectRatio as AspectRatioPrimitive } from "radix-ui"
4
+
5
+ function AspectRatio({
6
+ ...props
7
+ }: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {
8
+ return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...props} />
9
+ }
10
+
11
+ export { AspectRatio }
@@ -0,0 +1,112 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Avatar as AvatarPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ function Avatar({
9
+ className,
10
+ size = "default",
11
+ ...props
12
+ }: React.ComponentProps<typeof AvatarPrimitive.Root> & {
13
+ size?: "default" | "sm" | "lg"
14
+ }) {
15
+ return (
16
+ <AvatarPrimitive.Root
17
+ data-slot="avatar"
18
+ data-size={size}
19
+ className={cn(
20
+ "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",
21
+ className
22
+ )}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ function AvatarImage({
29
+ className,
30
+ ...props
31
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
32
+ return (
33
+ <AvatarPrimitive.Image
34
+ data-slot="avatar-image"
35
+ className={cn(
36
+ "aspect-square size-full rounded-full object-cover",
37
+ className
38
+ )}
39
+ {...props}
40
+ />
41
+ )
42
+ }
43
+
44
+ function AvatarFallback({
45
+ className,
46
+ ...props
47
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
48
+ return (
49
+ <AvatarPrimitive.Fallback
50
+ data-slot="avatar-fallback"
51
+ className={cn(
52
+ "flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs",
53
+ className
54
+ )}
55
+ {...props}
56
+ />
57
+ )
58
+ }
59
+
60
+ function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
61
+ return (
62
+ <span
63
+ data-slot="avatar-badge"
64
+ className={cn(
65
+ "absolute right-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",
66
+ "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
67
+ "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
68
+ "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
69
+ className
70
+ )}
71
+ {...props}
72
+ />
73
+ )
74
+ }
75
+
76
+ function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
77
+ return (
78
+ <div
79
+ data-slot="avatar-group"
80
+ className={cn(
81
+ "group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background",
82
+ className
83
+ )}
84
+ {...props}
85
+ />
86
+ )
87
+ }
88
+
89
+ function AvatarGroupCount({
90
+ className,
91
+ ...props
92
+ }: React.ComponentProps<"div">) {
93
+ return (
94
+ <div
95
+ data-slot="avatar-group-count"
96
+ className={cn(
97
+ "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",
98
+ className
99
+ )}
100
+ {...props}
101
+ />
102
+ )
103
+ }
104
+
105
+ export {
106
+ Avatar,
107
+ AvatarImage,
108
+ AvatarFallback,
109
+ AvatarGroup,
110
+ AvatarGroupCount,
111
+ AvatarBadge,
112
+ }
@@ -0,0 +1,49 @@
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
+ "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 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/80",
13
+ secondary:
14
+ "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
15
+ destructive:
16
+ "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
17
+ outline:
18
+ "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
19
+ ghost:
20
+ "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
21
+ link: "text-primary underline-offset-4 hover:underline",
22
+ },
23
+ },
24
+ defaultVariants: {
25
+ variant: "default",
26
+ },
27
+ }
28
+ )
29
+
30
+ function Badge({
31
+ className,
32
+ variant = "default",
33
+ asChild = false,
34
+ ...props
35
+ }: React.ComponentProps<"span"> &
36
+ VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
37
+ const Comp = asChild ? Slot.Root : "span"
38
+
39
+ return (
40
+ <Comp
41
+ data-slot="badge"
42
+ data-variant={variant}
43
+ className={cn(badgeVariants({ variant }), className)}
44
+ {...props}
45
+ />
46
+ )
47
+ }
48
+
49
+ export { Badge, badgeVariants }
@@ -0,0 +1,122 @@
1
+ import * as React from "react"
2
+ import { Slot } from "radix-ui"
3
+
4
+ import { cn } from "@/lib/utils"
5
+ import { ChevronRightIcon, MoreHorizontalIcon } from "lucide-react"
6
+
7
+ function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">) {
8
+ return (
9
+ <nav
10
+ aria-label="breadcrumb"
11
+ data-slot="breadcrumb"
12
+ className={cn(className)}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
19
+ return (
20
+ <ol
21
+ data-slot="breadcrumb-list"
22
+ className={cn(
23
+ "flex flex-wrap items-center gap-1.5 text-sm wrap-break-word text-muted-foreground",
24
+ className
25
+ )}
26
+ {...props}
27
+ />
28
+ )
29
+ }
30
+
31
+ function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
32
+ return (
33
+ <li
34
+ data-slot="breadcrumb-item"
35
+ className={cn("inline-flex items-center gap-1", className)}
36
+ {...props}
37
+ />
38
+ )
39
+ }
40
+
41
+ function BreadcrumbLink({
42
+ asChild,
43
+ className,
44
+ ...props
45
+ }: React.ComponentProps<"a"> & {
46
+ asChild?: boolean
47
+ }) {
48
+ const Comp = asChild ? Slot.Root : "a"
49
+
50
+ return (
51
+ <Comp
52
+ data-slot="breadcrumb-link"
53
+ className={cn("transition-colors hover:text-foreground", className)}
54
+ {...props}
55
+ />
56
+ )
57
+ }
58
+
59
+ function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
60
+ return (
61
+ <span
62
+ data-slot="breadcrumb-page"
63
+ role="link"
64
+ aria-disabled="true"
65
+ aria-current="page"
66
+ className={cn("font-normal text-foreground", className)}
67
+ {...props}
68
+ />
69
+ )
70
+ }
71
+
72
+ function BreadcrumbSeparator({
73
+ children,
74
+ className,
75
+ ...props
76
+ }: React.ComponentProps<"li">) {
77
+ return (
78
+ <li
79
+ data-slot="breadcrumb-separator"
80
+ role="presentation"
81
+ aria-hidden="true"
82
+ className={cn("[&>svg]:size-3.5", className)}
83
+ {...props}
84
+ >
85
+ {children ?? (
86
+ <ChevronRightIcon />
87
+ )}
88
+ </li>
89
+ )
90
+ }
91
+
92
+ function BreadcrumbEllipsis({
93
+ className,
94
+ ...props
95
+ }: React.ComponentProps<"span">) {
96
+ return (
97
+ <span
98
+ data-slot="breadcrumb-ellipsis"
99
+ role="presentation"
100
+ aria-hidden="true"
101
+ className={cn(
102
+ "flex size-5 items-center justify-center [&>svg]:size-4",
103
+ className
104
+ )}
105
+ {...props}
106
+ >
107
+ <MoreHorizontalIcon
108
+ />
109
+ <span className="sr-only">More</span>
110
+ </span>
111
+ )
112
+ }
113
+
114
+ export {
115
+ Breadcrumb,
116
+ BreadcrumbList,
117
+ BreadcrumbItem,
118
+ BreadcrumbLink,
119
+ BreadcrumbPage,
120
+ BreadcrumbSeparator,
121
+ BreadcrumbEllipsis,
122
+ }