@tulipfarm/sprout 0.3.0 → 0.4.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 (349) hide show
  1. package/README.md +45 -40
  2. package/dist/components/accordion.d.ts +2 -2
  3. package/dist/components/accordion.js +9 -9
  4. package/dist/components/agent-fanout.d.ts +2 -2
  5. package/dist/components/agent-fanout.js +65 -87
  6. package/dist/components/alert-dialog.d.ts +6 -6
  7. package/dist/components/alert-dialog.js +20 -20
  8. package/dist/components/alert.d.ts +6 -6
  9. package/dist/components/alert.js +13 -13
  10. package/dist/components/aspect-ratio.d.ts +2 -2
  11. package/dist/components/aspect-ratio.js +2 -2
  12. package/dist/components/attachment.d.ts +17 -17
  13. package/dist/components/attachment.js +82 -115
  14. package/dist/components/avatar.d.ts +10 -10
  15. package/dist/components/avatar.js +14 -14
  16. package/dist/components/badge.d.ts +4 -4
  17. package/dist/components/badge.js +18 -18
  18. package/dist/components/board.d.ts +107 -0
  19. package/dist/components/board.js +640 -0
  20. package/dist/components/brand-icon.d.ts +6 -6
  21. package/dist/components/brand-icon.js +55 -63
  22. package/dist/components/breadcrumb.d.ts +11 -11
  23. package/dist/components/breadcrumb.js +16 -18
  24. package/dist/components/button-group.d.ts +6 -6
  25. package/dist/components/button-group.js +14 -14
  26. package/dist/components/button.d.ts +11 -11
  27. package/dist/components/button.js +46 -56
  28. package/dist/components/calendar.d.ts +5 -5
  29. package/dist/components/calendar.js +44 -53
  30. package/dist/components/canvas.d.ts +4 -4
  31. package/dist/components/canvas.js +39 -46
  32. package/dist/components/card.d.ts +6 -6
  33. package/dist/components/card.js +17 -17
  34. package/dist/components/carousel.d.ts +7 -7
  35. package/dist/components/carousel.js +57 -75
  36. package/dist/components/chart.d.ts +5 -112
  37. package/dist/components/chart.js +5 -172
  38. package/dist/components/chat-confirmation.d.ts +13 -11
  39. package/dist/components/chat-confirmation.js +32 -38
  40. package/dist/components/chat-input.d.ts +4 -4
  41. package/dist/components/chat-input.js +74 -81
  42. package/dist/components/chat-plan.d.ts +2 -2
  43. package/dist/components/chat-plan.js +15 -20
  44. package/dist/components/chat-sources.d.ts +8 -8
  45. package/dist/components/chat-sources.js +18 -27
  46. package/dist/components/checkbox.d.ts +1 -1
  47. package/dist/components/checkbox.js +9 -9
  48. package/dist/components/choice-list.d.ts +2 -2
  49. package/dist/components/choice-list.js +16 -18
  50. package/dist/components/code-block.d.ts +5 -5
  51. package/dist/components/code-block.js +26 -26
  52. package/dist/components/collapsible.d.ts +1 -1
  53. package/dist/components/collapsible.js +7 -11
  54. package/dist/components/combobox.d.ts +3 -3
  55. package/dist/components/combobox.js +24 -24
  56. package/dist/components/command.d.ts +13 -13
  57. package/dist/components/command.js +61 -73
  58. package/dist/components/context-menu.d.ts +5 -5
  59. package/dist/components/context-menu.js +22 -22
  60. package/dist/components/dialog.d.ts +6 -6
  61. package/dist/components/dialog.js +23 -28
  62. package/dist/components/direction.d.ts +1 -1
  63. package/dist/components/direction.js +1 -1
  64. package/dist/components/dropdown-menu.d.ts +5 -5
  65. package/dist/components/dropdown-menu.js +20 -20
  66. package/dist/components/field.d.ts +11 -11
  67. package/dist/components/field.js +41 -61
  68. package/dist/components/file-explorer.d.ts +2 -2
  69. package/dist/components/file-explorer.js +89 -105
  70. package/dist/components/file-viewer.d.ts +10 -10
  71. package/dist/components/file-viewer.js +112 -140
  72. package/dist/components/form.d.ts +7 -7
  73. package/dist/components/form.js +24 -28
  74. package/dist/components/glass-banner.d.ts +3 -3
  75. package/dist/components/glass-banner.js +21 -24
  76. package/dist/components/gradient-banner.d.ts +5 -5
  77. package/dist/components/gradient-banner.js +13 -22
  78. package/dist/components/hover-card.d.ts +4 -4
  79. package/dist/components/hover-card.js +6 -6
  80. package/dist/components/input-group.d.ts +11 -11
  81. package/dist/components/input-group.js +22 -36
  82. package/dist/components/input-otp.d.ts +10 -10
  83. package/dist/components/input-otp.js +13 -15
  84. package/dist/components/input.d.ts +1 -1
  85. package/dist/components/input.js +7 -7
  86. package/dist/components/kbd.d.ts +3 -3
  87. package/dist/components/kbd.js +5 -5
  88. package/dist/components/label.d.ts +2 -2
  89. package/dist/components/label.js +2 -2
  90. package/dist/components/mention-list.d.ts +3 -3
  91. package/dist/components/mention-list.js +10 -10
  92. package/dist/components/menubar.d.ts +6 -6
  93. package/dist/components/menubar.js +22 -22
  94. package/dist/components/message-actions.d.ts +2 -2
  95. package/dist/components/message-actions.js +29 -31
  96. package/dist/components/message-response.d.ts +3 -3
  97. package/dist/components/message-response.js +18 -18
  98. package/dist/components/message-scroller.d.ts +12 -12
  99. package/dist/components/message-scroller.js +44 -56
  100. package/dist/components/message.d.ts +11 -11
  101. package/dist/components/message.js +25 -25
  102. package/dist/components/navigation-menu.d.ts +2 -2
  103. package/dist/components/navigation-menu.js +15 -15
  104. package/dist/components/notice-banner.d.ts +2 -2
  105. package/dist/components/notice-banner.js +2 -2
  106. package/dist/components/page-content.d.ts +2 -2
  107. package/dist/components/page-content.js +2 -2
  108. package/dist/components/page-header.d.ts +1 -1
  109. package/dist/components/page-header.js +16 -16
  110. package/dist/components/pagination.d.ts +9 -9
  111. package/dist/components/pagination.js +17 -17
  112. package/dist/components/plan-outline.d.ts +2 -2
  113. package/dist/components/plan-outline.js +43 -60
  114. package/dist/components/popover.d.ts +6 -6
  115. package/dist/components/popover.js +15 -15
  116. package/dist/components/presence-cursor.d.ts +2 -2
  117. package/dist/components/presence-cursor.js +3 -3
  118. package/dist/components/progress.d.ts +1 -1
  119. package/dist/components/progress.js +8 -8
  120. package/dist/components/prompt-list.d.ts +3 -3
  121. package/dist/components/prompt-list.js +6 -6
  122. package/dist/components/questionnaire.d.ts +19 -19
  123. package/dist/components/questionnaire.js +183 -242
  124. package/dist/components/radio-group.d.ts +2 -2
  125. package/dist/components/radio-group.js +6 -6
  126. package/dist/components/reasoning-effort.d.ts +3 -3
  127. package/dist/components/reasoning-effort.js +9 -12
  128. package/dist/components/record-list.d.ts +66 -0
  129. package/dist/components/record-list.js +151 -0
  130. package/dist/components/resizable.d.ts +5 -5
  131. package/dist/components/resizable.js +76 -102
  132. package/dist/components/result-card.d.ts +10 -5
  133. package/dist/components/result-card.js +42 -53
  134. package/dist/components/result-notice.d.ts +18 -0
  135. package/dist/components/result-notice.js +29 -0
  136. package/dist/components/review-card.d.ts +6 -6
  137. package/dist/components/review-card.js +18 -18
  138. package/dist/components/rich-text-editor.d.ts +2 -2
  139. package/dist/components/rich-text-editor.js +56 -72
  140. package/dist/components/schema-diagram.d.ts +3 -3
  141. package/dist/components/schema-diagram.js +39 -53
  142. package/dist/components/scroll-area.d.ts +1 -1
  143. package/dist/components/scroll-area.js +10 -14
  144. package/dist/components/search-dialog.d.ts +6 -6
  145. package/dist/components/search-dialog.js +16 -16
  146. package/dist/components/search-field.d.ts +1 -1
  147. package/dist/components/search-field.js +11 -11
  148. package/dist/components/select.d.ts +3 -3
  149. package/dist/components/select.js +20 -20
  150. package/dist/components/selection-slot.d.ts +2 -2
  151. package/dist/components/selection-slot.js +6 -9
  152. package/dist/components/separator.d.ts +15 -15
  153. package/dist/components/separator.js +22 -27
  154. package/dist/components/settings-list.d.ts +3 -3
  155. package/dist/components/settings-list.js +5 -5
  156. package/dist/components/sheet.d.ts +6 -6
  157. package/dist/components/sheet.js +27 -27
  158. package/dist/components/sidebar.d.ts +22 -22
  159. package/dist/components/sidebar.js +57 -58
  160. package/dist/components/skeleton.d.ts +5 -5
  161. package/dist/components/skeleton.js +14 -21
  162. package/dist/components/slider.d.ts +2 -2
  163. package/dist/components/slider.js +6 -6
  164. package/dist/components/spinner.d.ts +5 -5
  165. package/dist/components/spinner.js +22 -26
  166. package/dist/components/sql-viewer.d.ts +14 -14
  167. package/dist/components/sql-viewer.js +99 -128
  168. package/dist/components/state-panel-samples.d.ts +2 -2
  169. package/dist/components/state-panel-samples.js +209 -245
  170. package/dist/components/state-panel.d.ts +2 -35
  171. package/dist/components/state-panel.js +2 -29
  172. package/dist/components/state-sample.d.ts +7 -7
  173. package/dist/components/state-sample.js +18 -31
  174. package/dist/components/switch.d.ts +1 -1
  175. package/dist/components/switch.js +7 -7
  176. package/dist/components/table-nuqs.d.ts +2 -2
  177. package/dist/components/table-nuqs.js +11 -12
  178. package/dist/components/table.d.ts +4 -4
  179. package/dist/components/table.js +166 -235
  180. package/dist/components/tabs.d.ts +2 -2
  181. package/dist/components/tabs.js +12 -12
  182. package/dist/components/textarea.d.ts +2 -2
  183. package/dist/components/textarea.js +6 -8
  184. package/dist/components/timeline.d.ts +3 -0
  185. package/dist/components/timeline.js +3 -0
  186. package/dist/components/toast.d.ts +2 -2
  187. package/dist/components/toast.js +19 -25
  188. package/dist/components/toggle-group.d.ts +2 -2
  189. package/dist/components/toggle-group.js +18 -20
  190. package/dist/components/toggle.d.ts +2 -2
  191. package/dist/components/toggle.js +8 -8
  192. package/dist/components/tool-activity.d.ts +1 -1
  193. package/dist/components/tool-activity.js +83 -110
  194. package/dist/components/toolbar-status.d.ts +2 -2
  195. package/dist/components/toolbar-status.js +7 -7
  196. package/dist/components/tooltip.d.ts +5 -5
  197. package/dist/components/tooltip.js +12 -11
  198. package/dist/components/typed-text.d.ts +2 -2
  199. package/dist/components/typed-text.js +10 -12
  200. package/dist/components/view-switcher.d.ts +51 -0
  201. package/dist/components/view-switcher.js +114 -0
  202. package/dist/index.d.ts +98 -93
  203. package/dist/index.js +98 -93
  204. package/dist/internal/chart-kit.d.ts +142 -0
  205. package/dist/internal/chart-kit.js +200 -0
  206. package/dist/internal/charts/bars.d.ts +61 -0
  207. package/dist/internal/charts/bars.js +86 -0
  208. package/dist/internal/charts/lines.d.ts +67 -0
  209. package/dist/internal/charts/lines.js +70 -0
  210. package/dist/internal/charts/more.d.ts +77 -0
  211. package/dist/internal/charts/more.js +68 -0
  212. package/dist/internal/charts/parts.d.ts +54 -0
  213. package/dist/internal/charts/parts.js +82 -0
  214. package/dist/internal/charts/timeline-dates.d.ts +38 -0
  215. package/dist/internal/charts/timeline-dates.js +113 -0
  216. package/dist/internal/charts/timeline-window.d.ts +31 -0
  217. package/dist/internal/charts/timeline-window.js +26 -0
  218. package/dist/internal/charts/timeline.d.ts +72 -0
  219. package/dist/internal/charts/timeline.js +287 -0
  220. package/dist/internal/classes.d.ts +1 -1
  221. package/dist/internal/classes.js +7 -9
  222. package/dist/internal/code-tokens.d.ts +2 -2
  223. package/dist/internal/code-tokens.js +12 -12
  224. package/dist/internal/fieldset.d.ts +1 -1
  225. package/dist/internal/fieldset.js +6 -6
  226. package/dist/internal/file-kind.d.ts +1 -1
  227. package/dist/internal/file-kind.js +43 -51
  228. package/dist/internal/flow.d.ts +4 -4
  229. package/dist/internal/flow.js +20 -23
  230. package/dist/internal/languages.js +999 -999
  231. package/dist/internal/message-scroller.d.ts +3 -3
  232. package/dist/internal/message-scroller.js +64 -112
  233. package/dist/internal/pressable.d.ts +1 -1
  234. package/dist/internal/pressable.js +7 -7
  235. package/dist/internal/state-panel.d.ts +35 -0
  236. package/dist/internal/state-panel.js +22 -0
  237. package/dist/internal/syntax.d.ts +2 -2
  238. package/dist/internal/syntax.js +36 -47
  239. package/dist/styles/accordion.css +3 -5
  240. package/dist/styles/agent-fanout.css +64 -60
  241. package/dist/styles/alert-dialog.css +12 -26
  242. package/dist/styles/alert.css +10 -15
  243. package/dist/styles/attachment.css +51 -93
  244. package/dist/styles/avatar.css +17 -24
  245. package/dist/styles/badge.css +11 -36
  246. package/dist/styles/board.css +571 -0
  247. package/dist/styles/brand-icon.css +7 -8
  248. package/dist/styles/breadcrumb.css +4 -7
  249. package/dist/styles/button-group.css +8 -14
  250. package/dist/styles/button.css +22 -27
  251. package/dist/styles/calendar.css +24 -36
  252. package/dist/styles/canvas.css +2 -3
  253. package/dist/styles/card.css +7 -23
  254. package/dist/styles/carousel.css +11 -12
  255. package/dist/styles/chart.css +215 -31
  256. package/dist/styles/chat-input.css +15 -39
  257. package/dist/styles/chat-plan.css +3 -4
  258. package/dist/styles/chat-sources.css +3 -6
  259. package/dist/styles/checkbox.css +11 -25
  260. package/dist/styles/choice-list.css +17 -31
  261. package/dist/styles/code-block.css +11 -25
  262. package/dist/styles/collapsible.css +10 -15
  263. package/dist/styles/combobox.css +11 -15
  264. package/dist/styles/command.css +5 -8
  265. package/dist/styles/context-menu.css +2 -2
  266. package/dist/styles/dialog.css +5 -16
  267. package/dist/styles/dropdown-menu.css +2 -2
  268. package/dist/styles/field.css +15 -21
  269. package/dist/styles/file-explorer.css +19 -33
  270. package/dist/styles/file-viewer.css +13 -17
  271. package/dist/styles/form.css +3 -3
  272. package/dist/styles/glass-banner.css +12 -47
  273. package/dist/styles/gradient-banner.css +17 -35
  274. package/dist/styles/hover-card.css +9 -15
  275. package/dist/styles/index.css +116 -108
  276. package/dist/styles/input-group.css +25 -41
  277. package/dist/styles/input-otp.css +5 -6
  278. package/dist/styles/input.css +5 -5
  279. package/dist/styles/kbd.css +1 -1
  280. package/dist/styles/label.css +9 -30
  281. package/dist/styles/mention-list.css +6 -8
  282. package/dist/styles/menubar.css +5 -6
  283. package/dist/styles/message-actions.css +1 -1
  284. package/dist/styles/message-response.css +3 -5
  285. package/dist/styles/message-scroller.css +14 -21
  286. package/dist/styles/message.css +23 -60
  287. package/dist/styles/navigation-menu.css +14 -29
  288. package/dist/styles/notice-banner.css +1 -2
  289. package/dist/styles/page-header.css +7 -10
  290. package/dist/styles/pagination.css +1 -4
  291. package/dist/styles/plan-outline.css +20 -37
  292. package/dist/styles/popover.css +10 -19
  293. package/dist/styles/presence-cursor.css +1 -2
  294. package/dist/styles/progress.css +2 -4
  295. package/dist/styles/prompt-list.css +6 -17
  296. package/dist/styles/questionnaire.css +16 -40
  297. package/dist/styles/radio-group.css +12 -23
  298. package/dist/styles/reasoning-effort.css +8 -15
  299. package/dist/styles/record-list.css +243 -0
  300. package/dist/styles/resizable.css +10 -11
  301. package/dist/styles/result-card.css +17 -3
  302. package/dist/styles/result-notice.css +80 -0
  303. package/dist/styles/review-card.css +2 -3
  304. package/dist/styles/rich-text-editor.css +1 -2
  305. package/dist/styles/schema-diagram.css +12 -17
  306. package/dist/styles/scroll-area.css +8 -10
  307. package/dist/styles/search-dialog.css +1 -5
  308. package/dist/styles/search-field.css +1 -2
  309. package/dist/styles/select.css +7 -7
  310. package/dist/styles/selection-slot.css +1 -2
  311. package/dist/styles/separator.css +7 -8
  312. package/dist/styles/settings-list.css +1 -2
  313. package/dist/styles/sheet.css +40 -73
  314. package/dist/styles/sidebar.css +17 -21
  315. package/dist/styles/skeleton.css +9 -11
  316. package/dist/styles/slider.css +11 -21
  317. package/dist/styles/spinner.css +2 -2
  318. package/dist/styles/sql-viewer.css +29 -29
  319. package/dist/styles/state-panel.css +8 -9
  320. package/dist/styles/state-sample.css +20 -33
  321. package/dist/styles/switch.css +11 -18
  322. package/dist/styles/table.css +51 -77
  323. package/dist/styles/tabs.css +12 -16
  324. package/dist/styles/textarea.css +3 -3
  325. package/dist/styles/themes/chatgpt.css +11 -23
  326. package/dist/styles/themes/claude.css +12 -24
  327. package/dist/styles/themes/cloudflare.css +11 -23
  328. package/dist/styles/themes/discord.css +11 -23
  329. package/dist/styles/themes/github.css +11 -23
  330. package/dist/styles/themes/grok.css +11 -23
  331. package/dist/styles/themes/linear.css +12 -25
  332. package/dist/styles/themes/neutral.css +11 -23
  333. package/dist/styles/themes/notion.css +11 -23
  334. package/dist/styles/themes/perplexity.css +11 -23
  335. package/dist/styles/themes/raycast.css +11 -23
  336. package/dist/styles/themes/spotify.css +11 -23
  337. package/dist/styles/themes/stripe.css +11 -23
  338. package/dist/styles/themes/supabase.css +11 -23
  339. package/dist/styles/themes/tulipfarm.css +9 -10
  340. package/dist/styles/themes/vercel.css +12 -25
  341. package/dist/styles/timeline.css +276 -0
  342. package/dist/styles/toast.css +13 -20
  343. package/dist/styles/toggle-group.css +17 -23
  344. package/dist/styles/toggle.css +8 -8
  345. package/dist/styles/tool-activity.css +7 -13
  346. package/dist/styles/toolbar-status.css +2 -7
  347. package/dist/styles/tooltip.css +15 -21
  348. package/dist/styles/view-switcher.css +279 -0
  349. package/package.json +21 -1
