tokka-ui 0.1.0 → 0.2.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 (157) hide show
  1. package/dist/accordion.d.ts +9 -0
  2. package/dist/accordion.js +51 -0
  3. package/dist/alert-dialog.d.ts +23 -0
  4. package/dist/alert-dialog.js +122 -0
  5. package/dist/alert.d.ts +11 -0
  6. package/dist/alert.js +55 -0
  7. package/dist/aspect-ratio.d.ts +6 -0
  8. package/dist/aspect-ratio.js +6 -0
  9. package/dist/avatar.d.ts +8 -0
  10. package/dist/avatar.js +46 -0
  11. package/dist/badge.d.ts +13 -0
  12. package/dist/badge.js +31 -0
  13. package/dist/breadcrumb.d.ts +22 -0
  14. package/dist/breadcrumb.js +97 -0
  15. package/dist/button.d.ts +1 -1
  16. package/dist/button.js +4 -51
  17. package/dist/calendar.d.ts +11 -0
  18. package/dist/calendar.js +8 -0
  19. package/dist/carousel.d.ts +23 -0
  20. package/dist/carousel.js +200 -0
  21. package/dist/chart.d.ts +1 -0
  22. package/dist/chart.js +2 -0
  23. package/dist/checkbox.d.ts +6 -0
  24. package/dist/checkbox.js +31 -0
  25. package/dist/chunk-63HUTNB3.js +92 -0
  26. package/dist/chunk-7BHODGBN.js +25 -0
  27. package/dist/chunk-A4HW2TQU.js +66 -0
  28. package/dist/chunk-BOKKBA25.js +30 -0
  29. package/dist/chunk-DVPPDIDA.js +57 -0
  30. package/dist/chunk-FJGEWLIV.js +109 -0
  31. package/dist/chunk-KDTBFEE2.js +123 -0
  32. package/dist/chunk-PLLTYLGO.js +120 -0
  33. package/dist/chunk-QBAV4RWS.js +43 -0
  34. package/dist/collapsible.d.ts +8 -0
  35. package/dist/collapsible.js +10 -0
  36. package/dist/combobox.d.ts +6 -0
  37. package/dist/combobox.js +32 -0
  38. package/dist/command.d.ts +85 -0
  39. package/dist/command.js +24 -0
  40. package/dist/context-menu.d.ts +30 -0
  41. package/dist/context-menu.js +157 -0
  42. package/dist/data-table.d.ts +2 -0
  43. package/dist/data-table.js +21 -0
  44. package/dist/date-picker.d.ts +6 -0
  45. package/dist/date-picker.js +16 -0
  46. package/dist/dialog.d.ts +22 -0
  47. package/dist/dialog.js +25 -0
  48. package/dist/drawer.d.ts +27 -0
  49. package/dist/drawer.js +105 -0
  50. package/dist/dropdown-menu.d.ts +30 -0
  51. package/dist/dropdown-menu.js +155 -0
  52. package/dist/form.d.ts +28 -0
  53. package/dist/form.js +120 -0
  54. package/dist/hover-card.d.ts +8 -0
  55. package/dist/hover-card.js +29 -0
  56. package/dist/input-otp.d.ts +37 -0
  57. package/dist/input-otp.js +53 -0
  58. package/dist/label.d.ts +8 -0
  59. package/dist/label.js +7 -0
  60. package/dist/menubar.d.ts +31 -0
  61. package/dist/menubar.js +186 -0
  62. package/dist/native-select.d.ts +7 -0
  63. package/dist/native-select.js +31 -0
  64. package/dist/navigation-menu.d.ts +15 -0
  65. package/dist/navigation-menu.js +111 -0
  66. package/dist/pagination.d.ts +33 -0
  67. package/dist/pagination.js +111 -0
  68. package/dist/popover.d.ts +8 -0
  69. package/dist/popover.js +11 -0
  70. package/dist/progress.d.ts +6 -0
  71. package/dist/progress.js +30 -0
  72. package/dist/radio-group.d.ts +7 -0
  73. package/dist/radio-group.js +39 -0
  74. package/dist/resizable.d.ts +27 -0
  75. package/dist/resizable.js +42 -0
  76. package/dist/scroll-area.d.ts +7 -0
  77. package/dist/scroll-area.js +42 -0
  78. package/dist/select.d.ts +15 -0
  79. package/dist/select.js +128 -0
  80. package/dist/separator.d.ts +6 -0
  81. package/dist/separator.js +28 -0
  82. package/dist/sheet.d.ts +29 -0
  83. package/dist/sheet.js +25 -0
  84. package/dist/sidebar.d.ts +30 -0
  85. package/dist/sidebar.js +203 -0
  86. package/dist/skeleton.d.ts +5 -0
  87. package/dist/skeleton.js +21 -0
  88. package/dist/slider.d.ts +6 -0
  89. package/dist/slider.js +27 -0
  90. package/dist/sonner.d.ts +7 -0
  91. package/dist/sonner.js +23 -0
  92. package/dist/spinner.d.ts +12 -0
  93. package/dist/spinner.js +29 -0
  94. package/dist/switch.d.ts +6 -0
  95. package/dist/switch.js +31 -0
  96. package/dist/table.d.ts +12 -0
  97. package/dist/table.js +21 -0
  98. package/dist/tabs.d.ts +9 -0
  99. package/dist/tabs.js +51 -0
  100. package/dist/textarea.d.ts +7 -0
  101. package/dist/textarea.js +26 -0
  102. package/dist/toggle-group.d.ts +15 -0
  103. package/dist/toggle-group.js +49 -0
  104. package/dist/toggle.d.ts +15 -0
  105. package/dist/toggle.js +9 -0
  106. package/dist/tooltip.d.ts +9 -0
  107. package/dist/tooltip.js +30 -0
  108. package/package.json +237 -8
  109. package/src/accordion.tsx +55 -0
  110. package/src/alert-dialog.tsx +138 -0
  111. package/src/alert.tsx +58 -0
  112. package/src/aspect-ratio.tsx +5 -0
  113. package/src/avatar.tsx +47 -0
  114. package/src/badge.tsx +35 -0
  115. package/src/breadcrumb.tsx +114 -0
  116. package/src/calendar.tsx +63 -0
  117. package/src/carousel.tsx +259 -0
  118. package/src/chart.tsx +9 -0
  119. package/src/checkbox.tsx +27 -0
  120. package/src/collapsible.tsx +9 -0
  121. package/src/combobox.tsx +8 -0
  122. package/src/command.tsx +152 -0
  123. package/src/context-menu.tsx +197 -0
  124. package/src/data-table.tsx +9 -0
  125. package/src/date-picker.tsx +8 -0
  126. package/src/dialog.tsx +119 -0
  127. package/src/drawer.tsx +115 -0
  128. package/src/dropdown-menu.tsx +197 -0
  129. package/src/form.tsx +175 -0
  130. package/src/hover-card.tsx +26 -0
  131. package/src/input-otp.tsx +68 -0
  132. package/src/label.tsx +23 -0
  133. package/src/menubar.tsx +233 -0
  134. package/src/native-select.tsx +29 -0
  135. package/src/navigation-menu.tsx +127 -0
  136. package/src/pagination.tsx +116 -0
  137. package/src/popover.tsx +28 -0
  138. package/src/progress.tsx +25 -0
  139. package/src/radio-group.tsx +41 -0
  140. package/src/resizable.tsx +42 -0
  141. package/src/scroll-area.tsx +45 -0
  142. package/src/select.tsx +157 -0
  143. package/src/separator.tsx +28 -0
  144. package/src/sheet.tsx +137 -0
  145. package/src/sidebar.tsx +249 -0
  146. package/src/skeleton.tsx +15 -0
  147. package/src/slider.tsx +25 -0
  148. package/src/sonner.tsx +25 -0
  149. package/src/spinner.tsx +33 -0
  150. package/src/switch.tsx +26 -0
  151. package/src/table.tsx +116 -0
  152. package/src/tabs.tsx +52 -0
  153. package/src/textarea.tsx +23 -0
  154. package/src/toggle-group.tsx +58 -0
  155. package/src/toggle.tsx +42 -0
  156. package/src/tooltip.tsx +27 -0
  157. package/LICENSE +0 -21
