@object-ui/components 0.3.0 → 0.3.1

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 (317) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/ISSUES_FOUND.md +128 -0
  3. package/README.md +19 -1
  4. package/README_SHADCN_SYNC.md +281 -0
  5. package/TESTING.md +335 -0
  6. package/dist/index.css +1 -1
  7. package/dist/index.js +30981 -30027
  8. package/dist/index.umd.cjs +30 -39
  9. package/dist/src/hooks/use-mobile.d.ts +7 -0
  10. package/dist/src/index.d.ts +4 -1
  11. package/dist/src/renderers/basic/button-group.d.ts +8 -0
  12. package/dist/src/renderers/basic/div.d.ts +7 -0
  13. package/dist/src/renderers/basic/html.d.ts +7 -0
  14. package/dist/src/renderers/basic/icon.d.ts +7 -0
  15. package/dist/src/renderers/basic/image.d.ts +7 -0
  16. package/dist/src/renderers/basic/navigation-menu.d.ts +8 -0
  17. package/dist/src/renderers/basic/pagination.d.ts +8 -0
  18. package/dist/src/renderers/basic/separator.d.ts +7 -0
  19. package/dist/src/renderers/basic/span.d.ts +7 -0
  20. package/dist/src/renderers/basic/text.d.ts +7 -0
  21. package/dist/src/renderers/complex/carousel.d.ts +7 -0
  22. package/dist/src/renderers/complex/data-table.d.ts +7 -0
  23. package/dist/src/renderers/complex/filter-builder.d.ts +7 -0
  24. package/dist/src/renderers/complex/resizable.d.ts +7 -0
  25. package/dist/src/renderers/complex/scroll-area.d.ts +7 -0
  26. package/dist/src/renderers/complex/table.d.ts +7 -0
  27. package/dist/src/renderers/data-display/alert.d.ts +7 -0
  28. package/dist/src/renderers/data-display/avatar.d.ts +7 -0
  29. package/dist/src/renderers/data-display/badge.d.ts +7 -0
  30. package/dist/src/renderers/data-display/breadcrumb.d.ts +8 -0
  31. package/dist/src/renderers/data-display/kbd.d.ts +8 -0
  32. package/dist/src/renderers/data-display/list.d.ts +7 -0
  33. package/dist/src/renderers/data-display/statistic.d.ts +7 -0
  34. package/dist/src/renderers/data-display/table.d.ts +8 -0
  35. package/dist/src/renderers/data-display/tree-view.d.ts +7 -0
  36. package/dist/src/renderers/disclosure/accordion.d.ts +7 -0
  37. package/dist/src/renderers/disclosure/collapsible.d.ts +7 -0
  38. package/dist/src/renderers/disclosure/toggle-group.d.ts +8 -0
  39. package/dist/src/renderers/feedback/empty.d.ts +8 -0
  40. package/dist/src/renderers/feedback/loading.d.ts +7 -0
  41. package/dist/src/renderers/feedback/progress.d.ts +7 -0
  42. package/dist/src/renderers/feedback/skeleton.d.ts +7 -0
  43. package/dist/src/renderers/feedback/sonner.d.ts +8 -0
  44. package/dist/src/renderers/feedback/spinner.d.ts +8 -0
  45. package/dist/src/renderers/feedback/toast.d.ts +8 -0
  46. package/dist/src/renderers/feedback/toaster.d.ts +7 -0
  47. package/dist/src/renderers/form/button.d.ts +7 -0
  48. package/dist/src/renderers/form/calendar.d.ts +7 -0
  49. package/dist/src/renderers/form/checkbox.d.ts +7 -0
  50. package/dist/src/renderers/form/combobox.d.ts +8 -0
  51. package/dist/src/renderers/form/command.d.ts +8 -0
  52. package/dist/src/renderers/form/date-picker.d.ts +7 -0
  53. package/dist/src/renderers/form/file-upload.d.ts +7 -0
  54. package/dist/src/renderers/form/form.d.ts +7 -0
  55. package/dist/src/renderers/form/input-otp.d.ts +7 -0
  56. package/dist/src/renderers/form/input.d.ts +7 -0
  57. package/dist/src/renderers/form/label.d.ts +7 -0
  58. package/dist/src/renderers/form/radio-group.d.ts +7 -0
  59. package/dist/src/renderers/form/select.d.ts +7 -0
  60. package/dist/src/renderers/form/slider.d.ts +7 -0
  61. package/dist/src/renderers/form/switch.d.ts +7 -0
  62. package/dist/src/renderers/form/textarea.d.ts +7 -0
  63. package/dist/src/renderers/form/toggle.d.ts +7 -0
  64. package/dist/src/renderers/layout/aspect-ratio.d.ts +8 -0
  65. package/dist/src/renderers/layout/card.d.ts +7 -0
  66. package/dist/src/renderers/layout/container.d.ts +7 -0
  67. package/dist/src/renderers/layout/flex.d.ts +7 -0
  68. package/dist/src/renderers/layout/grid.d.ts +7 -0
  69. package/dist/src/renderers/layout/semantic.d.ts +7 -0
  70. package/dist/src/renderers/layout/stack.d.ts +7 -0
  71. package/dist/src/renderers/layout/tabs.d.ts +7 -0
  72. package/dist/src/renderers/navigation/header-bar.d.ts +7 -0
  73. package/dist/src/renderers/navigation/sidebar.d.ts +7 -0
  74. package/dist/src/renderers/overlay/alert-dialog.d.ts +7 -0
  75. package/dist/src/renderers/overlay/context-menu.d.ts +7 -0
  76. package/dist/src/renderers/overlay/dialog.d.ts +7 -0
  77. package/dist/src/renderers/overlay/drawer.d.ts +7 -0
  78. package/dist/src/renderers/overlay/dropdown-menu.d.ts +7 -0
  79. package/dist/src/renderers/overlay/hover-card.d.ts +7 -0
  80. package/dist/src/renderers/overlay/menubar.d.ts +8 -0
  81. package/dist/src/renderers/overlay/popover.d.ts +7 -0
  82. package/dist/src/renderers/overlay/sheet.d.ts +7 -0
  83. package/dist/src/renderers/overlay/tooltip.d.ts +7 -0
  84. package/dist/src/renderers/placeholders.d.ts +9 -0
  85. package/dist/src/ui/accordion.d.ts +7 -0
  86. package/dist/src/ui/alert-dialog.d.ts +7 -0
  87. package/dist/src/ui/alert.d.ts +7 -0
  88. package/dist/src/ui/aspect-ratio.d.ts +7 -0
  89. package/dist/src/ui/avatar.d.ts +7 -0
  90. package/dist/src/ui/badge.d.ts +7 -0
  91. package/dist/src/ui/breadcrumb.d.ts +7 -0
  92. package/dist/src/ui/button.d.ts +10 -5
  93. package/dist/src/ui/calendar.d.ts +14 -7
  94. package/dist/src/ui/card.d.ts +7 -0
  95. package/dist/src/ui/carousel.d.ts +7 -0
  96. package/dist/src/ui/checkbox.d.ts +7 -0
  97. package/dist/src/ui/collapsible.d.ts +7 -0
  98. package/dist/src/ui/combobox.d.ts +22 -0
  99. package/dist/src/ui/command.d.ts +7 -0
  100. package/dist/src/ui/context-menu.d.ts +7 -0
  101. package/dist/src/ui/date-picker.d.ts +15 -0
  102. package/dist/src/ui/dialog.d.ts +7 -0
  103. package/dist/src/ui/drawer.d.ts +7 -0
  104. package/dist/src/ui/dropdown-menu.d.ts +7 -0
  105. package/dist/src/ui/filter-builder.d.ts +7 -0
  106. package/dist/src/ui/form.d.ts +7 -0
  107. package/dist/src/ui/hover-card.d.ts +7 -0
  108. package/dist/src/ui/index.d.ts +10 -5
  109. package/dist/src/ui/input-otp.d.ts +7 -0
  110. package/dist/src/ui/input.d.ts +7 -0
  111. package/dist/src/ui/item.d.ts +7 -0
  112. package/dist/src/ui/kbd.d.ts +7 -0
  113. package/dist/src/ui/label.d.ts +7 -0
  114. package/dist/src/ui/menubar.d.ts +7 -0
  115. package/dist/src/ui/navigation-menu.d.ts +7 -0
  116. package/dist/src/ui/pagination.d.ts +7 -0
  117. package/dist/src/ui/popover.d.ts +7 -0
  118. package/dist/src/ui/progress.d.ts +7 -0
  119. package/dist/src/ui/radio-group.d.ts +7 -0
  120. package/dist/src/ui/resizable.d.ts +7 -0
  121. package/dist/src/ui/scroll-area.d.ts +7 -0
  122. package/dist/src/ui/select.d.ts +9 -2
  123. package/dist/src/ui/separator.d.ts +7 -0
  124. package/dist/src/ui/sheet.d.ts +7 -0
  125. package/dist/src/ui/sidebar.d.ts +14 -9
  126. package/dist/src/ui/skeleton.d.ts +7 -0
  127. package/dist/src/ui/slider.d.ts +7 -0
  128. package/dist/src/ui/spinner.d.ts +7 -0
  129. package/dist/src/ui/switch.d.ts +7 -0
  130. package/dist/src/ui/table.d.ts +15 -8
  131. package/dist/src/ui/tabs.d.ts +7 -0
  132. package/dist/src/ui/textarea.d.ts +7 -0
  133. package/dist/src/ui/toggle-group.d.ts +8 -3
  134. package/dist/src/ui/toggle.d.ts +7 -0
  135. package/dist/src/ui/tooltip.d.ts +7 -0
  136. package/metadata/ObjectGrid.component.yml +72 -0
  137. package/package.json +23 -11
  138. package/postcss.config.js +9 -1
  139. package/shadcn-components.json +310 -0
  140. package/src/__tests__/README.md +124 -0
  141. package/src/__tests__/basic-renderers.test.tsx +255 -0
  142. package/src/__tests__/complex-disclosure-renderers.test.tsx +301 -0
  143. package/src/__tests__/feedback-overlay-renderers.test.tsx +349 -0
  144. package/src/__tests__/form-renderers.test.tsx +364 -0
  145. package/src/__tests__/layout-data-renderers.test.tsx +340 -0
  146. package/src/__tests__/test-utils.tsx +190 -0
  147. package/src/hooks/use-mobile.tsx +8 -0
  148. package/src/index.css +86 -54
  149. package/src/index.test.ts +8 -0
  150. package/src/index.ts +21 -1
  151. package/src/lib/utils.tsx +8 -0
  152. package/src/new-components.test.ts +8 -9
  153. package/src/renderers/basic/button-group.tsx +78 -0
  154. package/src/renderers/basic/div.tsx +9 -1
  155. package/src/renderers/basic/html.tsx +8 -0
  156. package/src/renderers/basic/icon.tsx +66 -3
  157. package/src/renderers/basic/image.tsx +12 -1
  158. package/src/renderers/basic/index.ts +11 -0
  159. package/src/renderers/basic/navigation-menu.tsx +80 -0
  160. package/src/renderers/basic/pagination.tsx +82 -0
  161. package/src/renderers/basic/separator.tsx +9 -1
  162. package/src/renderers/basic/span.tsx +9 -1
  163. package/src/renderers/basic/text.tsx +8 -0
  164. package/src/renderers/complex/__tests__/data-table.test.ts +8 -0
  165. package/src/renderers/complex/carousel.tsx +11 -3
  166. package/src/renderers/complex/data-table.tsx +19 -4
  167. package/src/renderers/complex/filter-builder.tsx +8 -0
  168. package/src/renderers/complex/index.ts +9 -3
  169. package/src/renderers/complex/resizable.tsx +8 -0
  170. package/src/renderers/complex/scroll-area.tsx +8 -0
  171. package/src/renderers/complex/table.tsx +10 -2
  172. package/src/renderers/data-display/alert.tsx +8 -0
  173. package/src/renderers/data-display/avatar.tsx +8 -0
  174. package/src/renderers/data-display/badge.tsx +8 -0
  175. package/src/renderers/data-display/breadcrumb.tsx +59 -0
  176. package/src/renderers/data-display/index.ts +12 -0
  177. package/src/renderers/data-display/kbd.tsx +49 -0
  178. package/src/renderers/data-display/list.tsx +8 -0
  179. package/src/renderers/data-display/statistic.tsx +24 -43
  180. package/src/renderers/data-display/table.tsx +68 -0
  181. package/src/renderers/data-display/tree-view.tsx +26 -37
  182. package/src/renderers/disclosure/accordion.tsx +8 -0
  183. package/src/renderers/disclosure/collapsible.tsx +8 -0
  184. package/src/renderers/disclosure/index.ts +9 -0
  185. package/src/renderers/disclosure/toggle-group.tsx +77 -0
  186. package/src/renderers/feedback/empty.tsx +48 -0
  187. package/src/renderers/feedback/index.ts +12 -0
  188. package/src/renderers/feedback/loading.tsx +8 -0
  189. package/src/renderers/feedback/progress.tsx +8 -0
  190. package/src/renderers/feedback/skeleton.tsx +8 -0
  191. package/src/renderers/feedback/sonner.tsx +55 -0
  192. package/src/renderers/feedback/spinner.tsx +54 -0
  193. package/src/renderers/feedback/toast.tsx +58 -0
  194. package/src/renderers/feedback/toaster.tsx +13 -17
  195. package/src/renderers/form/button.tsx +8 -0
  196. package/src/renderers/form/calendar.tsx +8 -0
  197. package/src/renderers/form/checkbox.tsx +8 -0
  198. package/src/renderers/form/combobox.tsx +47 -0
  199. package/src/renderers/form/command.tsx +57 -0
  200. package/src/renderers/form/date-picker.tsx +10 -2
  201. package/src/renderers/form/file-upload.tsx +10 -2
  202. package/src/renderers/form/form.tsx +12 -3
  203. package/src/renderers/form/index.ts +10 -0
  204. package/src/renderers/form/input-otp.tsx +34 -15
  205. package/src/renderers/form/input.tsx +89 -50
  206. package/src/renderers/form/label.tsx +8 -0
  207. package/src/renderers/form/radio-group.tsx +8 -0
  208. package/src/renderers/form/select.tsx +8 -0
  209. package/src/renderers/form/slider.tsx +16 -1
  210. package/src/renderers/form/switch.tsx +8 -0
  211. package/src/renderers/form/textarea.tsx +8 -0
  212. package/src/renderers/form/toggle.tsx +8 -0
  213. package/src/renderers/index.ts +8 -0
  214. package/src/renderers/layout/aspect-ratio.tsx +50 -0
  215. package/src/renderers/layout/card.tsx +8 -0
  216. package/src/renderers/layout/container.tsx +20 -12
  217. package/src/renderers/layout/flex.tsx +16 -8
  218. package/src/renderers/layout/grid.tsx +8 -0
  219. package/src/renderers/layout/index.ts +9 -0
  220. package/src/renderers/layout/page.tsx +9 -1
  221. package/src/renderers/layout/semantic.tsx +8 -0
  222. package/src/renderers/layout/stack.tsx +16 -8
  223. package/src/renderers/layout/tabs.tsx +8 -0
  224. package/src/renderers/navigation/header-bar.tsx +9 -1
  225. package/src/renderers/navigation/index.ts +8 -0
  226. package/src/renderers/navigation/sidebar.tsx +8 -0
  227. package/src/renderers/overlay/alert-dialog.tsx +8 -0
  228. package/src/renderers/overlay/context-menu.tsx +9 -1
  229. package/src/renderers/overlay/dialog.tsx +8 -0
  230. package/src/renderers/overlay/drawer.tsx +8 -0
  231. package/src/renderers/overlay/dropdown-menu.tsx +8 -0
  232. package/src/renderers/overlay/hover-card.tsx +8 -0
  233. package/src/renderers/overlay/index.ts +9 -0
  234. package/src/renderers/overlay/menubar.tsx +75 -0
  235. package/src/renderers/overlay/popover.tsx +8 -0
  236. package/src/renderers/overlay/sheet.tsx +8 -0
  237. package/src/renderers/overlay/tooltip.tsx +8 -0
  238. package/src/renderers/placeholders.tsx +107 -0
  239. package/src/ui/accordion.tsx +8 -0
  240. package/src/ui/alert-dialog.tsx +8 -0
  241. package/src/ui/alert.tsx +14 -24
  242. package/src/ui/aspect-ratio.tsx +8 -0
  243. package/src/ui/avatar.tsx +8 -0
  244. package/src/ui/badge.tsx +13 -6
  245. package/src/ui/breadcrumb.tsx +8 -0
  246. package/src/ui/button-group.tsx +8 -0
  247. package/src/ui/button.tsx +38 -36
  248. package/src/ui/calendar.tsx +57 -200
  249. package/src/ui/card.tsx +8 -0
  250. package/src/ui/carousel.tsx +8 -0
  251. package/src/ui/checkbox.tsx +8 -0
  252. package/src/ui/collapsible.tsx +8 -0
  253. package/src/ui/combobox.tsx +104 -0
  254. package/src/ui/command.tsx +8 -0
  255. package/src/ui/context-menu.tsx +8 -0
  256. package/src/ui/date-picker.tsx +61 -0
  257. package/src/ui/dialog.tsx +8 -0
  258. package/src/ui/drawer.tsx +8 -0
  259. package/src/ui/dropdown-menu.tsx +8 -0
  260. package/src/ui/empty.tsx +8 -0
  261. package/src/ui/filter-builder.tsx +8 -0
  262. package/src/ui/form.tsx +8 -0
  263. package/src/ui/hover-card.tsx +8 -0
  264. package/src/ui/index.ts +11 -5
  265. package/src/ui/input-otp.tsx +20 -12
  266. package/src/ui/input.tsx +8 -0
  267. package/src/ui/item.tsx +8 -0
  268. package/src/ui/kbd.tsx +8 -0
  269. package/src/ui/label.tsx +8 -0
  270. package/src/ui/menubar.tsx +8 -0
  271. package/src/ui/navigation-menu.tsx +8 -0
  272. package/src/ui/pagination.tsx +8 -0
  273. package/src/ui/popover.tsx +9 -1
  274. package/src/ui/progress.tsx +11 -15
  275. package/src/ui/radio-group.tsx +8 -0
  276. package/src/ui/resizable.tsx +8 -0
  277. package/src/ui/scroll-area.tsx +9 -1
  278. package/src/ui/select.tsx +17 -9
  279. package/src/ui/separator.tsx +8 -0
  280. package/src/ui/sheet.tsx +8 -0
  281. package/src/ui/sidebar.tsx +34 -15
  282. package/src/ui/skeleton.tsx +8 -0
  283. package/src/ui/slider.tsx +8 -0
  284. package/src/ui/sonner.tsx +12 -20
  285. package/src/ui/spinner.tsx +11 -23
  286. package/src/ui/switch.tsx +8 -0
  287. package/src/ui/table.tsx +102 -97
  288. package/src/ui/tabs.tsx +8 -0
  289. package/src/ui/textarea.tsx +8 -0
  290. package/src/ui/toggle-group.tsx +12 -21
  291. package/src/ui/toggle.tsx +15 -12
  292. package/src/ui/tooltip.tsx +8 -0
  293. package/tsconfig.json +2 -1
  294. package/vite.config.ts +11 -1
  295. package/dist/src/index.test.d.ts +0 -1
  296. package/dist/src/new-components.test.d.ts +0 -1
  297. package/dist/src/renderers/complex/__tests__/data-table.test.d.ts +0 -0
  298. package/dist/src/renderers/complex/calendar-view.d.ts +0 -1
  299. package/dist/src/renderers/complex/chatbot.d.ts +0 -1
  300. package/dist/src/renderers/complex/chatbot.test.d.ts +0 -1
  301. package/dist/src/renderers/complex/timeline.d.ts +0 -1
  302. package/dist/src/ui/calendar-view.d.ts +0 -21
  303. package/dist/src/ui/chatbot.d.ts +0 -36
  304. package/dist/src/ui/field.d.ts +0 -24
  305. package/dist/src/ui/input-group.d.ts +0 -16
  306. package/dist/src/ui/timeline.d.ts +0 -25
  307. package/metadata/ObjectTable.component.yml +0 -41
  308. package/src/renderers/complex/calendar-view.tsx +0 -219
  309. package/src/renderers/complex/chatbot.test.ts +0 -44
  310. package/src/renderers/complex/chatbot.tsx +0 -185
  311. package/src/renderers/complex/timeline.tsx +0 -466
  312. package/src/ui/calendar-view.tsx +0 -503
  313. package/src/ui/chatbot.tsx +0 -240
  314. package/src/ui/field.tsx +0 -246
  315. package/src/ui/input-group.tsx +0 -170
  316. package/src/ui/timeline.tsx +0 -266
  317. package/tailwind.config.js +0 -75
