zsui 0.3.0-alpha.2

Rust-first feature-gated native UI framework for Win32, AppKit, and Linux.
Documentation
#[cfg(feature = "combo")]
pub fn combo_box<T, Msg>(
    options: impl IntoIterator<Item = T>,
    selected_index: Option<usize>,
) -> ViewNode<Msg>
where
    T: Into<String>,
{
    let metrics = crate::ZsBaseControlMetrics::for_platform(
        crate::ZsBaseControlPlatformStyle::current(),
    );
    let options = options.into_iter().map(Into::into).collect::<Vec<_>>();
    let selected_index = selected_index.filter(|index| *index < options.len());
    ViewNode::new(ViewNodeKind::ComboBox {
        options,
        selected_index,
        expanded: false,
        placeholder: None,
        on_select: None,
        on_expanded_change: None,
    })
    .min_width(metrics.selection_minimum_width)
    .native_typography_height(metrics.selection_height)
}

#[cfg(feature = "tabs")]
pub fn tab_view<Msg>(
    items: impl IntoIterator<Item = ZsTabItem<Msg>>,
    selected: Option<ZsTabId>,
) -> ViewNode<Msg> {
    let items = items.into_iter().collect::<Vec<_>>();
    let tabs = items
        .iter()
        .map(|item| item.spec.clone())
        .collect::<Vec<_>>();
    let selected = selected
        .filter(|selected| tabs.iter().any(|tab| tab.id == *selected))
        .or_else(|| tabs.first().map(|tab| tab.id));
    let node = ViewNode::new(ViewNodeKind::Tabs {
        tabs,
        selected,
        on_select: None,
    })
    .children(items.into_iter().map(|item| item.content));
    #[cfg(feature = "scroll")]
    let node = node.auto_scroll_y();
    node
}
#[cfg(feature = "list")]
pub fn list<T, Msg>(
    items: impl IntoIterator<Item = T>,
    render: impl FnMut(T) -> ViewNode<Msg>,
) -> ViewNode<Msg> {
    list_for_platform(
        crate::ZsBaseControlPlatformStyle::current(),
        items,
        render,
    )
}

#[cfg(feature = "list")]
pub(crate) fn list_for_platform<T, Msg>(
    platform: crate::ZsBaseControlPlatformStyle,
    items: impl IntoIterator<Item = T>,
    mut render: impl FnMut(T) -> ViewNode<Msg>,
) -> ViewNode<Msg> {
    let metrics = crate::ZsBaseControlMetrics::for_platform(platform);
    let horizontal_inset = crate::ZsuiSpacingTokens::for_platform(platform).sm;
    ViewNode::<Msg>::new(ViewNodeKind::List {
        selected_index: None,
        on_select: None,
    })
    .children(items.into_iter().map(|item| {
        let mut child = render(item);
        child.style.min_height = Some(Dp::new(
            child
                .style
                .min_height
                .map_or(metrics.selection_height.0, |minimum| {
                    minimum.0.max(metrics.selection_height.0)
                }),
        ));
        child.list_item_horizontal_inset = Some(horizontal_inset);
        child
    }))
}

/// Creates a responsive self-drawn collection of selectable gallery tiles.
#[cfg(feature = "grid-view")]
pub fn grid_view<Msg>(items: impl IntoIterator<Item = crate::ZsGridViewItem>) -> ViewNode<Msg> {
    ViewNode::<Msg>::new(ViewNodeKind::GridView {
        items: items.into_iter().collect(),
        selected: None,
        on_select: None,
        on_invoke: None,
    })
}

#[cfg(feature = "tree")]
pub fn tree_view<Msg>(roots: impl IntoIterator<Item = crate::ZsTreeNode>) -> ViewNode<Msg> {
    ViewNode::<Msg>::new(ViewNodeKind::TreeView {
        roots: roots.into_iter().collect(),
        expanded: BTreeSet::new(),
        selected: None,
        on_select: None,
        on_expansion_change: None,
        on_invoke: None,
    })
}

#[cfg(feature = "table")]
pub fn data_grid<Msg>(
    columns: impl IntoIterator<Item = crate::ZsTableColumn>,
    rows: impl IntoIterator<Item = crate::ZsTableRow>,
) -> ViewNode<Msg> {
    ViewNode::<Msg>::new(ViewNodeKind::DataGrid {
        columns: columns.into_iter().collect(),
        rows: rows.into_iter().collect(),
        selected: None,
        sort: None,
        on_select: None,
        on_sort: None,
        on_invoke: None,
    })
}