@tulipfarm/sprout 0.3.1 → 0.5.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 (355) hide show
  1. package/README.md +75 -68
  2. package/dist/components/accordion.d.ts +2 -2
  3. package/dist/components/accordion.js +9 -9
  4. package/dist/components/agent-avatar.d.ts +27 -0
  5. package/dist/components/agent-avatar.js +67 -0
  6. package/dist/components/agent-fanout.d.ts +2 -2
  7. package/dist/components/agent-fanout.js +65 -87
  8. package/dist/components/alert-dialog.d.ts +8 -8
  9. package/dist/components/alert-dialog.js +21 -21
  10. package/dist/components/alert.d.ts +6 -6
  11. package/dist/components/alert.js +13 -13
  12. package/dist/components/aspect-ratio.d.ts +2 -2
  13. package/dist/components/aspect-ratio.js +2 -2
  14. package/dist/components/attachment.d.ts +18 -18
  15. package/dist/components/attachment.js +82 -115
  16. package/dist/components/avatar.d.ts +9 -17
  17. package/dist/components/avatar.js +14 -51
  18. package/dist/components/badge.d.ts +4 -4
  19. package/dist/components/badge.js +18 -18
  20. package/dist/components/board.d.ts +107 -0
  21. package/dist/components/board.js +640 -0
  22. package/dist/components/brand-icon.d.ts +6 -6
  23. package/dist/components/brand-icon.js +55 -63
  24. package/dist/components/breadcrumb.d.ts +11 -11
  25. package/dist/components/breadcrumb.js +16 -18
  26. package/dist/components/button-group.d.ts +6 -6
  27. package/dist/components/button-group.js +14 -14
  28. package/dist/components/button.d.ts +13 -13
  29. package/dist/components/button.js +31 -57
  30. package/dist/components/calendar.d.ts +5 -5
  31. package/dist/components/calendar.js +44 -53
  32. package/dist/components/canvas.d.ts +4 -4
  33. package/dist/components/canvas.js +39 -46
  34. package/dist/components/card.d.ts +7 -7
  35. package/dist/components/card.js +17 -17
  36. package/dist/components/carousel.d.ts +7 -7
  37. package/dist/components/carousel.js +57 -75
  38. package/dist/components/chart.d.ts +5 -112
  39. package/dist/components/chart.js +5 -172
  40. package/dist/components/chat-confirmation.d.ts +10 -10
  41. package/dist/components/chat-confirmation.js +32 -38
  42. package/dist/components/chat-input.d.ts +4 -4
  43. package/dist/components/chat-input.js +74 -81
  44. package/dist/components/chat-plan.d.ts +2 -2
  45. package/dist/components/chat-plan.js +15 -20
  46. package/dist/components/chat-sources.d.ts +8 -8
  47. package/dist/components/chat-sources.js +18 -27
  48. package/dist/components/checkbox.d.ts +1 -1
  49. package/dist/components/checkbox.js +9 -9
  50. package/dist/components/choice-list.d.ts +2 -2
  51. package/dist/components/choice-list.js +16 -18
  52. package/dist/components/code-block.d.ts +5 -5
  53. package/dist/components/code-block.js +26 -26
  54. package/dist/components/collapsible.d.ts +1 -1
  55. package/dist/components/collapsible.js +7 -11
  56. package/dist/components/combobox.d.ts +12 -6
  57. package/dist/components/combobox.js +27 -26
  58. package/dist/components/command.d.ts +13 -13
  59. package/dist/components/command.js +61 -73
  60. package/dist/components/context-menu.d.ts +5 -5
  61. package/dist/components/context-menu.js +22 -22
  62. package/dist/components/dialog.d.ts +6 -6
  63. package/dist/components/dialog.js +23 -28
  64. package/dist/components/direction.d.ts +1 -1
  65. package/dist/components/direction.js +1 -1
  66. package/dist/components/dropdown-menu.d.ts +5 -5
  67. package/dist/components/dropdown-menu.js +20 -20
  68. package/dist/components/field.d.ts +11 -11
  69. package/dist/components/field.js +41 -61
  70. package/dist/components/file-explorer.d.ts +2 -2
  71. package/dist/components/file-explorer.js +89 -105
  72. package/dist/components/file-viewer.d.ts +10 -10
  73. package/dist/components/file-viewer.js +112 -140
  74. package/dist/components/form.d.ts +7 -7
  75. package/dist/components/form.js +24 -28
  76. package/dist/components/glass-banner.d.ts +3 -3
  77. package/dist/components/glass-banner.js +21 -24
  78. package/dist/components/gradient-banner.d.ts +7 -7
  79. package/dist/components/gradient-banner.js +13 -22
  80. package/dist/components/hover-card.d.ts +4 -4
  81. package/dist/components/hover-card.js +6 -6
  82. package/dist/components/input-group.d.ts +18 -18
  83. package/dist/components/input-group.js +25 -39
  84. package/dist/components/input-otp.d.ts +14 -10
  85. package/dist/components/input-otp.js +15 -15
  86. package/dist/components/input.d.ts +3 -3
  87. package/dist/components/input.js +7 -7
  88. package/dist/components/kbd.d.ts +3 -3
  89. package/dist/components/kbd.js +5 -5
  90. package/dist/components/label.d.ts +2 -2
  91. package/dist/components/label.js +2 -2
  92. package/dist/components/mention-list.d.ts +3 -3
  93. package/dist/components/mention-list.js +10 -10
  94. package/dist/components/menubar.d.ts +6 -6
  95. package/dist/components/menubar.js +22 -22
  96. package/dist/components/message-actions.d.ts +2 -2
  97. package/dist/components/message-actions.js +29 -31
  98. package/dist/components/message-response.d.ts +3 -3
  99. package/dist/components/message-response.js +18 -18
  100. package/dist/components/message-scroller.d.ts +12 -12
  101. package/dist/components/message-scroller.js +44 -56
  102. package/dist/components/message.d.ts +11 -11
  103. package/dist/components/message.js +25 -25
  104. package/dist/components/navigation-menu.d.ts +2 -2
  105. package/dist/components/navigation-menu.js +15 -15
  106. package/dist/components/notice-banner.d.ts +2 -2
  107. package/dist/components/notice-banner.js +2 -2
  108. package/dist/components/page-content.d.ts +2 -2
  109. package/dist/components/page-content.js +2 -2
  110. package/dist/components/page-header.d.ts +1 -1
  111. package/dist/components/page-header.js +17 -17
  112. package/dist/components/pagination.d.ts +9 -9
  113. package/dist/components/pagination.js +17 -17
  114. package/dist/components/plan-outline.d.ts +2 -2
  115. package/dist/components/plan-outline.js +43 -60
  116. package/dist/components/popover.d.ts +6 -6
  117. package/dist/components/popover.js +15 -15
  118. package/dist/components/presence-cursor.d.ts +2 -2
  119. package/dist/components/presence-cursor.js +3 -3
  120. package/dist/components/progress.d.ts +1 -1
  121. package/dist/components/progress.js +8 -8
  122. package/dist/components/prompt-list.d.ts +3 -3
  123. package/dist/components/prompt-list.js +6 -6
  124. package/dist/components/questionnaire.d.ts +19 -19
  125. package/dist/components/questionnaire.js +183 -242
  126. package/dist/components/radio-group.d.ts +2 -2
  127. package/dist/components/radio-group.js +6 -6
  128. package/dist/components/reasoning-effort.d.ts +3 -3
  129. package/dist/components/reasoning-effort.js +9 -12
  130. package/dist/components/record-list.d.ts +66 -0
  131. package/dist/components/record-list.js +151 -0
  132. package/dist/components/resizable.d.ts +5 -5
  133. package/dist/components/resizable.js +76 -102
  134. package/dist/components/result-card.d.ts +4 -4
  135. package/dist/components/result-card.js +42 -53
  136. package/dist/components/result-notice.d.ts +18 -0
  137. package/dist/components/result-notice.js +29 -0
  138. package/dist/components/review-card.d.ts +6 -6
  139. package/dist/components/review-card.js +18 -18
  140. package/dist/components/rich-text-editor.d.ts +5 -5
  141. package/dist/components/rich-text-editor.js +56 -72
  142. package/dist/components/schema-diagram.d.ts +3 -3
  143. package/dist/components/schema-diagram.js +39 -53
  144. package/dist/components/scroll-area.d.ts +3 -3
  145. package/dist/components/scroll-area.js +10 -14
  146. package/dist/components/search-dialog.d.ts +6 -6
  147. package/dist/components/search-dialog.js +16 -16
  148. package/dist/components/search-field.d.ts +1 -1
  149. package/dist/components/search-field.js +11 -11
  150. package/dist/components/select.d.ts +5 -9
  151. package/dist/components/select.js +20 -20
  152. package/dist/components/selection-slot.d.ts +2 -2
  153. package/dist/components/selection-slot.js +6 -9
  154. package/dist/components/separator.d.ts +15 -15
  155. package/dist/components/separator.js +22 -27
  156. package/dist/components/settings-list.d.ts +3 -3
  157. package/dist/components/settings-list.js +5 -5
  158. package/dist/components/sheet.d.ts +6 -6
  159. package/dist/components/sheet.js +27 -27
  160. package/dist/components/sidebar.d.ts +22 -22
  161. package/dist/components/sidebar.js +57 -58
  162. package/dist/components/skeleton.d.ts +5 -5
  163. package/dist/components/skeleton.js +14 -21
  164. package/dist/components/slider.d.ts +2 -2
  165. package/dist/components/slider.js +6 -6
  166. package/dist/components/spinner.d.ts +7 -7
  167. package/dist/components/spinner.js +22 -26
  168. package/dist/components/sql-viewer.d.ts +14 -14
  169. package/dist/components/sql-viewer.js +99 -128
  170. package/dist/components/state-panel-samples.d.ts +2 -2
  171. package/dist/components/state-panel-samples.js +209 -245
  172. package/dist/components/state-panel.d.ts +2 -35
  173. package/dist/components/state-panel.js +2 -29
  174. package/dist/components/state-sample.d.ts +8 -8
  175. package/dist/components/state-sample.js +18 -31
  176. package/dist/components/switch.d.ts +3 -3
  177. package/dist/components/switch.js +7 -7
  178. package/dist/components/table-nuqs.d.ts +2 -2
  179. package/dist/components/table-nuqs.js +11 -12
  180. package/dist/components/table.d.ts +4 -4
  181. package/dist/components/table.js +166 -235
  182. package/dist/components/tabs.d.ts +2 -2
  183. package/dist/components/tabs.js +12 -12
  184. package/dist/components/textarea.d.ts +2 -2
  185. package/dist/components/textarea.js +6 -8
  186. package/dist/components/timeline.d.ts +3 -0
  187. package/dist/components/timeline.js +3 -0
  188. package/dist/components/toast.d.ts +2 -2
  189. package/dist/components/toast.js +19 -25
  190. package/dist/components/toggle-group.d.ts +4 -4
  191. package/dist/components/toggle-group.js +18 -20
  192. package/dist/components/toggle.d.ts +4 -4
  193. package/dist/components/toggle.js +8 -8
  194. package/dist/components/tool-activity.d.ts +1 -1
  195. package/dist/components/tool-activity.js +83 -110
  196. package/dist/components/toolbar-status.d.ts +2 -2
  197. package/dist/components/toolbar-status.js +7 -7
  198. package/dist/components/tooltip.d.ts +5 -5
  199. package/dist/components/tooltip.js +12 -11
  200. package/dist/components/typed-text.d.ts +2 -2
  201. package/dist/components/typed-text.js +10 -12
  202. package/dist/components/view-switcher.d.ts +51 -0
  203. package/dist/components/view-switcher.js +114 -0
  204. package/dist/index.d.ts +99 -93
  205. package/dist/index.js +99 -93
  206. package/dist/internal/agent-avatar-artwork.d.ts +4 -0
  207. package/dist/internal/agent-avatar-artwork.js +219 -0
  208. package/dist/internal/chart-kit.d.ts +142 -0
  209. package/dist/internal/chart-kit.js +200 -0
  210. package/dist/internal/charts/bars.d.ts +61 -0
  211. package/dist/internal/charts/bars.js +86 -0
  212. package/dist/internal/charts/lines.d.ts +67 -0
  213. package/dist/internal/charts/lines.js +70 -0
  214. package/dist/internal/charts/more.d.ts +77 -0
  215. package/dist/internal/charts/more.js +68 -0
  216. package/dist/internal/charts/parts.d.ts +54 -0
  217. package/dist/internal/charts/parts.js +82 -0
  218. package/dist/internal/charts/timeline-dates.d.ts +38 -0
  219. package/dist/internal/charts/timeline-dates.js +113 -0
  220. package/dist/internal/charts/timeline-window.d.ts +31 -0
  221. package/dist/internal/charts/timeline-window.js +26 -0
  222. package/dist/internal/charts/timeline.d.ts +72 -0
  223. package/dist/internal/charts/timeline.js +287 -0
  224. package/dist/internal/classes.d.ts +1 -1
  225. package/dist/internal/classes.js +7 -9
  226. package/dist/internal/code-tokens.d.ts +2 -2
  227. package/dist/internal/code-tokens.js +12 -12
  228. package/dist/internal/fieldset.d.ts +1 -1
  229. package/dist/internal/fieldset.js +6 -6
  230. package/dist/internal/file-kind.d.ts +1 -1
  231. package/dist/internal/file-kind.js +43 -51
  232. package/dist/internal/flow.d.ts +4 -4
  233. package/dist/internal/flow.js +20 -23
  234. package/dist/internal/hash.d.ts +1 -0
  235. package/dist/internal/hash.js +9 -0
  236. package/dist/internal/languages.js +999 -999
  237. package/dist/internal/message-scroller.d.ts +3 -3
  238. package/dist/internal/message-scroller.js +64 -112
  239. package/dist/internal/pressable.d.ts +1 -1
  240. package/dist/internal/pressable.js +7 -7
  241. package/dist/internal/state-panel.d.ts +35 -0
  242. package/dist/internal/state-panel.js +22 -0
  243. package/dist/internal/syntax.d.ts +2 -2
  244. package/dist/internal/syntax.js +36 -47
  245. package/dist/styles/accordion.css +3 -5
  246. package/dist/styles/agent-fanout.css +64 -60
  247. package/dist/styles/alert-dialog.css +12 -26
  248. package/dist/styles/alert.css +10 -15
  249. package/dist/styles/attachment.css +56 -98
  250. package/dist/styles/avatar.css +14 -33
  251. package/dist/styles/badge.css +11 -36
  252. package/dist/styles/board.css +571 -0
  253. package/dist/styles/brand-icon.css +7 -8
  254. package/dist/styles/breadcrumb.css +4 -7
  255. package/dist/styles/button-group.css +9 -15
  256. package/dist/styles/button.css +45 -175
  257. package/dist/styles/calendar.css +24 -36
  258. package/dist/styles/canvas.css +2 -3
  259. package/dist/styles/card.css +7 -23
  260. package/dist/styles/carousel.css +11 -12
  261. package/dist/styles/chart.css +215 -31
  262. package/dist/styles/chat-input.css +15 -39
  263. package/dist/styles/chat-plan.css +3 -4
  264. package/dist/styles/chat-sources.css +4 -6
  265. package/dist/styles/checkbox.css +11 -25
  266. package/dist/styles/choice-list.css +17 -31
  267. package/dist/styles/code-block.css +11 -25
  268. package/dist/styles/collapsible.css +10 -15
  269. package/dist/styles/combobox.css +24 -17
  270. package/dist/styles/command.css +8 -9
  271. package/dist/styles/context-menu.css +4 -2
  272. package/dist/styles/dialog.css +5 -16
  273. package/dist/styles/dropdown-menu.css +4 -2
  274. package/dist/styles/field.css +15 -21
  275. package/dist/styles/file-explorer.css +19 -33
  276. package/dist/styles/file-viewer.css +13 -17
  277. package/dist/styles/form.css +3 -3
  278. package/dist/styles/glass-banner.css +12 -47
  279. package/dist/styles/gradient-banner.css +16 -39
  280. package/dist/styles/hover-card.css +9 -15
  281. package/dist/styles/index.css +121 -112
  282. package/dist/styles/input-group.css +61 -69
  283. package/dist/styles/input-otp.css +18 -9
  284. package/dist/styles/input.css +19 -11
  285. package/dist/styles/kbd.css +1 -1
  286. package/dist/styles/label.css +9 -30
  287. package/dist/styles/mention-list.css +6 -8
  288. package/dist/styles/menubar.css +9 -8
  289. package/dist/styles/message-actions.css +1 -1
  290. package/dist/styles/message-response.css +3 -5
  291. package/dist/styles/message-scroller.css +14 -21
  292. package/dist/styles/message.css +23 -60
  293. package/dist/styles/navigation-menu.css +15 -30
  294. package/dist/styles/notice-banner.css +1 -2
  295. package/dist/styles/page-header.css +11 -10
  296. package/dist/styles/pagination.css +12 -6
  297. package/dist/styles/plan-outline.css +20 -37
  298. package/dist/styles/popover.css +10 -19
  299. package/dist/styles/presence-cursor.css +1 -2
  300. package/dist/styles/progress.css +2 -4
  301. package/dist/styles/prompt-list.css +6 -17
  302. package/dist/styles/questionnaire.css +16 -40
  303. package/dist/styles/radio-group.css +12 -23
  304. package/dist/styles/reasoning-effort.css +8 -15
  305. package/dist/styles/record-list.css +243 -0
  306. package/dist/styles/resizable.css +10 -11
  307. package/dist/styles/result-card.css +4 -4
  308. package/dist/styles/result-notice.css +80 -0
  309. package/dist/styles/review-card.css +2 -3
  310. package/dist/styles/rich-text-editor.css +4 -5
  311. package/dist/styles/schema-diagram.css +12 -17
  312. package/dist/styles/scroll-area.css +8 -10
  313. package/dist/styles/search-dialog.css +1 -5
  314. package/dist/styles/search-field.css +1 -2
  315. package/dist/styles/select.css +15 -19
  316. package/dist/styles/selection-slot.css +1 -2
  317. package/dist/styles/separator.css +7 -8
  318. package/dist/styles/settings-list.css +1 -2
  319. package/dist/styles/sheet.css +40 -73
  320. package/dist/styles/sidebar.css +32 -34
  321. package/dist/styles/skeleton.css +9 -11
  322. package/dist/styles/slider.css +11 -21
  323. package/dist/styles/spinner.css +2 -2
  324. package/dist/styles/sql-viewer.css +29 -29
  325. package/dist/styles/state-panel.css +8 -9
  326. package/dist/styles/state-sample.css +20 -33
  327. package/dist/styles/switch.css +11 -18
  328. package/dist/styles/table.css +62 -81
  329. package/dist/styles/tabs.css +13 -19
  330. package/dist/styles/textarea.css +3 -3
  331. package/dist/styles/themes/chatgpt.css +11 -23
  332. package/dist/styles/themes/claude.css +12 -24
  333. package/dist/styles/themes/cloudflare.css +11 -23
  334. package/dist/styles/themes/discord.css +11 -23
  335. package/dist/styles/themes/github.css +11 -23
  336. package/dist/styles/themes/grok.css +11 -23
  337. package/dist/styles/themes/linear.css +12 -25
  338. package/dist/styles/themes/neutral.css +11 -23
  339. package/dist/styles/themes/notion.css +11 -23
  340. package/dist/styles/themes/perplexity.css +11 -23
  341. package/dist/styles/themes/raycast.css +11 -23
  342. package/dist/styles/themes/spotify.css +11 -23
  343. package/dist/styles/themes/stripe.css +11 -23
  344. package/dist/styles/themes/supabase.css +11 -23
  345. package/dist/styles/themes/tulipfarm.css +9 -10
  346. package/dist/styles/themes/vercel.css +12 -25
  347. package/dist/styles/timeline.css +276 -0
  348. package/dist/styles/toast.css +13 -20
  349. package/dist/styles/toggle-group.css +23 -29
  350. package/dist/styles/toggle.css +14 -14
  351. package/dist/styles/tool-activity.css +7 -13
  352. package/dist/styles/toolbar-status.css +2 -7
  353. package/dist/styles/tooltip.css +15 -21
  354. package/dist/styles/view-switcher.css +297 -0
  355. package/package.json +25 -1
