39 lines
1.1 KiB
TypeScript
39 lines
1.1 KiB
TypeScript
|
import { Children, PropsWithChildren } from 'react'
|
||
|
|
||
|
import styles from './style.module.scss'
|
||
|
|
||
|
interface UserAvatarGroupProps extends React.HTMLAttributes<HTMLDivElement> {
|
||
|
max: number
|
||
|
renderSurplus?: ((surplus: number) => React.ReactNode) | undefined
|
||
|
}
|
||
|
|
||
|
const defaultSurplus = (surplus: number) => {
|
||
|
return <span className={styles.icon}>+{surplus}</span>
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Renders children with the `max` limit (including surplus if available).
|
||
|
* The children are wrapped with a `div` (accepts standard `HTMLDivElement` attributes)
|
||
|
* @param max The maximum number of children rendered in a div.
|
||
|
* @param renderSurplus Custom render for surplus children (accepts surplus number).
|
||
|
*/
|
||
|
export const UserAvatarGroup = ({
|
||
|
max,
|
||
|
renderSurplus = defaultSurplus,
|
||
|
children,
|
||
|
...rest
|
||
|
}: PropsWithChildren<UserAvatarGroupProps>) => {
|
||
|
const total = Children.count(children)
|
||
|
const surplus = total - max + 1
|
||
|
|
||
|
const childrenArray = Children.toArray(children)
|
||
|
return (
|
||
|
<div {...rest}>
|
||
|
{surplus > 1
|
||
|
? childrenArray.slice(0, surplus * -1).map((c) => c)
|
||
|
: children}
|
||
|
{surplus > 1 && renderSurplus(surplus)}
|
||
|
</div>
|
||
|
)
|
||
|
}
|