@mastra/playground-ui 48.0.0-alpha.13 → 48.0.0-alpha.14

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 (247) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/{Button-Bm94fEF2.cjs → Button-CbPrvFVl.cjs} +3 -2
  3. package/dist/Button-CbPrvFVl.cjs.map +1 -0
  4. package/dist/{Button-Bx2lFdqb.js → Button-jSNYnNNS.js} +3 -2
  5. package/dist/Button-jSNYnNNS.js.map +1 -0
  6. package/dist/{Notice-B9cdEg8R.cjs → Notice-B57eB0Rg.cjs} +2 -2
  7. package/dist/{Notice-B9cdEg8R.cjs.map → Notice-B57eB0Rg.cjs.map} +1 -1
  8. package/dist/{Notice-DIK9IZsq.js → Notice-D3lGV4-M.js} +2 -2
  9. package/dist/{Notice-DIK9IZsq.js.map → Notice-D3lGV4-M.js.map} +1 -1
  10. package/dist/{SessionExpired-C5ADs4NL.cjs → SessionExpired-Bnc0Hf-P.cjs} +2 -2
  11. package/dist/{SessionExpired-C5ADs4NL.cjs.map → SessionExpired-Bnc0Hf-P.cjs.map} +1 -1
  12. package/dist/{SessionExpired-CHF__hq9.js → SessionExpired-JvcosjKD.js} +2 -2
  13. package/dist/{SessionExpired-CHF__hq9.js.map → SessionExpired-JvcosjKD.js.map} +1 -1
  14. package/dist/{combobox-sa_Pxyl4.js → combobox-B0okm2lT.js} +2 -2
  15. package/dist/{combobox-sa_Pxyl4.js.map → combobox-B0okm2lT.js.map} +1 -1
  16. package/dist/{combobox-DXwbHjvQ.cjs → combobox-hjSfb2cd.cjs} +2 -2
  17. package/dist/{combobox-DXwbHjvQ.cjs.map → combobox-hjSfb2cd.cjs.map} +1 -1
  18. package/dist/{command-Duq1xsiS.js → command-DRjtN9Ol.js} +2 -2
  19. package/dist/{command-Duq1xsiS.js.map → command-DRjtN9Ol.js.map} +1 -1
  20. package/dist/{command-qsEykgml.cjs → command-DZ5t8rS3.cjs} +2 -2
  21. package/dist/{command-qsEykgml.cjs.map → command-DZ5t8rS3.cjs.map} +1 -1
  22. package/dist/components/AlertDialog.cjs.js +1 -1
  23. package/dist/components/AlertDialog.es.js +1 -1
  24. package/dist/components/Button.cjs.js +1 -1
  25. package/dist/components/Button.es.js +1 -1
  26. package/dist/components/ClampedText.cjs.js +1 -1
  27. package/dist/components/ClampedText.es.js +1 -1
  28. package/dist/components/CodeBlock.cjs.js +2 -2
  29. package/dist/components/CodeBlock.es.js +2 -2
  30. package/dist/components/CodeEditor.cjs.js +1 -1
  31. package/dist/components/CodeEditor.es.js +1 -1
  32. package/dist/components/Columns.cjs.js +1 -1
  33. package/dist/components/Columns.es.js +1 -1
  34. package/dist/components/Combobox.cjs.js +1 -1
  35. package/dist/components/Combobox.es.js +1 -1
  36. package/dist/components/Command.cjs.js +1 -1
  37. package/dist/components/Command.es.js +1 -1
  38. package/dist/components/CommandPalette.cjs.js +1 -1
  39. package/dist/components/CommandPalette.es.js +1 -1
  40. package/dist/components/CopyButton.cjs.js +1 -1
  41. package/dist/components/CopyButton.es.js +1 -1
  42. package/dist/components/DataCodeSection.cjs.js +1 -1
  43. package/dist/components/DataCodeSection.es.js +1 -1
  44. package/dist/components/DataDetailsPanel.cjs.js +2 -2
  45. package/dist/components/DataDetailsPanel.es.js +2 -2
  46. package/dist/components/DataFilter.cjs.js +2 -2
  47. package/dist/components/DataFilter.es.js +2 -2
  48. package/dist/components/DataList.cjs.js +2 -2
  49. package/dist/components/DataList.es.js +2 -2
  50. package/dist/components/DataPanel.cjs.js +1 -1
  51. package/dist/components/DataPanel.es.js +1 -1
  52. package/dist/components/DateRangeTimeline.cjs.js +1 -1
  53. package/dist/components/DateRangeTimeline.es.js +1 -1
  54. package/dist/components/DateTimePicker.cjs.js +2 -2
  55. package/dist/components/DateTimePicker.es.js +2 -2
  56. package/dist/components/DateTimeRangePicker.cjs.js +1 -1
  57. package/dist/components/DateTimeRangePicker.es.js +1 -1
  58. package/dist/components/Dialog.cjs.js +1 -1
  59. package/dist/components/Dialog.es.js +1 -1
  60. package/dist/components/Drawer.cjs.js +1 -1
  61. package/dist/components/Drawer.es.js +1 -1
  62. package/dist/components/DropdownMenu.cjs.js +1 -1
  63. package/dist/components/DropdownMenu.es.js +1 -1
  64. package/dist/components/EnvironmentVariablesEditor.cjs.js +4 -4
  65. package/dist/components/EnvironmentVariablesEditor.es.js +4 -4
  66. package/dist/components/ErrorBoundary.cjs.js +1 -1
  67. package/dist/components/ErrorBoundary.es.js +1 -1
  68. package/dist/components/FormFieldBlocks.cjs.js +2 -2
  69. package/dist/components/FormFieldBlocks.es.js +2 -2
  70. package/dist/components/HoverCard.cjs.js +1 -1
  71. package/dist/components/HoverCard.es.js +1 -1
  72. package/dist/components/InputGroup.cjs.js +1 -1
  73. package/dist/components/InputGroup.es.js +1 -1
  74. package/dist/components/JSONSchemaForm.cjs.js +2 -2
  75. package/dist/components/JSONSchemaForm.es.js +2 -2
  76. package/dist/components/KeyValueList.cjs.js +1 -1
  77. package/dist/components/KeyValueList.es.js +1 -1
  78. package/dist/components/ListSearch.cjs.js +1 -1
  79. package/dist/components/ListSearch.es.js +1 -1
  80. package/dist/components/MainSidebar.cjs.js +72 -49
  81. package/dist/components/MainSidebar.cjs.js.map +1 -1
  82. package/dist/components/MainSidebar.es.js +72 -49
  83. package/dist/components/MainSidebar.es.js.map +1 -1
  84. package/dist/components/MarkdownRenderer.cjs.js +1 -1
  85. package/dist/components/MarkdownRenderer.es.js +1 -1
  86. package/dist/components/Notice.cjs.js +1 -1
  87. package/dist/components/Notice.es.js +1 -1
  88. package/dist/components/PrevNextNav.cjs.js +1 -1
  89. package/dist/components/PrevNextNav.es.js +1 -1
  90. package/dist/components/PropertyFilter.cjs.js +3 -3
  91. package/dist/components/PropertyFilter.es.js +4 -4
  92. package/dist/components/RuleBuilder.cjs.js +2 -2
  93. package/dist/components/RuleBuilder.es.js +2 -2
  94. package/dist/components/SankeyChart.cjs.js +266 -57
  95. package/dist/components/SankeyChart.cjs.js.map +1 -1
  96. package/dist/components/SankeyChart.es.js +267 -58
  97. package/dist/components/SankeyChart.es.js.map +1 -1
  98. package/dist/components/Select.cjs.js +1 -1
  99. package/dist/components/Select.es.js +1 -1
  100. package/dist/components/SessionExpired.cjs.js +1 -1
  101. package/dist/components/SessionExpired.es.js +1 -1
  102. package/dist/components/SideDialog.cjs.js +3 -3
  103. package/dist/components/SideDialog.es.js +3 -3
  104. package/dist/components/ThreadList.cjs.js +1 -1
  105. package/dist/components/ThreadList.es.js +1 -1
  106. package/dist/components/Truncate.cjs.js +1 -1
  107. package/dist/components/Truncate.es.js +1 -1
  108. package/dist/components/ai/ask-user.cjs.js +1 -1
  109. package/dist/components/ai/ask-user.es.js +1 -1
  110. package/dist/components/ai/plan.cjs.js +2 -2
  111. package/dist/components/ai/plan.es.js +2 -2
  112. package/dist/{copy-button-BKFcsNE1.cjs → copy-button-CbvvXi2V.cjs} +2 -2
  113. package/dist/{copy-button-BKFcsNE1.cjs.map → copy-button-CbvvXi2V.cjs.map} +1 -1
  114. package/dist/{copy-button-H2iaKMng.js → copy-button-D8qhMF81.js} +2 -2
  115. package/dist/{copy-button-H2iaKMng.js.map → copy-button-D8qhMF81.js.map} +1 -1
  116. package/dist/{data-code-section-D2zjah_b.cjs → data-code-section-BlnF-AcH.cjs} +5 -5
  117. package/dist/{data-code-section-D2zjah_b.cjs.map → data-code-section-BlnF-AcH.cjs.map} +1 -1
  118. package/dist/{data-code-section-MHMkC6q9.js → data-code-section-C8h-MUTj.js} +5 -5
  119. package/dist/{data-code-section-MHMkC6q9.js.map → data-code-section-C8h-MUTj.js.map} +1 -1
  120. package/dist/{data-list-Cb-piK4z.cjs → data-list-CeqAz6RR.cjs} +2 -2
  121. package/dist/{data-list-Cb-piK4z.cjs.map → data-list-CeqAz6RR.cjs.map} +1 -1
  122. package/dist/{data-list-CnQRIUyN.js → data-list-Chyj88BP.js} +2 -2
  123. package/dist/{data-list-CnQRIUyN.js.map → data-list-Chyj88BP.js.map} +1 -1
  124. package/dist/{data-panel-BumsjXVz.cjs → data-panel-1SM5j2BQ.cjs} +3 -3
  125. package/dist/{data-panel-BumsjXVz.cjs.map → data-panel-1SM5j2BQ.cjs.map} +1 -1
  126. package/dist/{data-panel-BEvHk4wg.js → data-panel-Bbhd1VVF.js} +3 -3
  127. package/dist/{data-panel-BEvHk4wg.js.map → data-panel-Bbhd1VVF.js.map} +1 -1
  128. package/dist/{date-time-range-picker-yJBIm34J.js → date-time-range-picker-Cz5Xdzm8.js} +4 -4
  129. package/dist/{date-time-range-picker-yJBIm34J.js.map → date-time-range-picker-Cz5Xdzm8.js.map} +1 -1
  130. package/dist/{date-time-range-picker-ue0m5G27.cjs → date-time-range-picker-DkNsQWnt.cjs} +4 -4
  131. package/dist/{date-time-range-picker-ue0m5G27.cjs.map → date-time-range-picker-DkNsQWnt.cjs.map} +1 -1
  132. package/dist/{dialog-bnt6epW2.js → dialog-CnY-gDja.js} +2 -2
  133. package/dist/{dialog-bnt6epW2.js.map → dialog-CnY-gDja.js.map} +1 -1
  134. package/dist/{dialog-ClItuCFY.cjs → dialog-Con_VmlQ.cjs} +2 -2
  135. package/dist/{dialog-ClItuCFY.cjs.map → dialog-Con_VmlQ.cjs.map} +1 -1
  136. package/dist/domains/logs/components/log-details-view.cjs.js +2 -2
  137. package/dist/domains/logs/components/log-details-view.es.js +2 -2
  138. package/dist/domains/logs/components/logs-error-content.cjs.js +1 -1
  139. package/dist/domains/logs/components/logs-error-content.es.js +1 -1
  140. package/dist/domains/logs/components/logs-toolbar.cjs.js +1 -1
  141. package/dist/domains/logs/components/logs-toolbar.es.js +1 -1
  142. package/dist/domains/logs/components/no-logs-info.cjs.js +1 -1
  143. package/dist/domains/logs/components/no-logs-info.es.js +1 -1
  144. package/dist/domains/memory/components/flame-graph.cjs.js +1 -1
  145. package/dist/domains/memory/components/flame-graph.es.js +1 -1
  146. package/dist/domains/memory/components/memory-studio-panel.cjs.js +1 -1
  147. package/dist/domains/memory/components/memory-studio-panel.es.js +1 -1
  148. package/dist/domains/metrics/components/card-action-buttons.cjs.js +1 -1
  149. package/dist/domains/metrics/components/card-action-buttons.es.js +1 -1
  150. package/dist/domains/metrics/components/date-range-selector.cjs.js +1 -1
  151. package/dist/domains/metrics/components/date-range-selector.es.js +1 -1
  152. package/dist/domains/metrics/components/memory-card-view.cjs.js +1 -1
  153. package/dist/domains/metrics/components/memory-card-view.es.js +1 -1
  154. package/dist/domains/metrics/components/model-usage-cost-card-view.cjs.js +1 -1
  155. package/dist/domains/metrics/components/model-usage-cost-card-view.es.js +1 -1
  156. package/dist/domains/metrics/components/scores-card-view.cjs.js +1 -1
  157. package/dist/domains/metrics/components/scores-card-view.es.js +1 -1
  158. package/dist/domains/traces/components/no-traces-info.cjs.js +1 -1
  159. package/dist/domains/traces/components/no-traces-info.es.js +1 -1
  160. package/dist/domains/traces/components/span-data-panel-view.cjs.js +2 -2
  161. package/dist/domains/traces/components/span-data-panel-view.es.js +2 -2
  162. package/dist/domains/traces/components/timeline-name-col.cjs.js +6 -2
  163. package/dist/domains/traces/components/timeline-name-col.cjs.js.map +1 -1
  164. package/dist/domains/traces/components/timeline-name-col.es.js +6 -2
  165. package/dist/domains/traces/components/timeline-name-col.es.js.map +1 -1
  166. package/dist/domains/traces/components/timeline-timing-col.cjs.js +1 -1
  167. package/dist/domains/traces/components/timeline-timing-col.es.js +1 -1
  168. package/dist/domains/traces/components/trace-columns-menu.cjs.js +3 -3
  169. package/dist/domains/traces/components/trace-columns-menu.es.js +3 -3
  170. package/dist/domains/traces/components/trace-data-panel-view.cjs.js +4 -10
  171. package/dist/domains/traces/components/trace-data-panel-view.cjs.js.map +1 -1
  172. package/dist/domains/traces/components/trace-data-panel-view.es.js +5 -11
  173. package/dist/domains/traces/components/trace-data-panel-view.es.js.map +1 -1
  174. package/dist/domains/traces/components/traces-error-content.cjs.js +1 -1
  175. package/dist/domains/traces/components/traces-error-content.es.js +1 -1
  176. package/dist/domains/traces/components/traces-list-mode-toggle.cjs.js +2 -2
  177. package/dist/domains/traces/components/traces-list-mode-toggle.es.js +2 -2
  178. package/dist/domains/traces/components/traces-list-view.cjs.js +2 -2
  179. package/dist/domains/traces/components/traces-list-view.es.js +2 -2
  180. package/dist/domains/traces/components/traces-toolbar.cjs.js +1 -1
  181. package/dist/domains/traces/components/traces-toolbar.es.js +1 -1
  182. package/dist/{drawer-CdsTitFp.cjs → drawer-Bng-J6Ne.cjs} +2 -2
  183. package/dist/{drawer-CdsTitFp.cjs.map → drawer-Bng-J6Ne.cjs.map} +1 -1
  184. package/dist/{drawer-DZ9amYo_.js → drawer-D9Cp7w6N.js} +2 -2
  185. package/dist/{drawer-DZ9amYo_.js.map → drawer-D9Cp7w6N.js.map} +1 -1
  186. package/dist/{dropdown-menu-ppWztidX.cjs → dropdown-menu-BZGlERgf.cjs} +4 -3
  187. package/dist/dropdown-menu-BZGlERgf.cjs.map +1 -0
  188. package/dist/{dropdown-menu-DEFygDZI.js → dropdown-menu-DCMh8P4w.js} +4 -3
  189. package/dist/dropdown-menu-DCMh8P4w.js.map +1 -0
  190. package/dist/ee/signals/components/signals-empty-state.cjs.js +1 -1
  191. package/dist/ee/signals/components/signals-empty-state.es.js +1 -1
  192. package/dist/ee/topics/components/topic-trace-summary-list.cjs.js +3 -3
  193. package/dist/ee/topics/components/topic-trace-summary-list.es.js +3 -3
  194. package/dist/{hover-card-crVofiZO.js → hover-card-Bs845QbV.js} +2 -2
  195. package/dist/{hover-card-crVofiZO.js.map → hover-card-Bs845QbV.js.map} +1 -1
  196. package/dist/{hover-card-Bx258om1.cjs → hover-card-Cd9QK50X.cjs} +2 -2
  197. package/dist/{hover-card-Bx258om1.cjs.map → hover-card-Cd9QK50X.cjs.map} +1 -1
  198. package/dist/{input-group-Dzs-ai0n.js → input-group-BnnvYySr.js} +2 -2
  199. package/dist/{input-group-Dzs-ai0n.js.map → input-group-BnnvYySr.js.map} +1 -1
  200. package/dist/{input-group-CH72YUVL.cjs → input-group-BxAiZUo5.cjs} +2 -2
  201. package/dist/{input-group-CH72YUVL.cjs.map → input-group-BxAiZUo5.cjs.map} +1 -1
  202. package/dist/{markdown-renderer-Bi2fWeoF.js → markdown-renderer-Bpucep5E.js} +36 -18
  203. package/dist/markdown-renderer-Bpucep5E.js.map +1 -0
  204. package/dist/{markdown-renderer-DwfNrhEH.cjs → markdown-renderer-tuX3CjAv.cjs} +36 -18
  205. package/dist/markdown-renderer-tuX3CjAv.cjs.map +1 -0
  206. package/dist/{property-filter-applied-DI4w1ACS.js → property-filter-applied-CdhgsCC8.js} +3 -3
  207. package/dist/{property-filter-applied-DI4w1ACS.js.map → property-filter-applied-CdhgsCC8.js.map} +1 -1
  208. package/dist/{property-filter-applied-BhxbHAN8.cjs → property-filter-applied-DROoy70i.cjs} +3 -3
  209. package/dist/{property-filter-applied-BhxbHAN8.cjs.map → property-filter-applied-DROoy70i.cjs.map} +1 -1
  210. package/dist/resize/panel-drawer.cjs.js +1 -1
  211. package/dist/resize/panel-drawer.es.js +1 -1
  212. package/dist/{search-field-block-DCnFZzRK.js → search-field-block-C15VrrNp.js} +2 -2
  213. package/dist/{search-field-block-DCnFZzRK.js.map → search-field-block-C15VrrNp.js.map} +1 -1
  214. package/dist/{search-field-block-D6TdrHZX.cjs → search-field-block-wjh5uz7E.cjs} +2 -2
  215. package/dist/{search-field-block-D6TdrHZX.cjs.map → search-field-block-wjh5uz7E.cjs.map} +1 -1
  216. package/dist/{select-B6ce20XX.cjs → select-DgOJ6a0U.cjs} +2 -2
  217. package/dist/{select-B6ce20XX.cjs.map → select-DgOJ6a0U.cjs.map} +1 -1
  218. package/dist/{select-Beo8qQ0e.js → select-DzvxwWFF.js} +2 -2
  219. package/dist/{select-Beo8qQ0e.js.map → select-DzvxwWFF.js.map} +1 -1
  220. package/dist/{select-field-block-DXw3tD0y.js → select-field-block-BWwOG2cP.js} +2 -2
  221. package/dist/{select-field-block-DXw3tD0y.js.map → select-field-block-BWwOG2cP.js.map} +1 -1
  222. package/dist/{select-field-block-svlHplxW.cjs → select-field-block-DY9ebut9.cjs} +2 -2
  223. package/dist/{select-field-block-svlHplxW.cjs.map → select-field-block-DY9ebut9.cjs.map} +1 -1
  224. package/dist/src/ds/components/MainSidebar/main-sidebar-nav-item-classes.d.ts +13 -2
  225. package/dist/src/ds/components/MainSidebar/main-sidebar-nav-link.d.ts +2 -2
  226. package/dist/src/ds/components/MarkdownRenderer/markdown-renderer.d.ts +3 -1
  227. package/dist/src/ds/components/SankeyChart/sankey-chart.d.ts +7 -2
  228. package/dist/src/ds/components/SankeyChart/sankey-portal-tooltip.d.ts +8 -0
  229. package/dist/src/ds/components/SankeyChart/use-sankey-geometry-transition.d.ts +11 -0
  230. package/dist/src/ds/components/SankeyChart/use-sankey-hover-tooltip.d.ts +15 -0
  231. package/dist/style.css +31 -4
  232. package/dist/{time-picker-mLzcoQMO.js → time-picker-BOncuX6N.js} +2 -2
  233. package/dist/{time-picker-mLzcoQMO.js.map → time-picker-BOncuX6N.js.map} +1 -1
  234. package/dist/{time-picker-BOQtPoyD.cjs → time-picker-D5KGkYTX.cjs} +2 -2
  235. package/dist/{time-picker-BOQtPoyD.cjs.map → time-picker-D5KGkYTX.cjs.map} +1 -1
  236. package/dist/{traces-data-list-vsvvvEiP.cjs → traces-data-list-BnQncyG0.cjs} +2 -2
  237. package/dist/{traces-data-list-vsvvvEiP.cjs.map → traces-data-list-BnQncyG0.cjs.map} +1 -1
  238. package/dist/{traces-data-list-DtuaCDES.js → traces-data-list-cySY6wpT.js} +2 -2
  239. package/dist/{traces-data-list-DtuaCDES.js.map → traces-data-list-cySY6wpT.js.map} +1 -1
  240. package/package.json +6 -6
  241. package/theme.css +8 -0
  242. package/dist/Button-Bm94fEF2.cjs.map +0 -1
  243. package/dist/Button-Bx2lFdqb.js.map +0 -1
  244. package/dist/dropdown-menu-DEFygDZI.js.map +0 -1
  245. package/dist/dropdown-menu-ppWztidX.cjs.map +0 -1
  246. package/dist/markdown-renderer-Bi2fWeoF.js.map +0 -1
  247. package/dist/markdown-renderer-DwfNrhEH.cjs.map +0 -1
