diff --git a/.changeset/forty-ants-promise.md b/.changeset/forty-ants-promise.md
new file mode 100644
index 0000000000..47eeaddd8a
--- /dev/null
+++ b/.changeset/forty-ants-promise.md
@@ -0,0 +1,6 @@
+---
+"@nextui-org/avatar": patch
+"@nextui-org/theme": patch
+---
+
+Support slots in AvatarGroup
diff --git a/apps/docs/content/docs/components/avatar.mdx b/apps/docs/content/docs/components/avatar.mdx
index ad8105f1f0..2cb464ea78 100644
--- a/apps/docs/content/docs/components/avatar.mdx
+++ b/apps/docs/content/docs/components/avatar.mdx
@@ -174,14 +174,15 @@ You can customize any part of the avatar by using the `classNames` prop, each `s
### Avatar Group Props
-| Attribute | Type | Description | Default |
-| ----------- | ------------------------------ | --------------------------------------------------- | ------- |
-| max | `number` | The maximum number of visible avatars | `5` |
-| total | `number` | Control the number of avatar not visible | - |
-| size | `AvatarProps['size']` | Size of the avatars | - |
-| color | `AvatarProps['color']` | Color of the avatars | - |
-| radius | `AvatarProps['radius']` | Radius of the avatars | - |
-| isGrid | `boolean` | Whether the avatars should be displayed in a grid | `false` |
-| isDisabled | `boolean` | Whether the avatars are disabled | - |
-| isBordered | `boolean` | Whether the avatars have a border | - |
-| renderCount | `(count: number) => ReactNode` | This allows you to render a custom count component. | - |
+| Attribute | Type | Description | Default |
+| ----------- | ---------------------------------- | --------------------------------------------------- | ------- |
+| max | `number` | The maximum number of visible avatars | `5` |
+| total | `number` | Control the number of avatar not visible | - |
+| size | `AvatarProps['size']` | Size of the avatars | - |
+| color | `AvatarProps['color']` | Color of the avatars | - |
+| radius | `AvatarProps['radius']` | Radius of the avatars | - |
+| isGrid | `boolean` | Whether the avatars should be displayed in a grid | `false` |
+| isDisabled | `boolean` | Whether the avatars are disabled | - |
+| isBordered | `boolean` | Whether the avatars have a border | - |
+| renderCount | `(count: number) => ReactNode` | This allows you to render a custom count component. | - |
+| classNames | `Record<"base"| "count", string>` | Allows to set custom class names for the avatar group slots. | - |
diff --git a/packages/components/avatar/src/avatar-group.tsx b/packages/components/avatar/src/avatar-group.tsx
index f164e70b68..1106703f57 100644
--- a/packages/components/avatar/src/avatar-group.tsx
+++ b/packages/components/avatar/src/avatar-group.tsx
@@ -12,8 +12,9 @@ const AvatarGroup = forwardRef<"div", AvatarGroupProps>((props, ref) => {
clones,
context,
remainingCount,
- renderCount = (count) => ,
+ getAvatarGroupCountProps,
getAvatarGroupProps,
+ renderCount = (count) => ,
} = useAvatarGroup({
...props,
ref,
diff --git a/packages/components/avatar/src/use-avatar-group.ts b/packages/components/avatar/src/use-avatar-group.ts
index 461e902508..c8bc27b48b 100644
--- a/packages/components/avatar/src/use-avatar-group.ts
+++ b/packages/components/avatar/src/use-avatar-group.ts
@@ -1,4 +1,5 @@
import type {ReactNode} from "react";
+import type {SlotsToClasses, AvatarGroupSlots, AvatarGroupVariantProps} from "@nextui-org/theme";
import {avatarGroup} from "@nextui-org/theme";
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
@@ -31,9 +32,23 @@ interface Props extends HTMLNextUIProps<"div"> {
* This allows you to render a custom count component.
*/
renderCount?: (count: number) => ReactNode;
+ /**
+ * Classname or List of classes to change the classNames of the avatar group.
+ * if `className` is passed, it will be added to the base slot.
+ *
+ * @example
+ * ```ts
+ *
+ * ```
+ */
+ classNames?: SlotsToClasses;
}
export type UseAvatarGroupProps = Props &
+ Omit &
Partial>;
export type ContextType = {
@@ -60,6 +75,7 @@ export function useAvatarGroup(props: UseAvatarGroupProps = {}) {
isGrid,
renderCount,
className,
+ classNames,
...otherProps
} = props;
@@ -78,7 +94,7 @@ export function useAvatarGroup(props: UseAvatarGroupProps = {}) {
}),
[size, color, radius, isGrid, isBordered, isDisabled],
);
- const classNames = useMemo(() => avatarGroup({className, isGrid}), [className, isGrid]);
+ const slots = useMemo(() => avatarGroup({className, isGrid}), [className, isGrid]);
const validChildren = getValidChildren(children);
const childrenWithinMax = max ? validChildren.slice(0, max) : validChildren;
@@ -102,12 +118,22 @@ export function useAvatarGroup(props: UseAvatarGroupProps = {}) {
const getAvatarGroupProps: PropGetter = () => {
return {
ref: domRef,
- className: classNames,
+ className: slots.base({
+ class: clsx(classNames?.base, className),
+ }),
role: "group",
...otherProps,
};
};
+ const getAvatarGroupCountProps = () => {
+ return {
+ className: slots.count({
+ class: classNames?.count,
+ }),
+ } as AvatarProps;
+ };
+
return {
Component,
context,
@@ -115,6 +141,7 @@ export function useAvatarGroup(props: UseAvatarGroupProps = {}) {
clones,
renderCount,
getAvatarGroupProps,
+ getAvatarGroupCountProps,
};
}
diff --git a/packages/components/avatar/stories/avatar-group.stories.tsx b/packages/components/avatar/stories/avatar-group.stories.tsx
index cb0e632469..2b5e75fc85 100644
--- a/packages/components/avatar/stories/avatar-group.stories.tsx
+++ b/packages/components/avatar/stories/avatar-group.stories.tsx
@@ -42,6 +42,47 @@ const Template = (args: AvatarGroupProps) => (
);
+const CustomSlotsTemplate = (args: AvatarGroupProps) => (
+
+
+
+
+
+
+
+
+);
+
export const Default = {
render: Template,
@@ -106,3 +147,14 @@ export const CustomCount = {
),
},
};
+
+export const CustomSlots = {
+ render: CustomSlotsTemplate,
+
+ args: {
+ classNames: {count: "border-2 border-yellow-400"},
+ max: 3,
+ radius: "sm",
+ size: "sm",
+ },
+};
diff --git a/packages/core/react/src/scripts/postbuild.js b/packages/core/react/src/scripts/postbuild.js
index 74f0cbc05c..4fc04f8009 100644
--- a/packages/core/react/src/scripts/postbuild.js
+++ b/packages/core/react/src/scripts/postbuild.js
@@ -52,7 +52,7 @@ function generateComponents() {
version: componentVersion,
docs: componentDocs,
description: componentDesc,
- status: (routeComponent.updated && 'updated') || (routeComponent.newPost && 'newPost') || 'stable',
+ status: (routeComponent.updated && 'updated') || (routeComponent.newPost && 'new') || 'stable',
style: style || '',
}
diff --git a/packages/core/theme/src/components/avatar.ts b/packages/core/theme/src/components/avatar.ts
index 96385f4873..16bf99f6f8 100644
--- a/packages/core/theme/src/components/avatar.ts
+++ b/packages/core/theme/src/components/avatar.ts
@@ -187,7 +187,10 @@ const avatar = tv({
*
*/
const avatarGroup = tv({
- base: "flex items-center justify-center h-auto w-max-content",
+ slots: {
+ base: "flex items-center justify-center h-auto w-max-content",
+ count: "hover:-translate-x-0",
+ },
variants: {
isGrid: {
true: "inline-grid grid-cols-4 gap-3",
@@ -200,6 +203,7 @@ const avatarGroup = tv({
// -ms-2 hover:-translate-x-0 ms-0
export type AvatarGroupVariantProps = VariantProps;
+export type AvatarGroupSlots = keyof ReturnType;
export type AvatarVariantProps = VariantProps;
export type AvatarSlots = keyof ReturnType;