@flikk/ui 1.0.0-beta.30 → 1.0.0-beta.31

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 (295) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/dist/components/ai/AgentStatus/AgentStatus.d.ts +3 -0
  3. package/dist/components/ai/AgentStatus/AgentStatus.js +144 -0
  4. package/dist/components/ai/AgentStatus/AgentStatus.theme.d.ts +2 -0
  5. package/dist/components/ai/AgentStatus/AgentStatus.theme.js +37 -0
  6. package/dist/components/ai/AgentStatus/AgentStatus.types.d.ts +116 -0
  7. package/dist/components/ai/AgentStatus/index.d.ts +3 -0
  8. package/dist/components/ai/CodeBlock/CodeBlock.js +3 -3
  9. package/dist/components/ai/CodeBlock/CodeBlock.theme.js +1 -1
  10. package/dist/components/ai/PromptInput/PromptInput.js +13 -14
  11. package/dist/components/ai/PromptInput/PromptInput.theme.js +1 -1
  12. package/dist/components/ai/PromptInput/VoiceRecorder.js +3 -3
  13. package/dist/components/ai/Reasoning/Reasoning.d.ts +5 -0
  14. package/dist/components/ai/Reasoning/Reasoning.js +16 -0
  15. package/dist/components/ai/Reasoning/Reasoning.types.d.ts +20 -0
  16. package/dist/components/ai/Reasoning/index.d.ts +2 -0
  17. package/dist/components/ai/SourceCitation/SourceCitation.d.ts +4 -0
  18. package/dist/components/ai/SourceCitation/SourceCitation.js +29 -0
  19. package/dist/components/ai/SourceCitation/SourceCitation.theme.d.ts +2 -0
  20. package/dist/components/ai/SourceCitation/SourceCitation.theme.js +23 -0
  21. package/dist/components/ai/SourceCitation/SourceCitation.types.d.ts +55 -0
  22. package/dist/components/ai/SourceCitation/index.d.ts +3 -0
  23. package/dist/components/ai/StreamingResponse/ErrorDisplay.js +2 -2
  24. package/dist/components/ai/StreamingResponse/StreamingResponse.js +1 -3
  25. package/dist/components/ai/StreamingResponse/StreamingResponse.theme.js +3 -1
  26. package/dist/components/ai/TokenCounter/TokenCounter.js +2 -2
  27. package/dist/components/ai/index.d.ts +3 -0
  28. package/dist/components/ai/index.js +6 -3
  29. package/dist/components/ai/shared/StatusIndicator.d.ts +8 -0
  30. package/dist/components/ai/shared/StatusIndicator.js +34 -0
  31. package/dist/components/canvas/CanvasToolbar.js +2 -2
  32. package/dist/components/canvas/NodeControls.js +2 -2
  33. package/dist/components/canvas/NodeRenderer.js +2 -2
  34. package/dist/components/charts/ActivityRings/ActivityRings.js +2 -2
  35. package/dist/components/charts/AreaChart/AreaChart.js +21 -32
  36. package/dist/components/charts/AreaChart/AreaChart.theme.d.ts +1 -6
  37. package/dist/components/charts/AreaChart/AreaChart.theme.js +7 -19
  38. package/dist/components/charts/AreaChart/AreaChart.types.d.ts +18 -11
  39. package/dist/components/charts/AreaChart/AreaChart.types.js +10 -3
  40. package/dist/components/charts/AreaChart/index.d.ts +1 -1
  41. package/dist/components/charts/BarChart/BarChart.js +9 -28
  42. package/dist/components/charts/BarChart/BarChart.types.d.ts +20 -16
  43. package/dist/components/charts/BarChart/BarChart.types.js +11 -4
  44. package/dist/components/charts/ComboChart/BarRenderer.js +8 -5
  45. package/dist/components/charts/ComboChart/ComboChart.js +11 -24
  46. package/dist/components/charts/ComboChart/ComboChart.types.d.ts +15 -13
  47. package/dist/components/charts/ComboChart/ComboChart.types.js +14 -2
  48. package/dist/components/charts/ComboChart/LineRenderer.js +15 -10
  49. package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.d.ts +16 -0
  50. package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.js +237 -0
  51. package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.types.d.ts +62 -0
  52. package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.types.js +21 -0
  53. package/dist/components/charts/HorizontalBarChart/index.d.ts +3 -0
  54. package/dist/components/charts/LineChart/LineChart.js +9 -26
  55. package/dist/components/charts/LineChart/LineChart.types.d.ts +11 -14
  56. package/dist/components/charts/LineChart/LineChart.types.js +11 -3
  57. package/dist/components/charts/LollipopChart/LollipopChart.d.ts +3 -0
  58. package/dist/components/charts/LollipopChart/LollipopChart.js +361 -0
  59. package/dist/components/charts/LollipopChart/LollipopChart.types.d.ts +42 -0
  60. package/dist/components/charts/LollipopChart/LollipopChart.types.js +12 -0
  61. package/dist/components/charts/LollipopChart/index.d.ts +3 -0
  62. package/dist/components/charts/ScatterPlot/ScatterPlot.js +5 -4
  63. package/dist/components/charts/ScatterPlot/ScatterPlot.types.d.ts +14 -19
  64. package/dist/components/charts/ScatterPlot/ScatterPlot.types.js +9 -2
  65. package/dist/components/charts/StackedBarChart/StackedBarChart.js +150 -132
  66. package/dist/components/charts/StackedBarChart/StackedBarChart.types.d.ts +20 -18
  67. package/dist/components/charts/StackedBarChart/StackedBarChart.types.js +10 -4
  68. package/dist/components/charts/hooks/useChartAccessibility.d.ts +1 -1
  69. package/dist/components/charts/hooks/useChartAccessibility.js +3 -0
  70. package/dist/components/charts/hooks/useTooltipPosition.js +18 -6
  71. package/dist/components/charts/index.d.ts +6 -0
  72. package/dist/components/charts/index.js +6 -0
  73. package/dist/components/charts/shared/ChartAxis/CategoryYAxis.d.ts +14 -0
  74. package/dist/components/charts/shared/ChartAxis/CategoryYAxis.js +35 -0
  75. package/dist/components/charts/shared/ChartAxis/ChartAxis.types.d.ts +69 -8
  76. package/dist/components/charts/shared/ChartAxis/ValueXAxis.d.ts +14 -0
  77. package/dist/components/charts/shared/ChartAxis/ValueXAxis.js +64 -0
  78. package/dist/components/charts/shared/ChartAxis/XAxis.js +1 -1
  79. package/dist/components/charts/shared/ChartAxis/YAxis.js +2 -2
  80. package/dist/components/charts/shared/ChartAxis/index.d.ts +3 -1
  81. package/dist/components/charts/shared/ChartGrid/HorizontalGrid.d.ts +0 -2
  82. package/dist/components/charts/shared/ChartGrid/HorizontalGrid.js +1 -1
  83. package/dist/components/charts/shared/ChartGrid/VerticalGrid.d.ts +29 -0
  84. package/dist/components/charts/shared/ChartGrid/VerticalGrid.js +26 -0
  85. package/dist/components/charts/shared/ChartGrid/index.d.ts +2 -0
  86. package/dist/components/charts/shared/ChartMarker/ChartMarker.js +7 -1
  87. package/dist/components/charts/theme/chart.theme.js +18 -23
  88. package/dist/components/charts/types/chart.types.d.ts +9 -5
  89. package/dist/components/charts/types/chart.types.js +1 -7
  90. package/dist/components/charts/utils/animation-utils.js +1 -3
  91. package/dist/components/charts/utils/bar-emphasis.d.ts +32 -3
  92. package/dist/components/charts/utils/bar-emphasis.js +24 -8
  93. package/dist/components/charts/utils/index.d.ts +1 -0
  94. package/dist/components/charts/utils/series-color.d.ts +7 -0
  95. package/dist/components/charts/utils/series-color.js +20 -0
  96. package/dist/components/core/Accordion/Accordion.theme.js +2 -2
  97. package/dist/components/core/Accordion/AccordionTrigger.js +2 -2
  98. package/dist/components/core/Alert/Alert.animations.d.ts +2 -1
  99. package/dist/components/core/Alert/Alert.animations.js +21 -6
  100. package/dist/components/core/Alert/Alert.js +7 -7
  101. package/dist/components/core/Avatar/Avatar.js +50 -42
  102. package/dist/components/core/Avatar/Avatar.theme.d.ts +8 -4
  103. package/dist/components/core/Avatar/Avatar.theme.js +64 -8
  104. package/dist/components/core/Avatar/Avatar.types.d.ts +13 -2
  105. package/dist/components/core/Avatar/index.d.ts +1 -1
  106. package/dist/components/core/AvatarGroup/AvatarGroup.js +6 -8
  107. package/dist/components/core/AvatarGroup/AvatarGroup.theme.d.ts +1 -2
  108. package/dist/components/core/AvatarGroup/AvatarGroup.theme.js +2 -6
  109. package/dist/components/core/AvatarGroup/AvatarGroup.types.d.ts +0 -6
  110. package/dist/components/core/AvatarGroup/index.d.ts +1 -1
  111. package/dist/components/core/Badge/Badge.animations.js +4 -2
  112. package/dist/components/core/Badge/Badge.js +9 -4
  113. package/dist/components/core/Badge/Badge.theme.js +18 -12
  114. package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.d.ts +1 -4
  115. package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.js +2 -2
  116. package/dist/components/core/Button/Button.js +9 -17
  117. package/dist/components/core/Button/Button.ripple.js +2 -2
  118. package/dist/components/core/Button/Button.theme.d.ts +2 -0
  119. package/dist/components/core/Button/Button.theme.js +34 -21
  120. package/dist/components/core/Button/Button.types.d.ts +18 -1
  121. package/dist/components/core/Calendar/Calendar.js +20 -5
  122. package/dist/components/core/Calendar/Calendar.theme.js +14 -22
  123. package/dist/components/core/Calendar/Calendar.types.d.ts +0 -1
  124. package/dist/components/core/Calendar/CalendarMini/CalendarMini.js +3 -3
  125. package/dist/components/core/Card/Card.theme.js +12 -4
  126. package/dist/components/core/Card/CardBody.js +1 -1
  127. package/dist/components/core/Card/CardFooter.js +1 -1
  128. package/dist/components/core/Card/CardHeader.js +1 -1
  129. package/dist/components/core/Carousel/CarouselNext.js +2 -2
  130. package/dist/components/core/Carousel/CarouselPrevious.js +2 -2
  131. package/dist/components/core/CommandPalette/CommandPalette.js +5 -4
  132. package/dist/components/core/CommandPalette/CommandPalette.theme.js +3 -7
  133. package/dist/components/core/CommandPalette/CommandPalette.types.d.ts +2 -0
  134. package/dist/components/core/ContextMenu/ContextMenuItem.js +2 -2
  135. package/dist/components/core/ContextMenu/ContextMenuSubTrigger.js +2 -2
  136. package/dist/components/core/Drawer/Drawer.theme.js +7 -4
  137. package/dist/components/core/Drawer/DrawerHeader.js +2 -2
  138. package/dist/components/core/Dropdown/Dropdown.theme.js +3 -1
  139. package/dist/components/core/Dropdown/DropdownItem.js +2 -2
  140. package/dist/components/core/Dropdown/DropdownTrigger.js +16 -5
  141. package/dist/components/core/HeroCard/HeroCard.theme.js +5 -2
  142. package/dist/components/core/Kbd/Kbd.theme.js +4 -2
  143. package/dist/components/core/Link/Link.js +6 -4
  144. package/dist/components/core/Message/Message.js +2 -2
  145. package/dist/components/core/Message/Message.theme.js +5 -7
  146. package/dist/components/core/Message/MessageAudio.js +2 -2
  147. package/dist/components/core/Message/MessageFile.js +2 -2
  148. package/dist/components/core/Message/MessageLink.js +2 -2
  149. package/dist/components/core/Message/MessageStatusIndicator.js +5 -5
  150. package/dist/components/core/Modal/Modal.d.ts +1 -1
  151. package/dist/components/core/Modal/Modal.js +2 -2
  152. package/dist/components/core/Modal/Modal.theme.js +9 -4
  153. package/dist/components/core/Modal/ModalHeader.js +2 -2
  154. package/dist/components/core/ModalStack/ModalStackModal.js +2 -2
  155. package/dist/components/core/NavItem/NavItem.js +6 -6
  156. package/dist/components/core/OfflineIndicator/OfflineIndicator.animations.d.ts +22 -0
  157. package/dist/components/core/OfflineIndicator/OfflineIndicator.animations.js +54 -0
  158. package/dist/components/core/OfflineIndicator/OfflineIndicator.js +23 -24
  159. package/dist/components/core/OfflineIndicator/OfflineIndicator.theme.js +25 -6
  160. package/dist/components/core/OfflineIndicator/OfflineIndicator.types.d.ts +17 -0
  161. package/dist/components/core/PageHeading/PageHeading.theme.js +1 -1
  162. package/dist/components/core/PageHeading/PageHeadingBackButton.js +2 -2
  163. package/dist/components/core/Pagination/Pagination.js +3 -3
  164. package/dist/components/core/Pagination/Pagination.theme.js +3 -3
  165. package/dist/components/core/Pill/Pill.js +4 -2
  166. package/dist/components/core/Pill/Pill.theme.js +6 -4
  167. package/dist/components/core/Rating/Rating.js +4 -5
  168. package/dist/components/core/Rating/Rating.theme.js +1 -1
  169. package/dist/components/core/Segmented/Segmented.theme.js +9 -6
  170. package/dist/components/core/Sidebar/Sidebar.types.d.ts +4 -2
  171. package/dist/components/core/Sidebar/SidebarHeader.js +2 -2
  172. package/dist/components/core/Sidebar/SidebarMobileTrigger.js +2 -2
  173. package/dist/components/core/Sidebar/SidebarSearch.js +3 -3
  174. package/dist/components/core/Sidebar/SidebarToggle.js +3 -3
  175. package/dist/components/core/Sidebar/SidebarUserProfile.js +2 -2
  176. package/dist/components/core/Sortable/Sortable.js +2 -2
  177. package/dist/components/core/Tag/Tag.js +2 -2
  178. package/dist/components/core/Tag/Tag.theme.js +4 -2
  179. package/dist/components/core/Toast/Toast.js +3 -3
  180. package/dist/components/core/Toast/Toast.types.d.ts +1 -1
  181. package/dist/components/core/Toast/useToast.js +5 -5
  182. package/dist/components/core/Tooltip/Tooltip.d.ts +1 -1
  183. package/dist/components/core/Tooltip/Tooltip.js +42 -10
  184. package/dist/components/core/Tooltip/Tooltip.types.d.ts +25 -0
  185. package/dist/components/core/Tree/Tree.js +2 -2
  186. package/dist/components/core/shared/interaction.animations.d.ts +51 -0
  187. package/dist/components/core/shared/interaction.animations.js +59 -0
  188. package/dist/components/data-display/Feed/Feed.js +2 -2
  189. package/dist/components/data-display/GanttChart/GanttChart.theme.js +1 -1
  190. package/dist/components/data-display/GanttChart/GanttChartPanel.js +2 -2
  191. package/dist/components/data-display/GanttChart/GanttTableGroupRow.js +3 -3
  192. package/dist/components/data-display/GanttChart/GanttTaskContextMenu.js +2 -2
  193. package/dist/components/data-display/GanttChart/GanttToolbar.js +2 -2
  194. package/dist/components/data-display/KPI/KPI.js +2 -2
  195. package/dist/components/data-display/KPI/KPI.theme.js +4 -4
  196. package/dist/components/data-display/Metric/Metric.js +2 -2
  197. package/dist/components/data-display/Metric/Metric.theme.js +25 -8
  198. package/dist/components/data-display/Metric/Metric.types.d.ts +1 -1
  199. package/dist/components/data-display/Table/Table.theme.js +9 -9
  200. package/dist/components/data-display/Table/TableActions.js +2 -2
  201. package/dist/components/data-display/Table/TableActionsMenu.js +1 -1
  202. package/dist/components/data-display/Table/TableColumnManager.js +2 -2
  203. package/dist/components/data-display/Table/TableDeclarative.js +3 -3
  204. package/dist/components/data-display/Table/TableFilter.js +4 -4
  205. package/dist/components/data-display/Table/TableHeader.js +3 -3
  206. package/dist/components/data-display/Table/TableRow.js +2 -2
  207. package/dist/components/data-display/Table/TableSelectionHeader.js +3 -3
  208. package/dist/components/data-display/Timeline/TimelineMarker.js +2 -2
  209. package/dist/components/effects/CustomCursor/CustomCursor.js +2 -2
  210. package/dist/components/effects/CustomCursor/CustomCursor.theme.js +2 -2
  211. package/dist/components/effects/DotPattern/DotPattern.js +6 -0
  212. package/dist/components/effects/DotPattern/DotPattern.types.d.ts +4 -2
  213. package/dist/components/effects/MeshGradient/MeshGradient.utils.d.ts +1 -1
  214. package/dist/components/effects/MeshGradient/MeshGradient.utils.js +1 -1
  215. package/dist/components/forms/Checkbox/Checkbox.js +2 -1
  216. package/dist/components/forms/Checkbox/Checkbox.theme.js +2 -2
  217. package/dist/components/forms/ColorPicker/ColorPickerEyeDropper.js +2 -2
  218. package/dist/components/forms/ColorPicker/ColorPickerGradient.js +2 -2
  219. package/dist/components/forms/ColorPicker/ColorPickerHeader.js +2 -2
  220. package/dist/components/forms/ColorPicker/ColorPickerImage.js +3 -3
  221. package/dist/components/forms/ColorPicker/ColorPickerInput.js +2 -2
  222. package/dist/components/forms/ColorPicker/ColorPickerPresets.js +2 -2
  223. package/dist/components/forms/ColorPicker/ColorPickerSavedColors.js +2 -2
  224. package/dist/components/forms/Combobox/Combobox.js +3 -3
  225. package/dist/components/forms/Combobox/Combobox.theme.js +2 -2
  226. package/dist/components/forms/DatePicker/DatePicker.animations.js +16 -25
  227. package/dist/components/forms/DatePicker/DatePicker.theme.js +2 -2
  228. package/dist/components/forms/DatePicker/DatePickerBody.js +1 -1
  229. package/dist/components/forms/DatePicker/DatePickerTrigger.js +2 -2
  230. package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +3 -3
  231. package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +1 -1
  232. package/dist/components/forms/DateRangePicker/DateRangePickerPresets.js +2 -2
  233. package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +2 -2
  234. package/dist/components/forms/FileUpload/FileUpload.js +4 -4
  235. package/dist/components/forms/FileUpload/FileUpload.theme.js +5 -1
  236. package/dist/components/forms/FileUpload/FileUploadProgress.js +7 -7
  237. package/dist/components/forms/Input/Input.js +6 -7
  238. package/dist/components/forms/Input/Input.theme.js +19 -15
  239. package/dist/components/forms/InputAddress/InputAddress.js +10 -3
  240. package/dist/components/forms/InputCounter/InputCounter.js +3 -3
  241. package/dist/components/forms/InputOTP/InputOTP.d.ts +3 -12
  242. package/dist/components/forms/InputOTP/InputOTP.js +140 -151
  243. package/dist/components/forms/InputOTP/InputOTP.theme.d.ts +5 -1
  244. package/dist/components/forms/InputOTP/InputOTP.theme.js +40 -5
  245. package/dist/components/forms/InputOTP/InputOTP.types.d.ts +45 -2
  246. package/dist/components/forms/InputOTP/index.d.ts +1 -1
  247. package/dist/components/forms/InputTag/InputTag.js +5 -5
  248. package/dist/components/forms/InputTag/InputTag.theme.js +1 -2
  249. package/dist/components/forms/Mention/Mention.theme.js +3 -5
  250. package/dist/components/forms/Radio/Radio.js +3 -2
  251. package/dist/components/forms/Radio/Radio.theme.js +2 -2
  252. package/dist/components/forms/RichTextEditor/RichTextEditor.js +22 -23
  253. package/dist/components/forms/Select/Select.d.ts +5 -1
  254. package/dist/components/forms/Select/Select.js +12 -11
  255. package/dist/components/forms/Select/Select.theme.js +4 -4
  256. package/dist/components/forms/Select/Select.types.d.ts +4 -1
  257. package/dist/components/forms/SelectableCard/SelectableCard.animations.d.ts +1 -2
  258. package/dist/components/forms/SelectableCard/SelectableCard.animations.js +6 -7
  259. package/dist/components/forms/SelectableCard/SelectableCard.js +1 -1
  260. package/dist/components/forms/Signature/Signature.js +1 -1
  261. package/dist/components/forms/Slider/Slider.js +24 -11
  262. package/dist/components/forms/Slider/Slider.theme.js +9 -3
  263. package/dist/components/forms/Switch/Switch.theme.js +1 -1
  264. package/dist/components/forms/TimePicker/TimePicker.theme.js +6 -7
  265. package/dist/components/forms/TimePicker/TimePickerContent.js +1 -1
  266. package/dist/components/forms/TimePicker/TimePickerTrigger.js +3 -3
  267. package/dist/components/forms/forms.theme.js +23 -12
  268. package/dist/components/forms/index.js +1 -1
  269. package/dist/components/generative/registry.js +195 -2
  270. package/dist/components/generative/resolvers.js +16 -16
  271. package/dist/components/generative/schema.generated.js +2687 -379
  272. package/dist/components/layout/Section/Section.theme.js +1 -1
  273. package/dist/generative.schema.json +2687 -379
  274. package/dist/hooks/index.d.ts +2 -0
  275. package/dist/hooks/useElapsedTime.d.ts +28 -0
  276. package/dist/hooks/useElapsedTime.js +37 -0
  277. package/dist/hooks/useSelectPortal.d.ts +10 -2
  278. package/dist/hooks/useSelectPortal.js +6 -3
  279. package/dist/index.js +1 -1
  280. package/dist/registry.json +835 -261
  281. package/dist/shadcn-compat.css +1 -1
  282. package/dist/styles.css +1 -1
  283. package/dist/theme.css +5 -1
  284. package/dist/themes/ember.css +131 -0
  285. package/dist/themes/iris.css +94 -0
  286. package/dist/themes/jade.css +139 -0
  287. package/dist/tools.json +2705 -361
  288. package/dist/utils/colorUtils.d.ts +6 -6
  289. package/dist/utils/colorUtils.js +8 -8
  290. package/package.json +9 -6
  291. package/src/global.scss +15 -4
  292. package/src/styles/theme.css +440 -152
  293. package/tailwind.preset.cjs +52 -34
  294. package/dist/components/core/Pill/Pill.animations.d.ts +0 -32
  295. package/dist/components/core/Pill/Pill.animations.js +0 -16
