1 |
rakinar2 |
575 |
import { ReactNode } from "react"; |
2 |
|
|
import { IconType } from "react-icons"; |
3 |
|
|
import { |
4 |
|
|
MdCheckCircle, |
5 |
|
|
MdError, |
6 |
|
|
MdInfo, |
7 |
|
|
MdNoteAlt, |
8 |
|
|
MdWarning, |
9 |
|
|
} from "react-icons/md"; |
10 |
|
|
|
11 |
|
|
type CalloutProps = { |
12 |
|
|
children?: ReactNode; |
13 |
|
|
type: "info" | "warning" | "danger" | "success" | "note"; |
14 |
|
|
hideHeading?: boolean; |
15 |
|
|
hideIcon?: boolean; |
16 |
|
|
title?: string; |
17 |
|
|
}; |
18 |
|
|
|
19 |
|
|
const styles: Record<CalloutProps["type"], string> = { |
20 |
|
|
danger: "bg-red-500 before:bg-red-600 [--tw-bg-opacity:0.2]", |
21 |
|
|
info: "bg-[rgba(0,123,255,0.2)] before:bg-blue-600", |
22 |
|
|
note: "bg-[rgba(255,255,255,0.2)] before:bg-white", |
23 |
|
|
success: "bg-green-500 before:bg-green-600 [--tw-bg-opacity:0.2]", |
24 |
|
|
warning: "bg-yellow-500 before:bg-yellow-600 [--tw-bg-opacity:0.2]", |
25 |
|
|
}; |
26 |
|
|
|
27 |
|
|
const headingStyles: Record<CalloutProps["type"], string> = { |
28 |
|
|
danger: "text-red-500", |
29 |
|
|
info: "text-white", |
30 |
|
|
note: "text-white", |
31 |
|
|
success: "text-green-500", |
32 |
|
|
warning: "text-yellow-600", |
33 |
|
|
}; |
34 |
|
|
|
35 |
|
|
const icons: Record<CalloutProps["type"], IconType> = { |
36 |
|
|
note: MdNoteAlt, |
37 |
|
|
danger: MdError, |
38 |
|
|
info: MdInfo, |
39 |
|
|
success: MdCheckCircle, |
40 |
|
|
warning: MdWarning, |
41 |
|
|
}; |
42 |
|
|
|
43 |
|
|
export default function Callout({ |
44 |
|
|
type, |
45 |
|
|
children, |
46 |
|
|
hideHeading = false, |
47 |
|
|
hideIcon = false, |
48 |
|
|
title, |
49 |
|
|
}: CalloutProps) { |
50 |
|
|
const Icon = icons[type]; |
51 |
|
|
return ( |
52 |
|
|
<div |
53 |
|
|
className={`${ |
54 |
|
|
hideHeading ? "flex items-center gap-5" : "" |
55 |
|
|
} my-3 p-3 pl-5 overflow-hidden relative rounded-md before:absolute before:left-0 before:h-[100%] before:top-0 before:w-[3px] ${ |
56 |
|
|
styles[type] |
57 |
|
|
}`} |
58 |
|
|
> |
59 |
|
|
{!hideIcon && !hideHeading && ( |
60 |
|
|
<div |
61 |
|
|
className={`flex items-center gap-3 mb-3 ${headingStyles[type]}`} |
62 |
|
|
> |
63 |
|
|
<Icon size={25} /> |
64 |
|
|
<span className="font-bold"> |
65 |
|
|
{title ?? |
66 |
|
|
`${type[0].toUpperCase()}${type.substring(1)}`} |
67 |
|
|
</span> |
68 |
|
|
</div> |
69 |
|
|
)} |
70 |
|
|
{!hideIcon && hideHeading && ( |
71 |
|
|
<div> |
72 |
|
|
<Icon size={25} /> |
73 |
|
|
</div> |
74 |
|
|
)} |
75 |
|
|
<div className="*:m-0 *:p-0">{children}</div> |
76 |
|
|
</div> |
77 |
|
|
); |
78 |
|
|
} |