@tuturuuu/ui 0.0.4

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 (104) hide show
  1. package/.checksum +1 -0
  2. package/README.md +46 -0
  3. package/components.json +20 -0
  4. package/eslint.config.mjs +20 -0
  5. package/jsr.json +10 -0
  6. package/package.json +120 -0
  7. package/postcss.config.mjs +8 -0
  8. package/rollup.config.js +40 -0
  9. package/src/components/ui/accordion.tsx +70 -0
  10. package/src/components/ui/alert-dialog.tsx +156 -0
  11. package/src/components/ui/alert.tsx +58 -0
  12. package/src/components/ui/aspect-ratio.tsx +11 -0
  13. package/src/components/ui/avatar.tsx +52 -0
  14. package/src/components/ui/badge.tsx +49 -0
  15. package/src/components/ui/breadcrumb.tsx +108 -0
  16. package/src/components/ui/button.tsx +61 -0
  17. package/src/components/ui/calendar.tsx +212 -0
  18. package/src/components/ui/card.tsx +74 -0
  19. package/src/components/ui/carousel.tsx +240 -0
  20. package/src/components/ui/chart.tsx +365 -0
  21. package/src/components/ui/checkbox.tsx +31 -0
  22. package/src/components/ui/codeblock.tsx +161 -0
  23. package/src/components/ui/collapsible.tsx +33 -0
  24. package/src/components/ui/color-picker.tsx +143 -0
  25. package/src/components/ui/command.tsx +176 -0
  26. package/src/components/ui/context-menu.tsx +251 -0
  27. package/src/components/ui/custom/autosize-textarea.tsx +111 -0
  28. package/src/components/ui/custom/calendar/core.tsx +61 -0
  29. package/src/components/ui/custom/calendar/day-cell.tsx +74 -0
  30. package/src/components/ui/custom/calendar/month-header.tsx +59 -0
  31. package/src/components/ui/custom/calendar/month-view.tsx +110 -0
  32. package/src/components/ui/custom/calendar/utils.ts +76 -0
  33. package/src/components/ui/custom/calendar/year-calendar.tsx +64 -0
  34. package/src/components/ui/custom/calendar/year-view.tsx +58 -0
  35. package/src/components/ui/custom/combobox.tsx +197 -0
  36. package/src/components/ui/custom/common-footer.tsx +215 -0
  37. package/src/components/ui/custom/compared-date-range-picker.tsx +561 -0
  38. package/src/components/ui/custom/date-input.tsx +279 -0
  39. package/src/components/ui/custom/empty-card.tsx +39 -0
  40. package/src/components/ui/custom/feature-summary.tsx +135 -0
  41. package/src/components/ui/custom/file-uploader.tsx +349 -0
  42. package/src/components/ui/custom/input-field.tsx +29 -0
  43. package/src/components/ui/custom/loading-indicator.tsx +28 -0
  44. package/src/components/ui/custom/modifiable-dialog-trigger.tsx +83 -0
  45. package/src/components/ui/custom/month-picker.tsx +157 -0
  46. package/src/components/ui/custom/report-preview.tsx +175 -0
  47. package/src/components/ui/custom/search-bar.tsx +56 -0
  48. package/src/components/ui/custom/select-field.tsx +78 -0
  49. package/src/components/ui/custom/tables/data-table-column-header.tsx +72 -0
  50. package/src/components/ui/custom/tables/data-table-create-button.tsx +31 -0
  51. package/src/components/ui/custom/tables/data-table-faceted-filter.tsx +142 -0
  52. package/src/components/ui/custom/tables/data-table-pagination.tsx +243 -0
  53. package/src/components/ui/custom/tables/data-table-refresh-button.tsx +45 -0
  54. package/src/components/ui/custom/tables/data-table-toolbar.tsx +133 -0
  55. package/src/components/ui/custom/tables/data-table-view-options.tsx +112 -0
  56. package/src/components/ui/custom/tables/data-table.tsx +228 -0
  57. package/src/components/ui/custom/uploaded-files-card.tsx +50 -0
  58. package/src/components/ui/dialog.tsx +137 -0
  59. package/src/components/ui/drawer.tsx +131 -0
  60. package/src/components/ui/dropdown-menu.tsx +256 -0
  61. package/src/components/ui/form.tsx +167 -0
  62. package/src/components/ui/hover-card.tsx +41 -0
  63. package/src/components/ui/icons.tsx +506 -0
  64. package/src/components/ui/input-otp.tsx +78 -0
  65. package/src/components/ui/input.tsx +18 -0
  66. package/src/components/ui/label.tsx +23 -0
  67. package/src/components/ui/markdown.tsx +7 -0
  68. package/src/components/ui/menubar.tsx +275 -0
  69. package/src/components/ui/navigation-menu.tsx +169 -0
  70. package/src/components/ui/pagination.tsx +126 -0
  71. package/src/components/ui/popover.tsx +47 -0
  72. package/src/components/ui/progress.tsx +30 -0
  73. package/src/components/ui/radio-group.tsx +44 -0
  74. package/src/components/ui/resizable.tsx +55 -0
  75. package/src/components/ui/scroll-area.tsx +57 -0
  76. package/src/components/ui/select.tsx +180 -0
  77. package/src/components/ui/separator.tsx +27 -0
  78. package/src/components/ui/sheet.tsx +138 -0
  79. package/src/components/ui/sidebar.tsx +734 -0
  80. package/src/components/ui/skeleton.tsx +13 -0
  81. package/src/components/ui/slider.tsx +62 -0
  82. package/src/components/ui/sonner.tsx +29 -0
  83. package/src/components/ui/switch.tsx +30 -0
  84. package/src/components/ui/table.tsx +112 -0
  85. package/src/components/ui/tabs.tsx +68 -0
  86. package/src/components/ui/tag-input.tsx +141 -0
  87. package/src/components/ui/textarea.tsx +17 -0
  88. package/src/components/ui/time-picker-input.tsx +117 -0
  89. package/src/components/ui/time-picker-utils.tsx +146 -0
  90. package/src/components/ui/toast.tsx +128 -0
  91. package/src/components/ui/toaster.tsx +35 -0
  92. package/src/components/ui/toggle-group.tsx +72 -0
  93. package/src/components/ui/toggle.tsx +46 -0
  94. package/src/components/ui/tooltip.tsx +60 -0
  95. package/src/globals.css +252 -0
  96. package/src/hooks/use-callback-ref.ts +28 -0
  97. package/src/hooks/use-controllable-state.ts +68 -0
  98. package/src/hooks/use-copy-to-clipboard.ts +46 -0
  99. package/src/hooks/use-form.ts +23 -0
  100. package/src/hooks/use-forwarded-ref.ts +17 -0
  101. package/src/hooks/use-mobile.tsx +21 -0
  102. package/src/hooks/use-toast.ts +191 -0
  103. package/src/resolvers.ts +3 -0
  104. package/tsconfig.json +17 -0