@@ -0,0 +1,114 @@
1
+ import * as React from "react"
2
+ import { ChevronRight, MoreHorizontal } from "lucide-react"
3
+ import { Slot } from "@radix-ui/react-slot"
4
+ import { cn } from "./lib/utils"
5
+
6
+ const Breadcrumb = React.forwardRef<
7
+ HTMLElement,
8
+ React.ComponentPropsWithoutRef<"nav"> & {
9
+ separator?: React.ReactNode
10
+ }
11
+ >(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />)
12
+ Breadcrumb.displayName = "Breadcrumb"
13
+
14
+ const BreadcrumbList = React.forwardRef<
15
+ HTMLOListElement,
16
+ React.ComponentPropsWithoutRef<"ol">
17
+ >(({ className, ...props }, ref) => (
18
+ <ol
19
+ ref={ref}
20
+ className={cn(
21
+ "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
22
+ className
23
+ )}
24
+ {...props}
25
+ />
26
+ ))
27
+ BreadcrumbList.displayName = "BreadcrumbList"
28
+
29
+ const BreadcrumbItem = React.forwardRef<
30
+ HTMLLIElement,
31
+ React.ComponentPropsWithoutRef<"li">
32
+ >(({ className, ...props }, ref) => (
33
+ <li
34
+ ref={ref}
35
+ className={cn("inline-flex items-center gap-1.5", className)}
36
+ {...props}
37
+ />
38
+ ))
39
+ BreadcrumbItem.displayName = "BreadcrumbItem"
40
+
41
+ const BreadcrumbLink = React.forwardRef<
42
+ HTMLAnchorElement,
43
+ React.ComponentPropsWithoutRef<"a"> & {
44
+ asChild?: boolean
45
+ }
46
+ >(({ asChild, className, ...props }, ref) => {
47
+ const Comp = asChild ? Slot : "a"
48
+
49
+ return (
50
+ <Comp
51
+ ref={ref}
52
+ className={cn("transition-colors hover:text-foreground", className)}
53
+ {...props}
54
+ />
55
+ )
56
+ })
57
+ BreadcrumbLink.displayName = "BreadcrumbLink"
58
+
59
+ const BreadcrumbPage = React.forwardRef<
60
+ HTMLSpanElement,
61
+ React.ComponentPropsWithoutRef<"span">
62
+ >(({ className, ...props }, ref) => (
63
+ <span
64
+ ref={ref}
65
+ role="link"
66
+ aria-disabled="true"
67
+ aria-current="page"
68
+ className={cn("font-normal text-foreground", className)}
69
+ {...props}
70
+ />
71
+ ))
72
+ BreadcrumbPage.displayName = "BreadcrumbPage"
73
+
74
+ const BreadcrumbSeparator = ({
75
+ children,
76
+ className,
77
+ ...props
78
+ }: React.ComponentProps<"li">) => (
79
+ <li
80
+ role="presentation"
81
+ aria-hidden="true"
82
+ className={cn("[&>svg]:size-3.5", className)}
83
+ {...props}
84
+ >
85
+ {children ?? <ChevronRight />}
86
+ </li>
87
+ )
88
+ BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
89
+
90
+ const BreadcrumbEllipsis = ({
91
+ className,
92
+ ...props
93
+ }: React.ComponentProps<"span">) => (
94
+ <span
95
+ role="presentation"
96
+ aria-hidden="true"
97
+ className={cn("flex size-9 items-center justify-center", className)}
98
+ {...props}
99
+ >
100
+ <MoreHorizontal className="size-4" />
101
+ <span className="sr-only">More</span>
102
+ </span>
103
+ )
104
+ BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
105
+
106
+ export {
107
+ Breadcrumb,
108
+ BreadcrumbList,
109
+ BreadcrumbItem,
110
+ BreadcrumbLink,
111
+ BreadcrumbPage,
112
+ BreadcrumbSeparator,
113
+ BreadcrumbEllipsis,
114
+ }
@@ -0,0 +1,63 @@
1
+ import * as React from "react"
2
+ import { DayPicker } from "react-day-picker"
3
+ import { ChevronLeft, ChevronRight } from "lucide-react"
4
+ import { cn } from "./lib/utils"
5
+ import { buttonVariants } from "./button"
6
+
7
+ export type CalendarProps = React.ComponentProps<typeof DayPicker>
8
+
9
+ function Calendar({
10
+ className,
11
+ classNames,
12
+ showOutsideDays = true,
13
+ ...props
14
+ }: CalendarProps) {
15
+ return (
16
+ <DayPicker
17
+ showOutsideDays={showOutsideDays}
18
+ className={cn("p-3", className)}
19
+ classNames={{
20
+ months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
21
+ month: "space-y-4",
22
+ caption: "flex justify-center pt-1 relative items-center",
23
+ caption_label: "text-sm font-medium",
24
+ nav: "space-x-1 flex items-center",
25
+ nav_button: cn(
26
+ buttonVariants({ variant: "outline" }),
27
+ "size-7 bg-transparent p-0 opacity-50 hover:opacity-100"
28
+ ),
29
+ nav_button_previous: "absolute left-1",
30
+ nav_button_next: "absolute right-1",
31
+ table: "w-full border-collapse space-y-1",
32
+ head_row: "flex",
33
+ head_cell:
34
+ "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
35
+ row: "flex w-full mt-2",
36
+ cell: "size-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
37
+ day: cn(
38
+ buttonVariants({ variant: "ghost" }),
39
+ "size-9 p-0 font-normal aria-selected:opacity-100"
40
+ ),
41
+ day_range_end: "day-range-end",
42
+ day_selected:
43
+ "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
44
+ day_today: "bg-accent text-accent-foreground",
45
+ day_outside:
46
+ "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
47
+ day_disabled: "text-muted-foreground opacity-50",
48
+ day_range_middle:
49
+ "aria-selected:bg-accent aria-selected:text-accent-foreground",
50
+ day_hidden: "invisible",
51
+ ...classNames,
52
+ }}
53
+ components={{
54
+ IconLeft: () => <ChevronLeft className="size-4" />,
55
+ IconRight: () => <ChevronRight className="size-4" />,
56
+ }}
57
+ {...props}
58
+ />
59
+ )
60
+ }
61
+ Calendar.displayName = "Calendar"
62
+
63
+ export { Calendar }
@@ -0,0 +1,259 @@
1
+ import * as React from "react"
2
+ import useEmblaCarousel, {
3
+ type UseEmblaCarouselType,
4
+ } from "embla-carousel-react"
5
+ import { ArrowLeft, ArrowRight } from "lucide-react"
6
+ import { cn } from "./lib/utils"
7
+ import { Button } from "./button"
8
+
9
+ type CarouselApi = UseEmblaCarouselType[1]
10
+ type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
11
+ type CarouselOptions = UseCarouselParameters[0]
12
+ type CarouselPlugin = UseCarouselParameters[1]
13
+
14
+ type CarouselProps = {
15
+ opts?: CarouselOptions
16
+ plugins?: CarouselPlugin
17
+ orientation?: "horizontal" | "vertical"
18
+ setApi?: (api: CarouselApi) => void
19
+ }
20
+
21
+ type CarouselContextProps = {
22
+ carouselRef: ReturnType<typeof useEmblaCarousel>[0]
23
+ api: ReturnType<typeof useEmblaCarousel>[1]
24
+ scrollPrev: () => void
25
+ scrollNext: () => void
26
+ canScrollPrev: boolean
27
+ canScrollNext: boolean
28
+ } & CarouselProps
29
+
30
+ const CarouselContext = React.createContext<CarouselContextProps | null>(null)
31
+
32
+ function useCarousel() {
33
+ const context = React.useContext(CarouselContext)
34
+
35
+ if (!context) {
36
+ throw new Error("useCarousel must be used within a <Carousel />")
37
+ }
38
+
39
+ return context
40
+ }
41
+
42
+ const Carousel = React.forwardRef<
43
+ HTMLDivElement,
44
+ React.HTMLAttributes<HTMLDivElement> & CarouselProps
45
+ >(
46
+ (
47
+ {
48
+ orientation = "horizontal",
49
+ opts,
50
+ setApi,
51
+ plugins,
52
+ className,
53
+ children,
54
+ ...props
55
+ },
56
+ ref
57
+ ) => {
58
+ const [carouselRef, api] = useEmblaCarousel(
59
+ {
60
+ ...opts,
61
+ axis: orientation === "horizontal" ? "x" : "y",
62
+ },
63
+ plugins
64
+ )
65
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false)
66
+ const [canScrollNext, setCanScrollNext] = React.useState(false)
67
+
68
+ const onSelect = React.useCallback((api: CarouselApi) => {
69
+ if (!api) {
70
+ return
71
+ }
72
+
73
+ setCanScrollPrev(api.canScrollPrev())
74
+ setCanScrollNext(api.canScrollNext())
75
+ }, [])
76
+
77
+ const scrollPrev = React.useCallback(() => {
78
+ api?.scrollPrev()
79
+ }, [api])
80
+
81
+ const scrollNext = React.useCallback(() => {
82
+ api?.scrollNext()
83
+ }, [api])
84
+
85
+ const handleKeyDown = React.useCallback(
86
+ (event: React.KeyboardEvent<HTMLDivElement>) => {
87
+ if (event.key === "ArrowLeft") {
88
+ event.preventDefault()
89
+ scrollPrev()
90
+ } else if (event.key === "ArrowRight") {
91
+ event.preventDefault()
92
+ scrollNext()
93
+ }
94
+ },
95
+ [scrollPrev, scrollNext]
96
+ )
97
+
98
+ React.useEffect(() => {
99
+ if (!api || !setApi) {
100
+ return
101
+ }
102
+
103
+ setApi(api)
104
+ }, [api, setApi])
105
+
106
+ React.useEffect(() => {
107
+ if (!api) {
108
+ return
109
+ }
110
+
111
+ onSelect(api)
112
+ api.on("reInit", onSelect)
113
+ api.on("select", onSelect)
114
+
115
+ return () => {
116
+ api?.off("select", onSelect)
117
+ }
118
+ }, [api, onSelect])
119
+
120
+ return (
121
+ <CarouselContext.Provider
122
+ value={{
123
+ carouselRef,
124
+ api: api,
125
+ opts,
126
+ orientation:
127
+ orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
128
+ scrollPrev,
129
+ scrollNext,
130
+ canScrollPrev,
131
+ canScrollNext,
132
+ }}
133
+ >
134
+ <div
135
+ ref={ref}
136
+ onKeyDownCapture={handleKeyDown}
137
+ className={cn("relative", className)}
138
+ role="region"
139
+ aria-roledescription="carousel"
140
+ {...props}
141
+ >
142
+ {children}
143
+ </div>
144
+ </CarouselContext.Provider>
145
+ )
146
+ }
147
+ )
148
+ Carousel.displayName = "Carousel"
149
+
150
+ const CarouselContent = React.forwardRef<
151
+ HTMLDivElement,
152
+ React.HTMLAttributes<HTMLDivElement>
153
+ >(({ className, ...props }, ref) => {
154
+ const { carouselRef, orientation } = useCarousel()
155
+
156
+ return (
157
+ <div ref={carouselRef} className="overflow-hidden">
158
+ <div
159
+ ref={ref}
160
+ className={cn(
161
+ "flex",
162
+ orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
163
+ className
164
+ )}
165
+ {...props}
166
+ />
167
+ </div>
168
+ )
169
+ })
170
+ CarouselContent.displayName = "CarouselContent"
171
+
172
+ const CarouselItem = React.forwardRef<
173
+ HTMLDivElement,
174
+ React.HTMLAttributes<HTMLDivElement>
175
+ >(({ className, ...props }, ref) => {
176
+ const { orientation } = useCarousel()
177
+
178
+ return (
179
+ <div
180
+ ref={ref}
181
+ role="group"
182
+ aria-roledescription="slide"
183
+ className={cn(
184
+ "min-w-0 shrink-0 grow-0 basis-full",
185
+ orientation === "horizontal" ? "pl-4" : "pt-4",
186
+ className
187
+ )}
188
+ {...props}
189
+ />
190
+ )
191
+ })
192
+ CarouselItem.displayName = "CarouselItem"
193
+
194
+ const CarouselPrevious = React.forwardRef<
195
+ HTMLButtonElement,
196
+ React.ComponentProps<typeof Button>
197
+ >(({ className, variant = "outline", size = "icon", ...props }, ref) => {
198
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel()
199
+
200
+ return (
201
+ <Button
202
+ ref={ref}
203
+ variant={variant}
204
+ size={size}
205
+ className={cn(
206
+ "absolute size-8 rounded-full",
207
+ orientation === "horizontal"
208
+ ? "-left-12 top-1/2 -translate-y-1/2"
209
+ : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
210
+ className
211
+ )}
212
+ disabled={!canScrollPrev}
213
+ onClick={scrollPrev}
214
+ {...props}
215
+ >
216
+ <ArrowLeft className="size-4" />
217
+ <span className="sr-only">Previous slide</span>
218
+ </Button>
219
+ )
220
+ })
221
+ CarouselPrevious.displayName = "CarouselPrevious"
222
+
223
+ const CarouselNext = React.forwardRef<
224
+ HTMLButtonElement,
225
+ React.ComponentProps<typeof Button>
226
+ >(({ className, variant = "outline", size = "icon", ...props }, ref) => {
227
+ const { orientation, scrollNext, canScrollNext } = useCarousel()
228
+
229
+ return (
230
+ <Button
231
+ ref={ref}
232
+ variant={variant}
233
+ size={size}
234
+ className={cn(
235
+ "absolute size-8 rounded-full",
236
+ orientation === "horizontal"
237
+ ? "-right-12 top-1/2 -translate-y-1/2"
238
+ : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
239
+ className
240
+ )}
241
+ disabled={!canScrollNext}
242
+ onClick={scrollNext}
243
+ {...props}
244
+ >
245
+ <ArrowRight className="size-4" />
246
+ <span className="sr-only">Next slide</span>
247
+ </Button>
248
+ )
249
+ })
250
+ CarouselNext.displayName = "CarouselNext"
251
+
252
+ export {
253
+ type CarouselApi,
254
+ Carousel,
255
+ CarouselContent,
256
+ CarouselItem,
257
+ CarouselPrevious,
258
+ CarouselNext,
259
+ }
package/src/chart.tsx ADDED
@@ -0,0 +1,9 @@
1
+ // Note: Chart is a comprehensive component built on recharts
2
+ // This is a placeholder export. Full implementation would be very large.
3
+ // Users should refer to https://ui.shadcn.com/docs/components/chart for the complete implementation.
4
+
5
+ // Re-export recharts for users who want to build charts
6
+ export * from "recharts"
7
+
8
+ // The chart component in shadcn is actually a pattern/example rather than a single component
9
+ // It demonstrates how to build charts with recharts + tailwind styling
@@ -0,0 +1,27 @@
1
+ import * as React from "react"
2
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
3
+ import { Check } from "lucide-react"
4
+ import { cn } from "./lib/utils"
5
+
6
+ const Checkbox = React.forwardRef<
7
+ React.ElementRef<typeof CheckboxPrimitive.Root>,
8
+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
9
+ >(({ className, ...props }, ref) => (
10
+ <CheckboxPrimitive.Root
11
+ ref={ref}
12
+ className={cn(
13
+ "peer size-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
14
+ className
15
+ )}
16
+ {...props}
17
+ >
18
+ <CheckboxPrimitive.Indicator
19
+ className={cn("flex items-center justify-center text-current")}
20
+ >
21
+ <Check className="size-4" />
22
+ </CheckboxPrimitive.Indicator>
23
+ </CheckboxPrimitive.Root>
24
+ ))
25
+ Checkbox.displayName = CheckboxPrimitive.Root.displayName
26
+
27
+ export { Checkbox }
@@ -0,0 +1,9 @@
1
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
2
+
3
+ const Collapsible = CollapsiblePrimitive.Root
4
+
5
+ const CollapsibleTrigger = CollapsiblePrimitive.Trigger
6
+
7
+ const CollapsibleContent = CollapsiblePrimitive.Content
8
+
9
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent }
@@ -0,0 +1,8 @@
1
+ // Combobox is a composition of Command + Popover
2
+ // This provides the building blocks - users compose them together
3
+
4
+ export * from "./command"
5
+ export * from "./popover"
6
+
7
+ // Example usage documented at: https://ui.shadcn.com/docs/components/combobox
8
+ // Combobox = Popover + Command + custom state management
@@ -0,0 +1,152 @@
1
+ import * as React from "react"
2
+ import { type DialogProps } from "@radix-ui/react-dialog"
3
+ import { Command as CommandPrimitive } from "cmdk"
4
+ import { Search } from "lucide-react"
5
+ import { cn } from "./lib/utils"
6
+ import { Dialog, DialogContent } from "./dialog"
7
+
8
+ const Command = React.forwardRef<
9
+ React.ElementRef<typeof CommandPrimitive>,
10
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive>
11
+ >(({ className, ...props }, ref) => (
12
+ <CommandPrimitive
13
+ ref={ref}
14
+ className={cn(
15
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
16
+ className
17
+ )}
18
+ {...props}
19
+ />
20
+ ))
21
+ Command.displayName = CommandPrimitive.displayName
22
+
23
+ interface CommandDialogProps extends DialogProps {}
24
+
25
+ const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
26
+ return (
27
+ <Dialog {...props}>
28
+ <DialogContent className="overflow-hidden p-0 shadow-lg">
29
+ <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:size-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:size-5">
30
+ {children}
31
+ </Command>
32
+ </DialogContent>
33
+ </Dialog>
34
+ )
35
+ }
36
+
37
+ const CommandInput = React.forwardRef<
38
+ React.ElementRef<typeof CommandPrimitive.Input>,
39
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
40
+ >(({ className, ...props }, ref) => (
41
+ <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
42
+ <Search className="mr-2 size-4 shrink-0 opacity-50" />
43
+ <CommandPrimitive.Input
44
+ ref={ref}
45
+ className={cn(
46
+ "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
47
+ className
48
+ )}
49
+ {...props}
50
+ />
51
+ </div>
52
+ ))
53
+
54
+ CommandInput.displayName = CommandPrimitive.Input.displayName
55
+
56
+ const CommandList = React.forwardRef<
57
+ React.ElementRef<typeof CommandPrimitive.List>,
58
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
59
+ >(({ className, ...props }, ref) => (
60
+ <CommandPrimitive.List
61
+ ref={ref}
62
+ className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
63
+ {...props}
64
+ />
65
+ ))
66
+
67
+ CommandList.displayName = CommandPrimitive.List.displayName
68
+
69
+ const CommandEmpty = React.forwardRef<
70
+ React.ElementRef<typeof CommandPrimitive.Empty>,
71
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
72
+ >((props, ref) => (
73
+ <CommandPrimitive.Empty
74
+ ref={ref}
75
+ className="py-6 text-center text-sm"
76
+ {...props}
77
+ />
78
+ ))
79
+
80
+ CommandEmpty.displayName = CommandPrimitive.Empty.displayName
81
+
82
+ const CommandGroup = React.forwardRef<
83
+ React.ElementRef<typeof CommandPrimitive.Group>,
84
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
85
+ >(({ className, ...props }, ref) => (
86
+ <CommandPrimitive.Group
87
+ ref={ref}
88
+ className={cn(
89
+ "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
90
+ className
91
+ )}
92
+ {...props}
93
+ />
94
+ ))
95
+
96
+ CommandGroup.displayName = CommandPrimitive.Group.displayName
97
+
98
+ const CommandSeparator = React.forwardRef<
99
+ React.ElementRef<typeof CommandPrimitive.Separator>,
100
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
101
+ >(({ className, ...props }, ref) => (
102
+ <CommandPrimitive.Separator
103
+ ref={ref}
104
+ className={cn("-mx-1 h-px bg-border", className)}
105
+ {...props}
106
+ />
107
+ ))
108
+ CommandSeparator.displayName = CommandPrimitive.Separator.displayName
109
+
110
+ const CommandItem = React.forwardRef<
111
+ React.ElementRef<typeof CommandPrimitive.Item>,
112
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
113
+ >(({ className, ...props }, ref) => (
114
+ <CommandPrimitive.Item
115
+ ref={ref}
116
+ className={cn(
117
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
118
+ className
119
+ )}
120
+ {...props}
121
+ />
122
+ ))
123
+
124
+ CommandItem.displayName = CommandPrimitive.Item.displayName
125
+
126
+ const CommandShortcut = ({
127
+ className,
128
+ ...props
129
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
130
+ return (
131
+ <span
132
+ className={cn(
133
+ "ml-auto text-xs tracking-widest text-muted-foreground",
134
+ className
135
+ )}
136
+ {...props}
137
+ />
138
+ )
139
+ }
140
+ CommandShortcut.displayName = "CommandShortcut"
141
+
142
+ export {
143
+ Command,
144
+ CommandDialog,
145
+ CommandInput,
146
+ CommandList,
147
+ CommandEmpty,
148
+ CommandGroup,
149
+ CommandItem,
150
+ CommandShortcut,
151
+ CommandSeparator,
152
+ }