Skip to content

Commit 656180c

Browse files
feat: Avatar Component (#46)
1 parent 06d1952 commit 656180c

File tree

8 files changed

+237
-1
lines changed

8 files changed

+237
-1
lines changed

.changeset/new-steaks-deny.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@zenml-io/react-component-library": minor
3+
---
4+
5+
add avatar component

.eslintrc.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,7 @@
2323
"version": "detect"
2424
}
2525
},
26-
"rules": {}
26+
"rules": {
27+
"react/prop-types": "off"
28+
}
2729
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
]
8585
},
8686
"dependencies": {
87+
"@radix-ui/react-avatar": "^1.0.4",
8788
"@radix-ui/react-slot": "^1.0.2",
8889
"class-variance-authority": "^0.7.0",
8990
"clsx": "^2.1.0",

pnpm-lock.yaml

Lines changed: 88 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Meta } from "@storybook/react";
2+
import { StoryObj } from "@storybook/react";
3+
import { Avatar, AvatarFallback, AvatarImage } from "./index";
4+
import React from "react";
5+
6+
const meta = {
7+
title: "UI/Avatar",
8+
component: Avatar,
9+
parameters: {
10+
layout: "centered"
11+
},
12+
decorators: [
13+
(Story) => (
14+
<div className="flex items-center gap-7">
15+
<Story />
16+
</div>
17+
)
18+
],
19+
argTypes: {
20+
size: {
21+
description: "defining the size of the avatar",
22+
control: "select",
23+
defaultValue: "md",
24+
options: ["xs", "sm", "md", "lg", "xl", "xxl"]
25+
},
26+
type: {
27+
description: "defining the type of the avatar",
28+
control: "select",
29+
defaultValue: "rounded",
30+
options: ["rounded", "square"]
31+
}
32+
},
33+
34+
tags: ["autodocs"]
35+
} satisfies Meta<typeof Avatar>;
36+
37+
export default meta;
38+
39+
type Story = StoryObj<typeof meta>;
40+
41+
export const DefaultVariant: Story = {
42+
name: "Default",
43+
args: {
44+
size: "md",
45+
type: "rounded"
46+
},
47+
render: (args) => (
48+
<>
49+
<Avatar size={args.size} type={args.type}>
50+
<AvatarImage src="https://avatar.vercel.sh/randomValue?size=24" />
51+
<AvatarFallback size={args.size}>RV</AvatarFallback>
52+
</Avatar>
53+
<Avatar size={args.size} type={args.type}>
54+
<AvatarFallback size={args.size}>RV</AvatarFallback>
55+
</Avatar>
56+
</>
57+
)
58+
};

src/components/Avatar/Avatar.tsx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
"use client";
2+
3+
import * as React from "react";
4+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
5+
6+
import { cva, VariantProps } from "class-variance-authority";
7+
import { cn } from "../../utilities";
8+
9+
export const avatarVariants = cva("relative flex shrink-0 overflow-hidden", {
10+
variants: {
11+
type: { square: "rounded-md", rounded: "rounded-rounded" },
12+
size: {
13+
xs: "w-3 h-3",
14+
sm: "w-5 h-5",
15+
md: "w-6 h-6",
16+
lg: "w-7 h-7",
17+
xl: "w-9 h-9",
18+
xxl: "w-12 h-12"
19+
}
20+
},
21+
defaultVariants: {
22+
type: "rounded",
23+
size: "lg"
24+
}
25+
});
26+
27+
const fallbackVariants = cva(
28+
"flex aspect-square items-center justify-center bg-primary-50 text-theme-text-brand font-semibold uppercase",
29+
{
30+
variants: {
31+
size: {
32+
xs: "text-text-xs",
33+
sm: "text-text-xs",
34+
md: "text-text-md",
35+
lg: "text-text-lg",
36+
xl: "text-display-sm",
37+
xxl: "text-display-md"
38+
}
39+
}
40+
}
41+
);
42+
43+
const Avatar = React.forwardRef<
44+
React.ElementRef<typeof AvatarPrimitive.Root>,
45+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> & VariantProps<typeof avatarVariants>
46+
>(({ className, size, type, ...props }, ref) => (
47+
<AvatarPrimitive.Root
48+
ref={ref}
49+
className={cn(avatarVariants({ size, type }), className)}
50+
{...props}
51+
/>
52+
));
53+
Avatar.displayName = AvatarPrimitive.Root.displayName;
54+
55+
const AvatarImage = React.forwardRef<
56+
React.ElementRef<typeof AvatarPrimitive.Image>,
57+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
58+
>(({ className, ...props }, ref) => (
59+
<AvatarPrimitive.Image
60+
ref={ref}
61+
className={cn("aspect-square h-full w-full", className)}
62+
{...props}
63+
/>
64+
));
65+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
66+
67+
const AvatarFallback = React.forwardRef<
68+
React.ElementRef<typeof AvatarPrimitive.Fallback>,
69+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback> &
70+
VariantProps<typeof fallbackVariants>
71+
>(({ className, size, ...props }, ref) => (
72+
<AvatarPrimitive.Fallback
73+
ref={ref}
74+
className={cn(fallbackVariants({ size }), className)}
75+
{...props}
76+
/>
77+
));
78+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
79+
80+
export { Avatar, AvatarImage, AvatarFallback };

src/components/Avatar/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./Avatar";

src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from "./Button";
22
export * from "./Input";
33
export * from "./Sidebar";
44
export * from "./Box";
5+
export * from "./Avatar";

0 commit comments

Comments
 (0)