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
52impl<T: 'static + NativeView> View for Native<T> {
53    #[allow(unused)]
54    #[allow(clippy::needless_return)]
55    fn body(self, _env: &Environment) -> impl View {
56        self.fallback
57            .unwrap_or_else(|| panic!("Native view ({})", type_name::<T>()))
58    }
59
60    fn stretch_axis(&self) -> StretchAxis {
61        NativeView::stretch_axis(&self.native)
62    }
63}
64
65/// A trait for all views handled by the native backend.
66///
67/// This includes:
68/// - Configurable views (`TextField`, Slider, Toggle, etc.)
69/// - Raw views (Color, Spacer, Divider, Container, etc.)
70///
71/// The native backend uses this trait to query layout behavior.
72pub trait NativeView {
73    /// Which axis (or axes) this view stretches to fill available space.
74    fn stretch_axis(&self) -> StretchAxis {
75        StretchAxis::None
76    }
77}