mixins for avatar

This commit is contained in:
Red Adaya 2024-10-03 10:32:29 +08:00
parent 02f8c02a44
commit 74efd1a825
4 changed files with 71 additions and 6 deletions

View File

@ -1,3 +1,8 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
@import "@/app/mixins.less";
.avatar {
position: relative;
width: 50px;
@ -10,7 +15,6 @@
color: var(--main-text-color);
font-size: 18px;
text-transform: uppercase;
margin-right: 10px;
.avatar-image {
width: 100%;
@ -48,4 +52,6 @@
background-color: var(--warning-color);
}
}
.avatar-dims-mixin();
}

View File

@ -2,15 +2,17 @@
// SPDX-License-Identifier: Apache-2.0
import { memo } from "react";
import clsx from "clsx";
import "./avatar.less";
interface AvatarProps {
name: string;
status: "online" | "offline" | "busy" | "away";
className?: string;
imageUrl?: string;
}
const Avatar = memo(({ name, status = "offline", imageUrl }: AvatarProps) => {
const Avatar = memo(({ name, status = "offline", className, imageUrl }: AvatarProps) => {
const getInitials = (name: string) => {
const nameParts = name.split(" ");
const initials = nameParts.map((part) => part[0]).join("");
@ -18,7 +20,7 @@ const Avatar = memo(({ name, status = "offline", imageUrl }: AvatarProps) => {
};
return (
<div className={`avatar ${status}`}>
<div className={clsx("avatar", status, className)} title="status">
{imageUrl ? (
<img src={imageUrl} alt={`${name}'s avatar`} className="avatar-image" />
) : (

View File

@ -198,17 +198,17 @@ export const NestedWithClickHandlers: Story = {
const avatarItems = [
{
text: "John Doe",
icon: <Avatar name="John Doe" status="online" />,
icon: <Avatar name="John Doe" status="online" className="size-md" />,
onClick: () => console.log("John Doe clicked"),
},
{
text: "Jane Smith",
icon: <Avatar name="Jane Smith" status="busy" />,
icon: <Avatar name="Jane Smith" status="busy" className="size-md" />,
onClick: () => console.log("Jane Smith clicked"),
},
{
text: "Robert Brown",
icon: <Avatar name="Robert Brown" status="away" />,
icon: <Avatar name="Robert Brown" status="away" className="size-md" />,
onClick: () => console.log("Robert Brown clicked"),
},
];

View File

@ -209,3 +209,60 @@
font-weight: 700;
}
}
.avatar-dims-mixin() {
&.size-xs {
width: 20px;
height: 20px;
font-size: 7px; // 18px * (20 / 50)
.status-indicator {
width: 5px; // scaled indicator size
height: 5px;
}
}
&.size-sm {
width: 30px;
height: 30px;
font-size: 11px; // 18px * (30 / 50)
.status-indicator {
width: 7px;
height: 7px;
}
}
&.size-md {
width: 40px;
height: 40px;
font-size: 14px; // 18px * (40 / 50)
.status-indicator {
width: 9px;
height: 9px;
}
}
&.size-lg {
width: 45px;
height: 45px;
font-size: 16px; // 18px * (45 / 50)
.status-indicator {
width: 10px;
height: 10px;
}
}
&.size-xl {
width: 50px;
height: 50px;
font-size: 18px; // base size
.status-indicator {
width: 12px;
height: 12px;
}
}
}