// ============================================================================= // Main showcase component // ============================================================================= fn ds_showcase() -> Element { let mut counter = use_signal(|| 0i64); let mut checkbox_val = use_signal(|| false); let mut switch_val = use_signal(|| true); let mut next_id = use_signal(|| 4usize); let mut tasks = use_signal(|| { vec![ Task { id: 0, title: "Build Touso renderer".into(), done: true }, Task { id: 1, title: "Generate DS bindings".into(), done: true }, Task { id: 2, title: "Write RSX showcase".into(), done: false }, Task { id: 3, title: "Ship it".into(), done: false }, ] }); let count_val = *counter.read(); let cb_val = *checkbox_val.read(); let sw_val = *switch_val.read(); let task_list = tasks.read().clone(); let total = task_list.len(); let done = task_list.iter().filter(|t| t.done).count(); rsx! { // FTheme + FScaffold are provided by the Flutter shell — just render content. singlechildscrollview { padding: EdgeInsets::symmetric().horizontal(16.0), column { cross_axis_alignment: CrossAxisAlignment::Stretch, // ── Buttons ── _section_header { title: "Buttons" } sizedbox { height: 8.0 } row { main_axis_alignment: MainAxisAlignment::Start, button { on_press: move |_| counter += 1, text { data: "Increment" } } sizedbox { width: 8.0 } button { on_press: move |_| counter -= 1, text { data: "Decrement" } } sizedbox { width: 8.0 } button { on_press: move |_| counter.set(0), text { data: "Reset" } } } sizedbox { height: 16.0 } // Counter card — uses named slots for title/subtitle card { title { text { data: "Counter" } } subtitle { text { data: "Tap the buttons above" } } text { data: "Value: {count_val}", style: TextStyle::new().font_size(28.0).font_weight(FontWeight::w700()), } } sizedbox { height: 24.0 } divider {} sizedbox { height: 24.0 } // ── Badges ── _section_header { title: "Badges" } sizedbox { height: 8.0 } row { main_axis_alignment: MainAxisAlignment::Start, badge { text { data: "Primary" } } sizedbox { width: 8.0 } badge { text { data: "{total} tasks" } } sizedbox { width: 8.0 } badge { text { data: "{done} done" } } } sizedbox { height: 24.0 } divider {} sizedbox { height: 24.0 } // ── Alert ── _section_header { title: "Alert" } sizedbox { height: 8.0 } alert { title { text { data: "Server-Side Rendering" } } subtitle { text { data: "This entire UI is rendered by Rust on the server using Dioxus RSX.", } } } sizedbox { height: 24.0 } divider {} sizedbox { height: 24.0 } // ── Form Controls ── _section_header { title: "Form Controls" } sizedbox { height: 8.0 } checkbox { value: cb_val, on_change: move |_| { let cur = *checkbox_val.read(); checkbox_val.set(!cur); }, label { text { data: "Accept terms and conditions" } } description { text { data: "You agree to our Terms of Service." } } } sizedbox { height: 12.0 } r#switch { value: sw_val, on_change: move |_| { let cur = *switch_val.read(); switch_val.set(!cur); }, label { text { data: "Enable notifications" } } description { text { data: "Receive push notifications." } } } sizedbox { height: 24.0 } divider {} sizedbox { height: 24.0 } // ── Progress ── _section_header { title: "Progress" } sizedbox { height: 8.0 } progress { semantics_label: "Loading" } sizedbox { height: 24.0 } divider {} sizedbox { height: 24.0 } // ── Task List ── _section_header { title: "Task List" } sizedbox { height: 8.0 } button { on_press: move |_| { let id = *next_id.read(); next_id += 1; tasks.write().push(Task { id, title: format!("New task #{id}"), done: false, }); }, text { data: "+ Add Task" } } sizedbox { height: 8.0 } tilegroup { for task in task_list.iter() { { let tid = task.id; let tdone = task.done; let ttitle = task.title.clone(); rsx! { tile { on_press: move |_| { if let Some(t) = tasks.write().iter_mut().find(|t| t.id == tid) { t.done = !t.done; } }, title { text { data: "{ttitle}" } } subtitle { text { data: if tdone { "Done" } else { "Pending" }, } } } } } } } sizedbox { height: 24.0 } divider {} sizedbox { height: 24.0 } // ── Accordion ── _section_header { title: "FAQ" } sizedbox { height: 8.0 } accordion { accordionitem { title { text { data: "What is Touso?" } } text { data: "A multi-language rendering engine: React/Dioxus authors Flutter UIs via a mutation protocol.", } } accordionitem { title { text { data: "What is ds_touso?" } } text { data: "Generated converters bridging the Genvoy DS design system to Touso.", } } accordionitem { title { text { data: "How does RSX work?" } } text { data: "genvoy-dioxus maps Rust element names (button, card) to Flutter widget types (Button, Card) via the Touso mutation protocol.", } } } sizedbox { height: 32.0 } // ── Stats Footer ── row { main_axis_alignment: MainAxisAlignment::SpaceEvenly, _stat_card { label: "Counter", value: "{count_val}" } _stat_card { label: "Tasks", value: "{total}" } _stat_card { label: "Done", value: "{done}" } } sizedbox { height: 24.0 } } } } } // ============================================================================= // Sub-components // ============================================================================= #[component] fn _section_header(title: String) -> Element { rsx! { text { data: "{title}", style: TextStyle::new().font_size(18.0).font_weight(FontWeight::w600()), } } } #[component] fn _stat_card(label: String, value: String) -> Element { rsx! { card { title { text { data: "{value}" } } subtitle { text { data: "{label}" } } } } } // ============================================================================= // Helpers // ============================================================================= #[derive(Clone, PartialEq)] struct Task { id: usize, title: String, done: bool, }