From e3dc44f6f90c430d8434f4c63096607eb2bdc8cd Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 21:50:11 -0700 Subject: [PATCH 1/2] fix(canvas): replace native title tooltip with styled overflow tooltip on block params Hovering a truncated subblock value or block name on the canvas popped the browser's raw native tooltip with the full untruncated content (including raw code). Replace the `title` attribute with the cursor-following styled Tooltip, shown only when the text is actually clipped. --- .../src/lib/overflow-span.tsx | 29 +++++++++++++++++++ .../src/workflow-block/sub-block-row-view.tsx | 17 +++++------ .../workflow-block/workflow-block-view.tsx | 9 +++--- 3 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 packages/workflow-renderer/src/lib/overflow-span.tsx diff --git a/packages/workflow-renderer/src/lib/overflow-span.tsx b/packages/workflow-renderer/src/lib/overflow-span.tsx new file mode 100644 index 00000000000..accae68b02b --- /dev/null +++ b/packages/workflow-renderer/src/lib/overflow-span.tsx @@ -0,0 +1,29 @@ +import { FloatingTooltip, isTextClipped, useFloatingTooltip, useIsOverflowing } from '@sim/emcn' + +interface OverflowSpanProps { + value: string + className: string +} + +/** + * Truncated span that reveals its full value in a floating tooltip when — and + * only when — the text is actually clipped. Never use a native `title` + * attribute here: on the canvas it pops the browser's raw, unstyled tooltip + * with the full untruncated value (including raw code/JSON) over the graph. + */ +export function OverflowSpan({ value, className }: OverflowSpanProps) { + const { ref, node } = useIsOverflowing() + const { state, handlers } = useFloatingTooltip(() => { + const element = node.current + return element !== null && isTextClipped(element) + }) + + return ( + <> + + {value} + + + + ) +} diff --git a/packages/workflow-renderer/src/workflow-block/sub-block-row-view.tsx b/packages/workflow-renderer/src/workflow-block/sub-block-row-view.tsx index 01930cdcac1..7be0b0bb7b6 100644 --- a/packages/workflow-renderer/src/workflow-block/sub-block-row-view.tsx +++ b/packages/workflow-renderer/src/workflow-block/sub-block-row-view.tsx @@ -1,4 +1,5 @@ import { cn } from '@sim/emcn' +import { OverflowSpan } from '../lib/overflow-span' /** * Props for the pure subblock summary row. The container resolves the value — @@ -22,22 +23,18 @@ export interface SubBlockRowViewProps { export function SubBlockRowView({ title, displayValue, isMonospace }: SubBlockRowViewProps) { return (
- - {title} - + /> {displayValue !== undefined && ( - - {displayValue} - + /> )}
) diff --git a/packages/workflow-renderer/src/workflow-block/workflow-block-view.tsx b/packages/workflow-renderer/src/workflow-block/workflow-block-view.tsx index 3b7dbb36cec..cf43c63796d 100644 --- a/packages/workflow-renderer/src/workflow-block/workflow-block-view.tsx +++ b/packages/workflow-renderer/src/workflow-block/workflow-block-view.tsx @@ -2,6 +2,7 @@ import type { ComponentType, ReactNode, Ref } from 'react' import { Badge, cn, handleKeyboardActivation, Tooltip } from '@sim/emcn' import { Handle, Position } from 'reactflow' import { HANDLE_POSITIONS } from '../dimensions' +import { OverflowSpan } from '../lib/overflow-span' import { tileIconColorClass } from '../lib/tile-icon-color' import type { BlockRunStatus } from '../types' import { SubBlockRowView } from './sub-block-row-view' @@ -212,15 +213,13 @@ export function WorkflowBlockView({ )} /> - - {name} - + />
{isWorkflowSelector && From 6e06e6cfb40a33f877c71895aba0881bc8aa78ae Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 21:54:21 -0700 Subject: [PATCH 2/2] fix(canvas): drop unused ResizeObserver in OverflowSpan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit useFloatingTooltip's canShow already receives the hovered element, so measuring overflow via useIsOverflowing was redundant — every canvas row was paying for a ResizeObserver and resize listener it never used. --- packages/workflow-renderer/src/lib/overflow-span.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/workflow-renderer/src/lib/overflow-span.tsx b/packages/workflow-renderer/src/lib/overflow-span.tsx index accae68b02b..65437f0d8a5 100644 --- a/packages/workflow-renderer/src/lib/overflow-span.tsx +++ b/packages/workflow-renderer/src/lib/overflow-span.tsx @@ -1,4 +1,4 @@ -import { FloatingTooltip, isTextClipped, useFloatingTooltip, useIsOverflowing } from '@sim/emcn' +import { FloatingTooltip, isTextClipped, useFloatingTooltip } from '@sim/emcn' interface OverflowSpanProps { value: string @@ -12,15 +12,11 @@ interface OverflowSpanProps { * with the full untruncated value (including raw code/JSON) over the graph. */ export function OverflowSpan({ value, className }: OverflowSpanProps) { - const { ref, node } = useIsOverflowing() - const { state, handlers } = useFloatingTooltip(() => { - const element = node.current - return element !== null && isTextClipped(element) - }) + const { state, handlers } = useFloatingTooltip(isTextClipped) return ( <> - + {value}