@openconsole/shadcn 0.2.2 → 0.2.5

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 (118) hide show
  1. package/README.md +460 -380
  2. package/components/ai-elements/agent.tsx +141 -0
  3. package/components/ai-elements/artifact.tsx +148 -0
  4. package/components/ai-elements/attachments.tsx +426 -0
  5. package/components/ai-elements/audio-player.tsx +231 -0
  6. package/components/ai-elements/canvas.tsx +26 -0
  7. package/components/ai-elements/chain-of-thought.tsx +222 -0
  8. package/components/ai-elements/checkpoint.tsx +71 -0
  9. package/components/ai-elements/code-block.tsx +562 -0
  10. package/components/ai-elements/commit.tsx +458 -0
  11. package/components/ai-elements/confirmation.tsx +174 -0
  12. package/components/ai-elements/connection.tsx +28 -0
  13. package/components/ai-elements/context.tsx +409 -0
  14. package/components/ai-elements/controls.tsx +18 -0
  15. package/components/ai-elements/conversation.tsx +168 -0
  16. package/components/ai-elements/edge.tsx +143 -0
  17. package/components/ai-elements/environment-variables.tsx +324 -0
  18. package/components/ai-elements/file-tree.tsx +304 -0
  19. package/components/ai-elements/image.tsx +24 -0
  20. package/components/ai-elements/index.ts +51 -0
  21. package/components/ai-elements/inline-citation.tsx +296 -0
  22. package/components/ai-elements/jsx-preview.tsx +310 -0
  23. package/components/ai-elements/message.tsx +360 -0
  24. package/components/ai-elements/mic-selector.tsx +375 -0
  25. package/components/ai-elements/model-selector.tsx +213 -0
  26. package/components/ai-elements/node.tsx +71 -0
  27. package/components/ai-elements/open-in-chat.tsx +370 -0
  28. package/components/ai-elements/package-info.tsx +239 -0
  29. package/components/ai-elements/panel.tsx +15 -0
  30. package/components/ai-elements/persona.tsx +306 -0
  31. package/components/ai-elements/plan.tsx +147 -0
  32. package/components/ai-elements/prompt-input.tsx +1463 -0
  33. package/components/ai-elements/queue.tsx +274 -0
  34. package/components/ai-elements/reasoning.tsx +228 -0
  35. package/components/ai-elements/sandbox.tsx +132 -0
  36. package/components/ai-elements/schema-display.tsx +471 -0
  37. package/components/ai-elements/shimmer.tsx +77 -0
  38. package/components/ai-elements/snippet.tsx +145 -0
  39. package/components/ai-elements/sources.tsx +77 -0
  40. package/components/ai-elements/speech-input.tsx +323 -0
  41. package/components/ai-elements/stack-trace.tsx +528 -0
  42. package/components/ai-elements/suggestion.tsx +57 -0
  43. package/components/ai-elements/task.tsx +87 -0
  44. package/components/ai-elements/terminal.tsx +273 -0
  45. package/components/ai-elements/test-results.tsx +496 -0
  46. package/components/ai-elements/tool.tsx +173 -0
  47. package/components/ai-elements/toolbar.tsx +16 -0
  48. package/components/ai-elements/transcription.tsx +125 -0
  49. package/components/ai-elements/voice-selector.tsx +524 -0
  50. package/components/ai-elements/web-preview.tsx +281 -0
  51. package/components/index.ts +3 -0
  52. package/{accordion.tsx → components/ui/accordion.tsx} +66 -66
  53. package/{alert-dialog.tsx → components/ui/alert-dialog.tsx} +196 -196
  54. package/{alert.tsx → components/ui/alert.tsx} +66 -66
  55. package/{aspect-ratio.tsx → components/ui/aspect-ratio.tsx} +11 -11
  56. package/{avatar.tsx → components/ui/avatar.tsx} +53 -53
  57. package/{badge.tsx → components/ui/badge.tsx} +46 -46
  58. package/{breadcrumb.tsx → components/ui/breadcrumb.tsx} +109 -109
  59. package/{button-group.tsx → components/ui/button-group.tsx} +83 -83
  60. package/{button.tsx → components/ui/button.tsx} +60 -60
  61. package/{calendar.tsx → components/ui/calendar.tsx} +219 -219
  62. package/{card.tsx → components/ui/card.tsx} +92 -92
  63. package/{carousel.tsx → components/ui/carousel.tsx} +241 -241
  64. package/{chart.tsx → components/ui/chart.tsx} +374 -374
  65. package/{checkbox.tsx → components/ui/checkbox.tsx} +32 -32
  66. package/{collapsible.tsx → components/ui/collapsible.tsx} +33 -33
  67. package/{command.tsx → components/ui/command.tsx} +184 -184
  68. package/{context-menu.tsx → components/ui/context-menu.tsx} +252 -252
  69. package/{dialog.tsx → components/ui/dialog.tsx} +143 -143
  70. package/{direction.tsx → components/ui/direction.tsx} +22 -22
  71. package/{drawer.tsx → components/ui/drawer.tsx} +135 -135
  72. package/{dropdown-menu.tsx → components/ui/dropdown-menu.tsx} +257 -257
  73. package/{empty.tsx → components/ui/empty.tsx} +104 -104
  74. package/{field.tsx → components/ui/field.tsx} +248 -248
  75. package/{form.tsx → components/ui/form.tsx} +167 -167
  76. package/{hover-card.tsx → components/ui/hover-card.tsx} +44 -44
  77. package/components/ui/icon.tsx +55 -0
  78. package/components/ui/index.ts +59 -0
  79. package/{input-group.tsx → components/ui/input-group.tsx} +170 -170
  80. package/{input-otp.tsx → components/ui/input-otp.tsx} +77 -77
  81. package/{input.tsx → components/ui/input.tsx} +21 -21
  82. package/{item.tsx → components/ui/item.tsx} +193 -193
  83. package/{kbd.tsx → components/ui/kbd.tsx} +28 -28
  84. package/{label.tsx → components/ui/label.tsx} +24 -24
  85. package/{menubar.tsx → components/ui/menubar.tsx} +276 -276
  86. package/{native-select.tsx → components/ui/native-select.tsx} +62 -62
  87. package/{navigation-menu.tsx → components/ui/navigation-menu.tsx} +168 -168
  88. package/{pagination.tsx → components/ui/pagination.tsx} +127 -127
  89. package/{popover.tsx → components/ui/popover.tsx} +89 -89
  90. package/{progress.tsx → components/ui/progress.tsx} +31 -31
  91. package/{radio-group.tsx → components/ui/radio-group.tsx} +45 -45
  92. package/{resizable.tsx → components/ui/resizable.tsx} +53 -53
  93. package/{scroll-area.tsx → components/ui/scroll-area.tsx} +58 -58
  94. package/{select.tsx → components/ui/select.tsx} +187 -187
  95. package/{separator.tsx → components/ui/separator.tsx} +28 -28
  96. package/{sheet.tsx → components/ui/sheet.tsx} +139 -139
  97. package/{sidebar.tsx → components/ui/sidebar.tsx} +724 -724
  98. package/{skeleton.tsx → components/ui/skeleton.tsx} +13 -13
  99. package/{slider.tsx → components/ui/slider.tsx} +63 -63
  100. package/{sonner.tsx → components/ui/sonner.tsx} +40 -40
  101. package/{spinner.tsx → components/ui/spinner.tsx} +16 -16
  102. package/{switch.tsx → components/ui/switch.tsx} +35 -35
  103. package/{table.tsx → components/ui/table.tsx} +116 -116
  104. package/{tabs.tsx → components/ui/tabs.tsx} +66 -66
  105. package/{textarea.tsx → components/ui/textarea.tsx} +18 -18
  106. package/{toggle-group.tsx → components/ui/toggle-group.tsx} +83 -83
  107. package/{toggle.tsx → components/ui/toggle.tsx} +47 -47
  108. package/{tooltip.tsx → components/ui/tooltip.tsx} +61 -61
  109. package/hooks/index.ts +1 -1
  110. package/hooks/use-mobile.ts +19 -19
  111. package/index.ts +3 -59
  112. package/lib/index.ts +1 -1
  113. package/lib/utils.ts +6 -6
  114. package/package.json +79 -1
  115. package/styles.css +124 -124
  116. package/icon.tsx +0 -21
  117. package/tsconfig.json +0 -12
  118. package/tsconfig.tsbuildinfo +0 -1