@@ -1,90 +1,65 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { Children, createContext, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, } from "react";
4
- import { mergeProps } from "@base-ui/react/merge-props";
5
- import { useRender } from "@base-ui/react/use-render";
6
- import { ChevronLeft } from "reicon-react/icons/ChevronLeft";
7
- import { ChevronRight } from "reicon-react/icons/ChevronRight";
8
- import { Image } from "reicon-react/icons/Image";
9
- import { Upload } from "reicon-react/icons/Upload";
10
- import { X } from "reicon-react/icons/X";
11
- import { cn } from "../internal/classes.js";
12
- import { defaultFileAccept, fileKind, formatFileSize, } from "../internal/file-kind.js";
13
- import { Button } from "./button.js";
14
- import { FilePreview, FileViewer, isPreviewableFile, } from "./file-viewer.js";
15
- import { HoverCard, HoverCardContent, HoverCardTrigger } from "./hover-card.js";
16
- import { Spinner } from "./spinner.js";
17
- export const attachmentStateNames = [
18
- "idle",
19
- "uploading",
20
- "processing",
21
- "error",
22
- "done",
23
- ];
24
- export const attachmentSizeNames = ["default", "sm", "xs"];
25
- export const attachmentOrientationNames = ["horizontal", "vertical"];
26
- export const attachmentMediaVariantNames = ["icon", "image"];
27
- export const attachmentGroupVariantNames = [
28
- "carousel",
29
- "grid",
30
- "inline",
31
- "list",
32
- ];
33
- export const fileAttachmentVariantNames = [
34
- "list",
35
- "grid",
36
- "inline",
37
- "chip",
38
- ];
39
- export const fileAttachmentStateNames = [
40
- "ready",
41
- "uploading",
42
- "processing",
43
- "error",
44
- ];
45
- export const fileTypeIconSizeNames = ["sm", "lg"];
3
+ import { Children, createContext, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, } from 'react';
4
+ import { mergeProps } from '@base-ui/react/merge-props';
5
+ import { useRender } from '@base-ui/react/use-render';
6
+ import { ChevronLeft } from 'reicon-react/icons/ChevronLeft';
7
+ import { ChevronRight } from 'reicon-react/icons/ChevronRight';
8
+ import { Image } from 'reicon-react/icons/Image';
9
+ import { Upload } from 'reicon-react/icons/Upload';
10
+ import { X } from 'reicon-react/icons/X';
11
+ import { cn } from '../internal/classes.js';
12
+ import { defaultFileAccept, fileKind, formatFileSize } from '../internal/file-kind.js';
13
+ import { Button } from './button.js';
14
+ import { FilePreview, FileViewer, isPreviewableFile } from './file-viewer.js';
15
+ import { HoverCard, HoverCardContent, HoverCardTrigger } from './hover-card.js';
16
+ import { Spinner } from './spinner.js';
17
+ export const attachmentStateNames = ['idle', 'uploading', 'processing', 'error', 'done'];
18
+ export const attachmentSizeNames = ['lg', 'md', 'sm'];
19
+ export const attachmentOrientationNames = ['horizontal', 'vertical'];
20
+ export const attachmentMediaVariantNames = ['icon', 'image'];
21
+ export const attachmentGroupVariantNames = ['carousel', 'grid', 'inline', 'list'];
22
+ export const fileAttachmentVariantNames = ['list', 'grid', 'inline', 'chip'];
23
+ export const fileAttachmentStateNames = ['ready', 'uploading', 'processing', 'error'];
24
+ export const fileTypeIconSizeNames = ['sm', 'lg'];
46
25
  /** A file card built from media, content, and actions. */
