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
use crate::prelude::*;
use yew::prelude::*;

#[derive(Clone, Debug, PartialEq, Properties)]
pub struct MenuToggleProperties {
    #[prop_or_default]
    pub r#ref: NodeRef,

    #[prop_or_default]
    pub text: Option<String>,

    #[prop_or_default]
    pub icon: Option<Html>,

    #[prop_or_default]
    pub aria_label: AttrValue,

    #[prop_or_default]
    pub expanded: bool,

    #[prop_or_default]
    pub disabled: bool,

    #[prop_or_default]
    pub full_height: bool,

    #[prop_or_default]
    pub full_width: bool,

    #[prop_or_default]
    pub variant: MenuToggleVariant,

    #[prop_or_default]
    pub ontoggle: Callback<()>,

    #[prop_or_default]
    pub children: Html,
}

#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
pub enum MenuToggleVariant {
    #[default]
    Default,
    Plain,
    Primary,
    Secondary,
}

impl AsClasses for MenuToggleVariant {
    fn extend_classes(&self, classes: &mut Classes) {
        match self {
            Self::Default => {}
            Self::Primary => classes.push(classes!("pf-m-primary")),
            Self::Secondary => classes.push(classes!("pf-m-secondary")),
            Self::Plain => classes.push(classes!("pf-m-plain")),
        }
    }
}

/// Menu toggle component
///
/// See: <https://www.patternfly.org/components/menus/menu-toggle>
///
/// ## Properties
///
/// Defined by [`MenuToggleProperties`].
#[function_component(MenuToggle)]
pub fn menu_toggle(props: &MenuToggleProperties) -> Html {
    let mut class = classes!("pf-v5-c-menu-toggle");

    if props.expanded {
        class.push(classes!("pf-m-expanded"));
    }

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

    if props.full_width {
        class.push(classes!("pf-m-full-width"));
    }

    if matches!(props.variant, MenuToggleVariant::Plain) && props.text.is_some() {
        class.push(classes!("pf-m-text"));
    }

    class.extend_from(&props.variant);

    let plain = matches!(props.variant, MenuToggleVariant::Plain);
    let text = props.text.is_some();

    html!(
        <button
            ref={props.r#ref.clone()}
            {class}
            type="button"
            disabled={ props.disabled }
            aria-expanded={ props.expanded.to_string() }
            aria-label={ &props.aria_label }
            onclick={ props.ontoggle.reform(|_|()) }
        >
            if let Some(icon) = &props.icon {
                if plain && !text{
                    // if we just have an icon, don't wrap it
                    { icon.clone() }
                } else {
                    <span class="pf-v5-c-menu-toggle__icon">{ icon.clone() }</span>
                }
            }
            if let Some(text) = &props.text {
                <span class="pf-v5-c-menu-toggle__text">{ text }</span>
            }

            if !plain || text {
                // if we have more than just a plain icon, add the toggle control
                <span class="pf-v5-c-menu-toggle__controls">
                    <span class="pf-v5-c-menu-toggle__toggle-icon">
                        <i class="fas fa-caret-down" aria-hidden="true"></i>
                    </span>
                </span>
            }

            { props.children.clone() }

        </button>
    )
}