add support for identicon ring to avatar
This commit is contained in:
parent
9b1347d233
commit
8cdf04da2c
|
@ -1,7 +1,8 @@
|
|||
import React from 'react'
|
||||
import React, { useMemo } from 'react'
|
||||
|
||||
import { Image } from '../image'
|
||||
import { Base, Indicator, Initials } from './styles'
|
||||
import { Base, Content, Indicator, Initials } from './styles'
|
||||
import { generateIdenticonRing } from './utils'
|
||||
|
||||
import type { Variants } from './styles'
|
||||
|
||||
|
@ -11,46 +12,43 @@ interface Props {
|
|||
indicator?: 'online' | 'offline'
|
||||
src?: string
|
||||
color?: string
|
||||
colorHash?: number[][]
|
||||
}
|
||||
|
||||
const Avatar = (props: Props) => {
|
||||
const { size, name, src, color, indicator } = props
|
||||
const { size, name, src, color, indicator, colorHash } = props
|
||||
|
||||
// const identicon = useMemo(() => {
|
||||
// const colors = colorWheel
|
||||
// .map((color, idx) => {
|
||||
// const prevDeg = idx === 0 ? '0deg' : `${colorWheel[idx - 1][1]}deg`
|
||||
// return `${color[0]} ${prevDeg} ${color[1]}deg`
|
||||
// })
|
||||
// .join(',')
|
||||
// return `conic-gradient(${colors})`
|
||||
// }, [colorWheel])
|
||||
|
||||
// const intials = useMemo(() => {
|
||||
// if (contact && contact?.customName) {
|
||||
// return contact.customName.slice(0, 2)
|
||||
// }
|
||||
// if (contact && contact.trueName) {
|
||||
// return contact.trueName.slice(0, 2)
|
||||
// }
|
||||
// }, [contact])
|
||||
const identiconRing = useMemo(() => {
|
||||
if (colorHash) {
|
||||
const gradient = generateIdenticonRing(colorHash)
|
||||
return `conic-gradient(${gradient})`
|
||||
}
|
||||
}, [colorHash])
|
||||
|
||||
const initials = name ? name.slice(0, 1) : ''
|
||||
|
||||
return (
|
||||
<Base size={size} style={{ backgroundColor: color }}>
|
||||
{initials && <Initials size={size}>{initials}</Initials>}
|
||||
{src && (
|
||||
<Image
|
||||
src={src}
|
||||
alt="avatar"
|
||||
width="100%"
|
||||
height="100%"
|
||||
fit="cover"
|
||||
radius="full"
|
||||
/>
|
||||
)}
|
||||
{indicator && <Indicator size={size} state={indicator} />}
|
||||
<Base
|
||||
size={size}
|
||||
style={{
|
||||
background: identiconRing,
|
||||
padding: !identiconRing ? 0 : undefined,
|
||||
}}
|
||||
>
|
||||
<Content style={{ background: color }}>
|
||||
{initials && <Initials size={size}>{initials}</Initials>}
|
||||
{src && (
|
||||
<Image
|
||||
src={src}
|
||||
alt="avatar"
|
||||
width="100%"
|
||||
height="100%"
|
||||
fit="cover"
|
||||
radius="full"
|
||||
/>
|
||||
)}
|
||||
{indicator && <Indicator size={size} state={indicator} />}
|
||||
</Content>
|
||||
</Base>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ export type Variants = VariantProps<typeof Base>
|
|||
|
||||
export const Base = styled('div', {
|
||||
position: 'relative',
|
||||
background: '$primary-1',
|
||||
borderRadius: '100%',
|
||||
flexShrink: 0,
|
||||
|
||||
|
@ -15,39 +14,54 @@ export const Base = styled('div', {
|
|||
20: {
|
||||
width: 20,
|
||||
height: 20,
|
||||
padding: 1,
|
||||
},
|
||||
24: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
padding: 1,
|
||||
},
|
||||
32: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
padding: 2,
|
||||
},
|
||||
36: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
padding: 2,
|
||||
},
|
||||
44: {
|
||||
width: 44,
|
||||
height: 44,
|
||||
padding: 2,
|
||||
},
|
||||
64: {
|
||||
width: 64,
|
||||
height: 64,
|
||||
padding: 3,
|
||||
},
|
||||
80: {
|
||||
width: 80,
|
||||
height: 80,
|
||||
padding: 4,
|
||||
},
|
||||
120: {
|
||||
width: 120,
|
||||
height: 120,
|
||||
padding: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const Content = styled('div', {
|
||||
background: '$primary-1',
|
||||
borderRadius: '100%',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
})
|
||||
|
||||
export const Indicator = styled('span', {
|
||||
position: 'absolute',
|
||||
right: -2,
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* returns value for conic-gradient
|
||||
*/
|
||||
export const generateIdenticonRing = (colorHash: number[][]) => {
|
||||
const segments = colorHash.reduce((acc, segment) => (acc += segment[0]), 0)
|
||||
|
||||
let prevAngle = 0
|
||||
const gradient = colorHash.reduce((acc, segment, index) => {
|
||||
const [length, colorIndex] = segment
|
||||
const color = COLORS[colorIndex]
|
||||
const nextAngle = Math.round(prevAngle + (length * 360) / segments)
|
||||
|
||||
acc += `${color} ${prevAngle}deg ${nextAngle}deg`
|
||||
|
||||
if (index !== colorHash.length - 1) {
|
||||
acc += `, `
|
||||
}
|
||||
|
||||
prevAngle = nextAngle
|
||||
|
||||
return acc
|
||||
}, '')
|
||||
|
||||
return gradient
|
||||
}
|
||||
|
||||
const COLORS = [
|
||||
'#000000',
|
||||
'#726F6F',
|
||||
'#C4C4C4',
|
||||
'#E7E7E7',
|
||||
'#FFFFFF',
|
||||
'#00FF00',
|
||||
'#009800',
|
||||
'#B8FFBB',
|
||||
'#FFC413',
|
||||
'#9F5947',
|
||||
'#FFFF00',
|
||||
'#A8AC00',
|
||||
'#FFFFB0',
|
||||
'#FF5733',
|
||||
'#FF0000',
|
||||
'#9A0000',
|
||||
'#FF9D9D',
|
||||
'#FF0099',
|
||||
'#C80078',
|
||||
'#FF00FF',
|
||||
'#900090',
|
||||
'#FFB0FF',
|
||||
'#9E00FF',
|
||||
'#0000FF',
|
||||
'#000086',
|
||||
'#9B81FF',
|
||||
'#3FAEF9',
|
||||
'#9A6600',
|
||||
'#00FFFF',
|
||||
'#008694',
|
||||
'#C2FFFF',
|
||||
'#00F0B6',
|
||||
]
|
Loading…
Reference in New Issue