create-deesse-app 0.3.0 → 0.4.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 (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,156 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cva, type VariantProps } from "class-variance-authority"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { Button } from "@/components/ui/button"
8
+ import { Input } from "@/components/ui/input"
9
+ import { Textarea } from "@/components/ui/textarea"
10
+
11
+ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
12
+ return (
13
+ <div
14
+ data-slot="input-group"
15
+ role="group"
16
+ className={cn(
17
+ "group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ const inputGroupAddonVariants = cva(
26
+ "flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",
27
+ {
28
+ variants: {
29
+ align: {
30
+ "inline-start":
31
+ "order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]",
32
+ "inline-end":
33
+ "order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]",
34
+ "block-start":
35
+ "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
36
+ "block-end":
37
+ "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2",
38
+ },
39
+ },
40
+ defaultVariants: {
41
+ align: "inline-start",
42
+ },
43
+ }
44
+ )
45
+
46
+ function InputGroupAddon({
47
+ className,
48
+ align = "inline-start",
49
+ ...props
50
+ }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
51
+ return (
52
+ <div
53
+ role="group"
54
+ data-slot="input-group-addon"
55
+ data-align={align}
56
+ className={cn(inputGroupAddonVariants({ align }), className)}
57
+ onClick={(e) => {
58
+ if ((e.target as HTMLElement).closest("button")) {
59
+ return
60
+ }
61
+ e.currentTarget.parentElement?.querySelector("input")?.focus()
62
+ }}
63
+ {...props}
64
+ />
65
+ )
66
+ }
67
+
68
+ const inputGroupButtonVariants = cva(
69
+ "flex items-center gap-2 text-sm shadow-none",
70
+ {
71
+ variants: {
72
+ size: {
73
+ xs: "h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
74
+ sm: "",
75
+ "icon-xs":
76
+ "size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0",
77
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0",
78
+ },
79
+ },
80
+ defaultVariants: {
81
+ size: "xs",
82
+ },
83
+ }
84
+ )
85
+
86
+ function InputGroupButton({
87
+ className,
88
+ type = "button",
89
+ variant = "ghost",
90
+ size = "xs",
91
+ ...props
92
+ }: Omit<React.ComponentProps<typeof Button>, "size"> &
93
+ VariantProps<typeof inputGroupButtonVariants>) {
94
+ return (
95
+ <Button
96
+ type={type}
97
+ data-size={size}
98
+ variant={variant}
99
+ className={cn(inputGroupButtonVariants({ size }), className)}
100
+ {...props}
101
+ />
102
+ )
103
+ }
104
+
105
+ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
106
+ return (
107
+ <span
108
+ className={cn(
109
+ "flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
110
+ className
111
+ )}
112
+ {...props}
113
+ />
114
+ )
115
+ }
116
+
117
+ function InputGroupInput({
118
+ className,
119
+ ...props
120
+ }: React.ComponentProps<"input">) {
121
+ return (
122
+ <Input
123
+ data-slot="input-group-control"
124
+ className={cn(
125
+ "flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent",
126
+ className
127
+ )}
128
+ {...props}
129
+ />
130
+ )
131
+ }
132
+
133
+ function InputGroupTextarea({
134
+ className,
135
+ ...props
136
+ }: React.ComponentProps<"textarea">) {
137
+ return (
138
+ <Textarea
139
+ data-slot="input-group-control"
140
+ className={cn(
141
+ "flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent",
142
+ className
143
+ )}
144
+ {...props}
145
+ />
146
+ )
147
+ }
148
+
149
+ export {
150
+ InputGroup,
151
+ InputGroupAddon,
152
+ InputGroupButton,
153
+ InputGroupText,
154
+ InputGroupInput,
155
+ InputGroupTextarea,
156
+ }
@@ -0,0 +1,87 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { OTPInput, OTPInputContext } from "input-otp"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { MinusIcon } from "lucide-react"
8
+
9
+ function InputOTP({
10
+ className,
11
+ containerClassName,
12
+ ...props
13
+ }: React.ComponentProps<typeof OTPInput> & {
14
+ containerClassName?: string
15
+ }) {
16
+ return (
17
+ <OTPInput
18
+ data-slot="input-otp"
19
+ containerClassName={cn(
20
+ "cn-input-otp flex items-center has-disabled:opacity-50",
21
+ containerClassName
22
+ )}
23
+ spellCheck={false}
24
+ className={cn("disabled:cursor-not-allowed", className)}
25
+ {...props}
26
+ />
27
+ )
28
+ }
29
+
30
+ function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
31
+ return (
32
+ <div
33
+ data-slot="input-otp-group"
34
+ className={cn(
35
+ "flex items-center rounded-lg has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40",
36
+ className
37
+ )}
38
+ {...props}
39
+ />
40
+ )
41
+ }
42
+
43
+ function InputOTPSlot({
44
+ index,
45
+ className,
46
+ ...props
47
+ }: React.ComponentProps<"div"> & {
48
+ index: number
49
+ }) {
50
+ const inputOTPContext = React.useContext(OTPInputContext)
51
+ const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}
52
+
53
+ return (
54
+ <div
55
+ data-slot="input-otp-slot"
56
+ data-active={isActive}
57
+ className={cn(
58
+ "relative flex size-8 items-center justify-center border-y border-r border-input text-sm transition-all outline-none first:rounded-l-lg first:border-l last:rounded-r-lg aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-3 data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40",
59
+ className
60
+ )}
61
+ {...props}
62
+ >
63
+ {char}
64
+ {hasFakeCaret && (
65
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
66
+ <div className="h-4 w-px animate-caret-blink bg-foreground duration-1000" />
67
+ </div>
68
+ )}
69
+ </div>
70
+ )
71
+ }
72
+
73
+ function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) {
74
+ return (
75
+ <div
76
+ data-slot="input-otp-separator"
77
+ className="flex items-center [&_svg:not([class*='size-'])]:size-4"
78
+ role="separator"
79
+ {...props}
80
+ >
81
+ <MinusIcon
82
+ />
83
+ </div>
84
+ )
85
+ }
86
+
87
+ export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
@@ -0,0 +1,19 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
+ return (
7
+ <input
8
+ type={type}
9
+ data-slot="input"
10
+ className={cn(
11
+ "h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
12
+ className
13
+ )}
14
+ {...props}
15
+ />
16
+ )
17
+ }
18
+
19
+ export { Input }
@@ -0,0 +1,196 @@
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
+ import { Separator } from "@/components/ui/separator"
7
+
8
+ function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
9
+ return (
10
+ <div
11
+ role="list"
12
+ data-slot="item-group"
13
+ className={cn(
14
+ "group/item-group flex w-full flex-col gap-4 has-data-[size=sm]:gap-2.5 has-data-[size=xs]:gap-2",
15
+ className
16
+ )}
17
+ {...props}
18
+ />
19
+ )
20
+ }
21
+
22
+ function ItemSeparator({
23
+ className,
24
+ ...props
25
+ }: React.ComponentProps<typeof Separator>) {
26
+ return (
27
+ <Separator
28
+ data-slot="item-separator"
29
+ orientation="horizontal"
30
+ className={cn("my-2", className)}
31
+ {...props}
32
+ />
33
+ )
34
+ }
35
+
36
+ const itemVariants = cva(
37
+ "group/item flex w-full flex-wrap items-center rounded-lg border text-sm transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors [a]:hover:bg-muted",
38
+ {
39
+ variants: {
40
+ variant: {
41
+ default: "border-transparent",
42
+ outline: "border-border",
43
+ muted: "border-transparent bg-muted/50",
44
+ },
45
+ size: {
46
+ default: "gap-2.5 px-3 py-2.5",
47
+ sm: "gap-2.5 px-3 py-2.5",
48
+ xs: "gap-2 px-2.5 py-2 in-data-[slot=dropdown-menu-content]:p-0",
49
+ },
50
+ },
51
+ defaultVariants: {
52
+ variant: "default",
53
+ size: "default",
54
+ },
55
+ }
56
+ )
57
+
58
+ function Item({
59
+ className,
60
+ variant = "default",
61
+ size = "default",
62
+ asChild = false,
63
+ ...props
64
+ }: React.ComponentProps<"div"> &
65
+ VariantProps<typeof itemVariants> & { asChild?: boolean }) {
66
+ const Comp = asChild ? Slot.Root : "div"
67
+ return (
68
+ <Comp
69
+ data-slot="item"
70
+ data-variant={variant}
71
+ data-size={size}
72
+ className={cn(itemVariants({ variant, size, className }))}
73
+ {...props}
74
+ />
75
+ )
76
+ }
77
+
78
+ const itemMediaVariants = cva(
79
+ "flex shrink-0 items-center justify-center gap-2 group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start [&_svg]:pointer-events-none",
80
+ {
81
+ variants: {
82
+ variant: {
83
+ default: "bg-transparent",
84
+ icon: "[&_svg:not([class*='size-'])]:size-4",
85
+ image:
86
+ "size-10 overflow-hidden rounded-sm group-data-[size=sm]/item:size-8 group-data-[size=xs]/item:size-6 [&_img]:size-full [&_img]:object-cover",
87
+ },
88
+ },
89
+ defaultVariants: {
90
+ variant: "default",
91
+ },
92
+ }
93
+ )
94
+
95
+ function ItemMedia({
96
+ className,
97
+ variant = "default",
98
+ ...props
99
+ }: React.ComponentProps<"div"> & VariantProps<typeof itemMediaVariants>) {
100
+ return (
101
+ <div
102
+ data-slot="item-media"
103
+ data-variant={variant}
104
+ className={cn(itemMediaVariants({ variant, className }))}
105
+ {...props}
106
+ />
107
+ )
108
+ }
109
+
110
+ function ItemContent({ className, ...props }: React.ComponentProps<"div">) {
111
+ return (
112
+ <div
113
+ data-slot="item-content"
114
+ className={cn(
115
+ "flex flex-1 flex-col gap-1 group-data-[size=xs]/item:gap-0 [&+[data-slot=item-content]]:flex-none",
116
+ className
117
+ )}
118
+ {...props}
119
+ />
120
+ )
121
+ }
122
+
123
+ function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
124
+ return (
125
+ <div
126
+ data-slot="item-title"
127
+ className={cn(
128
+ "font-heading line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
129
+ className
130
+ )}
131
+ {...props}
132
+ />
133
+ )
134
+ }
135
+
136
+ function ItemDescription({ className, ...props }: React.ComponentProps<"p">) {
137
+ return (
138
+ <p
139
+ data-slot="item-description"
140
+ className={cn(
141
+ "line-clamp-2 text-left text-sm leading-normal font-normal text-muted-foreground group-data-[size=xs]/item:text-xs [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
142
+ className
143
+ )}
144
+ {...props}
145
+ />
146
+ )
147
+ }
148
+
149
+ function ItemActions({ className, ...props }: React.ComponentProps<"div">) {
150
+ return (
151
+ <div
152
+ data-slot="item-actions"
153
+ className={cn("flex items-center gap-2", className)}
154
+ {...props}
155
+ />
156
+ )
157
+ }
158
+
159
+ function ItemHeader({ className, ...props }: React.ComponentProps<"div">) {
160
+ return (
161
+ <div
162
+ data-slot="item-header"
163
+ className={cn(
164
+ "flex basis-full items-center justify-between gap-2",
165
+ className
166
+ )}
167
+ {...props}
168
+ />
169
+ )
170
+ }
171
+
172
+ function ItemFooter({ className, ...props }: React.ComponentProps<"div">) {
173
+ return (
174
+ <div
175
+ data-slot="item-footer"
176
+ className={cn(
177
+ "flex basis-full items-center justify-between gap-2",
178
+ className
179
+ )}
180
+ {...props}
181
+ />
182
+ )
183
+ }
184
+
185
+ export {
186
+ Item,
187
+ ItemMedia,
188
+ ItemContent,
189
+ ItemActions,
190
+ ItemGroup,
191
+ ItemSeparator,
192
+ ItemTitle,
193
+ ItemDescription,
194
+ ItemHeader,
195
+ ItemFooter,
196
+ }
@@ -0,0 +1,26 @@
1
+ import { cn } from "@/lib/utils"
2
+
3
+ function Kbd({ className, ...props }: React.ComponentProps<"kbd">) {
4
+ return (
5
+ <kbd
6
+ data-slot="kbd"
7
+ className={cn(
8
+ "pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background dark:in-data-[slot=tooltip-content]:bg-background/10 [&_svg:not([class*='size-'])]:size-3",
9
+ className
10
+ )}
11
+ {...props}
12
+ />
13
+ )
14
+ }
15
+
16
+ function KbdGroup({ className, ...props }: React.ComponentProps<"div">) {
17
+ return (
18
+ <kbd
19
+ data-slot="kbd-group"
20
+ className={cn("inline-flex items-center gap-1", className)}
21
+ {...props}
22
+ />
23
+ )
24
+ }
25
+
26
+ export { Kbd, KbdGroup }
@@ -0,0 +1,24 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Label as LabelPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ function Label({
9
+ className,
10
+ ...props
11
+ }: React.ComponentProps<typeof LabelPrimitive.Root>) {
12
+ return (
13
+ <LabelPrimitive.Root
14
+ data-slot="label"
15
+ className={cn(
16
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ )
22
+ }
23
+
24
+ export { Label }