@@ -5,8 +5,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5
5
  const jsxRuntime = require('react/jsx-runtime');
6
6
  const React = require('react');
7
7
  const sankeyColor = require('../sankeyColor-DONd5cg9.cjs');
8
- const reactDom = require('react-dom');
9
8
  const recharts = require('recharts');
9
+ const reactDom = require('react-dom');
10
10
  const spacings = require('../spacings-BP8L49kn.cjs');
11
11
  const utils_cn = require('../cn-vA5sWo9W.cjs');
12
12
 
@@ -318,6 +318,82 @@ function orderColumns(columns, order) {
318
318
  );
319
319
  }
320
320
 
321
+ const SANKEY_TOOLTIP_MAX_WIDTH_PX = 320;
322
+ const TOOLTIP_TOP_FLIP_THRESHOLD = 120;
323
+ const TOOLTIP_EDGE_INSET = 16;
324
+ const TOOLTIP_RIGHT_INSET = SANKEY_TOOLTIP_MAX_WIDTH_PX + TOOLTIP_EDGE_INSET;
325
+ function useSankeyHoverTooltip(enabled) {
326
+ const id = React.useId();
327
+ const [isHovered, setIsHovered] = React.useState(false);
328
+ const [isFocused, setIsFocused] = React.useState(false);
329
+ const [position, setPosition] = React.useState();
330
+ function showAt(target) {
331
+ if (!enabled) return;
332
+ const rect = target.getBoundingClientRect();
333
+ const placement = rect.top < TOOLTIP_TOP_FLIP_THRESHOLD ? "below" : "above";
334
+ setPosition({
335
+ left: Math.min(
336
+ Math.max(rect.left, TOOLTIP_EDGE_INSET),
337
+ Math.max(window.innerWidth - TOOLTIP_RIGHT_INSET, TOOLTIP_EDGE_INSET)
338
+ ),
339
+ top: placement === "above" ? rect.top - 8 : rect.bottom + 8,
340
+ placement
341
+ });
342
+ }
343
+ return {
344
+ id,
345
+ position,
346
+ isVisible: Boolean(enabled && position && (isHovered || isFocused)),
347
+ showOnHover(target) {
348
+ setIsHovered(true);
349
+ showAt(target);
350
+ },
351
+ hideOnLeave() {
352
+ setIsHovered(false);
353
+ },
354
+ showOnFocus(target) {
355
+ setIsFocused(true);
356
+ showAt(target);
357
+ },
358
+ hideOnBlur() {
359
+ setIsFocused(false);
360
+ }
361
+ };
362
+ }
363
+
364
+ function SankeyPortalTooltip({
365
+ id,
366
+ title,
367
+ description,
368
+ position,
369
+ visible
370
+ }) {
371
+ if (!visible || !position) return null;
372
+ return reactDom.createPortal(
373
+ /* @__PURE__ */ jsxRuntime.jsxs(
374
+ "div",
375
+ {
376
+ "aria-label": `${title}: ${description}`,
377
+ className: "border-border1 bg-surface5 text-neutral6 shadow-elevated pointer-events-none fixed z-50 rounded-md border p-2 text-xs leading-4",
378
+ id,
379
+ role: "tooltip",
380
+ style: {
381
+ left: position.left,
382
+ maxWidth: `min(${SANKEY_TOOLTIP_MAX_WIDTH_PX}px, calc(100vw - 2rem))`,
383
+ top: position.top,
384
+ transform: position.placement === "above" ? "translateY(-100%)" : void 0,
385
+ width: "max-content"
386
+ },
387
+ children: [
388
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: title }),
389
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-neutral4 whitespace-pre-wrap", children: description })
390
+ ]
391
+ }
392
+ ),
393
+ document.body
394
+ );
395
+ }
396
+
321
397
  function useSankeyChartMeasurements({
322
398
  graph,
323
399
  height,
@@ -359,6 +435,117 @@ function useSankeyChartMeasurements({
359
435
  return { chartContainerRef, fixedGeometry, labelWidths };
360
436
  }
361
437
 
438
+ const TRANSITION_DURATION_MS = 850;
439
+ function mix(from, to, progress) {
440
+ return from + (to - from) * progress;
441
+ }
442
+ function interpolateNode(from, to, progress) {
443
+ return {
444
+ x: mix(from.x, to.x, progress),
445
+ y: mix(from.y, to.y, progress),
446
+ centerY: mix(from.centerY, to.centerY, progress),
447
+ height: mix(from.height, to.height, progress)
448
+ };
449
+ }
450
+ function interpolateLink(from, to, progress) {
451
+ return {
452
+ sourceX: mix(from.sourceX, to.sourceX, progress),
453
+ targetX: mix(from.targetX, to.targetX, progress),
454
+ sourceY: mix(from.sourceY, to.sourceY, progress),
455
+ targetY: mix(from.targetY, to.targetY, progress),
456
+ sourceWidth: mix(from.sourceWidth, to.sourceWidth, progress),
457
+ targetWidth: mix(from.targetWidth, to.targetWidth, progress)
458
+ };
459
+ }
460
+ function interpolateSankeyGeometry(from, to, progress) {
461
+ const replacedPreviousLinks = [...from.links].filter(([id]) => !to.links.has(id)).map(([, link]) => link);
462
+ const nodes = /* @__PURE__ */ new Map();
463
+ const links = /* @__PURE__ */ new Map();
464
+ for (const [id, target] of to.nodes) {
465
+ nodes.set(id, interpolateNode(from.nodes.get(id) ?? target, target, progress));
466
+ }
467
+ let replacedLinkIndex = 0;
468
+ for (const [id, target] of to.links) {
469
+ const matchingSource = from.links.get(id);
470
+ const syntheticSource = matchingSource ? void 0 : replacedPreviousLinks[replacedLinkIndex++];
471
+ links.set(id, interpolateLink(matchingSource ?? syntheticSource ?? target, target, progress));
472
+ }
473
+ return { nodes, links };
474
+ }
475
+ function prefersReducedMotion() {
476
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
477
+ }
478
+ class SankeyGeometryMotionStore {
479
+ animationFrame = 0;
480
+ key;
481
+ listeners = /* @__PURE__ */ new Set();
482
+ snapshot;
483
+ target;
484
+ transition;
485
+ constructor(key, geometry) {
486
+ this.key = key;
487
+ this.snapshot = geometry;
488
+ this.target = geometry;
489
+ }
490
+ getSnapshot = () => this.snapshot;
491
+ subscribe = (listener) => {
492
+ this.listeners.add(listener);
493
+ return () => this.listeners.delete(listener);
494
+ };
495
+ transitionTo(key, geometry) {
496
+ if (key === this.key && geometry === this.target) return;
497
+ const keyChanged = key !== this.key;
498
+ this.key = key;
499
+ this.target = geometry;
500
+ if (!keyChanged && geometry && this.transition) {
501
+ this.transition = { ...this.transition, to: geometry };
502
+ return;
503
+ }
504
+ cancelAnimationFrame(this.animationFrame);
505
+ this.animationFrame = 0;
506
+ if (!keyChanged || !geometry || !this.snapshot || prefersReducedMotion()) {
507
+ this.transition = void 0;
508
+ this.publish(geometry);
509
+ return;
510
+ }
511
+ this.transition = { from: this.snapshot, to: geometry, startedAt: performance.now() };
512
+ this.animationFrame = requestAnimationFrame(this.animate);
513
+ }
514
+ dispose() {
515
+ cancelAnimationFrame(this.animationFrame);
516
+ this.listeners.clear();
517
+ }
518
+ animate = (now) => {
519
+ const transition = this.transition;
520
+ if (!transition) return;
521
+ const elapsed = Math.min((now - transition.startedAt) / TRANSITION_DURATION_MS, 1);
522
+ const progress = 1 - (1 - elapsed) ** 3;
523
+ this.publish(interpolateSankeyGeometry(transition.from, transition.to, progress));
524
+ if (elapsed < 1) {
525
+ this.animationFrame = requestAnimationFrame(this.animate);
526
+ return;
527
+ }
528
+ this.transition = void 0;
529
+ this.animationFrame = 0;
530
+ };
531
+ publish(geometry) {
532
+ this.snapshot = geometry;
533
+ for (const listener of this.listeners) listener();
534
+ }
535
+ }
536
+ function useSankeyGeometryTransition({
537
+ geometry,
538
+ transitionKey
539
+ }) {
540
+ const [store] = React.useState(() => new SankeyGeometryMotionStore(transitionKey, geometry));
541
+ const animatedGeometry = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
542
+ React.useEffect(() => {
543
+ store.transitionTo(transitionKey, geometry);
544
+ }, [geometry, store, transitionKey]);
545
+ React.useEffect(() => () => store.dispose(), [store]);
546
+ return animatedGeometry;
547
+ }
548
+
362
549
  const NODE_LABEL_FONT_SIZE = 11;
363
550
  const COLUMN_LABEL_FONT_SIZE = 12;
364
551
  const NODE_LABEL_MAX_CHARACTERS = 23;
@@ -368,7 +555,10 @@ function SankeyChart({
368
555
  margin = { top: 64, right: 160, bottom: 12, left: 160 },
369
556
  onCurveClick,
370
557
  onNodeClick,
371
- isNodeClickable
558
+ isNodeClickable,
559
+ getColumnDescription,
560
+ hideColumnLabels = false,
561
+ geometryTransitionKey
372
562
  }) {
373
563
  const { graph, enabledColumns, hueMap, usesFixedGeometry } = useSankeyRenderContext();
374
564
  const { chartContainerRef, fixedGeometry, labelWidths } = useSankeyChartMeasurements({
@@ -377,6 +567,10 @@ function SankeyChart({
377
567
  margin,
378
568
  usesFixedGeometry
379
569
  });
570
+ const animatedGeometry = useSankeyGeometryTransition({
571
+ geometry: fixedGeometry,
572
+ transitionKey: geometryTransitionKey
573
+ });
380
574
  const [hoveredSourceName, setHoveredSourceName] = React.useState();
381
575
  const [focusedSourceName, setFocusedSourceName] = React.useState();
382
576
  const activeSourceName = hoveredSourceName ?? focusedSourceName;
@@ -410,8 +604,8 @@ function SankeyChart({
410
604
  margin,
411
605
  node: (props) => {
412
606
  const node = graph.nodes[props.index];
413
- const showColumnLabel = node ? graph.nodes.findIndex((candidate) => candidate.column.id === node.column.id) === props.index : false;
414
- const nodeGeometry = node ? fixedGeometry?.nodes.get(node.id) : void 0;
607
+ const showColumnLabel = !hideColumnLabels && node ? graph.nodes.findIndex((candidate) => candidate.column.id === node.column.id) === props.index : false;
608
+ const nodeGeometry = node ? animatedGeometry?.nodes.get(node.id) : void 0;
415
609
  const selection = node ? getSankeyChartNodeSelection(node) : void 0;
416
610
  const clickable = Boolean(
417
611
  onNodeClick && selection && (isNodeClickable === void 0 || isNodeClickable(selection))
@@ -425,6 +619,7 @@ function SankeyChart({
425
619
  height: nodeGeometry?.height ?? props.height,
426
620
  hueMap,
427
621
  columnLabel: node?.column.label,
622
+ columnDescription: node ? getColumnDescription?.(node.column) : void 0,
428
623
  label: node?.label,
429
624
  nodeValue: node?.displayValue,
430
625
  layoutValue: nodeGeometry ? void 0 : node ? nodeWeights.get(node.id) : void 0,
@@ -444,7 +639,7 @@ function SankeyChart({
444
639
  },
445
640
  link: (props) => {
446
641
  const link = graph.links[props.index];
447
- const linkGeometry = link ? fixedGeometry?.links.get(link.id) : void 0;
642
+ const linkGeometry = link ? animatedGeometry?.links.get(link.id) : void 0;
448
643
  const sourceX = linkGeometry?.sourceX ?? props.sourceX;
449
644
  const targetX = linkGeometry?.targetX ?? props.targetX;
450
645
  const fixedControlX = linkGeometry ? (sourceX + targetX) / 2 : void 0;
@@ -485,6 +680,7 @@ function SankeyNode({
485
680
  payload,
486
681
  hueMap,
487
682
  columnLabel,
683
+ columnDescription,
488
684
  label,
489
685
  nodeValue,
490
686
  layoutValue,
@@ -511,10 +707,7 @@ function SankeyNode({
511
707
  maxCharacters: NODE_LABEL_MAX_CHARACTERS
512
708
  });
513
709
  const visibleColumnLabel = columnLabel ? truncateSankeyLabel(columnLabel, { fontSize: COLUMN_LABEL_FONT_SIZE, maxWidth: nodeLabelWidth }) : void 0;
514
- const tooltipId = React.useId();
515
- const [isHovered, setIsHovered] = React.useState(false);
516
- const [isFocused, setIsFocused] = React.useState(false);
517
- const [tooltipPosition, setTooltipPosition] = React.useState();
710
+ const tooltip = useSankeyHoverTooltip(description !== void 0);
518
711
  const numericValue = nodeValue ?? (typeof payload.value === "number" ? payload.value : Number(payload.value));
519
712
  const value = Number.isFinite(numericValue) ? String(numericValue) : "";
520
713
  const percentage = columnTotal > 0 && Number.isFinite(numericValue) ? Math.round(numericValue / columnTotal * 100) : 0;
@@ -523,41 +716,27 @@ function SankeyNode({
523
716
  const textAnchor = isFirstColumn ? "start" : isLastColumn ? "end" : "middle";
524
717
  const labelX = isFirstColumn ? x : isLastColumn ? x + width : x + width / 2;
525
718
  const hue = hueMap[name] ?? 0;
526
- const isTooltipVisible = Boolean(description && tooltipPosition && (isHovered || isFocused));
527
- const showTooltipAt = (target) => {
528
- const rect = target.getBoundingClientRect();
529
- const placement = rect.top < 120 ? "below" : "above";
530
- setTooltipPosition({
531
- left: Math.min(Math.max(rect.left, 16), Math.max(window.innerWidth - 336, 16)),
532
- top: placement === "above" ? rect.top - 8 : rect.bottom + 8,
533
- placement
534
- });
535
- };
536
719
  const handleKeyDown = (event) => {
537
720
  if (event.key !== "Enter" && event.key !== " ") return;
538
721
  event.preventDefault();
539
722
  onSelect();
540
723
  };
541
724
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
542
- showColumnLabel && visibleColumnLabel ? /* @__PURE__ */ jsxRuntime.jsxs(
543
- "text",
725
+ showColumnLabel && visibleColumnLabel && columnLabel ? /* @__PURE__ */ jsxRuntime.jsx(
726
+ SankeyColumnHeader,
544
727
  {
545
728
  x: labelX,
546
- y: 18,
547
729
  textAnchor,
548
730
  fill: sankeyColor.nodeColor(hue),
549
- fontSize: COLUMN_LABEL_FONT_SIZE,
550
- fontWeight: 600,
551
- children: [
552
- visibleColumnLabel === columnLabel ? null : /* @__PURE__ */ jsxRuntime.jsx("title", { children: columnLabel }),
553
- visibleColumnLabel
554
- ]
731
+ label: visibleColumnLabel,
732
+ fullLabel: columnLabel,
733
+ description: columnDescription
555
734
  }
556
735
  ) : null,
557
736
  /* @__PURE__ */ jsxRuntime.jsxs(
558
737
  "g",
559
738
  {
560
- "aria-describedby": description ? tooltipId : void 0,
739
+ "aria-describedby": description ? tooltip.id : void 0,
561
740
  "aria-label": `${accessibleLabel}: ${value} ${numericValue === 1 ? "trace" : "traces"} (${percentage}%)`,
562
741
  className: "focus-visible:[&>rect]:stroke-neutral6 outline-hidden focus-visible:[&>rect]:stroke-2",
563
742
  onClick: clickable ? onSelect : void 0,
@@ -565,21 +744,19 @@ function SankeyNode({
565
744
  role: clickable ? "button" : void 0,
566
745
  onFocus: (event) => {
567
746
  onFocusChange(name);
568
- setIsFocused(true);
569
- showTooltipAt(event.currentTarget);
747
+ tooltip.showOnFocus(event.currentTarget);
570
748
  },
571
749
  onBlur: () => {
572
750
  onFocusChange(void 0);
573
- setIsFocused(false);
751
+ tooltip.hideOnBlur();
574
752
  },
575
753
  onMouseEnter: (event) => {
576
754
  onHoverChange(name);
577
- setIsHovered(true);
578
- showTooltipAt(event.currentTarget);
755
+ tooltip.showOnHover(event.currentTarget);
579
756
  },
580
757
  onMouseLeave: () => {
581
758
  onHoverChange(void 0);
582
- setIsHovered(false);
759
+ tooltip.hideOnLeave();
583
760
  },
584
761
  style: { cursor: clickable ? "pointer" : void 0 },
585
762
  tabIndex: 0,
@@ -607,28 +784,60 @@ function SankeyNode({
607
784
  ]
608
785
  }
609
786
  ),
610
- description && isTooltipVisible && tooltipPosition ? reactDom.createPortal(
611
- /* @__PURE__ */ jsxRuntime.jsxs(
612
- "div",
613
- {
614
- "aria-label": `${visibleDisplayLabel}: ${description}`,
615
- className: "border-border1 bg-surface5 text-neutral6 shadow-elevated pointer-events-none fixed z-50 rounded-md border p-2 text-xs leading-4",
616
- id: tooltipId,
617
- role: "tooltip",
618
- style: {
619
- left: tooltipPosition.left,
620
- maxWidth: "min(20rem, calc(100vw - 2rem))",
621
- top: tooltipPosition.top,
622
- transform: tooltipPosition.placement === "above" ? "translateY(-100%)" : void 0,
623
- width: "max-content"
624
- },
625
- children: [
626
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: visibleDisplayLabel }),
627
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-neutral4 whitespace-pre-wrap", children: description })
628
- ]
629
- }
630
- ),
631
- document.body
787
+ description ? /* @__PURE__ */ jsxRuntime.jsx(
788
+ SankeyPortalTooltip,
789
+ {
790
+ id: tooltip.id,
791
+ title: visibleDisplayLabel,
792
+ description,
793
+ position: tooltip.position,
794
+ visible: tooltip.isVisible
795
+ }
796
+ ) : null
797
+ ] });
798
+ }
799
+ function SankeyColumnHeader({
800
+ x,
801
+ textAnchor,
802
+ fill,
803
+ label,
804
+ fullLabel,
805
+ description
806
+ }) {
807
+ const tooltip = useSankeyHoverTooltip(description !== void 0);
808
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
809
+ /* @__PURE__ */ jsxRuntime.jsxs(
810
+ "text",
811
+ {
812
+ "aria-describedby": description ? tooltip.id : void 0,
813
+ "aria-label": description ? fullLabel : void 0,
814
+ role: description ? "img" : void 0,
815
+ x,
816
+ y: 18,
817
+ textAnchor,
818
+ fill,
819
+ fontSize: COLUMN_LABEL_FONT_SIZE,
820
+ fontWeight: 600,
821
+ tabIndex: description ? 0 : void 0,
822
+ onMouseEnter: description ? (event) => tooltip.showOnHover(event.currentTarget) : void 0,
823
+ onMouseLeave: description ? tooltip.hideOnLeave : void 0,
824
+ onFocus: description ? (event) => tooltip.showOnFocus(event.currentTarget) : void 0,
825
+ onBlur: description ? tooltip.hideOnBlur : void 0,
826
+ children: [
827
+ label === fullLabel || description ? null : /* @__PURE__ */ jsxRuntime.jsx("title", { children: fullLabel }),
828
+ label
829
+ ]
830
+ }
831
+ ),
832
+ description ? /* @__PURE__ */ jsxRuntime.jsx(
833
+ SankeyPortalTooltip,
834
+ {
835
+ id: tooltip.id,
836
+ title: fullLabel,
837
+ description,
838
+ position: tooltip.position,
839
+ visible: tooltip.isVisible
840
+ }
632
841
  ) : null
633
842
  ] });
634
843
  }