Avatar
tetra-ui/avatarFreeComponent
An image element with a fallback for representing the user.
Live preview
live · rendered by the registry
Rendered by tetra-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://tetra-ui.com/r/avatar.jsonSource
1import { cva, type VariantProps } from "class-variance-authority";2import {3 Children,4 cloneElement,5 createContext,6 isValidElement,7 useCallback,8 useContext,9 useMemo,10 useState,11} from "react";12import { Image, type ImageProps, Text, View } from "react-native";13import { withUniwind } from "uniwind";14import { cn } from "@/lib/utils";1516// Types17type AvatarSize = NonNullable<VariantProps<typeof avatarVariants>["size"]>;18type AvatarImageStatus = "idle" | "loading" | "loaded" | "error";1920type AvatarImageKeyStatus = {21 status: AvatarImageStatus;22 srcKey: string;23};2425type AvatarContextValue = {26 size: AvatarSize;27 imageKeyStatus: AvatarImageKeyStatus;28 setImageKeyStatus: (status: AvatarImageKeyStatus) => void;29};3031type AvatarProps = React.ComponentProps<typeof View> &32 VariantProps<typeof avatarVariants> & {33 children?: React.ReactNode;34 };3536type AvatarImageProps = ImageProps;3738type AvatarFallbackProps = React.ComponentProps<typeof View> & {39 children?: React.ReactNode;40};4142type AvatarBadgeProps = React.ComponentProps<typeof View> & {43 children?: React.ReactNode;44};4546type ClassNameElement = React.ReactElement<{ className?: string }>;4748// Context49const AvatarContext = createContext<AvatarContextValue | null>(null);5051const useAvatarContext = () => {52 const context = useContext(AvatarContext);53 if (!context) {54 throw new Error("Avatar components must be used within an Avatar");55 }56 return context;57};5859const StyledImage = withUniwind(Image);6061// Components62export const Avatar = ({63 children,64 className,65 size = "default",66 ...props67}: AvatarProps) => {68 const [imageKeyStatus, _setImageKeyStatus] = useState<AvatarImageKeyStatus>({69 srcKey: "",70 status: "idle",71 });7273 const setImageKeyStatus = useCallback((payload: AvatarImageKeyStatus) => {74 _setImageKeyStatus((prev) => {75 const isSameKey = payload.srcKey === prev.srcKey;7677 if (prev.status === "loaded" && isSameKey) {78 return prev;79 }8081 return payload;82 });83 }, []);8485 const ctx = useMemo(86 () => ({87 imageKeyStatus,88 setImageKeyStatus,89 size: size ?? "default",90 }),91 [imageKeyStatus, size, setImageKeyStatus]92 );9394 return (95 <AvatarContext.Provider value={ctx}>96 <View97 className={cn(avatarVariants({ className, size }))}98 data-slot="avatar"99 {...props}100 >101 {children}102 </View>103 </AvatarContext.Provider>104 );105};106107export const AvatarImage = ({108 alt,109 className,110// … truncated
Files it writes
More from tetra-ui
All 41 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | tetra-ui | Components | Free | 1 dep | |
| Action Inputaction-input | tetra-ui | Components | Free | no deps | |
| Alertalert | tetra-ui | Components | Free | no deps | |
| Badgebadge | tetra-ui | Components | Free | no deps | |
| Bottom Sheetbottom-sheet | tetra-ui | Components | Free | 4 deps · 7 files | |
| Buttonbutton | tetra-ui | Components | Free | no deps | |
| Cardcard | tetra-ui | Components | Free | no deps | |
| Checkboxcheckbox | tetra-ui | Components | Free | 1 dep |
