import React from 'react'; import { StyleProp, View, ViewStyle } from 'react-native'; const MAX = 4; type AvatarChildProps = { size?: number; square?: boolean; containerStyle?: StyleProp; }; type Props = React.PropsWithChildren<{ size?: number; containerStyle?: StyleProp; }>; const AvatarGroup = ({ children, containerStyle, size = 56 }: Props) => { const childAmount = React.Children.count(children); if (childAmount === 0) { return ( ); } const renderAvatars = () => { return ( React.Children.map(children, (child, index) => { if (index + 1 > MAX) return child; if (!React.isValidElement(child)) return child; if (childAmount === 1) { return React.cloneElement(child as React.ReactElement, { size, containerStyle }); } const top = getTopPoint(index, childAmount) * size; const start = getStartPoint(index) * size; const width = getWidthPoint(index, childAmount) * size; const height = getHeightPoint(index, childAmount) * size; const innerStart = -getInnerStart(index, childAmount) * size; const innerTop = -getInnerTop(childAmount) * size; return ( {React.cloneElement(child as React.ReactElement, { size, square: true, containerStyle: { start: innerStart, top: innerTop }, })} ); })?.slice(0, 4) ?? [] ); }; return ( {renderAvatars()} ); }; const getHeightPoint = (_: number, total: number) => { if (total === 2) return 1; return 0.5; }; const getWidthPoint = (idx: number, total: number) => { if (total === 3 && idx === 0) return 1; return 0.5; }; const getTopPoint = (idx: number, total: number) => { if (total === 2) return 0; if (total === 3 && idx === 0) return -0.025; if (total === 3 && idx !== 0) return 0.525; if (idx === 0 || idx === 1) return -0.025; return 0.525; }; const getStartPoint = (idx: number) => { if (idx === 0 || idx === 2) return -0.025; return 0.525; }; const getInnerStart = (idx: number, total: number) => { if (total === 3 && idx === 0) return 0; return 0.25; }; const getInnerTop = (total: number) => { if (total === 2) return 0; return 0.25; }; export default AvatarGroup;