input: Add Esc to clean. (#803)
This commit is contained in:
parent
7719d8b6fc
commit
f7be6a245a
3 changed files with 48 additions and 17 deletions
|
|
@ -1,9 +1,5 @@
|
|||
use gpui::*;
|
||||
use gpui_component::{
|
||||
alert::Alert,
|
||||
button::{Button, ButtonGroup},
|
||||
v_flex, IconName, Selectable as _, Sizable as _, Size,
|
||||
};
|
||||
|
||||
use story::{AlertStory, Assets};
|
||||
|
||||
pub struct Example {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use gpui_component::{
|
|||
button::{Button, ButtonVariant, ButtonVariants as _},
|
||||
h_flex,
|
||||
input::{InputEvent, TextInput},
|
||||
v_flex, FocusableCycle, Icon, IconName, Sizable, StyledExt,
|
||||
v_flex, FocusableCycle, Icon, IconName, Sizable,
|
||||
};
|
||||
|
||||
actions!(input_story, [Tab, TabPrev]);
|
||||
|
|
@ -26,6 +26,7 @@ pub fn init(cx: &mut App) {
|
|||
pub struct InputStory {
|
||||
input1: Entity<TextInput>,
|
||||
input2: Entity<TextInput>,
|
||||
input_esc: Entity<TextInput>,
|
||||
mask_input: Entity<TextInput>,
|
||||
disabled_input: Entity<TextInput>,
|
||||
prefix_input1: Entity<TextInput>,
|
||||
|
|
@ -68,6 +69,12 @@ impl InputStory {
|
|||
});
|
||||
|
||||
let input2 = cx.new(|cx| TextInput::new(window, cx).placeholder("Enter text here..."));
|
||||
let input_esc = cx.new(|cx| {
|
||||
TextInput::new(window, cx)
|
||||
.placeholder("Enter text and clear it by pressing ESC")
|
||||
.cleanable()
|
||||
.clean_on_escape()
|
||||
});
|
||||
|
||||
let mask_input = cx.new(|cx| {
|
||||
let mut input = TextInput::new(window, cx)
|
||||
|
|
@ -119,6 +126,7 @@ impl InputStory {
|
|||
Self {
|
||||
input1,
|
||||
input2,
|
||||
input_esc,
|
||||
mask_input,
|
||||
disabled_input: cx.new(|cx| {
|
||||
let mut input = TextInput::new(window, cx);
|
||||
|
|
@ -173,6 +181,7 @@ impl FocusableCycle for InputStory {
|
|||
[
|
||||
self.input1.focus_handle(cx),
|
||||
self.input2.focus_handle(cx),
|
||||
self.input_esc.focus_handle(cx),
|
||||
self.disabled_input.focus_handle(cx),
|
||||
self.mask_input.focus_handle(cx),
|
||||
self.prefix_input1.focus_handle(cx),
|
||||
|
|
@ -202,21 +211,18 @@ impl Render for InputStory {
|
|||
.gap_3()
|
||||
.child(
|
||||
section("Normal Input")
|
||||
.v_flex()
|
||||
.max_w_md()
|
||||
.child(self.input1.clone())
|
||||
.child(self.input2.clone()),
|
||||
)
|
||||
.child(
|
||||
section("Input State")
|
||||
.v_flex()
|
||||
.max_w_md()
|
||||
.child(self.disabled_input.clone())
|
||||
.child(self.mask_input.clone()),
|
||||
)
|
||||
.child(
|
||||
section("Prefix and Suffix")
|
||||
.v_flex()
|
||||
.max_w_md()
|
||||
.child(self.prefix_input1.clone())
|
||||
.child(self.both_input1.clone())
|
||||
|
|
@ -224,11 +230,15 @@ impl Render for InputStory {
|
|||
)
|
||||
.child(
|
||||
section("Input Size")
|
||||
.v_flex()
|
||||
.max_w_md()
|
||||
.child(self.large_input.clone())
|
||||
.child(self.small_input.clone()),
|
||||
)
|
||||
.child(
|
||||
section("Cleanable and ESC to clean")
|
||||
.max_w_md()
|
||||
.child(self.input_esc.clone()),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.items_center()
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ use unicode_segmentation::*;
|
|||
use gpui::prelude::FluentBuilder as _;
|
||||
use gpui::{
|
||||
actions, div, impl_internal_actions, point, px, relative, AnyElement, App, AppContext, Bounds,
|
||||
ClickEvent, ClipboardItem, Context, DefiniteLength, Entity, EntityInputHandler, EventEmitter,
|
||||
FocusHandle, Focusable, InteractiveElement as _, IntoElement, KeyBinding, KeyDownEvent,
|
||||
MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point,
|
||||
Rems, Render, ScrollHandle, ScrollWheelEvent, SharedString, Styled as _, Subscription,
|
||||
UTF16Selection, Window, WrappedLine,
|
||||
ClipboardItem, Context, DefiniteLength, Entity, EntityInputHandler, EventEmitter, FocusHandle,
|
||||
Focusable, InteractiveElement as _, IntoElement, KeyBinding, KeyDownEvent, MouseButton,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point, Rems, Render,
|
||||
ScrollHandle, ScrollWheelEvent, SharedString, Styled as _, Subscription, UTF16Selection,
|
||||
Window, WrappedLine,
|
||||
};
|
||||
|
||||
// TODO:
|
||||
|
|
@ -85,6 +85,7 @@ actions!(
|
|||
MoveToPreviousWord,
|
||||
MoveToNextWord,
|
||||
TextChanged,
|
||||
Escape
|
||||
]
|
||||
);
|
||||
|
||||
|
|
@ -116,6 +117,7 @@ pub fn init(cx: &mut App) {
|
|||
KeyBinding::new("ctrl-delete", DeleteToNextWordEnd, Some(CONTEXT)),
|
||||
KeyBinding::new("enter", Enter { secondary: false }, Some(CONTEXT)),
|
||||
KeyBinding::new("secondary-enter", Enter { secondary: true }, Some(CONTEXT)),
|
||||
KeyBinding::new("escape", Escape, Some(CONTEXT)),
|
||||
KeyBinding::new("up", Up, Some(CONTEXT)),
|
||||
KeyBinding::new("down", Down, Some(CONTEXT)),
|
||||
KeyBinding::new("left", Left, Some(CONTEXT)),
|
||||
|
|
@ -233,6 +235,7 @@ pub struct TextInput {
|
|||
pub(super) mask_toggle: bool,
|
||||
pub(super) appearance: bool,
|
||||
pub(super) cleanable: bool,
|
||||
pub(super) clean_on_escape: bool,
|
||||
pub(super) size: Size,
|
||||
pub(super) rows: usize,
|
||||
pub(super) min_rows: usize,
|
||||
|
|
@ -295,6 +298,7 @@ impl TextInput {
|
|||
mask_toggle: false,
|
||||
appearance: true,
|
||||
cleanable: false,
|
||||
clean_on_escape: false,
|
||||
loading: false,
|
||||
prefix: None,
|
||||
suffix: None,
|
||||
|
|
@ -662,6 +666,12 @@ impl TextInput {
|
|||
self
|
||||
}
|
||||
|
||||
/// Set true to clear the input by pressing Escape key.
|
||||
pub fn clean_on_escape(mut self) -> Self {
|
||||
self.clean_on_escape = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set true to not use gap between input and prefix, suffix, and clear button.
|
||||
///
|
||||
/// Default: false
|
||||
|
|
@ -1059,10 +1069,20 @@ impl TextInput {
|
|||
cx.notify();
|
||||
}
|
||||
|
||||
fn clean(&mut self, _: &ClickEvent, window: &mut Window, cx: &mut Context<Self>) {
|
||||
fn clean(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.replace_text("", window, cx);
|
||||
}
|
||||
|
||||
fn escape(&mut self, _: &Escape, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if self.selected_range.len() > 0 {
|
||||
return self.unselect(window, cx);
|
||||
}
|
||||
|
||||
if self.clean_on_escape {
|
||||
self.clean(window, cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn on_mouse_down(
|
||||
&mut self,
|
||||
event: &MouseDownEvent,
|
||||
|
|
@ -1788,6 +1808,7 @@ impl Render for TextInput {
|
|||
.on_action(cx.listener(Self::delete_previous_word))
|
||||
.on_action(cx.listener(Self::delete_next_word))
|
||||
.on_action(cx.listener(Self::enter))
|
||||
.on_action(cx.listener(Self::escape))
|
||||
})
|
||||
.on_action(cx.listener(Self::left))
|
||||
.on_action(cx.listener(Self::right))
|
||||
|
|
@ -1868,7 +1889,11 @@ impl Render for TextInput {
|
|||
})
|
||||
.children(self.render_toggle_mask_button(window, cx))
|
||||
.when(show_clear_button, |this| {
|
||||
this.child(clear_button(cx).on_click(cx.listener(Self::clean)))
|
||||
this.child(
|
||||
clear_button(cx).on_click(cx.listener(|view, _, window, cx| {
|
||||
view.clean(window, cx);
|
||||
})),
|
||||
)
|
||||
})
|
||||
.children(suffix),
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue