Implementation:TobikoData Sqlmesh NodePort
| Knowledge Sources | |
|---|---|
| Domains | Web_UI, Lineage_Visualization |
| Last Updated | 2026-02-07 20:00 GMT |
Overview
React component that renders connection ports on lineage nodes with handles for incoming and outgoing edges.
Description
NodePort is a React component that creates connection points on lineage graph nodes for column-level lineage visualization. It uses useNodeConnections from React Flow to detect which edges connect to the port as sources (outgoing) or targets (incoming). The component conditionally renders left and right handles based on connection existence: left handles appear for ports with incoming connections (targets), right handles appear for ports with outgoing connections (sources). Each handle is styled with circular badges (rounded-full with padding) colored via CSS variables: bg-lineage-node-port-handle-target for incoming and bg-lineage-node-port-handle-source for outgoing. The component wraps children in a NodeHandles container with appropriate styling and positioning.
Usage
Use this component when rendering columns or other sub-elements within lineage nodes that need to be connected to other nodes at a granular level, such as column-to-column lineage connections in SQL transformation graphs.
Code Reference
Source Location
- Repository: TobikoData_Sqlmesh
- File: web/common/src/components/Lineage/node/NodePort.tsx
Signature
export function NodePort<
TPortId extends string = PortHandleId,
TNodeID extends string = NodeId,
TLeftPortHandleId extends string = PortHandleId,
TRightPortHandleId extends string = PortHandleId,
>({
id,
nodeId,
className,
children,
}: {
id: TPortId
nodeId: TNodeID
className?: string
children: React.ReactNode
})
Import
import { NodePort } from '@sqlmesh-common/components/Lineage/node/NodePort'
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| id | TPortId | Yes | Unique identifier for the port (handle ID) |
| nodeId | TNodeID | Yes | Identifier of the parent node |
| className | string | No | Additional CSS classes for styling |
| children | React.ReactNode | Yes | Content to render inside the port (e.g., column information) |
Outputs
| Name | Type | Description |
|---|---|---|
| Component | React.ReactElement | Port container with conditional connection handles |
Usage Examples
import { NodePort } from '@sqlmesh-common/components/Lineage/node/NodePort'
// Basic usage in a lineage node
function LineageNode({ nodeId, columns, selectedColumns }) {
return (
<div className="lineage-node">
<h3>{nodeId}</h3>
{/* Render selected columns as ports with connection handles */}
{selectedColumns.map(column => (
<NodePort
key={column.id}
id={column.id} // e.g., "model1.column1"
nodeId={nodeId} // e.g., "model1"
className="border-t border-gray-200"
>
<ColumnDisplay
name={column.name}
type={column.type}
description={column.description}
/>
</NodePort>
))}
{/* Regular columns without ports */}
{columns.map(column => (
<ColumnDisplay key={column.id} {...column} />
))}
</div>
)
}
// In column-level lineage
function ColumnLevelLineageNode({ model, selectedColumns }) {
return (
<div>
<div className="model-header">{model.name}</div>
{/* Selected columns get connection ports */}
<div className="selected-columns">
{selectedColumns.map(col => (
<NodePort
id={`${model.name}.${col.name}`}
nodeId={model.name}
className="bg-blue-50"
>
<div className="flex items-center gap-2">
<span>{col.name}</span>
<span className="text-gray-500">{col.data_type}</span>
</div>
</NodePort>
))}
</div>
</div>
)
}
// Port handles are automatically shown based on connections:
// - Left handle (target) appears if port receives connections
// - Right handle (source) appears if port sends connections
// - Both handles appear if port has both incoming and outgoing
// - No handles appear if port has no connections