Skip to main content

stratum_components/utility/
separator.rs

1//! Styled Separator utility component.
2
3use crate::common::merge_classes;
4use stratum_core::aria::{AriaAttributes, AriaRole, Orientation};
5use stratum_core::render::RenderOutput;
6
7/// Properties for the Separator.
8#[derive(Debug, Clone, PartialEq)]
9pub struct SeparatorProps {
10    pub orientation: Orientation,
11    pub decorative: bool,
12    pub class: Option<String>,
13}
14
15impl Default for SeparatorProps {
16    fn default() -> Self {
17        Self {
18            orientation: Orientation::Horizontal,
19            decorative: true,
20            class: None,
21        }
22    }
23}
24
25pub struct Separator;
26
27impl Separator {
28    pub fn classes(props: &SeparatorProps) -> String {
29        let base = match props.orientation {
30            Orientation::Horizontal => "shrink-0 bg-border h-[1px] w-full",
31            Orientation::Vertical => "shrink-0 bg-border h-full w-[1px]",
32        };
33        merge_classes(base, &props.class)
34    }
35
36    pub fn render(props: &SeparatorProps) -> RenderOutput {
37        let classes = Self::classes(props);
38        let mut aria = AriaAttributes::new()
39            .with_role(if props.decorative {
40                AriaRole::None
41            } else {
42                AriaRole::Separator
43            })
44            .with_orientation(props.orientation);
45
46        if props.decorative {
47            aria.hidden = Some(true);
48        }
49
50        RenderOutput::new()
51            .with_tag("div")
52            .with_class(classes)
53            .with_aria(aria)
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn separator_horizontal() {
63        let props = SeparatorProps::default();
64        let classes = Separator::classes(&props);
65        assert!(classes.contains("w-full"));
66    }
67
68    #[test]
69    fn separator_decorative_is_hidden() {
70        let props = SeparatorProps::default();
71        let output = Separator::render(&props);
72        assert_eq!(output.aria.hidden, Some(true));
73        assert_eq!(output.aria.role, Some(AriaRole::None));
74    }
75
76    #[test]
77    fn separator_non_decorative() {
78        let props = SeparatorProps {
79            decorative: false,
80            ..Default::default()
81        };
82        let output = Separator::render(&props);
83        assert_eq!(output.aria.role, Some(AriaRole::Separator));
84        assert!(output.aria.hidden.is_none());
85    }
86}