Skip to content

Commit 21d7ce1

Browse files
authored
Merge pull request #6655 from LibenHailu/publish-avatar-and-avarat-group-component
Publish avatar and avarat group component
2 parents 1f4e4af + 5aa68cc commit 21d7ce1

8 files changed

Lines changed: 916 additions & 4 deletions

File tree

2.02 KB
Loading
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
import React, { useState } from "react";
2+
import { Avatar, AvatarGroup, SistentThemeProvider } from "@sistent/sistent";
3+
import { SistentLayout } from "../../sistent-layout";
4+
import TabButton from "../../../../../reusecore/Button";
5+
import { CodeBlock } from "../button/code-block";
6+
import { useStyledDarkMode } from "../../../../../theme/app/useStyledDarkMode";
7+
8+
import user1 from "../../../../../assets/images/sistent/placeholder/user.webp";
9+
import user2 from "../../../../../assets/images/sistent/placeholder/user.webp";
10+
import user3 from "../../../../../assets/images/sistent/placeholder/user.webp";
11+
import user4 from "../../../../../assets/images/sistent/placeholder/user.webp";
12+
13+
const TABS = ["Overview", "Guidance", "Code"];
14+
15+
const avatarGroupExamples = [
16+
{
17+
title: "Basic AvatarGroup",
18+
description: "Display a horizontal group of avatars with default overlap.",
19+
element: (
20+
<AvatarGroup>
21+
<Avatar src={user1} alt="User 1" />
22+
<Avatar src={user2} alt="User 2" />
23+
<Avatar src={user3} alt="User 3" />
24+
</AvatarGroup>
25+
),
26+
code: `<AvatarGroup>
27+
<Avatar src="/user1.jpg" alt="User 1" />
28+
<Avatar src="/user2.jpg" alt="User 2" />
29+
<Avatar src="/user3.jpg" alt="User 3" />
30+
</AvatarGroup>`,
31+
id: "basic-group",
32+
},
33+
{
34+
title: "Max Avatars",
35+
description: "Limit the number of visible avatars using the `max` prop.",
36+
element: (
37+
<AvatarGroup max={3}>
38+
<Avatar src={user1} alt="User 1" />
39+
<Avatar src={user2} alt="User 2" />
40+
<Avatar src={user3} alt="User 3" />
41+
<Avatar src={user4} alt="User 4" />
42+
</AvatarGroup>
43+
),
44+
code: `<AvatarGroup max={3}>
45+
<Avatar src="/user1.jpg" />
46+
<Avatar src="/user2.jpg" />
47+
<Avatar src="/user3.jpg" />
48+
<Avatar src="/user4.jpg" />
49+
</AvatarGroup>`,
50+
id: "max-group",
51+
},
52+
{
53+
title: "Custom Spacing",
54+
description: "Control the spacing between avatars.",
55+
element: (
56+
<AvatarGroup spacing="medium">
57+
<Avatar src={user1} />
58+
<Avatar src={user2} />
59+
<Avatar src={user3} />
60+
</AvatarGroup>
61+
),
62+
code: `<AvatarGroup spacing="medium">
63+
<Avatar src="/user1.jpg" />
64+
<Avatar src="/user2.jpg" />
65+
<Avatar src="/user3.jpg" />
66+
</AvatarGroup>`,
67+
id: "spacing-group",
68+
},
69+
{
70+
title: "Shape Variants",
71+
description: "Mix avatar shape variants like square and rounded.",
72+
element: (
73+
<AvatarGroup>
74+
<Avatar variant="rounded" src={user1} />
75+
<Avatar variant="square" src={user2} />
76+
<Avatar src={user3} />
77+
</AvatarGroup>
78+
),
79+
code: `<AvatarGroup>
80+
<Avatar variant="rounded" src="/user1.jpg" />
81+
<Avatar variant="square" src="/user2.jpg" />
82+
<Avatar src="/user3.jpg" />
83+
</AvatarGroup>`,
84+
id: "variant-group",
85+
},
86+
{
87+
title: "Total Avatars",
88+
description:
89+
"You can indicate the total number of avatars using the `total` prop, even if not all are rendered.",
90+
element: (
91+
<AvatarGroup total={7}>
92+
<Avatar src={user1} />
93+
<Avatar src={user2} />
94+
<Avatar src={user3} />
95+
</AvatarGroup>
96+
),
97+
code: `<AvatarGroup total={7}>
98+
<Avatar src="/user1.jpg" />
99+
<Avatar src="/user2.jpg" />
100+
<Avatar src="/user3.jpg" />
101+
</AvatarGroup>`,
102+
id: "total-avatars",
103+
},
104+
{
105+
title: "Custom Surplus Renderer",
106+
description:
107+
"Customize the overflow display using the `renderSurplus` prop for more control over surplus appearance.",
108+
element: (
109+
<AvatarGroup
110+
max={2}
111+
renderSurplus={(surplus) => <span>+{surplus.toString()[0]}k</span>}
112+
total={4251}
113+
>
114+
<Avatar src={user1} />
115+
<Avatar src={user2} />
116+
<Avatar src={user3} />
117+
<Avatar src={user4} />
118+
</AvatarGroup>
119+
),
120+
code: `<AvatarGroup
121+
max={2}
122+
renderSurplus={(surplus) => (
123+
<Avatar sx={{ bgcolor: 'secondary.main' }}>{\`+\${surplus} more\`}</Avatar>
124+
)}
125+
>
126+
<Avatar src="/user1.jpg" />
127+
<Avatar src="/user2.jpg" />
128+
<Avatar src="/user3.jpg" />
129+
<Avatar src="/user4.jpg" />
130+
</AvatarGroup>`,
131+
id: "custom-surplus",
132+
},
133+
];
134+
135+
const AvatarGroupComponent = () => {
136+
const { isDark } = useStyledDarkMode();
137+
const [activeTab, setActiveTab] = useState("Overview");
138+
139+
return (
140+
<SistentLayout title="Avatar Group">
141+
<section className="content">
142+
<a id="Identity">
143+
<h2>Avatar Group</h2>
144+
</a>
145+
<p>
146+
Below are practical implementation examples of the
147+
<code>AvatarGroup</code> component, showcasing different
148+
configurations such as max user limit, spacing, variant styling, and
149+
accessibility-friendly usage. These examples are designed to help you
150+
apply <code>AvatarGroup</code> effectively across team or user-related
151+
interfaces.
152+
</p>
153+
154+
<div className="filterBtns">
155+
{TABS.map((tab) => (
156+
<TabButton
157+
key={tab}
158+
title={tab}
159+
className={activeTab === tab ? "active" : ""}
160+
onClick={() => setActiveTab(tab)}
161+
/>
162+
))}
163+
</div>
164+
165+
<p>
166+
The AvatarGroup component helps visually group multiple avatars in a
167+
compact and meaningful layout, often representing users in a shared
168+
context.
169+
</p>
170+
171+
{activeTab === "Code" && (
172+
<div className="code-examples">
173+
<h3>AvatarGroup Implementation Variants</h3>
174+
<SistentThemeProvider initialMode={isDark ? "dark" : "light"}>
175+
{avatarGroupExamples.map(
176+
({ title, description, element, code, id }) => (
177+
<section key={id}>
178+
<h4>{title}</h4>
179+
<p>{description}</p>
180+
<div className="showcase">
181+
<div className="items">{element}</div>
182+
<CodeBlock name={id} code={code} />
183+
</div>
184+
</section>
185+
),
186+
)}
187+
</SistentThemeProvider>
188+
</div>
189+
)}
190+
191+
{activeTab === "Overview" && (
192+
<div className="overview">
193+
<h3>Usage</h3>
194+
<p>
195+
Use AvatarGroup when you want to display a group of users or
196+
entities visually. It's useful for team indicators,
197+
collaborations, or contributors. You can adjust overlap, limit
198+
display with `max`, or even indicate a total with `total`.
199+
</p>
200+
</div>
201+
)}
202+
203+
{activeTab === "Guidance" && (
204+
<div className="guidance">
205+
<h3>Design Guidance</h3>
206+
<p>
207+
Keep avatar count minimal (ideally &lt; 5) to reduce clutter.
208+
Surplus avatars should indicate remaining count clearly (e.g.
209+
"+3"). Consider consistent shapes, sizes, and padding across your
210+
app.
211+
</p>
212+
<ul>
213+
<li>
214+
Use `max` and `total` for clear grouping when avatars exceed
215+
space.
216+
</li>
217+
<li>
218+
Use `renderSurplus` to match branding or add tooltips/custom UI.
219+
</li>
220+
<li>Maintain consistent alt texts for accessibility.</li>
221+
</ul>
222+
</div>
223+
)}
224+
</section>
225+
</SistentLayout>
226+
);
227+
};
228+
229+
export default AvatarGroupComponent;
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import React from "react";
2+
import { navigate } from "gatsby";
3+
import { useLocation } from "@reach/router";
4+
import { SistentLayout } from "../../sistent-layout";
5+
import TabButton from "../../../../../reusecore/Button";
6+
7+
const AvatarGroupGuidance = () => {
8+
const location = useLocation();
9+
10+
return (
11+
<SistentLayout title="Avatar Group">
12+
<div className="content">
13+
<a id="Identity">
14+
<h2>Avatar Group</h2>
15+
</a>
16+
<p>
17+
The <strong>AvatarGroup</strong> component displays a compact
18+
collection of avatar elements that represent a group of users or
19+
entities. It’s useful in collaborative spaces, team-based features, or
20+
user listings.
21+
</p>
22+
23+
{/* Tabs */}
24+
<div className="filterBtns">
25+
<TabButton
26+
className={
27+
location.pathname === "/projects/sistent/components/avatar-group"
28+
? "active"
29+
: ""
30+
}
31+
onClick={() =>
32+
navigate("/projects/sistent/components/avatar-group")
33+
}
34+
title="Overview"
35+
/>
36+
<TabButton
37+
className={
38+
location.pathname ===
39+
"/projects/sistent/components/avatar-group/guidance"
40+
? "active"
41+
: ""
42+
}
43+
onClick={() =>
44+
navigate("/projects/sistent/components/avatar-group/guidance")
45+
}
46+
title="Guidance"
47+
/>
48+
<TabButton
49+
className={
50+
location.pathname ===
51+
"/projects/sistent/components/avatar-group/code"
52+
? "active"
53+
: ""
54+
}
55+
onClick={() =>
56+
navigate("/projects/sistent/components/avatar-group/code")
57+
}
58+
title="Code"
59+
/>
60+
</div>
61+
62+
<div className="main-content">
63+
<h3>Design Guidelines and Best Practices</h3>
64+
<p>
65+
When implementing <code>AvatarGroup</code>, it's important to
66+
consider how it enhances collaboration and identity clarity without
67+
overwhelming the interface. Here are key best practices:
68+
</p>
69+
70+
<ul>
71+
<li>
72+
<strong>Use to represent teams or shared ownership:</strong> Ideal
73+
for showing members of a project, contributors, or shared access
74+
groups in apps like dashboards or chat.
75+
</li>
76+
<li>
77+
<strong>Don’t overuse in dense interfaces:</strong> Too many
78+
avatars in a group can clutter the view. Use the <code>max</code>{" "}
79+
prop to collapse overflow into a <code>+N</code> indicator.
80+
</li>
81+
<li>
82+
<strong>Use consistent sizing and spacing:</strong> Align all
83+
avatars to the same size to maintain visual harmony. Use{" "}
84+
<code>spacing</code> options (or <code>sx</code>) for controlled
85+
overlap.
86+
</li>
87+
<li>
88+
<strong>
89+
Provide accessible <code>alt</code> text:
90+
</strong>{" "}
91+
Each avatar should have meaningful alternative text for screen
92+
readers. Avoid empty or redundant <code>alt</code> values.
93+
</li>
94+
<li>
95+
<strong>Avoid interactive behavior within AvatarGroup:</strong>{" "}
96+
The component is for display only. If avatars must be clickable,
97+
wrap each <code>&lt;Avatar&gt;</code> individually in buttons or
98+
links outside the group context.
99+
</li>
100+
<li>
101+
<strong>Keep it compact:</strong> AvatarGroup is not meant for
102+
long lists. For large user sets, link to a full view or show
103+
summary avatars only.
104+
</li>
105+
<li>
106+
<strong>Fallbacks matter:</strong> Always account for broken
107+
images by using initials or icons as fallback content within each{" "}
108+
<code>Avatar</code>.
109+
</li>
110+
</ul>
111+
112+
<p>
113+
These practices ensure that <code>AvatarGroup</code> remains a
114+
helpful, visually tidy, and accessible interface element wherever
115+
user identity grouping is necessary.
116+
</p>
117+
</div>
118+
</div>
119+
</SistentLayout>
120+
);
121+
};
122+
123+
export default AvatarGroupGuidance;

0 commit comments

Comments
 (0)