Edu Calvo

Figma Comment

Component

About

A Figma-style comment pin that springs open from a 32px bubble into a full note, measures its own height, and closes on click outside. Respects prefers-reduced-motion.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Figma Comment to your project and fits it to your theme.

Code

How Figma Comment is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

"use client";

import Component from "@/components/ui/figma-comment";

const PINS = [
  {
    authorName: "Edu Calvo",
    defaultOpen: true,
    left: "52%",
    message:
      "What happens if we adjust this to handle light and dark mode? The pink loses contrast on the dark surface.",
    timestamp: "Just now",
    top: "26%",
    width: 220,
  },
  {
    authorName: "Marta Ruiz",
    defaultOpen: false,
    left: "62%",
    message:
      "The card radius and the image radius disagree by 4px — concentric them so the inner corner reads as parallel.",
    timestamp: "2h",
    top: "50%",
    width: 210,
  },
  {
    authorName: "Nil Prat",
    defaultOpen: false,
    left: "34%",
    message: "Ship it. Only note: 0.25s spring instead of the 0.4s ease.",
    timestamp: "Yesterday",
    top: "78%",
    width: 190,
  },
];

export default function DemoOne() {
  return (
    <div className="flex min-h-[720px] w-full items-center justify-center bg-background p-8">
      <div className="w-full max-w-4xl overflow-hidden rounded-3xl border bg-card shadow-sm">
        <header className="flex items-center justify-between border-b px-5 py-3">
          <div className="flex items-center gap-3">
            <span className="font-semibold text-foreground text-sm">
              Pricing · v4
            </span>
            <span className="rounded-md bg-muted px-2 py-0.5 font-mono text-[11px] text-muted-foreground">
              3 comments
            </span>
          </div>
          <div className="flex items-center gap-2 text-muted-foreground text-xs">
            <span className="rounded-md border px-2 py-1">100%</span>
            <span className="rounded-md border px-2 py-1">Comment</span>
          </div>
        </header>

        <div className="relative h-[520px] bg-[repeating-linear-gradient(0deg,transparent,transparent_31px,color-mix(in_oklch,currentColor_8%,transparent)_31px,color-mix(in_oklch,currentColor_8%,transparent)_32px),repeating-linear-gradient(90deg,transparent,transparent_31px,color-mix(in_oklch,currentColor_8%,transparent)_31px,color-mix(in_oklch,currentColor_8%,transparent)_32px)] text-muted-foreground">
          <div className="absolute inset-10 rounded-2xl border bg-background p-8">
            <p className="font-semibold text-2xl text-foreground tracking-tight">
              Simple, honest pricing
            </p>
            <p className="mt-2 max-w-sm text-muted-foreground text-sm leading-relaxed">
              Two plans, no seats, no metering. Cancel whenever you like.
            </p>
            <div className="mt-6 grid grid-cols-2 gap-4">
              {["Solo", "Studio"].map((plan) => (
                <div className="rounded-xl border p-5" key={plan}>
                  <p className="font-medium text-foreground text-sm">{plan}</p>
                  <p className="mt-3 font-semibold text-3xl text-foreground tracking-tight tabular-nums">
                    {plan === "Solo" ? "€19" : "€49"}
                  </p>
                  <p className="mt-1 text-muted-foreground text-xs">
                    per month
                  </p>
                </div>
              ))}
            </div>
          </div>

          {PINS.map((pin) => (
            <div
              className="absolute"
              key={pin.authorName}
              style={{ left: pin.left, top: pin.top }}
            >
              <Component
                authorName={pin.authorName}
                defaultOpen={pin.defaultOpen}
                message={pin.message}
                timestamp={pin.timestamp}
                width={pin.width}
              />
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Dependencies

More by Edu Calvo

View all
  • Scrollable Card Stack

    Scrollable Card Stack

    235
  • AI Task List

    AI Task List

    160
  • Siri Orb

    Siri Orb

    160
  • Cursor Follow

    Cursor Follow

    154
  • Pixel Flow Field

    Pixel Flow Field

    142
  • Agent Avatar

    Agent Avatar

    130
  • Gravity Stars

    Gravity Stars

    112
  • Coverflow Carousel

    Coverflow Carousel

    95