Skip to content

Commit 8f48a83

Browse files
committed
Add new Avatar component
1 parent ad7e11a commit 8f48a83

File tree

4 files changed

+249
-1
lines changed

4 files changed

+249
-1
lines changed

site/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"@mui/system": "5.16.7",
5151
"@mui/utils": "5.16.6",
5252
"@mui/x-tree-view": "7.18.0",
53+
"@radix-ui/react-avatar": "1.1.2",
5354
"@radix-ui/react-dialog": "1.1.2",
5455
"@radix-ui/react-label": "2.1.0",
5556
"@radix-ui/react-slider": "1.2.1",

site/pnpm-lock.yaml

Lines changed: 81 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import { Avatar, AvatarFallback, AvatarImage } from "./Avatar";
3+
4+
const meta: Meta<typeof Avatar> = {
5+
title: "components/Avatar",
6+
component: Avatar,
7+
args: {
8+
children: <AvatarImage src="https://github.com/kylecarbs.png" />,
9+
},
10+
};
11+
12+
export default meta;
13+
type Story = StoryObj<typeof Avatar>;
14+
15+
export const ImageLgSize: Story = {
16+
args: { size: "lg" },
17+
};
18+
19+
export const ImageDefaultSize: Story = {};
20+
21+
export const ImageSmSize: Story = {
22+
args: { size: "sm" },
23+
};
24+
25+
export const IconLgSize: Story = {
26+
args: {
27+
size: "lg",
28+
variant: "icon",
29+
children: (
30+
<AvatarImage src="https://em-content.zobj.net/source/apple/391/billed-cap_1f9e2.png" />
31+
),
32+
},
33+
};
34+
35+
export const IconDefaultSize: Story = {
36+
args: {
37+
variant: "icon",
38+
children: (
39+
<AvatarImage src="https://em-content.zobj.net/source/apple/391/billed-cap_1f9e2.png" />
40+
),
41+
},
42+
};
43+
44+
export const IconSmSize: Story = {
45+
args: {
46+
variant: "icon",
47+
size: "sm",
48+
children: (
49+
<AvatarImage src="https://em-content.zobj.net/source/apple/391/billed-cap_1f9e2.png" />
50+
),
51+
},
52+
};
53+
54+
export const FallbackLgSize: Story = {
55+
args: {
56+
size: "lg",
57+
58+
children: <AvatarFallback>AR</AvatarFallback>,
59+
},
60+
};
61+
62+
export const FallbackDefaultSize: Story = {
63+
args: {
64+
children: <AvatarFallback>AR</AvatarFallback>,
65+
},
66+
};
67+
68+
export const FallbackSmSize: Story = {
69+
args: {
70+
size: "sm",
71+
children: <AvatarFallback>AR</AvatarFallback>,
72+
},
73+
};

site/src/components/Avatar/Avatar.tsx

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* Copied from shadc/ui on 12/16/2024
3+
* @see {@link https://ui.shadcn.com/docs/components/avatar}
4+
*
5+
* This component was updated to support the variants and match the styles from
6+
* the Figma design:
7+
* @see {@link https://www.figma.com/design/WfqIgsTFXN2BscBSSyXWF8/Coder-kit?node-id=711-383&t=xqxOSUk48GvDsjGK-0}
8+
*/
9+
import * as React from "react";
10+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
11+
import { cn } from "utils/cn";
12+
import { cva, type VariantProps } from "class-variance-authority";
13+
14+
const avatarVariants = cva(
15+
"relative flex shrink-0 overflow-hidden rounded border border-solid bg-surface-secondary text-content-secondary",
16+
{
17+
variants: {
18+
size: {
19+
lg: "h-10 w-10 rounded-[6px] text-sm font-medium",
20+
default: "h-6 w-6 text-2xs",
21+
sm: "h-[18px] w-[18px] text-[8px]",
22+
},
23+
variant: {
24+
default: "",
25+
icon: "",
26+
},
27+
},
28+
defaultVariants: {
29+
size: "default",
30+
},
31+
compoundVariants: [
32+
{
33+
size: "lg",
34+
variant: "icon",
35+
className: "p-[9px]",
36+
},
37+
{
38+
size: "default",
39+
variant: "icon",
40+
className: "p-[3px]",
41+
},
42+
{
43+
size: "sm",
44+
variant: "icon",
45+
className: "p-[2px]",
46+
},
47+
],
48+
},
49+
);
50+
51+
export interface AvatarProps
52+
extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>,
53+
VariantProps<typeof avatarVariants> {}
54+
55+
const Avatar = React.forwardRef<
56+
React.ElementRef<typeof AvatarPrimitive.Root>,
57+
AvatarProps
58+
>(({ className, size, variant, ...props }, ref) => (
59+
<AvatarPrimitive.Root
60+
ref={ref}
61+
className={cn(avatarVariants({ size, variant, className }))}
62+
{...props}
63+
/>
64+
));
65+
Avatar.displayName = AvatarPrimitive.Root.displayName;
66+
67+
const AvatarImage = React.forwardRef<
68+
React.ElementRef<typeof AvatarPrimitive.Image>,
69+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
70+
>(({ className, ...props }, ref) => (
71+
<AvatarPrimitive.Image
72+
ref={ref}
73+
className={cn("aspect-square h-full w-full", className)}
74+
{...props}
75+
/>
76+
));
77+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
78+
79+
const AvatarFallback = React.forwardRef<
80+
React.ElementRef<typeof AvatarPrimitive.Fallback>,
81+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
82+
>(({ className, ...props }, ref) => (
83+
<AvatarPrimitive.Fallback
84+
ref={ref}
85+
className={cn(
86+
"flex h-full w-full items-center justify-center rounded-full",
87+
className,
88+
)}
89+
{...props}
90+
/>
91+
));
92+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
93+
94+
export { Avatar, AvatarImage, AvatarFallback };

0 commit comments

Comments
 (0)