diff --git a/core/components/atoms/avatar/Avatar.tsx b/core/components/atoms/avatar/Avatar.tsx
index 489cb2d98..a3b8dfd78 100644
--- a/core/components/atoms/avatar/Avatar.tsx
+++ b/core/components/atoms/avatar/Avatar.tsx
@@ -63,6 +63,10 @@ export interface AvatarProps extends BaseProps {
* Show presence indicator for the `Avatar`
*/
presence?: TPresence;
+ /**
+ * Show status indicator for the `Avatar`
+ */
+ status?: React.ReactNode;
/**
* Stroke color of `Presence indicator` & `Status indicator` in `Avatar`
*/
@@ -88,6 +92,7 @@ export const Avatar = (props: AvatarProps) => {
tooltipSuffix,
tabIndex,
presence,
+ status,
strokeColor,
role = 'presentation',
} = props;
@@ -112,6 +117,7 @@ export const Avatar = (props: AvatarProps) => {
const darkAppearance = ['secondary', 'success', 'warning', 'accent1', 'accent4'];
const showPresence = presence && !disabled && shape === 'round';
+ const showStatus = status && size === 'regular' && shape === 'round';
const AvatarClassNames = classNames(
{
@@ -215,6 +221,11 @@ export const Avatar = (props: AvatarProps) => {
{showPresence && (
)}
+ {showStatus && (
+
+ {status}
+
+ )}
);
diff --git a/core/components/atoms/avatar/__stories__/assets/status-image.png b/core/components/atoms/avatar/__stories__/assets/status-image.png
new file mode 100644
index 000000000..a303c6ebe
Binary files /dev/null and b/core/components/atoms/avatar/__stories__/assets/status-image.png differ
diff --git a/core/components/atoms/avatar/__stories__/statusWithIcon.story.jsx b/core/components/atoms/avatar/__stories__/statusWithIcon.story.jsx
new file mode 100644
index 000000000..178872189
--- /dev/null
+++ b/core/components/atoms/avatar/__stories__/statusWithIcon.story.jsx
@@ -0,0 +1,30 @@
+import * as React from 'react';
+import { Avatar, Icon, Tooltip } from '@/index';
+
+// CSF format story
+export const statusWithIcon = () => {
+ return (
+
+
+
+ }
+ />
+ );
+};
+
+export default {
+ title: 'Components/Avatar/Avatar/Status/Status With Icon',
+ component: Avatar,
+ parameters: {
+ docs: {
+ docPage: {
+ title: 'Avatar',
+ },
+ },
+ },
+};
diff --git a/core/components/atoms/avatar/__stories__/statusWithImage.story.jsx b/core/components/atoms/avatar/__stories__/statusWithImage.story.jsx
new file mode 100644
index 000000000..abded76a1
--- /dev/null
+++ b/core/components/atoms/avatar/__stories__/statusWithImage.story.jsx
@@ -0,0 +1,31 @@
+import * as React from 'react';
+import { Avatar, Tooltip } from '@/index';
+import StatusImage from './assets/status-image.png';
+
+// CSF format story
+export const statusWithImage = () => {
+ return (
+
+
+
+ }
+ />
+ );
+};
+
+export default {
+ title: 'Components/Avatar/Avatar/Status/Status With Image',
+ component: Avatar,
+ parameters: {
+ docs: {
+ docPage: {
+ title: 'Avatar',
+ },
+ },
+ },
+};
diff --git a/core/components/atoms/avatar/__tests__/Avatar.test.tsx b/core/components/atoms/avatar/__tests__/Avatar.test.tsx
index 51d743e69..3c160c82f 100644
--- a/core/components/atoms/avatar/__tests__/Avatar.test.tsx
+++ b/core/components/atoms/avatar/__tests__/Avatar.test.tsx
@@ -20,6 +20,8 @@ const sizes: AvatarSize[] = ['regular', 'tiny'];
const shapes: AvatarShape[] = ['round', 'square'];
const booleanValues = [true, false];
+const statusComponent = status
;
+
describe('Avatar component', () => {
const mapper = {
appearance: valueHelper(appearances, { required: true, iterate: true }),
@@ -270,3 +272,47 @@ describe('Avatar component with prop:presence', () => {
expect(presenceEle).toHaveStyle('box-shadow: 0 0 0 var(--spacing-s) red');
});
});
+
+describe('Avatar component with prop:status', () => {
+ it('should have the Avatar-status class when size is regular', () => {
+ const { getByTestId } = render(Design);
+ const statusElement = getByTestId('DesignSystem-Avatar--Status');
+ expect(statusElement).toBeInTheDocument();
+ expect(statusElement).toHaveClass('Avatar-status');
+ });
+
+ it('should not have the Avatar-status class when size is tiny', () => {
+ render(
+
+ Design
+
+ );
+ const statusElement = screen.queryByText('DesignSystem-Avatar--Status');
+ expect(statusElement).not.toBeInTheDocument();
+ });
+
+ it('should have the Avatar-status class when shape is round', () => {
+ const { getByTestId } = render(Design);
+ const statusElement = getByTestId('DesignSystem-Avatar--Status');
+ expect(statusElement).toBeInTheDocument();
+ expect(statusElement).toHaveClass('Avatar-status');
+ });
+
+ it('should not have the Avatar-status class when shape is square', () => {
+ render(
+
+ Design
+
+ );
+ const statusElement = screen.queryByText('DesignSystem-Avatar--Status');
+ expect(statusElement).not.toBeInTheDocument();
+ });
+
+ it('status should have custom stroke color', () => {
+ const { getByTestId } = render(
+
+ );
+ const statusElement = getByTestId('DesignSystem-Avatar--Status');
+ expect(statusElement).toHaveStyle('box-shadow: 0 0 0 var(--spacing-s) red');
+ });
+});
diff --git a/css/src/components/avatar.css b/css/src/components/avatar.css
index 967464e25..017457548 100644
--- a/css/src/components/avatar.css
+++ b/css/src/components/avatar.css
@@ -123,3 +123,17 @@
.Avatar-presence--away {
background: var(--secondary-dark);
}
+
+.Avatar-status {
+ top: calc(-1 * var(--spacing-s));
+ right: calc(-1 * var(--spacing-s));
+ width: var(--spacing-l);
+ height: var(--spacing-l);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ cursor: pointer;
+ overflow: hidden;
+}
diff --git a/figma/Avatar.figma.tsx b/figma/Avatar.figma.tsx
index f7a10b192..44ccf896d 100644
--- a/figma/Avatar.figma.tsx
+++ b/figma/Avatar.figma.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { Avatar } from '@/index';
+import { Avatar, Icon, Tooltip } from '@/index';
import figma from '@figma/code-connect';
figma.connect(Avatar, 'https://www.figma.com/design/w8sqBtJpvq86D06UE7gN0T/MDS---Web?node-id=37-592', {
@@ -39,6 +39,13 @@ figma.connect(Avatar, 'https://www.figma.com/design/w8sqBtJpvq86D06UE7gN0T/MDS--
icon: figma.enum('Type', {
Icon: ,
}),
+ status: figma.enum('Status', {
+ true: (
+
+
+
+ ),
+ }),
},
example: ({ icon, image, ...rest }) => (