@@ -13,8 +13,7 @@ import '../../core/Dropdown/DropdownSection.js';
13
13
  import '../../core/Dropdown/DropdownSeparator.js';
14
14
  import '../../core/Dropdown/Dropdown.theme.js';
15
15
  import { cn } from '../../../utils/cn.js';
16
- import { CloudArrowUpIcon, MicrophoneIcon, PaperClipIcon, LinkIcon, DocumentIcon, XMarkIcon, PlusIcon, AdjustmentsHorizontalIcon, ChevronDownIcon, ArrowRightIcon } from '@heroicons/react/24/outline';
17
- import { MicrophoneIcon as MicrophoneIcon$1, StopIcon } from '@heroicons/react/24/solid';
16
+ import { CloudArrowUp, Microphone, Paperclip, Link, File as File$1, X, Plus, SlidersHorizontal, CaretDown, ArrowRight, Stop } from '@phosphor-icons/react';
18
17
  import { promptInputTheme } from './PromptInput.theme.js';
19
18
  import { VoiceRecorder } from './VoiceRecorder.js';
20
19
  import { dropzoneContainerVariants, dropzoneChildVariants, dropzoneActionIconVariants, textareaSwapVariants, iconSwapVariants } from './PromptInput.animations.js';
@@ -70,7 +69,7 @@ attachments: controlledAttachments, onAttachmentsChange, acceptedFileTypes = ["i
70
69
  // Button visibility
71
70
  showAttachmentButton = true, showVoiceButton = true, showSettingsButton = true, showModelSelector = true,
72
71
  // Submit button
73
- submitButtonLabel = "Submit prompt", submitButtonIcon = (jsx(ArrowRightIcon, { className: "size-4", strokeWidth: 2.5 })), submitShortcut,
72
+ submitButtonLabel = "Submit prompt", submitButtonIcon = (jsx(ArrowRight, { className: "size-4", weight: "bold" })), submitShortcut,
74
73
  // Variant
75
74
  variant = "default",
76
75
  // Styling
@@ -508,7 +507,7 @@ className, textareaClassName, footerClassName, theme = {},
508
507
  */
509
508
  const renderSubmitButton = (buttonSize, buttonVariant, buttonColor, extraClassName) => {
510
509
  if (showStopButton) {
511
- return (jsx(Button, { iconOnly: true, className: cn(mergedTheme.submitButtonStyle, extraClassName), size: buttonSize, variant: buttonVariant, color: "danger", onClick: onStop, "aria-label": "Stop generation", title: "Stop generation", showReflection: false, children: jsx(AnimatePresence, { mode: "wait", initial: false, children: jsx(motion.span, { variants: iconSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex items-center justify-center", children: jsx(StopIcon, { className: "size-4" }) }, "stop") }) }));
510
+ return (jsx(Button, { iconOnly: true, className: cn(mergedTheme.submitButtonStyle, extraClassName), size: buttonSize, variant: buttonVariant, color: "danger", onClick: onStop, "aria-label": "Stop generation", title: "Stop generation", showReflection: false, children: jsx(AnimatePresence, { mode: "wait", initial: false, children: jsx(motion.span, { variants: iconSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex items-center justify-center", children: jsx(Stop, { className: "size-4" }) }, "stop") }) }));
512
511
  }
513
512
  return (jsx(Button, { iconOnly: true, className: cn(mergedTheme.submitButtonStyle, extraClassName), size: buttonSize, variant: buttonVariant, color: buttonColor, onClick: handleSubmit, disabled: !canSubmit, state: isLoading ? "loading" : "default", "aria-label": submitButtonLabel, title: submitShortcut ? `Submit (${submitShortcut})` : undefined, showReflection: buttonVariant === "filled" ? false : undefined, children: jsx(AnimatePresence, { mode: "wait", initial: false, children: jsx(motion.span, { variants: iconSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex items-center justify-center", children: submitButtonIcon }, "submit") }) }));
514
513
  };
@@ -517,24 +516,24 @@ className, textareaClassName, footerClassName, theme = {},
517
516
  if (e.target.files)
518
517
  processFiles(e.target.files);
519
518
  e.target.value = "";
520
- }, className: "sr-only", "aria-label": "Attach files" }), jsxs("div", { className: cn("relative", mergedTheme.baseStyle, mergedTheme.stateStyle, variant === "simple" ? "p-3 rounded-full pl-5" : ""), onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [jsx(AnimatePresence, { children: isDragOver && enableDropzone && (jsxs(motion.div, { variants: dropzoneContainerVariants, initial: "initial", animate: "animate", exit: "exit", className: mergedTheme.dropzoneStyle, children: [jsx(motion.div, { variants: dropzoneChildVariants, children: jsx(CloudArrowUpIcon, { className: "size-8 text-[var(--color-primary)] mx-auto" }) }), jsx(motion.p, { variants: dropzoneChildVariants, className: mergedTheme.dropzoneTitleStyle, children: dropzoneTitle ? (
519
+ }, className: "sr-only", "aria-label": "Attach files" }), jsxs("div", { className: cn("relative", mergedTheme.baseStyle, mergedTheme.stateStyle, variant === "simple" ? "p-3 rounded-full pl-5" : ""), onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [jsx(AnimatePresence, { children: isDragOver && enableDropzone && (jsxs(motion.div, { variants: dropzoneContainerVariants, initial: "initial", animate: "animate", exit: "exit", className: mergedTheme.dropzoneStyle, children: [jsx(motion.div, { variants: dropzoneChildVariants, children: jsx(CloudArrowUp, { className: "size-8 text-[var(--color-primary)] mx-auto" }) }), jsx(motion.p, { variants: dropzoneChildVariants, className: mergedTheme.dropzoneTitleStyle, children: dropzoneTitle ? (
521
520
  // Parse **browse** as clickable button
522
521
  jsx(Fragment, { children: resolvedDropzoneTitle
523
522
  .split(/\*\*(.*?)\*\*/)
524
523
  .map((part, i) => i % 2 === 1 ? (jsx("button", { type: "button", onClick: handleDropzoneBrowse, className: "font-bold underline underline-offset-2 cursor-pointer hover:opacity-80", children: part }, i)) : (jsx("span", { children: part }, i))) })) : (resolvedDropzoneTitle) }), dropzoneSubtitle && (jsx(motion.p, { variants: dropzoneChildVariants, className: mergedTheme.dropzoneSubtitleStyle, children: dropzoneSubtitle })), dropzoneTitle && (jsx(motion.div, { variants: dropzoneChildVariants, className: mergedTheme.dropzoneActionsStyle, children: [
525
- CloudArrowUpIcon,
526
- MicrophoneIcon,
527
- PaperClipIcon,
528
- LinkIcon,
524
+ CloudArrowUp,
525
+ Microphone,
526
+ Paperclip,
527
+ Link,
529
528
  ].map((Icon, i) => (jsx(motion.div, { variants: dropzoneActionIconVariants, className: "size-8 rounded-full bg-white/30 dark:bg-white/10 flex items-center justify-center", children: jsx(Icon, { className: "size-4 text-[var(--color-primary)]" }) }, i))) }))] })) }), currentAttachments.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 py-2 px-1", children: currentAttachments.map((attachment) => {
530
529
  var _a;
531
- return (jsxs("div", { className: "relative group rounded-lg border border-[var(--color-border)] bg-white", children: [attachment.type === "image" ? (attachment.isCompressing ? (jsx("div", { className: "size-12 flex items-center justify-center bg-gray-100 rounded-lg", children: jsx("div", { className: "w-4 h-4 border-2 border-gray-300 border-t-[var(--color-primary)] rounded-full animate-spin" }) })) : (jsx("img", { src: attachment.previewUrl, alt: attachment.file.name, className: "size-12 object-cover rounded-lg" }))) : (jsxs("div", { className: "size-12 flex flex-col items-center justify-center text-center p-1 rounded-lg", children: [jsx(DocumentIcon, { className: "w-5 h-5 text-[var(--color-text-muted)]" }), jsx("span", { className: "text-[10px] text-[var(--color-text-secondary)] truncate w-full", children: (_a = attachment.file.name.split(".").pop()) === null || _a === void 0 ? void 0 : _a.toUpperCase() })] })), jsx("button", { onClick: () => removeAttachment(attachment.id), className: "absolute -top-1.5 -right-1.5 size-5 rounded-full bg-[var(--color-danger)] text-[var(--color-danger-contrast)] flex items-center justify-center opacity-0 translate-y-1 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300 ease-in-out cursor-pointer shadow-md", "aria-label": `Remove ${attachment.file.name}`, children: jsx(XMarkIcon, { className: "size-3", strokeWidth: 3 }) })] }, attachment.id));
530
+ return (jsxs("div", { className: "relative group rounded-lg border border-[var(--color-border)] bg-white", children: [attachment.type === "image" ? (attachment.isCompressing ? (jsx("div", { className: "size-12 flex items-center justify-center bg-gray-100 rounded-lg", children: jsx("div", { className: "w-4 h-4 border-2 border-gray-300 border-t-[var(--color-primary)] rounded-full animate-spin" }) })) : (jsx("img", { src: attachment.previewUrl, alt: attachment.file.name, className: "size-12 object-cover rounded-lg" }))) : (jsxs("div", { className: "size-12 flex flex-col items-center justify-center text-center p-1 rounded-lg", children: [jsx(File$1, { className: "w-5 h-5 text-[var(--color-text-muted)]" }), jsx("span", { className: "text-[10px] text-[var(--color-text-secondary)] truncate w-full", children: (_a = attachment.file.name.split(".").pop()) === null || _a === void 0 ? void 0 : _a.toUpperCase() })] })), jsx("button", { onClick: () => removeAttachment(attachment.id), className: "absolute -top-1.5 -right-1.5 size-5 rounded-full bg-[var(--color-danger)] text-[var(--color-danger-contrast)] flex items-center justify-center opacity-0 translate-y-1 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300 ease-in-out cursor-pointer shadow-md", "aria-label": `Remove ${attachment.file.name}`, children: jsx(X, { className: "size-3", weight: "bold" }) })] }, attachment.id));
532
531
  }) })), jsxs("div", { className: cn("flex gap-2", variant === "simple" ? "items-end" : "items-start"), children: [jsx(AnimatePresence, { mode: "wait", initial: false, children: isRecording && enableVoiceRecording ? (jsx(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex-1 min-w-0", children: jsx("p", { className: "text-center text-sm text-[var(--color-text-placeholder)]", children: placeholder }) }, "voice-recorder")) : (jsx(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: cn("flex-1 min-w-0", variant === "simple" && "flex items-end"), children: jsx(Textarea, { ref: textareaRef, id: id, unstyled: true, value: currentValue, onChange: handleChange, onKeyDown: handleKeyDown, onPaste: handlePaste, placeholder: placeholder, disabled: isDisabled, maxLength: maxLength, rows: rows, "aria-label": ariaLabel || "Prompt input", "aria-describedby": helperTextId, "aria-invalid": isInvalid, "aria-disabled": isDisabled, className: cn(mergedTheme.textareaStyle, variant === "simple" &&
533
532
  "!w-auto flex-1 min-w-0 justify-center", textareaClassName), style: {
534
533
  minHeight,
535
534
  maxHeight,
536
535
  } }) }, "textarea")) }), variant === "simple" &&
537
- renderSubmitButton("md", "filled", "neutral", "shrink-0")] }), variant !== "simple" && (jsx("div", { className: cn(mergedTheme.footerStyle, footerClassName), children: jsx(AnimatePresence, { mode: "wait", initial: false, children: isRecording && enableVoiceRecording ? (jsx(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "w-full", children: jsx(VoiceRecorder, { onComplete: handleRecordingComplete, onCancel: handleRecordingCancel, maxDuration: maxRecordingDuration, className: mergedTheme.voiceRecorderStyle }) }, "recorder-controls")) : (jsxs(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex justify-between items-end w-full", children: [jsxs("div", { className: mergedTheme.actionsStyle, children: [showAttachmentButton && (jsxs(Dropdown, { selectionMode: "none", children: [jsx(Dropdown.Trigger, { children: jsx(Button, { iconOnly: true, variant: "outline", color: "neutral", size: "sm", className: "rounded-full !border-0.5", "aria-label": "Add attachment", disabled: isDisabled, children: jsx(PlusIcon, { className: "size-4", strokeWidth: 2 }) }) }), jsxs(Dropdown.Menu, { children: [jsx(Dropdown.Item, { itemKey: "upload-image", onAction: () => {
536
+ renderSubmitButton("md", "filled", "mono", "shrink-0")] }), variant !== "simple" && (jsx("div", { className: cn(mergedTheme.footerStyle, footerClassName), children: jsx(AnimatePresence, { mode: "wait", initial: false, children: isRecording && enableVoiceRecording ? (jsx(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "w-full", children: jsx(VoiceRecorder, { onComplete: handleRecordingComplete, onCancel: handleRecordingCancel, maxDuration: maxRecordingDuration, className: mergedTheme.voiceRecorderStyle }) }, "recorder-controls")) : (jsxs(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex justify-between items-end w-full", children: [jsxs("div", { className: mergedTheme.actionsStyle, children: [showAttachmentButton && (jsxs(Dropdown, { selectionMode: "none", children: [jsx(Dropdown.Trigger, { children: jsx(Button, { iconOnly: true, variant: "outline", color: "mono", size: "sm", className: "rounded-full !border-0.5", "aria-label": "Add attachment", disabled: isDisabled, children: jsx(Plus, { className: "size-4", weight: "bold" }) }) }), jsxs(Dropdown.Menu, { children: [jsx(Dropdown.Item, { itemKey: "upload-image", onAction: () => {
538
537
  // Set accept to images only and trigger file input
539
538
  if (fileInputRef.current) {
540
539
  fileInputRef.current.accept = "image/*";
@@ -553,12 +552,12 @@ className, textareaClassName, footerClassName, theme = {},
553
552
  fileInputRef.current.click();
554
553
  }
555
554
  onAttachmentClick === null || onAttachmentClick === void 0 ? void 0 : onAttachmentClick();
556
- }, children: "Upload PDF" }, "upload-pdf")] })] })), showSettingsButton && (jsx(Button, { iconOnly: true, variant: "outline", color: "neutral", size: "sm", className: "rounded-full !border-0.5", onClick: onSettingsClick, "aria-label": "Open settings", disabled: isDisabled, children: jsx(AdjustmentsHorizontalIcon, { className: "size-4 text-[var(--color-text-muted)]", strokeWidth: 2 }) })), showVoiceButton && (jsxs(Button, { variant: "outline", color: "neutral", size: "sm", className: "rounded-full border-0 hover:bg-[var(--color-surface-hover)] dark:hover:bg-[var(--color-surface-hover)] text-[var(--color-text-secondary)]", onClick: handleVoiceClick, "aria-label": "Voice input", disabled: isDisabled || isRecording, children: [jsx(MicrophoneIcon$1, { className: "size-4" }), "Voice"] })), showModelSelector && (jsxs(Dropdown, { selectionMode: "single", selectedKeys: isModelControlled
555
+ }, children: "Upload PDF" }, "upload-pdf")] })] })), showSettingsButton && (jsx(Button, { iconOnly: true, variant: "outline", color: "mono", size: "sm", className: "rounded-full !border-0.5", onClick: onSettingsClick, "aria-label": "Open settings", disabled: isDisabled, children: jsx(SlidersHorizontal, { className: "size-4 text-[var(--color-text-muted)]", weight: "bold" }) })), showVoiceButton && (jsxs(Button, { variant: "outline", color: "mono", size: "sm", className: "rounded-full border-0 hover:bg-[var(--color-surface-hover)] dark:hover:bg-[var(--color-surface-hover)] text-[var(--color-text-secondary)]", onClick: handleVoiceClick, "aria-label": "Voice input", disabled: isDisabled || isRecording, children: [jsx(Microphone, { className: "size-4" }), "Voice"] })), showModelSelector && (jsxs(Dropdown, { selectionMode: "single", selectedKeys: isModelControlled
557
556
  ? [controlledModel]
558
- : internalModel, onSelectionChange: handleModelChange, children: [jsx(Dropdown.Trigger, { children: jsxs(Button, { variant: "outline", color: "neutral", size: "sm",
557
+ : internalModel, onSelectionChange: handleModelChange, children: [jsx(Dropdown.Trigger, { children: jsxs(Button, { variant: "outline", color: "mono", size: "sm",
559
558
  // Hover + open active state now come from Dropdown.Trigger
560
559
  // (unified surface-hover tint). `group` stays for the chevron flip.
561
- className: "group bg-transparent rounded-full border-0 font-medium text-[var(--color-text-secondary)]", "aria-label": "Select AI model", disabled: isDisabled, children: [modelMap[currentModel] || "Select Model", jsx(ChevronDownIcon, { className: "size-3 opacity-80 transition-transform duration-200 group-aria-[expanded=true]:rotate-180", strokeWidth: 2 })] }) }), jsx(Dropdown.Menu, { children: models.map((model) => (jsxs(Dropdown.Item, { itemKey: model.key, children: [model.icon && (jsx("span", { className: "mr-2", children: model.icon })), model.label] }, model.key))) })] }))] }), jsx("div", { children: renderSubmitButton("sm", "outline", "neutral") })] }, "footer-controls")) }) }))] }), displayHelperText && (jsx("div", { id: helperTextId, className: cn("mt-1 text-sm", isInvalid
560
+ className: "group bg-transparent rounded-full border-0 font-medium text-[var(--color-text-secondary)]", "aria-label": "Select AI model", disabled: isDisabled, children: [modelMap[currentModel] || "Select Model", jsx(CaretDown, { className: "size-3 opacity-80 transition-transform duration-200 group-aria-[expanded=true]:rotate-180", weight: "bold" })] }) }), jsx(Dropdown.Menu, { children: models.map((model) => (jsx(Dropdown.Item, { itemKey: model.key, startContent: model.icon, children: model.label }, model.key))) })] }))] }), jsx("div", { children: renderSubmitButton("sm", "outline", "mono") })] }, "footer-controls")) }) }))] }), displayHelperText && (jsx("div", { id: helperTextId, className: cn("mt-1 text-sm", isInvalid
562
561
  ? "text-[var(--color-danger)]"
563
562
  : "text-[var(--color-text-muted)]"), role: isInvalid ? "alert" : undefined, "aria-live": isInvalid ? "polite" : undefined, children: displayHelperText }))] }));
