patternfly_yew/components/menu/
context.rs

1use yew::prelude::*;
2
3/// A context to request a menu to close.
4///
5/// This is intended to be used by components implementing a drop-down style menu, where clicking
6/// on a menu entry is intended to close the menu.
7#[derive(Clone, PartialEq)]
8pub struct CloseMenuContext {
9    onclose: Callback<()>,
10}
11
12impl CloseMenuContext {
13    pub fn new(onclose: Callback<()>) -> Self {
14        Self { onclose }
15    }
16
17    /// Close the expanded menu
18    pub fn close(&self) {
19        self.onclose.emit(());
20    }
21}
22
23/// Access the menu context.
24///
25/// This will only return a non-none value when called from a component nested in a component
26/// supporting this context.
27#[hook]
28pub fn use_close_menu_context() -> Option<CloseMenuContext> {
29    use_context()
30}
31
32#[derive(Clone, PartialEq)]
33pub struct UseCloseMenu {
34    pub context: Option<CloseMenuContext>,
35}
36
37impl UseCloseMenu {
38    pub fn close(&self) {
39        if let Some(context) = &self.context {
40            context.close();
41        } else {
42            log::warn!("Ignored request to close menu: no context was found")
43        }
44    }
45}
46
47/// Allow closing the menu.
48///
49/// **NOTE**: If the hook is used inside a component which is not wrapped with a component
50/// providing a [`CloseMenuContext`], then all operations become a no-op.
51#[hook]
52pub fn use_close_menu() -> UseCloseMenu {
53    UseCloseMenu {
54        context: use_context(),
55    }
56}
57
58/// Provide a stable callback for closing the menu.
59///
60/// **NOTE**: If the hook is used inside a component which is not wrapped with a component
61/// providing a [`CloseMenuContext`], then all operations become a no-op.
62#[hook]
63pub fn use_close_menu_callback() -> Callback<()> {
64    let context = use_close_menu();
65    use_callback(context, |(), context| context.close())
66}