{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "rough-arrow", "title": "RoughArrow", "description": "Hand-drawn curved arrow SVG primitive.", "dependencies": [ "roughjs" ], "registryDependencies": [ "https://www.bydefaulthuman.fun/r/use-rough.json", "https://www.bydefaulthuman.fun/r/crumble-theme.json", "https://www.bydefaulthuman.fun/r/rough-lib.json", "utils" ], "files": [ { "path": "registry/new-york/primitives/rough-arrow.tsx", "content": "\"use client\";\n\nimport { useCallback, useEffect } from \"react\";\nimport type { CrumbleTheme } from \"@/lib/rough\";\nimport { useRough } from \"@/hooks/use-rough\";\n\nexport interface RoughArrowProps {\n className?: string;\n curvature?: number;\n height?: number;\n id?: string;\n stroke?: string;\n theme?: CrumbleTheme;\n width?: number;\n x1: number;\n x2: number;\n y1: number;\n y2: number;\n}\n\nexport function RoughArrow({\n className,\n curvature = 30,\n height = 100,\n id,\n stroke,\n theme: themeProp,\n width = 200,\n x1,\n x2,\n y1,\n y2,\n}: RoughArrowProps) {\n const { drawLine, drawPath, svgRef, theme } = useRough({\n stableId: id,\n theme: themeProp,\n variant: \"border\",\n });\n\n const draw = useCallback(() => {\n const svg = svgRef.current;\n if (!svg) return;\n\n svg.replaceChildren();\n\n const strokeColor = stroke ?? \"currentColor\";\n const midX = (x1 + x2) / 2;\n const midY = (y1 + y2) / 2 - curvature;\n const pathD = `M ${x1} ${y1} Q ${midX} ${midY} ${x2} ${y2}`;\n\n const lineNode = drawPath(pathD, {\n fill: \"none\",\n stroke: strokeColor,\n });\n\n if (lineNode) {\n svg.appendChild(lineNode);\n }\n\n const angle = Math.atan2(y2 - midY, x2 - midX);\n const arrowSize = theme === \"crayon\" ? 12 : 8;\n const ax1 = x2 - arrowSize * Math.cos(angle - Math.PI / 6);\n const ay1 = y2 - arrowSize * Math.sin(angle - Math.PI / 6);\n const ax2 = x2 - arrowSize * Math.cos(angle + Math.PI / 6);\n const ay2 = y2 - arrowSize * Math.sin(angle + Math.PI / 6);\n\n const head1 = drawLine(x2, y2, ax1, ay1, { stroke: strokeColor });\n const head2 = drawLine(x2, y2, ax2, ay2, { stroke: strokeColor });\n\n if (head1) {\n svg.appendChild(head1);\n }\n\n if (head2) {\n svg.appendChild(head2);\n }\n }, [curvature, drawLine, drawPath, stroke, svgRef, theme, x1, x2, y1, y2]);\n\n useEffect(() => {\n draw();\n }, [draw, theme]);\n\n return (\n \n );\n}\n", "type": "registry:ui", "target": "components/crumble/primitives/rough-arrow.tsx" } ], "type": "registry:ui" }