# Desktop Navigation Patterns

Comparison of mobile vs desktop navigation patterns in AmethystMultiplatform.

## Core Difference

| Platform    | Pattern               | Location               | Rationale               |
|-------------|-----------------------|------------------------|-------------------------|
| **Android** | Bottom Navigation Bar | Horizontal, bottom     | Thumb reach on mobile   |
| **Desktop** | Navigation Rail       | Vertical, left sidebar | Horizontal screen space |

---

## Desktop: NavigationRail

### Current Implementation

**File:** `desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt:191-264`

```kotlin
@Composable
fun MainContent(
    currentScreen: AppScreen,
    onScreenChange: (AppScreen) -> Unit,
    // ...
) {
    Row(Modifier.fillMaxSize()) {
        // LEFT: Vertical Sidebar (NavigationRail)
        NavigationRail(
            modifier = Modifier.width(80.dp).fillMaxHeight(),
            containerColor = MaterialTheme.colorScheme.surfaceVariant
        ) {
            Spacer(Modifier.height(16.dp))

            // Top navigation items
            NavigationRailItem(
                icon = { Icon(Icons.Default.Home, "Feed") },
                label = { Text("Feed") },
                selected = currentScreen == AppScreen.Feed,
                onClick = { onScreenChange(AppScreen.Feed) }
            )

            NavigationRailItem(
                icon = { Icon(Icons.Default.Search, "Search") },
                label = { Text("Search") },
                selected = currentScreen == AppScreen.Search,
                onClick = { onScreenChange(AppScreen.Search) }
            )

            NavigationRailItem(
                icon = { Icon(Icons.Default.Email, "Messages") },
                label = { Text("DMs") },
                selected = currentScreen == AppScreen.Messages,
                onClick = { onScreenChange(AppScreen.Messages) }
            )

            NavigationRailItem(
                icon = { Icon(Icons.Default.Notifications, "Notifications") },
                label = { Text("Alerts") },
                selected = currentScreen == AppScreen.Notifications,
                onClick = { onScreenChange(AppScreen.Notifications) }
            )

            NavigationRailItem(
                icon = { Icon(Icons.Default.Person, "Profile") },
                label = { Text("Profile") },
                selected = currentScreen == AppScreen.Profile,
                onClick = { onScreenChange(AppScreen.Profile) }
            )

            // Push Settings to bottom
            Spacer(Modifier.weight(1f))

            HorizontalDivider(Modifier.padding(horizontal = 16.dp))

            NavigationRailItem(
                icon = { Icon(Icons.Default.Settings, "Settings") },
                label = { Text("Settings") },
                selected = currentScreen == AppScreen.Settings,
                onClick = { onScreenChange(AppScreen.Settings) }
            )

            Spacer(Modifier.height(16.dp))
        }

        VerticalDivider()

        // RIGHT: Main Content Area
        Box(modifier = Modifier.weight(1f).fillMaxHeight().padding(24.dp)) {
            when (currentScreen) {
                AppScreen.Feed -> FeedScreen(relayManager)
                AppScreen.Search -> SearchPlaceholder()
                AppScreen.Messages -> MessagesPlaceholder()
                AppScreen.Notifications -> NotificationsPlaceholder()
                AppScreen.Profile -> ProfileScreen(account, accountManager)
                AppScreen.Settings -> RelaySettingsScreen(relayManager)
            }
        }
    }
}
```

### Layout Structure

```
┌────────────────────────────────────────┐
│  [Menu Bar: File, Edit, View, Help]   │  ← MenuBar (OS-native)
├──────┬─────────────────────────────────┤
│      │                                 │
│ [🏠] │                                 │
│ Feed │                                 │
│      │                                 │
│ [🔍] │      Main Content Area          │
│Search│      (Feed, Messages, etc.)     │
│      │                                 │
│ [✉️] │                                 │
│ DMs  │                                 │
│      │                                 │
│ [🔔] │                                 │
│Alerts│                                 │
│      │                                 │
│ [👤] │                                 │
│Profile                                 │
│      │                                 │
│  ─   │                                 │
│ [⚙️] │                                 │
│Settings                                │
│      │                                 │
└──────┴─────────────────────────────────┘
  80dp          Remaining width (weight=1f)
```

