Skip to main content

Author Tooltip

An interactive avatar with tooltip showing author information and social links.

Micro InteractionReactTailwind CSS
CSSshadcn

Manual

Create a file and paste the following code into it.

author-tooltip.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"use client";

import type * as React from "react";
import { GithubLogo, LinkedinLogo, TwitterLogo } from "@phosphor-icons/react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
	Tooltip,
	TooltipContent,
	TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/cn";

export interface Author {
	name: string;
	avatar: string;
	role: string;
	linkedin?: string;
	twitter?: string;
	github?: string;
}

interface AuthorTooltipProps {
	author: Author;
	avatarSize?: "sm" | "md" | "lg" | "xl";
	avatarClassName?: string;
	/** Custom trigger element - if not provided, defaults to avatar */
	trigger?: React.ReactNode;
	/** Additional content to render in the tooltip */
	children?: React.ReactNode;
}

const sizeMap = {
	sm: "h-8 w-8",
	md: "h-10 w-10",
	lg: "h-12 w-12",
	xl: "h-16 w-16",
};

export function AuthorTooltip({
	author,
	avatarSize = "sm",
	avatarClassName = "cursor-help border-2 border-border",
	trigger,
	children,
}: AuthorTooltipProps) {
	const getInitials = (name: string) => {
		return name
			.split(" ")
			.map((n) => n[0])
			.join("")
			.toUpperCase()
			.slice(0, 2);
	};

	const defaultTrigger = (
		<Avatar className={cn(sizeMap[avatarSize], avatarClassName)}>
			<AvatarImage src={author.avatar} alt={author.name} />
			<AvatarFallback>{getInitials(author.name)}</AvatarFallback>
		</Avatar>
	);

	return (
		<Tooltip>
			<TooltipTrigger asChild>
				{trigger ? <div>{trigger}</div> : defaultTrigger}
			</TooltipTrigger>
			<TooltipContent className="p-0 rounded-xl">
				<div className="flex flex-col gap-2 p-3">
					<div className="flex flex-row items-center gap-3">
						<Avatar className="h-10 w-10">
							<AvatarImage src={author.avatar} alt={author.name} />
							<AvatarFallback>{getInitials(author.name)}</AvatarFallback>
						</Avatar>
						<div className="flex flex-col">
							<span className="text-sm font-medium">{author.name}</span>
							<span className="text-xs text-muted-foreground">
								{author.role}
							</span>
						</div>
						{(author.linkedin || author.twitter || author.github) && (
							<div className="ml-4 flex gap-2.5">
								{author.linkedin && (
									<a
										href={author.linkedin}
										target="_blank"
										rel="noopener noreferrer"
										className="text-background hover:text-muted-foreground transition-colors"
									>
										<LinkedinLogo weight="fill" className="h-5 w-5" />
									</a>
								)}
								{author.twitter && (
									<a
										href={author.twitter}
										target="_blank"
										rel="noopener noreferrer"
										className="text-background hover:text-muted-foreground transition-colors"
									>
										<TwitterLogo weight="fill" className="h-5 w-5" />
									</a>
								)}
								{author.github && (
									<a
										href={author.github}
										target="_blank"
										rel="noopener noreferrer"
										className="text-background hover:text-muted-foreground transition-colors"
									>
										<GithubLogo weight="fill" className="h-5 w-5" />
									</a>
								)}
							</div>
						)}
					</div>
					{children && <div>{children}</div>}
				</div>
			</TooltipContent>
		</Tooltip>
	);
}

Update the import paths to match your project setup.

Similar components

Status Badge Table

Max

Morphing Dropdown

SVG Branch Connector

Tool Calls Section

Resource details

PublishedMarch 3, 2026
CategoryMicro Interaction
ReactTailwind CSS