BaseNode (structured node shell with header/content/footer slots), BaseHandle (styled connection handle), LabeledHandle (handle with port label), NodeStatusIndicator (status border effect), NodeTooltip (hover details via NodeToolbar). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
78 lines
1.7 KiB
TypeScript
78 lines
1.7 KiB
TypeScript
import { createContext, useContext, useState, useCallback, type ReactNode, type ComponentProps } from 'react'
|
|
import { NodeToolbar, type NodeToolbarProps } from '@xyflow/react'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
interface NodeTooltipContextValue {
|
|
visible: boolean
|
|
show: () => void
|
|
hide: () => void
|
|
}
|
|
|
|
const NodeTooltipContext = createContext<NodeTooltipContextValue>({
|
|
visible: false,
|
|
show: () => {},
|
|
hide: () => {},
|
|
})
|
|
|
|
export function NodeTooltip({ children, ...props }: ComponentProps<'div'>) {
|
|
const [visible, setVisible] = useState(false)
|
|
const show = useCallback(() => setVisible(true), [])
|
|
const hide = useCallback(() => setVisible(false), [])
|
|
|
|
return (
|
|
<NodeTooltipContext.Provider value={{ visible, show, hide }}>
|
|
<div {...props}>{children}</div>
|
|
</NodeTooltipContext.Provider>
|
|
)
|
|
}
|
|
|
|
export function NodeTooltipTrigger({
|
|
children,
|
|
onMouseEnter,
|
|
onMouseLeave,
|
|
...props
|
|
}: ComponentProps<'div'>) {
|
|
const { show, hide } = useContext(NodeTooltipContext)
|
|
|
|
return (
|
|
<div
|
|
onMouseEnter={(e) => {
|
|
show()
|
|
onMouseEnter?.(e)
|
|
}}
|
|
onMouseLeave={(e) => {
|
|
hide()
|
|
onMouseLeave?.(e)
|
|
}}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export function NodeTooltipContent({
|
|
className,
|
|
position,
|
|
children,
|
|
...props
|
|
}: Omit<NodeToolbarProps, 'children'> & { children: ReactNode }) {
|
|
const { visible } = useContext(NodeTooltipContext)
|
|
|
|
if (!visible) return null
|
|
|
|
return (
|
|
<NodeToolbar
|
|
position={position}
|
|
className={cn(
|
|
'rounded-lg border border-default bg-elevated px-3 py-2',
|
|
'pointer-events-none',
|
|
className,
|
|
)}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</NodeToolbar>
|
|
)
|
|
}
|