| Crates.io | gpui-nav |
| lib.rs | gpui-nav |
| version | 0.1.1 |
| created_at | 2025-10-15 12:14:44.406212+00 |
| updated_at | 2025-10-15 12:45:04.335975+00 |
| description | A lightweight screen navigation library for GPUI |
| homepage | |
| repository | https://github.com/benodiwal/gpui-nav |
| max_upload_size | |
| id | 1884258 |
| size | 196,698 |
A lightweight screen navigation library for GPUI applications.
Add this to your Cargo.toml:
[dependencies]
gpui = "0.2.1"
gpui-nav = "0.1.0"
use gpui::*;
use gpui_nav::{Navigator, Screen, ScreenContext};
// Define your app state
pub struct AppState {
navigator: Navigator,
}
// Define a screen
pub struct HomeScreen {
ctx: ScreenContext<AppState>,
}
impl Screen for HomeScreen {
fn id(&self) -> &'static str {
"home"
}
}
impl Render for HomeScreen {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
div()
.child("Home Screen")
.child(
div()
.child("Go to Settings")
.on_mouse_down(MouseButton::Left, cx.listener(|this, _event, _window, cx| {
this.ctx.update(cx, |app, inner_cx| {
let settings = SettingsScreen::new(inner_cx.weak_entity());
app.navigator.push(settings, inner_cx);
});
}))
)
}
}
let settings_screen = SettingsScreen::new(ctx.weak_entity());
app.navigator.push(settings_screen, cx);
app.navigator.pop(cx);
let login_screen = LoginScreen::new(ctx.weak_entity());
app.navigator.replace(login_screen, cx);
let home_screen = HomeScreen::new(ctx.weak_entity());
app.navigator.clear_and_push(home_screen, cx);
A complete example demonstrating navigation between multiple screens with state management:
cd examples/basic_navigation
cargo run
Features demonstrated:
Every screen must implement the Screen trait:
pub trait Screen {
fn id(&self) -> &'static str;
}
ScreenContext provides convenient navigation methods:
pub struct ScreenContext<T> {
// Provides access to app state and navigation
}
impl<T> ScreenContext<T> {
pub fn new(app_state: WeakEntity<T>) -> Self;
pub fn app_state(&self) -> WeakEntity<T>;
pub fn update<R>(&self, cx: &mut Context<impl Render>, f: impl FnOnce(&mut T, &mut Context<T>) -> R) -> Option<R>;
}
The Navigator manages your navigation stack:
impl Navigator {
pub fn new() -> Self;
pub fn push<S: Screen, T: 'static>(&mut self, screen: S, cx: &mut Context<T>);
pub fn pop<T: 'static>(&mut self, cx: &mut Context<T>) -> bool;
pub fn replace<S: Screen, T: 'static>(&mut self, screen: S, cx: &mut Context<T>) -> bool;
pub fn clear_and_push<S: Screen, T: 'static>(&mut self, screen: S, cx: &mut Context<T>);
pub fn current(&self) -> Option<&AnyView>;
pub fn can_go_back(&self) -> bool;
pub fn len(&self) -> usize;
}
Your App State
├── Navigator (manages screen stack)
├── Shared Data (accessible to all screens)
└── Business Logic
Screen A ←→ ScreenContext ←→ Navigator ←→ Screen B
↓ ↓ ↓
UI Logic Navigation API UI Logic
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.