+++
title = "Flat Navigation"
weight = 0
[extra]
section = 1
disclaimer = "These docs are incomplete."
+++

In a flat navigation structure, each page is equivalent in importance and can be opened form any of the others.
Different platforms offer different solutions for flat navigation, such as a top bar or a sidebar.
This view will select the most appropriate based on number of elements and available space.

Label views with capitalized nouns with a similar length. Order the elements according to what is most useful for the user.
The icons should clearly communicate a page's function even without the label.

Note that this view should be used exclusively as a direct child of a window.

## Sidebar Design

The sidebar design will be used if there are more than five items or the developer chooses to force the sidebar design (see below).

<div class="pattern-images">
{{ image(url="sidebarGNOME.png", alt="A navigation view with a sidebar on GNOME" transparent=true) }}

{{ image(url="sidebarWindows.png", alt="A navigation view with a sidebar on Windows") }}
</div>

## Top Bar Design

The top bar design will be used for five items or less if the sidebar design is not forced.

<div class="pattern-images">
{{ image(url="topGNOME.png", alt="A navigation view with a top bar on GNOME" transparent=true) }}

{{ image(url="topWindows.png", alt="A navigation view with a top bar on GNOME") }}
</div>

## Equatable Items

A flat navigation view can be initialized either with identifiable or with equatable items.
The initializer for equatable items is useful for a fixed number of items.

```swift
struct ContentView: View {

    @State private var selectedItem: Page = .navigation

    var view: Body {
        FlatNavigation(Page.allCases, selection: $selectedItem) {
            // The content.
            Text(selectedItem.description)
        }
    }

}

enum Page: FlatNavigationItem, CaseIterable {

    // The pages.
    case navigation
    case alert

    // The title of the page.
    var description: String {
        switch self {
        case .navigation:
            Loc.navigation
        case .alert:
            Loc.alert
        }
    }

    // The icon of the page.
    var icon: Icon {
        switch self {
        case .navigation:
            .navigation
        case .alert:
            .warning
        }
    }

}
```

## Identifiable Items

The initializer for identifiable items should be used for a dynamic list of items.
It will automatically force the sidebar design (more information below).

```swift
struct ContentView: View {

    @State private var selectedItem: UUID?
    @State private var items: [Item] = [.init(title: "Item 1"), .init(title: "Item 2")]

    var view: Body {
        FlatNavigation(items, selection: $selectedItem) {
            // The content.
            Text("Content")
        }
    }

}

struct Item: DynamicFlatNavigationItem, Identifiable {

    let id: UUID = .init()
    var title: String

    // The title of the page.
    var description: String { title }

    // The icon of the page.
    var icon: Icon { .document }

}
```

## Force the Sidebar Design

Force the sidebar design with the [`forceSplitView(_:)`](https://aparoksha.aparoksha.dev/documentation/aparoksha/flatnavigation/forcesplitview(_:)) modifier.

```swift
FlatNavigation(Page.allCases, selection: $selectedItem) {
    // The content.
    Text(selectedItem.description)
}
.forceSplitView()
```

## Primary Action

The primary action usually modifies the navigation items or triggers an important action.

<div class="pattern-images">
{{ image(url="primaryGNOME.png", alt="A navigation view with a sidebar and a primary action on GNOME" transparent=true) }}

{{ image(url="primaryWindows.png", alt="A navigation view with a sidebar and a primary action on Windows") }}

{{ image(url="primaryGNOMETop.png", alt="A navigation view with a sidebar on GNOME" transparent=true) }}

{{ image(url="primaryWindowsTop.png", alt="A navigation view with a sidebar on Windows") }}
</div>

```swift
FlatNavigation(items, selection: $selectedItem) {
    // The content.
    Text(selectedItem.description)
}
.primaryAction(Loc.addItem, icon: .plus) {
    // The action.
    items.append(.init(title: Loc.newItem))
}
```

## Guidelines

- <a class="external" href="https://developer.gnome.org/hig/guidelines/navigation.html#flat-navigation">GNOME</a>
- <a class="external" href="https://learn.microsoft.com/en-us/windows/apps/design/basics/navigation-basics">Windows</a>

## Documentation

- <a class="external" href="https://aparoksha.aparoksha.dev/documentation/aparoksha/flatnavigation">Reference Documentation</a>
- <a class="external" href="https://adwaita-swift.aparoksha.dev/documentation/adwaita/navigationsplitview">Native GNOME Implementation (Sidebar)</a>
- <a class="external" href="https://adwaita-swift.aparoksha.dev/documentation/adwaita/viewswitcher">Native GNOME Implementation (Top Bar)</a>
- <a class="external" href="https://winui-swift.aparoksha.dev/documentation/winui_swift/navigationview">Native Windows Implementation</a>
