impulse_thaw/menu/
menu_item.rs

1use crate::{Icon, MenuInjection};
2use leptos::prelude::*;
3use thaw_components::{Fallback, If, OptionComp, Then};
4use thaw_utils::{class_list, mount_style};
5
6#[component]
7pub fn MenuItem(
8    #[prop(optional, into)] class: MaybeProp<String>,
9    /// The icon of the menu item.
10    #[prop(optional, into)]
11    icon: MaybeProp<icondata_core::Icon>,
12    /// The value of the menu item.
13    #[prop(into)]
14    value: Signal<String>,
15    /// Whether the menu item is disabled.
16    #[prop(optional, into)]
17    disabled: Signal<bool>,
18    children: Children,
19) -> impl IntoView {
20    mount_style("menu-item", include_str!("./menu-item.css"));
21
22    let MenuInjection {
23        has_icon,
24        on_select,
25    } = MenuInjection::expect_context();
26
27    if icon.with_untracked(|i| i.is_some()) {
28        has_icon.set(true);
29    }
30
31    let on_click = move |_| {
32        if disabled.get_untracked() {
33            return;
34        }
35
36        on_select(value.get_untracked());
37    };
38
39    view! {
40        <div
41            class=class_list![
42                "thaw-menu-item", ("thaw-menu-item--disabled", move || disabled.get()),
43                class
44            ]
45            on:click=on_click
46        >
47
48            <OptionComp value=icon.get() let:icon>
49                <Fallback slot>
50                    <If cond=has_icon>
51                        <Then slot>
52                            <span style="width: 18px; margin-right: 8px"></span>
53                        </Then>
54                    </If>
55                </Fallback>
56
57                <Icon icon=icon style="font-size: 18px; margin-right: 8px" />
58            </OptionComp>
59            <span style="flex-grow: 1">{children()}</span>
60        </div>
61    }
62}