swiftui-native 0.0.1

SwiftUI from pure Rust — no Swift bridge, no shim, only swift-runtime calls
Documentation
//! Navigation, toolbars, sheets and search — an app's shell.
//!
//! Part of [`crate::view::View`]'s chainable API; Rust allows a type's
//! inherent methods to be split across modules, and 400 of them in one file
//! was a file nobody could find anything in.

use super::View;
use crate::views;

impl View {
    // ── Navigation ──

    /// `.navigationDestination(isPresented:destination:)` bound to Rust state —
    /// pushing sets it, and the back button writes `false` back.
    pub fn navigation_destination(
        self,
        state: &views::BoundState<bool>,
        destination: View,
    ) -> Self {
        Self::new(views::navigation_destination(
            &self.handle,
            state,
            destination.handle(),
        ))
    }

    /// `.inspector(isPresented:content:)` bound to Rust state.
    pub fn inspector(self, state: &views::BoundState<bool>, content: View) -> Self {
        Self::new(views::inspector(&self.handle, state, content.handle()))
    }

    /// `.inspectorColumnWidth(_:)` — one fixed width for the inspector column.
    pub fn inspector_column_width(self, width: f64) -> Self {
        Self::new(views::inspector_column_width(&self.handle, width))
    }

    /// `.inspectorColumnWidth(min:ideal:max:)` — a width the user can drag
    /// within.
    ///
    /// `None` for a bound leaves the column unconstrained in that direction,
    /// which is not the same as pinning it to zero. `.inspector_column_width`
    /// above is the fixed spelling.
    pub fn inspector_column_width_range(
        self,
        min: Option<f64>,
        ideal: f64,
        max: Option<f64>,
    ) -> Self {
        Self::new(views::inspector_column_width_range(&self.handle, min, ideal, max))
    }

    /// `.toolbarBackground(_:for:)`
    pub fn toolbar_background(
        self,
        visibility: views::Visibility,
        placements: &[views::ToolbarPlacement],
    ) -> Self {
        Self::new(views::toolbar_background(&self.handle, visibility, placements))
    }

    /// `.toolbarVisibility(_:for:)` — whether the bar shows at all.
    ///
    /// SwiftUI also spells this `.toolbar(_:for:)`; this reaches the named one.
    pub fn toolbar_visibility(
        self,
        visibility: views::Visibility,
        placements: &[views::ToolbarPlacement],
    ) -> Self {
        Self::new(views::toolbar_visibility(&self.handle, visibility, placements))
    }

    /// `.toolbarTitleDisplayMode(_:)` — large title or inline.
    pub fn toolbar_title_display_mode(self, mode: views::ToolbarTitleDisplayMode) -> Self {
        Self::new(views::toolbar_title_display_mode(&self.handle, mode))
    }

    /// `.toolbarRole(_:)`
    pub fn toolbar_role(self, role: views::ToolbarRole) -> Self {
        Self::new(views::toolbar_role(&self.handle, role))
    }

    /// `.searchable(text:isPresented:placement:prompt:)`, both bindings owned by
    /// Rust — the query text lands in `text` as it is typed.
    pub fn searchable(
        self,
        text: &views::BoundState<String>,
        presented: &views::BoundState<bool>,
        placement: views::SearchFieldPlacement,
        prompt: &str,
    ) -> Self {
        Self::new(views::searchable(&self.handle, text, presented, placement, prompt))
    }

    /// `.navigationSplitViewStyle(.automatic)`
    pub fn navigation_split_view_style_automatic(self) -> Self {
        Self::new(views::navigation_split_view_style_automatic(&self.handle))
    }

    /// `.navigationViewStyle(.automatic)`
    pub fn navigation_view_style_automatic(self) -> Self {
        Self::new(views::navigation_view_style_automatic(&self.handle))
    }

    /// `.navigationDocument(_:)`
    pub fn navigation_document(self, item: &str) -> Self {
        Self::new(views::navigation_document(&self.handle, item))
    }

    /// `.navigationDocument(_:)` with a URL.
    pub fn navigation_document_url(self, spec: &str) -> Self {
        Self::new(views::navigation_document_url(&self.handle, spec))
    }

    // ── Toolbars ──

    /// `.toolbarBackgroundVisibility(_:for:)` — distinct from
    /// [`View::toolbar_background`], which sets *what* the background is.
    pub fn toolbar_background_visibility(
        self,
        visibility: views::Visibility,
        placements: &[views::ToolbarPlacement],
    ) -> Self {
        Self::new(views::toolbar_background_visibility(&self.handle, visibility, placements))
    }

    /// `.toolbarColorScheme(_:in:)` — `None` restores the inherited scheme.
    pub fn toolbar_color_scheme(
        self,
        scheme: Option<views::ColorScheme>,
        placements: &[views::ToolbarPlacement],
    ) -> Self {
        Self::new(views::toolbar_color_scheme(&self.handle, scheme, placements))
    }

    /// `.toolbarTitleMenu(content:)` — the menu behind a tappable title.
    pub fn toolbar_title_menu(self, content: View) -> Self {
        Self::new(views::toolbar_title_menu(&self.handle, content.handle()))
    }

    /// `.presentationSizing(_:)`
    pub fn presentation_sizing(self) -> Self {
        Self::new(views::presentation_sizing(&self.handle))
    }

