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/// # use dioxus::prelude::*;
15/// # use dioxus_bootstrap_css::prelude::*;
16/// # fn _doctest() -> Element {
17/// // Dioxus equivalent
18/// let mut expanded = use_signal(|| false);
19/// rsx! {
20/// Button { onclick: move |_| expanded.toggle(), "Toggle Content" }
21/// Collapse { expanded: expanded,
22/// Card { body: rsx! { "Collapsible content here." } }
23/// }
24/// }
25/// # }
26/// ```
27///
28/// # Props
29///
30/// - `expanded` — `Signal<bool>` controlling expanded/collapsed state
31/// - `horizontal` — horizontal collapse instead of vertical
32#[derive(Clone, PartialEq, Props)]
33pub struct CollapseProps {
34 /// Signal controlling expanded/collapsed state.
35 pub expanded: Signal<bool>,
36 /// Use horizontal collapse instead of vertical.
37 #[props(default)]
38 pub horizontal: bool,
39 /// Additional CSS classes.
40 #[props(default)]
41 pub class: String,
42 /// Child elements.
43 pub children: Element,
44}
45
46#[component]
47pub fn Collapse(props: CollapseProps) -> Element {
48 let is_expanded = *props.expanded.read();
49
50 let horizontal = if props.horizontal {
51 " collapse-horizontal"
52 } else {
53 ""
54 };
55
56 let show = if is_expanded { " show" } else { "" };
57
58 let full_class = if props.class.is_empty() {
59 format!("collapse{horizontal}{show}")
60 } else {
61 format!("collapse{horizontal}{show} {}", props.class)
62 };
63
64 rsx! {
65 div { class: "{full_class}",
66 {props.children}
67 }
68 }
69}