@@ -1,240 +0,0 @@
1
- import * as React from "react"
2
- import { cn } from "../lib/utils"
3
- import { Button } from "./button"
4
- import { Input } from "./input"
5
- import { ScrollArea } from "./scroll-area"
6
- import { Avatar, AvatarFallback, AvatarImage } from "./avatar"
7
- import { Send } from "lucide-react"
8
-
9
- // Message type definition
10
- export interface ChatMessage {
11
- id: string
12
- role: "user" | "assistant" | "system"
13
- content: string
14
- timestamp?: string
15
- avatar?: string
16
- avatarFallback?: string
17
- }
18
-
19
- // Chatbot container props
20
- export interface ChatbotProps extends React.HTMLAttributes<HTMLDivElement> {
21
- messages?: ChatMessage[]
22
- placeholder?: string
23
- onSendMessage?: (message: string) => void
24
- disabled?: boolean
25
- showTimestamp?: boolean
26
- userAvatarUrl?: string
27
- userAvatarFallback?: string
28
- assistantAvatarUrl?: string
29
- assistantAvatarFallback?: string
30
- maxHeight?: string
31
- }
32
-
33
- // Chatbot container component
34
- const Chatbot = React.forwardRef<HTMLDivElement, ChatbotProps>(
35
- (
36
- {
37
- className,
38
- messages = [],
39
- placeholder = "Type your message...",
40
- onSendMessage,
41
- disabled = false,
42
- showTimestamp = false,
43
- userAvatarUrl,
44
- userAvatarFallback = "You",
45
- assistantAvatarUrl,
46
- assistantAvatarFallback = "AI",
47
- maxHeight = "500px",
48
- ...props
49
- },
50
- ref
51
- ) => {
52
- const [inputValue, setInputValue] = React.useState("")
53
- const scrollRef = React.useRef<HTMLDivElement>(null)
54
- const inputRef = React.useRef<HTMLInputElement>(null)
55
-
56
- // Auto-scroll to bottom when new messages arrive
57
- React.useEffect(() => {
58
- if (scrollRef.current) {
59
- const scrollElement = scrollRef.current.querySelector('[data-radix-scroll-area-viewport]')
60
- if (scrollElement) {
61
- scrollElement.scrollTop = scrollElement.scrollHeight
62
- }
63
- }
64
- }, [messages])
65
-
66
- const handleSend = () => {
67
- if (inputValue.trim() && onSendMessage) {
68
- onSendMessage(inputValue.trim())
69
- setInputValue("")
70
- inputRef.current?.focus()
71
- }
72
- }
73
-
74
- const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
75
- if (e.key === "Enter" && !e.shiftKey) {
76
- e.preventDefault()
77
- handleSend()
78
- }
79
- }
80
-
81
- return (
82
- <div
83
- ref={ref}
84
- className={cn(
85
- "flex flex-col border rounded-lg bg-background overflow-hidden",
86
- className
87
- )}
88
- style={{ maxHeight }}
89
- {...props}
90
- >
91
- {/* Messages area */}
92
- <ScrollArea ref={scrollRef} className="flex-1 p-4">
93
- <div className="space-y-4">
94
- {messages.length === 0 ? (
95
- <div className="flex items-center justify-center h-32 text-muted-foreground text-sm">
96
- No messages yet. Start a conversation!
97
- </div>
98
- ) : (
99
- messages.map((message) => (
100
- <ChatMessageItem
101
- key={message.id}
102
- message={message}
103
- showTimestamp={showTimestamp}
104
- userAvatarUrl={userAvatarUrl}
105
- userAvatarFallback={userAvatarFallback}
106
- assistantAvatarUrl={assistantAvatarUrl}
107
- assistantAvatarFallback={assistantAvatarFallback}
108
- />
109
- ))
110
- )}
111
- </div>
112
- </ScrollArea>
113
-
114
- {/* Input area */}
115
- <div className="border-t p-4">
116
- <div className="flex gap-2">
117
- <Input
118
- ref={inputRef}
119
- value={inputValue}
120
- onChange={(e) => setInputValue(e.target.value)}
121
- onKeyDown={handleKeyDown}
122
- placeholder={placeholder}
123
- disabled={disabled}
124
- className="flex-1"
125
- />
126
- <Button
127
- onClick={handleSend}
128
- disabled={disabled || !inputValue.trim()}
129
- size="icon"
130
- >
131
- <Send className="h-4 w-4" />
132
- </Button>
133
- </div>
134
- </div>
135
- </div>
136
- )
137
- }
138
- )
139
- Chatbot.displayName = "Chatbot"
140
-
141
- // Individual message component
142
- export interface ChatMessageProps {
143
- message: ChatMessage
144
- showTimestamp?: boolean
145
- userAvatarUrl?: string
146
- userAvatarFallback?: string
147
- assistantAvatarUrl?: string
148
- assistantAvatarFallback?: string
149
- }
150
-
151
- const ChatMessageItem: React.FC<ChatMessageProps> = ({
152
- message,
153
- showTimestamp,
154
- userAvatarUrl,
155
- userAvatarFallback,
156
- assistantAvatarUrl,
157
- assistantAvatarFallback,
158
- }) => {
159
- const isUser = message.role === "user"
160
- const isSystem = message.role === "system"
161
-
162
- if (isSystem) {
163
- return (
164
- <div className="flex justify-center">
165
- <div className="text-xs text-muted-foreground bg-muted px-3 py-1 rounded-full">
166
- {message.content}
167
- </div>
168
- </div>
169
- )
170
- }
171
-
172
- const avatar = isUser
173
- ? (message.avatar || userAvatarUrl)
174
- : (message.avatar || assistantAvatarUrl)
175
-
176
- const avatarFallback = isUser
177
- ? (message.avatarFallback || userAvatarFallback)
178
- : (message.avatarFallback || assistantAvatarFallback)
179
-
180
- return (
181
- <div
182
- className={cn(
183
- "flex gap-3",
184
- isUser ? "flex-row-reverse" : "flex-row"
185
- )}
186
- >
187
- <Avatar className="h-8 w-8">
188
- <AvatarImage src={avatar} />
189
- <AvatarFallback className="text-xs">{avatarFallback}</AvatarFallback>
190
- </Avatar>
191
-
192
- <div className={cn("flex flex-col gap-1", isUser ? "items-end" : "items-start")}>
193
- <div
194
- className={cn(
195
- "rounded-lg px-4 py-2 max-w-[70%] break-words",
196
- isUser
197
- ? "bg-primary text-primary-foreground"
198
- : "bg-muted"
199
- )}
200
- >
201
- <p className="text-sm whitespace-pre-wrap">{message.content}</p>
202
- </div>
203
- {showTimestamp && message.timestamp && (
204
- <span className="text-xs text-muted-foreground">
205
- {message.timestamp}
206
- </span>
207
- )}
208
- </div>
209
- </div>
210
- )
211
- }
212
-
213
- // Typing indicator component
214
- export interface TypingIndicatorProps extends React.HTMLAttributes<HTMLDivElement> {
215
- avatarSrc?: string
216
- avatarFallback?: string
217
- }
218
-
219
- const TypingIndicator = React.forwardRef<HTMLDivElement, TypingIndicatorProps>(
220
- ({ className, avatarSrc, avatarFallback = "AI", ...props }, ref) => {
221
- return (
222
- <div ref={ref} className={cn("flex gap-3", className)} {...props}>
223
- <Avatar className="h-8 w-8">
224
- <AvatarImage src={avatarSrc} />
225
- <AvatarFallback className="text-xs">{avatarFallback}</AvatarFallback>
226
- </Avatar>
227
- <div className="flex items-center bg-muted rounded-lg px-4 py-2">
228
- <div className="flex gap-1">
229
- <span className="w-2 h-2 bg-muted-foreground rounded-full animate-bounce [animation-delay:-0.3s]"></span>
230
- <span className="w-2 h-2 bg-muted-foreground rounded-full animate-bounce [animation-delay:-0.15s]"></span>
231
- <span className="w-2 h-2 bg-muted-foreground rounded-full animate-bounce"></span>
232
- </div>
233
- </div>
234
- </div>
235
- )
236
- }
237
- )
238
- TypingIndicator.displayName = "TypingIndicator"
239
-
240
- export { Chatbot, TypingIndicator }
package/src/ui/field.tsx DELETED
@@ -1,246 +0,0 @@
1
- import { useMemo } 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.ComponentProps<"fieldset">) {
9
- return (
10
- <fieldset
11
- data-slot="field-set"
12
- className={cn(
13
- "flex flex-col gap-6",
14
- "has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
15
- className
16
- )}
17
- {...props}
18
- />
19
- )
20
- }
21
-
22
- function FieldLegend({
23
- className,
24
- variant = "legend",
25
- ...props
26
- }: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
27
- return (
28
- <legend
29
- data-slot="field-legend"
30
- data-variant={variant}
31
- className={cn(
32
- "mb-3 font-medium",
33
- "data-[variant=legend]:text-base",
34
- "data-[variant=label]:text-sm",
35
- className
36
- )}
37
- {...props}
38
- />
39
- )
40
- }
41
-
42
- function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
43
- return (
44
- <div
45
- data-slot="field-group"
46
- className={cn(
47
- "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
48
- className
49
- )}
50
- {...props}
51
- />
52
- )
53
- }
54
-
55
- const fieldVariants = cva(
56
- "group/field flex w-full gap-3 data-[invalid=true]:text-destructive",
57
- {
58
- variants: {
59
- orientation: {
60
- vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
61
- horizontal: [
62
- "flex-row items-center",
63
- "[&>[data-slot=field-label]]:flex-auto",
64
- "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
65
- ],
66
- responsive: [
67
- "flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto",
68
- "@md/field-group:[&>[data-slot=field-label]]:flex-auto",
69
- "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
70
- ],
71
- },
72
- },
73
- defaultVariants: {
74
- orientation: "vertical",
75
- },
76
- }
77
- )
78
-
79
- function Field({
80
- className,
81
- orientation = "vertical",
82
- ...props
83
- }: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
84
- return (
85
- <div
86
- role="group"
87
- data-slot="field"
88
- data-orientation={orientation}
89
- className={cn(fieldVariants({ orientation }), className)}
90
- {...props}
91
- />
92
- )
93
- }
94
-
95
- function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
96
- return (
97
- <div
98
- data-slot="field-content"
99
- className={cn(
100
- "group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
101
- className
102
- )}
103
- {...props}
104
- />
105
- )
106
- }
107
-
108
- function FieldLabel({
109
- className,
110
- ...props
111
- }: React.ComponentProps<typeof Label>) {
112
- return (
113
- <Label
114
- data-slot="field-label"
115
- className={cn(
116
- "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
117
- "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
118
- "has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
119
- className
120
- )}
121
- {...props}
122
- />
123
- )
124
- }
125
-
126
- function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
127
- return (
128
- <div
129
- data-slot="field-label"
130
- className={cn(
131
- "flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50",
132
- className
133
- )}
134
- {...props}
135
- />
136
- )
137
- }
138
-
139
- function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
140
- return (
141
- <p
142
- data-slot="field-description"
143
- className={cn(
144
- "text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
145
- "last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5",
146
- "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
147
- className
148
- )}
149
- {...props}
150
- />
151
- )
152
- }
153
-
154
- function FieldSeparator({
155
- children,
156
- className,
157
- ...props
158
- }: React.ComponentProps<"div"> & {
159
- children?: React.ReactNode
160
- }) {
161
- return (
162
- <div
163
- data-slot="field-separator"
164
- data-content={!!children}
165
- className={cn(
166
- "relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
167
- className
168
- )}
169
- {...props}
170
- >
171
- <Separator className="absolute inset-0 top-1/2" />
172
- {children && (
173
- <span
174
- className="bg-background text-muted-foreground relative mx-auto block w-fit px-2"
175
- data-slot="field-separator-content"
176
- >
177
- {children}
178
- </span>
179
- )}
180
- </div>
181
- )
182
- }
183
-
184
- function FieldError({
185
- className,
186
- children,
187
- errors,
188
- ...props
189
- }: React.ComponentProps<"div"> & {
190
- errors?: Array<{ message?: string } | undefined>
191
- }) {
192
- const content = useMemo(() => {
193
- if (children) {
194
- return children
195
- }
196
-
197
- if (!errors?.length) {
198
- return null
199
- }
200
-
201
- const uniqueErrors = [
202
- ...new Map(errors.map((error) => [error?.message, error])).values(),
203
- ]
204
-
205
- if (uniqueErrors?.length == 1) {
206
- return uniqueErrors[0]?.message
207
- }
208
-
209
- return (
210
- <ul className="ml-4 flex list-disc flex-col gap-1">
211
- {uniqueErrors.map(
212
- (error, index) =>
213
- error?.message && <li key={index}>{error.message}</li>
214
- )}
215
- </ul>
216
- )
217
- }, [children, errors])
218
-
219
- if (!content) {
220
- return null
221
- }
222
-
223
- return (
224
- <div
225
- role="alert"
226
- data-slot="field-error"
227
- className={cn("text-destructive text-sm font-normal", className)}
228
- {...props}
229
- >
230
- {content}
231
- </div>
232
- )
233
- }
234
-
235
- export {
236
- Field,
237
- FieldLabel,
238
- FieldDescription,
239
- FieldError,
240
- FieldGroup,
241
- FieldLegend,
242
- FieldSeparator,
243
- FieldSet,
244
- FieldContent,
245
- FieldTitle,
246
- }
@@ -1,170 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { cva, type VariantProps } from "class-variance-authority"
5
-
6
- import { cn } from "../lib/utils"
7
- import { Button } from "./button"
8
- import { Input } from "./input"
9
- import { Textarea } from "./textarea"
10
-
11
- function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
12
- return (
13
- <div
14
- data-slot="input-group"
15
- role="group"
16
- className={cn(
17
- "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",
18
- "h-9 min-w-0 has-[>textarea]:h-auto",
19
-
20
- // Variants based on alignment.
21
- "has-[>[data-align=inline-start]]:[&>input]:pl-2",
22
- "has-[>[data-align=inline-end]]:[&>input]:pr-2",
23
- "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3",
24
- "has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3",
25
-
26
- // Focus state.
27
- "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]",
28
-
29
- // Error state.
30
- "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",
31
-
32
- className
33
- )}
34
- {...props}
35
- />
36
- )
37
- }
38
-
39
- const inputGroupAddonVariants = cva(
40
- "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",
41
- {
42
- variants: {
43
- align: {
44
- "inline-start":
45
- "order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
46
- "inline-end":
47
- "order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
48
- "block-start":
49
- "order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5",
50
- "block-end":
51
- "order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5",
52
- },
53
- },
54
- defaultVariants: {
55
- align: "inline-start",
56
- },
57
- }
58
- )
59
-
60
- function InputGroupAddon({
61
- className,
62
- align = "inline-start",
63
- ...props
64
- }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
65
- return (
66
- <div
67
- role="group"
68
- data-slot="input-group-addon"
69
- data-align={align}
70
- className={cn(inputGroupAddonVariants({ align }), className)}
71
- onClick={(e) => {
72
- if ((e.target as HTMLElement).closest("button")) {
73
- return
74
- }
75
- e.currentTarget.parentElement?.querySelector("input")?.focus()
76
- }}
77
- {...props}
78
- />
79
- )
80
- }
81
-
82
- const inputGroupButtonVariants = cva(
83
- "text-sm shadow-none flex gap-2 items-center",
84
- {
85
- variants: {
86
- size: {
87
- xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2",
88
- sm: "h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5",
89
- "icon-xs":
90
- "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
91
- "icon-sm": "size-8 p-0 has-[>svg]:p-0",
92
- },
93
- },
94
- defaultVariants: {
95
- size: "xs",
96
- },
97
- }
98
- )
99
-
100
- function InputGroupButton({
101
- className,
102
- type = "button",
103
- variant = "ghost",
104
- size = "xs",
105
- ...props
106
- }: Omit<React.ComponentProps<typeof Button>, "size"> &
107
- VariantProps<typeof inputGroupButtonVariants>) {
108
- return (
109
- <Button
110
- type={type}
111
- data-size={size}
112
- variant={variant}
113
- className={cn(inputGroupButtonVariants({ size }), className)}
114
- {...props}
115
- />
116
- )
117
- }
118
-
119
- function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
120
- return (
121
- <span
122
- className={cn(
123
- "text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
124
- className
125
- )}
126
- {...props}
127
- />
128
- )
129
- }
130
-
131
- function InputGroupInput({
132
- className,
133
- ...props
134
- }: React.ComponentProps<"input">) {
135
- return (
136
- <Input
137
- data-slot="input-group-control"
138
- className={cn(
139
- "flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent",
140
- className
141
- )}
142
- {...props}
143
- />
144
- )
145
- }
146
-
147
- function InputGroupTextarea({
148
- className,
149
- ...props
150
- }: React.ComponentProps<"textarea">) {
151
- return (
152
- <Textarea
153
- data-slot="input-group-control"
154
- className={cn(
155
- "flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent",
156
- className
157
- )}
158
- {...props}
159
- />
160
- )
161
- }
162
-
163
- export {
164
- InputGroup,
165
- InputGroupAddon,
166
- InputGroupButton,
167
- InputGroupText,
168
- InputGroupInput,
169
- InputGroupTextarea,
170
- }