Connector
ProA measured line between two elements with a label on it, for showing that one passage overrides another or that two records disagree.
npx prodular-ui add connectorPart of Prodular UI Pro. Preview and read the docs freely, install with a license. See pricing
Bracket
Two passages in one column. The line runs down their left and follows them when the layout changes.
Master agreement, section 12.2
Total liability is limited to the fees paid in the prior twelve months. This limit applies to every claim under this agreement.
Sections 12.3 to 14.1 cover notices, assignment and the term of the agreement, and do not change the limit above.
Exhibit B, section 9.2
Data protection claims are not subject to any limit of liability. Where this exhibit conflicts with the agreement, this exhibit controls.
import { Connector, ConnectorAnchor, ConnectorLabel, ConnectorRoot } from "@/components/ui/connector"import { Highlight } from "@/components/ui/highlight"
export default function ConnectorBracket() { return ( <ConnectorRoot className="w-full max-w-2xl py-2 pl-24"> <div className="flex flex-col gap-6 text-sm leading-6 text-foreground"> <section> <h3 className="m-0 mb-1 text-[13px] font-normal text-muted-foreground">Master agreement, section 12.2</h3> <p className="m-0"> <ConnectorAnchor name="msa" render={<span />}> <Highlight>Total liability is limited to the fees paid in the prior twelve months.</Highlight> </ConnectorAnchor>{" "} This limit applies to every claim under this agreement. </p> </section> <p className="m-0 text-muted-foreground">Sections 12.3 to 14.1 cover notices, assignment and the term of the agreement, and do not change the limit above.</p> <section> <h3 className="m-0 mb-1 text-[13px] font-normal text-muted-foreground">Exhibit B, section 9.2</h3> <p className="m-0"> <ConnectorAnchor name="exhibit" render={<span />}> <Highlight>Data protection claims are not subject to any limit of liability.</Highlight> </ConnectorAnchor>{" "} Where this exhibit conflicts with the agreement, this exhibit controls. </p> </section> </div> <Connector from="msa" to="exhibit" shape="bracket" inset={56} className="text-foreground"> <ConnectorLabel>Overrides</ConnectorLabel> </Connector> </ConnectorRoot> )}Bridge
Two things side by side. The line crosses the gutter, and steps aside when they stack on a phone.
Purchase order PO-1187
Invoice INV-2047
import { Connector, ConnectorAnchor, ConnectorLabel, ConnectorRoot } from "@/components/ui/connector"
function Row({ label, value }: { label: string; value: string }) { return ( <div className="flex items-baseline justify-between gap-4 py-2 text-sm"> <span className="text-muted-foreground">{label}</span> <span className="font-medium tabular-nums">{value}</span> </div> )}
export default function ConnectorBridge() { return ( <ConnectorRoot className="grid w-full max-w-2xl grid-cols-1 gap-6 sm:grid-cols-2 sm:gap-24"> <div> <h3 className="m-0 mb-1 text-[13px] font-normal text-muted-foreground">Purchase order PO-1187</h3> <div className="divide-y"> <Row label="Platform fee" value="$12,000.00" /> <ConnectorAnchor name="po"> <Row label="Onboarding" value="$4,500.00" /> </ConnectorAnchor> <Row label="Support" value="$1,800.00" /> </div> </div> <div> <h3 className="m-0 mb-1 text-[13px] font-normal text-muted-foreground">Invoice INV-2047</h3> <div className="divide-y"> <Row label="Platform fee" value="$12,000.00" /> <Row label="Support" value="$1,800.00" /> <ConnectorAnchor name="invoice"> <Row label="Onboarding" value="$6,000.00" /> </ConnectorAnchor> </div> </div> <Connector from="po" to="invoice" shape="bridge" className="text-warning-subtle-foreground"> <ConnectorLabel>+$1,500</ConnectorLabel> </Connector> </ConnectorRoot> )}Anatomy
<ConnectorRoot className="pl-24"> <ConnectorAnchor name="a">…</ConnectorAnchor> <ConnectorAnchor name="b">…</ConnectorAnchor> <Connector from="a" to="b" shape="bracket" inset={56}> <ConnectorLabel>Overrides</ConnectorLabel> </Connector></ConnectorRoot>Guidance
Use it when
- Use it when the relationship is the point: this clause overrides that one, this invoice line does not match that order.
- Say the relationship in the label, in a few words.
- Use one connector at a time. Show the one that matters to the item in review.
Avoid
- Diagrams and flows with many nodes. It draws one line, not a graph.
- Decoration. If nothing would be lost without the line, leave it out.
- Anchors in different scroll containers. Both ends must sit inside one ConnectorRoot.
Rules for AI agents
Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.
- Wrap both ends and the Connector in one ConnectorRoot, and leave room on the left for a bracket and half its label: pl-24 with inset={56} fits a one-word label.
- Mark each end with ConnectorAnchor and a unique name. Pass render={<span />} when the anchor sits inside a paragraph.
- The line is hidden from screen readers. State the same relationship in text near it, or in the ConnectorLabel.
- Set the colour with a text-* token on Connector. Use a status subtle foreground only when the relationship is a problem.
API
Connector
| Prop | Type | Default | Description |
|---|---|---|---|
| from / to | string | Names of the two ConnectorAnchors. | |
| shape | "bracket" | "bridge" | "bracket" | bracket runs down the left of both anchors. bridge crosses a gutter between them. |
| inset | number | 20 | bracket: how far left of the anchors the line runs, in px. |
| at | number | 0.5 | Where the label sits along the line, 0 to 1. |
| labelAlign | "center" | "start" | "center" | start begins the label at the line, so a wide label stays clear of the margin. |
ConnectorAnchor
| Prop | Type | Default | Description |
|---|---|---|---|
| name | string | Required. What a Connector refers to. | |
| render | ReactElement | The element to render, for example <span /> inside text. |
Installation
The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.
npx prodular-ui add connector# or, with the registry in components.jsonnpx shadcn@latest add @prodular/connector