@arronqzy/ui 0.0.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 (64) hide show
  1. package/.eslintrc.cjs +10 -0
  2. package/.turbo/turbo-lint.log +4 -0
  3. package/components.json +20 -0
  4. package/dist/styles.css +3105 -0
  5. package/index.ts +7 -0
  6. package/package.json +76 -0
  7. package/postcss.config.cjs +7 -0
  8. package/scripts/sync-shadcn.mjs +144 -0
  9. package/src/hooks/use-toast.ts +194 -0
  10. package/src/lib/overlay-z-index.ts +8 -0
  11. package/src/lib/utils.ts +7 -0
  12. package/src/styles.css +89 -0
  13. package/src/theme-provider.tsx +36 -0
  14. package/src/ui/accordion.tsx +58 -0
  15. package/src/ui/alert-dialog.tsx +149 -0
  16. package/src/ui/alert.tsx +59 -0
  17. package/src/ui/aspect-ratio.tsx +7 -0
  18. package/src/ui/avatar.tsx +50 -0
  19. package/src/ui/badge.tsx +36 -0
  20. package/src/ui/breadcrumb.tsx +115 -0
  21. package/src/ui/button.tsx +56 -0
  22. package/src/ui/calendar.tsx +213 -0
  23. package/src/ui/card.tsx +79 -0
  24. package/src/ui/carousel.tsx +262 -0
  25. package/src/ui/chart.tsx +403 -0
  26. package/src/ui/checkbox.tsx +30 -0
  27. package/src/ui/collapsible.tsx +11 -0
  28. package/src/ui/command.tsx +153 -0
  29. package/src/ui/context-menu.tsx +200 -0
  30. package/src/ui/dialog.tsx +130 -0
  31. package/src/ui/drawer.tsx +124 -0
  32. package/src/ui/dropdown-menu.tsx +200 -0
  33. package/src/ui/empty.tsx +50 -0
  34. package/src/ui/form.tsx +178 -0
  35. package/src/ui/hover-card.tsx +29 -0
  36. package/src/ui/index.ts +50 -0
  37. package/src/ui/input-otp.tsx +71 -0
  38. package/src/ui/input.tsx +22 -0
  39. package/src/ui/label.tsx +26 -0
  40. package/src/ui/menubar.tsx +256 -0
  41. package/src/ui/navigation-menu.tsx +128 -0
  42. package/src/ui/pagination.tsx +117 -0
  43. package/src/ui/popover.tsx +31 -0
  44. package/src/ui/progress.tsx +28 -0
  45. package/src/ui/radio-group.tsx +44 -0
  46. package/src/ui/resizable.tsx +46 -0
  47. package/src/ui/scroll-area.tsx +48 -0
  48. package/src/ui/select.tsx +160 -0
  49. package/src/ui/separator.tsx +31 -0
  50. package/src/ui/sheet.tsx +146 -0
  51. package/src/ui/skeleton.tsx +15 -0
  52. package/src/ui/slider.tsx +28 -0
  53. package/src/ui/sonner.tsx +45 -0
  54. package/src/ui/switch.tsx +29 -0
  55. package/src/ui/table.tsx +117 -0
  56. package/src/ui/tabs.tsx +55 -0
  57. package/src/ui/textarea.tsx +22 -0
  58. package/src/ui/toast.tsx +129 -0
  59. package/src/ui/toaster.tsx +35 -0
  60. package/src/ui/toggle-group.tsx +61 -0
  61. package/src/ui/toggle.tsx +45 -0
  62. package/src/ui/tooltip.tsx +32 -0
  63. package/tailwind.config.ts +8 -0
  64. package/tsconfig.json +5 -0