@@ -0,0 +1,256 @@
1
+ 'use client';
2
+
3
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
4
+ import { cn } from '@tuturuuu/utils/format';
5
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
6
+ import * as React from 'react';
7
+
8
+ function DropdownMenu({
9
+ ...props
10
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
11
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
12
+ }
13
+
14
+ function DropdownMenuPortal({
15
+ ...props
16
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
17
+ return (
18
+ <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
19
+ );
20
+ }
21
+
22
+ function DropdownMenuTrigger({
23
+ ...props
24
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
25
+ return (
26
+ <DropdownMenuPrimitive.Trigger
27
+ data-slot="dropdown-menu-trigger"
28
+ {...props}
29
+ />
30
+ );
31
+ }
32
+
33
+ function DropdownMenuContent({
34
+ className,
35
+ sideOffset = 4,
36
+ ...props
37
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
38
+ return (
39
+ <DropdownMenuPrimitive.Portal>
40
+ <DropdownMenuPrimitive.Content
41
+ data-slot="dropdown-menu-content"
42
+ sideOffset={sideOffset}
43
+ className={cn(
44
+ 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md 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',
45
+ className
46
+ )}
47
+ {...props}
48
+ />
49
+ </DropdownMenuPrimitive.Portal>
50
+ );
51
+ }
52
+
53
+ function DropdownMenuGroup({
54
+ ...props
55
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
56
+ return (
57
+ <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
58
+ );
59
+ }
60
+
61
+ function DropdownMenuItem({
62
+ className,
63
+ inset,
64
+ variant = 'default',
65
+ ...props
66
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
67
+ inset?: boolean;
68
+ variant?: 'default' | 'destructive';
69
+ }) {
70
+ return (
71
+ <DropdownMenuPrimitive.Item
72
+ data-slot="dropdown-menu-item"
73
+ data-inset={inset}
74
+ data-variant={variant}
75
+ className={cn(
76
+ "relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:!text-destructive",
77
+ className
78
+ )}
79
+ {...props}
80
+ />
81
+ );
82
+ }
83
+
84
+ function DropdownMenuCheckboxItem({
85
+ className,
86
+ children,
87
+ checked,
88
+ ...props
89
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
90
+ return (
91
+ <DropdownMenuPrimitive.CheckboxItem
92
+ data-slot="dropdown-menu-checkbox-item"
93
+ className={cn(
94
+ "relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
95
+ className
96
+ )}
97
+ checked={checked}
98
+ {...props}
99
+ >
100
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
101
+ <DropdownMenuPrimitive.ItemIndicator>
102
+ <CheckIcon className="size-4" />
103
+ </DropdownMenuPrimitive.ItemIndicator>
104
+ </span>
105
+ {children}
106
+ </DropdownMenuPrimitive.CheckboxItem>
107
+ );
108
+ }
109
+
110
+ function DropdownMenuRadioGroup({
111
+ ...props
112
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
113
+ return (
114
+ <DropdownMenuPrimitive.RadioGroup
115
+ data-slot="dropdown-menu-radio-group"
116
+ {...props}
117
+ />
118
+ );
119
+ }
120
+
121
+ function DropdownMenuRadioItem({
122
+ className,
123
+ children,
124
+ ...props
125
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
126
+ return (
127
+ <DropdownMenuPrimitive.RadioItem
128
+ data-slot="dropdown-menu-radio-item"
129
+ className={cn(
130
+ "relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
131
+ className
132
+ )}
133
+ {...props}
134
+ >
135
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
136
+ <DropdownMenuPrimitive.ItemIndicator>
137
+ <CircleIcon className="size-2 fill-current" />
138
+ </DropdownMenuPrimitive.ItemIndicator>
139
+ </span>
140
+ {children}
141
+ </DropdownMenuPrimitive.RadioItem>
142
+ );
143
+ }
144
+
145
+ function DropdownMenuLabel({
146
+ className,
147
+ inset,
148
+ ...props
149
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
150
+ inset?: boolean;
151
+ }) {
152
+ return (
153
+ <DropdownMenuPrimitive.Label
154
+ data-slot="dropdown-menu-label"
155
+ data-inset={inset}
156
+ className={cn(
157
+ 'px-2 py-1.5 text-sm font-semibold data-[inset]:pl-8',
158
+ className
159
+ )}
160
+ {...props}
161
+ />
162
+ );
163
+ }
164
+
165
+ function DropdownMenuSeparator({
166
+ className,
167
+ ...props
168
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
169
+ return (
170
+ <DropdownMenuPrimitive.Separator
171
+ data-slot="dropdown-menu-separator"
172
+ className={cn('-mx-1 my-1 h-px bg-border', className)}
173
+ {...props}
174
+ />
175
+ );
176
+ }
177
+
178
+ function DropdownMenuShortcut({
179
+ className,
180
+ ...props
181
+ }: React.ComponentProps<'span'>) {
182
+ return (
183
+ <span
184
+ data-slot="dropdown-menu-shortcut"
185
+ className={cn(
186
+ 'ml-auto text-xs tracking-widest text-muted-foreground',
187
+ className
188
+ )}
189
+ {...props}
190
+ />
191
+ );
192
+ }
193
+
194
+ function DropdownMenuSub({
195
+ ...props
196
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
197
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
198
+ }
199
+
200
+ function DropdownMenuSubTrigger({
201
+ className,
202
+ inset,
203
+ children,
204
+ ...props
205
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
206
+ inset?: boolean;
207
+ }) {
208
+ return (
209
+ <DropdownMenuPrimitive.SubTrigger
210
+ data-slot="dropdown-menu-sub-trigger"
211
+ data-inset={inset}
212
+ className={cn(
213
+ 'flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',
214
+ className
215
+ )}
216
+ {...props}
217
+ >
218
+ {children}
219
+ <ChevronRightIcon className="ml-auto size-4" />
220
+ </DropdownMenuPrimitive.SubTrigger>
221
+ );
222
+ }
223
+
224
+ function DropdownMenuSubContent({
225
+ className,
226
+ ...props
227
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
228
+ return (
229
+ <DropdownMenuPrimitive.SubContent
230
+ data-slot="dropdown-menu-sub-content"
231
+ className={cn(
232
+ 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg 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',
233
+ className
234
+ )}
235
+ {...props}
236
+ />
237
+ );
238
+ }
239
+
240
+ export {
241
+ DropdownMenu,
242
+ DropdownMenuCheckboxItem,
243
+ DropdownMenuContent,
244
+ DropdownMenuGroup,
245
+ DropdownMenuItem,
246
+ DropdownMenuLabel,
247
+ DropdownMenuPortal,
248
+ DropdownMenuRadioGroup,
249
+ DropdownMenuRadioItem,
250
+ DropdownMenuSeparator,
251
+ DropdownMenuShortcut,
252
+ DropdownMenuSub,
253
+ DropdownMenuSubContent,
254
+ DropdownMenuSubTrigger,
255
+ DropdownMenuTrigger,
256
+ };
@@ -0,0 +1,167 @@
1
+ 'use client';
2
+
3
+ import { Label } from './label';
4
+ import * as LabelPrimitive from '@radix-ui/react-label';
5
+ import { Slot } from '@radix-ui/react-slot';
6
+ import { cn } from '@tuturuuu/utils/format';
7
+ import * as React from 'react';
8
+ import {
9
+ Controller,
10
+ ControllerProps,
11
+ FieldPath,
12
+ FieldValues,
13
+ FormProvider,
14
+ useFormContext,
15
+ useFormState,
16
+ } from 'react-hook-form';
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>(
28
+ {} as FormFieldContextValue
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
+ const useFormField = () => {
45
+ const fieldContext = React.useContext(FormFieldContext);
46
+ const itemContext = React.useContext(FormItemContext);
47
+ const { getFieldState } = useFormContext();
48
+ const formState = useFormState({ name: fieldContext.name });
49
+ const fieldState = getFieldState(fieldContext.name, formState);
50
+
51
+ if (!fieldContext) {
52
+ throw new Error('useFormField should be used within <FormField>');
53
+ }
54
+
55
+ const { id } = itemContext;
56
+
57
+ return {
58
+ id,
59
+ name: fieldContext.name,
60
+ formItemId: `${id}-form-item`,
61
+ formDescriptionId: `${id}-form-item-description`,
62
+ formMessageId: `${id}-form-item-message`,
63
+ ...fieldState,
64
+ };
65
+ };
66
+
67
+ type FormItemContextValue = {
68
+ id: string;
69
+ };
70
+
71
+ const FormItemContext = React.createContext<FormItemContextValue>(
72
+ {} as FormItemContextValue
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>) {
107
+ const { error, formItemId, formDescriptionId, formMessageId } =
108
+ useFormField();
109
+
110
+ return (
111
+ <Slot
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 font-medium text-destructive', className)}
151
+ {...props}
152
+ >
153
+ {body}
154
+ </p>
155
+ );
156
+ }
157
+
158
+ export {
159
+ Form,
160
+ FormControl,
161
+ FormDescription,
162
+ FormField,
163
+ FormItem,
164
+ FormLabel,
165
+ FormMessage,
166
+ useFormField,
167
+ };
@@ -0,0 +1,41 @@
1
+ 'use client';
2
+
3
+ import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
4
+ import { cn } from '@tuturuuu/utils/format';
5
+ import * as React from 'react';
6
+
7
+ function HoverCard({
8
+ ...props
9
+ }: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
10
+ return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />;
11
+ }
12
+
13
+ function HoverCardTrigger({
14
+ ...props
15
+ }: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
16
+ return (
17
+ <HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
18
+ );
19
+ }
20
+
21
+ function HoverCardContent({
22
+ className,
23
+ align = 'center',
24
+ sideOffset = 4,
25
+ ...props
26
+ }: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
27
+ return (
28
+ <HoverCardPrimitive.Content
29
+ data-slot="hover-card-content"
30
+ align={align}
31
+ sideOffset={sideOffset}
32
+ className={cn(
33
+ 'z-50 w-64 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',
34
+ className
35
+ )}
36
+ {...props}
37
+ />
38
+ );
39
+ }
40
+
41
+ export { HoverCard, HoverCardContent, HoverCardTrigger };