preskok
uiavatarsource: ok · refreshed
Avatar
A flexible avatar component with initials and image support
npx shadcn add "https://ui-three-mu.vercel.app/r/avatar.json"free
No selection tags yet — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lightcn@^0.2.4
Files1 · source cached 10/8/2026, 12:27:15 AM
registry/preskok/ui/preskok-ui/avatar.tsx
"use client"
import React from "react"
import { twMerge } from "cn"
interface AvatarProps extends React.ComponentProps<"span"> {
src?: string | null
initials?: string
alt?: string
className?: string
isSquare?: boolean
size?: "xs" | "sm" | "md" | "lg" | "xl"
}
const Avatar = ({
src = null,
isSquare = false,
size = "md",
initials,
alt = "",
className,
...props
}: AvatarProps) => {
return (
<span
data-slot="avatar"
{...props}
className={twMerge(
"outline-foreground/(--ring-opacity) inline-grid shrink-0 align-middle outline-1 -outline-offset-1 [--avatar-radius:20%] [--ring-opacity:20%] *:col-start-1 *:row-start-1",
size === "xs" && "size-5 *:size-5",
size === "sm" && "size-6 *:size-6",
size === "md" && "size-8 *:size-8",
size === "lg" && "size-10 *:size-10",
size === "xl" && "size-12 *:size-12",
isSquare
? "rounded-(--avatar-radius) *:rounded-(--avatar-radius)"
: "rounded-full *:rounded-full",
className
)}
>
{initials && (
<svg
className="font-md size-full fill-current p-[5%] text-[48px] uppercase select-none"
viewBox="0 0 100 100"
aria-hidden={alt ? undefined : "true"}
>
{alt && <title>{alt}</title>}
<text
x="50%"
y="50%"
alignmentBaseline="middle"
dominantBaseline="middle"
textAnchor="middle"
dy=".125em"
>
{initials}
</text>
</svg>
)}
{src && (
// eslint-disable-next-line @next/next/no-img-element -- Keep registry output framework-agnostic.
<img
className="size-full object-cover object-center"
src={src}
alt={alt}
/>
)}
</span>
)
}
export { Avatar }
export type { AvatarProps }