47
- export function Attachment({ className, state = "done", size = "default", orientation = "horizontal", ...props }) {
48
- return (_jsx("div", { "data-slot": "attachment", "data-state": state, "data-size": size, "data-orientation": orientation, className: cn("sprout-attachment", `sprout-attachment-size-${size}`, `sprout-attachment-${orientation}`, className), ...props }));
26
+ export function Attachment({ className, state = 'done', size = 'lg', orientation = 'horizontal', ...props }) {
27
+ return (_jsx("div", { "data-slot": "attachment", "data-state": state, "data-size": size, "data-orientation": orientation, className: cn('sprout-attachment', `sprout-attachment-size-${size}`, `sprout-attachment-${orientation}`, className), ...props }));
49
28
  }
50
- export function AttachmentMedia({ className, variant = "icon", ...props }) {
51
- return (_jsx("div", { "data-slot": "attachment-media", "data-variant": variant, className: cn("sprout-attachment-media", className), ...props }));
29
+ export function AttachmentMedia({ className, variant = 'icon', ...props }) {
30
+ return (_jsx("div", { "data-slot": "attachment-media", "data-variant": variant, className: cn('sprout-attachment-media', className), ...props }));
52
31
  }
53
32
  export function AttachmentContent({ className, ...props }) {
54
- return (_jsx("div", { "data-slot": "attachment-content", className: cn("sprout-attachment-content", className), ...props }));
33
+ return _jsx("div", { "data-slot": "attachment-content", className: cn('sprout-attachment-content', className), ...props });
55
34
  }
56
35
  /** A single-line name. It shimmers while the attachment uploads or processes. */
57
36
  export function AttachmentTitle({ className, ...props }) {
58
- return (_jsx("span", { "data-slot": "attachment-title", className: cn("sprout-attachment-title", className), ...props }));
37
+ return _jsx("span", { "data-slot": "attachment-title", className: cn('sprout-attachment-title', className), ...props });
59
38
  }
60
39
  export function AttachmentDescription({ className, ...props }) {
61
- return (_jsx("span", { "data-slot": "attachment-description", className: cn("sprout-attachment-description", className), ...props }));
40
+ return (_jsx("span", { "data-slot": "attachment-description", className: cn('sprout-attachment-description', className), ...props }));
62
41
  }
63
42
  /** Sits above the trigger. Vertical attachments float it over the media corner. */
64
43
  export function AttachmentActions({ className, ...props }) {
65
- return (_jsx("div", { "data-slot": "attachment-actions", className: cn("sprout-attachment-actions", className), ...props }));
44
+ return _jsx("div", { "data-slot": "attachment-actions", className: cn('sprout-attachment-actions', className), ...props });
66
45
  }
67
46
  /** A ghost `icon-xs` Button. Give icon-only actions an `aria-label`. */
68
- export function AttachmentAction({ variant, size = "icon-xs", ...props }) {
69
- return (_jsx(Button, { "data-slot": "attachment-action", variant: variant ?? "ghost", size: size, ...props }));
47
+ export function AttachmentAction({ variant, size = 'icon-xs', ...props }) {
48
+ return _jsx(Button, { "data-slot": "attachment-action", variant: variant ?? 'ghost', size: size, ...props });
70
49
  }
71
50
  /** Stretches over the whole attachment so a click anywhere opens it. Name it with `aria-label`. */
72
51
  export function AttachmentTrigger({ className, render, type, ...props }) {
73
52
  return useRender({
74
- defaultTagName: "button",
53
+ defaultTagName: 'button',
75
54
  render,
76
55
  props: mergeProps({
77
- type: render ? type : (type ?? "button"),
78
- className: cn("sprout-attachment-trigger", className),
79
- }, { "data-slot": "attachment-trigger" }, props),
56
+ type: render ? type : (type ?? 'button'),
57
+ className: cn('sprout-attachment-trigger', className),
58
+ }, { 'data-slot': 'attachment-trigger' }, props),
80
59
  });
81
60
  }
82
61
  const SharedViewerContext = createContext(null);
83
- const byDocumentOrder = (a, b) => a.node &&
84
- b.node &&
85
- a.node.compareDocumentPosition(b.node) & Node.DOCUMENT_POSITION_PRECEDING
86
- ? 1
87
- : -1;
62
+ const byDocumentOrder = (a, b) => a.node && b.node && a.node.compareDocumentPosition(b.node) & Node.DOCUMENT_POSITION_PRECEDING ? 1 : -1;
88
63
  /** One FileViewer for every viewable attachment in a group, stepping through them in page order. */
89
64
  function SharedFileViewer({ children }) {
90
65
  const entries = useRef(new Map());
@@ -104,29 +79,27 @@ function SharedFileViewer({ children }) {
104
79
  }))