    /// `.presentationBackgroundInteraction(_:)` — whether what is behind a
    /// sheet still takes touches, which is what makes a half-sheet usable.
    pub fn presentation_background_interaction(
        self,
        value: views::PresentationBackgroundInteraction,
    ) -> Self {
        Self::new(views::presentation_background_interaction(&self.handle, value))
    }

    /// `.presentationCompactAdaptation(_:)` — what a popover becomes when the
    /// size class is compact, which on a phone is always.
    pub fn presentation_compact_adaptation(self, value: views::PresentationAdaptation) -> Self {
        Self::new(views::presentation_compact_adaptation(&self.handle, value))
    }

    /// `.presentationContentInteraction(_:)` — whether a drag resizes the sheet
    /// or scrolls its content.
    pub fn presentation_content_interaction(
        self,
        value: views::PresentationContentInteraction,
    ) -> Self {
        Self::new(views::presentation_content_interaction(&self.handle, value))
    }

    /// `.navigationTransition(_:)`
    pub fn navigation_transition(self) -> Self {
        Self::new(views::navigation_transition(&self.handle))
    }

    /// `.navigationSplitViewColumnWidth(_:)`
    pub fn navigation_split_view_column_width(self, width: f64) -> Self {
        Self::new(views::navigation_split_view_column_width(&self.handle, width))
    }

    /// `.matchedTransitionSource(id:in:)` — the view a zoom transition grows
    /// from, paired with [`View::matched_geometry_effect`]'s destination.
    pub fn matched_transition_source(self, id: views::HashableValue<'_>) -> Self {
        Self::new(views::matched_transition_source(&self.handle, id))
    }

    // ── How a sheet presents ──

    /// `.presentationDetents(_:)` — the heights a sheet can rest at, which is
    /// what makes it a half-sheet rather than a full one.
    pub fn presentation_detents(self, detents: &[views::PresentationDetent]) -> Self {
        Self::new(views::presentation_detents(&self.handle, detents))
    }

    /// `.presentationDragIndicator(_:)`
    pub fn presentation_drag_indicator(self, visibility: views::Visibility) -> Self {
        Self::new(views::presentation_drag_indicator(&self.handle, visibility))
    }

    /// `.presentationCornerRadius(_:)` — `None` restores the system radius.
    pub fn presentation_corner_radius(self, radius: Option<f64>) -> Self {
        Self::new(views::presentation_corner_radius(&self.handle, radius))
    }

    /// `.presentationBackground(alignment:content:)`
    pub fn presentation_background(self, alignment: views::Alignment, content: View) -> Self {
        Self::new(views::presentation_background(
            &self.handle,
            alignment,
            content.handle(),
        ))
    }

    /// `.tint(_:)` with one of SwiftUI's own colours.
    ///
    /// [`View::tint`] takes a literal `Color`; a named colour is not a fixed
    /// triple, so for an accent — which is what the system draws controls with —
    /// naming it is usually what is meant.
    pub fn tint_system(self, c: views::SystemColor) -> Self {
        Self::new(views::tint_color(&self.handle, views::system_color_value(c)))
    }

    // ── Search ──

    /// `.searchToolbarBehavior(_:)`
    pub fn search_toolbar_behavior(self, value: views::SearchToolbarBehavior) -> Self {
        Self::new(views::search_toolbar_behavior(&self.handle, value))
    }

    /// `.searchPresentationToolbarBehavior(_:)`
    pub fn search_presentation_toolbar_behavior(
        self,
        value: views::SearchPresentationToolbarBehavior,
    ) -> Self {
        Self::new(views::search_presentation_toolbar_behavior(&self.handle, value))
    }

    /// `.textSelectionAffinity(_:)`
    pub fn text_selection_affinity(self, value: views::TextSelectionAffinity) -> Self {
        Self::new(views::text_selection_affinity(&self.handle, value))
    }

    /// `.typeSelectEquivalent(_:)` — what typing in a list jumps to.
    pub fn type_select_equivalent(self, text: Option<&str>) -> Self {
        Self::new(views::type_select_equivalent(&self.handle, text))
    }

    /// `.searchScopes(_:scopes:)` bound to Rust state — the chosen scope lands
    /// in `scope`.
    pub fn search_scopes(self, scope: &views::BoundState<i64>, scopes: View) -> Self {
        Self::new(views::search_scopes(&self.handle, scope, scopes.handle()))
    }

    /// `.searchSuggestions(_:for:)` — where suggestions may appear.
    pub fn search_suggestions(
        self,
        visibility: views::Visibility,
        placements: views::SearchSuggestionsPlacementSet,
    ) -> Self {
        Self::new(views::search_suggestions(&self.handle, visibility, placements))
    }

    /// `.searchSelection(_:)`
    pub fn search_selection(self, changed: impl Fn() + 'static) -> Self {
        Self::new(views::search_selection(&self.handle, changed))
    }

    /// `.searchFocused(_:)`
    pub fn search_focused(self) -> Self {
        Self::new(views::search_focused(&self.handle))
    }

    /// `.textInputSuggestions { … }` — completions offered under a field.
    pub fn text_input_suggestions(self, count: usize, content: View) -> Self {
        Self::new(views::text_input_suggestions(&self.handle, count, content.handle()))
    }

    /// `.findNavigator(isPresented:)` bound to Rust state — the find bar.
    pub fn find_navigator(self, state: &views::BoundState<bool>) -> Self {
        Self::new(views::find_navigator(&self.handle, state))
    }

}