lite-math 1.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 (321) hide show
  1. package/.eslintrc.json +19 -0
  2. package/.prettierrc +10 -0
  3. package/CHANGELOG.md +22 -0
  4. package/CONTRIBUTING.md +51 -0
  5. package/LICENSE +21 -0
  6. package/README.md +213 -0
  7. package/app/globals.css +125 -0
  8. package/app/layout.tsx +27 -0
  9. package/app/page.tsx +7 -0
  10. package/components/theme-provider.tsx +11 -0
  11. package/components/ui/accordion.tsx +66 -0
  12. package/components/ui/alert-dialog.tsx +157 -0
  13. package/components/ui/alert.tsx +66 -0
  14. package/components/ui/aspect-ratio.tsx +11 -0
  15. package/components/ui/avatar.tsx +53 -0
  16. package/components/ui/badge.tsx +46 -0
  17. package/components/ui/breadcrumb.tsx +109 -0
  18. package/components/ui/button-group.tsx +83 -0
  19. package/components/ui/button.tsx +60 -0
  20. package/components/ui/calendar.tsx +213 -0
  21. package/components/ui/card.tsx +92 -0
  22. package/components/ui/carousel.tsx +241 -0
  23. package/components/ui/chart.tsx +353 -0
  24. package/components/ui/checkbox.tsx +32 -0
  25. package/components/ui/collapsible.tsx +33 -0
  26. package/components/ui/command.tsx +184 -0
  27. package/components/ui/context-menu.tsx +252 -0
  28. package/components/ui/dialog.tsx +143 -0
  29. package/components/ui/drawer.tsx +135 -0
  30. package/components/ui/dropdown-menu.tsx +257 -0
  31. package/components/ui/empty.tsx +104 -0
  32. package/components/ui/field.tsx +244 -0
  33. package/components/ui/form.tsx +167 -0
  34. package/components/ui/hover-card.tsx +44 -0
  35. package/components/ui/input-group.tsx +169 -0
  36. package/components/ui/input-otp.tsx +77 -0
  37. package/components/ui/input.tsx +21 -0
  38. package/components/ui/item.tsx +193 -0
  39. package/components/ui/kbd.tsx +28 -0
  40. package/components/ui/label.tsx +24 -0
  41. package/components/ui/menubar.tsx +276 -0
  42. package/components/ui/navigation-menu.tsx +166 -0
  43. package/components/ui/pagination.tsx +127 -0
  44. package/components/ui/popover.tsx +48 -0
  45. package/components/ui/progress.tsx +31 -0
  46. package/components/ui/radio-group.tsx +45 -0
  47. package/components/ui/resizable.tsx +56 -0
  48. package/components/ui/scroll-area.tsx +58 -0
  49. package/components/ui/select.tsx +185 -0
  50. package/components/ui/separator.tsx +28 -0
  51. package/components/ui/sheet.tsx +139 -0
  52. package/components/ui/sidebar.tsx +726 -0
  53. package/components/ui/skeleton.tsx +13 -0
  54. package/components/ui/slider.tsx +63 -0
  55. package/components/ui/sonner.tsx +25 -0
  56. package/components/ui/spinner.tsx +16 -0
  57. package/components/ui/switch.tsx +31 -0
  58. package/components/ui/table.tsx +116 -0
  59. package/components/ui/tabs.tsx +66 -0
  60. package/components/ui/textarea.tsx +18 -0
  61. package/components/ui/toast.tsx +129 -0
  62. package/components/ui/toaster.tsx +35 -0
  63. package/components/ui/toggle-group.tsx +73 -0
  64. package/components/ui/toggle.tsx +47 -0
  65. package/components/ui/tooltip.tsx +61 -0
  66. package/components/ui/use-mobile.tsx +19 -0
  67. package/components/ui/use-toast.ts +191 -0
  68. package/components.json +21 -0
  69. package/dist/advanced/cube-root.d.ts +2 -0
  70. package/dist/advanced/cube-root.d.ts.map +1 -0
  71. package/dist/advanced/cube-root.js +4 -0
  72. package/dist/advanced/cube-root.js.map +1 -0
  73. package/dist/advanced/factorial.d.ts +2 -0
  74. package/dist/advanced/factorial.d.ts.map +1 -0
  75. package/dist/advanced/factorial.js +11 -0
  76. package/dist/advanced/factorial.js.map +1 -0
  77. package/dist/advanced/fibonacci.d.ts +2 -0
  78. package/dist/advanced/fibonacci.d.ts.map +1 -0
  79. package/dist/advanced/fibonacci.js +15 -0
  80. package/dist/advanced/fibonacci.js.map +1 -0
  81. package/dist/advanced/gcd.d.ts +2 -0
  82. package/dist/advanced/gcd.d.ts.map +1 -0
  83. package/dist/advanced/gcd.js +10 -0
  84. package/dist/advanced/gcd.js.map +1 -0
  85. package/dist/advanced/lcm.d.ts +2 -0
  86. package/dist/advanced/lcm.d.ts.map +1 -0
  87. package/dist/advanced/lcm.js +13 -0
  88. package/dist/advanced/lcm.js.map +1 -0
  89. package/dist/advanced/power.d.ts +2 -0
  90. package/dist/advanced/power.d.ts.map +1 -0
  91. package/dist/advanced/power.js +4 -0
  92. package/dist/advanced/power.js.map +1 -0
  93. package/dist/advanced/prime-check.d.ts +2 -0
  94. package/dist/advanced/prime-check.d.ts.map +1 -0
  95. package/dist/advanced/prime-check.js +14 -0
  96. package/dist/advanced/prime-check.js.map +1 -0
  97. package/dist/advanced/prime-list.d.ts +2 -0
  98. package/dist/advanced/prime-list.d.ts.map +1 -0
  99. package/dist/advanced/prime-list.js +14 -0
  100. package/dist/advanced/prime-list.js.map +1 -0
  101. package/dist/advanced/sqrt.d.ts +2 -0
  102. package/dist/advanced/sqrt.d.ts.map +1 -0
  103. package/dist/advanced/sqrt.js +6 -0
  104. package/dist/advanced/sqrt.js.map +1 -0
  105. package/dist/algebra/circle-area.d.ts +2 -0
  106. package/dist/algebra/circle-area.d.ts.map +1 -0
  107. package/dist/algebra/circle-area.js +4 -0
  108. package/dist/algebra/circle-area.js.map +1 -0
  109. package/dist/algebra/distance.d.ts +2 -0
  110. package/dist/algebra/distance.d.ts.map +1 -0
  111. package/dist/algebra/distance.js +4 -0
  112. package/dist/algebra/distance.js.map +1 -0
  113. package/dist/algebra/midpoint.d.ts +2 -0
  114. package/dist/algebra/midpoint.d.ts.map +1 -0
  115. package/dist/algebra/midpoint.js +4 -0
  116. package/dist/algebra/midpoint.js.map +1 -0
  117. package/dist/algebra/slope.d.ts +2 -0
  118. package/dist/algebra/slope.d.ts.map +1 -0
  119. package/dist/algebra/slope.js +6 -0
  120. package/dist/algebra/slope.js.map +1 -0
  121. package/dist/algebra/solve-linear.d.ts +2 -0
  122. package/dist/algebra/solve-linear.d.ts.map +1 -0
  123. package/dist/algebra/solve-linear.js +6 -0
  124. package/dist/algebra/solve-linear.js.map +1 -0
  125. package/dist/algebra/solve-quadratic.d.ts +2 -0
  126. package/dist/algebra/solve-quadratic.d.ts.map +1 -0
  127. package/dist/algebra/solve-quadratic.js +12 -0
  128. package/dist/algebra/solve-quadratic.js.map +1 -0
  129. package/dist/algebra/triangle-area.d.ts +2 -0
  130. package/dist/algebra/triangle-area.d.ts.map +1 -0
  131. package/dist/algebra/triangle-area.js +5 -0
  132. package/dist/algebra/triangle-area.js.map +1 -0
  133. package/dist/arithmetic/add.d.ts +2 -0
  134. package/dist/arithmetic/add.d.ts.map +1 -0
  135. package/dist/arithmetic/add.js +4 -0
  136. package/dist/arithmetic/add.js.map +1 -0
  137. package/dist/arithmetic/ceil.d.ts +2 -0
  138. package/dist/arithmetic/ceil.d.ts.map +1 -0
  139. package/dist/arithmetic/ceil.js +4 -0
  140. package/dist/arithmetic/ceil.js.map +1 -0
  141. package/dist/arithmetic/clamp.d.ts +2 -0
  142. package/dist/arithmetic/clamp.d.ts.map +1 -0
  143. package/dist/arithmetic/clamp.js +4 -0
  144. package/dist/arithmetic/clamp.js.map +1 -0
  145. package/dist/arithmetic/divide.d.ts +2 -0
  146. package/dist/arithmetic/divide.d.ts.map +1 -0
  147. package/dist/arithmetic/divide.js +6 -0
  148. package/dist/arithmetic/divide.js.map +1 -0
  149. package/dist/arithmetic/floor.d.ts +2 -0
  150. package/dist/arithmetic/floor.d.ts.map +1 -0
  151. package/dist/arithmetic/floor.js +4 -0
  152. package/dist/arithmetic/floor.js.map +1 -0
  153. package/dist/arithmetic/modulo.d.ts +2 -0
  154. package/dist/arithmetic/modulo.d.ts.map +1 -0
  155. package/dist/arithmetic/modulo.js +4 -0
  156. package/dist/arithmetic/modulo.js.map +1 -0
  157. package/dist/arithmetic/multiply.d.ts +2 -0
  158. package/dist/arithmetic/multiply.d.ts.map +1 -0
  159. package/dist/arithmetic/multiply.js +4 -0
  160. package/dist/arithmetic/multiply.js.map +1 -0
  161. package/dist/arithmetic/percentage.d.ts +2 -0
  162. package/dist/arithmetic/percentage.d.ts.map +1 -0
  163. package/dist/arithmetic/percentage.js +4 -0
  164. package/dist/arithmetic/percentage.js.map +1 -0
  165. package/dist/arithmetic/round.d.ts +2 -0
  166. package/dist/arithmetic/round.d.ts.map +1 -0
  167. package/dist/arithmetic/round.js +5 -0
  168. package/dist/arithmetic/round.js.map +1 -0
  169. package/dist/arithmetic/subtract.d.ts +2 -0
  170. package/dist/arithmetic/subtract.d.ts.map +1 -0
  171. package/dist/arithmetic/subtract.js +4 -0
  172. package/dist/arithmetic/subtract.js.map +1 -0
  173. package/dist/cli.d.ts +3 -0
  174. package/dist/cli.d.ts.map +1 -0
  175. package/dist/cli.js +277 -0
  176. package/dist/cli.js.map +1 -0
  177. package/dist/convert/c-to-f.d.ts +2 -0
  178. package/dist/convert/c-to-f.d.ts.map +1 -0
  179. package/dist/convert/c-to-f.js +4 -0
  180. package/dist/convert/c-to-f.js.map +1 -0
  181. package/dist/convert/deg-to-rad.d.ts +2 -0
  182. package/dist/convert/deg-to-rad.d.ts.map +1 -0
  183. package/dist/convert/deg-to-rad.js +4 -0
  184. package/dist/convert/deg-to-rad.js.map +1 -0
  185. package/dist/convert/f-to-c.d.ts +2 -0
  186. package/dist/convert/f-to-c.d.ts.map +1 -0
  187. package/dist/convert/f-to-c.js +4 -0
  188. package/dist/convert/f-to-c.js.map +1 -0
  189. package/dist/convert/km-to-miles.d.ts +2 -0
  190. package/dist/convert/km-to-miles.d.ts.map +1 -0
  191. package/dist/convert/km-to-miles.js +4 -0
  192. package/dist/convert/km-to-miles.js.map +1 -0
  193. package/dist/convert/miles-to-km.d.ts +2 -0
  194. package/dist/convert/miles-to-km.d.ts.map +1 -0
  195. package/dist/convert/miles-to-km.js +4 -0
  196. package/dist/convert/miles-to-km.js.map +1 -0
  197. package/dist/convert/rad-to-deg.d.ts +2 -0
  198. package/dist/convert/rad-to-deg.d.ts.map +1 -0
  199. package/dist/convert/rad-to-deg.js +4 -0
  200. package/dist/convert/rad-to-deg.js.map +1 -0
  201. package/dist/index.d.ts +45 -0
  202. package/dist/index.d.ts.map +1 -0
  203. package/dist/index.js +45 -0
  204. package/dist/index.js.map +1 -0
  205. package/dist/random/random-array.d.ts +2 -0
  206. package/dist/random/random-array.d.ts.map +1 -0
  207. package/dist/random/random-array.js +4 -0
  208. package/dist/random/random-array.js.map +1 -0
  209. package/dist/random/random-float.d.ts +2 -0
  210. package/dist/random/random-float.d.ts.map +1 -0
  211. package/dist/random/random-float.js +4 -0
  212. package/dist/random/random-float.js.map +1 -0
  213. package/dist/random/random-from-array.d.ts +2 -0
  214. package/dist/random/random-from-array.d.ts.map +1 -0
  215. package/dist/random/random-from-array.js +4 -0
  216. package/dist/random/random-from-array.js.map +1 -0
  217. package/dist/random/random-int.d.ts +2 -0
  218. package/dist/random/random-int.d.ts.map +1 -0
  219. package/dist/random/random-int.js +4 -0
  220. package/dist/random/random-int.js.map +1 -0
  221. package/dist/statistics/mean.d.ts +2 -0
  222. package/dist/statistics/mean.d.ts.map +1 -0
  223. package/dist/statistics/mean.js +6 -0
  224. package/dist/statistics/mean.js.map +1 -0
  225. package/dist/statistics/median.d.ts +2 -0
  226. package/dist/statistics/median.d.ts.map +1 -0
  227. package/dist/statistics/median.js +8 -0
  228. package/dist/statistics/median.js.map +1 -0
  229. package/dist/statistics/mode.d.ts +2 -0
  230. package/dist/statistics/mode.d.ts.map +1 -0
  231. package/dist/statistics/mode.js +13 -0
  232. package/dist/statistics/mode.js.map +1 -0
  233. package/dist/statistics/product-array.d.ts +2 -0
  234. package/dist/statistics/product-array.d.ts.map +1 -0
  235. package/dist/statistics/product-array.js +4 -0
  236. package/dist/statistics/product-array.js.map +1 -0
  237. package/dist/statistics/range.d.ts +2 -0
  238. package/dist/statistics/range.d.ts.map +1 -0
  239. package/dist/statistics/range.js +6 -0
  240. package/dist/statistics/range.js.map +1 -0
  241. package/dist/statistics/std-dev.d.ts +2 -0
  242. package/dist/statistics/std-dev.d.ts.map +1 -0
  243. package/dist/statistics/std-dev.js +10 -0
  244. package/dist/statistics/std-dev.js.map +1 -0
  245. package/dist/statistics/sum-array.d.ts +2 -0
  246. package/dist/statistics/sum-array.d.ts.map +1 -0
  247. package/dist/statistics/sum-array.js +4 -0
  248. package/dist/statistics/sum-array.js.map +1 -0
  249. package/dist/statistics/variance.d.ts +2 -0
  250. package/dist/statistics/variance.d.ts.map +1 -0
  251. package/dist/statistics/variance.js +7 -0
  252. package/dist/statistics/variance.js.map +1 -0
  253. package/examples/advanced-examples.ts +31 -0
  254. package/examples/algebra-examples.ts +24 -0
  255. package/examples/arithmetic-examples.ts +24 -0
  256. package/examples/conversion-examples.ts +24 -0
  257. package/examples/statistics-examples.ts +29 -0
  258. package/hooks/use-mobile.ts +19 -0
  259. package/hooks/use-toast.ts +191 -0
  260. package/jest.config.js +15 -0
  261. package/lib/utils.ts +6 -0
  262. package/next.config.mjs +11 -0
  263. package/package.json +110 -0
  264. package/postcss.config.mjs +8 -0
  265. package/public/apple-icon.png +0 -0
  266. package/public/icon-dark-32x32.png +0 -0
  267. package/public/icon-light-32x32.png +0 -0
  268. package/public/icon.svg +26 -0
  269. package/public/placeholder-logo.png +0 -0
  270. package/public/placeholder-logo.svg +1 -0
  271. package/public/placeholder-user.jpg +0 -0
  272. package/public/placeholder.jpg +0 -0
  273. package/public/placeholder.svg +1 -0
  274. package/src/advanced/cube-root.ts +8 -0
  275. package/src/advanced/factorial.ts +12 -0
  276. package/src/advanced/fibonacci.ts +16 -0
  277. package/src/advanced/gcd.ts +14 -0
  278. package/src/advanced/lcm.ts +18 -0
  279. package/src/advanced/power.ts +9 -0
  280. package/src/advanced/prime-check.ts +14 -0
  281. package/src/advanced/prime-list.ts +16 -0
  282. package/src/advanced/sqrt.ts +9 -0
  283. package/src/algebra/circle-area.ts +8 -0
  284. package/src/algebra/distance.ts +11 -0
  285. package/src/algebra/midpoint.ts +11 -0
  286. package/src/algebra/slope.ts +12 -0
  287. package/src/algebra/solve-linear.ts +10 -0
  288. package/src/algebra/solve-quadratic.ts +15 -0
  289. package/src/algebra/triangle-area.ts +11 -0
  290. package/src/arithmetic/add.ts +9 -0
  291. package/src/arithmetic/ceil.ts +8 -0
  292. package/src/arithmetic/clamp.ts +10 -0
  293. package/src/arithmetic/divide.ts +11 -0
  294. package/src/arithmetic/floor.ts +8 -0
  295. package/src/arithmetic/modulo.ts +9 -0
  296. package/src/arithmetic/multiply.ts +9 -0
  297. package/src/arithmetic/percentage.ts +9 -0
  298. package/src/arithmetic/round.ts +10 -0
  299. package/src/arithmetic/subtract.ts +9 -0
  300. package/src/cli.ts +321 -0
  301. package/src/convert/c-to-f.ts +8 -0
  302. package/src/convert/deg-to-rad.ts +8 -0
  303. package/src/convert/f-to-c.ts +8 -0
  304. package/src/convert/km-to-miles.ts +8 -0
  305. package/src/convert/miles-to-km.ts +8 -0
  306. package/src/convert/rad-to-deg.ts +8 -0
  307. package/src/index.ts +49 -0
  308. package/src/random/random-array.ts +10 -0
  309. package/src/random/random-float.ts +9 -0
  310. package/src/random/random-from-array.ts +8 -0
  311. package/src/random/random-int.ts +9 -0
  312. package/src/statistics/mean.ts +9 -0
  313. package/src/statistics/median.ts +11 -0
  314. package/src/statistics/mode.ts +16 -0
  315. package/src/statistics/product-array.ts +8 -0
  316. package/src/statistics/range.ts +9 -0
  317. package/src/statistics/std-dev.ts +14 -0
  318. package/src/statistics/sum-array.ts +8 -0
  319. package/src/statistics/variance.ts +10 -0
  320. package/styles/globals.css +125 -0
  321. package/tsconfig.json +25 -0