### Key Features

1. **Always visible:** All nav items visible at once
2. **Icon + Label:** Both shown (not just icons)
3. **Vertical list:** Natural reading order
4. **Settings at bottom:** Separated by divider + Spacer.weight(1f)
5. **80dp width:** Standard NavigationRail width

---

## Android: BottomNavigationBar (Future)

### Expected Implementation

**Location:** `amethyst/src/androidMain/kotlin/...` (not yet implemented)

```kotlin
@Composable
fun MainScreen(
    currentScreen: AppScreen,
    onScreenChange: (AppScreen) -> Unit
) {
    Scaffold(
        bottomBar = {
            NavigationBar {
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Home, "Feed") },
                    label = { Text("Feed") },
                    selected = currentScreen == AppScreen.Feed,
                    onClick = { onScreenChange(AppScreen.Feed) }
                )
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Search, "Search") },
                    label = { Text("Search") },
                    selected = currentScreen == AppScreen.Search,
                    onClick = { onScreenChange(AppScreen.Search) }
                )
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Email, "Messages") },
                    label = { Text("Messages") },
                    selected = currentScreen == AppScreen.Messages,
                    onClick = { onScreenChange(AppScreen.Messages) }
                )
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Person, "Profile") },
                    label = { Text("Profile") },
                    selected = currentScreen == AppScreen.Profile,
                    onClick = { onScreenChange(AppScreen.Profile) }
                )
            }
        }
    ) { paddingValues ->
        Box(Modifier.padding(paddingValues)) {
            when (currentScreen) {
                AppScreen.Feed -> FeedScreen()
                AppScreen.Search -> SearchScreen()
                AppScreen.Messages -> MessagesScreen()
                AppScreen.Profile -> ProfileScreen()
                // Settings accessed via Profile or overflow menu
            }
        }
    }
}
```

### Layout Structure

```
┌─────────────────────────────────────┐
│                                     │
│                                     │
│        Main Content Area            │
│        (Feed, Messages, etc.)       │
│                                     │
│                                     │
│                                     │
├─────────────────────────────────────┤
│ [🏠]   [🔍]   [✉️]   [👤]          │  ← NavigationBar
│ Feed  Search  DMs  Profile          │
└─────────────────────────────────────┘
```

### Key Differences from Desktop

1. **Bottom placement:** Thumb reach
2. **Horizontal layout:** Limited vertical space
3. **Fewer items:** 3-5 primary destinations
4. **Label optional:** Can hide on small screens
5. **Settings hidden:** In profile or overflow

---

## Shared Navigation State

Both platforms use the same `AppScreen` enum from `commons`.

**File:** `commons/src/commonMain/kotlin/.../navigation/AppScreen.kt` (expected)

```kotlin
// Shared navigation destinations
enum class AppScreen {
    Feed,
    Search,
    Messages,
    Notifications,
    Profile,
    Settings
}
```

**State management (shared):**

```kotlin
// commons/src/jvmAndroid/kotlin/.../navigation/NavigationViewModel.kt
class NavigationViewModel : ViewModel() {
    private val _currentScreen = MutableStateFlow(AppScreen.Feed)
    val currentScreen: StateFlow<AppScreen> = _currentScreen.asStateFlow()

    fun navigateTo(screen: AppScreen) {
        _currentScreen.value = screen
    }
}
```

---

## Multi-Pane Desktop Layout (Advanced)

Desktop can utilize horizontal space for multi-pane layouts.

### Two-Pane Layout

```kotlin
Row(Modifier.fillMaxSize()) {
    // Left: NavigationRail (fixed 80dp)
    NavigationRail { /* ... */ }

    VerticalDivider()

    // Center: Main content (60% width)
    Box(Modifier.weight(0.6f)) {
        FeedScreen()
    }

    // Right: Detail pane (40% width, conditional)
    if (selectedNote != null) {
        VerticalDivider()
        Box(Modifier.weight(0.4f)) {
            NoteDetailPane(selectedNote)
        }
    }
}
```

### Layout:

```
┌──────┬───────────────────┬─────────────┐
│      │                   │             │
│ Nav  │   Feed List       │   Detail    │
│ Rail │   (60%)           │   Pane      │
│      │                   │   (40%)     │
│      │                   │             │
└──────┴───────────────────┴─────────────┘
 80dp      weight(0.6f)      weight(0.4f)
```

**Use cases:**

- Email: List + message detail
- Notes: List + editor
- Settings: Categories + options

---

## Keyboard Navigation

Desktop should support keyboard navigation.

### Tab Navigation

```kotlin
NavigationRail(
    modifier = Modifier.focusable()
) {
    NavigationRailItem(
        icon = { Icon(Icons.Default.Home, "Feed") },
        label = { Text("Feed") },
        selected = currentScreen == AppScreen.Feed,
        onClick = { onScreenChange(AppScreen.Feed) },
        modifier = Modifier.focusable()
    )
    // More items...
}
```

### Keyboard Shortcuts

```kotlin
Window(
    onPreviewKeyEvent = { event ->
        when {
            event.key == Key.One && event.isCtrlPressed ->
                onScreenChange(AppScreen.Feed).also { true }
            event.key == Key.Two && event.isCtrlPressed ->
                onScreenChange(AppScreen.Search).also { true }
            event.key == Key.Three && event.isCtrlPressed ->
                onScreenChange(AppScreen.Messages).also { true }
            else -> false
        }
    }
) {
    // Content
}
```

**Standard:**

- Ctrl+1: First nav item (Feed)
- Ctrl+2: Second nav item (Search)
- Ctrl+3: Third nav item (Messages)
- Ctrl+Comma: Settings

---

## Navigation Transitions

### Desktop (Instant)

No fancy animations. Instant switch.

```kotlin
Box {
    when (currentScreen) {
        AppScreen.Feed -> FeedScreen()
        AppScreen.Search -> SearchScreen()
    }
}
```

### Android (Animated, Future)

Can use Navigation Compose for transitions.

```kotlin
NavHost(navController, startDestination = "feed") {
    composable("feed") { FeedScreen() }
    composable("search") { SearchScreen() }
}
```

---

## Best Practices

### Desktop NavigationRail

✅ **DO:**

- Keep width 72-80dp
- Show both icon and label
- Use Spacer.weight(1f) for bottom items
- Separate sections with HorizontalDivider
- Limit to 5-7 primary items

❌ **DON'T:**

- Use bottom navigation on desktop
- Hide labels (plenty of space)
- Make it collapsible (not standard)
- Use hamburger menu (not desktop pattern)

### Android NavigationBar

✅ **DO:**

- Limit to 3-5 items
- Use bottom placement
- Consider label visibility on small screens
- Use standard icons

❌ **DON'T:**

- Put more than 5 items
- Use top placement (deprecated)
- Put critical actions only in nav bar

---

## Migration Strategy

When adding Android support:

1. **Extract shared state:** Move `AppScreen` to `commons/commonMain`
2. **Platform layouts:** Keep `NavigationRail` in `desktopApp/jvmMain`, `NavigationBar` in
   `amethyst/androidMain`
3. **Shared screens:** Composables in `commons/commonMain` (FeedScreen content)
4. **Platform chrome:** Navigation containers in platform modules

**Example:**

```kotlin
// commons/commonMain - Shared screen content
@Composable
fun FeedContent(notes: List<Note>) {
    LazyColumn {
        items(notes) { note ->
            NoteCard(note)
        }
    }
}

// desktopApp/jvmMain - Desktop wrapper
@Composable
fun FeedScreen() {
    Column {
        FeedHeader()  // Desktop-specific header
        FeedContent(notes)  // Shared content
    }
}

// amethyst/androidMain - Android wrapper
@Composable
fun FeedScreen() {
    Scaffold(
        topBar = { TopAppBar { Text("Feed") } }
    ) {
        FeedContent(notes)  // Same shared content
    }
}
```

---

## References

- **Current Desktop:** Main.kt:191-264
- **Material3 NavigationRail:
  ** [Material Design Docs](https://m3.material.io/components/navigation-rail)
- **Material3 NavigationBar:
  ** [Material Design Docs](https://m3.material.io/components/navigation-bar)