@@ -1,8 +1,8 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Children, createContext, Fragment, isValidElement, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, } from "react";
4
- import { cn } from "../internal/classes.js";
5
- export const resizableOrientationNames = ["horizontal", "vertical"];
3
+ import { Children, createContext, Fragment, isValidElement, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, } from 'react';
4
+ import { cn } from '../internal/classes.js';
5
+ export const resizableOrientationNames = ['horizontal', 'vertical'];
6
6
  const GroupContext = createContext(null);
7
7
  function useGroup(part) {
8
8
  const context = useContext(GroupContext);
@@ -10,12 +10,12 @@ function useGroup(part) {
10
10
  throw new Error(`${part} must be used inside ResizablePanelGroup.`);
11
11
  return context;
12
12
  }
13
- const useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
13
+ const useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;
14
14
  const KEYBOARD_STEP = 5;
15
15
  const EPSILON = 0.001;
16
16
  /** Percent value of a size that can be resolved without measuring, or undefined. */
17
17
  function staticPercent(size) {
18
- if (typeof size !== "string")
18
+ if (typeof size !== 'string')
19
19
  return undefined;
20
20
  const value = size.trim();
21
21
  if (/^-?[\d.]+%?$/.test(value))
@@ -31,22 +31,22 @@ function toPercent(size, available, element) {
31
31
  if (available <= 0)
32
32
  return undefined;
33
33
  let pixels;
34
- if (typeof size === "number")
34
+ if (typeof size === 'number')
35
35
  pixels = size;
36
36
  else {
37
37
  const value = Number.parseFloat(size);
38
- const unit = size.trim().replace(/^-?[\d.]+/, "");
38
+ const unit = size.trim().replace(/^-?[\d.]+/, '');
39
39
  const view = element.ownerDocument.defaultView;
40
- const font = (node) => Number.parseFloat(view?.getComputedStyle(node).fontSize ?? "") || 16;
41
- if (unit === "px")
40
+ const font = (node) => Number.parseFloat(view?.getComputedStyle(node).fontSize ?? '') || 16;
41
+ if (unit === 'px')
42
42
  pixels = value;
43
- else if (unit === "rem")
43
+ else if (unit === 'rem')
44
44
  pixels = value * font(element.ownerDocument.documentElement);
45
- else if (unit === "em")
45
+ else if (unit === 'em')
46
46
  pixels = value * font(element);
47
- else if (unit === "vw")
47
+ else if (unit === 'vw')
48
48
  pixels = (value * (view?.innerWidth ?? 0)) / 100;
49
- else if (unit === "vh")
49
+ else if (unit === 'vh')
50
50
  pixels = (value * (view?.innerHeight ?? 0)) / 100;
51
51
  else
52
52
  return undefined;
@@ -62,18 +62,14 @@ function validate(sizes, bounds) {
62
62
  const diff = 100 - total(next);
63
63
  if (Math.abs(diff) < EPSILON)
64
64
  break;
65
- const open = next.flatMap((size, index) => (diff > 0 ? size < bounds[index].max : size > bounds[index].min)
66
- ? [index]
67
- : []);
65
+ const open = next.flatMap((size, index) => (diff > 0 ? size < bounds[index].max : size > bounds[index].min) ? [index] : []);
68
66
  if (!open.length)
69
67
  break;
70
68
  for (const index of open)
71
69
  next[index] = clamp(next[index] + diff / open.length, bounds[index]);
72
70
  }
73
71
  const sum = total(next);
74
- return Math.abs(sum - 100) < EPSILON || sum <= 0
75
- ? next
76
- : next.map((size) => (size / sum) * 100);
72
+ return Math.abs(sum - 100) < EPSILON || sum <= 0 ? next : next.map(size => (size / sum) * 100);
77
73
  }
78
74
  /**
79
75
  * Move the boundary after panel `pivot` by `delta` percent. The adjacent panel
@@ -91,7 +87,7 @@ function resize(base, bounds, pivot, delta) {
91
87
  .map((_, index) => index)
92
88
  .slice(0, pivot + 1)
93
89
  .reverse();
94
- const room = Math.min(bounds[grow].max - next[grow], total(shrink.map((index) => next[index] - bounds[index].min)));
90
+ const room = Math.min(bounds[grow].max - next[grow], total(shrink.map(index => next[index] - bounds[index].min)));
95
91
  let remaining = Math.max(0, Math.min(Math.abs(delta), room));
96
92
  next[grow] = next[grow] + remaining;
97
93
  for (const index of shrink) {
@@ -105,11 +101,10 @@ function resize(base, bounds, pivot, delta) {
105
101
  }
106
102
  function sameLayout(a, b) {
107
103
  const keys = Object.keys(a);
108
- return (keys.length === Object.keys(b).length &&
109
- keys.every((key) => key in b && Math.abs(a[key] - b[key]) < EPSILON));
104
+ return keys.length === Object.keys(b).length && keys.every(key => key in b && Math.abs(a[key] - b[key]) < EPSILON);
110
105
  }
111
106
  function collectPanelProps(children, found = []) {
112
- Children.forEach(children, (child) => {
107
+ Children.forEach(children, child => {
113
108
  if (!isValidElement(child))
114
109
  return;
115
110
  if (child.type === ResizablePanel)
@@ -120,13 +115,13 @@ function collectPanelProps(children, found = []) {
120
115
  return found;
121
116
  }
122
117
  function assignRef(ref, value) {
123
- if (typeof ref === "function")
118
+ if (typeof ref === 'function')
124
119
  ref(value);
125
120
  else if (ref)
126
121
  ref.current = value;
127
122
  }
128
123
  /** A row or column of resizable panels separated by `ResizableHandle`s. */
129
- export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout, onLayoutChange, onLayoutChanged, className, children, ref, ...props }) {
124
+ export function ResizablePanelGroup({ orientation = 'horizontal', defaultLayout, onLayoutChange, onLayoutChanged, className, children, ref, ...props }) {
130
125
  const element = useRef(null);
131
126
  const panels = useRef(new Map());
132
127
  const separators = useRef(new Map());
@@ -142,17 +137,14 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
142
137
  const interacted = useRef(false);
143
138
  const callbacks = useRef({ onLayoutChange, onLayoutChanged });
144
139
  callbacks.current = { onLayoutChange, onLayoutChanged };
145
- const horizontal = orientation === "horizontal";
140
+ const horizontal = orientation === 'horizontal';
146
141
  const autoSize = useMemo(() => {
147
- const declared = collectPanelProps(children).map((panel) => staticPercent(panel.defaultSize));
148
- const unknown = declared.filter((size) => size === undefined).length;
142
+ const declared = collectPanelProps(children).map(panel => staticPercent(panel.defaultSize));
143
+ const unknown = declared.filter(size => size === undefined).length;
149
144
  const known = total(declared.filter((size) => size !== undefined));
150
145
  return unknown ? Math.max(0, 100 - known) / unknown : 0;
151
146
  }, [children]);
152
- const ordered = useCallback(() => [...panels.current.values()].sort((a, b) => a.element.compareDocumentPosition(b.element) &
153
- Node.DOCUMENT_POSITION_FOLLOWING
154
- ? -1
155
- : 1), []);
147
+ const ordered = useCallback(() => [...panels.current.values()].sort((a, b) => a.element.compareDocumentPosition(b.element) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1), []);
156
148
  const available = useCallback(() => {
157
149
  const root = element.current;
158
150
  if (!root)
@@ -164,7 +156,7 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
164
156
  }, [horizontal]);
165
157
  const measureBounds = useCallback((entries) => {
166
158
  const space = available();
167
- return entries.map((entry) => {
159
+ return entries.map(entry => {
168
160
  const min = toPercent(entry.minSize, space, entry.element) ?? 0;
169
161
  const max = toPercent(entry.maxSize, space, entry.element) ?? 100;
170
162
  return {
@@ -185,11 +177,11 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
185
177
  if (settled)
186
178
  callbacks.current.onLayoutChanged?.(next, settled);
187
179
  }, []);
188
- const defaultLayoutKey = defaultLayout ? JSON.stringify(defaultLayout) : "";
180
+ const defaultLayoutKey = defaultLayout ? JSON.stringify(defaultLayout) : '';
189
181
  useIsomorphicLayoutEffect(() => {
190
182
  const entries = ordered();
191
- const ids = entries.map((entry) => entry.id);
192
- const key = ids.join("\u0000");
183
+ const ids = entries.map(entry => entry.id);
184
+ const key = ids.join('\u0000');
193
185
  const limits = measureBounds(entries);
194
186
  const changedPanels = key !== panelKey.current;
195
187
  const changedDefaults = defaultLayoutKey !== defaultsKey.current;
@@ -197,24 +189,22 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
197
189
  interacted.current = false;
198
190
  let sizes;
199
191
  if (changedPanels || (changedDefaults && !interacted.current)) {
200
- const saved = defaultLayout &&
201
- ids.length &&
202
- ids.every((id) => typeof defaultLayout[id] === "number")
203
- ? ids.map((id) => defaultLayout[id])
192
+ const saved = defaultLayout && ids.length && ids.every(id => typeof defaultLayout[id] === 'number')
193
+ ? ids.map(id => defaultLayout[id])
204
194
  : null;
205
195
  if (saved)
206
196
  sizes = saved;
207
197
  else {
208
198
  const space = available();
209
- const declared = entries.map((entry) => toPercent(entry.defaultSize, space, entry.element));
210
- const unknown = declared.filter((size) => size === undefined).length;
211
- const rest = Math.max(0, 100 -
212
- total(declared.filter((size) => size !== undefined))) / Math.max(unknown, 1);
213
- sizes = declared.map((size) => size ?? rest);
199
+ const declared = entries.map(entry => toPercent(entry.defaultSize, space, entry.element));
200
+ const unknown = declared.filter(size => size === undefined).length;
201
+ const rest = Math.max(0, 100 - total(declared.filter((size) => size !== undefined))) /
202
+ Math.max(unknown, 1);
203
+ sizes = declared.map(size => size ?? rest);
214
204
  }
215
205
  }
216
206
  else
217
- sizes = ids.map((id) => layoutRef.current[id] ?? 0);
207
+ sizes = ids.map(id => layoutRef.current[id] ?? 0);
218
208
  const before = layoutRef.current;
219
209
  const next = validate(sizes, limits);
220
210
  const nextLayout = Object.fromEntries(ids.map((id, index) => [id, next[index]]));
@@ -226,16 +216,13 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
226
216
  panelKey.current = key;
227
217
  defaultsKey.current = defaultLayoutKey;
228
218
  const nextBounds = Object.fromEntries(ids.map((id, index) => [id, limits[index]]));
229
- setBounds((current) => JSON.stringify(current) === JSON.stringify(nextBounds)
230
- ? current
231
- : nextBounds);
219
+ setBounds(current => (JSON.stringify(current) === JSON.stringify(nextBounds) ? current : nextBounds));
232
220
  const nextLinks = {};
233
221
  for (const [separatorId, separator] of separators.current) {
234
222
  let previous;
235
223
  let following;
236
224
  for (const entry of entries) {
237
- if (separator.compareDocumentPosition(entry.element) &
238
- Node.DOCUMENT_POSITION_PRECEDING)
225
+ if (separator.compareDocumentPosition(entry.element) & Node.DOCUMENT_POSITION_PRECEDING)
239
226
  previous = entry;
240
227
  else {
241
228
  following = entry;
@@ -245,21 +232,11 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
245
232
  if (previous && following)
246
233
  nextLinks[separatorId] = { before: previous.id, after: following.id };
247
234
  }
248
- setLinks((current) => JSON.stringify(current) === JSON.stringify(nextLinks)
249
- ? current
250
- : nextLinks);
251
- }, [
252
- version,
253
- extent,
254
- defaultLayoutKey,
255
- ordered,
256
- measureBounds,
257
- available,
258
- commit,
259
- ]);
235
+ setLinks(current => (JSON.stringify(current) === JSON.stringify(nextLinks) ? current : nextLinks));
236
+ }, [version, extent, defaultLayoutKey, ordered, measureBounds, available, commit]);
260
237
  useEffect(() => {
261
238
  const root = element.current;
262
- if (!root || typeof ResizeObserver === "undefined")
239
+ if (!root || typeof ResizeObserver === 'undefined')
263
240
  return;
264
241
  const observer = new ResizeObserver(() => setExtent(Math.round(available())));
265
242
  observer.observe(root);
@@ -267,19 +244,19 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
267
244
  }, [available]);
268
245
  const registerPanel = useCallback((entry) => {
269
246
  panels.current.set(entry.id, entry);
270
- setVersion((value) => value + 1);
247
+ setVersion(value => value + 1);
271
248
  return () => {
272
249
  if (panels.current.get(entry.id) === entry)
273
250
  panels.current.delete(entry.id);
274
- setVersion((value) => value + 1);
251
+ setVersion(value => value + 1);
275
252
  };
276
253
  }, []);
277
254
  const registerSeparator = useCallback((id, node) => {
278
255
  separators.current.set(id, node);
279
- setVersion((value) => value + 1);
256
+ setVersion(value => value + 1);
280
257
  return () => {
281
258
  separators.current.delete(id);
282
- setVersion((value) => value + 1);
259
+ setVersion(value => value + 1);
283
260
  };
284
261
  }, []);
285
262
  const pivotFor = useCallback((separatorId) => {
@@ -289,23 +266,20 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
289
266
  const entries = ordered();
290
267
  let pivot = -1;
291
268
  entries.forEach((entry, index) => {
292
- if (separator.compareDocumentPosition(entry.element) &
293
- Node.DOCUMENT_POSITION_PRECEDING)
269
+ if (separator.compareDocumentPosition(entry.element) & Node.DOCUMENT_POSITION_PRECEDING)
294
270
  pivot = index;
295
271
  });
296
272
  if (pivot < 0 || pivot >= entries.length - 1)
297
273
  return null;
298
- const ids = entries.map((entry) => entry.id);
274
+ const ids = entries.map(entry => entry.id);
299
275
  return {
300
276
  ids,
301
277
  pivot,
302
- base: ids.map((id) => layoutRef.current[id] ?? 0),
278
+ base: ids.map(id => layoutRef.current[id] ?? 0),
303
279
  limits: measureBounds(entries),
304
280
  };
305
281
  }, [ordered, measureBounds]);
306
- const reversed = useCallback(() => horizontal &&
307
- !!element.current &&
308
- getComputedStyle(element.current).direction === "rtl", [horizontal]);
282
+ const reversed = useCallback(() => horizontal && !!element.current && getComputedStyle(element.current).direction === 'rtl', [horizontal]);
309
283
  const startDrag = useCallback((separatorId, event) => {
310
284
  const target = pivotFor(separatorId);
311
285
  if (!target)
@@ -320,8 +294,8 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
320
294
  const root = ownerDocument.documentElement;
321
295
  const previousCursor = root.style.cursor;
322
296
  const previousSelect = root.style.userSelect;
323
- root.style.cursor = horizontal ? "col-resize" : "row-resize";
324
- root.style.userSelect = "none";
297
+ root.style.cursor = horizontal ? 'col-resize' : 'row-resize';
298
+ root.style.userSelect = 'none';
325
299
  handle.setPointerCapture?.(pointerId);
326
300
  handle.focus({ preventScroll: true });
327
301
  setDragging(separatorId);
@@ -337,9 +311,9 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
337
311
  const end = (endEvent) => {
338
312
  if (endEvent.pointerId !== pointerId)
339
313
  return;
340
- handle.removeEventListener("pointermove", move);
341
- handle.removeEventListener("pointerup", end);
342
- handle.removeEventListener("pointercancel", end);
314
+ handle.removeEventListener('pointermove', move);
315
+ handle.removeEventListener('pointerup', end);
316
+ handle.removeEventListener('pointercancel', end);
343
317
  handle.releasePointerCapture?.(pointerId);
344
318
  root.style.cursor = previousCursor;
345
319
  root.style.userSelect = previousSelect;
@@ -347,9 +321,9 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
347
321
  interacted.current = true;
348
322
  commit(target.ids, latest, { isUserInteraction: true });
349
323
  };
350
- handle.addEventListener("pointermove", move);
351
- handle.addEventListener("pointerup", end);
352
- handle.addEventListener("pointercancel", end);
324
+ handle.addEventListener('pointermove', move);
325
+ handle.addEventListener('pointerup', end);
326
+ handle.addEventListener('pointercancel', end);
353
327
  }, [pivotFor, horizontal, available, reversed, commit]);
354
328
  const resizeWithKey = useCallback((separatorId, key) => {
355
329
  const target = pivotFor(separatorId);
@@ -358,13 +332,13 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
358
332
  const { base, limits, pivot } = target;
359
333
  const forward = reversed() ? -KEYBOARD_STEP : KEYBOARD_STEP;
360
334
  let delta;
361
- if (key === (horizontal ? "ArrowRight" : "ArrowDown"))
335
+ if (key === (horizontal ? 'ArrowRight' : 'ArrowDown'))
362
336
  delta = forward;
363
- else if (key === (horizontal ? "ArrowLeft" : "ArrowUp"))
337
+ else if (key === (horizontal ? 'ArrowLeft' : 'ArrowUp'))
364
338
  delta = -forward;
365
- else if (key === "Home")
339
+ else if (key === 'Home')
366
340
  delta = limits[pivot].min - base[pivot];
367
- else if (key === "End")
341
+ else if (key === 'End')
368
342
  delta = limits[pivot].max - base[pivot];
369
343
  else
370
344
  return false;
@@ -397,14 +371,14 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
397
371
  startDrag,
398
372
  resizeWithKey,
399
373
  ]);
400
- return (_jsx(GroupContext, { value: context, children: _jsx("div", { "data-slot": "resizable-panel-group", "data-orientation": orientation, "data-dragging": dragging ? "" : undefined, className: cn("sprout-resizable-group", className), ref: (node) => {
374
+ return (_jsx(GroupContext, { value: context, children: _jsx("div", { "data-slot": "resizable-panel-group", "data-orientation": orientation, "data-dragging": dragging ? '' : undefined, className: cn('sprout-resizable-group', className), ref: node => {
401
375
  element.current = node;
402
376
  assignRef(ref, node);
403
377
  }, ...props, children: children }) }));
404
378
  }
405
379
  /** One resizable region. It must be a direct child of `ResizablePanelGroup`. */
406
380
  export function ResizablePanel({ id: idProp, defaultSize, minSize, maxSize, className, style, ref, ...props }) {
407
- const group = useGroup("ResizablePanel");
381
+ const group = useGroup('ResizablePanel');
408
382
  const generated = useId();
409
383
  const id = idProp ?? generated;
410
384
  const element = useRef(null);
@@ -422,7 +396,7 @@ export function ResizablePanel({ id: idProp, defaultSize, minSize, maxSize, clas
422
396
  }, [registerPanel, id, defaultSize, minSize, maxSize]);
423
397
  const size = group.layout[id] ?? staticPercent(defaultSize) ?? group.autoSize;
424
398
  const flex = { flexGrow: size, flexShrink: 1, flexBasis: 0 };
425
- return (_jsx("div", { "data-slot": "resizable-panel", "data-panel-id": id, id: id, className: cn("sprout-resizable-panel", className), ref: (node) => {
399
+ return (_jsx("div", { "data-slot": "resizable-panel", "data-panel-id": id, id: id, className: cn('sprout-resizable-panel', className), ref: node => {
426
400
  element.current = node;
427
401
  assignRef(ref, node);
428
402
  }, ...props, style: { ...style, ...flex } }));
@@ -432,7 +406,7 @@ export function ResizablePanel({ id: idProp, defaultSize, minSize, maxSize, clas
432
406
  * Home and End move it to the first panel's minimum and maximum size.
433
407
  */
434
408
  export function ResizableHandle({ withHandle = false, className, children, onPointerDown, onKeyDown, ref, ...props }) {
435
- const group = useGroup("ResizableHandle");
409
+ const group = useGroup('ResizableHandle');
436
410
  const id = useId();
437
411
  const element = useRef(null);
438
412
  const { registerSeparator } = group;
@@ -452,11 +426,11 @@ export function ResizableHandle({ withHandle = false, className, children, onPoi
452
426
  max: Math.min(own.max, 100 - total(others.map(([, bound]) => bound.min))),
453
427
  };
454
428
  }
455
- const lineOrientation = group.orientation === "horizontal" ? "vertical" : "horizontal";
456
- return (_jsxs("div", { role: "separator", tabIndex: 0, "aria-orientation": lineOrientation, "aria-controls": link?.before, "aria-valuenow": value === undefined ? undefined : Math.round(value), "aria-valuemin": limits ? Math.round(limits.min) : 0, "aria-valuemax": limits ? Math.round(limits.max) : 100, "data-slot": "resizable-handle", "data-orientation": lineOrientation, "data-with-handle": withHandle ? "" : undefined, "data-dragging": group.dragging === id ? "" : undefined, className: cn("sprout-resizable-handle", className), ref: (node) => {
429
+ const lineOrientation = group.orientation === 'horizontal' ? 'vertical' : 'horizontal';
430
+ return (_jsxs("div", { role: "separator", tabIndex: 0, "aria-orientation": lineOrientation, "aria-controls": link?.before, "aria-valuenow": value === undefined ? undefined : Math.round(value), "aria-valuemin": limits ? Math.round(limits.min) : 0, "aria-valuemax": limits ? Math.round(limits.max) : 100, "data-slot": "resizable-handle", "data-orientation": lineOrientation, "data-with-handle": withHandle ? '' : undefined, "data-dragging": group.dragging === id ? '' : undefined, className: cn('sprout-resizable-handle', className), ref: node => {
457
431
  element.current = node;
458
432
  assignRef(ref, node);
459
- }, onPointerDown: (event) => {
433
+ }, onPointerDown: event => {
460
434
  onPointerDown?.(event);
461
435
  if (event.defaultPrevented || event.button !== 0)
462
436
  return;
@@ -467,12 +441,12 @@ export function ResizableHandle({ withHandle = false, className, children, onPoi
467
441
  return;
468
442
  if (group.resizeWithKey(id, event.key))
469
443
  event.preventDefault();
470
- }, ...props, children: [withHandle && (_jsx("span", { "aria-hidden": "true", "data-slot": "resizable-handle-grip", className: "sprout-resizable-grip" })), children] }));
444
+ }, ...props, children: [withHandle && _jsx("span", { "aria-hidden": "true", "data-slot": "resizable-handle-grip", className: "sprout-resizable-grip" }), children] }));
471
445
  }
472
446
  const storageListeners = new Set();
473
447
  function browserStorage() {
474
448
  try {
475
- return typeof window === "undefined" ? undefined : window.localStorage;
449
+ return typeof window === 'undefined' ? undefined : window.localStorage;
476
450
  }
477
451
  catch {
478
452
  return undefined;
@@ -483,13 +457,13 @@ function browserStorage() {
483
457
  * `ResizablePanelGroup` as `defaultLayout` and `onLayoutChanged`.
484
458
  */
485
459
  export function useResizableLayout({ id, panelIds, onlySaveAfterUserInteractions = false, storage, }) {
486
- const key = `sprout-resizable:${id}${panelIds ? `:${panelIds.join(",")}` : ""}`;
460
+ const key = `sprout-resizable:${id}${panelIds ? `:${panelIds.join(',')}` : ''}`;
487
461
  const subscribe = useCallback((listener) => {
488
462
  storageListeners.add(listener);
489
- window.addEventListener("storage", listener);
463
+ window.addEventListener('storage', listener);
490
464
  return () => {
491
465
  storageListeners.delete(listener);
492
- window.removeEventListener("storage", listener);
466
+ window.removeEventListener('storage', listener);
493
467
  };
494
468
  }, []);
495
469
  const raw = useSyncExternalStore(subscribe, () => {
@@ -505,10 +479,10 @@ export function useResizableLayout({ id, panelIds, onlySaveAfterUserInteractions
505
479
  return undefined;
506
480
  try {
507
481
  const parsed = JSON.parse(raw);
508
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
482
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
509
483
  return undefined;
510
484
  const entries = Object.entries(parsed);
511
- return entries.every(([, size]) => typeof size === "number" && Number.isFinite(size))
485
+ return entries.every(([, size]) => typeof size === 'number' && Number.isFinite(size))
512
486
  ? Object.fromEntries(entries)
513
487
  : undefined;
514
488
  }
@@ -1,5 +1,5 @@
1
- import type { ComponentProps, ReactNode } from "react";
2
- import { type Brand } from "./brand-icon.js";
1
+ import type { ComponentProps, ReactNode } from 'react';
2
+ import { type Brand } from './brand-icon.js';
3
3
  export declare const resultCardKindNames: readonly ["File", "Plan", "Workflow", "Action", "Calendar", "Table", "Activity", "Agent", "Skill"];
4
4
  export declare const resultCardStateNames: readonly ["default", "loading", "running", "disabled", "error", "success"];
5
5
  export declare const resultAppActionStateNames: readonly ["completed", "pending", "running", "failed", "unknown", "blocked", "cancelled", "skipped"];
@@ -10,10 +10,15 @@ export type ResultAppAction = {
10
10
  label: string;
11
11
  state: ResultAppActionState;
12
12
  };
13
- /** One app that took part in a result. `brand: null` shows a generic plug. */
13
+ /**
14
+ * One app that took part in a result. `brand: null` shows `icon`, or a
15
+ * generic plug when no icon is given.
16
+ */
14
17
  export type ResultApp = {
15
18
  brand: Brand | null;
16
19
  name: string;
20
+ /** Shown when `brand` is null, such as a table icon for your own data. */
21
+ icon?: ReactNode;
17
22
  actions: readonly ResultAppAction[];
18
23
  };
19
24
  export type ResultCardAction = {
@@ -21,7 +26,7 @@ export type ResultCardAction = {
21
26
  onClick: () => void;
22
27
  disabled?: boolean | undefined;
23
28
  };
24
- export interface ResultCardProps extends Omit<ComponentProps<"section">, "title" | "children"> {
29
+ export interface ResultCardProps extends Omit<ComponentProps<'section'>, 'title' | 'children'> {
25
30
  title: string;
26
31
  kind: ResultCardKind;
27
32
  /** Apps used. Repeated brands merge; two tiles show, the rest fold into “+N”. */
@@ -46,7 +51,7 @@ export interface ResultCardProps extends Omit<ComponentProps<"section">, "title"
46
51
  * live status, and offers one action such as “Open in Canvas”.
47
52
  */
48
53
  export declare function ResultCard({ title, kind, apps, status, state, action, icon, children, className, ...props }: ResultCardProps): import("react").JSX.Element;
49
- export interface ResultAppActionsProps extends Omit<ComponentProps<"div">, "children"> {
54
+ export interface ResultAppActionsProps extends Omit<ComponentProps<'div'>, 'children'> {
50
55
  apps: readonly ResultApp[];
51
56
  /** Show each app’s icon and name above its actions. Defaults to `true`. */
52
57
  showAppNames?: boolean | undefined;
@@ -1,59 +1,50 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Check } from "reicon-react/icons/Check";
4
- import { Danger } from "reicon-react/icons/Danger";
5
- import { Plug } from "reicon-react/icons/Plug";
6
- import { cn } from "../internal/classes.js";
7
- import { BrandIcon, BrandTile } from "./brand-icon.js";
8
- import { Button } from "./button.js";
9
- import { Popover, PopoverContent, PopoverTitle, PopoverTrigger, } from "./popover.js";
10
- import { Spinner } from "./spinner.js";
3
+ import { Check } from 'reicon-react/icons/Check';
4
+ import { Danger } from 'reicon-react/icons/Danger';
5
+ import { Plug } from 'reicon-react/icons/Plug';
6
+ import { cn } from '../internal/classes.js';
7
+ import { BrandIcon, BrandTile } from './brand-icon.js';
8
+ import { Button } from './button.js';
9
+ import { Popover, PopoverContent, PopoverTitle, PopoverTrigger } from './popover.js';
10
+ import { Spinner } from './spinner.js';
11
11
  export const resultCardKindNames = [
12
- "File",
13
- "Plan",
14
- "Workflow",
15
- "Action",
16
- "Calendar",
17
- "Table",
18
- "Activity",
19
- "Agent",
20
- "Skill",
21
- ];
22
- export const resultCardStateNames = [
23
- "default",
24
- "loading",
25
- "running",
26
- "disabled",
27
- "error",
28
- "success",
12
+ 'File',
13
+ 'Plan',
14
+ 'Workflow',
15
+ 'Action',
16
+ 'Calendar',
17
+ 'Table',
18
+ 'Activity',
19
+ 'Agent',
20
+ 'Skill',
29
21
  ];
22
+ export const resultCardStateNames = ['default', 'loading', 'running', 'disabled', 'error', 'success'];
30
23
  export const resultAppActionStateNames = [
31
- "completed",
32
- "pending",
33
- "running",
34
- "failed",
35
- "unknown",
36
- "blocked",
37
- "cancelled",
38
- "skipped",
24
+ 'completed',
25
+ 'pending',
26
+ 'running',
27
+ 'failed',
28
+ 'unknown',
29
+ 'blocked',
30
+ 'cancelled',
31
+ 'skipped',
39
32
  ];
40
33
  const actionPrefixes = {
41
- failed: "Failed:",
42
- unknown: "Unconfirmed:",
43
- pending: "Pending:",
44
- running: "In progress:",
45
- blocked: "Blocked:",
46
- cancelled: "Cancelled:",
47
- skipped: "Skipped:",
34
+ failed: 'Failed:',
35
+ unknown: 'Unconfirmed:',
36
+ pending: 'Pending:',
37
+ running: 'In progress:',
38
+ blocked: 'Blocked:',
39
+ cancelled: 'Cancelled:',
40
+ skipped: 'Skipped:',
48
41
  };
49
42
  function mergeApps(apps) {
50
43
  const byKey = new Map();
51
44
  for (const app of apps) {
52
45
  const key = app.brand ?? app.name;
53
46
  const existing = byKey.get(key);
54
- byKey.set(key, existing
55
- ? { ...existing, actions: [...existing.actions, ...app.actions] }
56
- : app);
47
+ byKey.set(key, existing ? { ...existing, actions: [...existing.actions, ...app.actions] } : app);
57
48
  }
58
49
  return [...byKey.values()];
59
50
  }
@@ -62,27 +53,25 @@ function mergeApps(apps) {
62
53
  * action, calendar read, or table result. It names the apps used, shows a
63
54
  * live status, and offers one action such as “Open in Canvas”.
64
55
  */
65
- export function ResultCard({ title, kind, apps, status, state = "default", action, icon, children, className, ...props }) {
56
+ export function ResultCard({ title, kind, apps, status, state = 'default', action, icon, children, className, ...props }) {
66
57
  const unique = mergeApps(apps);
67
58
  const visible = unique.slice(0, 2);
68
59
  const hidden = unique.slice(2);
69
- const busy = state === "loading" || state === "running";
70
- const disabled = state === "disabled";
71
- return (_jsxs("section", { "data-slot": "result-card", "data-state": state, "data-kind": kind, "aria-label": `${kind}: ${title}`, "aria-busy": busy, ...props, className: cn("sprout-result-card", className), children: [_jsxs("div", { className: "sprout-result-card-header", children: [visible.length > 0 ? (_jsxs("div", { role: "group", "aria-label": "Apps used", className: "sprout-result-card-apps", children: [visible.map((app) => (_jsx("span", { "data-result-app": app.brand ?? "connected-app", className: "sprout-result-card-app", children: _jsx(AppActionsPopover, { apps: [app], disabled: disabled }) }, app.brand ?? app.name))), hidden.length > 0 && (_jsx("span", { "data-result-overflow": hidden.length, className: "sprout-result-card-app", children: _jsx(AppActionsPopover, { apps: hidden, overflow: true, disabled: disabled }) }))] })) : (icon && (_jsx(BrandTile, { "aria-hidden": "true", className: "sprout-result-card-icon", children: icon }))), _jsxs("div", { className: "sprout-result-card-main", children: [_jsxs("div", { className: "sprout-result-card-text", children: [_jsx("h3", { className: "sprout-result-card-title", children: title }), _jsxs("div", { className: "sprout-result-card-meta", children: [_jsx("span", { children: kind }), _jsx("span", { "aria-hidden": "true", children: "\u00B7" }), _jsxs("span", { role: "status", "data-tone": state === "success" || state === "error" ? state : undefined, className: "sprout-result-card-status", children: [busy ? (_jsx(Spinner, { "aria-hidden": "true" })) : state === "success" ? (_jsx(Check, { size: 14, "aria-hidden": "true" })) : state === "error" ? (_jsx(Danger, { size: 14, "aria-hidden": "true" })) : null, status] })] })] }), action && (_jsx("div", { className: "sprout-result-card-action", children: _jsx(Button, { variant: "outline", size: "result-card", disabled: state === "loading" || disabled || action.disabled === true, onClick: action.onClick, children: action.label }) }))] })] }), children && _jsx("div", { className: "sprout-result-card-body", children: children })] }));
60
+ const busy = state === 'loading' || state === 'running';
61
+ const disabled = state === 'disabled';
62
+ return (_jsxs("section", { "data-slot": "result-card", "data-state": state, "data-kind": kind, "aria-label": `${kind}: ${title}`, "aria-busy": busy, ...props, className: cn('sprout-result-card', className), children: [_jsxs("div", { className: "sprout-result-card-header", children: [visible.length > 0 ? (_jsxs("div", { role: "group", "aria-label": "Apps used", className: "sprout-result-card-apps", children: [visible.map(app => (_jsx("span", { "data-result-app": app.brand ?? 'connected-app', className: "sprout-result-card-app", children: _jsx(AppActionsPopover, { apps: [app], disabled: disabled }) }, app.brand ?? app.name))), hidden.length > 0 && (_jsx("span", { "data-result-overflow": hidden.length, className: "sprout-result-card-app", children: _jsx(AppActionsPopover, { apps: hidden, overflow: true, disabled: disabled }) }))] })) : (icon && (_jsx(BrandTile, { "aria-hidden": "true", className: "sprout-result-card-icon", children: icon }))), _jsxs("div", { className: "sprout-result-card-main", children: [_jsxs("div", { className: "sprout-result-card-text", children: [_jsx("h3", { className: "sprout-result-card-title", children: title }), _jsxs("div", { className: "sprout-result-card-meta", children: [_jsx("span", { children: kind }), _jsx("span", { "aria-hidden": "true", children: "\u00B7" }), _jsxs("span", { role: "status", "data-tone": state === 'success' || state === 'error' ? state : undefined, className: "sprout-result-card-status", children: [busy ? (_jsx(Spinner, { "aria-hidden": "true" })) : state === 'success' ? (_jsx(Check, { size: 14, "aria-hidden": "true" })) : state === 'error' ? (_jsx(Danger, { size: 14, "aria-hidden": "true" })) : null, status] })] })] }), action && (_jsx("div", { className: "sprout-result-card-action", children: _jsx(Button, { variant: "outline", size: "result-card", disabled: state === 'loading' || disabled || action.disabled === true, onClick: action.onClick, children: action.label }) }))] })] }), children && _jsx("div", { className: "sprout-result-card-body", children: children })] }));
72
63
  }
73
64
  function AppActionsPopover({ apps, overflow = false, disabled, }) {
74
65
  const first = apps[0];
75
66
  if (!first)
76
67
  return null;
77
- const title = overflow
78
- ? `${apps.length} more ${apps.length === 1 ? "app" : "apps"}`
79
- : `${first.name} actions`;
80
- return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { openOnHover: true, delay: 800, closeDelay: 200, render: _jsx(BrandTile, { size: "action", render: _jsx(Button, { variant: "ghost", size: "icon", disabled: disabled }) }), "aria-label": title, children: overflow ? (_jsxs("span", { className: "sprout-result-card-overflow", children: ["+", apps.length] })) : first.brand ? (_jsx(BrandIcon, { brand: first.brand, size: "fill" })) : (_jsx(Plug, { size: 18, "aria-hidden": "true" })) }), _jsxs(PopoverContent, { size: "app-actions", align: "start", sideOffset: 8, initialFocus: (interaction) => interaction !== "mouse", children: [_jsx(PopoverTitle, { children: title }), _jsx(ResultAppActions, { apps: apps, showAppNames: overflow })] })] }));
68
+ const title = overflow ? `${apps.length} more ${apps.length === 1 ? 'app' : 'apps'}` : `${first.name} actions`;
69
+ return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { openOnHover: true, delay: 800, closeDelay: 200, render: _jsx(BrandTile, { size: "action", render: _jsx(Button, { variant: "ghost", size: "icon", disabled: disabled }) }), "aria-label": title, children: overflow ? (_jsxs("span", { className: "sprout-result-card-overflow", children: ["+", apps.length] })) : first.brand ? (_jsx(BrandIcon, { brand: first.brand, size: "fill" })) : first.icon ? (_jsx("span", { "aria-hidden": "true", className: "sprout-result-app-icon", children: first.icon })) : (_jsx(Plug, { size: 18, "aria-hidden": "true" })) }), _jsxs(PopoverContent, { size: "app-actions", align: "start", sideOffset: 8, initialFocus: interaction => interaction !== 'mouse', children: [_jsx(PopoverTitle, { children: title }), _jsx(ResultAppActions, { apps: apps, showAppNames: overflow })] })] }));
81
70
  }
82
71
  /**
83
72
  * The actions each app took, grouped by app. A check marks completed
84
73
  * actions; every other state is spelled out, such as “Unconfirmed:”.
85
74
  */
86
75
  export function ResultAppActions({ apps, showAppNames = true, className, ...props }) {
87
- return (_jsx("div", { "data-slot": "result-app-actions", ...props, className: cn("sprout-result-app-actions", className), children: apps.map((app) => (_jsxs("section", { "aria-label": app.name, className: "sprout-result-app", children: [showAppNames && (_jsxs("div", { className: "sprout-result-app-name", children: [app.brand ? (_jsx(BrandIcon, { brand: app.brand, size: "glyph" })) : (_jsx(Plug, { size: 20, "aria-hidden": "true" })), _jsx("h4", { children: app.name })] })), app.actions.length === 0 ? (_jsx("p", { className: "sprout-result-app-empty", children: "No action details were recorded." })) : (_jsx("ul", { className: "sprout-result-app-list", children: app.actions.map((action, index) => (_jsxs("li", { "data-state": action.state, className: "sprout-result-app-action", children: [action.state === "completed" ? (_jsxs("span", { className: "sprout-result-app-check", children: [_jsx(Check, { size: 16, "aria-hidden": "true" }), _jsx("span", { className: "sprout-result-sr-only", children: "Completed:" })] })) : (_jsx("span", { className: "sprout-result-app-prefix", children: actionPrefixes[action.state] })), _jsx("span", { className: "sprout-result-app-label", children: action.label })] }, `${action.label}:${index}`))) }))] }, app.brand ?? app.name))) }));
76
+ return (_jsx("div", { "data-slot": "result-app-actions", ...props, className: cn('sprout-result-app-actions', className), children: apps.map(app => (_jsxs("section", { "aria-label": app.name, className: "sprout-result-app", children: [showAppNames && (_jsxs("div", { className: "sprout-result-app-name", children: [app.brand ? (_jsx(BrandIcon, { brand: app.brand, size: "glyph" })) : app.icon ? (_jsx("span", { "aria-hidden": "true", className: "sprout-result-app-icon", children: app.icon })) : (_jsx(Plug, { size: 20, "aria-hidden": "true" })), _jsx("h4", { children: app.name })] })), app.actions.length === 0 ? (_jsx("p", { className: "sprout-result-app-empty", children: "No action details were recorded." })) : (_jsx("ul", { className: "sprout-result-app-list", children: app.actions.map((action, index) => (_jsxs("li", { "data-state": action.state, className: "sprout-result-app-action", children: [action.state === 'completed' ? (_jsxs("span", { className: "sprout-result-app-check", children: [_jsx(Check, { size: 16, "aria-hidden": "true" }), _jsx("span", { className: "sprout-result-sr-only", children: "Completed:" })] })) : (_jsx("span", { className: "sprout-result-app-prefix", children: actionPrefixes[action.state] })), _jsx("span", { className: "sprout-result-app-label", children: action.label })] }, `${action.label}:${index}`))) }))] }, app.brand ?? app.name))) }));
88
77
  }