105
80
  .filter((item) => item.file !== null)
106
81
  .sort(byDocumentOrder);
107
- const index = ordered.findIndex((item) => item.id === id);
82
+ const index = ordered.findIndex(item => item.id === id);
108
83
  if (index < 0)
109
84
  return;
110
85
  setSet({
111
- ids: ordered.map((item) => item.id),
112
- files: ordered.map((item) => item.file),
86
+ ids: ordered.map(item => item.id),
87
+ files: ordered.map(item => item.file),
113
88
  index,
114
89
  });
115
90
  setOpen(true);
116
91
  },
117
92
  }), []);
118
- const current = set && entries.current.get(set.ids[set.index] ?? "");
119
- return (_jsxs(SharedViewerContext.Provider, { value: shared, children: [children, set && (_jsx(FileViewer, { files: set.files, index: set.index, onIndexChange: (index) => setSet({ ...set, index }), open: open, onOpenChange: setOpen, finalFocus: () => current
120
- ?.node()
121
- ?.querySelector("button.sprout-file-attachment-open") ?? true }))] }));
93
+ const current = set && entries.current.get(set.ids[set.index] ?? '');
94
+ return (_jsxs(SharedViewerContext.Provider, { value: shared, children: [children, set && (_jsx(FileViewer, { files: set.files, index: set.index, onIndexChange: index => setSet({ ...set, index }), open: open, onOpenChange: setOpen, finalFocus: () => current?.node()?.querySelector('button.sprout-file-attachment-open') ?? true }))] }));
122
95
  }
123
96
  export function AttachmentGroup(props) {
124
97
  return (_jsx(SharedFileViewer, { children: _jsx(AttachmentGroupFrame, { ...props }) }));
125
98
  }
126
- function AttachmentGroupFrame({ className, variant = "carousel", children, ...props }) {
127
- if (variant === "carousel")
99
+ function AttachmentGroupFrame({ className, variant = 'carousel', children, ...props }) {
100
+ if (variant === 'carousel')
128
101
  return (_jsx(AttachmentCarousel, { className: className, ...props, children: children }));
129
- return (_jsx("div", { "data-slot": "attachment-group", "data-variant": variant, role: props["aria-label"] || props["aria-labelledby"] ? "group" : undefined, className: cn("sprout-attachment-group", `sprout-attachment-group-${variant}`, className), ...props, children: children }));
102
+ return (_jsx("div", { "data-slot": "attachment-group", "data-variant": variant, role: props['aria-label'] || props['aria-labelledby'] ? 'group' : undefined, className: cn('sprout-attachment-group', `sprout-attachment-group-${variant}`, className), ...props, children: children }));
130
103
  }
131
104
  const typing = 'input, textarea, select, [contenteditable="true"]';
132
105
  function AttachmentCarousel({ className, children, onKeyDownCapture, ...props }) {
@@ -139,7 +112,7 @@ function AttachmentCarousel({ className, children, onKeyDownCapture, ...props })
139
112
  const max = node.scrollWidth - node.clientWidth;
140
113
  const start = node.scrollLeft > 1;
141
114
  const end = node.scrollLeft < max - 1;
142
- setEdges((current) => current.start === start && current.end === end ? current : { start, end });
115
+ setEdges(current => (current.start === start && current.end === end ? current : { start, end }));
143
116
  }, []);
144
117
  useEffect(() => {
145
118
  const node = viewport.current;
@@ -163,55 +136,49 @@ function AttachmentCarousel({ className, children, onKeyDownCapture, ...props })
163
136
  return;
164
137
  if (event.target.closest(typing))
165
138
  return;
166
- if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
139
+ if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
167
140
  event.preventDefault();
168
- scroll(event.key === "ArrowLeft" ? -1 : 1);
141
+ scroll(event.key === 'ArrowLeft' ? -1 : 1);
169
142
  }
170
143
  };
