mirror of
https://github.com/zhigang1992/react.git
synced 2026-04-29 04:35:32 +08:00
feat(avatar): use group to display multiple avatars
This commit is contained in:
50
components/avatar/avatar-group.tsx
Normal file
50
components/avatar/avatar-group.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import React from 'react'
|
||||
import useTheme from '../styles/use-theme'
|
||||
import withDefaults from '../utils/with-defaults'
|
||||
|
||||
interface Props {
|
||||
count?: number
|
||||
className?: string
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
className: '',
|
||||
}
|
||||
|
||||
type NativeAttrs = Omit<React.HTMLAttributes<any>, keyof Props>
|
||||
export type AvatarGroupProps = Props & typeof defaultProps & NativeAttrs
|
||||
|
||||
const AvatarGroup: React.FC<React.PropsWithChildren<AvatarGroupProps>> = ({
|
||||
count, className, children
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
|
||||
return (
|
||||
<div className={`avatar-group ${className}`}>
|
||||
{children}
|
||||
{count && <span className="count">+{count}</span>}
|
||||
<style jsx>{`
|
||||
.avatar-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: auto;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.avatar-group :global(.avatar) {
|
||||
margin-left: -.625rem;
|
||||
}
|
||||
|
||||
.count {
|
||||
font-size: .875rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding-left: ${theme.layout.gapQuarter};
|
||||
color: ${theme.palette.accents_7};
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withDefaults(AvatarGroup, defaultProps)
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react'
|
||||
import { AVATAR_SIZES } from './constants'
|
||||
import { NormalSizes } from '../utils/prop-types'
|
||||
import withDefaults from '../utils/with-defaults'
|
||||
import useTheme from '../styles/use-theme'
|
||||
import AvatarGroup from './avatar-group'
|
||||
|
||||
interface Props {
|
||||
src?: string
|
||||
@@ -41,7 +41,7 @@ const Avatar: React.FC<AvatarProps> = React.memo(({
|
||||
const theme = useTheme()
|
||||
const showText = !src
|
||||
const radius = isSquare ? theme.layout.radius : '50%'
|
||||
const marginLeft = stacked ? '-10px' : 0
|
||||
const marginLeft = stacked ? '-.625rem' : 0
|
||||
|
||||
return (
|
||||
<span className={`avatar ${className}`}>
|
||||
@@ -88,5 +88,12 @@ const Avatar: React.FC<AvatarProps> = React.memo(({
|
||||
)
|
||||
})
|
||||
|
||||
type AvatarComponent<P = {}> = React.FC<P> & {
|
||||
Group: typeof AvatarGroup
|
||||
}
|
||||
|
||||
export default withDefaults(Avatar, defaultProps)
|
||||
type ComponentProps = Partial<typeof defaultProps> & Omit<Props, keyof typeof defaultProps> & NativeAttrs
|
||||
|
||||
(Avatar as AvatarComponent<ComponentProps>).defaultProps = defaultProps
|
||||
|
||||
export default Avatar as AvatarComponent<ComponentProps>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Avatar from './avatar'
|
||||
import { AvatarProps } from './avatar'
|
||||
import AvatarGroup from './avatar-group'
|
||||
|
||||
Avatar.Group = AvatarGroup
|
||||
|
||||
export type Props = AvatarProps
|
||||
export default Avatar
|
||||
|
||||
Reference in New Issue
Block a user