stratum_components/overlay/
alert_dialog.rs1use crate::common::merge_classes;
4use stratum_core::aria::{AriaAttributes, AriaRole};
5use stratum_core::render::RenderOutput;
6
7#[derive(Debug, Clone, PartialEq, Default)]
9pub struct AlertDialogProps {
10 pub open: bool,
11 pub class: Option<String>,
12 pub aria_label: Option<String>,
13 pub aria_describedby: Option<String>,
14}
15
16pub struct AlertDialog;
17
18impl AlertDialog {
19 const BASE: &'static str = "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 sm:rounded-lg";
20
21 pub fn classes(props: &AlertDialogProps) -> String {
22 merge_classes(Self::BASE, &props.class)
23 }
24
25 pub fn render(props: &AlertDialogProps) -> RenderOutput {
26 let classes = Self::classes(props);
27 let mut aria = AriaAttributes::new()
28 .with_role(AriaRole::AlertDialog)
29 .with_modal(true);
30
31 if let Some(ref label) = props.aria_label {
32 aria = aria.with_label(label.clone());
33 }
34 if let Some(ref desc) = props.aria_describedby {
35 aria = aria.with_describedby(desc.clone());
36 }
37
38 RenderOutput::new()
39 .with_tag("div")
40 .with_class(classes)
41 .with_aria(aria)
42 .with_data("state", if props.open { "open" } else { "closed" })
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn alert_dialog_role() {
52 let props = AlertDialogProps::default();
53 let output = AlertDialog::render(&props);
54 assert_eq!(output.aria.role, Some(AriaRole::AlertDialog));
55 assert_eq!(output.aria.modal, Some(true));
56 }
57
58 #[test]
59 fn alert_dialog_open_state() {
60 let props = AlertDialogProps {
61 open: true,
62 ..Default::default()
63 };
64 let output = AlertDialog::render(&props);
65 assert!(
66 output
67 .data_attrs
68 .iter()
69 .any(|(k, v)| k == "state" && v == "open")
70 );
71 }
72}