From 5aad0bf3407572408e026512f1060ce7ef92a968 Mon Sep 17 00:00:00 2001 From: ihavecoke Date: Fri, 8 Nov 2024 13:50:05 +0800 Subject: [PATCH] modal: Add `keyboard` option to Modal to enable/disable default keyboard event. (#400) --- crates/story/src/modal_story.rs | 13 +++++++++++++ crates/ui/src/modal.rs | 30 ++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/crates/story/src/modal_story.rs b/crates/story/src/modal_story.rs index 508404b8..4ddf0d38 100644 --- a/crates/story/src/modal_story.rs +++ b/crates/story/src/modal_story.rs @@ -154,6 +154,7 @@ pub struct ModalStory { modal_overlay: bool, model_show_close: bool, model_padding: bool, + model_keyboard: bool, } impl super::Story for ModalStory { @@ -274,6 +275,7 @@ impl ModalStory { modal_overlay: true, model_show_close: true, model_padding: true, + model_keyboard: true, } } @@ -335,11 +337,13 @@ impl ModalStory { let date_picker = self.date_picker.clone(); let dropdown = self.dropdown.clone(); let view = cx.view().clone(); + let keyboard = self.model_keyboard; cx.open_modal(move |modal, _| { modal .title("Form Modal") .overlay(overlay) + .keyboard(keyboard) .show_close(modal_show_close) .when(!modal_padding, |this| this.p(px(0.))) .child( @@ -448,6 +452,15 @@ impl Render for ModalStory { view.model_padding = !view.model_padding; cx.notify(); })), + ) + .child( + Checkbox::new("modal-keyboard") + .label("Keyboard") + .checked(self.model_keyboard) + .on_click(cx.listener(|view, _, cx| { + view.model_keyboard = !view.model_keyboard; + cx.notify(); + })), ), ) .child( diff --git a/crates/ui/src/modal.rs b/crates/ui/src/modal.rs index 1cd5e380..8aa7e228 100644 --- a/crates/ui/src/modal.rs +++ b/crates/ui/src/modal.rs @@ -34,6 +34,7 @@ pub struct Modal { on_close: Rc, show_close: bool, overlay: bool, + keyboard: bool, /// This will be change when open the modal, the focus handle is create when open the modal. pub(crate) focus_handle: FocusHandle, @@ -75,6 +76,7 @@ impl Modal { width: px(480.), max_width: None, overlay: true, + keyboard: true, layer_ix: 0, overlay_visible: true, on_close: Rc::new(|_, _| {}), @@ -133,6 +135,12 @@ impl Modal { self } + /// Set whether to support keyboard esc to close the modal, defaults to `true`. + pub fn keyboard(mut self, keyboard: bool) -> Self { + self.keyboard = keyboard; + self + } + pub(crate) fn has_overlay(&self) -> bool { self.overlay } @@ -185,16 +193,18 @@ impl RenderOnce for Modal { .id(SharedString::from(format!("modal-{layer_ix}"))) .key_context(CONTEXT) .track_focus(&self.focus_handle) - .on_action({ - let on_close = self.on_close.clone(); - move |_: &Escape, cx| { - // FIXME: - // - // Here some Modal have no focus_handle, so it will not work will Escape key. - // But by now, we `cx.close_modal()` going to close the last active model, so the Escape is unexpected to work. - on_close(&ClickEvent::default(), cx); - cx.close_modal(); - } + .when(self.keyboard, |this| { + this.on_action({ + let on_close = self.on_close.clone(); + move |_: &Escape, cx| { + // FIXME: + // + // Here some Modal have no focus_handle, so it will not work will Escape key. + // But by now, we `cx.close_modal()` going to close the last active model, so the Escape is unexpected to work. + on_close(&ClickEvent::default(), cx); + cx.close_modal(); + } + }) }) .absolute() .occlude()