zu/stack/
mod.rs

1// Copyright (c) 2024 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
2// Use of this source is governed by Lesser General Public License
3// that can be found in the LICENSE file.
4
5mod spacing;
6
7use yew::{classes, function_component, html, AttrValue, Children, Classes, Html, Properties};
8use zu_util::prop::ToAttr;
9
10use crate::styles::flex_direction::FlexDirection;
11use crate::styles::spacing::Spacing;
12use crate::styles::CssClass;
13
14#[derive(Debug, Clone, PartialEq, Properties)]
15pub struct Props {
16    #[prop_or_default]
17    pub children: Children,
18
19    #[prop_or_default]
20    pub classes: Classes,
21
22    /// Default value is `div`.
23    #[prop_or(AttrValue::from("div"))]
24    pub component: AttrValue,
25
26    /// Defines the flex-direction style property.
27    #[prop_or_default]
28    pub direction: FlexDirection,
29
30    /// Add an element between each child.
31    #[prop_or_default]
32    pub divider: Html,
33
34    /// Defines the space between immediate children.
35    ///
36    /// Default is 0.
37    #[prop_or_default]
38    // TODO(Shaohua): Replace with i32, margin = spacing * 8px.
39    pub spacing: Spacing,
40
41    #[prop_or_default]
42    pub style: AttrValue,
43
44    /// If true, the CSS flexbox gap is used instead of applying margin to children.
45    #[prop_or(false)]
46    pub use_flex_gap: bool,
47}
48
49#[function_component(Stack)]
50pub fn stack(props: &Props) -> Html {
51    let root_cls = classes!(
52        "ZuStack-root",
53        props.direction.css_class(),
54        spacing::css_cls(props.spacing),
55        props.classes.clone(),
56    );
57
58    // TODO(Shaohua): Add divider elements
59
60    html! {
61        <@{props.component.to_string()}
62            class={root_cls}
63            style={props.style.to_attr()}>
64            {for props.children.iter()}
65        </@>
66    }
67}