-
Notifications
You must be signed in to change notification settings - Fork 323
/
AvatarListUser.tsx
101 lines (96 loc) · 2.59 KB
/
AvatarListUser.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import styled from '@emotion/styled'
import graphql from 'babel-plugin-relay/macro'
import React from 'react'
import {useFragment} from 'react-relay'
import {TransitionStatus} from '~/hooks/useTransition'
import {MenuPosition} from '../hooks/useCoords'
import useTooltip from '../hooks/useTooltip'
import {BezierCurve} from '../types/constEnums'
import {AvatarListUser_user$key} from '../__generated__/AvatarListUser_user.graphql'
import Avatar from './Avatar/Avatar'
const Wrapper = styled('div')<{offset: number; isColumn?: boolean}>(({offset, isColumn}) => ({
position: 'absolute',
transform: `translate${isColumn ? 'Y' : 'X'}(${offset}px)`,
transition: `all 300ms ${BezierCurve.DECELERATE}`
}))
const StyledAvatar = styled(Avatar)<{
status?: TransitionStatus
isAnimated: boolean
borderColor?: string
width: number
}>(({status, isAnimated, borderColor = '#fff', width}) => ({
border: `${width >= 40 ? '3px' : '2px'} solid ${borderColor}`,
opacity: !isAnimated
? undefined
: status === TransitionStatus.EXITING || status === TransitionStatus.MOUNTED
? 0
: 1,
transform: !isAnimated
? undefined
: status === TransitionStatus.EXITING || status === TransitionStatus.MOUNTED
? 'scale(0)'
: 'scale(1)',
transition: `all 300ms ${BezierCurve.DECELERATE}`
}))
interface Props {
className?: string
offset: number
isColumn?: boolean
isAnimated: boolean
onTransitionEnd?: () => void
status?: TransitionStatus
user: AvatarListUser_user$key
width: number
onClick?: () => void
borderColor?: string
}
const AvatarListUser = (props: Props) => {
const {
className,
isColumn,
user: userRef,
onTransitionEnd,
status,
offset,
isAnimated,
width,
onClick,
borderColor
} = props
const user = useFragment(
graphql`
fragment AvatarListUser_user on User {
picture
preferredName
}
`,
userRef
)
const {picture, preferredName} = user
const {tooltipPortal, openTooltip, closeTooltip, originRef} = useTooltip<HTMLDivElement>(
MenuPosition.UPPER_CENTER
)
return (
<Wrapper
ref={originRef}
offset={offset}
isColumn={isColumn}
onClick={onClick}
onMouseOver={openTooltip}
onMouseLeave={closeTooltip}
>
<StyledAvatar
className={className}
status={status}
onTransitionEnd={onTransitionEnd}
picture={picture}
size={width}
isAnimated={isAnimated}
borderColor={borderColor}
width={width}
/>
{tooltipPortal(preferredName)}
</Wrapper>
)
}
export default AvatarListUser