1+ import BulbOutlined from "@ant-design/icons/BulbOutlined"
2+ import ExclamationCircleFilled from "@ant-design/icons/ExclamationCircleFilled"
3+ import InfoCircleOutlined from "@ant-design/icons/InfoCircleOutlined"
4+ import WarningOutlined from "@ant-design/icons/WarningOutlined"
15import React from "react"
26
37import cn from "../clsx"
4- import { Button , ButtonProps } from "./Button"
5- import {
6- BulbOutlined ,
7- ExclamationCircleFilled ,
8- InfoCircleOutlined ,
9- WarningOutlined ,
10- } from "@loft-enterprise/icons"
8+ import { Button , ButtonProps , ButtonStyles } from "./Button"
119
12- type Props = {
10+ type AlertVariant = "info" | "warning" | "error" | "blank" | "neutral" | "danger"
11+
12+ type AlertBoxProps = {
1313 title ?: string
14- text : string
15- buttonText ?: string
16- onButtonClick ?: ( ) => Promise < void >
17- linkText ?: string
18- linkUrl ?: string
19- variant ?: "info" | "warning" | "error" | "blank"
14+ variant ?: AlertVariant
2015 className ?: string
2116 children ?: React . ReactNode
17+ }
18+
19+ type Props = AlertBoxProps & {
20+ text ?: string
21+ buttonText ?: React . ReactNode
22+ buttonStyles ?: ButtonStyles
23+ onButtonClick ?: ( ) => void | Promise < void >
24+ linkText ?: React . ReactNode
25+ linkUrl ?: string
26+ linkHideUnderline ?: boolean
2227 icon ?: React . ReactNode
28+ hideIcon ?: boolean
29+ }
30+
31+ function AlertBox ( { title, variant, className, children } : AlertBoxProps ) {
32+ return (
33+ < div
34+ className = { cn ( "rounded-md border px-3 py-3" , className , {
35+ "border-primary-light bg-primary-extra-light" : variant === "info" ,
36+ "border-warning-light bg-warning-extra-light" : variant === "warning" ,
37+ "border-error-light bg-error-extra-light" : variant === "error" ,
38+ "border-neutral-light bg-neutral-extra-light" : variant === "neutral" ,
39+ "border-neutral-light" : variant === "blank" ,
40+ "border-danger-light bg-danger-extra-light" : variant === "danger" ,
41+ "flex flex-col gap-2" : title ,
42+ } ) } >
43+ { children }
44+ </ div >
45+ )
2346}
2447
2548function Alert ( {
@@ -32,47 +55,66 @@ function Alert({
3255 variant = "info" ,
3356 className,
3457 children,
58+ buttonStyles,
59+ linkHideUnderline,
3560 icon : Icon ,
61+ hideIcon = false ,
3662} : Props ) {
3763 const icon = {
3864 info : < InfoCircleOutlined /> ,
65+ neutral : < InfoCircleOutlined /> ,
3966 warning : < WarningOutlined /> ,
4067 error : < ExclamationCircleFilled /> ,
4168 blank : < BulbOutlined /> ,
69+ danger : < WarningOutlined /> ,
4270 }
4371
4472 const buttonChild = React . Children . toArray ( children ) . find (
4573 ( child ) => React . isValidElement ( child ) && ( child . type as any ) ?. name === "AlertButton"
4674 ) as React . ReactElement | undefined
4775
76+ const contentChildren = React . Children . toArray ( children ) . filter (
77+ ( child ) => ! React . isValidElement ( child ) || ( child . type as any ) ?. name !== "AlertButton"
78+ )
79+
4880 return (
49- < div
50- className = { cn ( "rounded-md border px-3 py-3" , className , {
51- "border-primary-light bg-primary-extra-light" : variant === "info" ,
52- "border-warning-light bg-warning-extra-light" : variant === "warning" ,
53- "border-error-light bg-error-extra-light" : variant === "error" ,
54- "border-neutral-light" : variant === "blank" ,
55- "flex flex-col gap-2" : title ,
56- } ) } >
81+ < AlertBox className = { className } title = { title } variant = { variant } >
5782 < span className = "flex flex-row items-center gap-2 [&_svg]:size-4" >
58- { Icon ? Icon : icon [ variant ] }
59- { title ? < span className = "font-bold" > { title } </ span > : < span > { text } </ span > }
83+ { ! hideIcon && ( Icon ? Icon : icon [ variant ] ) }
84+ { title ? (
85+ < span className = "text-sm font-semibold" > { title } </ span >
86+ ) : (
87+ < span className = "text-sm" > { text } </ span >
88+ ) }
6089 </ span >
61- { title && < span className = "text-primary-main text-sm" > { text } </ span > }
90+ { title &&
91+ ( contentChildren . length > 0 ? (
92+ < span className = "text-primary-main text-sm" > { contentChildren } </ span >
93+ ) : (
94+ text && < span className = "text-primary-main whitespace-pre-wrap text-sm" > { text } </ span >
95+ ) ) }
6296 < div className = "flex flex-row items-center gap-2" >
6397 { buttonText && ! buttonChild && (
64- < Button className = "self-start" size = "small" onClickAsync = { onButtonClick } >
98+ < Button
99+ { ...buttonStyles }
100+ className = "self-start"
101+ size = "small"
102+ onClickAsync = { onButtonClick } >
65103 { buttonText }
66104 </ Button >
67105 ) }
68106 { buttonChild }
69107 { linkText && linkUrl && (
70- < a href = { linkUrl } rel = "noreferrer" target = "_blank" className = "text-xs underline" >
108+ < a
109+ href = { linkUrl }
110+ rel = "noreferrer"
111+ target = "_blank"
112+ className = { cn ( "text-xs" , { underline : ! linkHideUnderline } ) } >
71113 < span className = "text-primary-main" > { linkText } </ span >
72114 </ a >
73115 ) }
74116 </ div >
75- </ div >
117+ </ AlertBox >
76118 )
77119}
78120
@@ -82,6 +124,8 @@ function AlertButton({ children, ...props }: ButtonProps) {
82124
83125AlertButton . displayName = "AlertButton"
84126
127+ Alert . Box = AlertBox
128+
85129Alert . Button = AlertButton
86130
87131export { Alert }
0 commit comments