@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.
- package/CHANGELOG.md +25 -0
- package/dist/{Button-Bm94fEF2.cjs → Button-CbPrvFVl.cjs} +3 -2
- package/dist/Button-CbPrvFVl.cjs.map +1 -0
- package/dist/{Button-Bx2lFdqb.js → Button-jSNYnNNS.js} +3 -2
- package/dist/Button-jSNYnNNS.js.map +1 -0
- package/dist/{Notice-B9cdEg8R.cjs → Notice-B57eB0Rg.cjs} +2 -2
- package/dist/{Notice-B9cdEg8R.cjs.map → Notice-B57eB0Rg.cjs.map} +1 -1
- package/dist/{Notice-DIK9IZsq.js → Notice-D3lGV4-M.js} +2 -2
- package/dist/{Notice-DIK9IZsq.js.map → Notice-D3lGV4-M.js.map} +1 -1
- package/dist/{SessionExpired-C5ADs4NL.cjs → SessionExpired-Bnc0Hf-P.cjs} +2 -2
- package/dist/{SessionExpired-C5ADs4NL.cjs.map → SessionExpired-Bnc0Hf-P.cjs.map} +1 -1
- package/dist/{SessionExpired-CHF__hq9.js → SessionExpired-JvcosjKD.js} +2 -2
- package/dist/{SessionExpired-CHF__hq9.js.map → SessionExpired-JvcosjKD.js.map} +1 -1
- package/dist/{combobox-sa_Pxyl4.js → combobox-B0okm2lT.js} +2 -2
- package/dist/{combobox-sa_Pxyl4.js.map → combobox-B0okm2lT.js.map} +1 -1
- package/dist/{combobox-DXwbHjvQ.cjs → combobox-hjSfb2cd.cjs} +2 -2
- package/dist/{combobox-DXwbHjvQ.cjs.map → combobox-hjSfb2cd.cjs.map} +1 -1
- package/dist/{command-Duq1xsiS.js → command-DRjtN9Ol.js} +2 -2
- package/dist/{command-Duq1xsiS.js.map → command-DRjtN9Ol.js.map} +1 -1
- package/dist/{command-qsEykgml.cjs → command-DZ5t8rS3.cjs} +2 -2
- package/dist/{command-qsEykgml.cjs.map → command-DZ5t8rS3.cjs.map} +1 -1
- package/dist/components/AlertDialog.cjs.js +1 -1
- package/dist/components/AlertDialog.es.js +1 -1
- package/dist/components/Button.cjs.js +1 -1
- package/dist/components/Button.es.js +1 -1
- package/dist/components/ClampedText.cjs.js +1 -1
- package/dist/components/ClampedText.es.js +1 -1
- package/dist/components/CodeBlock.cjs.js +2 -2
- package/dist/components/CodeBlock.es.js +2 -2
- package/dist/components/CodeEditor.cjs.js +1 -1
- package/dist/components/CodeEditor.es.js +1 -1
- package/dist/components/Columns.cjs.js +1 -1
- package/dist/components/Columns.es.js +1 -1
- package/dist/components/Combobox.cjs.js +1 -1
- package/dist/components/Combobox.es.js +1 -1
- package/dist/components/Command.cjs.js +1 -1
- package/dist/components/Command.es.js +1 -1
- package/dist/components/CommandPalette.cjs.js +1 -1
- package/dist/components/CommandPalette.es.js +1 -1
- package/dist/components/CopyButton.cjs.js +1 -1
- package/dist/components/CopyButton.es.js +1 -1
- package/dist/components/DataCodeSection.cjs.js +1 -1
- package/dist/components/DataCodeSection.es.js +1 -1
- package/dist/components/DataDetailsPanel.cjs.js +2 -2
- package/dist/components/DataDetailsPanel.es.js +2 -2
- package/dist/components/DataFilter.cjs.js +2 -2
- package/dist/components/DataFilter.es.js +2 -2
- package/dist/components/DataList.cjs.js +2 -2
- package/dist/components/DataList.es.js +2 -2
- package/dist/components/DataPanel.cjs.js +1 -1
- package/dist/components/DataPanel.es.js +1 -1
- package/dist/components/DateRangeTimeline.cjs.js +1 -1
- package/dist/components/DateRangeTimeline.es.js +1 -1
- package/dist/components/DateTimePicker.cjs.js +2 -2
- package/dist/components/DateTimePicker.es.js +2 -2
- package/dist/components/DateTimeRangePicker.cjs.js +1 -1
- package/dist/components/DateTimeRangePicker.es.js +1 -1
- package/dist/components/Dialog.cjs.js +1 -1
- package/dist/components/Dialog.es.js +1 -1
- package/dist/components/Drawer.cjs.js +1 -1
- package/dist/components/Drawer.es.js +1 -1
- package/dist/components/DropdownMenu.cjs.js +1 -1
- package/dist/components/DropdownMenu.es.js +1 -1
- package/dist/components/EnvironmentVariablesEditor.cjs.js +4 -4
- package/dist/components/EnvironmentVariablesEditor.es.js +4 -4
- package/dist/components/ErrorBoundary.cjs.js +1 -1
- package/dist/components/ErrorBoundary.es.js +1 -1
- package/dist/components/FormFieldBlocks.cjs.js +2 -2
- package/dist/components/FormFieldBlocks.es.js +2 -2
- package/dist/components/HoverCard.cjs.js +1 -1
- package/dist/components/HoverCard.es.js +1 -1
- package/dist/components/InputGroup.cjs.js +1 -1
- package/dist/components/InputGroup.es.js +1 -1
- package/dist/components/JSONSchemaForm.cjs.js +2 -2
- package/dist/components/JSONSchemaForm.es.js +2 -2
- package/dist/components/KeyValueList.cjs.js +1 -1
- package/dist/components/KeyValueList.es.js +1 -1
- package/dist/components/ListSearch.cjs.js +1 -1
- package/dist/components/ListSearch.es.js +1 -1
- package/dist/components/MainSidebar.cjs.js +72 -49
- package/dist/components/MainSidebar.cjs.js.map +1 -1
- package/dist/components/MainSidebar.es.js +72 -49
- package/dist/components/MainSidebar.es.js.map +1 -1
- package/dist/components/MarkdownRenderer.cjs.js +1 -1
- package/dist/components/MarkdownRenderer.es.js +1 -1
- package/dist/components/Notice.cjs.js +1 -1
- package/dist/components/Notice.es.js +1 -1
- package/dist/components/PrevNextNav.cjs.js +1 -1
- package/dist/components/PrevNextNav.es.js +1 -1
- package/dist/components/PropertyFilter.cjs.js +3 -3
- package/dist/components/PropertyFilter.es.js +4 -4
- package/dist/components/RuleBuilder.cjs.js +2 -2
- package/dist/components/RuleBuilder.es.js +2 -2
- package/dist/components/SankeyChart.cjs.js +266 -57
- package/dist/components/SankeyChart.cjs.js.map +1 -1
- package/dist/components/SankeyChart.es.js +267 -58
- package/dist/components/SankeyChart.es.js.map +1 -1
- package/dist/components/Select.cjs.js +1 -1
- package/dist/components/Select.es.js +1 -1
- package/dist/components/SessionExpired.cjs.js +1 -1
- package/dist/components/SessionExpired.es.js +1 -1
- package/dist/components/SideDialog.cjs.js +3 -3
- package/dist/components/SideDialog.es.js +3 -3
- package/dist/components/ThreadList.cjs.js +1 -1
- package/dist/components/ThreadList.es.js +1 -1
- package/dist/components/Truncate.cjs.js +1 -1
- package/dist/components/Truncate.es.js +1 -1
- package/dist/components/ai/ask-user.cjs.js +1 -1
- package/dist/components/ai/ask-user.es.js +1 -1
- package/dist/components/ai/plan.cjs.js +2 -2
- package/dist/components/ai/plan.es.js +2 -2
- package/dist/{copy-button-BKFcsNE1.cjs → copy-button-CbvvXi2V.cjs} +2 -2
- package/dist/{copy-button-BKFcsNE1.cjs.map → copy-button-CbvvXi2V.cjs.map} +1 -1
- package/dist/{copy-button-H2iaKMng.js → copy-button-D8qhMF81.js} +2 -2
- package/dist/{copy-button-H2iaKMng.js.map → copy-button-D8qhMF81.js.map} +1 -1
- package/dist/{data-code-section-D2zjah_b.cjs → data-code-section-BlnF-AcH.cjs} +5 -5
- package/dist/{data-code-section-D2zjah_b.cjs.map → data-code-section-BlnF-AcH.cjs.map} +1 -1
- package/dist/{data-code-section-MHMkC6q9.js → data-code-section-C8h-MUTj.js} +5 -5
- package/dist/{data-code-section-MHMkC6q9.js.map → data-code-section-C8h-MUTj.js.map} +1 -1
- package/dist/{data-list-Cb-piK4z.cjs → data-list-CeqAz6RR.cjs} +2 -2
- package/dist/{data-list-Cb-piK4z.cjs.map → data-list-CeqAz6RR.cjs.map} +1 -1
- package/dist/{data-list-CnQRIUyN.js → data-list-Chyj88BP.js} +2 -2
- package/dist/{data-list-CnQRIUyN.js.map → data-list-Chyj88BP.js.map} +1 -1
- package/dist/{data-panel-BumsjXVz.cjs → data-panel-1SM5j2BQ.cjs} +3 -3
- package/dist/{data-panel-BumsjXVz.cjs.map → data-panel-1SM5j2BQ.cjs.map} +1 -1
- package/dist/{data-panel-BEvHk4wg.js → data-panel-Bbhd1VVF.js} +3 -3
- package/dist/{data-panel-BEvHk4wg.js.map → data-panel-Bbhd1VVF.js.map} +1 -1
- package/dist/{date-time-range-picker-yJBIm34J.js → date-time-range-picker-Cz5Xdzm8.js} +4 -4
- package/dist/{date-time-range-picker-yJBIm34J.js.map → date-time-range-picker-Cz5Xdzm8.js.map} +1 -1
- package/dist/{date-time-range-picker-ue0m5G27.cjs → date-time-range-picker-DkNsQWnt.cjs} +4 -4
- package/dist/{date-time-range-picker-ue0m5G27.cjs.map → date-time-range-picker-DkNsQWnt.cjs.map} +1 -1
- package/dist/{dialog-bnt6epW2.js → dialog-CnY-gDja.js} +2 -2
- package/dist/{dialog-bnt6epW2.js.map → dialog-CnY-gDja.js.map} +1 -1
- package/dist/{dialog-ClItuCFY.cjs → dialog-Con_VmlQ.cjs} +2 -2
- package/dist/{dialog-ClItuCFY.cjs.map → dialog-Con_VmlQ.cjs.map} +1 -1
- package/dist/domains/logs/components/log-details-view.cjs.js +2 -2
- package/dist/domains/logs/components/log-details-view.es.js +2 -2
- package/dist/domains/logs/components/logs-error-content.cjs.js +1 -1
- package/dist/domains/logs/components/logs-error-content.es.js +1 -1
- package/dist/domains/logs/components/logs-toolbar.cjs.js +1 -1
- package/dist/domains/logs/components/logs-toolbar.es.js +1 -1
- package/dist/domains/logs/components/no-logs-info.cjs.js +1 -1
- package/dist/domains/logs/components/no-logs-info.es.js +1 -1
- package/dist/domains/memory/components/flame-graph.cjs.js +1 -1
- package/dist/domains/memory/components/flame-graph.es.js +1 -1
- package/dist/domains/memory/components/memory-studio-panel.cjs.js +1 -1
- package/dist/domains/memory/components/memory-studio-panel.es.js +1 -1
- package/dist/domains/metrics/components/card-action-buttons.cjs.js +1 -1
- package/dist/domains/metrics/components/card-action-buttons.es.js +1 -1
- package/dist/domains/metrics/components/date-range-selector.cjs.js +1 -1
- package/dist/domains/metrics/components/date-range-selector.es.js +1 -1
- package/dist/domains/metrics/components/memory-card-view.cjs.js +1 -1
- package/dist/domains/metrics/components/memory-card-view.es.js +1 -1
- package/dist/domains/metrics/components/model-usage-cost-card-view.cjs.js +1 -1
- package/dist/domains/metrics/components/model-usage-cost-card-view.es.js +1 -1
- package/dist/domains/metrics/components/scores-card-view.cjs.js +1 -1
- package/dist/domains/metrics/components/scores-card-view.es.js +1 -1
- package/dist/domains/traces/components/no-traces-info.cjs.js +1 -1
- package/dist/domains/traces/components/no-traces-info.es.js +1 -1
- package/dist/domains/traces/components/span-data-panel-view.cjs.js +2 -2
- package/dist/domains/traces/components/span-data-panel-view.es.js +2 -2
- package/dist/domains/traces/components/timeline-name-col.cjs.js +6 -2
- package/dist/domains/traces/components/timeline-name-col.cjs.js.map +1 -1
- package/dist/domains/traces/components/timeline-name-col.es.js +6 -2
- package/dist/domains/traces/components/timeline-name-col.es.js.map +1 -1
- package/dist/domains/traces/components/timeline-timing-col.cjs.js +1 -1
- package/dist/domains/traces/components/timeline-timing-col.es.js +1 -1
- package/dist/domains/traces/components/trace-columns-menu.cjs.js +3 -3
- package/dist/domains/traces/components/trace-columns-menu.es.js +3 -3
- package/dist/domains/traces/components/trace-data-panel-view.cjs.js +4 -10
- package/dist/domains/traces/components/trace-data-panel-view.cjs.js.map +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.es.js +5 -11
- package/dist/domains/traces/components/trace-data-panel-view.es.js.map +1 -1
- package/dist/domains/traces/components/traces-error-content.cjs.js +1 -1
- package/dist/domains/traces/components/traces-error-content.es.js +1 -1
- package/dist/domains/traces/components/traces-list-mode-toggle.cjs.js +2 -2
- package/dist/domains/traces/components/traces-list-mode-toggle.es.js +2 -2
- package/dist/domains/traces/components/traces-list-view.cjs.js +2 -2
- package/dist/domains/traces/components/traces-list-view.es.js +2 -2
- package/dist/domains/traces/components/traces-toolbar.cjs.js +1 -1
- package/dist/domains/traces/components/traces-toolbar.es.js +1 -1
- package/dist/{drawer-CdsTitFp.cjs → drawer-Bng-J6Ne.cjs} +2 -2
- package/dist/{drawer-CdsTitFp.cjs.map → drawer-Bng-J6Ne.cjs.map} +1 -1
- package/dist/{drawer-DZ9amYo_.js → drawer-D9Cp7w6N.js} +2 -2
- package/dist/{drawer-DZ9amYo_.js.map → drawer-D9Cp7w6N.js.map} +1 -1
- package/dist/{dropdown-menu-ppWztidX.cjs → dropdown-menu-BZGlERgf.cjs} +4 -3
- package/dist/dropdown-menu-BZGlERgf.cjs.map +1 -0
- package/dist/{dropdown-menu-DEFygDZI.js → dropdown-menu-DCMh8P4w.js} +4 -3
- package/dist/dropdown-menu-DCMh8P4w.js.map +1 -0
- package/dist/ee/signals/components/signals-empty-state.cjs.js +1 -1
- package/dist/ee/signals/components/signals-empty-state.es.js +1 -1
- package/dist/ee/topics/components/topic-trace-summary-list.cjs.js +3 -3
- package/dist/ee/topics/components/topic-trace-summary-list.es.js +3 -3
- package/dist/{hover-card-crVofiZO.js → hover-card-Bs845QbV.js} +2 -2
- package/dist/{hover-card-crVofiZO.js.map → hover-card-Bs845QbV.js.map} +1 -1
- package/dist/{hover-card-Bx258om1.cjs → hover-card-Cd9QK50X.cjs} +2 -2
- package/dist/{hover-card-Bx258om1.cjs.map → hover-card-Cd9QK50X.cjs.map} +1 -1
- package/dist/{input-group-Dzs-ai0n.js → input-group-BnnvYySr.js} +2 -2
- package/dist/{input-group-Dzs-ai0n.js.map → input-group-BnnvYySr.js.map} +1 -1
- package/dist/{input-group-CH72YUVL.cjs → input-group-BxAiZUo5.cjs} +2 -2
- package/dist/{input-group-CH72YUVL.cjs.map → input-group-BxAiZUo5.cjs.map} +1 -1
- package/dist/{markdown-renderer-Bi2fWeoF.js → markdown-renderer-Bpucep5E.js} +36 -18
- package/dist/markdown-renderer-Bpucep5E.js.map +1 -0
- package/dist/{markdown-renderer-DwfNrhEH.cjs → markdown-renderer-tuX3CjAv.cjs} +36 -18
- package/dist/markdown-renderer-tuX3CjAv.cjs.map +1 -0
- package/dist/{property-filter-applied-DI4w1ACS.js → property-filter-applied-CdhgsCC8.js} +3 -3
- package/dist/{property-filter-applied-DI4w1ACS.js.map → property-filter-applied-CdhgsCC8.js.map} +1 -1
- package/dist/{property-filter-applied-BhxbHAN8.cjs → property-filter-applied-DROoy70i.cjs} +3 -3
- package/dist/{property-filter-applied-BhxbHAN8.cjs.map → property-filter-applied-DROoy70i.cjs.map} +1 -1
- package/dist/resize/panel-drawer.cjs.js +1 -1
- package/dist/resize/panel-drawer.es.js +1 -1
- package/dist/{search-field-block-DCnFZzRK.js → search-field-block-C15VrrNp.js} +2 -2
- package/dist/{search-field-block-DCnFZzRK.js.map → search-field-block-C15VrrNp.js.map} +1 -1
- package/dist/{search-field-block-D6TdrHZX.cjs → search-field-block-wjh5uz7E.cjs} +2 -2
- package/dist/{search-field-block-D6TdrHZX.cjs.map → search-field-block-wjh5uz7E.cjs.map} +1 -1
- package/dist/{select-B6ce20XX.cjs → select-DgOJ6a0U.cjs} +2 -2
- package/dist/{select-B6ce20XX.cjs.map → select-DgOJ6a0U.cjs.map} +1 -1
- package/dist/{select-Beo8qQ0e.js → select-DzvxwWFF.js} +2 -2
- package/dist/{select-Beo8qQ0e.js.map → select-DzvxwWFF.js.map} +1 -1
- package/dist/{select-field-block-DXw3tD0y.js → select-field-block-BWwOG2cP.js} +2 -2
- package/dist/{select-field-block-DXw3tD0y.js.map → select-field-block-BWwOG2cP.js.map} +1 -1
- package/dist/{select-field-block-svlHplxW.cjs → select-field-block-DY9ebut9.cjs} +2 -2
- package/dist/{select-field-block-svlHplxW.cjs.map → select-field-block-DY9ebut9.cjs.map} +1 -1
- package/dist/src/ds/components/MainSidebar/main-sidebar-nav-item-classes.d.ts +13 -2
- package/dist/src/ds/components/MainSidebar/main-sidebar-nav-link.d.ts +2 -2
- package/dist/src/ds/components/MarkdownRenderer/markdown-renderer.d.ts +3 -1
- package/dist/src/ds/components/SankeyChart/sankey-chart.d.ts +7 -2
- package/dist/src/ds/components/SankeyChart/sankey-portal-tooltip.d.ts +8 -0
- package/dist/src/ds/components/SankeyChart/use-sankey-geometry-transition.d.ts +11 -0
- package/dist/src/ds/components/SankeyChart/use-sankey-hover-tooltip.d.ts +15 -0
- package/dist/style.css +31 -4
- package/dist/{time-picker-mLzcoQMO.js → time-picker-BOncuX6N.js} +2 -2
- package/dist/{time-picker-mLzcoQMO.js.map → time-picker-BOncuX6N.js.map} +1 -1
- package/dist/{time-picker-BOQtPoyD.cjs → time-picker-D5KGkYTX.cjs} +2 -2
- package/dist/{time-picker-BOQtPoyD.cjs.map → time-picker-D5KGkYTX.cjs.map} +1 -1
- package/dist/{traces-data-list-vsvvvEiP.cjs → traces-data-list-BnQncyG0.cjs} +2 -2
- package/dist/{traces-data-list-vsvvvEiP.cjs.map → traces-data-list-BnQncyG0.cjs.map} +1 -1
- package/dist/{traces-data-list-DtuaCDES.js → traces-data-list-cySY6wpT.js} +2 -2
- package/dist/{traces-data-list-DtuaCDES.js.map → traces-data-list-cySY6wpT.js.map} +1 -1
- package/package.json +6 -6
- package/theme.css +8 -0
- package/dist/Button-Bm94fEF2.cjs.map +0 -1
- package/dist/Button-Bx2lFdqb.js.map +0 -1
- package/dist/dropdown-menu-DEFygDZI.js.map +0 -1
- package/dist/dropdown-menu-ppWztidX.cjs.map +0 -1
- package/dist/markdown-renderer-Bi2fWeoF.js.map +0 -1
- package/dist/markdown-renderer-DwfNrhEH.cjs.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { useState, useContext, createContext, useRef, useEffect, useMemo,
|
|
2
|
+
import { useState, useContext, createContext, useId, useRef, useEffect, useMemo, useSyncExternalStore } from 'react';
|
|
3
3
|
import { b as buildSankeyHueMap, n as nodeColor, a as nodeColorVivid } from '../sankeyColor-CQ5nkgtL.js';
|
|
4
4
|
export { h as hashHue } from '../sankeyColor-CQ5nkgtL.js';
|
|
5
|
-
import { createPortal } from 'react-dom';
|
|
6
5
|
import { ResponsiveContainer, Sankey as Sankey$1 } from 'recharts';
|
|
6
|
+
import { createPortal } from 'react-dom';
|
|
7
7
|
import { C as Colors } from '../spacings-C87dXiT-.js';
|
|
8
8
|
import { c as cn } from '../cn-BakJzhuv.js';
|
|
9
9
|
|
|
@@ -315,6 +315,82 @@ function orderColumns(columns, order) {
|
|
|
315
315
|
);
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
+
const SANKEY_TOOLTIP_MAX_WIDTH_PX = 320;
|
|
319
|
+
const TOOLTIP_TOP_FLIP_THRESHOLD = 120;
|
|
320
|
+
const TOOLTIP_EDGE_INSET = 16;
|
|
321
|
+
const TOOLTIP_RIGHT_INSET = SANKEY_TOOLTIP_MAX_WIDTH_PX + TOOLTIP_EDGE_INSET;
|
|
322
|
+
function useSankeyHoverTooltip(enabled) {
|
|
323
|
+
const id = useId();
|
|
324
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
325
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
326
|
+
const [position, setPosition] = useState();
|
|
327
|
+
function showAt(target) {
|
|
328
|
+
if (!enabled) return;
|
|
329
|
+
const rect = target.getBoundingClientRect();
|
|
330
|
+
const placement = rect.top < TOOLTIP_TOP_FLIP_THRESHOLD ? "below" : "above";
|
|
331
|
+
setPosition({
|
|
332
|
+
left: Math.min(
|
|
333
|
+
Math.max(rect.left, TOOLTIP_EDGE_INSET),
|
|
334
|
+
Math.max(window.innerWidth - TOOLTIP_RIGHT_INSET, TOOLTIP_EDGE_INSET)
|
|
335
|
+
),
|
|
336
|
+
top: placement === "above" ? rect.top - 8 : rect.bottom + 8,
|
|
337
|
+
placement
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
id,
|
|
342
|
+
position,
|
|
343
|
+
isVisible: Boolean(enabled && position && (isHovered || isFocused)),
|
|
344
|
+
showOnHover(target) {
|
|
345
|
+
setIsHovered(true);
|
|
346
|
+
showAt(target);
|
|
347
|
+
},
|
|
348
|
+
hideOnLeave() {
|
|
349
|
+
setIsHovered(false);
|
|
350
|
+
},
|
|
351
|
+
showOnFocus(target) {
|
|
352
|
+
setIsFocused(true);
|
|
353
|
+
showAt(target);
|
|
354
|
+
},
|
|
355
|
+
hideOnBlur() {
|
|
356
|
+
setIsFocused(false);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function SankeyPortalTooltip({
|
|
362
|
+
id,
|
|
363
|
+
title,
|
|
364
|
+
description,
|
|
365
|
+
position,
|
|
366
|
+
visible
|
|
367
|
+
}) {
|
|
368
|
+
if (!visible || !position) return null;
|
|
369
|
+
return createPortal(
|
|
370
|
+
/* @__PURE__ */ jsxs(
|
|
371
|
+
"div",
|
|
372
|
+
{
|
|
373
|
+
"aria-label": `${title}: ${description}`,
|
|
374
|
+
className: "border-border1 bg-surface5 text-neutral6 shadow-elevated pointer-events-none fixed z-50 rounded-md border p-2 text-xs leading-4",
|
|
375
|
+
id,
|
|
376
|
+
role: "tooltip",
|
|
377
|
+
style: {
|
|
378
|
+
left: position.left,
|
|
379
|
+
maxWidth: `min(${SANKEY_TOOLTIP_MAX_WIDTH_PX}px, calc(100vw - 2rem))`,
|
|
380
|
+
top: position.top,
|
|
381
|
+
transform: position.placement === "above" ? "translateY(-100%)" : void 0,
|
|
382
|
+
width: "max-content"
|
|
383
|
+
},
|
|
384
|
+
children: [
|
|
385
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium", children: title }),
|
|
386
|
+
/* @__PURE__ */ jsx("div", { className: "text-neutral4 whitespace-pre-wrap", children: description })
|
|
387
|
+
]
|
|
388
|
+
}
|
|
389
|
+
),
|
|
390
|
+
document.body
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
318
394
|
function useSankeyChartMeasurements({
|
|
319
395
|
graph,
|
|
320
396
|
height,
|
|
@@ -356,6 +432,117 @@ function useSankeyChartMeasurements({
|
|
|
356
432
|
return { chartContainerRef, fixedGeometry, labelWidths };
|
|
357
433
|
}
|
|
358
434
|
|
|
435
|
+
const TRANSITION_DURATION_MS = 850;
|
|
436
|
+
function mix(from, to, progress) {
|
|
437
|
+
return from + (to - from) * progress;
|
|
438
|
+
}
|
|
439
|
+
function interpolateNode(from, to, progress) {
|
|
440
|
+
return {
|
|
441
|
+
x: mix(from.x, to.x, progress),
|
|
442
|
+
y: mix(from.y, to.y, progress),
|
|
443
|
+
centerY: mix(from.centerY, to.centerY, progress),
|
|
444
|
+
height: mix(from.height, to.height, progress)
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
function interpolateLink(from, to, progress) {
|
|
448
|
+
return {
|
|
449
|
+
sourceX: mix(from.sourceX, to.sourceX, progress),
|
|
450
|
+
targetX: mix(from.targetX, to.targetX, progress),
|
|
451
|
+
sourceY: mix(from.sourceY, to.sourceY, progress),
|
|
452
|
+
targetY: mix(from.targetY, to.targetY, progress),
|
|
453
|
+
sourceWidth: mix(from.sourceWidth, to.sourceWidth, progress),
|
|
454
|
+
targetWidth: mix(from.targetWidth, to.targetWidth, progress)
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function interpolateSankeyGeometry(from, to, progress) {
|
|
458
|
+
const replacedPreviousLinks = [...from.links].filter(([id]) => !to.links.has(id)).map(([, link]) => link);
|
|
459
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
460
|
+
const links = /* @__PURE__ */ new Map();
|
|
461
|
+
for (const [id, target] of to.nodes) {
|
|
462
|
+
nodes.set(id, interpolateNode(from.nodes.get(id) ?? target, target, progress));
|
|
463
|
+
}
|
|
464
|
+
let replacedLinkIndex = 0;
|
|
465
|
+
for (const [id, target] of to.links) {
|
|
466
|
+
const matchingSource = from.links.get(id);
|
|
467
|
+
const syntheticSource = matchingSource ? void 0 : replacedPreviousLinks[replacedLinkIndex++];
|
|
468
|
+
links.set(id, interpolateLink(matchingSource ?? syntheticSource ?? target, target, progress));
|
|
469
|
+
}
|
|
470
|
+
return { nodes, links };
|
|
471
|
+
}
|
|
472
|
+
function prefersReducedMotion() {
|
|
473
|
+
return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
474
|
+
}
|
|
475
|
+
class SankeyGeometryMotionStore {
|
|
476
|
+
animationFrame = 0;
|
|
477
|
+
key;
|
|
478
|
+
listeners = /* @__PURE__ */ new Set();
|
|
479
|
+
snapshot;
|
|
480
|
+
target;
|
|
481
|
+
transition;
|
|
482
|
+
constructor(key, geometry) {
|
|
483
|
+
this.key = key;
|
|
484
|
+
this.snapshot = geometry;
|
|
485
|
+
this.target = geometry;
|
|
486
|
+
}
|
|
487
|
+
getSnapshot = () => this.snapshot;
|
|
488
|
+
subscribe = (listener) => {
|
|
489
|
+
this.listeners.add(listener);
|
|
490
|
+
return () => this.listeners.delete(listener);
|
|
491
|
+
};
|
|
492
|
+
transitionTo(key, geometry) {
|
|
493
|
+
if (key === this.key && geometry === this.target) return;
|
|
494
|
+
const keyChanged = key !== this.key;
|
|
495
|
+
this.key = key;
|
|
496
|
+
this.target = geometry;
|
|
497
|
+
if (!keyChanged && geometry && this.transition) {
|
|
498
|
+
this.transition = { ...this.transition, to: geometry };
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
cancelAnimationFrame(this.animationFrame);
|
|
502
|
+
this.animationFrame = 0;
|
|
503
|
+
if (!keyChanged || !geometry || !this.snapshot || prefersReducedMotion()) {
|
|
504
|
+
this.transition = void 0;
|
|
505
|
+
this.publish(geometry);
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
this.transition = { from: this.snapshot, to: geometry, startedAt: performance.now() };
|
|
509
|
+
this.animationFrame = requestAnimationFrame(this.animate);
|
|
510
|
+
}
|
|
511
|
+
dispose() {
|
|
512
|
+
cancelAnimationFrame(this.animationFrame);
|
|
513
|
+
this.listeners.clear();
|
|
514
|
+
}
|
|
515
|
+
animate = (now) => {
|
|
516
|
+
const transition = this.transition;
|
|
517
|
+
if (!transition) return;
|
|
518
|
+
const elapsed = Math.min((now - transition.startedAt) / TRANSITION_DURATION_MS, 1);
|
|
519
|
+
const progress = 1 - (1 - elapsed) ** 3;
|
|
520
|
+
this.publish(interpolateSankeyGeometry(transition.from, transition.to, progress));
|
|
521
|
+
if (elapsed < 1) {
|
|
522
|
+
this.animationFrame = requestAnimationFrame(this.animate);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
this.transition = void 0;
|
|
526
|
+
this.animationFrame = 0;
|
|
527
|
+
};
|
|
528
|
+
publish(geometry) {
|
|
529
|
+
this.snapshot = geometry;
|
|
530
|
+
for (const listener of this.listeners) listener();
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
function useSankeyGeometryTransition({
|
|
534
|
+
geometry,
|
|
535
|
+
transitionKey
|
|
536
|
+
}) {
|
|
537
|
+
const [store] = useState(() => new SankeyGeometryMotionStore(transitionKey, geometry));
|
|
538
|
+
const animatedGeometry = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
539
|
+
useEffect(() => {
|
|
540
|
+
store.transitionTo(transitionKey, geometry);
|
|
541
|
+
}, [geometry, store, transitionKey]);
|
|
542
|
+
useEffect(() => () => store.dispose(), [store]);
|
|
543
|
+
return animatedGeometry;
|
|
544
|
+
}
|
|
545
|
+
|
|
359
546
|
const NODE_LABEL_FONT_SIZE = 11;
|
|
360
547
|
const COLUMN_LABEL_FONT_SIZE = 12;
|
|
361
548
|
const NODE_LABEL_MAX_CHARACTERS = 23;
|
|
@@ -365,7 +552,10 @@ function SankeyChart({
|
|
|
365
552
|
margin = { top: 64, right: 160, bottom: 12, left: 160 },
|
|
366
553
|
onCurveClick,
|
|
367
554
|
onNodeClick,
|
|
368
|
-
isNodeClickable
|
|
555
|
+
isNodeClickable,
|
|
556
|
+
getColumnDescription,
|
|
557
|
+
hideColumnLabels = false,
|
|
558
|
+
geometryTransitionKey
|
|
369
559
|
}) {
|
|
370
560
|
const { graph, enabledColumns, hueMap, usesFixedGeometry } = useSankeyRenderContext();
|
|
371
561
|
const { chartContainerRef, fixedGeometry, labelWidths } = useSankeyChartMeasurements({
|
|
@@ -374,6 +564,10 @@ function SankeyChart({
|
|
|
374
564
|
margin,
|
|
375
565
|
usesFixedGeometry
|
|
376
566
|
});
|
|
567
|
+
const animatedGeometry = useSankeyGeometryTransition({
|
|
568
|
+
geometry: fixedGeometry,
|
|
569
|
+
transitionKey: geometryTransitionKey
|
|
570
|
+
});
|
|
377
571
|
const [hoveredSourceName, setHoveredSourceName] = useState();
|
|
378
572
|
const [focusedSourceName, setFocusedSourceName] = useState();
|
|
379
573
|
const activeSourceName = hoveredSourceName ?? focusedSourceName;
|
|
@@ -407,8 +601,8 @@ function SankeyChart({
|
|
|
407
601
|
margin,
|
|
408
602
|
node: (props) => {
|
|
409
603
|
const node = graph.nodes[props.index];
|
|
410
|
-
const showColumnLabel = node ? graph.nodes.findIndex((candidate) => candidate.column.id === node.column.id) === props.index : false;
|
|
411
|
-
const nodeGeometry = node ?
|
|
604
|
+
const showColumnLabel = !hideColumnLabels && node ? graph.nodes.findIndex((candidate) => candidate.column.id === node.column.id) === props.index : false;
|
|
605
|
+
const nodeGeometry = node ? animatedGeometry?.nodes.get(node.id) : void 0;
|
|
412
606
|
const selection = node ? getSankeyChartNodeSelection(node) : void 0;
|
|
413
607
|
const clickable = Boolean(
|
|
414
608
|
onNodeClick && selection && (isNodeClickable === void 0 || isNodeClickable(selection))
|
|
@@ -422,6 +616,7 @@ function SankeyChart({
|
|
|
422
616
|
height: nodeGeometry?.height ?? props.height,
|
|
423
617
|
hueMap,
|
|
424
618
|
columnLabel: node?.column.label,
|
|
619
|
+
columnDescription: node ? getColumnDescription?.(node.column) : void 0,
|
|
425
620
|
label: node?.label,
|
|
426
621
|
nodeValue: node?.displayValue,
|
|
427
622
|
layoutValue: nodeGeometry ? void 0 : node ? nodeWeights.get(node.id) : void 0,
|
|
@@ -441,7 +636,7 @@ function SankeyChart({
|
|
|
441
636
|
},
|
|
442
637
|
link: (props) => {
|
|
443
638
|
const link = graph.links[props.index];
|
|
444
|
-
const linkGeometry = link ?
|
|
639
|
+
const linkGeometry = link ? animatedGeometry?.links.get(link.id) : void 0;
|
|
445
640
|
const sourceX = linkGeometry?.sourceX ?? props.sourceX;
|
|
446
641
|
const targetX = linkGeometry?.targetX ?? props.targetX;
|
|
447
642
|
const fixedControlX = linkGeometry ? (sourceX + targetX) / 2 : void 0;
|
|
@@ -482,6 +677,7 @@ function SankeyNode({
|
|
|
482
677
|
payload,
|
|
483
678
|
hueMap,
|
|
484
679
|
columnLabel,
|
|
680
|
+
columnDescription,
|
|
485
681
|
label,
|
|
486
682
|
nodeValue,
|
|
487
683
|
layoutValue,
|
|
@@ -508,10 +704,7 @@ function SankeyNode({
|
|
|
508
704
|
maxCharacters: NODE_LABEL_MAX_CHARACTERS
|
|
509
705
|
});
|
|
510
706
|
const visibleColumnLabel = columnLabel ? truncateSankeyLabel(columnLabel, { fontSize: COLUMN_LABEL_FONT_SIZE, maxWidth: nodeLabelWidth }) : void 0;
|
|
511
|
-
const
|
|
512
|
-
const [isHovered, setIsHovered] = useState(false);
|
|
513
|
-
const [isFocused, setIsFocused] = useState(false);
|
|
514
|
-
const [tooltipPosition, setTooltipPosition] = useState();
|
|
707
|
+
const tooltip = useSankeyHoverTooltip(description !== void 0);
|
|
515
708
|
const numericValue = nodeValue ?? (typeof payload.value === "number" ? payload.value : Number(payload.value));
|
|
516
709
|
const value = Number.isFinite(numericValue) ? String(numericValue) : "";
|
|
517
710
|
const percentage = columnTotal > 0 && Number.isFinite(numericValue) ? Math.round(numericValue / columnTotal * 100) : 0;
|
|
@@ -520,41 +713,27 @@ function SankeyNode({
|
|
|
520
713
|
const textAnchor = isFirstColumn ? "start" : isLastColumn ? "end" : "middle";
|
|
521
714
|
const labelX = isFirstColumn ? x : isLastColumn ? x + width : x + width / 2;
|
|
522
715
|
const hue = hueMap[name] ?? 0;
|
|
523
|
-
const isTooltipVisible = Boolean(description && tooltipPosition && (isHovered || isFocused));
|
|
524
|
-
const showTooltipAt = (target) => {
|
|
525
|
-
const rect = target.getBoundingClientRect();
|
|
526
|
-
const placement = rect.top < 120 ? "below" : "above";
|
|
527
|
-
setTooltipPosition({
|
|
528
|
-
left: Math.min(Math.max(rect.left, 16), Math.max(window.innerWidth - 336, 16)),
|
|
529
|
-
top: placement === "above" ? rect.top - 8 : rect.bottom + 8,
|
|
530
|
-
placement
|
|
531
|
-
});
|
|
532
|
-
};
|
|
533
716
|
const handleKeyDown = (event) => {
|
|
534
717
|
if (event.key !== "Enter" && event.key !== " ") return;
|
|
535
718
|
event.preventDefault();
|
|
536
719
|
onSelect();
|
|
537
720
|
};
|
|
538
721
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
539
|
-
showColumnLabel && visibleColumnLabel ? /* @__PURE__ */
|
|
540
|
-
|
|
722
|
+
showColumnLabel && visibleColumnLabel && columnLabel ? /* @__PURE__ */ jsx(
|
|
723
|
+
SankeyColumnHeader,
|
|
541
724
|
{
|
|
542
725
|
x: labelX,
|
|
543
|
-
y: 18,
|
|
544
726
|
textAnchor,
|
|
545
727
|
fill: nodeColor(hue),
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
visibleColumnLabel === columnLabel ? null : /* @__PURE__ */ jsx("title", { children: columnLabel }),
|
|
550
|
-
visibleColumnLabel
|
|
551
|
-
]
|
|
728
|
+
label: visibleColumnLabel,
|
|
729
|
+
fullLabel: columnLabel,
|
|
730
|
+
description: columnDescription
|
|
552
731
|
}
|
|
553
732
|
) : null,
|
|
554
733
|
/* @__PURE__ */ jsxs(
|
|
555
734
|
"g",
|
|
556
735
|
{
|
|
557
|
-
"aria-describedby": description ?
|
|
736
|
+
"aria-describedby": description ? tooltip.id : void 0,
|
|
558
737
|
"aria-label": `${accessibleLabel}: ${value} ${numericValue === 1 ? "trace" : "traces"} (${percentage}%)`,
|
|
559
738
|
className: "focus-visible:[&>rect]:stroke-neutral6 outline-hidden focus-visible:[&>rect]:stroke-2",
|
|
560
739
|
onClick: clickable ? onSelect : void 0,
|
|
@@ -562,21 +741,19 @@ function SankeyNode({
|
|
|
562
741
|
role: clickable ? "button" : void 0,
|
|
563
742
|
onFocus: (event) => {
|
|
564
743
|
onFocusChange(name);
|
|
565
|
-
|
|
566
|
-
showTooltipAt(event.currentTarget);
|
|
744
|
+
tooltip.showOnFocus(event.currentTarget);
|
|
567
745
|
},
|
|
568
746
|
onBlur: () => {
|
|
569
747
|
onFocusChange(void 0);
|
|
570
|
-
|
|
748
|
+
tooltip.hideOnBlur();
|
|
571
749
|
},
|
|
572
750
|
onMouseEnter: (event) => {
|
|
573
751
|
onHoverChange(name);
|
|
574
|
-
|
|
575
|
-
showTooltipAt(event.currentTarget);
|
|
752
|
+
tooltip.showOnHover(event.currentTarget);
|
|
576
753
|
},
|
|
577
754
|
onMouseLeave: () => {
|
|
578
755
|
onHoverChange(void 0);
|
|
579
|
-
|
|
756
|
+
tooltip.hideOnLeave();
|
|
580
757
|
},
|
|
581
758
|
style: { cursor: clickable ? "pointer" : void 0 },
|
|
582
759
|
tabIndex: 0,
|
|
@@ -604,28 +781,60 @@ function SankeyNode({
|
|
|
604
781
|
]
|
|
605
782
|
}
|
|
606
783
|
),
|
|
607
|
-
description
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
784
|
+
description ? /* @__PURE__ */ jsx(
|
|
785
|
+
SankeyPortalTooltip,
|
|
786
|
+
{
|
|
787
|
+
id: tooltip.id,
|
|
788
|
+
title: visibleDisplayLabel,
|
|
789
|
+
description,
|
|
790
|
+
position: tooltip.position,
|
|
791
|
+
visible: tooltip.isVisible
|
|
792
|
+
}
|
|
793
|
+
) : null
|
|
794
|
+
] });
|
|
795
|
+
}
|
|
796
|
+
function SankeyColumnHeader({
|
|
797
|
+
x,
|
|
798
|
+
textAnchor,
|
|
799
|
+
fill,
|
|
800
|
+
label,
|
|
801
|
+
fullLabel,
|
|
802
|
+
description
|
|
803
|
+
}) {
|
|
804
|
+
const tooltip = useSankeyHoverTooltip(description !== void 0);
|
|
805
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
806
|
+
/* @__PURE__ */ jsxs(
|
|
807
|
+
"text",
|
|
808
|
+
{
|
|
809
|
+
"aria-describedby": description ? tooltip.id : void 0,
|
|
810
|
+
"aria-label": description ? fullLabel : void 0,
|
|
811
|
+
role: description ? "img" : void 0,
|
|
812
|
+
x,
|
|
813
|
+
y: 18,
|
|
814
|
+
textAnchor,
|
|
815
|
+
fill,
|
|
816
|
+
fontSize: COLUMN_LABEL_FONT_SIZE,
|
|
817
|
+
fontWeight: 600,
|
|
818
|
+
tabIndex: description ? 0 : void 0,
|
|
819
|
+
onMouseEnter: description ? (event) => tooltip.showOnHover(event.currentTarget) : void 0,
|
|
820
|
+
onMouseLeave: description ? tooltip.hideOnLeave : void 0,
|
|
821
|
+
onFocus: description ? (event) => tooltip.showOnFocus(event.currentTarget) : void 0,
|
|
822
|
+
onBlur: description ? tooltip.hideOnBlur : void 0,
|
|
823
|
+
children: [
|
|
824
|
+
label === fullLabel || description ? null : /* @__PURE__ */ jsx("title", { children: fullLabel }),
|
|
825
|
+
label
|
|
826
|
+
]
|
|
827
|
+
}
|
|
828
|
+
),
|
|
829
|
+
description ? /* @__PURE__ */ jsx(
|
|
830
|
+
SankeyPortalTooltip,
|
|
831
|
+
{
|
|
832
|
+
id: tooltip.id,
|
|
833
|
+
title: fullLabel,
|
|
834
|
+
description,
|
|
835
|
+
position: tooltip.position,
|
|
836
|
+
visible: tooltip.isVisible
|
|
837
|
+
}
|
|
629
838
|
) : null
|
|
630
839
|
] });
|
|
631
840
|
}
|