171
- return (_jsxs("div", { "data-slot": "attachment-group", "data-variant": "carousel", role: "region", "aria-roledescription": "carousel", className: cn("sprout-attachment-group", "sprout-attachment-group-carousel", className), onKeyDownCapture: handleKeyDown, ...props, children: [_jsx("div", { ref: viewport, className: "sprout-attachment-carousel-viewport", onScroll: measure, children: _jsx("div", { className: "sprout-attachment-carousel-track", children: Children.map(children, (child) => child == null || child === false ? null : (_jsx("div", { role: "group", "aria-roledescription": "slide", className: "sprout-attachment-carousel-item", children: child }))) }) }), edges.start && (_jsx("span", { className: "sprout-attachment-carousel-edge", "data-side": "start", children: _jsx(Button, { variant: "outline", size: "icon-xs", "aria-label": "Previous attachments", tabIndex: -1, className: "sprout-attachment-carousel-arrow", onClick: () => scroll(-1), children: _jsx(ChevronLeft, { "aria-hidden": "true" }) }) })), edges.end && (_jsx("span", { className: "sprout-attachment-carousel-edge", "data-side": "end", children: _jsx(Button, { variant: "outline", size: "icon-xs", "aria-label": "Next attachments", tabIndex: -1, className: "sprout-attachment-carousel-arrow", onClick: () => scroll(1), children: _jsx(ChevronRight, { "aria-hidden": "true" }) }) }))] }));
144
+ return (_jsxs("div", { "data-slot": "attachment-group", "data-variant": "carousel", role: "region", "aria-roledescription": "carousel", className: cn('sprout-attachment-group', 'sprout-attachment-group-carousel', className), onKeyDownCapture: handleKeyDown, ...props, children: [_jsx("div", { ref: viewport, className: "sprout-attachment-carousel-viewport", onScroll: measure, children: _jsx("div", { className: "sprout-attachment-carousel-track", children: Children.map(children, child => child == null || child === false ? null : (_jsx("div", { role: "group", "aria-roledescription": "slide", className: "sprout-attachment-carousel-item", children: child }))) }) }), edges.start && (_jsx("span", { className: "sprout-attachment-carousel-edge", "data-side": "start", children: _jsx(Button, { variant: "outline", size: "icon-xs", "aria-label": "Previous attachments", tabIndex: -1, className: "sprout-attachment-carousel-arrow", onClick: () => scroll(-1), children: _jsx(ChevronLeft, { "aria-hidden": "true" }) }) })), edges.end && (_jsx("span", { className: "sprout-attachment-carousel-edge", "data-side": "end", children: _jsx(Button, { variant: "outline", size: "icon-xs", "aria-label": "Next attachments", tabIndex: -1, className: "sprout-attachment-carousel-arrow", onClick: () => scroll(1), children: _jsx(ChevronRight, { "aria-hidden": "true" }) }) }))] }));
172
145
  }
173
146
  /** A paper glyph with a colored extension badge, such as PDF or XLSX. Decorative. */