564
563
  });
@@ -26,7 +26,7 @@ const promptInputTheme = {
26
26
  // Inset danger edge + fill (mirrors the resting/focus border model above) so invalid
27
27
  // composes over baseStyle instead of stacking a second real border on the hairline.
28
28
  invalid: "shadow-[inset_0_0_0_1px_var(--color-danger)] bg-[var(--color-danger-50)] " +
29
- "focus-within:shadow-[inset_0_0_0_1px_var(--color-danger)] focus-within:ring-[var(--color-danger-500)]/10 " +
29
+ "focus-within:shadow-[inset_0_0_0_1px_var(--color-danger)] focus-within:ring-[var(--color-danger)]/10 " +
30
30
  "not-focus-within:hover:shadow-[inset_0_0_0_1px_var(--color-danger)] " +
31
31
  "dark:bg-[var(--color-danger-950)]/30 dark:shadow-[inset_0_0_0_1px_var(--color-danger-500)] " +
32
32
  "dark:focus-within:ring-[var(--color-danger-500)]/20",
@@ -2,7 +2,7 @@
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { useState, useRef, useEffect, useCallback } from 'react';
4
4
  import { motion } from 'motion/react';
5
- import { PlayIcon, PauseIcon, CheckIcon } from '@heroicons/react/24/outline';
5
+ import { Play, Pause, Check } from '@phosphor-icons/react';
6
6
  import { cn } from '../../../utils/cn.js';
7
7
  import { Button } from '../../core/Button/Button.js';
8
8
 
@@ -315,13 +315,13 @@ const VoiceRecorder = ({ onComplete, onCancel, maxDuration, className, }) => {
315
315
  }
316
316
  }
