adui_dioxus/components/
divider.rs

1use crate::theme::use_theme;
2use dioxus::prelude::*;
3
4#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
5pub enum DividerOrientation {
6    Left,
7    #[default]
8    Center,
9    Right,
10}
11
12/// Props for rendering a horizontal or vertical divider.
13#[derive(Props, Clone, PartialEq)]
14pub struct DividerProps {
15    #[props(default)]
16    pub dashed: bool,
17    #[props(default)]
18    pub plain: bool,
19    #[props(default)]
20    pub vertical: bool,
21    #[props(default)]
22    pub orientation: DividerOrientation,
23    #[props(optional)]
24    pub orientation_margin: Option<String>,
25    #[props(optional)]
26    pub class: Option<String>,
27    #[props(optional)]
28    pub style: Option<String>,
29    /// 可选内容。
30    #[props(optional)]
31    pub content: Option<Element>,
32}
33
34/// Divider with optional title content and orientation.
35#[component]
36pub fn Divider(props: DividerProps) -> Element {
37    let DividerProps {
38        dashed,
39        plain,
40        vertical,
41        orientation,
42        orientation_margin,
43        class,
44        style,
45        content,
46    } = props;
47    let theme = use_theme();
48    let tokens = theme.tokens();
49
50    let has_content = content.is_some();
51
52    let mut class_list = vec!["adui-divider".to_string()];
53    if vertical {
54        class_list.push("adui-divider-vertical".into());
55    } else {
56        class_list.push("adui-divider-horizontal".into());
57        if has_content {
58            class_list.push(match orientation {
59                DividerOrientation::Left => "adui-divider-left".into(),
60                DividerOrientation::Center => "adui-divider-center".into(),
61                DividerOrientation::Right => "adui-divider-right".into(),
62            });
63        }
64    }
65    if dashed {
66        class_list.push("adui-divider-dashed".into());
67    }
68    if plain {
69        class_list.push("adui-divider-plain".into());
70    }
71    if let Some(extra) = class.as_ref() {
72        class_list.push(extra.clone());
73    }
74    let class_attr = class_list.join(" ");
75
76    let style_attr = format!(
77        "border-color:{};{}",
78        tokens.color_border,
79        style.unwrap_or_default()
80    );
81
82    if vertical {
83        return rsx! {
84            div {
85                class: "{class_attr}",
86                style: "{style_attr}",
87                role: "separator",
88                "aria-orientation": "vertical",
89            }
90        };
91    }
92
93    let margin = orientation_margin.unwrap_or_else(|| "16px".into());
94
95    rsx! {
96        div {
97            class: "{class_attr}",
98            style: "{style_attr}",
99            role: "separator",
100            "aria-orientation": "horizontal",
101            if let Some(node) = content {
102                span {
103                    class: "adui-divider-inner-text",
104                    style: format!("margin: 0 {margin};"),
105                    {node}
106                }
107            }
108        }
109    }
110}