1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use crate::prelude::*;
/// A sidebar container with optional header, scrollable content area, and optional footer.
///
/// The sidebar is composed as:
/// - `sidebar-header`
/// - `sidebar-content`
/// - `sidebar-footer`
pub struct Sidebar {
_width: Signal<Units>,
}
impl Sidebar {
/// Creates a new [Sidebar] with custom header, content and footer builders.
pub fn new<H, C, F>(cx: &mut Context, header: H, content: C, footer: F) -> Handle<Self>
where
H: 'static + Fn(&mut Context),
C: 'static + Fn(&mut Context),
F: 'static + Fn(&mut Context),
{
let _width: Signal<Units> = Signal::new(Pixels(200.0));
Self { _width }.build(cx, move |cx| {
Resizable::new(
cx,
_width,
ResizeStackDirection::Right,
move |_cx, new_size| _width.set(Pixels(new_size)),
move |cx| {
VStack::new(cx, |cx| {
(header)(cx);
})
.class("sidebar-header")
.height(Auto);
Divider::new(cx).class("sidebar-divider");
ScrollView::new(cx, move |cx| {
(content)(cx);
})
.class("sidebar-content")
.height(Stretch(1.0));
Divider::new(cx).class("sidebar-divider");
VStack::new(cx, |cx| {
(footer)(cx);
})
.class("sidebar-footer")
.height(Auto);
},
);
})
}
}
impl View for Sidebar {
fn element(&self) -> Option<&'static str> {
Some("sidebar")
}
}