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