1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//! Toolbar
mod child;
mod divider;
mod group;
mod item;

pub use child::*;
pub use divider::*;
pub use group::*;
pub use item::*;

use crate::ouia;
use crate::prelude::{AsClasses, ExtendClasses, WithBreakpoints};
use crate::utils::{Ouia, OuiaComponentType, OuiaSafe};
use yew::{html::ChildrenRenderer, prelude::*};

const OUIA: Ouia = ouia!("Toolbar");

/// Modifier for toolbar elements.
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum ToolbarElementModifier {
    Hidden,
    Visible,
    Left,
    Right,
}

impl AsClasses for ToolbarElementModifier {
    fn extend_classes(&self, classes: &mut Classes) {
        classes.push(match self {
            Self::Hidden => "pf-m-hidden",
            Self::Visible => "pf-m-visible",
            Self::Left => "pf-m-align-left", // Only allowed as direct descendants of toolbar...
            Self::Right => "pf-m-align-right", // ^
        });
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ToolbarInset {
    None,
    Small,
    Medium,
    Large,
    XLarge,
    XXLarge,
}

impl AsClasses for ToolbarInset {
    fn extend_classes(&self, classes: &mut Classes) {
        classes.push(match self {
            ToolbarInset::None => "pf-m-inset-none",
            ToolbarInset::Small => "pf-m-inset-sm",
            ToolbarInset::Medium => "pf-m-inset-md",
            ToolbarInset::Large => "pf-m-inset-lg",
            ToolbarInset::XLarge => "pf-m-inset-xl",
            ToolbarInset::XXLarge => "pf-m-inset-2xl",
        });
    }
}

/// Properties for [`Toolbar`]
#[derive(Clone, PartialEq, Properties)]
pub struct ToolbarProperties {
    #[prop_or_default]
    pub class: Classes,

    #[prop_or_default]
    pub children: ChildrenWithProps<ToolbarContent>,

    #[prop_or_default]
    pub id: AttrValue,

    #[prop_or_default]
    pub full_height: bool,

    #[prop_or_default]
    pub insets: WithBreakpoints<ToolbarInset>,

    /// OUIA Component id
    #[prop_or_default]
    pub ouia_id: Option<String>,
    /// OUIA Component Type
    #[prop_or(OUIA.component_type())]
    pub ouia_type: OuiaComponentType,
    /// OUIA Component Safe
    #[prop_or(OuiaSafe::TRUE)]
    pub ouia_safe: OuiaSafe,
}

/// Toolbar component
///
/// > A **toolbar** allows a user to manage and manipulate a data set. Data can be presented in any valid presentation, a table, a list, or a data visualization (chart), for example. The toolbar responsively accommodates controls and displays applied filters in chip groups.
///
/// See: <https://www.patternfly.org/components/toolbar>
///
/// ## Properties
///
/// Defined by [`ToolbarProperties`].
///
/// ## Children
///
/// The toolbar requires one or more [`ToolbarContent`] children.
#[function_component(Toolbar)]
pub fn toolbar(props: &ToolbarProperties) -> Html {
    let ouia_id = use_memo(props.ouia_id.clone(), |id| {
        id.clone().unwrap_or(OUIA.generated_id())
    });
    let mut class = classes!("pf-v5-c-toolbar", props.class.clone());
    class.extend_from(&props.insets);

    if props.full_height {
        class.push("pf-m-full-height")
    }

    html! (
        <div
            id={&props.id}
            {class}
            data-ouia-component-id={(*ouia_id).clone()}
            data-ouia-component-type={props.ouia_type}
            data-ouia-safe={props.ouia_safe}
        >
            { for props.children.iter() }
        </div>
    )
}

/// Properties for [`Toolbar`]
#[derive(Clone, PartialEq, Properties)]
pub struct ToolbarContentProperties {
    #[prop_or_default]
    pub children: ChildrenRenderer<ToolbarChildVariant>,

    #[prop_or_default]
    pub id: AttrValue,
}

#[function_component(ToolbarContent)]
pub fn toolbar_content(props: &ToolbarContentProperties) -> Html {
    html! (
        <div class="pf-v5-c-toolbar__content" id={&props.id}>
            <div class="pf-v5-c-toolbar__content-section">
                { for props.children.iter() }
            </div>
        </div>
    )
}