File tree 9 files changed +156
-0
lines changed
9 files changed +156
-0
lines changed Original file line number Diff line number Diff line change
1
+ import styled from '@emotion/styled' ;
2
+
3
+ import { Image } from '@components/shared/Image' ;
4
+
5
+ import { AvatarProps } from './Avatar' ;
6
+
7
+ export const StyledImage = styled ( Image ) < AvatarProps > `
8
+ border: ${ ( { border } ) => border } ;
9
+ border-radius: ${ ( { radius } ) => radius } ;
10
+ ` ;
Original file line number Diff line number Diff line change
1
+ import { HTMLAttributes } from 'react' ;
2
+
3
+ import { StyledImage } from './Avatar.styles' ;
4
+
5
+ export type AvatarProps = {
6
+ src : string ;
7
+ size ?: number ;
8
+ radius ?: string ;
9
+ border ?: string ;
10
+ } & HTMLAttributes < HTMLImageElement > ;
11
+
12
+ export const Avatar = ( {
13
+ src,
14
+ size = 30 ,
15
+ radius = '50%' ,
16
+ border,
17
+ ...props
18
+ } : AvatarProps ) => {
19
+ return (
20
+ < StyledImage
21
+ src = { src }
22
+ alt = "avatar"
23
+ width = { size }
24
+ border = { border }
25
+ radius = { radius }
26
+ { ...props }
27
+ />
28
+ ) ;
29
+ } ;
Original file line number Diff line number Diff line change
1
+ export * from './Avatar' ;
Original file line number Diff line number Diff line change
1
+ import styled from '@emotion/styled' ;
2
+
3
+ import { Avatar , AvatarProps } from '@components/shared/Avatar' ;
4
+
5
+ import { AvatarGroupProps } from './AvatarGroup' ;
6
+
7
+ type AvatarGroupWrapperProps = Required < Pick < AvatarGroupProps , 'overlap' > > ;
8
+
9
+ export const AvatarGroupWrapper = styled . div < AvatarGroupWrapperProps > `
10
+ padding-left: ${ ( { overlap } ) => `${ overlap / 16 } rem` } ;
11
+ ` ;
12
+
13
+ export const OverlapedAvatar = styled ( Avatar ) <
14
+ AvatarProps & { overlap : number }
15
+ > `
16
+ margin-left: ${ ( { overlap } ) => `-${ overlap / 16 } rem` } ;
17
+ ` ;
Original file line number Diff line number Diff line change
1
+ import React , { HTMLAttributes } from 'react' ;
2
+
3
+ import { Avatar , AvatarProps } from '../Avatar' ;
4
+ import { AvatarGroupWrapper , OverlapedAvatar } from './AvatarGroup.styles' ;
5
+
6
+ export type AvatarGroupProps = {
7
+ children : React . ReactNode ;
8
+ overlap ?: number ;
9
+ } & Omit < AvatarProps , 'src' > &
10
+ HTMLAttributes < HTMLDivElement > ;
11
+
12
+ export const AvatarGroup = ( {
13
+ children,
14
+ size = 30 ,
15
+ radius = '50%' ,
16
+ border,
17
+ overlap = 10 ,
18
+ ...props
19
+ } : AvatarGroupProps ) => {
20
+ const avatars = React . Children . toArray ( children )
21
+ . filter ( ( element ) : element is React . ReactElement < AvatarProps > => {
22
+ if ( ! React . isValidElement ( element ) ) {
23
+ return false ;
24
+ }
25
+ if ( element . type !== Avatar ) {
26
+ return false ;
27
+ }
28
+ return true ;
29
+ } )
30
+ . map ( ( { props } ) => (
31
+ < OverlapedAvatar
32
+ { ...props }
33
+ size = { size }
34
+ border = { border }
35
+ radius = { radius }
36
+ overlap = { overlap }
37
+ />
38
+ ) ) ;
39
+
40
+ return (
41
+ < AvatarGroupWrapper overlap = { overlap } { ...props } >
42
+ { avatars }
43
+ </ AvatarGroupWrapper >
44
+ ) ;
45
+ } ;
Original file line number Diff line number Diff line change
1
+ export * from './AvatarGroup' ;
Original file line number Diff line number Diff line change
1
+ import styled from '@emotion/styled' ;
2
+
3
+ import { ImageCustomProps } from './Image' ;
4
+
5
+ type ImgProps = Required < ImageCustomProps > ;
6
+
7
+ export const Img = styled . img < ImgProps > `
8
+ display: ${ ( { block } ) => ( block ? 'block' : 'inline' ) } ;
9
+ width: ${ ( { width } ) => width } ;
10
+ height: ${ ( { height } ) => height } ;
11
+ object-fit: ${ ( { mode } ) => mode } ;
12
+ ` ;
Original file line number Diff line number Diff line change
1
+ import { CSSProperties , HTMLAttributes } from 'react' ;
2
+
3
+ import { Img } from './Image.styles' ;
4
+
5
+ export type ImageCustomProps = {
6
+ src : string ;
7
+ block ?: boolean ;
8
+ width : number | string ;
9
+ height ?: number | string ;
10
+ alt : string ;
11
+ mode ?: CSSProperties [ 'objectFit' ] ;
12
+ } ;
13
+ type ImageProps = ImageCustomProps & HTMLAttributes < HTMLImageElement > ;
14
+
15
+ export const Image = ( {
16
+ src,
17
+ block = false ,
18
+ width,
19
+ height = width ,
20
+ alt,
21
+ mode = 'cover' ,
22
+ ...props
23
+ } : ImageProps ) => {
24
+ const stringifiedWidth =
25
+ typeof width === 'number' ? `${ width / 16 } rem` : width ;
26
+ const stringifiedHeight =
27
+ typeof height === 'number' ? `${ height / 16 } rem` : height ;
28
+
29
+ return (
30
+ < Img
31
+ src = { src }
32
+ alt = { alt }
33
+ width = { stringifiedWidth }
34
+ height = { stringifiedHeight }
35
+ block = { block }
36
+ mode = { mode }
37
+ { ...props }
38
+ />
39
+ ) ;
40
+ } ;
Original file line number Diff line number Diff line change
1
+ export * from './Image' ;
You can’t perform that action at this time.
0 commit comments