dioxus_bootstrap_css/collapse.rs
1use dioxus::prelude::*;
2
3/// Bootstrap Collapse component — signal-driven, no JavaScript.
4///
5/// # Bootstrap HTML → Dioxus
6///
7/// ```html
8/// <!-- Bootstrap HTML (requires JavaScript) -->
9/// <button data-bs-toggle="collapse" data-bs-target="#content">Toggle</button>
10/// <div class="collapse" id="content">Hidden content</div>
11/// ```
12///
13/// ```rust,no_run
14/// // Dioxus equivalent
15/// let expanded = use_signal(|| false);
16/// rsx! {
17/// Button { onclick: move |_| expanded.toggle(), "Toggle Content" }
18/// Collapse { expanded: expanded,
19/// Card { body: rsx! { "Collapsible content here." } }
20/// }
21/// }
22/// ```
23///
24/// # Props
25///
26/// - `expanded` — `Signal<bool>` controlling expanded/collapsed state
27/// - `horizontal` — horizontal collapse instead of vertical
28#[derive(Clone, PartialEq, Props)]
29pub struct CollapseProps {
30 /// Signal controlling expanded/collapsed state.
31 pub expanded: Signal<bool>,
32 /// Use horizontal collapse instead of vertical.
33 #[props(default)]
34 pub horizontal: bool,
35 /// Additional CSS classes.
36 #[props(default)]
37 pub class: String,
38 /// Child elements.
39 pub children: Element,
40}
41
42#[component]
43pub fn Collapse(props: CollapseProps) -> Element {
44 let is_expanded = *props.expanded.read();
45
46 let horizontal = if props.horizontal {
47 " collapse-horizontal"
48 } else {
49 ""
50 };
51
52 let show = if is_expanded { " show" } else { "" };
53
54 let full_class = if props.class.is_empty() {
55 format!("collapse{horizontal}{show}")
56 } else {
57 format!("collapse{horizontal}{show} {}", props.class)
58 };
59
60 rsx! {
61 div { class: "{full_class}",
62 {props.children}
63 }
64 }
65}