#![allow(clippy::needless_update)]
use hikari_icons::Icon;
use hikari_icons::mdi_minimal::MdiIcon;
use hikari_palette::classes::{AlertClass, ClassesBuilder, TypedClass};
use crate::basic::{IconButton, IconButtonSize, IconButtonVariant};
use crate::feedback::{Glow, GlowBlur, GlowColor, GlowIntensity};
use crate::prelude::*;
use crate::styled::StyledComponent;
pub struct AlertComponent;
#[derive(Clone, Copy, PartialEq, Debug, Default)]
pub enum AlertVariant {
#[default]
Info,
Success,
Warning,
Error,
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
pub enum AlertSize {
#[default]
Md,
Sm,
Lg,
}
#[define_props]
pub struct AlertProps {
pub variant: AlertVariant,
pub size: AlertSize,
pub title: Option<String>,
pub description: Option<String>,
pub closable: bool,
pub icon: Option<Element>,
pub class: String,
pub on_close: Option<EventHandler<MouseEvent>>,
}
#[component]
pub fn Alert(props: AlertProps) -> Element {
let variant_class = match props.variant {
AlertVariant::Info => AlertClass::AlertInfo,
AlertVariant::Success => AlertClass::AlertSuccess,
AlertVariant::Warning => AlertClass::AlertWarning,
AlertVariant::Error => AlertClass::AlertError,
};
let size_class = match props.size {
AlertSize::Sm => AlertClass::Sm,
AlertSize::Md => AlertClass::Md,
AlertSize::Lg => AlertClass::Lg,
};
let glow_color = match props.variant {
AlertVariant::Info => GlowColor::Info,
AlertVariant::Success => GlowColor::Success,
AlertVariant::Warning => GlowColor::Warning,
AlertVariant::Error => GlowColor::Danger,
};
let alert_classes = ClassesBuilder::new()
.add_typed(AlertClass::Alert)
.add_typed(variant_class)
.add_typed(size_class)
.add(&props.class)
.build();
let default_icon: Option<Element> = match props.variant {
AlertVariant::Info => Some(rsx! {
Icon {
icon: MdiIcon::Information,
class: AlertClass::AlertIcon.class_name().to_string(),
size: 20,
color: "var(--hi-color-primary)".to_string(),
}
}),
AlertVariant::Success => Some(rsx! {
Icon {
icon: MdiIcon::Check,
class: AlertClass::AlertIcon.class_name().to_string(),
size: 20,
color: "var(--hi-color-success)".to_string(),
}
}),
AlertVariant::Warning => Some(rsx! {
Icon {
icon: MdiIcon::AlertTriangle,
class: AlertClass::AlertIcon.class_name().to_string(),
size: 20,
color: "var(--hi-color-warning)".to_string(),
}
}),
AlertVariant::Error => Some(rsx! {
Icon {
icon: MdiIcon::Alert,
class: AlertClass::AlertIcon.class_name().to_string(),
size: 20,
color: "var(--hi-color-danger)".to_string(),
}
}),
};
let icon = props.icon.as_ref().or(default_icon.as_ref());
let icon_wrapper_class = AlertClass::AlertIconWrapper.class_name();
let content_class = AlertClass::AlertContent.class_name();
let title_class = AlertClass::AlertTitle.class_name();
let description_class = AlertClass::AlertDescription.class_name();
let on_close_handler = props.on_close.clone();
let aria_role = match props.variant {
AlertVariant::Error | AlertVariant::Warning => "alert",
AlertVariant::Info | AlertVariant::Success => "status",
};
let aria_live = match props.variant {
AlertVariant::Error | AlertVariant::Warning => "assertive",
AlertVariant::Info | AlertVariant::Success => "polite",
};
rsx! {
Glow {
class: "hi-alert-glow-wrapper".to_string(),
blur: GlowBlur::Light,
color: glow_color,
intensity: GlowIntensity::Soft,
block: true,
div { class: alert_classes, role: "{aria_role}", "aria-live": "{aria_live}",
if icon.is_some() {
div { class: icon_wrapper_class, {icon.unwrap().clone()} }
}
div { class: content_class,
if props.title.is_some() {
div { class: title_class, "{props.title.as_ref().unwrap()}" }
}
if props.description.is_some() {
div { class: description_class, "{props.description.as_ref().unwrap()}" }
}
}
if props.closable {
IconButton {
icon: MdiIcon::Close,
size: IconButtonSize::Small,
variant: IconButtonVariant::Ghost,
class: "hi-alert-close".to_string(),
glow: false,
onclick: Some(
EventHandler::new(move |e| {
if let Some(handler) = on_close_handler.as_ref() {
handler(e);
}
}),
),
}
}
}
}
}
}
impl StyledComponent for AlertComponent {
fn styles() -> &'static str {
include_str!(concat!(env!("OUT_DIR"), "/styles/alert.css"))
}
fn name() -> &'static str {
"alert"
}
}