317
317
  }, [recordingState, clearTimer, startTimer]);
318
- return (jsxs("div", { className: cn("flex items-center justify-between w-full", className), children: [jsx(Button, { variant: "soft", color: "neutral", size: "sm", className: "rounded-full", onClick: handleCancel, "aria-label": "Cancel recording", children: "Cancel" }), jsxs("div", { className: "flex items-center gap-4", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx(motion.div, { className: "size-2 rounded-full bg-[var(--color-danger)]", animate: recordingState === "recording"
318
+ return (jsxs("div", { className: cn("flex items-center justify-between w-full", className), children: [jsx(Button, { variant: "soft", color: "mono", size: "sm", className: "rounded-full", onClick: handleCancel, "aria-label": "Cancel recording", children: "Cancel" }), jsxs("div", { className: "flex items-center gap-4", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx(motion.div, { className: "size-2 rounded-full bg-[var(--color-danger)]", animate: recordingState === "recording"
319
319
  ? { scale: [1, 1.4, 1] }
320
320
  : undefined, transition: {
321
321
  duration: 1.5,
322
322
  repeat: Infinity,
323
323
  ease: "easeInOut",
324
- } }), jsx("span", { className: "text-sm font-medium tabular-nums text-[var(--color-text-primary)] min-w-[2.5rem] text-center", children: formatTime(elapsed) })] }), jsx("canvas", { ref: canvasRef, width: 128, height: 32, className: "w-32 h-8 bg-transparent" })] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button, { iconOnly: true, variant: "outline", color: "neutral", size: "sm", className: "rounded-full", onClick: handleTogglePause, "aria-label": recordingState === "paused" ? "Resume recording" : "Pause recording", children: recordingState === "paused" ? (jsx(PlayIcon, { className: "size-4", strokeWidth: 2 })) : (jsx(PauseIcon, { className: "size-4", strokeWidth: 2 })) }), jsx(Button, { iconOnly: true, variant: "filled", color: "primary", size: "sm", className: "rounded-full", onClick: handleConfirm, "aria-label": "Confirm recording", children: jsx(CheckIcon, { className: "size-4", strokeWidth: 2.5 }) })] })] }));
324
+ } }), jsx("span", { className: "text-sm font-medium tabular-nums text-[var(--color-text-primary)] min-w-[2.5rem] text-center", children: formatTime(elapsed) })] }), jsx("canvas", { ref: canvasRef, width: 128, height: 32, className: "w-32 h-8 bg-transparent" })] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button, { iconOnly: true, variant: "outline", color: "mono", size: "sm", className: "rounded-full", onClick: handleTogglePause, "aria-label": recordingState === "paused" ? "Resume recording" : "Pause recording", children: recordingState === "paused" ? (jsx(Play, { className: "size-4", weight: "bold" })) : (jsx(Pause, { className: "size-4", weight: "bold" })) }), jsx(Button, { iconOnly: true, variant: "filled", color: "primary", size: "sm", className: "rounded-full", onClick: handleConfirm, "aria-label": "Confirm recording", children: jsx(Check, { className: "size-4", weight: "bold" }) })] })] }));
325
325
  };
