Skip to main content

dioxus_bulma/components/
card.rs

1use dioxus::prelude::*;
2use crate::utils::build_class;
3
4#[derive(Props, Clone, PartialEq)]
5pub struct CardProps {
6    #[props(default)]
7    pub id: Option<String>,
8    #[props(default)]
9    pub class: Option<String>,
10    #[props(default)]
11    pub style: Option<String>,
12    pub children: Element,
13}
14
15#[component]
16pub fn Card(props: CardProps) -> Element {
17    let base_classes = vec!["card"];
18    let optional_classes = vec![props.class.clone()];
19    let final_class = build_class(&base_classes, &optional_classes);
20    let card_style = props.style.as_deref().unwrap_or("");
21
22    rsx! {
23        div {
24            class: "{final_class}",
25            style: "{card_style}",
26            id: props.id.clone(),
27            {props.children}
28        }
29    }
30}
31
32#[derive(Props, Clone, PartialEq)]
33pub struct CardHeaderProps {
34    #[props(default)]
35    pub id: Option<String>,
36    #[props(default)]
37    pub class: Option<String>,
38    #[props(default)]
39    pub style: Option<String>,
40    pub children: Element,
41}
42
43#[component]
44pub fn CardHeader(props: CardHeaderProps) -> Element {
45    let base_classes = vec!["card-header"];
46    let optional_classes = vec![props.class.clone()];
47    let final_class = build_class(&base_classes, &optional_classes);
48    let style = props.style.as_deref().unwrap_or("");
49
50    rsx! {
51        header {
52            class: "{final_class}",
53            style: "{style}",
54            {props.children}
55        }
56    }
57}
58
59#[derive(Props, Clone, PartialEq)]
60pub struct CardHeaderTitleProps {
61    #[props(default)]
62    pub id: Option<String>,
63    #[props(default)]
64    pub class: Option<String>,
65    #[props(default)]
66    pub style: Option<String>,
67    pub children: Element,
68}
69
70#[component]
71pub fn CardHeaderTitle(props: CardHeaderTitleProps) -> Element {
72    let base_classes = vec!["card-header-title"];
73    let optional_classes = vec![props.class.clone()];
74    let final_class = build_class(&base_classes, &optional_classes);
75    let style = props.style.as_deref().unwrap_or("");
76
77    rsx! {
78        p {
79            class: "{final_class}",
80            style: "{style}",
81            {props.children}
82        }
83    }
84}
85
86#[derive(Props, Clone, PartialEq)]
87pub struct CardContentProps {
88    #[props(default)]
89    pub id: Option<String>,
90    #[props(default)]
91    pub class: Option<String>,
92    #[props(default)]
93    pub style: Option<String>,
94    pub children: Element,
95}
96
97#[component]
98pub fn CardContent(props: CardContentProps) -> Element {
99    let base_classes = vec!["card-content"];
100    let optional_classes = vec![props.class.clone()];
101    let final_class = build_class(&base_classes, &optional_classes);
102    let style = props.style.as_deref().unwrap_or("");
103
104    rsx! {
105        div {
106            class: "{final_class}",
107            style: "{style}",
108            {props.children}
109        }
110    }
111}
112
113#[derive(Props, Clone, PartialEq)]
114pub struct CardFooterProps {
115    #[props(default)]
116    pub id: Option<String>,
117    #[props(default)]
118    pub class: Option<String>,
119    #[props(default)]
120    pub style: Option<String>,
121    pub children: Element,
122}
123
124#[component]
125pub fn CardFooter(props: CardFooterProps) -> Element {
126    let base_classes = vec!["card-footer"];
127    let optional_classes = vec![props.class.clone()];
128    let final_class = build_class(&base_classes, &optional_classes);
129    let style = props.style.as_deref().unwrap_or("");
130
131    rsx! {
132        footer {
133            class: "{final_class}",
134            style: "{style}",
135            {props.children}
136        }
137    }
138}
139
140#[derive(Props, Clone, PartialEq)]
141pub struct CardFooterItemProps {
142    #[props(default)]
143    pub href: Option<String>,
144    #[props(default)]
145    pub onclick: Option<EventHandler<MouseEvent>>,
146    #[props(default)]
147    pub id: Option<String>,
148    #[props(default)]
149    pub class: Option<String>,
150    #[props(default)]
151    pub style: Option<String>,
152    pub children: Element,
153}
154
155#[component]
156pub fn CardFooterItem(props: CardFooterItemProps) -> Element {
157    let base_classes = vec!["card-footer-item"];
158    let optional_classes = vec![props.class.clone()];
159    let final_class = build_class(&base_classes, &optional_classes);
160    let style = props.style.as_deref().unwrap_or("");
161
162    rsx! {
163        if let Some(href) = props.href {
164            a {
165                class: "{final_class}",
166                style: "{style}",
167                href: "{href}",
168                onclick: move |evt| {
169                    if let Some(handler) = &props.onclick {
170                        handler.call(evt);
171                    }
172                },
173                {props.children}
174            }
175        } else {
176            p {
177                class: "{final_class}",
178                style: "{style}",
179                onclick: move |evt| {
180                    if let Some(handler) = &props.onclick {
181                        handler.call(evt);
182                    }
183                },
184                {props.children}
185            }
186        }
187    }
188}