174
- export function FileTypeIcon({ name, mediaType, size = "sm", className, ...props }) {
175
- const label = name.includes(".")
176
- ? (name.split(".").at(-1) ?? "").toUpperCase().slice(0, 4)
177
- : "";
147
+ export function FileTypeIcon({ name, mediaType, size = 'sm', className, ...props }) {
148
+ const label = name.includes('.') ? (name.split('.').at(-1) ?? '').toUpperCase().slice(0, 4) : '';
178
149
  const badgeWidth = label.length > 3 ? 13 : 11;
179
- return (_jsxs("svg", { viewBox: "0 0 20 24", "aria-hidden": "true", focusable: "false", "data-slot": "file-type-icon", "data-size": size, "data-kind": fileKind(name, mediaType), className: cn("sprout-file-type-icon", `sprout-file-type-icon-size-${size}`, className), ...props, children: [_jsx("path", { d: "M3.5 1.5h9l4.5 4.5v16a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5v-20a.5.5 0 0 1 .5-.5Z", className: "sprout-file-type-icon-paper", strokeLinejoin: "round" }), _jsx("path", { d: "M12.5 1.5v4a.5.5 0 0 0 .5.5h4", className: "sprout-file-type-icon-fold", strokeLinejoin: "round" }), _jsx("path", { d: "M6 15h8M6 17.5h8M6 20h5", className: "sprout-file-type-icon-lines", strokeLinecap: "round" }), label && (_jsxs(_Fragment, { children: [_jsx("rect", { x: "1", y: "6", width: badgeWidth, height: "6", rx: "1.5", className: "sprout-file-type-icon-badge" }), _jsx("text", { x: 1 + badgeWidth / 2, y: "10.4", textAnchor: "middle", fontSize: "4.2", fontWeight: "700", className: "sprout-file-type-icon-label", children: label })] }))] }));
150
+ return (_jsxs("svg", { viewBox: "0 0 20 24", "aria-hidden": "true", focusable: "false", "data-slot": "file-type-icon", "data-size": size, "data-kind": fileKind(name, mediaType), className: cn('sprout-file-type-icon', `sprout-file-type-icon-size-${size}`, className), ...props, children: [_jsx("path", { d: "M3.5 1.5h9l4.5 4.5v16a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5v-20a.5.5 0 0 1 .5-.5Z", className: "sprout-file-type-icon-paper", strokeLinejoin: "round" }), _jsx("path", { d: "M12.5 1.5v4a.5.5 0 0 0 .5.5h4", className: "sprout-file-type-icon-fold", strokeLinejoin: "round" }), _jsx("path", { d: "M6 15h8M6 17.5h8M6 20h5", className: "sprout-file-type-icon-lines", strokeLinecap: "round" }), label && (_jsxs(_Fragment, { children: [_jsx("rect", { x: "1", y: "6", width: badgeWidth, height: "6", rx: "1.5", className: "sprout-file-type-icon-badge" }), _jsx("text", { x: 1 + badgeWidth / 2, y: "10.4", textAnchor: "middle", fontSize: "4.2", fontWeight: "700", className: "sprout-file-type-icon-label", children: label })] }))] }));
180
151
  }
181
152
  function AttachmentImage({ src, name }) {
182
153
  const [failed, setFailed] = useState(false);
183
154
  return failed ? (_jsxs("span", { className: "sprout-attachment-image-failed", children: [_jsx(Image, { size: 16, "aria-hidden": "true" }), "Image unavailable"] })) : (_jsx("img", { src: src, alt: name, onError: () => setFailed(true), className: "sprout-attachment-image" }));
184
155
  }
185
156
  function viewableFile(file) {
186
- const source = file.source ??
187
- (file.url ? { kind: "remote", url: file.url } : null);
157
+ const source = file.source ?? (file.url ? { kind: 'remote', url: file.url } : null);
188
158
  return source && { name: file.name, mediaType: file.mediaType, source };
189
159
  }
190
160
  function stateLabelFor(file) {
191
- return file.state === "ready"
161
+ return file.state === 'ready'
192
162
  ? file.size
193
- : file.state === "error"
194
- ? "Upload failed"
195
- : file.state === "uploading"
196
- ? "Uploading…"
197
- : "Processing…";
163
+ : file.state === 'error'
164
+ ? 'Upload failed'
165
+ : file.state === 'uploading'
166
+ ? 'Uploading…'
167
+ : 'Processing…';
198
168
  }
199
169
  /** A ready-made file row, card, inline mention, or chip with upload states, retry, and remove. */
200
- export function FileAttachment({ file, variant = "list", onRemove, onRetry, onOpen, viewable = false, preview = false, actionLabel = "Inspect", className, }) {
170
+ export function FileAttachment({ file, variant = 'list', onRemove, onRetry, onOpen, viewable = false, preview = false, actionLabel = 'Inspect', className, }) {
201
171
  const [open, setOpen] = useState(false);
202
172
  const shared = useContext(SharedViewerContext);
203
173
  const id = useId();
204
174
  const root = useRef(null);
205
- const image = fileKind(file.name, file.mediaType) === "image";
206
- const busy = file.state === "uploading" || file.state === "processing";
175
+ const image = fileKind(file.name, file.mediaType) === 'image';
176
+ const busy = file.state === 'uploading' || file.state === 'processing';
207
177
  const stateLabel = stateLabelFor(file);
208
178
  const target = viewable || preview ? viewableFile(file) : null;
209
179
  const inViewer = !onOpen && viewable && target !== null;
210
180
  const openable = !!onOpen || inViewer;
211
- const peek = preview &&
212
- target !== null &&
213
- file.state !== "error" &&
214
- isPreviewableFile(target);
181
+ const peek = preview && target !== null && file.state !== 'error' && isPreviewableFile(target);
215
182
  const latest = useRef(target);
216
183
  latest.current = inViewer ? target : null;
217
184
  useEffect(() => shared && inViewer
@@ -223,21 +190,21 @@ export function FileAttachment({ file, variant = "list", onRemove, onRetry, onOp
223
190
  const withPreview = (trigger) => peek ? (_jsxs(HoverCard, { children: [_jsx(HoverCardTrigger, { delay: 400, closeDelay: 150, render: trigger }), _jsx(HoverCardContent, { side: "top", align: "start", className: "sprout-file-attachment-peek", children: _jsx(FilePreview, { file: target }) })] })) : (trigger);
224
191
  const openLabel = `${actionLabel} ${file.name}`;
225
192
  const openProps = {
226
- type: "button",
193
+ type: 'button',
227
194
  disabled: !!onOpen && busy,
228
- onClick: () => onOpen ? onOpen() : shared ? shared.open(id) : setOpen(true),
195
+ onClick: () => (onOpen ? onOpen() : shared ? shared.open(id) : setOpen(true)),
229
196
  };
230
- const retry = file.state === "error" && onRetry && (_jsx(Button, { variant: "ghost", size: "sm", onClick: onRetry, "aria-label": `Retry ${file.name}`, children: "Retry" }));
197
+ const retry = file.state === 'error' && onRetry && (_jsx(Button, { variant: "ghost", size: "sm", onClick: onRetry, "aria-label": `Retry ${file.name}`, children: "Retry" }));
231
198
  const remove = (size) => onRemove && (_jsx(Button, { variant: "ghost", size: size, "aria-label": `Remove ${file.name}`, onClick: onRemove, children: _jsx(X, { size: 14, "aria-hidden": "true" }) }));
232
- const viewer = inViewer && !shared && (_jsx(FileViewer, { file: target, open: open, onOpenChange: setOpen }));
233
- if (variant === "chip") {
199
+ const viewer = inViewer && !shared && _jsx(FileViewer, { file: target, open: open, onOpenChange: setOpen });
200
+ if (variant === 'chip') {
234
201
  const inner = (_jsxs(_Fragment, { children: [image && file.url ? (_jsx("span", { className: "sprout-file-attachment-thumb", children: _jsx(AttachmentImage, { src: file.url, name: file.name }, file.url) })) : (_jsx(FileTypeIcon, { name: file.name, mediaType: file.mediaType })), _jsx("span", { className: "sprout-file-attachment-name", children: file.name })] }));
235
- return (_jsxs(_Fragment, { children: [_jsxs("div", { ref: root, "data-slot": "file-attachment", "data-variant": "chip", "data-state": file.state, "data-removable": onRemove ? "" : undefined, className: cn("sprout-file-attachment", className), title: openable ? undefined : `${file.name} · ${stateLabel}`, children: [withPreview(openable ? (_jsx("button", { ...openProps, "aria-label": openLabel, title: peek ? undefined : `${file.name} · ${stateLabel}`, className: "sprout-file-attachment-open", children: inner })) : (_jsx("span", { className: "sprout-file-attachment-open", children: inner }))), busy && _jsx(Spinner, { "aria-label": stateLabel }), retry, remove("icon-xs")] }), viewer] }));
202
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { ref: root, "data-slot": "file-attachment", "data-variant": "chip", "data-state": file.state, "data-removable": onRemove ? '' : undefined, className: cn('sprout-file-attachment', className), title: openable ? undefined : `${file.name} · ${stateLabel}`, children: [withPreview(openable ? (_jsx("button", { ...openProps, "aria-label": openLabel, title: peek ? undefined : `${file.name} · ${stateLabel}`, className: "sprout-file-attachment-open", children: inner })) : (_jsx("span", { className: "sprout-file-attachment-open", children: inner }))), busy && _jsx(Spinner, { "aria-label": stateLabel }), retry, remove('icon-xs')] }), viewer] }));
236
203
  }
237
- const name = (_jsxs(_Fragment, { children: [_jsx("span", { className: "sprout-file-attachment-name", title: file.name, children: file.name }), variant !== "inline" && (_jsxs("span", { className: "sprout-file-attachment-status", children: [busy && _jsx(Spinner, { size: "sm", "aria-hidden": "true" }), stateLabel] }))] }));
204
+ const name = (_jsxs(_Fragment, { children: [_jsx("span", { className: "sprout-file-attachment-name", title: file.name, children: file.name }), variant !== 'inline' && (_jsxs("span", { className: "sprout-file-attachment-status", children: [busy && _jsx(Spinner, { size: "sm", "aria-hidden": "true" }), stateLabel] }))] }));
238
205
  const thumbnail = image && file.url ? (_jsx(AttachmentImage, { src: file.url, name: file.name }, file.url)) : (_jsx(FileTypeIcon, { name: file.name, mediaType: file.mediaType, size: "lg" }));
239
- return (_jsxs(_Fragment, { children: [_jsxs("div", { ref: root, "data-slot": "file-attachment", "data-variant": variant, "data-state": file.state, className: cn("sprout-file-attachment", className), children: [variant === "grid" &&
240
- (openable ? (_jsx("button", { ...openProps, tabIndex: -1, "aria-hidden": "true", className: "sprout-file-attachment-preview", children: thumbnail })) : (_jsx("span", { className: "sprout-file-attachment-preview", children: thumbnail }))), variant !== "grid" && (_jsx("span", { className: "sprout-file-attachment-media", children: image && file.url && variant === "list" ? (_jsx(AttachmentImage, { src: file.url, name: file.name }, file.url)) : (_jsx(FileTypeIcon, { name: file.name, mediaType: file.mediaType })) })), withPreview(openable ? (_jsx("button", { ...openProps, "aria-label": openLabel, className: "sprout-file-attachment-open", children: name })) : (_jsx("span", { className: "sprout-file-attachment-open", children: name }))), variant === "inline" && busy && _jsx(Spinner, { "aria-label": stateLabel }), variant === "inline" && file.state === "error" && (_jsx("span", { className: "sprout-file-attachment-failed", children: "Failed" })), (retry || onRemove) && (_jsxs("div", { className: "sprout-file-attachment-actions", children: [retry, remove("icon-sm")] }))] }), viewer] }));
206
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { ref: root, "data-slot": "file-attachment", "data-variant": variant, "data-state": file.state, className: cn('sprout-file-attachment', className), children: [variant === 'grid' &&
207
+ (openable ? (_jsx("button", { ...openProps, tabIndex: -1, "aria-hidden": "true", className: "sprout-file-attachment-preview", children: thumbnail })) : (_jsx("span", { className: "sprout-file-attachment-preview", children: thumbnail }))), variant !== 'grid' && (_jsx("span", { className: "sprout-file-attachment-media", children: image && file.url && variant === 'list' ? (_jsx(AttachmentImage, { src: file.url, name: file.name }, file.url)) : (_jsx(FileTypeIcon, { name: file.name, mediaType: file.mediaType })) })), withPreview(openable ? (_jsx("button", { ...openProps, "aria-label": openLabel, className: "sprout-file-attachment-open", children: name })) : (_jsx("span", { className: "sprout-file-attachment-open", children: name }))), variant === 'inline' && busy && _jsx(Spinner, { "aria-label": stateLabel }), variant === 'inline' && file.state === 'error' && (_jsx("span", { className: "sprout-file-attachment-failed", children: "Failed" })), (retry || onRemove) && (_jsxs("div", { className: "sprout-file-attachment-actions", children: [retry, remove('icon-sm')] }))] }), viewer] }));
241
208
  }
242
209
  /** A dashed drop target with a “Choose files” button. Files are handed to `onFiles`; nothing is uploaded. */
