This component no longer exists. It was in godui’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-07 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
Comment Pin
godui/comment-pinRemovedComponent
Figma-style annotation pins that spring in over any surface and expand into a threaded comment popover with a reply field.
Install it
npx shadcn@latest add https://godui.design/r/comment-pin.jsonSource
1"use client";23import { AnimatePresence, motion } from "framer-motion";4import * as React from "react";5import { initials, presenceColor } from "../lib/presence";67export type Comment = {8 id: string;9 author: string;10 avatar?: string;11 body: string;12 time?: string;13};1415export type CommentPinProps = Omit<16 React.HTMLAttributes<HTMLDivElement>,17 "onSubmit"18> & {19 /** Horizontal position as a percentage of the container (0–100). */20 x: number;21 /** Vertical position as a percentage of the container (0–100). */22 y: number;23 /** Thread comments. */24 comments?: Comment[];25 /** Pin face label — defaults to the first author's initials, else a dot. */26 label?: React.ReactNode;27 color?: string;28 resolved?: boolean;29 defaultOpen?: boolean;30 open?: boolean;31 onOpenChange?: (open: boolean) => void;32 /** Show a reply field and fire on submit. */33 onReply?: (text: string) => void;34};3536const CommentPin = React.forwardRef<HTMLDivElement, CommentPinProps>(37 (38 {39 x,40 y,41 comments = [],42 label,43 color,44 resolved = false,45 defaultOpen = false,46 open: controlledOpen,47 onOpenChange,48 onReply,49 className,50 style,51 ...props52 },53 ref,54 ) => {55 const isControlled = controlledOpen !== undefined;56 const [internalOpen, setInternalOpen] = React.useState(defaultOpen);57 const open = isControlled ? controlledOpen : internalOpen;58 const [reply, setReply] = React.useState("");5960 const setOpen = (next: boolean) => {61 if (!isControlled) setInternalOpen(next);62 onOpenChange?.(next);63 };6465 const pinColor = color ?? presenceColor(comments[0]?.author ?? `${x},${y}`);66 const face = label ?? (comments[0] ? initials(comments[0].author) : null);6768 return (69 <div70 ref={ref}71 data-slot="comment-pin"72 data-resolved={resolved ? "" : undefined}73 data-open={open ? "" : undefined}74 className={`absolute z-raised ${className ?? ""}`}75 style={{ left: `${x}%`, top: `${y}%`, ...style }}76 {...props}77 >78 <motion.button79 type="button"80 layout81 initial={{ scale: 0 }}82 animate={{ scale: resolved ? 0.85 : 1 }}83 transition={{ type: "spring", stiffness: 520, damping: 32 }}84 onClick={() => setOpen(!open)}85 aria-label={resolved ? "Resolved comment" : "Open comment thread"}86 aria-expanded={open}87// … truncated
What it pulls in
npm packages
Other registry items
