@ptengine/design-components 0.3.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 (197) hide show
  1. package/README.md +309 -0
  2. package/components.json +21 -0
  3. package/dist/components/ui/accordion.d.ts +8 -0
  4. package/dist/components/ui/accordion.d.ts.map +1 -0
  5. package/dist/components/ui/alert-dialog.d.ts +21 -0
  6. package/dist/components/ui/alert-dialog.d.ts.map +1 -0
  7. package/dist/components/ui/alert.d.ts +9 -0
  8. package/dist/components/ui/alert.d.ts.map +1 -0
  9. package/dist/components/ui/aspect-ratio.d.ts +4 -0
  10. package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
  11. package/dist/components/ui/attachment.d.ts +26 -0
  12. package/dist/components/ui/attachment.d.ts.map +1 -0
  13. package/dist/components/ui/avatar.d.ts +10 -0
  14. package/dist/components/ui/avatar.d.ts.map +1 -0
  15. package/dist/components/ui/badge.d.ts +10 -0
  16. package/dist/components/ui/badge.d.ts.map +1 -0
  17. package/dist/components/ui/breadcrumb.d.ts +22 -0
  18. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  19. package/dist/components/ui/bubble.d.ts +19 -0
  20. package/dist/components/ui/bubble.d.ts.map +1 -0
  21. package/dist/components/ui/button-group.d.ts +13 -0
  22. package/dist/components/ui/button-group.d.ts.map +1 -0
  23. package/dist/components/ui/button.d.ts +13 -0
  24. package/dist/components/ui/button.d.ts.map +1 -0
  25. package/dist/components/ui/calendar.d.ts +9 -0
  26. package/dist/components/ui/calendar.d.ts.map +1 -0
  27. package/dist/components/ui/card.d.ts +9 -0
  28. package/dist/components/ui/card.d.ts.map +1 -0
  29. package/dist/components/ui/carousel.d.ts +23 -0
  30. package/dist/components/ui/carousel.d.ts.map +1 -0
  31. package/dist/components/ui/chart.d.ts +63 -0
  32. package/dist/components/ui/chart.d.ts.map +1 -0
  33. package/dist/components/ui/checkbox.d.ts +5 -0
  34. package/dist/components/ui/checkbox.d.ts.map +1 -0
  35. package/dist/components/ui/collapsible.d.ts +6 -0
  36. package/dist/components/ui/collapsible.d.ts.map +1 -0
  37. package/dist/components/ui/command.d.ts +81 -0
  38. package/dist/components/ui/command.d.ts.map +1 -0
  39. package/dist/components/ui/context-menu.d.ts +28 -0
  40. package/dist/components/ui/context-menu.d.ts.map +1 -0
  41. package/dist/components/ui/dialog.d.ts +22 -0
  42. package/dist/components/ui/dialog.d.ts.map +1 -0
  43. package/dist/components/ui/direction.d.ts +8 -0
  44. package/dist/components/ui/direction.d.ts.map +1 -0
  45. package/dist/components/ui/drawer.d.ts +23 -0
  46. package/dist/components/ui/drawer.d.ts.map +1 -0
  47. package/dist/components/ui/dropdown-menu.d.ts +28 -0
  48. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  49. package/dist/components/ui/empty.d.ts +13 -0
  50. package/dist/components/ui/empty.d.ts.map +1 -0
  51. package/dist/components/ui/field.d.ts +25 -0
  52. package/dist/components/ui/field.d.ts.map +1 -0
  53. package/dist/components/ui/hover-card.d.ts +7 -0
  54. package/dist/components/ui/hover-card.d.ts.map +1 -0
  55. package/dist/components/ui/input-group.d.ts +13 -0
  56. package/dist/components/ui/input-group.d.ts.map +1 -0
  57. package/dist/components/ui/input-otp.d.ts +35 -0
  58. package/dist/components/ui/input-otp.d.ts.map +1 -0
  59. package/dist/components/ui/input.d.ts +5 -0
  60. package/dist/components/ui/input.d.ts.map +1 -0
  61. package/dist/components/ui/item.d.ts +24 -0
  62. package/dist/components/ui/item.d.ts.map +1 -0
  63. package/dist/components/ui/kbd.d.ts +5 -0
  64. package/dist/components/ui/kbd.d.ts.map +1 -0
  65. package/dist/components/ui/label.d.ts +6 -0
  66. package/dist/components/ui/label.d.ts.map +1 -0
  67. package/dist/components/ui/marker.d.ts +13 -0
  68. package/dist/components/ui/marker.d.ts.map +1 -0
  69. package/dist/components/ui/menubar.d.ts +29 -0
  70. package/dist/components/ui/menubar.d.ts.map +1 -0
  71. package/dist/components/ui/message-scroller.d.ts +26 -0
  72. package/dist/components/ui/message-scroller.d.ts.map +1 -0
  73. package/dist/components/ui/message.d.ts +11 -0
  74. package/dist/components/ui/message.d.ts.map +1 -0
  75. package/dist/components/ui/native-select.d.ts +4 -0
  76. package/dist/components/ui/native-select.d.ts.map +1 -0
  77. package/dist/components/ui/navigation-menu.d.ts +13 -0
  78. package/dist/components/ui/navigation-menu.d.ts.map +1 -0
  79. package/dist/components/ui/pagination.d.ts +35 -0
  80. package/dist/components/ui/pagination.d.ts.map +1 -0
  81. package/dist/components/ui/popover.d.ts +8 -0
  82. package/dist/components/ui/popover.d.ts.map +1 -0
  83. package/dist/components/ui/progress.d.ts +5 -0
  84. package/dist/components/ui/progress.d.ts.map +1 -0
  85. package/dist/components/ui/radio-group.d.ts +6 -0
  86. package/dist/components/ui/radio-group.d.ts.map +1 -0
  87. package/dist/components/ui/resizable.d.ts +24 -0
  88. package/dist/components/ui/resizable.d.ts.map +1 -0
  89. package/dist/components/ui/scroll-area.d.ts +6 -0
  90. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  91. package/dist/components/ui/search-input.d.ts +23 -0
  92. package/dist/components/ui/search-input.d.ts.map +1 -0
  93. package/dist/components/ui/select.d.ts +14 -0
  94. package/dist/components/ui/select.d.ts.map +1 -0
  95. package/dist/components/ui/separator.d.ts +5 -0
  96. package/dist/components/ui/separator.d.ts.map +1 -0
  97. package/dist/components/ui/sheet.d.ts +28 -0
  98. package/dist/components/ui/sheet.d.ts.map +1 -0
  99. package/dist/components/ui/sidebar.d.ts +70 -0
  100. package/dist/components/ui/sidebar.d.ts.map +1 -0
  101. package/dist/components/ui/skeleton.d.ts +4 -0
  102. package/dist/components/ui/skeleton.d.ts.map +1 -0
  103. package/dist/components/ui/slider.d.ts +5 -0
  104. package/dist/components/ui/slider.d.ts.map +1 -0
  105. package/dist/components/ui/sonner.d.ts +6 -0
  106. package/dist/components/ui/sonner.d.ts.map +1 -0
  107. package/dist/components/ui/spinner.d.ts +7 -0
  108. package/dist/components/ui/spinner.d.ts.map +1 -0
  109. package/dist/components/ui/switch.d.ts +5 -0
  110. package/dist/components/ui/switch.d.ts.map +1 -0
  111. package/dist/components/ui/table.d.ts +11 -0
  112. package/dist/components/ui/table.d.ts.map +1 -0
  113. package/dist/components/ui/tabs.d.ts +13 -0
  114. package/dist/components/ui/tabs.d.ts.map +1 -0
  115. package/dist/components/ui/textarea.d.ts +5 -0
  116. package/dist/components/ui/textarea.d.ts.map +1 -0
  117. package/dist/components/ui/toggle-group.d.ts +13 -0
  118. package/dist/components/ui/toggle-group.d.ts.map +1 -0
  119. package/dist/components/ui/toggle.d.ts +13 -0
  120. package/dist/components/ui/toggle.d.ts.map +1 -0
  121. package/dist/components/ui/tooltip.d.ts +8 -0
  122. package/dist/components/ui/tooltip.d.ts.map +1 -0
  123. package/dist/hooks/use-mobile.d.ts +2 -0
  124. package/dist/hooks/use-mobile.d.ts.map +1 -0
  125. package/dist/index.cjs +82 -0
  126. package/dist/index.d.ts +71 -0
  127. package/dist/index.d.ts.map +1 -0
  128. package/dist/index.js +20969 -0
  129. package/dist/lib/utils.d.ts +4 -0
  130. package/dist/lib/utils.d.ts.map +1 -0
  131. package/llms.txt +173 -0
  132. package/package.json +125 -0
  133. package/src/components/ui/accordion.tsx +51 -0
  134. package/src/components/ui/alert-dialog.tsx +115 -0
  135. package/src/components/ui/alert.tsx +48 -0
  136. package/src/components/ui/aspect-ratio.tsx +5 -0
  137. package/src/components/ui/attachment.tsx +186 -0
  138. package/src/components/ui/avatar.tsx +57 -0
  139. package/src/components/ui/badge.tsx +40 -0
  140. package/src/components/ui/breadcrumb.tsx +101 -0
  141. package/src/components/ui/bubble.tsx +123 -0
  142. package/src/components/ui/button-group.tsx +74 -0
  143. package/src/components/ui/button.tsx +64 -0
  144. package/src/components/ui/calendar.tsx +63 -0
  145. package/src/components/ui/card.tsx +55 -0
  146. package/src/components/ui/carousel.tsx +252 -0
  147. package/src/components/ui/chart.tsx +323 -0
  148. package/src/components/ui/checkbox.tsx +26 -0
  149. package/src/components/ui/collapsible.tsx +9 -0
  150. package/src/components/ui/command.tsx +136 -0
  151. package/src/components/ui/context-menu.tsx +187 -0
  152. package/src/components/ui/dialog.tsx +103 -0
  153. package/src/components/ui/direction.tsx +15 -0
  154. package/src/components/ui/drawer.tsx +98 -0
  155. package/src/components/ui/dropdown-menu.tsx +186 -0
  156. package/src/components/ui/empty.tsx +75 -0
  157. package/src/components/ui/field.tsx +175 -0
  158. package/src/components/ui/hover-card.tsx +27 -0
  159. package/src/components/ui/input-group.tsx +80 -0
  160. package/src/components/ui/input-otp.tsx +67 -0
  161. package/src/components/ui/input.tsx +24 -0
  162. package/src/components/ui/item.tsx +118 -0
  163. package/src/components/ui/kbd.tsx +21 -0
  164. package/src/components/ui/label.tsx +19 -0
  165. package/src/components/ui/marker.tsx +67 -0
  166. package/src/components/ui/menubar.tsx +218 -0
  167. package/src/components/ui/message-scroller.tsx +206 -0
  168. package/src/components/ui/message.tsx +85 -0
  169. package/src/components/ui/native-select.tsx +29 -0
  170. package/src/components/ui/navigation-menu.tsx +120 -0
  171. package/src/components/ui/pagination.tsx +108 -0
  172. package/src/components/ui/popover.tsx +31 -0
  173. package/src/components/ui/progress.tsx +23 -0
  174. package/src/components/ui/radio-group.tsx +36 -0
  175. package/src/components/ui/resizable.tsx +40 -0
  176. package/src/components/ui/scroll-area.tsx +44 -0
  177. package/src/components/ui/search-input.tsx +97 -0
  178. package/src/components/ui/select.tsx +151 -0
  179. package/src/components/ui/separator.tsx +24 -0
  180. package/src/components/ui/sheet.tsx +124 -0
  181. package/src/components/ui/sidebar.tsx +704 -0
  182. package/src/components/ui/skeleton.tsx +9 -0
  183. package/src/components/ui/slider.tsx +41 -0
  184. package/src/components/ui/sonner.tsx +45 -0
  185. package/src/components/ui/spinner.tsx +21 -0
  186. package/src/components/ui/switch.tsx +27 -0
  187. package/src/components/ui/table.tsx +95 -0
  188. package/src/components/ui/tabs.tsx +119 -0
  189. package/src/components/ui/textarea.tsx +23 -0
  190. package/src/components/ui/toggle-group.tsx +55 -0
  191. package/src/components/ui/toggle.tsx +40 -0
  192. package/src/components/ui/tooltip.tsx +30 -0
  193. package/src/hooks/use-mobile.ts +19 -0
  194. package/src/index.ts +414 -0
  195. package/src/lib/utils.ts +7 -0
  196. package/src/styles/tokens.css +360 -0
  197. package/tailwind.preset.js +235 -0