243
210
  export function AttachmentDropzone({ onFiles, disabled = false, accept = defaultFileAccept, className, }) {
@@ -245,29 +212,29 @@ export function AttachmentDropzone({ onFiles, disabled = false, accept = default
245
212
  const input = useRef(null);
246
213
  const over = (event) => {
247
214
  event.preventDefault();
248
- event.dataTransfer.dropEffect = disabled ? "none" : "copy";
215
+ event.dataTransfer.dropEffect = disabled ? 'none' : 'copy';
249
216
  if (!disabled)
250
217
  setDragging(true);
251
218
  };
252
- return (_jsxs("div", { "data-slot": "attachment-dropzone", "data-dragging": dragging ? "" : undefined, "data-disabled": disabled ? "" : undefined, className: cn("sprout-attachment-dropzone", className), onDragEnter: over, onDragOver: over, onDragLeave: (event) => {
219
+ return (_jsxs("div", { "data-slot": "attachment-dropzone", "data-dragging": dragging ? '' : undefined, "data-disabled": disabled ? '' : undefined, className: cn('sprout-attachment-dropzone', className), onDragEnter: over, onDragOver: over, onDragLeave: event => {
253
220
  if (!event.currentTarget.contains(event.relatedTarget))
254
221
  setDragging(false);
255
- }, onDrop: (event) => {
222
+ }, onDrop: event => {
256
223
  event.preventDefault();
257
224
  setDragging(false);
258
225
  if (!disabled)
259
226
  onFiles(Array.from(event.dataTransfer.files));
260
- }, children: [_jsx("input", { ref: input, type: "file", accept: accept, multiple: true, hidden: true, disabled: disabled, onChange: (event) => {
227
+ }, children: [_jsx("input", { ref: input, type: "file", accept: accept, multiple: true, hidden: true, disabled: disabled, onChange: event => {
261
228
  onFiles(Array.from(event.target.files ?? []));
262
- event.target.value = "";
229
+ event.target.value = '';
263
230
  } }), _jsx(Upload, { size: 20, "aria-hidden": "true", className: "sprout-attachment-dropzone-icon" }), _jsx("p", { className: "sprout-attachment-dropzone-text", children: "Drop files here, or choose them from your device." }), _jsx(Button, { variant: "outline", disabled: disabled, onClick: () => input.current?.click(), children: "Choose files" })] }));
264
231
  }
265
232
  /** A chip for a `File` still in browser memory, with a live image preview. */
266
- export function LocalFileAttachment({ file, onRemove, onOpen, viewable, preview, }) {
233
+ export function LocalFileAttachment({ file, onRemove, onOpen, viewable, preview }) {
267
234
  const [url, setUrl] = useState();
268
- const source = useMemo(() => ({ kind: "local", file }), [file]);
235
+ const source = useMemo(() => ({ kind: 'local', file }), [file]);
269
236
  useEffect(() => {
270
- if (fileKind(file.name, file.type) !== "image")
237
+ if (fileKind(file.name, file.type) !== 'image')
271
238
  return;
272
239
  const next = URL.createObjectURL(file);
273
240
  setUrl(next);
@@ -278,7 +245,7 @@ export function LocalFileAttachment({ file, onRemove, onOpen, viewable, preview,
278
245
  name: file.name,
279
246
  mediaType: file.type,
280
247
  size: formatFileSize(file.size),
281
- state: "ready",
248
+ state: 'ready',
282
249
  source,
283
250
  url,
284
251
  }, onRemove: onRemove, onOpen: onOpen, viewable: viewable, preview: preview }));
@@ -1,8 +1,8 @@
1
- import type { ComponentProps } from "react";
2
- import { Avatar as AvatarPrimitive } from "@base-ui/react/avatar";
3
- export type AvatarSize = "xs" | "sm" | "default" | "lg";
4
- export type EntityAvatarSize = AvatarSize | "xl";
5
- export type EntityAvatarShape = "circle" | "square";
1
+ import type { ComponentProps } from 'react';
2
+ import { Avatar as AvatarPrimitive } from '@base-ui/react/avatar';
3
+ export type AvatarSize = 'sm' | 'md' | 'lg';
4
+ export type EntityAvatarSize = AvatarSize;
5
+ export type EntityAvatarShape = 'circle' | 'square';
6
6
  export interface AvatarProps extends AvatarPrimitive.Root.Props {
7
7
  size?: AvatarSize;
8
8
  }
@@ -11,18 +11,10 @@ export type AvatarImageProps = AvatarPrimitive.Image.Props;
11
11
  export declare function AvatarImage({ className, ...props }: AvatarImageProps): import("react").JSX.Element;
12
12
  export type AvatarFallbackProps = AvatarPrimitive.Fallback.Props;
13
13
  export declare function AvatarFallback({ className, ...props }: AvatarFallbackProps): import("react").JSX.Element;
14
- export declare function AvatarBadge({ className, ...props }: ComponentProps<"span">): import("react").JSX.Element;
15
- export declare function AvatarGroup({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
16
- export declare function AvatarGroupCount({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
17
- export declare function agentAvatarSrc(agentId: string, baseUrl?: string): string;
18
- export interface AgentAvatarProps extends Omit<AvatarProps, "children"> {
19
- agentId: string;
20
- name: string;
21
- /** Overrides the artwork derived from `agentId`. */
22
- src?: string | undefined;
23
- }
24
- export declare function AgentAvatar({ agentId, name, src, ...props }: AgentAvatarProps): import("react").JSX.Element;
25
- export interface EntityAvatarProps extends Omit<AvatarPrimitive.Root.Props, "children"> {
14
+ export declare function AvatarBadge({ className, ...props }: ComponentProps<'span'>): import("react").JSX.Element;
15
+ export declare function AvatarGroup({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
16
+ export declare function AvatarGroupCount({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
17
+ export interface EntityAvatarProps extends Omit<AvatarPrimitive.Root.Props, 'children'> {
26
18
  seed: string;
27
19
  name: string;
28
20
  image?: string | null | undefined;
@@ -1,65 +1,28 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Avatar as AvatarPrimitive } from "@base-ui/react/avatar";
4
- import { cn, stateClassName } from "../internal/classes.js";
5
- export function Avatar({ className, size = "default", ...props }) {
6
- return (_jsx(AvatarPrimitive.Root, { "data-slot": "avatar", "data-size": size, ...props, className: stateClassName("sprout-avatar", className) }));
3
+ import { Avatar as AvatarPrimitive } from '@base-ui/react/avatar';
4
+ import { cn, stateClassName } from '../internal/classes.js';
5
+ import { hash } from '../internal/hash.js';
6
+ export function Avatar({ className, size = 'md', ...props }) {
7
+ return (_jsx(AvatarPrimitive.Root, { "data-slot": "avatar", "data-size": size, ...props, className: stateClassName('sprout-avatar', className) }));
7
8
  }
8
9
  export function AvatarImage({ className, ...props }) {
9
- return (_jsx(AvatarPrimitive.Image, { "data-slot": "avatar-image", ...props, className: stateClassName("sprout-avatar-image", className) }));
10
+ return (_jsx(AvatarPrimitive.Image, { "data-slot": "avatar-image", ...props, className: stateClassName('sprout-avatar-image', className) }));
10
11
  }
11
12
  export function AvatarFallback({ className, ...props }) {
12
- return (_jsx(AvatarPrimitive.Fallback, { "data-slot": "avatar-fallback", ...props, className: stateClassName("sprout-avatar-fallback", className) }));
13
+ return (_jsx(AvatarPrimitive.Fallback, { "data-slot": "avatar-fallback", ...props, className: stateClassName('sprout-avatar-fallback', className) }));
13
14
  }
14
15
  export function AvatarBadge({ className, ...props }) {
15
- return (_jsx("span", { "data-slot": "avatar-badge", ...props, className: cn("sprout-avatar-badge", className) }));
16
+ return _jsx("span", { "data-slot": "avatar-badge", ...props, className: cn('sprout-avatar-badge', className) });
16
17
  }
17
18
  export function AvatarGroup({ className, ...props }) {
18
- return (_jsx("div", { "data-slot": "avatar-group", ...props, className: cn("sprout-avatar-group", className) }));
19
+ return _jsx("div", { "data-slot": "avatar-group", ...props, className: cn('sprout-avatar-group', className) });
19
20
  }
20
21
  export function AvatarGroupCount({ className, ...props }) {
21
- return (_jsx("div", { "data-slot": "avatar-group-count", ...props, className: cn("sprout-avatar-group-count", className) }));
22
- }
23
- // FNV-1a: small, stable, and spreads similar ids apart.
24
- function hash(value) {
25
- let h = 0x811c9dc5;
26
- for (let i = 0; i < value.length; i++) {
27
- h ^= value.charCodeAt(i);
28
- h = Math.imul(h, 0x01000193);
29
- }
30
- return h >>> 0;
31
- }
32
- // Frozen order: any edit, even appending, changes existing agent avatars.
33
- // prettier-ignore
34
- const agentObjects = [
35
- "tulip", "tulip-bouquet", "cactus", "sunflower", "daisy", "sprout", "bonsai", "monstera", "fern",
36
- "lavender", "rose", "poppy", "daffodil", "lily", "bellflower", "eucalyptus", "ivy", "succulent",
37
- "acorn", "pinecone", "watering-can", "hand-trowel", "garden-fork", "pruning-shears",
38
- "gardening-gloves", "rain-boots", "wheelbarrow", "seed-packet", "flower-pot", "plant-mister",
39
- "spade", "rake", "hoe", "garden-hose", "seed-tray", "garden-apron", "plant-label", "twine-spool",
40
- "compost-bin", "pruning-saw", "mushroom", "strawberry", "carrot", "pumpkin", "apple", "pear",
41
- "lemon", "corn-cob", "honey-jar", "harvest-basket", "windmill", "barn", "tractor", "wheat",
42
- "pea-pod", "beetroot", "radish", "eggplant", "cherries", "hay-bale", "umbrella", "mug", "teapot",
43
- "moka-pot", "lantern", "candle", "picnic-basket", "straw-hat", "vase", "jam-jar", "birdhouse",
44
- "rocking-chair", "kettle", "bread-loaf", "croissant", "milk-bottle", "cookie", "oven-mitt",
45
- "thermos", "yarn-ball", "notebook", "pencil", "paintbrush", "paint-palette", "fountain-pen",
46
- "camera", "headphones", "desk-lamp", "book-stack", "alarm-clock", "scissors", "ruler", "stapler",
47
- "paperclip", "binder-clip", "tape-dispenser", "magnifying-glass", "envelope", "typewriter",
48
- "globe",
49
- ];
50
- // prettier-ignore
51
- const agentColors = ["pink", "coral", "orange", "yellow", "green", "teal", "blue", "purple"];
52
- export function agentAvatarSrc(agentId, baseUrl = "https://avatars.tulipfarm.ai/avatar") {
53
- const h = hash(agentId);
54
- const object = agentObjects[h % agentObjects.length];
55
- const color = agentColors[(h >>> 16) % agentColors.length];
56
- return `${baseUrl}/${object}/${color}.svg`;
22
+ return _jsx("div", { "data-slot": "avatar-group-count", ...props, className: cn('sprout-avatar-group-count', className) });
57
23
  }
58
24
  function initial(name) {
59
- return name.trim().charAt(0).toUpperCase() || "?";
60
- }
61
- export function AgentAvatar({ agentId, name, src, ...props }) {
62
- return (_jsxs(Avatar, { "data-agent-avatar": "", ...props, children: [_jsx(AvatarImage, { src: src ?? agentAvatarSrc(agentId), alt: "" }), _jsx(AvatarFallback, { children: initial(name) })] }));
25
+ return name.trim().charAt(0).toUpperCase() || '?';
63
26
  }
64
27
  // Same seed, same gradient: the fallback never changes between visits.
65
28
  function gradientFor(seed) {
@@ -68,6 +31,6 @@ function gradientFor(seed) {
68
31
  const to = (from + 40 + ((h >>> 9) % 60)) % 360;
69
32
  return `linear-gradient(135deg, oklch(0.62 0.15 ${from}), oklch(0.5 0.15 ${to}))`;
70
33
  }
71
- export function EntityAvatar({ seed, name, image, size = "default", shape = "circle", className, ...props }) {
72
- return (_jsxs(AvatarPrimitive.Root, { "data-slot": "entity-avatar", "data-size": size, "data-shape": shape, ...props, className: stateClassName("sprout-entity-avatar", className), children: [image && (_jsx(AvatarPrimitive.Image, { src: image, alt: "", referrerPolicy: "no-referrer", className: "sprout-avatar-image" })), _jsx(AvatarPrimitive.Fallback, { className: "sprout-entity-avatar-fallback", style: { backgroundImage: gradientFor(seed) }, children: initial(name) })] }));
34
+ export function EntityAvatar({ seed, name, image, size = 'md', shape = 'circle', className, ...props }) {
35
+ return (_jsxs(AvatarPrimitive.Root, { "data-slot": "entity-avatar", "data-size": size, "data-shape": shape, ...props, className: stateClassName('sprout-entity-avatar', className), children: [image && (_jsx(AvatarPrimitive.Image, { src: image, alt: "", referrerPolicy: "no-referrer", className: "sprout-avatar-image" })), _jsx(AvatarPrimitive.Fallback, { className: "sprout-entity-avatar-fallback", style: { backgroundImage: gradientFor(seed) }, children: initial(name) })] }));
73
36
  }
@@ -1,4 +1,4 @@
1
- import { useRender } from "@base-ui/react/use-render";
1
+ import { useRender } from '@base-ui/react/use-render';
2
2
  export declare const badgeVariantNames: readonly ["default", "success", "warning", "info", "secondary", "destructive", "outline", "ghost", "link"];
3
3
  export declare const badgeSizeNames: readonly ["default", "chip"];
4
4
  export type BadgeVariant = (typeof badgeVariantNames)[number];
@@ -8,13 +8,13 @@ export interface BadgeVariantOptions {
8
8
  size?: BadgeSize | null;
9
9
  className?: string;
10
10
  }
11
- export declare function badgeVariants({ variant, size, className, }?: BadgeVariantOptions): string;
11
+ export declare function badgeVariants({ variant, size, className }?: BadgeVariantOptions): string;
12
12
  export interface BadgeState extends Record<string, unknown> {
13
- slot: "badge";
13
+ slot: 'badge';
14
14
  variant: BadgeVariant;
15
15
  size: BadgeSize;
16
16
  }
17
- export interface BadgeProps extends useRender.ComponentProps<"span", BadgeState> {
17
+ export interface BadgeProps extends useRender.ComponentProps<'span', BadgeState> {
18
18
  variant?: BadgeVariant;
19
19
  size?: BadgeSize;
20
20
  }
@@ -1,27 +1,27 @@
1
- import { mergeProps } from "@base-ui/react/merge-props";
2
- import { useRender } from "@base-ui/react/use-render";
3
- import { cn } from "../internal/classes.js";
1
+ import { mergeProps } from '@base-ui/react/merge-props';
2
+ import { useRender } from '@base-ui/react/use-render';
3
+ import { cn } from '../internal/classes.js';
4
4
  export const badgeVariantNames = [
5
- "default",
6
- "success",
7
- "warning",
8
- "info",
9
- "secondary",
10
- "destructive",
11
- "outline",
12
- "ghost",
13
- "link",
5
+ 'default',
6
+ 'success',
7
+ 'warning',
8
+ 'info',
9
+ 'secondary',
10
+ 'destructive',
11
+ 'outline',
12
+ 'ghost',
13
+ 'link',
14
14
  ];
15
- export const badgeSizeNames = ["default", "chip"];
16
- export function badgeVariants({ variant, size, className, } = {}) {
17
- return cn("sprout-badge", `sprout-badge-${variant ?? "default"}`, size === "chip" && "sprout-badge-chip", className);
15
+ export const badgeSizeNames = ['default', 'chip'];
16
+ export function badgeVariants({ variant, size, className } = {}) {
17
+ return cn('sprout-badge', `sprout-badge-${variant ?? 'default'}`, size === 'chip' && 'sprout-badge-chip', className);
18
18
  }
19
- export function Badge({ className, variant = "default", size = "default", render, ref, ...props }) {
19
+ export function Badge({ className, variant = 'default', size = 'default', render, ref, ...props }) {
20
20
  return useRender({
21
- defaultTagName: "span",
21
+ defaultTagName: 'span',
22
22
  ref,
23
23
  render,
24
24
  props: mergeProps({ className: badgeVariants({ variant, size, className }) }, props),
25
- state: { slot: "badge", variant, size },
25
+ state: { slot: 'badge', variant, size },
26
26
  });
27
27
  }