//! ContextMenu checkbox and radio components //! //! This module contains the ContextMenuCheckboxItem, ContextMenuRadioGroup, //! and ContextMenuRadioItem components for interactive menu items. use leptos::prelude::*; use leptos_style::Style; use web_sys::MouseEvent; #[component] pub fn ContextMenuCheckboxItem( #[prop(into)] checked: RwSignal, #[prop(into, optional)] on_checked_change: Option>, #[prop(into, optional)] class: MaybeProp, #[prop(into, optional)] id: MaybeProp, #[prop(into, optional)] style: MaybeProp, #[prop(into, optional)] disabled: MaybeProp, #[prop(optional)] children: Option, ) -> impl IntoView { let open = expect_context::>(); let handle_click = move |e: MouseEvent| { if !disabled.get().unwrap_or(false) { e.stop_propagation(); let new_checked = !checked.get(); checked.set(new_checked); if let Some(callback) = &on_checked_change { callback.run(new_checked); } open.set(false); } }; let item_class = move || { let base_class = "context-menu-checkbox-item"; let checked_class = if checked.get() { " checked" } else { "" }; let disabled_class = if disabled.get().unwrap_or(false) { " disabled" } else { "" }; let custom_class = class.get().unwrap_or_default(); format!("{}{}{} {}", base_class, checked_class, disabled_class, custom_class) }; view! {
{children.map(|c| c())}
} } #[component] pub fn ContextMenuRadioGroup( #[prop(into)] value: RwSignal, #[prop(into, optional)] on_value_change: Option>, #[prop(into, optional)] class: MaybeProp, #[prop(optional)] children: Option, ) -> impl IntoView { provide_context(value); provide_context(on_value_change); view! {
{children.map(|c| c())}
} } #[component] pub fn ContextMenuRadioItem( #[prop(into)] value: String, #[prop(into, optional)] class: MaybeProp, #[prop(into, optional)] id: MaybeProp, #[prop(into, optional)] style: MaybeProp, #[prop(into, optional)] disabled: MaybeProp, #[prop(optional)] children: Option, ) -> impl IntoView { let open = expect_context::>(); let group_value = expect_context::>(); let on_value_change = expect_context::>>(); let value_clone = value.clone(); let is_selected = Signal::derive(move || group_value.get() == value_clone); let handle_click = move |e: MouseEvent| { if !disabled.get().unwrap_or(false) { e.stop_propagation(); group_value.set(value.clone()); if let Some(callback) = &on_value_change { callback.run(value.clone()); } open.set(false); } }; let item_class = move || { let base_class = "context-menu-radio-item"; let selected_class = if is_selected.get() { " selected" } else { "" }; let disabled_class = if disabled.get().unwrap_or(false) { " disabled" } else { "" }; let custom_class = class.get().unwrap_or_default(); format!("{}{}{} {}", base_class, selected_class, disabled_class, custom_class) }; view! {
{children.map(|c| c())}
} }