@@ -0,0 +1,167 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import * as LabelPrimitive from '@radix-ui/react-label'
5
+ import { Slot } from '@radix-ui/react-slot'
6
+ import {
7
+ Controller,
8
+ FormProvider,
9
+ useFormContext,
10
+ useFormState,
11
+ type ControllerProps,
12
+ type FieldPath,
13
+ type FieldValues,
14
+ } from 'react-hook-form'
15
+
16
+ import { cn } from '@/lib/utils'
17
+ import { Label } from '@/components/ui/label'
18
+
19
+ const Form = FormProvider
20
+
21
+ type FormFieldContextValue<
22
+ TFieldValues extends FieldValues = FieldValues,
23
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
24
+ > = {
25
+ name: TName
26
+ }
27
+
28
+ const FormFieldContext = React.createContext<FormFieldContextValue>(
29
+ {} as FormFieldContextValue,
30
+ )
31
+
32
+ const FormField = <
33
+ TFieldValues extends FieldValues = FieldValues,
34
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
35
+ >({
36
+ ...props
37
+ }: ControllerProps<TFieldValues, TName>) => {
38
+ return (
39
+ <FormFieldContext.Provider value={{ name: props.name }}>
40
+ <Controller {...props} />
41
+ </FormFieldContext.Provider>
42
+ )
43
+ }
44
+
45
+ const useFormField = () => {
46
+ const fieldContext = React.useContext(FormFieldContext)
47
+ const itemContext = React.useContext(FormItemContext)
48
+ const { getFieldState } = useFormContext()
49
+ const formState = useFormState({ name: fieldContext.name })
50
+ const fieldState = getFieldState(fieldContext.name, formState)
51
+
52
+ if (!fieldContext) {
53
+ throw new Error('useFormField should be used within <FormField>')
54
+ }
55
+
56
+ const { id } = itemContext
57
+
58
+ return {
59
+ id,
60
+ name: fieldContext.name,
61
+ formItemId: `${id}-form-item`,
62
+ formDescriptionId: `${id}-form-item-description`,
63
+ formMessageId: `${id}-form-item-message`,
64
+ ...fieldState,
65
+ }
66
+ }
67
+
68
+ type FormItemContextValue = {
69
+ id: string
70
+ }
71
+
72
+ const FormItemContext = React.createContext<FormItemContextValue>(
73
+ {} as FormItemContextValue,
74
+ )
75
+
76
+ function FormItem({ className, ...props }: React.ComponentProps<'div'>) {
77
+ const id = React.useId()
78
+
79
+ return (
80
+ <FormItemContext.Provider value={{ id }}>
81
+ <div
82
+ data-slot="form-item"
83
+ className={cn('grid gap-2', className)}
84
+ {...props}
85
+ />
86
+ </FormItemContext.Provider>
87
+ )
88
+ }
89
+
90
+ function FormLabel({
91
+ className,
92
+ ...props
93
+ }: React.ComponentProps<typeof LabelPrimitive.Root>) {
94
+ const { error, formItemId } = useFormField()
95
+
96
+ return (
97
+ <Label
98
+ data-slot="form-label"
99
+ data-error={!!error}
100
+ className={cn('data-[error=true]:text-destructive', className)}
101
+ htmlFor={formItemId}
102
+ {...props}
103
+ />
104
+ )
105
+ }
106
+
107
+ function FormControl({ ...props }: React.ComponentProps<typeof Slot>) {
108
+ const { error, formItemId, formDescriptionId, formMessageId } = 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-muted-foreground text-sm', 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-destructive text-sm', 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
+ }
@@ -0,0 +1,44 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import * as HoverCardPrimitive from '@radix-ui/react-hover-card'
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
+ 'bg-popover text-popover-foreground 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 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden',
36
+ className,
37
+ )}
38
+ {...props}
39
+ />
40
+ </HoverCardPrimitive.Portal>
41
+ )
42
+ }
43
+
44
+ export { HoverCard, HoverCardTrigger, HoverCardContent }
@@ -0,0 +1,169 @@
1
+ 'use client'
2
+
3
+ import { cva, type VariantProps } from 'class-variance-authority'
4
+
5
+ import { cn } from '@/lib/utils'
6
+ import { Button } from '@/components/ui/button'
7
+ import { Input } from '@/components/ui/input'
8
+ import { Textarea } from '@/components/ui/textarea'
9
+
10
+ function InputGroup({ className, ...props }: React.ComponentProps<'div'>) {
11
+ return (
12
+ <div
13
+ data-slot="input-group"
14
+ role="group"
15
+ className={cn(
16
+ 'group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none',
17
+ 'h-9 has-[>textarea]:h-auto',
18
+
19
+ // Variants based on alignment.
20
+ 'has-[>[data-align=inline-start]]:[&>input]:pl-2',
21
+ 'has-[>[data-align=inline-end]]:[&>input]:pr-2',
22
+ 'has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3',
23
+ 'has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3',
24
+
25
+ // Focus state.
26
+ 'has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]',
27
+
28
+ // Error state.
29
+ 'has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40',
30
+
31
+ className,
32
+ )}
33
+ {...props}
34
+ />
35
+ )
36
+ }
37
+
38
+ const inputGroupAddonVariants = cva(
39
+ "text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50",
40
+ {
41
+ variants: {
42
+ align: {
43
+ 'inline-start':
44
+ 'order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]',
45
+ 'inline-end':
46
+ 'order-last pr-3 has-[>button]:mr-[-0.4rem] has-[>kbd]:mr-[-0.35rem]',
47
+ 'block-start':
48
+ 'order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5',
49
+ 'block-end':
50
+ 'order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5',
51
+ },
52
+ },
53
+ defaultVariants: {
54
+ align: 'inline-start',
55
+ },
56
+ },
57
+ )
58
+
59
+ function InputGroupAddon({
60
+ className,
61
+ align = 'inline-start',
62
+ ...props
63
+ }: React.ComponentProps<'div'> & VariantProps<typeof inputGroupAddonVariants>) {
64
+ return (
65
+ <div
66
+ role="group"
67
+ data-slot="input-group-addon"
68
+ data-align={align}
69
+ className={cn(inputGroupAddonVariants({ align }), className)}
70
+ onClick={(e) => {
71
+ if ((e.target as HTMLElement).closest('button')) {
72
+ return
73
+ }
74
+ e.currentTarget.parentElement?.querySelector('input')?.focus()
75
+ }}
76
+ {...props}
77
+ />
78
+ )
79
+ }
80
+
81
+ const inputGroupButtonVariants = cva(
82
+ 'text-sm shadow-none flex gap-2 items-center',
83
+ {
84
+ variants: {
85
+ size: {
86
+ xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2",
87
+ sm: 'h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5',
88
+ 'icon-xs':
89
+ 'size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0',
90
+ 'icon-sm': 'size-8 p-0 has-[>svg]:p-0',
91
+ },
92
+ },
93
+ defaultVariants: {
94
+ size: 'xs',
95
+ },
96
+ },
97
+ )
98
+
99
+ function InputGroupButton({
100
+ className,
101
+ type = 'button',
102
+ variant = 'ghost',
103
+ size = 'xs',
104
+ ...props
105
+ }: Omit<React.ComponentProps<typeof Button>, 'size'> &
106
+ VariantProps<typeof inputGroupButtonVariants>) {
107
+ return (
108
+ <Button
109
+ type={type}
110
+ data-size={size}
111
+ variant={variant}
112
+ className={cn(inputGroupButtonVariants({ size }), className)}
113
+ {...props}
114
+ />
115
+ )
116
+ }
117
+
118
+ function InputGroupText({ className, ...props }: React.ComponentProps<'span'>) {
119
+ return (
120
+ <span
121
+ className={cn(
122
+ "text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
123
+ className,
124
+ )}
125
+ {...props}
126
+ />
127
+ )
128
+ }
129
+
130
+ function InputGroupInput({
131
+ className,
132
+ ...props
133
+ }: React.ComponentProps<'input'>) {
134
+ return (
135
+ <Input
136
+ data-slot="input-group-control"
137
+ className={cn(
138
+ 'flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent',
139
+ className,
140
+ )}
141
+ {...props}
142
+ />
143
+ )
144
+ }
145
+
146
+ function InputGroupTextarea({
147
+ className,
148
+ ...props
149
+ }: React.ComponentProps<'textarea'>) {
150
+ return (
151
+ <Textarea
152
+ data-slot="input-group-control"
153
+ className={cn(
154
+ 'flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent',
155
+ className,
156
+ )}
157
+ {...props}
158
+ />
159
+ )
160
+ }
161
+
162
+ export {
163
+ InputGroup,
164
+ InputGroupAddon,
165
+ InputGroupButton,
166
+ InputGroupText,
167
+ InputGroupInput,
168
+ InputGroupTextarea,
169
+ }
@@ -0,0 +1,77 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { OTPInput, OTPInputContext } from 'input-otp'
5
+ import { MinusIcon } from 'lucide-react'
6
+
7
+ import { cn } from '@/lib/utils'
8
+
9
+ function InputOTP({
10
+ className,
11
+ containerClassName,
12
+ ...props
13
+ }: React.ComponentProps<typeof OTPInput> & {
14
+ containerClassName?: string
15
+ }) {
16
+ return (
17
+ <OTPInput
18
+ data-slot="input-otp"
19
+ containerClassName={cn(
20
+ 'flex items-center gap-2 has-disabled:opacity-50',
21
+ containerClassName,
22
+ )}
23
+ className={cn('disabled:cursor-not-allowed', className)}
24
+ {...props}
25
+ />
26
+ )
27
+ }
28
+
29
+ function InputOTPGroup({ className, ...props }: React.ComponentProps<'div'>) {
30
+ return (
31
+ <div
32
+ data-slot="input-otp-group"
33
+ className={cn('flex items-center', className)}
34
+ {...props}
35
+ />
36
+ )
37
+ }
38
+
39
+ function InputOTPSlot({
40
+ index,
41
+ className,
42
+ ...props
43
+ }: React.ComponentProps<'div'> & {
44
+ index: number
45
+ }) {
46
+ const inputOTPContext = React.useContext(OTPInputContext)
47
+ const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}
48
+
49
+ return (
50
+ <div
51
+ data-slot="input-otp-slot"
52
+ data-active={isActive}
53
+ className={cn(
54
+ 'data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]',
55
+ className,
56
+ )}
57
+ {...props}
58
+ >
59
+ {char}
60
+ {hasFakeCaret && (
61
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
62
+ <div className="animate-caret-blink bg-foreground h-4 w-px duration-1000" />
63
+ </div>
64
+ )}
65
+ </div>
66
+ )
67
+ }
68
+
69
+ function InputOTPSeparator({ ...props }: React.ComponentProps<'div'>) {
70
+ return (
71
+ <div data-slot="input-otp-separator" role="separator" {...props}>
72
+ <MinusIcon />
73
+ </div>
74
+ )
75
+ }
76
+
77
+ export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
@@ -0,0 +1,21 @@
1
+ import * as React from 'react'
2
+
3
+ import { cn } from '@/lib/utils'
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
6
+ return (
7
+ <input
8
+ type={type}
9
+ data-slot="input"
10
+ className={cn(
11
+ 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
12
+ 'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
13
+ 'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
14
+ className,
15
+ )}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ export { Input }
@@ -0,0 +1,193 @@
1
+ import * as React from 'react'
2
+ import { Slot } from '@radix-ui/react-slot'
3
+ import { cva, type VariantProps } from 'class-variance-authority'
4
+
5
+ import { cn } from '@/lib/utils'
6
+ import { Separator } from '@/components/ui/separator'
7
+
8
+ function ItemGroup({ className, ...props }: React.ComponentProps<'div'>) {
9
+ return (
10
+ <div
11
+ role="list"
12
+ data-slot="item-group"
13
+ className={cn('group/item-group flex flex-col', className)}
14
+ {...props}
15
+ />
16
+ )
17
+ }
18
+
19
+ function ItemSeparator({
20
+ className,
21
+ ...props
22
+ }: React.ComponentProps<typeof Separator>) {
23
+ return (
24
+ <Separator
25
+ data-slot="item-separator"
26
+ orientation="horizontal"
27
+ className={cn('my-0', className)}
28
+ {...props}
29
+ />
30
+ )
31
+ }
32
+
33
+ const itemVariants = cva(
34
+ 'group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a&]:hover:bg-accent/50 [a&]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
35
+ {
36
+ variants: {
37
+ variant: {
38
+ default: 'bg-transparent',
39
+ outline: 'border-border',
40
+ muted: 'bg-muted/50',
41
+ },
42
+ size: {
43
+ default: 'p-4 gap-4 ',
44
+ sm: 'py-3 px-4 gap-2.5',
45
+ },
46
+ },
47
+ defaultVariants: {
48
+ variant: 'default',
49
+ size: 'default',
50
+ },
51
+ },
52
+ )
53
+
54
+ function Item({
55
+ className,
56
+ variant = 'default',
57
+ size = 'default',
58
+ asChild = false,
59
+ ...props
60
+ }: React.ComponentProps<'div'> &
61
+ VariantProps<typeof itemVariants> & { asChild?: boolean }) {
62
+ const Comp = asChild ? Slot : 'div'
63
+ return (
64
+ <Comp
65
+ data-slot="item"
66
+ data-variant={variant}
67
+ data-size={size}
68
+ className={cn(itemVariants({ variant, size, className }))}
69
+ {...props}
70
+ />
71
+ )
72
+ }
73
+
74
+ const itemMediaVariants = cva(
75
+ 'flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none group-has-[[data-slot=item-description]]/item:translate-y-0.5',
76
+ {
77
+ variants: {
78
+ variant: {
79
+ default: 'bg-transparent',
80
+ icon: "size-8 border rounded-sm bg-muted [&_svg:not([class*='size-'])]:size-4",
81
+ image:
82
+ 'size-10 rounded-sm overflow-hidden [&_img]:size-full [&_img]:object-cover',
83
+ },
84
+ },
85
+ defaultVariants: {
86
+ variant: 'default',
87
+ },
88
+ },
89
+ )
90
+
91
+ function ItemMedia({
92
+ className,
93
+ variant = 'default',
94
+ ...props
95
+ }: React.ComponentProps<'div'> & VariantProps<typeof itemMediaVariants>) {
96
+ return (
97
+ <div
98
+ data-slot="item-media"
99
+ data-variant={variant}
100
+ className={cn(itemMediaVariants({ variant, className }))}
101
+ {...props}
102
+ />
103
+ )
104
+ }
105
+
106
+ function ItemContent({ className, ...props }: React.ComponentProps<'div'>) {
107
+ return (
108
+ <div
109
+ data-slot="item-content"
110
+ className={cn(
111
+ 'flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none',
112
+ className,
113
+ )}
114
+ {...props}
115
+ />
116
+ )
117
+ }
118
+
119
+ function ItemTitle({ className, ...props }: React.ComponentProps<'div'>) {
120
+ return (
121
+ <div
122
+ data-slot="item-title"
123
+ className={cn(
124
+ 'flex w-fit items-center gap-2 text-sm leading-snug font-medium',
125
+ className,
126
+ )}
127
+ {...props}
128
+ />
129
+ )
130
+ }
131
+
132
+ function ItemDescription({ className, ...props }: React.ComponentProps<'p'>) {
133
+ return (
134
+ <p
135
+ data-slot="item-description"
136
+ className={cn(
137
+ 'text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance',
138
+ '[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',
139
+ className,
140
+ )}
141
+ {...props}
142
+ />
143
+ )
144
+ }
145
+
146
+ function ItemActions({ className, ...props }: React.ComponentProps<'div'>) {
147
+ return (
148
+ <div
149
+ data-slot="item-actions"
150
+ className={cn('flex items-center gap-2', className)}
151
+ {...props}
152
+ />
153
+ )
154
+ }
155
+
156
+ function ItemHeader({ className, ...props }: React.ComponentProps<'div'>) {
157
+ return (
158
+ <div
159
+ data-slot="item-header"
160
+ className={cn(
161
+ 'flex basis-full items-center justify-between gap-2',
162
+ className,
163
+ )}
164
+ {...props}
165
+ />
166
+ )
167
+ }
168
+
169
+ function ItemFooter({ className, ...props }: React.ComponentProps<'div'>) {
170
+ return (
171
+ <div
172
+ data-slot="item-footer"
173
+ className={cn(
174
+ 'flex basis-full items-center justify-between gap-2',
175
+ className,
176
+ )}
177
+ {...props}
178
+ />
179
+ )
180
+ }
181
+
182
+ export {
183
+ Item,
184
+ ItemMedia,
185
+ ItemContent,
186
+ ItemActions,
187
+ ItemGroup,
188
+ ItemSeparator,
189
+ ItemTitle,
190
+ ItemDescription,
191
+ ItemHeader,
192
+ ItemFooter,
193
+ }
@@ -0,0 +1,28 @@
1
+ import { cn } from '@/lib/utils'
2
+
3
+ function Kbd({ className, ...props }: React.ComponentProps<'kbd'>) {
4
+ return (
5
+ <kbd
6
+ data-slot="kbd"
7
+ className={cn(
8
+ 'bg-muted w-fit text-muted-foreground pointer-events-none inline-flex h-5 min-w-5 items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium select-none',
9
+ "[&_svg:not([class*='size-'])]:size-3",
10
+ '[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10',
11
+ className,
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ function KbdGroup({ className, ...props }: React.ComponentProps<'div'>) {
19
+ return (
20
+ <kbd
21
+ data-slot="kbd-group"
22
+ className={cn('inline-flex items-center gap-1', className)}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ export { Kbd, KbdGroup }