Files
blitzkit/packages/website-ue/src/components/AvatarCard/index.tsx
T

50 lines
1.3 KiB
TypeScript
Raw Normal View History

2026-01-12 14:13:21 -06:00
import type { Avatar } from "../../protos/avatar";
2026-01-14 12:34:28 -06:00
import type { SkeletonProps } from "../../types/SkeletonProps";
2026-01-12 14:13:21 -06:00
import { Text } from "../Text";
import "./index.css";
2026-01-14 13:58:53 -06:00
interface Props {
name: string;
avatars: Avatar[];
}
2026-01-13 13:30:09 -06:00
2026-01-14 13:58:53 -06:00
const MAX_CARDS = 3;
const CARD_TRIM = "var(--space-3)";
export function AvatarCard(props: SkeletonProps<Props>) {
2026-01-12 14:13:21 -06:00
return (
<div className="avatar-card">
2026-01-14 13:58:53 -06:00
{!props.skeleton && <Series avatars={props.avatars} />}
2026-01-13 13:30:09 -06:00
<Text align="center" className="avatar-label">
2026-01-14 13:58:53 -06:00
{props.skeleton ? "LOADING" : props.name}
2026-01-13 13:30:09 -06:00
</Text>
2026-01-12 14:13:21 -06:00
</div>
);
}
2026-01-14 13:58:53 -06:00
interface SeriesProps {
avatars: Avatar[];
}
function Series({ avatars }: SeriesProps) {
const count = Math.min(avatars.length, MAX_CARDS);
return (
<div className="avatar-series">
{avatars.slice(-MAX_CARDS).map((avatar, index) => (
<div
className="avatar-entry"
style={{
filter: `brightness(${(index + 1) / count})`,
top: `calc(${index} * ${CARD_TRIM})`,
left: `calc(${index} * ${CARD_TRIM})`,
width: `calc(100% - ${CARD_TRIM} * ${count - 1})`,
height: `calc(100% - ${CARD_TRIM} * ${count - 1})`,
backgroundImage: `url(/api/avatars/${avatar.name}.webp)`,
}}
/>
))}
</div>
);
}