byDefaultHuman
Components

Callout Arrow

A hand-drawn curved arrow connecting two DOM elements.

Basic Usage

The CalloutArrow component creates a dynamic, hand-drawn connection between two elements using React refs. It renders into a fixed SVG overlay, allowing it to span across different layout containers.

Annotation Start
Main Content Area

Installation

package manager
npx shadcn add https://bydefaulthuman.fun/r/callout-arrow.json

Props

PropTypeDefaultDescription
className
string
Additional Tailwind classes applied to the component.
color
string
"currentColor"
Overrides the main accent or stroke color.
curvature
number
80
Controls the arrow bend amount.
fromRef*
RefObject<HTMLElement | null>
Reference to the starting element.
id
string
Optional stable id used for sketch seeding and accessibility.
label
ReactNode
Optional label text shown with the component.
style
CSSProperties
Controls the `style` behavior.
theme
CrumbleTheme
Overrides the global Crumble theme for this instance.
toRef*
RefObject<HTMLElement | null>
Reference to the target element.
withHead
boolean
true
Shows an arrow head at the end of the callout.

Customization

Curvature

Adjust the curvature prop to change the arc. Positive values bow one way, negative values the other, and 0 results in a straight line.

Main Content Area

Color

The arrow and label inherit the current text color by default, but you can pass any valid CSS color string to the color prop.

Main Content Area

Accessibility

CalloutArrow is decorative and renders aria-hidden. Any relationship the arrow implies between two elements should also be explained in nearby text.

Examples

import { useRef } from "react";
import { CalloutArrow } from "@/components/ui/callout-arrow";

export default function Demo() {
  const fromRef = useRef(null);
  const toRef = useRef(null);

  return (
    <div className="flex flex-col items-center gap-12">
      <div ref={fromRef}>Source</div>
      <div ref={toRef}>Target</div>
      <CalloutArrow fromRef={fromRef} toRef={toRef} label="Look here!" />
    </div>
  );
}