1
1
import * as React from "react"
2
+ import upperCase from "lodash/upperCase"
2
3
import * as AvatarPrimitive from "@radix-ui/react-avatar"
3
4
4
- import { cn } from "@/lib/utils"
5
+ import { cn } from "@/lib/utils/cn "
5
6
6
- const Avatar = React . forwardRef <
7
+ import { Center } from "./flex"
8
+ import { BaseLink , type LinkProps } from "./Link"
9
+ import { LinkBox , LinkOverlay } from "./link-box"
10
+
11
+ type AvatarBaseProps = React . ComponentProps < typeof AvatarPrimitive . Root >
12
+
13
+ const AvatarBase = React . forwardRef <
7
14
React . ElementRef < typeof AvatarPrimitive . Root > ,
8
- React . ComponentPropsWithoutRef < typeof AvatarPrimitive . Root >
15
+ AvatarBaseProps
9
16
> ( ( { className, ...props } , ref ) => (
10
17
< AvatarPrimitive . Root
11
18
ref = { ref }
@@ -16,15 +23,16 @@ const Avatar = React.forwardRef<
16
23
{ ...props }
17
24
/>
18
25
) )
19
- Avatar . displayName = AvatarPrimitive . Root . displayName
26
+ AvatarBase . displayName = AvatarPrimitive . Root . displayName
20
27
21
28
const AvatarImage = React . forwardRef <
22
29
React . ElementRef < typeof AvatarPrimitive . Image > ,
23
30
React . ComponentPropsWithoutRef < typeof AvatarPrimitive . Image >
24
- > ( ( { className, ...props } , ref ) => (
31
+ > ( ( { className, alt = "" , ...props } , ref ) => (
25
32
< AvatarPrimitive . Image
26
33
ref = { ref }
27
34
className = { cn ( "aspect-square h-full w-full" , className ) }
35
+ alt = { alt }
28
36
{ ...props }
29
37
/>
30
38
) )
@@ -45,4 +53,70 @@ const AvatarFallback = React.forwardRef<
45
53
) )
46
54
AvatarFallback . displayName = AvatarPrimitive . Fallback . displayName
47
55
48
- export { Avatar , AvatarFallback , AvatarImage }
56
+ export type AvatarProps = AvatarBaseProps &
57
+ Required < Pick < LinkProps , "href" > > & {
58
+ label ?: string
59
+ /**
60
+ * @default "row"
61
+ */
62
+ direction ?: "column" | "row"
63
+ name : string
64
+ src : string
65
+ }
66
+
67
+ const Avatar = React . forwardRef <
68
+ React . ElementRef < "span" > | React . ElementRef < "div" > ,
69
+ AvatarProps
70
+ > ( ( props , ref ) => {
71
+ const { href, src, name, label, direction = "row" } = props
72
+
73
+ const commonLinkProps = {
74
+ href,
75
+ }
76
+
77
+ const fallbackInitials = upperCase (
78
+ name
79
+ . split ( " " )
80
+ . map ( ( n ) => n [ 0 ] )
81
+ . join ( "" )
82
+ )
83
+
84
+ if ( label ) {
85
+ const _direction : "flex-col-reverse" | "flex-row-reverse" =
86
+ direction === "row" ? "flex-row-reverse" : "flex-col-reverse"
87
+
88
+ const _ref = ref as React . ForwardedRef < HTMLDivElement >
89
+ return (
90
+ < LinkBox
91
+ // !! Inconsistent strategy, using `as` prop instead of `asChild` bool
92
+ as = { Center }
93
+ ref = { _ref }
94
+ className = { cn ( _direction , "gap-x-1 gap-y-0" ) }
95
+ >
96
+ < LinkOverlay
97
+ asChild
98
+ className = "z-overlay inline-flex items-center gap-1 p-1 no-underline"
99
+ data-peer
100
+ >
101
+ < BaseLink { ...commonLinkProps } > { label } </ BaseLink >
102
+ </ LinkOverlay >
103
+ < AvatarBase >
104
+ < AvatarImage src = { src } />
105
+ < AvatarFallback > { fallbackInitials } </ AvatarFallback >
106
+ </ AvatarBase >
107
+ </ LinkBox >
108
+ )
109
+ }
110
+
111
+ return (
112
+ < AvatarBase ref = { ref } asChild >
113
+ < BaseLink { ...commonLinkProps } >
114
+ < AvatarImage src = { src } />
115
+ < AvatarFallback > { fallbackInitials } </ AvatarFallback >
116
+ </ BaseLink >
117
+ </ AvatarBase >
118
+ )
119
+ } )
120
+ Avatar . displayName = "Avatar"
121
+
122
+ export { Avatar , AvatarBase , AvatarFallback , AvatarImage }
0 commit comments