87 lines
1.8 KiB
TypeScript
87 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import React, { memo } from "react";
|
|
import Image from "next/image";
|
|
import clsx from "clsx";
|
|
import icons from "@/constant/images/icons";
|
|
|
|
// 👉 Types
|
|
export const ICON_ROUND_TYPES = [
|
|
"successPlay",
|
|
"success",
|
|
"error",
|
|
"errorEnd",
|
|
"errorGoods",
|
|
] as const;
|
|
|
|
export type IconRoundType = (typeof ICON_ROUND_TYPES)[number];
|
|
|
|
export interface PropsIconRound {
|
|
type?: IconRoundType;
|
|
icon?: React.ReactNode;
|
|
className?: string;
|
|
size?: number;
|
|
}
|
|
|
|
// 👉 Icon map
|
|
const iconMap = {
|
|
success: icons.tickCircle,
|
|
successPlay: icons.successPlay,
|
|
error: icons.errorWarning,
|
|
errorEnd: icons.errorEnd,
|
|
errorGoods: icons.errorGoods,
|
|
};
|
|
|
|
// 🎨 Background mapping
|
|
const outerBgMap: Record<IconRoundType, string> = {
|
|
success: "bg-green-100",
|
|
successPlay: "bg-green-100",
|
|
error: "bg-red-100",
|
|
errorEnd: "bg-red-100",
|
|
errorGoods: "bg-red-100",
|
|
};
|
|
|
|
const innerBgMap: Record<IconRoundType, string> = {
|
|
success: "bg-green-200",
|
|
successPlay: "bg-green-200",
|
|
error: "bg-red-200",
|
|
errorEnd: "bg-red-200",
|
|
errorGoods: "bg-red-200",
|
|
};
|
|
|
|
function IconRound({
|
|
type = "success",
|
|
icon,
|
|
className,
|
|
size = 24,
|
|
}: PropsIconRound) {
|
|
const renderDefaultIcon = () => {
|
|
const imgSrc = iconMap[type] ?? icons.tickCircle;
|
|
return (
|
|
<Image alt={`icon ${type}`} src={imgSrc} width={size} height={size} />
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={clsx(
|
|
"p-2 rounded-full flex items-center justify-center w-fit h-fit",
|
|
outerBgMap[type],
|
|
className,
|
|
)}
|
|
>
|
|
<div
|
|
className={clsx(
|
|
"flex items-center justify-center rounded-full p-2",
|
|
innerBgMap[type],
|
|
)}
|
|
style={{ width: 40, height: 40 }}
|
|
>
|
|
{icon ?? renderDefaultIcon()}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default memo(IconRound);
|