326
326
  VoiceRecorder.displayName = "VoiceRecorder";
327
327
 
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ import type { ReasoningProps, ReasoningStepProps } from "./Reasoning.types";
3
+ export declare const Reasoning: React.ForwardRefExoticComponent<ReasoningProps & React.RefAttributes<HTMLDivElement>> & {
4
+ Step: React.ForwardRefExoticComponent<ReasoningStepProps & React.RefAttributes<HTMLDivElement>>;
5
+ };
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import React__default from 'react';
4
+ import { AgentStatus } from '../AgentStatus/AgentStatus.js';
5
+
6
+ // Reasoning is AgentStatus in its reasoning mode, with a discoverable name.
7
+ const ReasoningRoot = React__default.forwardRef((props, ref) => jsx(AgentStatus, { ref: ref, mode: "reasoning", ...props }));
8
+ ReasoningRoot.displayName = "Reasoning";
9
+ // A step is just a status row; children carry its text.
10
+ const ReasoningStep = React__default.forwardRef(({ children, status = "complete", ...rest }, ref) => (jsx(AgentStatus, { ref: ref, mode: "status", status: status, label: children, wrap: true, live: "off", ...rest })));
11
+ ReasoningStep.displayName = "Reasoning.Step";
12
+ const Reasoning = Object.assign(ReasoningRoot, {
13
+ Step: ReasoningStep,
14
+ });
15
+
16
+ export { Reasoning };
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import type { AgentStatusProps, AgentStatusState, AgentStatusStepData, AgentStatusThemeOverrides } from "../AgentStatus";
3
+ /**
4
+ * Reasoning is a preset of AgentStatus fixed to `mode="reasoning"` — the
5
+ * collapsible "show the AI's thinking" disclosure. Every AgentStatus prop
6
+ * except `mode` applies.
7
+ */
8
+ export type ReasoningProps = Omit<AgentStatusProps, "mode">;
9
+ /** A structured reasoning step (an AgentStatus row). */
10
+ export type ReasoningStepData = AgentStatusStepData;
11
+ export type ReasoningThemeOverrides = AgentStatusThemeOverrides;
12
+ export interface ReasoningStepProps {
13
+ /** Step state — drives the indicator glyph. @default "complete" */
14
+ status?: AgentStatusState;
15
+ /** Step text. */
16
+ children: React.ReactNode;
17
+ /** Elapsed or final step duration in seconds. */
18
+ duration?: number;
19
+ className?: string;
20
+ }
@@ -0,0 +1,2 @@
1
+ export { Reasoning } from "./Reasoning";
2
+ export type { ReasoningProps, ReasoningStepProps, ReasoningStepData, ReasoningThemeOverrides, } from "./Reasoning.types";
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ import type { SourceCitationGroupProps, SourceCitationProps } from "./SourceCitation.types";
3
+ export declare const SourceCitation: React.ForwardRefExoticComponent<SourceCitationProps & React.RefAttributes<HTMLButtonElement>>;
4
+ export declare const SourceCitationGroup: React.ForwardRefExoticComponent<SourceCitationGroupProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
+ import React__default, { useMemo } from 'react';
4
+ import { Link, ArrowSquareOut } from '@phosphor-icons/react';
5
+ import { cn } from '../../../utils/cn.js';
6
+ import { Link as Link$1 } from '../../core/Link/Link.js';
7
+ import { Popover } from '../../core/Popover/Popover.js';
8
+ import '../../core/Popover/PopoverContext.js';
9
+ import '../../core/Popover/PopoverBody.js';
10
+ import { sourceCitationTheme } from './SourceCitation.theme.js';
11
+
12
+ const SourceCitation = React__default.forwardRef(({ index, title, domain, excerpt, href, icon, preview, placement = "top-start", open, defaultOpen, onOpenChange, openInNewTab = true, linkLabel = "Open source", className, theme: themeOverrides, disabled, ...props }, ref) => {
13
+ const theme = useMemo(() => ({ ...sourceCitationTheme, ...themeOverrides }), [themeOverrides]);
14
+ // `title` and `domain` are both ReactNode, so neither is guaranteed to yield a
15
+ // usable name. Fall back through the domain (already the visible chip text) before
16
+ // the generic word, so rich-titled citations stay distinguishable by ear.
17
+ const label = (typeof title === "string" && title) ||
18
+ (typeof domain === "string" && domain) ||
19
+ "source";
20
+ return (jsxs(Popover, { placement: placement, isOpen: open, defaultIsOpen: defaultOpen, onOpenChange: onOpenChange, children: [jsx(Popover.Trigger, { children: jsxs("button", { ref: ref, type: "button", className: cn(theme.triggerStyle, className), "aria-label": `View source: ${label}`, disabled: disabled, ...props, children: [icon ? (jsx("span", { className: theme.faviconStyle, "aria-hidden": "true", children: icon })) : (index !== undefined && (jsx("span", { className: theme.indexStyle, children: index }))), jsx("span", { className: theme.domainStyle, children: domain !== null && domain !== void 0 ? domain : title })] }) }), jsx(Popover.Body, { className: theme.popoverStyle, children: preview !== null && preview !== void 0 ? preview : (jsxs(Fragment, { children: [jsxs("div", { className: theme.previewHeaderStyle, children: [jsx("span", { className: theme.previewIconStyle, "aria-hidden": "true", children: icon !== null && icon !== void 0 ? icon : jsx(Link, { className: "size-4" }) }), jsxs("div", { className: "min-w-0", children: [jsx("div", { className: theme.previewTitleStyle, children: title }), domain && (jsx("div", { className: theme.previewDomainStyle, children: domain }))] })] }), excerpt && jsx("div", { className: theme.excerptStyle, children: excerpt }), href && (jsxs(Link$1, { href: href, target: openInNewTab ? "_blank" : undefined, rel: openInNewTab ? "noopener noreferrer" : undefined, className: theme.linkStyle, children: [linkLabel, jsx(ArrowSquareOut, { className: "size-3.5", "aria-hidden": "true", weight: "bold" })] }))] })) })] }));
21
+ });
22
+ SourceCitation.displayName = "SourceCitation";
23
+ const SourceCitationGroup = React__default.forwardRef(({ children, className, theme: themeOverrides, ...props }, ref) => {
24
+ var _a;
25
+ return (jsx("div", { ref: ref, role: "group", "aria-label": "Sources", className: cn((_a = themeOverrides === null || themeOverrides === void 0 ? void 0 : themeOverrides.groupStyle) !== null && _a !== void 0 ? _a : sourceCitationTheme.groupStyle, className), ...props, children: children }));
26
+ });
27
+ SourceCitationGroup.displayName = "SourceCitation.Group";
28
+
29
+ export { SourceCitation, SourceCitationGroup };
@@ -0,0 +1,2 @@
1
+ import type { SourceCitationTheme } from "./SourceCitation.types";
2
+ export declare const sourceCitationTheme: SourceCitationTheme;
@@ -0,0 +1,23 @@
1
+ const sourceCitationTheme = {
2
+ // Asymmetric padding: the round leading token provides its own visual inset,
3
+ // so the left padding is tighter than the right where the domain text sits.
4
+ triggerStyle: "inline-flex max-w-52 cursor-pointer items-center gap-1.5 rounded-full border border-[var(--color-border)] bg-[var(--color-surface)] py-0.5 pl-0.5 pr-2.5 text-xs font-medium text-[var(--color-text-secondary)] transition-colors hover:border-[var(--color-border-hover)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)]",
5
+ // Quiet numbered token — a recessed well with a hairline, not a loud filled disc.
6
+ indexStyle: "flex size-[1.125rem] shrink-0 items-center justify-center rounded-full bg-[var(--color-surface-sunken)] text-[10px] font-semibold tabular-nums text-[var(--color-text-secondary)] ring-1 ring-inset ring-[var(--color-border)]",
7
+ // Favicon well (shown instead of the number when an icon is supplied).
8
+ faviconStyle: "flex size-[1.125rem] shrink-0 items-center justify-center overflow-hidden rounded-full bg-[var(--color-surface-sunken)] ring-1 ring-inset ring-[var(--color-border)] [&>img]:size-full [&>img]:object-cover [&>svg]:size-3",
9
+ domainStyle: "truncate",
10
+ popoverStyle: "w-80 space-y-3",
11
+ previewHeaderStyle: "flex items-start gap-2.5",
12
+ previewIconStyle: "flex size-10 shrink-0 items-center justify-center rounded-lg bg-[var(--color-surface-sunken)] text-[var(--color-text-muted)]",
13
+ previewTitleStyle: "line-clamp-2 text-sm font-semibold text-[var(--color-text-primary)]",
14
+ previewDomainStyle: "mt-0.5 truncate text-xs text-[var(--color-text-muted)]",
15
+ excerptStyle: "line-clamp-4 text-sm leading-5 text-[var(--color-text-secondary)]",
16
+ // Link's own base already provides layout (inline-flex/items-center/gap),
17
+ // color, hover underline, and focus-visible ring — only the size-specific
18
+ // bits need overriding here.
19
+ linkStyle: "text-xs font-medium",
20
+ groupStyle: "inline-flex flex-wrap items-center gap-1.5",
21
+ };
22
+
23
+ export { sourceCitationTheme };
@@ -0,0 +1,55 @@
1
+ import React from "react";
2
+ import type { PopoverPlacement } from "../../core/Popover";
3
+ export interface SourceCitationTheme {
4
+ triggerStyle: string;
5
+ indexStyle: string;
6
+ faviconStyle: string;
7
+ domainStyle: string;
8
+ popoverStyle: string;
9
+ previewHeaderStyle: string;
10
+ previewIconStyle: string;
11
+ previewTitleStyle: string;
12
+ previewDomainStyle: string;
13
+ excerptStyle: string;
14
+ linkStyle: string;
15
+ groupStyle: string;
16
+ }
17
+ export type SourceCitationThemeOverrides = Partial<SourceCitationTheme>;
18
+ export interface SourceCitationProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children" | "title"> {
19
+ /** Citation number or compact identifier displayed in the chip. */
20
+ index?: React.ReactNode;
21
+ /** Source title displayed in the preview. */
22
+ title: React.ReactNode;
23
+ /** Source domain displayed in both the chip and preview. */
24
+ domain?: React.ReactNode;
25
+ /** Supporting source excerpt. */
26
+ excerpt?: React.ReactNode;
27
+ /** Destination URL. */
28
+ href?: string;
29
+ /** Optional source or favicon icon. */
30
+ icon?: React.ReactNode;
31
+ /** Fully custom preview content. */
32
+ preview?: React.ReactNode;
33
+ /** Popover placement relative to the citation chip. */
34
+ placement?: PopoverPlacement;
35
+ /** Controlled popover state. */
36
+ open?: boolean;
37
+ /** Initial popover state for uncontrolled usage. */
38
+ defaultOpen?: boolean;
39
+ onOpenChange?: (open: boolean) => void;
40
+ /** Open the source link in a new tab. @default true */
41
+ openInNewTab?: boolean;
42
+ /**
43
+ * Label for the link at the foot of the preview. Overridable so the string is
44
+ * not trapped in English.
45
+ * @default "Open source"
46
+ */
47
+ linkLabel?: React.ReactNode;
48
+ className?: string;
49
+ theme?: SourceCitationThemeOverrides;
50
+ }
51
+ export interface SourceCitationGroupProps extends React.HTMLAttributes<HTMLDivElement> {
52
+ children: React.ReactNode;
53
+ className?: string;
54
+ theme?: Pick<SourceCitationThemeOverrides, "groupStyle">;
55
+ }
@@ -0,0 +1,3 @@
1
+ export { SourceCitation, SourceCitationGroup } from "./SourceCitation";
2
+ export { sourceCitationTheme } from "./SourceCitation.theme";
3
+ export type { SourceCitationProps, SourceCitationGroupProps, SourceCitationTheme, SourceCitationThemeOverrides, } from "./SourceCitation.types";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { ExclamationCircleIcon } from '@heroicons/react/24/outline';
3
+ import { WarningCircle } from '@phosphor-icons/react';
4
4
  import { cn } from '../../../utils/cn.js';
