{"version":3,"file":"AvatarGroup.mjs","sources":["../../../../src/components/AvatarGroup/AvatarGroup.tsx"],"sourcesContent":["'use client'\n\nimport { forwardRef, useCallback, useMemo } from 'react'\nimport * as React from 'react'\n\nimport { MoreIcon } from '@channel.io/bezier-icons'\nimport classNames from 'classnames'\n\nimport { isLastIndex } from '~/src/utils/array'\nimport { px } from '~/src/utils/style'\n\nimport {\n  type AvatarProps,\n  type AvatarSize,\n  useAvatarRadiusToken,\n} from '~/src/components/Avatar'\nimport { Icon } from '~/src/components/Icon'\nimport { SmoothCornersBox } from '~/src/components/SmoothCornersBox'\nimport { Text } from '~/src/components/Text'\n\nimport { type AvatarGroupProps } from './AvatarGroup.types'\n\nimport styles from './AvatarGroup.module.scss'\n\nconst MAX_AVATAR_LIST_COUNT = 99\nconst AVATAR_GROUP_DEFAULT_SPACING = 4\nexport const AVATAR_GROUP_ELLIPSIS_ICON_TEST_ID =\n  'bezier-avatar-group-ellipsis-icon'\n\nfunction getRestAvatarListCountText(count: number, max: number) {\n  const restCount = count - max\n  return `+${restCount > MAX_AVATAR_LIST_COUNT ? MAX_AVATAR_LIST_COUNT : restCount}`\n}\n\n// TODO: Not specified\nfunction getProperIconSize(avatarSize: AvatarSize) {\n  return (\n    {\n      20: 'xxs',\n      24: 'xs',\n      30: 's',\n      36: 'm',\n      42: 'm',\n      48: 'l',\n      72: 'l',\n      90: 'l',\n      120: 'l',\n    } as const\n  )[avatarSize]\n}\n\n// TODO: Not specified\nfunction getProperTypoSize(avatarSize: AvatarSize) {\n  return (\n    {\n      20: '12',\n      24: '13',\n      30: '15',\n      36: '16',\n      42: '18',\n      48: '24',\n      72: '24',\n      90: '24',\n      120: '24',\n    } as const\n  )[avatarSize]\n}\n\n/**\n * `AvatarGroup` is a component for grouping `Avatar` components\n * @example\n *\n * ```tsx\n * <AvatarGroup\n *  max={2}\n *  spacing={4}\n *  ellipsisType=\"icon\"\n * >\n *    <Avatar />\n *    <Avatar />\n *    <Avatar />\n * </AvatarGroup>\n * ```\n */\nexport const AvatarGroup = forwardRef<HTMLDivElement, AvatarGroupProps>(\n  function AvatarGroup(\n    {\n      max,\n      size = '24',\n      spacing = AVATAR_GROUP_DEFAULT_SPACING,\n      ellipsisType = 'icon',\n      onMouseEnterEllipsis,\n      onMouseLeaveEllipsis,\n      style,\n      className,\n      children,\n      ...rest\n    },\n    forwardedRef\n  ) {\n    const AVATAR_BORDER_RADIUS = useAvatarRadiusToken()\n\n    const renderAvatarElement = useCallback(\n      (avatar: React.ReactElement<AvatarProps>, avatarListCount: number) => {\n        const key =\n          avatar.key ?? `${avatar.props.name}-${avatar.props.avatarUrl}`\n        const shouldShowBorder = avatarListCount > 1 && spacing < 0\n        const showBorder = avatar.props.showBorder || shouldShowBorder\n        return React.cloneElement(avatar, { key, size, showBorder })\n      },\n      [size, spacing]\n    )\n\n    const avatarListCount = useMemo(\n      () => React.Children.count(children),\n      [children]\n    )\n\n    const AvatarListComponent = useMemo(() => {\n      if (avatarListCount <= max) {\n        return React.Children.map(\n          children,\n          (avatar) =>\n            React.isValidElement<AvatarProps>(avatar) &&\n            renderAvatarElement(avatar, avatarListCount)\n        )\n      }\n\n      const sliceEndIndex = max - avatarListCount\n      const slicedAvatarList = React.Children.toArray(children).slice(\n        0,\n        sliceEndIndex\n      )\n\n      return slicedAvatarList.map((avatar, index, arr) => {\n        if (!React.isValidElement<AvatarProps>(avatar)) {\n          return null\n        }\n\n        const AvatarElement = renderAvatarElement(\n          avatar,\n          slicedAvatarList.length\n        )\n\n        if (!isLastIndex(arr, index)) {\n          return AvatarElement\n        }\n\n        if (ellipsisType === 'icon') {\n          return (\n            <div\n              key=\"ellipsis\"\n              className={styles.AvatarEllipsisIconWrapper}\n              onMouseEnter={onMouseEnterEllipsis}\n              onMouseLeave={onMouseLeaveEllipsis}\n              data-testid={AVATAR_GROUP_ELLIPSIS_ICON_TEST_ID}\n            >\n              <SmoothCornersBox\n                borderRadius={AVATAR_BORDER_RADIUS}\n                backgroundColor=\"fill-absolute-black-light\"\n                className={styles.AvatarEllipsisIcon}\n              >\n                <Icon\n                  source={MoreIcon}\n                  size={getProperIconSize(size)}\n                  color=\"text-absolute-white\"\n                />\n              </SmoothCornersBox>\n              {AvatarElement}\n            </div>\n          )\n        }\n\n        if (ellipsisType === 'count') {\n          return (\n            <React.Fragment key=\"ellipsis\">\n              {AvatarElement}\n              <div\n                style={\n                  {\n                    '--b-avatar-group-ellipsis-ml': px(\n                      Math.max(spacing, AVATAR_GROUP_DEFAULT_SPACING)\n                    ),\n                  } as React.CSSProperties\n                }\n                className={classNames(\n                  styles.AvatarEllipsisCountWrapper,\n                  styles[`size-${size}`]\n                )}\n                onMouseEnter={onMouseEnterEllipsis}\n                onMouseLeave={onMouseLeaveEllipsis}\n              >\n                <Text\n                  typo={getProperTypoSize(size)}\n                  color=\"text-neutral-lighter\"\n                  className={styles.AvatarEllipsisCount}\n                >\n                  {getRestAvatarListCountText(avatarListCount, max)}\n                </Text>\n              </div>\n            </React.Fragment>\n          )\n        }\n\n        return null\n      })\n    }, [\n      avatarListCount,\n      max,\n      children,\n      renderAvatarElement,\n      ellipsisType,\n      onMouseEnterEllipsis,\n      onMouseLeaveEllipsis,\n      AVATAR_BORDER_RADIUS,\n      size,\n      spacing,\n    ])\n\n    return (\n      <div\n        role=\"group\"\n        ref={forwardedRef}\n        className={classNames(\n          styles.AvatarGroup,\n          styles[`size-${size}`],\n          className\n        )}\n        style={\n          {\n            '--b-avatar-group-spacing': px(spacing),\n            ...style,\n          } as React.CSSProperties\n        }\n        {...rest}\n      >\n        {AvatarListComponent}\n      </div>\n    )\n  }\n)\n"],"names":["MAX_AVATAR_LIST_COUNT","AVATAR_GROUP_DEFAULT_SPACING","AVATAR_GROUP_ELLIPSIS_ICON_TEST_ID","getRestAvatarListCountText","count","max","restCount","getProperIconSize","avatarSize","getProperTypoSize","AvatarGroup","forwardRef","size","spacing","ellipsisType","onMouseEnterEllipsis","onMouseLeaveEllipsis","style","className","children","rest","forwardedRef","AVATAR_BORDER_RADIUS","useAvatarRadiusToken","renderAvatarElement","useCallback","avatar","avatarListCount","_avatar$key","key","props","name","avatarUrl","shouldShowBorder","showBorder","React","cloneElement","useMemo","Children","AvatarListComponent","map","isValidElement","sliceEndIndex","slicedAvatarList","toArray","slice","index","arr","AvatarElement","length","isLastIndex","_jsxs","styles","AvatarEllipsisIconWrapper","onMouseEnter","onMouseLeave","_jsx","SmoothCornersBox","borderRadius","backgroundColor","AvatarEllipsisIcon","Icon","source","MoreIcon","color","Fragment","px","Math","classNames","AvatarEllipsisCountWrapper","Text","typo","AvatarEllipsisCount","role","ref"],"mappings":";;;;;;;;;;;;;AAwBA,MAAMA,qBAAqB,GAAG,EAAE;AAChC,MAAMC,4BAA4B,GAAG,CAAC;AAC/B,MAAMC,kCAAkC,GAC7C;AAEF,SAASC,0BAA0BA,CAACC,KAAa,EAAEC,GAAW,EAAE;AAC9D,EAAA,MAAMC,SAAS,GAAGF,KAAK,GAAGC,GAAG;EAC7B,OAAO,CAAA,CAAA,EAAIC,SAAS,GAAGN,qBAAqB,GAAGA,qBAAqB,GAAGM,SAAS,CAAE,CAAA;AACpF;;AAEA;AACA,SAASC,iBAAiBA,CAACC,UAAsB,EAAE;EACjD,OACE;AACE,IAAA,EAAE,EAAE,KAAK;AACT,IAAA,EAAE,EAAE,IAAI;AACR,IAAA,EAAE,EAAE,GAAG;AACP,IAAA,EAAE,EAAE,GAAG;AACP,IAAA,EAAE,EAAE,GAAG;AACP,IAAA,EAAE,EAAE,GAAG;AACP,IAAA,EAAE,EAAE,GAAG;AACP,IAAA,EAAE,EAAE,GAAG;AACP,IAAA,GAAG,EAAE;GACN,CACDA,UAAU,CAAC;AACf;;AAEA;AACA,SAASC,iBAAiBA,CAACD,UAAsB,EAAE;EACjD,OACE;AACE,IAAA,EAAE,EAAE,IAAI;AACR,IAAA,EAAE,EAAE,IAAI;AACR,IAAA,EAAE,EAAE,IAAI;AACR,IAAA,EAAE,EAAE,IAAI;AACR,IAAA,EAAE,EAAE,IAAI;AACR,IAAA,EAAE,EAAE,IAAI;AACR,IAAA,EAAE,EAAE,IAAI;AACR,IAAA,EAAE,EAAE,IAAI;AACR,IAAA,GAAG,EAAE;GACN,CACDA,UAAU,CAAC;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACaE,WAAW,gBAAGC,UAAU,CACnC,SAASD,WAAWA,CAClB;EACEL,GAAG;AACHO,EAAAA,IAAI,GAAG,IAAI;AACXC,EAAAA,OAAO,GAAGZ,4BAA4B;AACtCa,EAAAA,YAAY,GAAG,MAAM;EACrBC,oBAAoB;EACpBC,oBAAoB;EACpBC,KAAK;EACLC,SAAS;EACTC,QAAQ;EACR,GAAGC;AACL,CAAC,EACDC,YAAY,EACZ;AACA,EAAA,MAAMC,oBAAoB,GAAGC,oBAAoB,EAAE;EAEnD,MAAMC,mBAAmB,GAAGC,WAAW,CACrC,CAACC,MAAuC,EAAEC,eAAuB,KAAK;AAAA,IAAA,IAAAC,WAAA;IACpE,MAAMC,GAAG,GAAAD,CAAAA,WAAA,GACPF,MAAM,CAACG,GAAG,MAAA,IAAA,IAAAD,WAAA,KAAA,KAAA,CAAA,GAAAA,WAAA,GAAI,GAAGF,MAAM,CAACI,KAAK,CAACC,IAAI,CAAA,CAAA,EAAIL,MAAM,CAACI,KAAK,CAACE,SAAS,CAAE,CAAA;IAChE,MAAMC,gBAAgB,GAAGN,eAAe,GAAG,CAAC,IAAId,OAAO,GAAG,CAAC;IAC3D,MAAMqB,UAAU,GAAGR,MAAM,CAACI,KAAK,CAACI,UAAU,IAAID,gBAAgB;AAC9D,IAAA,oBAAOE,KAAK,CAACC,YAAY,CAACV,MAAM,EAAE;MAAEG,GAAG;MAAEjB,IAAI;AAAEsB,MAAAA;AAAW,KAAC,CAAC;AAC9D,GAAC,EACD,CAACtB,IAAI,EAAEC,OAAO,CAChB,CAAC;AAED,EAAA,MAAMc,eAAe,GAAGU,OAAO,CAC7B,MAAMF,KAAK,CAACG,QAAQ,CAAClC,KAAK,CAACe,QAAQ,CAAC,EACpC,CAACA,QAAQ,CACX,CAAC;AAED,EAAA,MAAMoB,mBAAmB,GAAGF,OAAO,CAAC,MAAM;IACxC,IAAIV,eAAe,IAAItB,GAAG,EAAE;MAC1B,OAAO8B,KAAK,CAACG,QAAQ,CAACE,GAAG,CACvBrB,QAAQ,EACPO,MAAM,iBACLS,KAAK,CAACM,cAAc,CAAcf,MAAM,CAAC,IACzCF,mBAAmB,CAACE,MAAM,EAAEC,eAAe,CAC/C,CAAC;AACH;AAEA,IAAA,MAAMe,aAAa,GAAGrC,GAAG,GAAGsB,eAAe;AAC3C,IAAA,MAAMgB,gBAAgB,GAAGR,KAAK,CAACG,QAAQ,CAACM,OAAO,CAACzB,QAAQ,CAAC,CAAC0B,KAAK,CAC7D,CAAC,EACDH,aACF,CAAC;IAED,OAAOC,gBAAgB,CAACH,GAAG,CAAC,CAACd,MAAM,EAAEoB,KAAK,EAAEC,GAAG,KAAK;AAClD,MAAA,IAAI,eAACZ,KAAK,CAACM,cAAc,CAAcf,MAAM,CAAC,EAAE;AAC9C,QAAA,OAAO,IAAI;AACb;MAEA,MAAMsB,aAAa,GAAGxB,mBAAmB,CACvCE,MAAM,EACNiB,gBAAgB,CAACM,MACnB,CAAC;AAED,MAAA,IAAI,CAACC,WAAW,CAACH,GAAG,EAAED,KAAK,CAAC,EAAE;AAC5B,QAAA,OAAOE,aAAa;AACtB;MAEA,IAAIlC,YAAY,KAAK,MAAM,EAAE;AAC3B,QAAA,oBACEqC,IAAA,CAAA,KAAA,EAAA;UAEEjC,SAAS,EAAEkC,MAAM,CAACC,yBAA0B;AAC5CC,UAAAA,YAAY,EAAEvC,oBAAqB;AACnCwC,UAAAA,YAAY,EAAEvC,oBAAqB;AACnC,UAAA,aAAA,EAAad,kCAAmC;UAAAiB,QAAA,EAAA,cAEhDqC,GAAA,CAACC,gBAAgB,EAAA;AACfC,YAAAA,YAAY,EAAEpC,oBAAqB;AACnCqC,YAAAA,eAAe,EAAC,2BAA2B;YAC3CzC,SAAS,EAAEkC,MAAM,CAACQ,kBAAmB;YAAAzC,QAAA,eAErCqC,GAAA,CAACK,IAAI,EAAA;AACHC,cAAAA,MAAM,EAAEC,QAAS;AACjBnD,cAAAA,IAAI,EAAEL,iBAAiB,CAACK,IAAI,CAAE;AAC9BoD,cAAAA,KAAK,EAAC;aACP;WACe,CAAC,EAClBhB,aAAa;AAAA,SAAA,EAjBV,UAkBD,CAAC;AAEV;MAEA,IAAIlC,YAAY,KAAK,OAAO,EAAE;AAC5B,QAAA,oBACEqC,IAAA,CAAChB,KAAK,CAAC8B,QAAQ,EAAA;UAAA9C,QAAA,EAAA,CACZ6B,aAAa,eACdQ,GAAA,CAAA,KAAA,EAAA;AACEvC,YAAAA,KAAK,EACH;cACE,8BAA8B,EAAEiD,EAAE,CAChCC,IAAI,CAAC9D,GAAG,CAACQ,OAAO,EAAEZ,4BAA4B,CAChD;aAEH;AACDiB,YAAAA,SAAS,EAAEkD,UAAU,CACnBhB,MAAM,CAACiB,0BAA0B,EACjCjB,MAAM,CAAC,CAAA,KAAA,EAAQxC,IAAI,CAAA,CAAE,CACvB,CAAE;AACF0C,YAAAA,YAAY,EAAEvC,oBAAqB;AACnCwC,YAAAA,YAAY,EAAEvC,oBAAqB;YAAAG,QAAA,eAEnCqC,GAAA,CAACc,IAAI,EAAA;AACHC,cAAAA,IAAI,EAAE9D,iBAAiB,CAACG,IAAI,CAAE;AAC9BoD,cAAAA,KAAK,EAAC,sBAAsB;cAC5B9C,SAAS,EAAEkC,MAAM,CAACoB,mBAAoB;AAAArD,cAAAA,QAAA,EAErChB,0BAA0B,CAACwB,eAAe,EAAEtB,GAAG;aAC5C;AAAC,WACJ,CAAC;AAAA,SAAA,EAxBY,UAyBJ,CAAC;AAErB;AAEA,MAAA,OAAO,IAAI;AACb,KAAC,CAAC;GACH,EAAE,CACDsB,eAAe,EACftB,GAAG,EACHc,QAAQ,EACRK,mBAAmB,EACnBV,YAAY,EACZC,oBAAoB,EACpBC,oBAAoB,EACpBM,oBAAoB,EACpBV,IAAI,EACJC,OAAO,CACR,CAAC;AAEF,EAAA,oBACE2C,GAAA,CAAA,KAAA,EAAA;AACEiB,IAAAA,IAAI,EAAC,OAAO;AACZC,IAAAA,GAAG,EAAErD,YAAa;AAClBH,IAAAA,SAAS,EAAEkD,UAAU,CACnBhB,MAAM,CAAC1C,WAAW,EAClB0C,MAAM,CAAC,QAAQxC,IAAI,CAAA,CAAE,CAAC,EACtBM,SACF,CAAE;AACFD,IAAAA,KAAK,EACH;AACE,MAAA,0BAA0B,EAAEiD,EAAE,CAACrD,OAAO,CAAC;MACvC,GAAGI;KAEN;AAAA,IAAA,GACGG,IAAI;AAAAD,IAAAA,QAAA,EAEPoB;AAAmB,GACjB,CAAC;AAEV,CACF;;;;"}