@@ -0,0 +1,403 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as RechartsPrimitive from "recharts"
5
+
6
+ import { cn } from "../lib/utils"
7
+
8
+ // Format: { THEME_NAME: CSS_SELECTOR }
9
+ const THEMES = { light: "", dark: ".dark" } as const
10
+
11
+ export type ChartConfig = {
12
+ [k in string]: {
13
+ label?: React.ReactNode
14
+ icon?: React.ComponentType
15
+ } & (
16
+ | { color?: string; theme?: never }
17
+ | { color?: never; theme: Record<keyof typeof THEMES, string> }
18
+ )
19
+ }
20
+
21
+ type ChartContextProps = {
22
+ config: ChartConfig
23
+ }
24
+
25
+ const ChartContext = React.createContext<ChartContextProps | null>(null)
26
+
27
+ function useChart() {
28
+ const context = React.useContext(ChartContext)
29
+
30
+ if (!context) {
31
+ throw new Error("useChart must be used within a <ChartContainer />")
32
+ }
33
+
34
+ return context
35
+ }
36
+
37
+ const ChartContainer = React.forwardRef<
38
+ HTMLDivElement,
39
+ React.ComponentProps<"div"> & {
40
+ config: ChartConfig
41
+ children: React.ComponentProps<
42
+ typeof RechartsPrimitive.ResponsiveContainer
43
+ >["children"]
44
+ }
45
+ >(({ id, className, children, config, ...props }, ref) => {
46
+ const uniqueId = React.useId()
47
+ const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
48
+
49
+ return (
50
+ <ChartContext.Provider value={{ config }}>
51
+ <div
52
+ data-chart={chartId}
53
+ ref={ref}
54
+ className={cn(
55
+ "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
56
+ className
57
+ )}
58
+ {...props}
59
+ >
60
+ <ChartStyle id={chartId} config={config} />
61
+ <RechartsPrimitive.ResponsiveContainer>
62
+ {children}
63
+ </RechartsPrimitive.ResponsiveContainer>
64
+ </div>
65
+ </ChartContext.Provider>
66
+ )
67
+ })
68
+ ChartContainer.displayName = "Chart"
69
+
70
+ const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
71
+ const colorConfig = Object.entries(config).filter(
72
+ ([, config]) => config.theme || config.color
73
+ )
74
+
75
+ if (!colorConfig.length) {
76
+ return null
77
+ }
78
+
79
+ return (
80
+ <style
81
+ dangerouslySetInnerHTML={{
82
+ __html: Object.entries(THEMES)
83
+ .map(
84
+ ([theme, prefix]) => `
85
+ ${prefix} [data-chart=${id}] {
86
+ ${colorConfig
87
+ .map(([key, itemConfig]) => {
88
+ const color =
89
+ itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||
90
+ itemConfig.color
91
+ return color ? ` --color-${key}: ${color};` : null
92
+ })
93
+ .join("\n")}
94
+ }
95
+ `
96
+ )
97
+ .join("\n"),
98
+ }}
99
+ />
100
+ )
101
+ }
102
+
103
+ const ChartTooltip = RechartsPrimitive.Tooltip
104
+
105
+ type RechartsInjectedTooltipProps = {
106
+ active?: boolean
107
+ payload?: RechartsInjectedTooltipPayloadItem[]
108
+ label?: unknown
109
+ labelFormatter?: (
110
+ label: unknown,
111
+ payload: RechartsInjectedTooltipPayloadItem[]
112
+ ) => React.ReactNode
113
+ labelClassName?: string
114
+ formatter?: (...args: unknown[]) => React.ReactNode
115
+ color?: unknown
116
+ }
117
+
118
+ type RechartsInjectedTooltipPayloadItem = {
119
+ type?: string
120
+ dataKey?: string
121
+ name?: string
122
+ value?: number | string
123
+ color?: string
124
+ payload?: { fill?: unknown } & Record<string, unknown>
125
+ } & Record<string, unknown>
126
+
127
+ const ChartTooltipContent = React.forwardRef<
128
+ HTMLDivElement,
129
+ RechartsInjectedTooltipProps &
130
+ React.ComponentProps<"div"> & {
131
+ hideLabel?: boolean
132
+ hideIndicator?: boolean
133
+ indicator?: "line" | "dot" | "dashed"
134
+ nameKey?: string
135
+ labelKey?: string
136
+ }
137
+ >(
138
+ (
139
+ {
140
+ active,
141
+ payload,
142
+ className,
143
+ indicator = "dot",
144
+ hideLabel = false,
145
+ hideIndicator = false,
146
+ label,
147
+ labelFormatter,
148
+ labelClassName,
149
+ formatter,
150
+ color,
151
+ nameKey,
152
+ labelKey,
153
+ },
154
+ ref
155
+ ) => {
156
+ const { config } = useChart()
157
+
158
+ const tooltipLabel = React.useMemo(() => {
159
+ if (hideLabel || !payload?.length) {
160
+ return null
161
+ }
162
+
163
+ const [item] = payload
164
+ const key = `${labelKey || item?.dataKey || item?.name || "value"}`
165
+ const itemConfig = getPayloadConfigFromPayload(config, item, key)
166
+ const value =
167
+ !labelKey && typeof label === "string"
168
+ ? config[label as keyof typeof config]?.label || label
169
+ : itemConfig?.label
170
+
171
+ if (labelFormatter) {
172
+ return (
173
+ <div className={cn("font-medium", labelClassName)}>
174
+ {labelFormatter(value, payload)}
175
+ </div>
176
+ )
177
+ }
178
+
179
+ if (!value) {
180
+ return null
181
+ }
182
+
183
+ return <div className={cn("font-medium", labelClassName)}>{value}</div>
184
+ }, [
185
+ label,
186
+ labelFormatter,
187
+ payload,
188
+ hideLabel,
189
+ labelClassName,
190
+ config,
191
+ labelKey,
192
+ ])
193
+
194
+ if (!active || !payload?.length) {
195
+ return null
196
+ }
197
+
198
+ const nestLabel = payload.length === 1 && indicator !== "dot"
199
+
200
+ return (
201
+ <div
202
+ ref={ref}
203
+ className={cn(
204
+ "grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
205
+ className
206
+ )}
207
+ >
208
+ {!nestLabel ? tooltipLabel : null}
209
+ <div className="grid gap-1.5">
210
+ {payload
211
+ .filter((item) => item.type !== "none")
212
+ .map((item, index) => {
213
+ const key = `${nameKey || item.name || item.dataKey || "value"}`
214
+ const itemConfig = getPayloadConfigFromPayload(config, item, key)
215
+ const indicatorColor = color || item.payload?.fill || item.color
216
+
217
+ return (
218
+ <div
219
+ key={String(item.dataKey ?? item.name ?? index)}
220
+ className={cn(
221
+ "flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
222
+ indicator === "dot" && "items-center"
223
+ )}
224
+ >
225
+ {formatter && item?.value !== undefined && item.name ? (
226
+ formatter(item.value, item.name, item, index, item.payload)
227
+ ) : (
228
+ <>
229
+ {itemConfig?.icon ? (
230
+ <itemConfig.icon />
231
+ ) : (
232
+ !hideIndicator && (
233
+ <div
234
+ className={cn(
235
+ "shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]",
236
+ {
237
+ "h-2.5 w-2.5": indicator === "dot",
238
+ "w-1": indicator === "line",
239
+ "w-0 border-[1.5px] border-dashed bg-transparent":
240
+ indicator === "dashed",
241
+ "my-0.5": nestLabel && indicator === "dashed",
242
+ }
243
+ )}
244
+ style={
245
+ {
246
+ "--color-bg": indicatorColor,
247
+ "--color-border": indicatorColor,
248
+ } as React.CSSProperties
249
+ }
250
+ />
251
+ )
252
+ )}
253
+ <div
254
+ className={cn(
255
+ "flex flex-1 justify-between leading-none",
256
+ nestLabel ? "items-end" : "items-center"
257
+ )}
258
+ >
259
+ <div className="grid gap-1.5">
260
+ {nestLabel ? tooltipLabel : null}
261
+ <span className="text-muted-foreground">
262
+ {itemConfig?.label || item.name}
263
+ </span>
264
+ </div>
265
+ {item.value !== undefined && (
266
+ <span className="font-mono font-medium tabular-nums text-foreground">
267
+ {typeof item.value === "number"
268
+ ? item.value.toLocaleString()
269
+ : item.value}
270
+ </span>
271
+ )}
272
+ </div>
273
+ </>
274
+ )}
275
+ </div>
276
+ )
277
+ })}
278
+ </div>
279
+ </div>
280
+ )
281
+ }
282
+ )
283
+ ChartTooltipContent.displayName = "ChartTooltip"
284
+
285
+ const ChartLegend = RechartsPrimitive.Legend
286
+
287
+ type RechartsInjectedLegendPayloadItem = {
288
+ value?: string
289
+ dataKey?: string
290
+ type?: string
291
+ color?: string
292
+ payload?: unknown
293
+ }
294
+
295
+ const ChartLegendContent = React.forwardRef<
296
+ HTMLDivElement,
297
+ React.ComponentProps<"div"> &
298
+ {
299
+ payload?: RechartsInjectedLegendPayloadItem[]
300
+ verticalAlign?: "top" | "bottom"
301
+ hideIcon?: boolean
302
+ nameKey?: string
303
+ }
304
+ >(
305
+ (
306
+ { className, hideIcon = false, payload, verticalAlign = "bottom", nameKey },
307
+ ref
308
+ ) => {
309
+ const { config } = useChart()
310
+
311
+ if (!payload?.length) {
312
+ return null
313
+ }
314
+
315
+ return (
316
+ <div
317
+ ref={ref}
318
+ className={cn(
319
+ "flex items-center justify-center gap-4",
320
+ verticalAlign === "top" ? "pb-3" : "pt-3",
321
+ className
322
+ )}
323
+ >
324
+ {payload
325
+ .filter((item) => item.type !== "none")
326
+ .map((item) => {
327
+ const key = `${nameKey || item.dataKey || "value"}`
328
+ const itemConfig = getPayloadConfigFromPayload(config, item, key)
329
+
330
+ return (
331
+ <div
332
+ key={String(item.value ?? item.dataKey ?? item.color ?? key)}
333
+ className={cn(
334
+ "flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"
335
+ )}
336
+ >
337
+ {itemConfig?.icon && !hideIcon ? (
338
+ <itemConfig.icon />
339
+ ) : (
340
+ <div
341
+ className="h-2 w-2 shrink-0 rounded-[2px]"
342
+ style={{
343
+ backgroundColor: item.color,
344
+ }}
345
+ />
346
+ )}
347
+ {itemConfig?.label}
348
+ </div>
349
+ )
350
+ })}
351
+ </div>
352
+ )
353
+ }
354
+ )
355
+ ChartLegendContent.displayName = "ChartLegend"
356
+
357
+ // Helper to extract item config from a payload.
358
+ function getPayloadConfigFromPayload(
359
+ config: ChartConfig,
360
+ payload: unknown,
361
+ key: string
362
+ ) {
363
+ if (typeof payload !== "object" || payload === null) {
364
+ return undefined
365
+ }
366
+
367
+ const payloadPayload =
368
+ "payload" in payload &&
369
+ typeof payload.payload === "object" &&
370
+ payload.payload !== null
371
+ ? payload.payload
372
+ : undefined
373
+
374
+ let configLabelKey: string = key
375
+
376
+ if (
377
+ key in payload &&
378
+ typeof payload[key as keyof typeof payload] === "string"
379
+ ) {
380
+ configLabelKey = payload[key as keyof typeof payload] as string
381
+ } else if (
382
+ payloadPayload &&
383
+ key in payloadPayload &&
384
+ typeof payloadPayload[key as keyof typeof payloadPayload] === "string"
385
+ ) {
386
+ configLabelKey = payloadPayload[
387
+ key as keyof typeof payloadPayload
388
+ ] as string
389
+ }
390
+
391
+ return configLabelKey in config
392
+ ? config[configLabelKey]
393
+ : config[key as keyof typeof config]
394
+ }
395
+
396
+ export {
397
+ ChartContainer,
398
+ ChartTooltip,
399
+ ChartTooltipContent,
400
+ ChartLegend,
401
+ ChartLegendContent,
402
+ ChartStyle,
403
+ }
@@ -0,0 +1,30 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
5
+ import { Check } from "lucide-react"
6
+
7
+ import { cn } from "../lib/utils"
8
+
9
+ const Checkbox = React.forwardRef<
10
+ React.ElementRef<typeof CheckboxPrimitive.Root>,
11
+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
12
+ >(({ className, ...props }, ref) => (
13
+ <CheckboxPrimitive.Root
14
+ ref={ref}
15
+ className={cn(
16
+ "grid place-content-center peer h-4 w-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",
17
+ className
18
+ )}
19
+ {...props}
20
+ >
21
+ <CheckboxPrimitive.Indicator
22
+ className={cn("grid place-content-center text-current")}
23
+ >
24
+ <Check className="h-4 w-4" />
25
+ </CheckboxPrimitive.Indicator>
26
+ </CheckboxPrimitive.Root>
27
+ ))
28
+ Checkbox.displayName = CheckboxPrimitive.Root.displayName
29
+
30
+ export { Checkbox }
@@ -0,0 +1,11 @@
1
+ "use client"
2
+
3
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
4
+
5
+ const Collapsible = CollapsiblePrimitive.Root
6
+
7
+ const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
8
+
9
+ const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
10
+
11
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent }
@@ -0,0 +1,153 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { type DialogProps } from "@radix-ui/react-dialog"
5
+ import { Command as CommandPrimitive } from "cmdk"
6
+ import { Search } from "lucide-react"
7
+
8
+ import { cn } from "../lib/utils"
9
+ import { Dialog, DialogContent } from "./dialog"
10
+
11
+ const Command = React.forwardRef<
12
+ React.ElementRef<typeof CommandPrimitive>,
13
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive>
14
+ >(({ className, ...props }, ref) => (
15
+ <CommandPrimitive
16
+ ref={ref}
17
+ className={cn(
18
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
19
+ className
20
+ )}
21
+ {...props}
22
+ />
23
+ ))
24
+ Command.displayName = CommandPrimitive.displayName
25
+
26
+ const CommandDialog = ({ children, ...props }: DialogProps) => {
27
+ return (
28
+ <Dialog {...props}>
29
+ <DialogContent className="overflow-hidden p-0 shadow-lg">
30
+ <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]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
31
+ {children}
32
+ </Command>
33
+ </DialogContent>
34
+ </Dialog>
35
+ )
36
+ }
37
+
38
+ const CommandInput = React.forwardRef<
39
+ React.ElementRef<typeof CommandPrimitive.Input>,
40
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
41
+ >(({ className, ...props }, ref) => (
42
+ <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
43
+ <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
44
+ <CommandPrimitive.Input
45
+ ref={ref}
46
+ className={cn(
47
+ "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",
48
+ className
49
+ )}
50
+ {...props}
51
+ />
52
+ </div>
53
+ ))
54
+
55
+ CommandInput.displayName = CommandPrimitive.Input.displayName
56
+
57
+ const CommandList = React.forwardRef<
58
+ React.ElementRef<typeof CommandPrimitive.List>,
59
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
60
+ >(({ className, ...props }, ref) => (
61
+ <CommandPrimitive.List
62
+ ref={ref}
63
+ className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
64
+ {...props}
65
+ />
66
+ ))
67
+
68
+ CommandList.displayName = CommandPrimitive.List.displayName
69
+
70
+ const CommandEmpty = React.forwardRef<
71
+ React.ElementRef<typeof CommandPrimitive.Empty>,
72
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
73
+ >((props, ref) => (
74
+ <CommandPrimitive.Empty
75
+ ref={ref}
76
+ className="py-6 text-center text-sm"
77
+ {...props}
78
+ />
79
+ ))
80
+
81
+ CommandEmpty.displayName = CommandPrimitive.Empty.displayName
82
+
83
+ const CommandGroup = React.forwardRef<
84
+ React.ElementRef<typeof CommandPrimitive.Group>,
85
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
86
+ >(({ className, ...props }, ref) => (
87
+ <CommandPrimitive.Group
88
+ ref={ref}
89
+ className={cn(
90
+ "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",
91
+ className
92
+ )}
93
+ {...props}
94
+ />
95
+ ))
96
+
97
+ CommandGroup.displayName = CommandPrimitive.Group.displayName
98
+
99
+ const CommandSeparator = React.forwardRef<
100
+ React.ElementRef<typeof CommandPrimitive.Separator>,
101
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
102
+ >(({ className, ...props }, ref) => (
103
+ <CommandPrimitive.Separator
104
+ ref={ref}
105
+ className={cn("-mx-1 h-px bg-border", className)}
106
+ {...props}
107
+ />
108
+ ))
109
+ CommandSeparator.displayName = CommandPrimitive.Separator.displayName
110
+
111
+ const CommandItem = React.forwardRef<
112
+ React.ElementRef<typeof CommandPrimitive.Item>,
113
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
114
+ >(({ className, ...props }, ref) => (
115
+ <CommandPrimitive.Item
116
+ ref={ref}
117
+ className={cn(
118
+ "relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
119
+ className
120
+ )}
121
+ {...props}
122
+ />
123
+ ))
124
+
125
+ CommandItem.displayName = CommandPrimitive.Item.displayName
126
+
127
+ const CommandShortcut = ({
128
+ className,
129
+ ...props
130
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
131
+ return (
132
+ <span
133
+ className={cn(
134
+ "ml-auto text-xs tracking-widest text-muted-foreground",
135
+ className
136
+ )}
137
+ {...props}
138
+ />
139
+ )
140
+ }
141
+ CommandShortcut.displayName = "CommandShortcut"
142
+
143
+ export {
144
+ Command,
145
+ CommandDialog,
146
+ CommandInput,
147
+ CommandList,
148
+ CommandEmpty,
149
+ CommandGroup,
150
+ CommandItem,
151
+ CommandShortcut,
152
+ CommandSeparator,
153
+ }