waterui_navigation/
tab.rs

1//! Tabs module provides UI elements for building tabbed interfaces.
2//!
3//! This module includes the components needed to create and manage tabs,
4//! with support for selection binding and navigation views.
5
6use alloc::vec::Vec;
7
8use nami::Binding;
9use waterui_core::{
10    AnyView,
11    handler::{AnyViewBuilder, ViewBuilder},
12    id::Id,
13    impl_debug,
14    layout::StretchAxis,
15    raw_view,
16};
17
18use super::NavigationView;
19use waterui_core::id::TaggedView;
20
21/// Position of the tab bar within the tab container.
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
23#[repr(u8)]
24pub enum TabPosition {
25    /// Tab bar is positioned at the top of the container.
26    Top,
27    /// Tab bar is positioned at the bottom of the container (default).
28    #[default]
29    Bottom,
30}
31
32/// Represents a single tab with a label and content.
33///
34/// The generic parameter `T` is used for tag identification.
35///
36pub struct Tab<T> {
37    /// The visual label for the tab, wrapped in a tagged view.
38    pub label: TaggedView<T, AnyView>,
39
40    /// The content to display when this tab is selected.
41    /// Returns a [`NavigationView`] when given an Environment.
42    pub content: AnyViewBuilder<NavigationView>,
43}
44
45impl_debug!(Tab<Id>);
46
47impl<T> Tab<T> {
48    /// Creates a new tab with the given label and content.
49    ///
50    /// # Arguments
51    ///
52    /// * `label` - The visual representation of the tab
53    /// * `content` - A function that returns the tab's content as a [`NavigationView`]
54    pub fn new(
55        label: TaggedView<T, AnyView>,
56        content: impl ViewBuilder<Output = NavigationView>,
57    ) -> Self {
58        Self {
59            label,
60            content: AnyViewBuilder::new(content),
61        }
62    }
63}
64
65/// Configuration for the Tabs component.
66///
67/// This struct holds the current tab selection and the collection of tabs.
68#[derive(Debug)]
69#[non_exhaustive]
70pub struct Tabs {
71    /// The currently selected tab identifier.
72    pub selection: Binding<Id>,
73
74    /// The collection of tabs to display.
75    pub tabs: Vec<Tab<Id>>,
76
77    /// Position of the tab bar (top or bottom).
78    pub position: TabPosition,
79}
80
81// Make Tabs a raw view that stretches to fill available space
82raw_view!(Tabs, StretchAxis::Both);