@@ -1,167 +1,167 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { Label as LabelPrimitive, Slot } from "radix-ui";
5
- import {
6
- Controller,
7
- FormProvider,
8
- useFormContext,
9
- useFormState,
10
- type ControllerProps,
11
- type FieldPath,
12
- type FieldValues,
13
- } from "react-hook-form";
14
-
15
- import { cn } from "./lib/utils";
16
- import { Label } from "./label";
17
-
18
- const Form = FormProvider;
19
-
20
- type FormFieldContextValue<
21
- TFieldValues extends FieldValues = FieldValues,
22
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
23
- > = {
24
- name: TName;
25
- };
26
-
27
- const FormFieldContext = React.createContext<FormFieldContextValue | null>(
28
- null,
29
- );
30
-
31
- const FormField = <
32
- TFieldValues extends FieldValues = FieldValues,
33
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
34
- >({
35
- ...props
36
- }: ControllerProps<TFieldValues, TName>) => {
37
- return (
38
- <FormFieldContext.Provider value={{ name: props.name }}>
39
- <Controller {...props} />
40
- </FormFieldContext.Provider>
41
- );
42
- };
43
-
44
- type FormItemContextValue = {
45
- id: string;
46
- };
47
-
48
- const FormItemContext = React.createContext<FormItemContextValue | null>(null);
49
-
50
- const useFormField = () => {
51
- const fieldContext = React.useContext(FormFieldContext);
52
- const itemContext = React.useContext(FormItemContext);
53
- if (!fieldContext) {
54
- throw new Error("useFormField should be used within <FormField>");
55
- }
56
- if (!itemContext) {
57
- throw new Error("useFormField should be used within <FormItem>");
58
- }
59
- const { getFieldState } = useFormContext();
60
- const formState = useFormState({ name: fieldContext.name });
61
- const fieldState = getFieldState(fieldContext.name, formState);
62
-
63
- const { id } = itemContext;
64
-
65
- return {
66
- id,
67
- name: fieldContext.name,
68
- formItemId: `${id}-form-item`,
69
- formDescriptionId: `${id}-form-item-description`,
70
- formMessageId: `${id}-form-item-message`,
71
- ...fieldState,
72
- };
73
- };
74
-
75
- function FormItem({ className, ...props }: React.ComponentProps<"div">) {
76
- const id = React.useId();
77
-
78
- return (
79
- <FormItemContext.Provider value={{ id }}>
80
- <div
81
- data-slot="form-item"
82
- className={cn("grid gap-2", className)}
83
- {...props}
84
- />
85
- </FormItemContext.Provider>
86
- );
87
- }
88
-
89
- function FormLabel({
90
- className,
91
- ...props
92
- }: React.ComponentProps<typeof LabelPrimitive.Root>) {
93
- const { error, formItemId } = useFormField();
94
-
95
- return (
96
- <Label
97
- data-slot="form-label"
98
- data-error={!!error}
99
- className={cn("data-[error=true]:text-destructive", className)}
100
- htmlFor={formItemId}
101
- {...props}
102
- />
103
- );
104
- }
105
-
106
- function FormControl({ ...props }: React.ComponentProps<typeof Slot.Root>) {
107
- const { error, formItemId, formDescriptionId, formMessageId } =
108
- useFormField();
109
-
110
- return (
111
- <Slot.Root
112
- data-slot="form-control"
113
- id={formItemId}
114
- aria-describedby={
115
- !error
116
- ? `${formDescriptionId}`
117
- : `${formDescriptionId} ${formMessageId}`
118
- }
119
- aria-invalid={!!error}
120
- {...props}
121
- />
122
- );
123
- }
124
-
125
- function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
126
- const { formDescriptionId } = useFormField();
127
-
128
- return (
129
- <p
130
- data-slot="form-description"
131
- id={formDescriptionId}
132
- className={cn("text-sm text-muted-foreground", className)}
133
- {...props}
134
- />
135
- );
136
- }
137
-
138
- function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
139
- const { error, formMessageId } = useFormField();
140
- const body = error ? String(error?.message ?? "") : props.children;
141
-
142
- if (!body) {
143
- return null;
144
- }
145
-
146
- return (
147
- <p
148
- data-slot="form-message"
149
- id={formMessageId}
150
- className={cn("text-sm text-destructive", className)}
151
- {...props}
152
- >
153
- {body}
154
- </p>
155
- );
156
- }
157
-
158
- export {
159
- useFormField,
160
- Form,
161
- FormItem,
162
- FormLabel,
163
- FormControl,
164
- FormDescription,
165
- FormMessage,
166
- FormField,
167
- };
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { Label as LabelPrimitive, Slot } from "radix-ui";
5
+ import {
6
+ Controller,
7
+ FormProvider,
8
+ useFormContext,
9
+ useFormState,
10
+ type ControllerProps,
11
+ type FieldPath,
12
+ type FieldValues,
13
+ } from "react-hook-form";
14
+
15
+ import { cn } from "../../lib/utils";
16
+ import { Label } from "./label";
17
+
18
+ const Form = FormProvider;
19
+
20
+ type FormFieldContextValue<
21
+ TFieldValues extends FieldValues = FieldValues,
22
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
23
+ > = {
24
+ name: TName;
25
+ };
26
+
27
+ const FormFieldContext = React.createContext<FormFieldContextValue | null>(
28
+ null,
29
+ );
30
+
31
+ const FormField = <
32
+ TFieldValues extends FieldValues = FieldValues,
33
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
34
+ >({
35
+ ...props
36
+ }: ControllerProps<TFieldValues, TName>) => {
37
+ return (
38
+ <FormFieldContext.Provider value={{ name: props.name }}>
39
+ <Controller {...props} />
40
+ </FormFieldContext.Provider>
41
+ );
42
+ };
43
+
44
+ type FormItemContextValue = {
45
+ id: string;
46
+ };
47
+
48
+ const FormItemContext = React.createContext<FormItemContextValue | null>(null);
49
+
50
+ const useFormField = () => {
51
+ const fieldContext = React.useContext(FormFieldContext);
52
+ const itemContext = React.useContext(FormItemContext);
53
+ if (!fieldContext) {
54
+ throw new Error("useFormField should be used within <FormField>");
55
+ }
56
+ if (!itemContext) {
57
+ throw new Error("useFormField should be used within <FormItem>");
58
+ }
59
+ const { getFieldState } = useFormContext();
60
+ const formState = useFormState({ name: fieldContext.name });
61
+ const fieldState = getFieldState(fieldContext.name, formState);
62
+
63
+ const { id } = itemContext;
64
+
65
+ return {
66
+ id,
67
+ name: fieldContext.name,
68
+ formItemId: `${id}-form-item`,
69
+ formDescriptionId: `${id}-form-item-description`,
70
+ formMessageId: `${id}-form-item-message`,
71
+ ...fieldState,
72
+ };
73
+ };
74
+
75
+ function FormItem({ className, ...props }: React.ComponentProps<"div">) {
76
+ const id = React.useId();
77
+
78
+ return (
79
+ <FormItemContext.Provider value={{ id }}>
80
+ <div
81
+ data-slot="form-item"
82
+ className={cn("grid gap-2", className)}
83
+ {...props}
84
+ />
85
+ </FormItemContext.Provider>
86
+ );
87
+ }
88
+
89
+ function FormLabel({
90
+ className,
91
+ ...props
92
+ }: React.ComponentProps<typeof LabelPrimitive.Root>) {
93
+ const { error, formItemId } = useFormField();
94
+
95
+ return (
96
+ <Label
97
+ data-slot="form-label"
98
+ data-error={!!error}
99
+ className={cn("data-[error=true]:text-destructive", className)}
100
+ htmlFor={formItemId}
101
+ {...props}
102
+ />
103
+ );
104
+ }
105
+
106
+ function FormControl({ ...props }: React.ComponentProps<typeof Slot.Root>) {
107
+ const { error, formItemId, formDescriptionId, formMessageId } =
108
+ useFormField();
109
+
110
+ return (
111
+ <Slot.Root
112
+ data-slot="form-control"
113
+ id={formItemId}
114
+ aria-describedby={
115
+ !error
116
+ ? `${formDescriptionId}`
117
+ : `${formDescriptionId} ${formMessageId}`
118
+ }
119
+ aria-invalid={!!error}
120
+ {...props}
121
+ />
122
+ );
123
+ }
124
+
125
+ function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
126
+ const { formDescriptionId } = useFormField();
127
+
128
+ return (
129
+ <p
130
+ data-slot="form-description"
131
+ id={formDescriptionId}
132
+ className={cn("text-sm text-muted-foreground", className)}
133
+ {...props}
134
+ />
135
+ );
136
+ }
137
+
138
+ function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
139
+ const { error, formMessageId } = useFormField();
140
+ const body = error ? String(error?.message ?? "") : props.children;
141
+
142
+ if (!body) {
143
+ return null;
144
+ }
145
+
146
+ return (
147
+ <p
148
+ data-slot="form-message"
149
+ id={formMessageId}
150
+ className={cn("text-sm text-destructive", className)}
151
+ {...props}
152
+ >
153
+ {body}
154
+ </p>
155
+ );
156
+ }
157
+
158
+ export {
159
+ useFormField,
160
+ Form,
161
+ FormItem,
162
+ FormLabel,
163
+ FormControl,
164
+ FormDescription,
165
+ FormMessage,
166
+ FormField,
167
+ };
@@ -1,44 +1,44 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { HoverCard as HoverCardPrimitive } from "radix-ui"
5
-
6
- import { cn } from "./lib/utils"
7
-
8
- function HoverCard({
9
- ...props
10
- }: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
11
- return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />
12
- }
13
-
14
- function HoverCardTrigger({
15
- ...props
16
- }: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
17
- return (
18
- <HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
19
- )
20
- }
21
-
22
- function HoverCardContent({
23
- className,
24
- align = "center",
25
- sideOffset = 4,
26
- ...props
27
- }: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
28
- return (
29
- <HoverCardPrimitive.Portal data-slot="hover-card-portal">
30
- <HoverCardPrimitive.Content
31
- data-slot="hover-card-content"
32
- align={align}
33
- sideOffset={sideOffset}
34
- className={cn(
35
- "z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
36
- className
37
- )}
38
- {...props}
39
- />
40
- </HoverCardPrimitive.Portal>
41
- )
42
- }
43
-
44
- export { HoverCard, HoverCardTrigger, HoverCardContent }
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { HoverCard as HoverCardPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "../../lib/utils"
7
+
8
+ function HoverCard({
9
+ ...props
10
+ }: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
11
+ return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />
12
+ }
13
+
14
+ function HoverCardTrigger({
15
+ ...props
16
+ }: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
17
+ return (
18
+ <HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
19
+ )
20
+ }
21
+
22
+ function HoverCardContent({
23
+ className,
24
+ align = "center",
25
+ sideOffset = 4,
26
+ ...props
27
+ }: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
28
+ return (
29
+ <HoverCardPrimitive.Portal data-slot="hover-card-portal">
30
+ <HoverCardPrimitive.Content
31
+ data-slot="hover-card-content"
32
+ align={align}
33
+ sideOffset={sideOffset}
34
+ className={cn(
35
+ "z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
36
+ className
37
+ )}
38
+ {...props}
39
+ />
40
+ </HoverCardPrimitive.Portal>
41
+ )
42
+ }
43
+
44
+ export { HoverCard, HoverCardTrigger, HoverCardContent }
@@ -0,0 +1,55 @@
1
+ "use client";
2
+
3
+ import { icons as lucideIcons, type LucideProps } from "lucide-react";
4
+
5
+ import { cn } from "../../lib/utils";
6
+
7
+ interface IconProps extends LucideProps {
8
+ /**
9
+ * 图标来源,按形态自动判别(三选一):
10
+ * - lucide-react 图标名,PascalCase(例如 `"LayoutDashboard"`);
11
+ * - 内联 SVG 源码(以 `<svg` 开头);
12
+ * - 图片地址:http(s) URL、绝对/相对路径、`data:image/` 或以图片
13
+ * 后缀(png/jpg/svg/webp…)结尾的字符串。
14
+ */
15
+ name?: string;
16
+ /** `name` 为图片时的 `alt`;其余形态忽略。默认空串(按装饰性处理)。 */
17
+ alt?: string;
18
+ }
19
+
20
+ /** 起始前缀或图片后缀任一命中即视为图片地址。 */
21
+ const IMAGE_SOURCE =
22
+ /^(https?:\/\/|\/|\.\.?\/|data:image\/)|\.(png|jpe?g|gif|webp|avif|svg|ico|bmp)(\?.*)?$/i;
23
+
24
+ /**
25
+ * 渲染一个图标。`name` 可以是 lucide 图标名、内联 SVG 源码或图片地址,
26
+ * 组件按形态自动选择渲染方式,三者共享同一个 `className`(尺寸/颜色)。
27
+ *
28
+ * Sidebar 等数据把图标存成可序列化的纯字符串,以跨 RSC / Client 边界传递,
29
+ * 真正的查表 / 渲染发生在这里(客户端)。
30
+ *
31
+ * 注意:内联 SVG 经 `dangerouslySetInnerHTML` 注入,仅供可信来源(应用
32
+ * 自身配置)使用,切勿把用户输入直接传入。
33
+ */
34
+ export function Icon({ name, alt = "", className, ...props }: IconProps) {
35
+ if (!name) return null;
36
+
37
+ if (name.trimStart().startsWith("<svg")) {
38
+ return (
39
+ <span
40
+ className={cn("inline-flex [&>svg]:size-full", className)}
41
+ dangerouslySetInnerHTML={{ __html: name }}
42
+ />
43
+ );
44
+ }
45
+
46
+ if (IMAGE_SOURCE.test(name)) {
47
+ // 基础原语,刻意用原生 <img> 而非 next/image,避免 shadcn 层耦合框架。
48
+ return (
49
+ <img src={name} alt={alt} className={cn("object-contain", className)} />
50
+ );
51
+ }
52
+
53
+ const LucideIcon = lucideIcons[name as keyof typeof lucideIcons];
54
+ return LucideIcon ? <LucideIcon className={className} {...props} /> : null;
55
+ }
@@ -0,0 +1,59 @@
1
+ // Barrel — re-export every shadcn UI primitive in this directory.
2
+ // Add a line when you add a component (keep sorted).
3
+
4
+ export * from "./accordion";
5
+ export * from "./alert";
6
+ export * from "./alert-dialog";
7
+ export * from "./aspect-ratio";
8
+ export * from "./avatar";
9
+ export * from "./badge";
10
+ export * from "./breadcrumb";
11
+ export * from "./button";
12
+ export * from "./button-group";
13
+ export * from "./calendar";
14
+ export * from "./card";
15
+ export * from "./carousel";
16
+ export * from "./chart";
17
+ export * from "./checkbox";
18
+ export * from "./collapsible";
19
+ export * from "./command";
20
+ export * from "./context-menu";
21
+ export * from "./dialog";
22
+ export * from "./direction";
23
+ export * from "./drawer";
24
+ export * from "./dropdown-menu";
25
+ export * from "./empty";
26
+ export * from "./field";
27
+ export * from "./form";
28
+ export * from "./hover-card";
29
+ export * from "./icon";
30
+ export * from "./input";
31
+ export * from "./input-group";
32
+ export * from "./input-otp";
33
+ export * from "./item";
34
+ export * from "./kbd";
35
+ export * from "./label";
36
+ export * from "./menubar";
37
+ export * from "./native-select";
38
+ export * from "./navigation-menu";
39
+ export * from "./pagination";
40
+ export * from "./popover";
41
+ export * from "./progress";
42
+ export * from "./radio-group";
43
+ export * from "./resizable";
44
+ export * from "./scroll-area";
45
+ export * from "./select";
46
+ export * from "./separator";
47
+ export * from "./sheet";
48
+ export * from "./sidebar";
49
+ export * from "./skeleton";
50
+ export * from "./slider";
51
+ export * from "./sonner";
52
+ export * from "./spinner";
53
+ export * from "./switch";
54
+ export * from "./table";
55
+ export * from "./tabs";
56
+ export * from "./textarea";
57
+ export * from "./toggle";
58
+ export * from "./toggle-group";
59
+ export * from "./tooltip";