5
5
  import { streamingResponseTheme } from './StreamingResponse.theme.js';
6
6
 
@@ -29,7 +29,7 @@ const getErrorTitle = (type) => {
29
29
  */
30
30
  const ErrorDisplay = ({ error, onRetry, retryAttempt, maxAttempts, className, }) => {
31
31
  const canRetry = error.retryable && retryAttempt < maxAttempts;
32
- return (jsxs("div", { className: cn(streamingResponseTheme.errorContainerStyle, className), role: "alert", "aria-live": "assertive", children: [jsx(ExclamationCircleIcon, { className: "size-5 text-[var(--color-danger)] flex-shrink-0" }), jsxs("div", { className: "flex-1", children: [jsx("p", { className: cn(streamingResponseTheme.errorTitleStyle), children: getErrorTitle(error.type) }), jsx("p", { className: cn(streamingResponseTheme.errorMessageStyle), children: error.message }), canRetry && (jsxs("button", { onClick: onRetry, className: cn(streamingResponseTheme.errorRetryButtonStyle), type: "button", children: ["Retry (", retryAttempt + 1, "/", maxAttempts, ")"] }))] })] }));
32
+ return (jsxs("div", { className: cn(streamingResponseTheme.errorContainerStyle, className), role: "alert", "aria-live": "assertive", children: [jsx(WarningCircle, { className: "size-5 text-[var(--color-danger)] flex-shrink-0" }), jsxs("div", { className: "flex-1", children: [jsx("p", { className: cn(streamingResponseTheme.errorTitleStyle), children: getErrorTitle(error.type) }), jsx("p", { className: cn(streamingResponseTheme.errorMessageStyle), children: error.message }), canRetry && (jsxs("button", { onClick: onRetry, className: cn(streamingResponseTheme.errorRetryButtonStyle), type: "button", children: ["Retry (", retryAttempt + 1, "/", maxAttempts, ")"] }))] })] }));
33
33
  };
34
34
  ErrorDisplay.displayName = 'ErrorDisplay';
35
35
 
@@ -7,9 +7,7 @@ import { TypeWriter } from '../../core/Message/TypeWriter.js';
7
7
  import '../../core/Message/MessageBody.js';
8
8
  import '../../../utils/cn.js';
9
9
  import '../../core/Link/Link.js';
10
- import '@heroicons/react/16/solid';
11
- import '@heroicons/react/24/outline';
12
- import '@heroicons/react/24/solid';
10
+ import '@phosphor-icons/react';
13
11
  import { ErrorDisplay } from './ErrorDisplay.js';
14
12
  import { MarkdownRenderer } from './MarkdownRenderer.js';
15
13
  import { AnimatedText } from './AnimatedText.js';
@@ -1,5 +1,7 @@
1
1
  const streamingResponseTheme = {
2
- errorContainerStyle: "flex items-start gap-3 rounded-[var(--radius-base)] border border-[var(--color-danger-200)] bg-[var(--color-danger-50)] px-4 py-3",
2
+ // Danger banner same role as Alert, so it reuses --alert-radius rather
3
+ // than the bare --radius-base (which would be uncapped at extreme themes).
4
+ errorContainerStyle: "flex items-start gap-3 rounded-[var(--alert-radius)] border border-[var(--color-danger-200)] bg-[var(--color-danger-50)] px-4 py-3",
3
5
  errorTitleStyle: "text-sm font-medium text-[var(--color-danger)]",
4
6
  errorMessageStyle: "text-sm text-[var(--color-text-secondary)] mt-1",
5
7
  errorRetryButtonStyle: "mt-2 text-sm font-medium text-[var(--color-danger)] hover:text-[var(--color-danger-700)] transition-colors",
@@ -4,7 +4,7 @@ import React__default, { useMemo } from 'react';
4
4
  import { tokenCounterTheme } from './TokenCounter.theme.js';
5
5
  import { MODEL_CONFIGS, estimateTokens, calculateCost, formatTokenCount, formatCost } from './tokenUtils.js';
6
6
  import { cn } from '../../../utils/cn.js';
7
- import { CircleStackIcon } from '@heroicons/react/16/solid';
7
+ import { Database } from '@phosphor-icons/react';
8
8
 
9
9
  /**
10
10
  * TokenCounter - Real-time token usage display with cost estimation
@@ -55,7 +55,7 @@ const TokenCounter = React__default.forwardRef(({ text = "", tokens: providedTok
55
55
  const costStyle = customTheme.costStyle || tokenCounterTheme.costStyle;
56
56
  const progressStyle = customTheme.progressStyle || tokenCounterTheme.progressStyle;
57
57
  const progressBarStyle = customTheme.progressBarStyle || tokenCounterTheme.progressBarStyle;
58
- return (jsxs("div", { ref: ref, className: cn(baseStyle, sizeConfig.container, className), ...props, children: [icon || jsx(CircleStackIcon, { className: cn(iconStyle, sizeConfig.icon) }), jsx("span", { className: cn(countStyle, sizeConfig.text, isOverLimit && "text-[var(--color-danger)]"), children: formatTokenCount(tokenCount) }), maxTokens && format === "detailed" && (jsxs("span", { className: cn(labelStyle, sizeConfig.text), children: ["/ ", formatTokenCount(effectiveMaxTokens)] })), jsx("span", { className: cn(labelStyle, sizeConfig.text), children: "tokens" }), showCost && (jsxs("span", { className: cn(costStyle, sizeConfig.text), children: ["(", formatCost(cost), ")"] })), format === "detailed" && maxTokens && (jsx("div", { className: cn(progressStyle, "w-16 ml-2"), children: jsx("div", { className: cn(progressBarStyle, isOverLimit && "bg-[var(--color-danger)]"), style: { width: `${progressPercent}%` } }) }))] }));
58
+ return (jsxs("div", { ref: ref, className: cn(baseStyle, sizeConfig.container, className), ...props, children: [icon || jsx(Database, { className: cn(iconStyle, sizeConfig.icon) }), jsx("span", { className: cn(countStyle, sizeConfig.text, isOverLimit && "text-[var(--color-danger)]"), children: formatTokenCount(tokenCount) }), maxTokens && format === "detailed" && (jsxs("span", { className: cn(labelStyle, sizeConfig.text), children: ["/ ", formatTokenCount(effectiveMaxTokens)] })), jsx("span", { className: cn(labelStyle, sizeConfig.text), children: "tokens" }), showCost && (jsxs("span", { className: cn(costStyle, sizeConfig.text), children: ["(", formatCost(cost), ")"] })), format === "detailed" && maxTokens && (jsx("div", { className: cn(progressStyle, "w-16 ml-2"), children: jsx("div", { className: cn(progressBarStyle, isOverLimit && "bg-[var(--color-danger)]"), style: { width: `${progressPercent}%` } }) }))] }));
59
59
  });
60
60
  TokenCounter.displayName = "TokenCounter";
61
61
 
@@ -10,3 +10,6 @@ export { StreamingResponse, ErrorDisplay, MarkdownRenderer, AnimatedText, Stream
10
10
  export type { StreamingResponseProps, StreamingResponseTheme, MarkdownOptions, AnimatedTextProps, StreamingCursorProps, MarkdownRendererProps, } from "./StreamingResponse";
11
11
  export { CodeBlock, codeBlockTheme } from "./CodeBlock";
12
12
  export type { CodeBlockProps, CodeBlockLanguage, CodeBlockTheme, CodeBlockThemeOverrides, } from "./CodeBlock";
13
+ export * from "./AgentStatus";
14
+ export * from "./Reasoning";
15
+ export * from "./SourceCitation";
@@ -6,9 +6,7 @@ import 'react/jsx-runtime';
6
6
  import '../../utils/cn.js';
7
7
  import 'react';
8
8
  import '../core/Link/Link.js';
9
- import '@heroicons/react/16/solid';
10
- import '@heroicons/react/24/outline';
11
- import '@heroicons/react/24/solid';
9
+ import '@phosphor-icons/react';
12
10
  export { PromptInput } from './PromptInput/PromptInput.js';
13
11
  export { promptInputTheme } from './PromptInput/PromptInput.theme.js';
14
12
  export { TokenCounter } from './TokenCounter/TokenCounter.js';
@@ -26,3 +24,8 @@ export { streamingResponseTheme } from './StreamingResponse/StreamingResponse.th
26
24
  export { blockSlideIn, blockTransition, cursorPulse, staggerContainer, tokenFadeIn, tokenTransition } from './StreamingResponse/StreamingResponse.animations.js';
27
25
  export { CodeBlock } from './CodeBlock/CodeBlock.js';
28
26
  export { codeBlockTheme } from './CodeBlock/CodeBlock.theme.js';
27
+ export { AgentStatus } from './AgentStatus/AgentStatus.js';
28
+ export { agentStatusTheme } from './AgentStatus/AgentStatus.theme.js';
29
+ export { Reasoning } from './Reasoning/Reasoning.js';
30
+ export { SourceCitation, SourceCitationGroup } from './SourceCitation/SourceCitation.js';
31
+ export { sourceCitationTheme } from './SourceCitation/SourceCitation.theme.js';
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ export type AIStatusIndicatorState = "idle" | "active" | "complete" | "pending" | "error";
3
+ export interface AIStatusIndicatorProps extends Omit<React.SVGAttributes<SVGSVGElement>, "children"> {
4
+ state: AIStatusIndicatorState;
5
+ className?: string;
6
+ }
7
+ /** A rotating open arc that settles into a drawn semantic status glyph. */
8
+ export declare const AIStatusIndicator: React.ForwardRefExoticComponent<AIStatusIndicatorProps & React.RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,34 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import React__default from 'react';
4
+ import { useReducedMotion, AnimatePresence, motion } from 'motion/react';
5
+ import { cn } from '../../../utils/cn.js';
6
+
7
+ /** A rotating open arc that settles into a drawn semantic status glyph. */
8
+ const AIStatusIndicator = React__default.forwardRef(({ state, className, ...props }, ref) => {
9
+ const shouldReduceMotion = useReducedMotion();
10
+ const instant = shouldReduceMotion ? { duration: 0 } : undefined;
11
+ // Unique per instance: SVG gradient ids are document-global, so a shared id
12
+ // would let the first-mounted indicator's def win for every spinner on the page.
13
+ const gradientId = `${React__default.useId()}-arc`;
14
+ return (jsx("svg", { ref: ref, viewBox: "0 0 16 16", fill: "none", className: cn("size-4 overflow-visible", className), "data-ai-status-indicator": state, "aria-hidden": "true", ...props, children: jsxs(AnimatePresence, { initial: false, mode: "sync", children: [state === "active" && (jsx(motion.g, { initial: shouldReduceMotion ? false : { opacity: 0, scale: 0.7 }, animate: { opacity: 1, scale: 1 }, exit: shouldReduceMotion
15
+ ? { opacity: 0, transition: { duration: 0 } }
16
+ : {
17
+ opacity: 0,
18
+ scale: 0.55,
19
+ transition: { duration: 0.18, ease: "easeOut" },
20
+ }, transition: {
21
+ opacity: { duration: 0.16 },
22
+ scale: { duration: 0.2, ease: "easeOut" },
23
+ }, style: { transformBox: "view-box", transformOrigin: "8px 8px" }, children: jsxs("g", { className: "animate-spin motion-reduce:animate-none [transform-box:view-box] [transform-origin:center]", children: [jsx("defs", { children: jsxs("linearGradient", { id: gradientId, gradientUnits: "userSpaceOnUse", x1: "2.5", y1: "8", x2: "13.5", y2: "8", children: [jsx("stop", { offset: "0%", stopColor: "currentColor", stopOpacity: "1" }), jsx("stop", { offset: "55%", stopColor: "currentColor", stopOpacity: "1" }), jsx("stop", { offset: "100%", stopColor: "currentColor", stopOpacity: "0" })] }) }), jsx("circle", { cx: "8", cy: "8", r: "5.5", stroke: `url(#${gradientId})`, strokeWidth: "1.75", strokeLinecap: "round", strokeDasharray: "17.3 34.6" })] }) }, "active")), state === "complete" && (jsx(motion.path, { d: "M3.5 8.25 6.65 11.2 12.6 4.9", stroke: "currentColor", strokeWidth: "1.9", strokeLinecap: "round", strokeLinejoin: "round", initial: shouldReduceMotion
24
+ ? false
25
+ : { opacity: 0, pathLength: 0, scale: 0.7, rotate: -18 }, animate: { opacity: 1, pathLength: 1, scale: 1, rotate: 0 }, exit: { opacity: 0, scale: 0.7 }, transition: instant !== null && instant !== void 0 ? instant : {
26
+ opacity: { duration: 0.12 },
27
+ pathLength: { duration: 0.32, delay: 0.08, ease: "easeOut" },
28
+ scale: { type: "spring", stiffness: 420, damping: 24 },
29
+ rotate: { type: "spring", stiffness: 360, damping: 22 },
30
+ }, style: { transformOrigin: "8px 8px" } }, "complete")), state === "pending" && (jsx(motion.circle, { cx: "8", cy: "8", r: "4.5", stroke: "currentColor", strokeWidth: "1.4", initial: shouldReduceMotion ? false : { opacity: 0, scale: 0.7 }, animate: { opacity: 0.55, scale: 1 }, exit: { opacity: 0, scale: 0.7 }, transition: instant !== null && instant !== void 0 ? instant : { duration: 0.2 }, style: { transformOrigin: "8px 8px" } }, "pending")), state === "error" && (jsx(motion.path, { d: "M4.5 4.5 11.5 11.5 M11.5 4.5 4.5 11.5", stroke: "currentColor", strokeWidth: "1.7", strokeLinecap: "round", initial: shouldReduceMotion ? false : { opacity: 0, pathLength: 0 }, animate: { opacity: 1, pathLength: 1 }, exit: { opacity: 0, scale: 0.7 }, transition: instant !== null && instant !== void 0 ? instant : { duration: 0.24 } }, "error")), state === "idle" && (jsx(motion.circle, { cx: "8", cy: "8", r: "2.25", fill: "currentColor", initial: shouldReduceMotion ? false : { opacity: 0, scale: 0.6 }, animate: { opacity: 0.7, scale: 1 }, exit: { opacity: 0, scale: 0.6 }, transition: instant !== null && instant !== void 0 ? instant : { duration: 0.18 }, style: { transformOrigin: "8px 8px" } }, "idle"))] }) }));
31
+ });
32
+ AIStatusIndicator.displayName = "AIStatusIndicator";
33
+
34
+ export { AIStatusIndicator };
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
- import { CursorArrowRaysIcon, HandRaisedIcon, PlusIcon } from '@heroicons/react/24/outline';
3
+ import { CursorClick, Hand, Plus } from '@phosphor-icons/react';
4
4
  import { cn } from '../../utils/cn.js';
5
5
  import { Button } from '../core/Button/Button.js';
6
6
  import 'react';
@@ -28,7 +28,7 @@ const Divider = () => (jsx("span", { className: "mx-0.5 h-6 w-px bg-[var(--color
28
28
  function CanvasToolbar({ nodeOptions, onAddNode, showTools = true, position = "bottom", className, children, }) {
29
29
  const { tool, setTool } = useCanvasApi();
30
30
  const hasNodes = !!(nodeOptions === null || nodeOptions === void 0 ? void 0 : nodeOptions.length);
31
- return (jsxs("div", { "data-flikkui-nopan": "", className: cn("absolute z-30 flex items-center gap-1 rounded-full border border-[var(--color-border)] bg-[var(--color-surface-overlay)]/60 backdrop-blur-lg p-1 shadow-real-lg", POSITIONS[position], className), children: [showTools && (jsxs(Fragment, { children: [jsx(Button, { variant: tool === "select" ? "soft" : "ghost", color: "neutral", size: "sm", iconOnly: true, onClick: () => setTool("select"), "aria-label": "Select tool", "aria-pressed": tool === "select", className: cn("rounded-full", tool === "select" && "shadow-inner"), children: jsx(CursorArrowRaysIcon, { className: "size-4" }) }), jsx(Button, { variant: tool === "pan" ? "soft" : "ghost", color: "neutral", size: "sm", iconOnly: true, onClick: () => setTool("pan"), "aria-label": "Hand (pan) tool", "aria-pressed": tool === "pan", className: cn("rounded-full", tool === "pan" && "shadow-inner"), children: jsx(HandRaisedIcon, { className: "size-4" }) })] })), showTools && hasNodes && jsx(Divider, {}), hasNodes && (jsxs(Dropdown, { placement: "top", offset: 10, onAction: (type) => onAddNode === null || onAddNode === void 0 ? void 0 : onAddNode(type), children: [jsx(Dropdown.Trigger, { children: jsxs(Button, { variant: "ghost", color: "neutral", size: "sm", className: "rounded-full gap-1.5", children: [jsx(PlusIcon, { className: "size-4" }), "Add node"] }) }), jsx(Dropdown.Menu, { "aria-label": "Add node", children: nodeOptions === null || nodeOptions === void 0 ? void 0 : nodeOptions.map((opt) => (jsx(Dropdown.Item, { itemKey: opt.type, startContent: opt.icon && (jsx("span", { className: "size-4 grid place-items-center text-[var(--color-text-muted)]", children: opt.icon })), children: opt.label }, opt.type))) })] })), children && (jsxs(Fragment, { children: [(showTools || hasNodes) && jsx(Divider, {}), children] }))] }));
31
+ return (jsxs("div", { "data-flikkui-nopan": "", className: cn("absolute z-30 flex items-center gap-1 rounded-full border border-[var(--color-border)] bg-[var(--color-surface-overlay)]/60 backdrop-blur-lg p-1 shadow-real-lg", POSITIONS[position], className), children: [showTools && (jsxs(Fragment, { children: [jsx(Button, { variant: tool === "select" ? "soft" : "ghost", color: "mono", size: "sm", iconOnly: true, onClick: () => setTool("select"), "aria-label": "Select tool", "aria-pressed": tool === "select", className: cn("rounded-full", tool === "select" && "shadow-inner"), children: jsx(CursorClick, { className: "size-4" }) }), jsx(Button, { variant: tool === "pan" ? "soft" : "ghost", color: "mono", size: "sm", iconOnly: true, onClick: () => setTool("pan"), "aria-label": "Hand (pan) tool", "aria-pressed": tool === "pan", className: cn("rounded-full", tool === "pan" && "shadow-inner"), children: jsx(Hand, { className: "size-4" }) })] })), showTools && hasNodes && jsx(Divider, {}), hasNodes && (jsxs(Dropdown, { placement: "top", offset: 10, onAction: (type) => onAddNode === null || onAddNode === void 0 ? void 0 : onAddNode(type), children: [jsx(Dropdown.Trigger, { children: jsxs(Button, { variant: "ghost", color: "mono", size: "sm", className: "rounded-full gap-1.5", children: [jsx(Plus, { className: "size-4" }), "Add node"] }) }), jsx(Dropdown.Menu, { "aria-label": "Add node", children: nodeOptions === null || nodeOptions === void 0 ? void 0 : nodeOptions.map((opt) => (jsx(Dropdown.Item, { itemKey: opt.type, startContent: opt.icon && (jsx("span", { className: "size-4 grid place-items-center text-[var(--color-text-muted)]", children: opt.icon })), children: opt.label }, opt.type))) })] })), children && (jsxs(Fragment, { children: [(showTools || hasNodes) && jsx(Divider, {}), children] }))] }));
32
32
  }
33
33
  CanvasToolbar.displayName = "CanvasToolbar";
34
34
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
- import { PlusIcon, MinusIcon, ArrowsPointingOutIcon, LockClosedIcon, LockOpenIcon } from '@heroicons/react/24/outline';
3
+ import { Plus, Minus, ArrowsOutSimple, Lock, LockOpen } from '@phosphor-icons/react';
4
4
  import { cn } from '../../utils/cn.js';
5
5
  import { Button } from '../core/Button/Button.js';
6
6
  import 'react';
@@ -34,7 +34,7 @@ function NodeControls({ position = "bottom-right", showZoom = true, showFitView
34
34
  });
35
35
  };
36
36
  const ctrlBtn = "size-8 rounded-none";
37
- return (jsxs("div", { "data-flikkui-controls": "", className: cn("absolute z-20 flex flex-col overflow-hidden rounded-lg border border-[var(--color-border)] divide-y divide-[var(--color-border)] bg-[var(--color-surface-overlay)]/60 backdrop-blur-lg shadow-real-lg", POSITIONS[position], className), children: [showZoom && (jsxs(Fragment, { children: [jsx(Button, { variant: "ghost", color: "neutral", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => zoomBy(zoomStep), "aria-label": "Zoom in", children: jsx(PlusIcon, { className: "size-4" }) }), jsx(Button, { variant: "ghost", color: "neutral", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => zoomBy(1 / zoomStep), "aria-label": "Zoom out", children: jsx(MinusIcon, { className: "size-4" }) })] })), showFitView && (jsx(Button, { variant: "ghost", color: "neutral", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => fitView(), "aria-label": "Fit view", children: jsx(ArrowsPointingOutIcon, { className: "size-4" }) })), showLock && (jsx(Button, { variant: locked ? "soft" : "ghost", color: locked ? "primary" : "neutral", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => setLocked(!locked), "aria-label": locked ? "Unlock canvas" : "Lock canvas", "aria-pressed": locked, children: locked ? jsx(LockClosedIcon, { className: "size-4" }) : jsx(LockOpenIcon, { className: "size-4" }) }))] }));
37
+ return (jsxs("div", { "data-flikkui-controls": "", className: cn("absolute z-20 flex flex-col overflow-hidden rounded-lg border border-[var(--color-border)] divide-y divide-[var(--color-border)] bg-[var(--color-surface-overlay)]/60 backdrop-blur-lg shadow-real-lg", POSITIONS[position], className), children: [showZoom && (jsxs(Fragment, { children: [jsx(Button, { variant: "ghost", color: "mono", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => zoomBy(zoomStep), "aria-label": "Zoom in", children: jsx(Plus, { className: "size-4" }) }), jsx(Button, { variant: "ghost", color: "mono", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => zoomBy(1 / zoomStep), "aria-label": "Zoom out", children: jsx(Minus, { className: "size-4" }) })] })), showFitView && (jsx(Button, { variant: "ghost", color: "mono", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => fitView(), "aria-label": "Fit view", children: jsx(ArrowsOutSimple, { className: "size-4" }) })), showLock && (jsx(Button, { variant: locked ? "soft" : "ghost", color: locked ? "primary" : "mono", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => setLocked(!locked), "aria-label": locked ? "Unlock canvas" : "Lock canvas", "aria-pressed": locked, children: locked ? jsx(Lock, { className: "size-4" }) : jsx(LockOpen, { className: "size-4" }) }))] }));
38
38
  }
39
39
  NodeControls.displayName = "NodeControls";
40
40
 
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
3
  import React__default, { useCallback, useRef, useEffect } from 'react';
4
- import { PlusIcon } from '@heroicons/react/16/solid';
4
+ import { Plus } from '@phosphor-icons/react';
5
5
  import { cn } from '../../utils/cn.js';
6
6
  import { NodeIdProvider } from './context/NodeIdContext.js';
7
7
  import { useCanvasApi } from './context/CanvasContext.js';
@@ -79,7 +79,7 @@ function AutoHandle({ nodeId, position }) {
79
79
  };
80
80
  }, [nodeId, handleId, position, register, unregister, viewportRef]);
81
81
  return (jsx("button", { ref: ref, type: "button", "data-flikkui-handle": "", "data-node-id": nodeId, "data-handle-type": "source", "data-handle-id": handleId, "data-handle-kind": "auto", "aria-label": `Connect from ${position}`, className: cn("nodrag absolute z-20 grid place-items-center size-4 rounded-full", "bg-[var(--color-primary)] text-[var(--color-primary-contrast)] shadow-md ring-2 ring-[var(--color-surface)] cursor-crosshair", "opacity-0 scale-75 pointer-events-none transition-[opacity,transform,box-shadow] duration-150 ease-out", "hover:scale-110 hover:shadow-lg hover:ring-4 active:scale-95", !disabled &&
82
- "group-hover:opacity-100 group-hover:scale-100 group-hover:pointer-events-auto group-focus-within:opacity-100 group-focus-within:scale-100 group-focus-within:pointer-events-auto", AUTO_SIDE_CLASSES[position]), onPointerDown: disabled ? undefined : onPointerDown, children: jsx(PlusIcon, { className: "size-2.5" }) }));
82
+ "group-hover:opacity-100 group-hover:scale-100 group-hover:pointer-events-auto group-focus-within:opacity-100 group-focus-within:scale-100 group-focus-within:pointer-events-auto", AUTO_SIDE_CLASSES[position]), onPointerDown: disabled ? undefined : onPointerDown, children: jsx(Plus, { className: "size-2.5" }) }));
83
83
  }
