Skip to main content

waterui_core/components/
native.rs

1//! This module provides platform-specific native views that can wrap platform-native UI components.
2
3use core::any::type_name;
4
5use crate::{AnyView, Environment, View, layout::StretchAxis};
6
7/// A wrapper for platform-specific native UI components.
8///
9/// `Native<T>` allows embedding platform-specific UI elements within the view hierarchy.
10/// The generic parameter `T` represents the platform-specific component type.
11///
12/// # Panics
13///
14/// Attempting to render a `Native<T>` view directly will panic. This type is intended
15/// to be handled by platform-specific rendering backends.
16#[derive(Debug)]
17pub struct Native<T: NativeView> {
18    native: T,
19    fallback: Option<AnyView>,
20}
21
22impl<T: NativeView> Native<T> {
23    /// Creates a new `Native<T>` view wrapping the given native component.
24    ///
25    /// # Arguments
26    ///
27    /// * `native` - The platform-specific native UI component to wrap.
28    pub const fn new(native: T) -> Self {
29        Self {
30            native,
31            fallback: None,
32        }
33    }
34
35    /// Sets a fallback view to be used if the native view cannot be rendered.
36    ///
37    /// # Arguments
38    /// * `fallback` - The fallback view to display.
39    #[must_use]
40    pub fn with_fallback(mut self, fallback: impl View) -> Self {
41        self.fallback = Some(AnyView::new(fallback));
42        self
43    }
44
45    /// Consumes the wrapper and returns the inner native component.
46    #[must_use]
47    pub fn into_inner(self) -> T {
48        self.native
49    }
50
51    /// Returns a shared reference to the wrapped native component.
52    #[must_use]
53    pub const fn as_inner(&self) -> &T {
54        &self.native
55    }
56
57    /// Returns a mutable reference to the wrapped native component.
58    pub const fn as_inner_mut(&mut self) -> &mut T {
59        &mut self.native
60    }
61}
62
63impl<T: 'static + NativeView> View for Native<T> {
64    fn body(self, _env: &Environment) -> impl View {
65        self.fallback
66            .unwrap_or_else(|| panic!("Native view ({})", type_name::<T>()))
67    }
68
69    fn stretch_axis(&self) -> StretchAxis {
70        NativeView::stretch_axis(&self.native)
71    }
72}
73
74/// A trait for all views handled by the native backend.
75///
76/// This includes:
77/// - Configurable views (`TextField`, Slider, Toggle, etc.)
78/// - Raw views (Color, Spacer, Divider, Container, etc.)
79///
80/// The native backend uses this trait to query layout behavior.
81pub trait NativeView {
82    /// Which axis (or axes) this view stretches to fill available space.
83    fn stretch_axis(&self) -> StretchAxis {
84        StretchAxis::None
85    }
86}