diff --git a/src/components/AvatarGroup/AvatarGroupCounter.tsx b/src/components/AvatarGroup/AvatarGroupCounter.tsx new file mode 100644 index 000000000..3965d978a --- /dev/null +++ b/src/components/AvatarGroup/AvatarGroupCounter.tsx @@ -0,0 +1,17 @@ +import React, { PropsWithChildren } from 'react'; + +export type AvatarGroupdCounterProps = PropsWithChildren<{ + total?: number; + href: string; +}>; + +export const AvatarGroupCounter: React.FC<AvatarGroupdCounterProps> = ({ total, href }) => { + return ( + <a + className="relative flex h-10 w-10 items-center justify-center rounded-full bg-gray-700 text-xs font-medium text-white ring-2 ring-gray-300 hover:bg-gray-600 dark:border-gray-800 " + href={href} + > + +{total} + </a> + ); +}; diff --git a/src/components/AvatarGroup/index.tsx b/src/components/AvatarGroup/index.tsx new file mode 100644 index 000000000..131b9a006 --- /dev/null +++ b/src/components/AvatarGroup/index.tsx @@ -0,0 +1,14 @@ +import React, { PropsWithChildren, ReactNode } from 'react'; +import { AvatarGroupCounter } from './AvatarGroupCounter'; + +export type AvatarGroupProps = PropsWithChildren<{ + children: ReactNode; +}>; + +const AvatarGroupComponent: React.FC<AvatarGroupProps> = ({ children }) => { + return <div className="mb-5 flex -space-x-4">{children}</div>; +}; + +export const AvatarGroup = Object.assign(AvatarGroupComponent, { + Counter: AvatarGroupCounter, +}); diff --git a/src/components/Avatar.tsx b/src/components/avatar/Avatar.tsx similarity index 90% rename from src/components/Avatar.tsx rename to src/components/avatar/Avatar.tsx index b9f41eaf6..e9ab87311 100644 --- a/src/components/Avatar.tsx +++ b/src/components/avatar/Avatar.tsx @@ -8,6 +8,7 @@ export type AvatarProps = PropsWithChildren<{ img?: string; status?: 'offline' | 'online' | 'away' | 'busy'; statusPosition?: 'top-left' | 'top-right' | 'bottom-right' | 'bottom-left'; + stacked?: boolean; }>; const sizeClasses: Record<AvatarProps['size'] & string, string> = { @@ -40,6 +41,7 @@ export const Avatar: FC<AvatarProps> = ({ size = 'md', rounded = false, bordered = false, + stacked = false, }) => { return ( <div className="flex items-center space-x-4"> @@ -49,7 +51,8 @@ export const Avatar: FC<AvatarProps> = ({ className={classNames(sizeClasses[size], { rounded: !rounded, 'rounded-full': rounded, - 'p-1 ring-2 ring-gray-300 dark:ring-gray-500': bordered, + 'ring-2 ring-gray-300 dark:ring-gray-500': bordered || stacked, + 'p-1': bordered, })} src={img} alt="Rounded avatar" @@ -59,7 +62,8 @@ export const Avatar: FC<AvatarProps> = ({ className={classNames(`relative overflow-hidden bg-gray-100 dark:bg-gray-600`, sizeClasses[size], { rounded: !rounded, 'rounded-full': rounded, - 'p-1 ring-2 ring-gray-300 dark:ring-gray-500': bordered, + 'ring-2 ring-gray-300 dark:ring-gray-500': bordered || stacked, + 'p-1': bordered, })} > <svg diff --git a/src/components/index.ts b/src/components/index.ts index d44a4f3dc..83f9b01d3 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,6 +1,7 @@ export * from './Alert'; export * from './Accordion'; -export * from './Avatar'; +export * from './avatar/Avatar'; +export * from './AvatarGroup'; export * from './Badge'; export * from './Breadcrumb'; export * from './Button'; diff --git a/src/pages/AvatarPage.tsx b/src/pages/AvatarPage.tsx index 58090172b..8325df216 100644 --- a/src/pages/AvatarPage.tsx +++ b/src/pages/AvatarPage.tsx @@ -1,6 +1,7 @@ import { FC } from 'react'; import { Avatar, Dropdown } from '../components'; +import { AvatarGroup } from '../components/AvatarGroup'; import { CodeExample, DemoPage } from './DemoPage'; const AvatarPage: FC = () => { @@ -57,6 +58,27 @@ const AvatarPage: FC = () => { </div> ), }, + { + title: 'Stacked', + code: ( + <> + <AvatarGroup> + <Avatar img="https://flowbite.com/docs/images/people/profile-picture-1.jpg" rounded stacked /> + <Avatar img="https://flowbite.com/docs/images/people/profile-picture-2.jpg" rounded stacked /> + <Avatar img="https://flowbite.com/docs/images/people/profile-picture-3.jpg" rounded stacked /> + <Avatar img="https://flowbite.com/docs/images/people/profile-picture-4.jpg" rounded stacked /> + <Avatar img="https://flowbite.com/docs/images/people/profile-picture-5.jpg" rounded stacked /> + </AvatarGroup> + <AvatarGroup> + <Avatar img="https://flowbite.com/docs/images/people/profile-picture-1.jpg" rounded stacked /> + <Avatar img="https://flowbite.com/docs/images/people/profile-picture-2.jpg" rounded stacked /> + <Avatar img="https://flowbite.com/docs/images/people/profile-picture-3.jpg" rounded stacked /> + <Avatar img="https://flowbite.com/docs/images/people/profile-picture-4.jpg" rounded stacked /> + <AvatarGroup.Counter total={99} href="#" /> + </AvatarGroup> + </> + ), + }, { title: 'Avatar text', code: (