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}