Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
examples/modern_dashboard/src/components/sidebar.rs
1use strato_widgets::{
2 Widget, Column, Container, Text, Button, Flex,
3 text::FontWeight,
4 layout::{CrossAxisAlignment, MainAxisAlignment},
5};
6use strato_core::{
7 types::Color,
8 state::Signal,
9};
10use crate::theme::{AppTheme, BORDER_RADIUS_MD, SPACING_MD, SPACING_SM};
11 
12pub struct Sidebar {
13 active_tab: Signal<String>,
14 theme: AppTheme,
15}
16 
17impl Sidebar {
18 pub fn new(active_tab: Signal<String>) -> Self {
19 Self {
20 active_tab,
21 theme: AppTheme::dark(),
22 }
23 }
24 
25 pub fn build(self) -> Box<dyn Widget> {
26 let theme = self.theme;
27 let active_tab = self.active_tab.clone();
28 
29 Box::new(Container::new()
30 .background(theme.bg_secondary)
31 .width(260.0)
32 .padding(SPACING_MD)
33 .child(
34 Column::new()
35 .cross_axis_alignment(CrossAxisAlignment::Stretch)
36 .spacing(SPACING_MD)
37 .children(vec![
38 // Logo Area
39 Box::new(Container::new()
40 .padding(SPACING_SM)
41 .child(
42 Text::new("StratoUI")
43 .font_size(24.0)
44 .font_weight(FontWeight::Bold)
45 .color(theme.accent)
46 )
47 ) as Box<dyn Widget>,
48 
49 // Navigation Items
50 self.nav_item("Dashboard", "dashboard", active_tab.clone(), theme.clone()),
51 self.nav_item("Analytics", "analytics", active_tab.clone(), theme.clone()),
52 self.nav_item("Users", "users", active_tab.clone(), theme.clone()),
53 self.nav_item("Settings", "settings", active_tab.clone(), theme.clone()),
54 
55 // Spacer
56 Box::new(Flex::new(Box::new(Container::new())).flex(1.0)) as Box<dyn Widget>,
57 
58 // Bottom Area
59 Box::new(Container::new()
60 .background(theme.bg_tertiary)
61 .border_radius(BORDER_RADIUS_MD)
62 .padding(SPACING_MD)
63 .child(
64 Column::new()
65 .spacing(SPACING_SM)
66 .children(vec![
67 Box::new(Text::new("Pro Plan").font_weight(FontWeight::Bold).color(theme.text_primary)) as Box<dyn Widget>,
68 Box::new(Text::new("Expires in 12 days").font_size(12.0).color(theme.text_secondary)) as Box<dyn Widget>,
69 Box::new(Button::new("Upgrade").primary()) as Box<dyn Widget>,
70 ])
71 )
72 ) as Box<dyn Widget>,
73 ])
74 )
75 )
76 }
77 
78 fn nav_item(&self, label: &str, id: &str, active_signal: Signal<String>, _theme: AppTheme) -> Box<dyn Widget> {
79 // Note: Real interactivity would check active_signal value to change style
80 // For now, we simulate basic structure
81 let id_owned = id.to_string();
82 
83 Box::new(Button::new(label)
84 .secondary() // Use secondary style by default
85 .on_click(move || {
86 active_signal.set(id_owned.clone());
87 })
88 )
89 }
90}
91