@@ -0,0 +1,186 @@
1
+ import * as React from 'react';
2
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
3
+ import { Check, ChevronRight, Circle } from 'lucide-react';
4
+
5
+ import { cn } from '../../lib/utils';
6
+
7
+ const DropdownMenu = DropdownMenuPrimitive.Root;
8
+
9
+ const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
10
+
11
+ const DropdownMenuGroup = DropdownMenuPrimitive.Group;
12
+
13
+ const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
14
+
15
+ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
16
+
17
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
18
+
19
+ const DropdownMenuSubTrigger = React.forwardRef<
20
+ React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
21
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
22
+ inset?: boolean;
23
+ }
24
+ >(({ className, inset, children, ...props }, ref) => (
25
+ <DropdownMenuPrimitive.SubTrigger
26
+ ref={ref}
27
+ className={cn(
28
+ 'flex cursor-default select-none items-center rounded-[var(--pt-radius-sm)] px-[8px] py-[6px] text-[14px] leading-[20px] outline-none focus:bg-accent data-[state=open]:bg-accent',
29
+ inset && 'pl-[32px]',
30
+ className
31
+ )}
32
+ {...props}
33
+ >
34
+ {children}
35
+ <ChevronRight className="ml-auto h-[16px] w-[16px]" />
36
+ </DropdownMenuPrimitive.SubTrigger>
37
+ ));
38
+ DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
39
+
40
+ const DropdownMenuSubContent = React.forwardRef<
41
+ React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
42
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
43
+ >(({ className, ...props }, ref) => (
44
+ <DropdownMenuPrimitive.SubContent
45
+ ref={ref}
46
+ className={cn(
47
+ 'z-[var(--pt-z-popup,50)] min-w-[8rem] overflow-hidden rounded-[var(--pt-radius-md)] border bg-popover p-[4px] text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 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',
48
+ className
49
+ )}
50
+ {...props}
51
+ />
52
+ ));
53
+ DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
54
+
55
+ const DropdownMenuContent = React.forwardRef<
56
+ React.ElementRef<typeof DropdownMenuPrimitive.Content>,
57
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
58
+ >(({ className, sideOffset = 4, ...props }, ref) => (
59
+ <DropdownMenuPrimitive.Portal>
60
+ <DropdownMenuPrimitive.Content
61
+ ref={ref}
62
+ sideOffset={sideOffset}
63
+ className={cn(
64
+ 'z-[var(--pt-z-popup,50)] min-w-[8rem] overflow-hidden rounded-[var(--pt-radius-md)] border bg-popover p-[4px] text-popover-foreground shadow-md',
65
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 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',
66
+ className
67
+ )}
68
+ {...props}
69
+ />
70
+ </DropdownMenuPrimitive.Portal>
71
+ ));
72
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
73
+
74
+ const DropdownMenuItem = React.forwardRef<
75
+ React.ElementRef<typeof DropdownMenuPrimitive.Item>,
76
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
77
+ inset?: boolean;
78
+ }
79
+ >(({ className, inset, ...props }, ref) => (
80
+ <DropdownMenuPrimitive.Item
81
+ ref={ref}
82
+ className={cn(
83
+ 'relative flex cursor-default select-none items-center gap-[8px] rounded-[var(--pt-radius-sm)] px-[8px] py-[6px] text-[14px] leading-[20px] outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-[16px] [&>svg]:shrink-0',
84
+ inset && 'pl-[32px]',
85
+ className
86
+ )}
87
+ {...props}
88
+ />
89
+ ));
90
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
91
+
92
+ const DropdownMenuCheckboxItem = React.forwardRef<
93
+ React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
94
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
95
+ >(({ className, children, checked, ...props }, ref) => (
96
+ <DropdownMenuPrimitive.CheckboxItem
97
+ ref={ref}
98
+ className={cn(
99
+ 'relative flex cursor-default select-none items-center rounded-[var(--pt-radius-sm)] py-[6px] pl-[32px] pr-[8px] text-[14px] leading-[20px] outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
100
+ className
101
+ )}
102
+ checked={checked}
103
+ {...props}
104
+ >
105
+ <span className="absolute left-[8px] flex h-[14px] w-[14px] items-center justify-center">
106
+ <DropdownMenuPrimitive.ItemIndicator>
107
+ <Check className="h-[16px] w-[16px]" />
108
+ </DropdownMenuPrimitive.ItemIndicator>
109
+ </span>
110
+ {children}
111
+ </DropdownMenuPrimitive.CheckboxItem>
112
+ ));
113
+ DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
114
+
115
+ const DropdownMenuRadioItem = React.forwardRef<
116
+ React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
117
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
118
+ >(({ className, children, ...props }, ref) => (
119
+ <DropdownMenuPrimitive.RadioItem
120
+ ref={ref}
121
+ className={cn(
122
+ 'relative flex cursor-default select-none items-center rounded-[var(--pt-radius-sm)] py-[6px] pl-[32px] pr-[8px] text-[14px] leading-[20px] outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
123
+ className
124
+ )}
125
+ {...props}
126
+ >
127
+ <span className="absolute left-[8px] flex h-[14px] w-[14px] items-center justify-center">
128
+ <DropdownMenuPrimitive.ItemIndicator>
129
+ <Circle className="h-[8px] w-[8px] fill-current" />
130
+ </DropdownMenuPrimitive.ItemIndicator>
131
+ </span>
132
+ {children}
133
+ </DropdownMenuPrimitive.RadioItem>
134
+ ));
135
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
136
+
137
+ const DropdownMenuLabel = React.forwardRef<
138
+ React.ElementRef<typeof DropdownMenuPrimitive.Label>,
139
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
140
+ inset?: boolean;
141
+ }
142
+ >(({ className, inset, ...props }, ref) => (
143
+ <DropdownMenuPrimitive.Label
144
+ ref={ref}
145
+ className={cn('px-[8px] py-[6px] text-[14px] leading-[20px] font-semibold', inset && 'pl-[32px]', className)}
146
+ {...props}
147
+ />
148
+ ));
149
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
150
+
151
+ const DropdownMenuSeparator = React.forwardRef<
152
+ React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
153
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
154
+ >(({ className, ...props }, ref) => (
155
+ <DropdownMenuPrimitive.Separator
156
+ ref={ref}
157
+ className={cn('-mx-[4px] my-[4px] h-px bg-muted', className)}
158
+ {...props}
159
+ />
160
+ ));
161
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
162
+
163
+ const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
164
+ return (
165
+ <span className={cn('ml-auto text-[13px] leading-[20px] tracking-widest opacity-60', className)} {...props} />
166
+ );
167
+ };
168
+ DropdownMenuShortcut.displayName = 'DropdownMenuShortcut';
169
+
170
+ export {
171
+ DropdownMenu,
172
+ DropdownMenuTrigger,
173
+ DropdownMenuContent,
174
+ DropdownMenuItem,
175
+ DropdownMenuCheckboxItem,
176
+ DropdownMenuRadioItem,
177
+ DropdownMenuLabel,
178
+ DropdownMenuSeparator,
179
+ DropdownMenuShortcut,
180
+ DropdownMenuGroup,
181
+ DropdownMenuPortal,
182
+ DropdownMenuSub,
183
+ DropdownMenuSubContent,
184
+ DropdownMenuSubTrigger,
185
+ DropdownMenuRadioGroup
186
+ };
@@ -0,0 +1,75 @@
1
+ import * as React from 'react';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+
4
+ import { cn } from '../../lib/utils';
5
+
6
+ function Empty({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
7
+ return (
8
+ <div
9
+ className={cn(
10
+ 'flex min-w-0 flex-1 flex-col items-center justify-center gap-[24px] text-balance rounded-[var(--pt-radius)] border border-dashed p-[24px] text-center text-foreground md:p-[48px]',
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ );
16
+ }
17
+
18
+ function EmptyHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
19
+ return (
20
+ <div
21
+ className={cn('flex max-w-sm flex-col items-center gap-[8px] text-center', className)}
22
+ {...props}
23
+ />
24
+ );
25
+ }
26
+
27
+ const emptyMediaVariants = cva('flex shrink-0 items-center justify-center', {
28
+ variants: {
29
+ variant: {
30
+ default: '',
31
+ icon: 'size-[40px] rounded-[var(--pt-radius)] bg-secondary text-foreground [&_svg]:size-[24px]'
32
+ }
33
+ },
34
+ defaultVariants: {
35
+ variant: 'default'
36
+ }
37
+ });
38
+
39
+ function EmptyMedia({
40
+ className,
41
+ variant,
42
+ ...props
43
+ }: React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof emptyMediaVariants>) {
44
+ return <div className={cn(emptyMediaVariants({ variant }), className)} {...props} />;
45
+ }
46
+
47
+ function EmptyTitle({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
48
+ return <div className={cn('text-[18px] leading-[28px] font-medium tracking-tight', className)} {...props} />;
49
+ }
50
+
51
+ function EmptyDescription({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
52
+ return (
53
+ <div
54
+ className={cn(
55
+ 'text-[14px] leading-[20px] leading-relaxed text-muted-foreground [&>a]:text-primary [&>a]:underline [&>a]:underline-offset-4',
56
+ className
57
+ )}
58
+ {...props}
59
+ />
60
+ );
61
+ }
62
+
63
+ function EmptyContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
64
+ return (
65
+ <div
66
+ className={cn(
67
+ 'flex w-full max-w-sm min-w-0 flex-col items-center gap-[16px] text-balance text-[14px] leading-[20px]',
68
+ className
69
+ )}
70
+ {...props}
71
+ />
72
+ );
73
+ }
74
+
75
+ export { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent };
@@ -0,0 +1,175 @@
1
+ import * as React from 'react';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+
4
+ import { cn } from '../../lib/utils';
5
+ import { Label } from './label';
6
+ import { Separator } from './separator';
7
+
8
+ function FieldSet({ className, ...props }: React.FieldsetHTMLAttributes<HTMLFieldSetElement>) {
9
+ return <fieldset className={cn('flex flex-col gap-[24px]', className)} {...props} />;
10
+ }
11
+
12
+ const fieldLegendVariants = cva('mb-[12px] font-medium text-foreground', {
13
+ variants: {
14
+ variant: {
15
+ legend: 'text-[16px] leading-[24px]',
16
+ label: 'text-[14px] leading-[20px]'
17
+ }
18
+ },
19
+ defaultVariants: {
20
+ variant: 'legend'
21
+ }
22
+ });
23
+
24
+ function FieldLegend({
25
+ className,
26
+ variant,
27
+ ...props
28
+ }: React.HTMLAttributes<HTMLLegendElement> & VariantProps<typeof fieldLegendVariants>) {
29
+ return <legend className={cn(fieldLegendVariants({ variant }), className)} {...props} />;
30
+ }
31
+
32
+ function FieldGroup({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
33
+ return <div className={cn('group/field-group flex w-full flex-col gap-[28px]', className)} {...props} />;
34
+ }
35
+
36
+ const fieldVariants = cva('group/field flex w-full gap-[8px] data-[invalid=true]:text-destructive', {
37
+ variants: {
38
+ orientation: {
39
+ vertical: 'flex-col',
40
+ horizontal: 'flex-row items-center',
41
+ responsive: 'flex-col md:flex-row md:items-center'
42
+ }
43
+ },
44
+ defaultVariants: {
45
+ orientation: 'vertical'
46
+ }
47
+ });
48
+
49
+ function Field({
50
+ className,
51
+ orientation,
52
+ ...props
53
+ }: React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof fieldVariants>) {
54
+ return (
55
+ <div
56
+ role="group"
57
+ data-slot="field"
58
+ className={cn(fieldVariants({ orientation }), className)}
59
+ {...props}
60
+ />
61
+ );
62
+ }
63
+
64
+ function FieldContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
65
+ return (
66
+ <div
67
+ className={cn('group/field-content flex flex-1 flex-col gap-[6px] leading-snug', className)}
68
+ {...props}
69
+ />
70
+ );
71
+ }
72
+
73
+ function FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>) {
74
+ return (
75
+ <Label
76
+ data-slot="field-label"
77
+ className={cn('flex w-fit gap-[8px] leading-snug', className)}
78
+ {...props}
79
+ />
80
+ );
81
+ }
82
+
83
+ function FieldTitle({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
84
+ return (
85
+ <div
86
+ className={cn(
87
+ 'flex w-fit items-center gap-[8px] text-[14px] leading-[20px] font-medium leading-snug text-foreground',
88
+ className
89
+ )}
90
+ {...props}
91
+ />
92
+ );
93
+ }
94
+
95
+ function FieldDescription({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) {
96
+ return (
97
+ <p
98
+ className={cn('text-[14px] leading-[20px] font-normal leading-normal text-muted-foreground', className)}
99
+ {...props}
100
+ />
101
+ );
102
+ }
103
+
104
+ function FieldSeparator({
105
+ children,
106
+ className,
107
+ ...props
108
+ }: React.HTMLAttributes<HTMLDivElement>) {
109
+ return (
110
+ <div className={cn('relative -my-[8px] h-[20px] text-[14px] leading-[20px]', className)} {...props}>
111
+ <Separator className="absolute inset-0 top-1/2" />
112
+ {children && (
113
+ <span className="relative mx-auto flex w-fit items-center justify-center bg-background px-[8px] text-muted-foreground">
114
+ {children}
115
+ </span>
116
+ )}
117
+ </div>
118
+ );
119
+ }
120
+
121
+ function FieldError({
122
+ className,
123
+ children,
124
+ errors,
125
+ ...props
126
+ }: React.HTMLAttributes<HTMLDivElement> & {
127
+ errors?: Array<{ message?: string } | undefined>;
128
+ }) {
129
+ const content = React.useMemo(() => {
130
+ if (children) {
131
+ return children;
132
+ }
133
+ if (!errors?.length) {
134
+ return null;
135
+ }
136
+ const messages = [...new Set(errors.map(error => error?.message).filter(Boolean))];
137
+ if (messages.length === 1) {
138
+ return messages[0];
139
+ }
140
+ return (
141
+ <ul className="ml-[16px] flex list-disc flex-col gap-[4px]">
142
+ {messages.map((message, index) => (
143
+ <li key={index}>{message}</li>
144
+ ))}
145
+ </ul>
146
+ );
147
+ }, [children, errors]);
148
+
149
+ if (!content) {
150
+ return null;
151
+ }
152
+
153
+ return (
154
+ <div
155
+ role="alert"
156
+ className={cn('text-[14px] leading-[20px] font-normal text-destructive', className)}
157
+ {...props}
158
+ >
159
+ {content}
160
+ </div>
161
+ );
162
+ }
163
+
164
+ export {
165
+ Field,
166
+ FieldContent,
167
+ FieldDescription,
168
+ FieldError,
169
+ FieldGroup,
170
+ FieldLabel,
171
+ FieldLegend,
172
+ FieldSeparator,
173
+ FieldSet,
174
+ FieldTitle
175
+ };
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+ import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
3
+
4
+ import { cn } from '../../lib/utils';
5
+
6
+ const HoverCard = HoverCardPrimitive.Root;
7
+
8
+ const HoverCardTrigger = HoverCardPrimitive.Trigger;
9
+
10
+ const HoverCardContent = React.forwardRef<
11
+ React.ElementRef<typeof HoverCardPrimitive.Content>,
12
+ React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>
13
+ >(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (
14
+ <HoverCardPrimitive.Content
15
+ ref={ref}
16
+ align={align}
17
+ sideOffset={sideOffset}
18
+ className={cn(
19
+ 'z-[var(--pt-z-popup,50)] w-[256px] rounded-[var(--pt-radius-md)] border bg-popover p-[16px] text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 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',
20
+ className
21
+ )}
22
+ {...props}
23
+ />
24
+ ));
25
+ HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
26
+
27
+ export { HoverCard, HoverCardTrigger, HoverCardContent };
@@ -0,0 +1,80 @@
1
+ import * as React from 'react';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+
4
+ import { cn } from '../../lib/utils';
5
+ import { Button } from './button';
6
+
7
+ function InputGroup({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
8
+ return (
9
+ <div
10
+ role="group"
11
+ className={cn(
12
+ 'group/input-group relative flex h-[32px] w-full items-center gap-[8px] rounded-[var(--pt-radius-md)] border border-input px-[12px] transition-colors',
13
+ 'hover:border-neutral',
14
+ 'has-[input:focus-visible]:ring-1 has-[input:focus-visible]:ring-ring',
15
+ 'has-[input[aria-invalid=true]]:border-destructive has-[input[aria-invalid=true]]:hover:border-destructive',
16
+ 'has-[input:disabled]:cursor-not-allowed has-[input:disabled]:opacity-50 has-[input:disabled]:hover:border-input',
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ );
22
+ }
23
+
24
+ const InputGroupInput = React.forwardRef<
25
+ HTMLInputElement,
26
+ React.InputHTMLAttributes<HTMLInputElement>
27
+ >(({ className, ...props }, ref) => (
28
+ <input
29
+ ref={ref}
30
+ className={cn(
31
+ 'h-full w-full flex-1 bg-transparent text-[13px] leading-[20px] text-foreground placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed',
32
+ className
33
+ )}
34
+ {...props}
35
+ />
36
+ ));
37
+ InputGroupInput.displayName = 'InputGroupInput';
38
+
39
+ const inputGroupAddonVariants = cva(
40
+ 'flex items-center gap-[8px] text-[14px] leading-[20px] text-muted-foreground [&_svg]:size-[16px] [&_svg]:shrink-0',
41
+ {
42
+ variants: {
43
+ align: {
44
+ 'inline-start': 'order-first',
45
+ 'inline-end': 'order-last'
46
+ }
47
+ },
48
+ defaultVariants: {
49
+ align: 'inline-start'
50
+ }
51
+ }
52
+ );
53
+
54
+ function InputGroupAddon({
55
+ className,
56
+ align,
57
+ ...props
58
+ }: React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof inputGroupAddonVariants>) {
59
+ return <div className={cn(inputGroupAddonVariants({ align }), className)} {...props} />;
60
+ }
61
+
62
+ function InputGroupText({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) {
63
+ return (
64
+ <span
65
+ className={cn('flex items-center gap-[8px] text-[14px] leading-[20px] text-muted-foreground', className)}
66
+ {...props}
67
+ />
68
+ );
69
+ }
70
+
71
+ function InputGroupButton({
72
+ className,
73
+ size = 'sm',
74
+ variant = 'ghost',
75
+ ...props
76
+ }: React.ComponentProps<typeof Button>) {
77
+ return <Button size={size} variant={variant} className={cn('shrink-0', className)} {...props} />;
78
+ }
79
+
80
+ export { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText };
@@ -0,0 +1,67 @@
1
+ import * as React from 'react';
2
+ import { OTPInput, OTPInputContext } from 'input-otp';
3
+ import { Minus } from 'lucide-react';
4
+
5
+ import { cn } from '../../lib/utils';
6
+
7
+ const InputOTP = React.forwardRef<
8
+ React.ElementRef<typeof OTPInput>,
9
+ React.ComponentPropsWithoutRef<typeof OTPInput>
10
+ >(({ className, containerClassName, ...props }, ref) => (
11
+ <OTPInput
12
+ ref={ref}
13
+ containerClassName={cn(
14
+ 'group/input-otp flex items-center gap-[8px] has-[:disabled]:opacity-50',
15
+ containerClassName
16
+ )}
17
+ className={cn('disabled:cursor-not-allowed', className)}
18
+ {...props}
19
+ />
20
+ ));
21
+ InputOTP.displayName = 'InputOTP';
22
+
23
+ const InputOTPGroup = React.forwardRef<HTMLDivElement, React.ComponentPropsWithoutRef<'div'>>(
24
+ ({ className, ...props }, ref) => (
25
+ <div ref={ref} className={cn('flex items-center', className)} {...props} />
26
+ )
27
+ );
28
+ InputOTPGroup.displayName = 'InputOTPGroup';
29
+
30
+ const InputOTPSlot = React.forwardRef<
31
+ HTMLDivElement,
32
+ React.ComponentPropsWithoutRef<'div'> & { index: number }
33
+ >(({ index, className, ...props }, ref) => {
34
+ const inputOTPContext = React.useContext(OTPInputContext);
35
+ const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index];
36
+
37
+ return (
38
+ <div
39
+ ref={ref}
40
+ className={cn(
41
+ 'relative flex h-[32px] w-[36px] items-center justify-center border-y border-r border-input text-[13px] leading-[20px] text-foreground transition-all first:rounded-l-[var(--pt-radius-md)] first:border-l last:rounded-r-[var(--pt-radius-md)] group-hover/input-otp:border-neutral',
42
+ isActive && 'z-10 ring-1 ring-ring',
43
+ className
44
+ )}
45
+ {...props}
46
+ >
47
+ {char}
48
+ {hasFakeCaret && (
49
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
50
+ <div className="h-[16px] w-px animate-caret-blink bg-foreground duration-1000" />
51
+ </div>
52
+ )}
53
+ </div>
54
+ );
55
+ });
56
+ InputOTPSlot.displayName = 'InputOTPSlot';
57
+
58
+ const InputOTPSeparator = React.forwardRef<HTMLDivElement, React.ComponentPropsWithoutRef<'div'>>(
59
+ ({ ...props }, ref) => (
60
+ <div ref={ref} role="separator" className="text-muted-foreground" {...props}>
61
+ <Minus className="h-[16px] w-[16px]" />
62
+ </div>
63
+ )
64
+ );
65
+ InputOTPSeparator.displayName = 'InputOTPSeparator';
66
+
67
+ export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
@@ -0,0 +1,24 @@
1
+ import * as React from 'react';
2
+
3
+ import { cn } from '../../lib/utils';
4
+
5
+ export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
6
+
7
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
8
+ ({ className, type, ...props }, ref) => {
9
+ return (
10
+ <input
11
+ type={type}
12
+ className={cn(
13
+ 'flex h-[32px] w-full rounded-[var(--pt-radius-md)] border border-input bg-transparent px-[12px] py-[4px] text-[13px] leading-[20px] transition-colors file:border-0 file:bg-transparent file:text-[14px] file:leading-[20px] file:font-medium placeholder:text-muted-foreground enabled:hover:border-neutral focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 aria-[invalid=true]:border-destructive aria-[invalid=true]:enabled:hover:border-destructive aria-[invalid=true]:focus-visible:ring-destructive/30',
14
+ className
15
+ )}
16
+ ref={ref}
17
+ {...props}
18
+ />
19
+ );
20
+ }
21
+ );
22
+ Input.displayName = 'Input';
23
+
24
+ export { Input };