Avatar
optics/avatarFreeComponent
An image element with a fallback for representing the user.
See it running
Open the demo on optics
optics.agusmayol.com.ar/components/avatarInstall it
npx shadcn@latest add https://optics.agusmayol.com.ar/r/avatar.jsonSource
1"use client";23import Image from "next/image";4import * as React from "react";5import { Avatar as AvatarPrimitive } from "@base-ui/react/avatar";67import {8 Tooltip,9 TooltipContent,10 TooltipTrigger,11} from "@/registry/optics/tooltip";12import { cn } from "@/lib/utils";1314const AvatarContext = React.createContext({15 loaded: false,16 setLoaded: () => {},17});1819function Avatar({20 className = "",21 size = "default",22 title,23 tooltipSide = "top",24 tooltipSideOffset = 4,25 tooltipAlign = "center",26 tooltipAlignOffset = 0,27 children,28 ...props29}) {30 const [loaded, setLoaded] = React.useState(false);3132 const renderAvatar = (triggerProps = {}) => {33 const {34 className: triggerClassName,35 ref: triggerRef,36 ...triggerRest37 } = triggerProps;3839 return (40 <AvatarContext.Provider value={{ loaded, setLoaded }}>41 <AvatarPrimitive.Root42 ref={triggerRef}43 data-slot="avatar"44 data-size={size}45 className={cn(46 "ring-background ring-2 size-8 rounded-full after:rounded-full squircle-none data-[size=lg]:size-10 data-[size=sm]:size-6 after:border-border group/avatar isolate relative flex shrink-0 select-none after:absolute after:inset-0 after:border after:mix-blend-darken dark:after:mix-blend-lighten",47 className,48 triggerClassName,49 )}50 {...props}51 {...triggerRest}52 >53 {children}54 </AvatarPrimitive.Root>55 </AvatarContext.Provider>56 );57 };5859 if (!title) {60 return renderAvatar();61 }6263 return (64 <Tooltip>65 <TooltipTrigger render={renderAvatar} />66 <TooltipContent67 side={tooltipSide}68 sideOffset={tooltipSideOffset}69 align={tooltipAlign}70 alignOffset={tooltipAlignOffset}71 >72 {title}73 </TooltipContent>74 </Tooltip>75 );76}7778function AvatarStack({79 data = [],80 children,81 width = 50,82 height = 50,83 alt = "",84 ...props85}) {86 return (87 <div className="flex items-center -space-x-2">88 {data.map((item, index) => (89 <Avatar title={item.title} key={index}>90 <AvatarImage91 src={item.image}92 width={width}93 height={height}94 alt={alt}95 {...props}96 />97 <AvatarFallback>{item.fallback}</AvatarFallback>98 </Avatar>99 ))}100 </div>101 );102}103104function AvatarImage({105 className = "",106 width = 50,107 height = 50,108 alt = "",109 ...props110}) {111 const { setLoaded } = React.useContext(AvatarContext);112113 return (114 <Image115 data-slot="avatar-image"116 className={cn(117 "aspect-square size-full rounded-full squircle-none object-cover absolute inset-0 z-10 bg-background",118 className,119// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from optics
All 79 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | optics | Components | Free | 5 deps | |
| Alertalert | optics | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | optics | Components | Free | 4 deps | |
| Aspect Ratioaspect-ratio | optics | Components | Free | 2 deps | |
| Auto Heightauto-height | optics | Components | Free | 3 deps | |
| Badgebadge | optics | Components | Free | 4 deps | |
| Breadcrumbbreadcrumb | optics | Components | Free | 4 deps | |
| Buttonbutton | optics | Components | Free | 4 deps |
