gpui-nav

Crates.iogpui-nav
lib.rsgpui-nav
version0.1.1
created_at2025-10-15 12:14:44.406212+00
updated_at2025-10-15 12:45:04.335975+00
descriptionA lightweight screen navigation library for GPUI
homepage
repositoryhttps://github.com/benodiwal/gpui-nav
max_upload_size
id1884258
size196,698
Sachin Beniwal (benodiwal)

documentation

README

gpui-nav

A lightweight screen navigation library for GPUI applications.

Crates.io Documentation License: MIT

Quick Start

Add this to your Cargo.toml:

[dependencies]
gpui = "0.2.1"
gpui-nav = "0.1.0"

Basic Usage

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);
                        });
                    }))
            )
    }
}

Navigation Operations

Push a new screen

let settings_screen = SettingsScreen::new(ctx.weak_entity());
app.navigator.push(settings_screen, cx);

Pop the current screen

app.navigator.pop(cx);

Replace the current screen

let login_screen = LoginScreen::new(ctx.weak_entity());
app.navigator.replace(login_screen, cx);

Clear stack and push new screen

let home_screen = HomeScreen::new(ctx.weak_entity());
app.navigator.clear_and_push(home_screen, cx);

Examples

Basic Navigation Example

A complete example demonstrating navigation between multiple screens with state management:

cd examples/basic_navigation
cargo run

Features demonstrated:

  • Multiple screens (Home, Profile, Settings)
  • All navigation operations (push, pop, replace, clear_and_push)
  • Shared state management
  • Login/logout flow
  • Clean modular architecture

👉 View the complete example

Core Concepts

Screen Trait

Every screen must implement the Screen trait:

pub trait Screen {
    fn id(&self) -> &'static str;
}

ScreenContext

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>;
}

Navigator

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;
}

Architecture

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

Best Practices

  1. Single Navigator: Keep one navigator instance in your app state
  2. Screen IDs: Use descriptive, unique screen identifiers
  3. State Management: Store shared data in your app state, not in screens
  4. Memory: Screens are automatically cleaned up when popped

Compatibility

  • GPUI: 0.2+
  • Rust: 1.70+

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Commit count: 0

cargo fmt