Skip to main content

logicaffeine_web/ui/components/
mode_toggle.rs

1//! Studio mode toggle component.
2//!
3//! Provides a segmented control for switching between Logic, Code, Math, and
4//! Hardware modes in the Studio playground. Icons indicate each mode; labels are
5//! hidden on mobile.
6//!
7//! # Props
8//!
9//! - `mode` - Currently active mode
10//! - `on_change` - Callback when a new mode is selected
11//!
12//! # Modes
13//!
14//! - **Logic** (∀): English-to-FOL translation
15//! - **Code** (λ): Vernacular programming REPL
16//! - **Math** (π): LaTeX formula builder
17//! - **Hardware** (⚙): English-to-SVA synthesis with in-browser certified proving
18
19use dioxus::prelude::*;
20use crate::ui::state::StudioMode;
21
22const MODE_TOGGLE_STYLE: &str = r#"
23.mode-toggle {
24    display: flex;
25    gap: 2px;
26    background: rgba(255, 255, 255, 0.04);
27    border: 1px solid rgba(255, 255, 255, 0.08);
28    border-radius: 8px;
29    padding: 3px;
30}
31
32.mode-toggle-btn {
33    display: flex;
34    align-items: center;
35    gap: 6px;
36    padding: 8px 14px;
37    border: none;
38    background: transparent;
39    color: rgba(255, 255, 255, 0.5);
40    font-size: 13px;
41    font-weight: 500;
42    border-radius: 6px;
43    cursor: pointer;
44    transition: all 0.15s ease;
45    white-space: nowrap;
46}
47
48.mode-toggle-btn:hover {
49    color: rgba(255, 255, 255, 0.8);
50    background: rgba(255, 255, 255, 0.04);
51}
52
53.mode-toggle-btn.active {
54    background: rgba(102, 126, 234, 0.15);
55    color: #667eea;
56}
57
58.mode-toggle-btn .icon {
59    font-size: 14px;
60}
61
62/* Mobile: compact with labels */
63@media (max-width: 768px) {
64    .mode-toggle-btn {
65        padding: 6px 10px;
66        font-size: 12px;
67        gap: 4px;
68    }
69
70    .mode-toggle-btn .icon {
71        font-size: 12px;
72    }
73
74    .mode-toggle-btn .label {
75        font-size: 12px;
76    }
77}
78"#;
79
80#[component]
81pub fn ModeToggle(
82    mode: StudioMode,
83    on_change: EventHandler<StudioMode>,
84) -> Element {
85    rsx! {
86        style { "{MODE_TOGGLE_STYLE}" }
87
88        div { class: "mode-toggle",
89            // Logic mode button
90            button {
91                class: if mode == StudioMode::Logic { "mode-toggle-btn active" } else { "mode-toggle-btn" },
92                onclick: move |_| on_change.call(StudioMode::Logic),
93                title: "Logic Mode - English to FOL translation",
94                span { class: "icon", "\u{2200}" } // ∀ forall
95                span { class: "label", "Logic" }
96            }
97
98            // Code mode button
99            button {
100                class: if mode == StudioMode::Code { "mode-toggle-btn active" } else { "mode-toggle-btn" },
101                onclick: move |_| on_change.call(StudioMode::Code),
102                title: "Code Mode - Vernacular REPL",
103                span { class: "icon", "\u{03BB}" } // λ lambda
104                span { class: "label", "Code" }
105            }
106
107            // Math mode button
108            button {
109                class: if mode == StudioMode::Math { "mode-toggle-btn active" } else { "mode-toggle-btn" },
110                onclick: move |_| on_change.call(StudioMode::Math),
111                title: "Math Mode - Formula builder",
112                span { class: "icon", "\u{03C0}" } // π pi
113                span { class: "label", "Math" }
114            }
115
116            // Hardware mode button
117            button {
118                class: if mode == StudioMode::Hardware { "mode-toggle-btn active" } else { "mode-toggle-btn" },
119                onclick: move |_| on_change.call(StudioMode::Hardware),
120                title: "Hardware Mode - English to SystemVerilog Assertions",
121                span { class: "icon", "\u{2699}" } // ⚙ gear
122                span { class: "label", "Hardware" }
123            }
124        }
125    }
126}