84
84
  // Memoized so unrelated graph updates (another node's data/position, selection
85
85
  // elsewhere) skip this node: `node` identity is preserved by applyNodeChanges,
@@ -5,7 +5,7 @@ import { motion, useReducedMotion } from 'motion/react';
5
5
  import { cn } from '../../../utils/cn.js';
6
6
  import { activityRingsTheme } from './ActivityRings.theme.js';
7
7
  import { ACTIVITY_RINGS_DEFAULTS } from './ActivityRings.types.js';
8
- import { ExclamationTriangleIcon } from '@heroicons/react/20/solid';
8
+ import { Warning } from '@phosphor-icons/react';
9
9
  import { useTooltipPosition } from '../hooks/useTooltipPosition.js';
10
10
  import { ChartTooltip } from '../shared/ChartTooltip/ChartTooltip.js';
11
11
  import { getSpringAnimation, CIRCULAR_CHART_ANIMATIONS, getStaggerDelay } from '../utils/animation-utils.js';
@@ -127,7 +127,7 @@ const ActivityRings = ({ rings, centerLabel, centerSuffix, size = ACTIVITY_RINGS
127
127
  // BarChart.tsx.
128
128
  // Early return for invalid configuration
129
129
  if (!Array.isArray(rings) || rings.length === 0) {
130
- return (jsxs("div", { className: cn("flex items-center justify-center p-6 border border-[var(--color-border)] rounded-lg", className), role: "alert", ...props, children: [jsx(ExclamationTriangleIcon, { className: "size-5 text-[var(--color-danger)] mr-2" }), jsx("span", { className: "text-base text-[var(--color-text-secondary)]", children: "Invalid ActivityRings: rings array is required" })] }));
130
+ return (jsxs("div", { className: cn("flex items-center justify-center p-6 border border-[var(--color-border)] rounded-lg", className), role: "alert", ...props, children: [jsx(Warning, { className: "size-5 text-[var(--color-danger)] mr-2" }), jsx("span", { className: "text-base text-[var(--color-text-secondary)]", children: "Invalid ActivityRings: rings array is required" })] }));
131
131
  }
132
132
  // Get color for a ring by index
133
133
  // Priority: ring.color > colors prop > theme colors > fallback