avatar.tsx raw

   1  "use client";
   2  
   3  import * as React from "react";
   4  import { Avatar as AvatarPrimitive } from "radix-ui";
   5  
   6  import { cn } from "src/lib/utils";
   7  
   8  function Avatar({
   9    className,
  10    size = "default",
  11    ...props
  12  }: React.ComponentProps<typeof AvatarPrimitive.Root> & {
  13    size?: "default" | "sm" | "lg";
  14  }) {
  15    return (
  16      <AvatarPrimitive.Root
  17        data-slot="avatar"
  18        data-size={size}
  19        className={cn(
  20          "group/avatar relative flex size-8 shrink-0 overflow-hidden rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
  21          className
  22        )}
  23        {...props}
  24      />
  25    );
  26  }
  27  
  28  function AvatarImage({
  29    className,
  30    ...props
  31  }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
  32    return (
  33      <AvatarPrimitive.Image
  34        data-slot="avatar-image"
  35        className={cn("aspect-square size-full", className)}
  36        {...props}
  37      />
  38    );
  39  }
  40  
  41  function AvatarFallback({
  42    className,
  43    ...props
  44  }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
  45    return (
  46      <AvatarPrimitive.Fallback
  47        data-slot="avatar-fallback"
  48        className={cn(
  49          "flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs",
  50          className
  51        )}
  52        {...props}
  53      />
  54    );
  55  }
  56  
  57  function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
  58    return (
  59      <span
  60        data-slot="avatar-badge"
  61        className={cn(
  62          "absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground ring-2 ring-background select-none",
  63          "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
  64          "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
  65          "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
  66          className
  67        )}
  68        {...props}
  69      />
  70    );
  71  }
  72  
  73  function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
  74    return (
  75      <div
  76        data-slot="avatar-group"
  77        className={cn(
  78          "group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background",
  79          className
  80        )}
  81        {...props}
  82      />
  83    );
  84  }
  85  
  86  function AvatarGroupCount({
  87    className,
  88    ...props
  89  }: React.ComponentProps<"div">) {
  90    return (
  91      <div
  92        data-slot="avatar-group-count"
  93        className={cn(
  94          "relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
  95          className
  96        )}
  97        {...props}
  98      />
  99    );
 100  }
 101  
 102  export {
 103    Avatar,
 104    AvatarImage,
 105    AvatarFallback,
 106    AvatarBadge,
 107    AvatarGroup,
 108    AvatarGroupCount,
 109  };
 110