input: Improve clear button position in Input. (#782)
| Before | After | | -- | -- | | <img width="529" alt="image" src="https://github.com/user-attachments/assets/02fdba71-7e83-43b9-ba4c-476eb21dcf28" /> | <img width="530" alt="image" src="https://github.com/user-attachments/assets/ad7b6378-c9ff-4ea4-943a-87af53a2ac79" /> |
This commit is contained in:
parent
d04866eb77
commit
73be54a0f7
6 changed files with 63 additions and 31 deletions
|
|
@ -11,7 +11,7 @@ use gpui_component::{
|
|||
checkbox::Checkbox,
|
||||
h_flex,
|
||||
input::{InputEvent, NumberInput, NumberInputEvent, OtpInput, StepAction, TextInput},
|
||||
v_flex, FocusableCycle, IconName, Sizable,
|
||||
v_flex, FocusableCycle, Icon, IconName, Sizable,
|
||||
};
|
||||
|
||||
actions!(input_story, [Tab, TabPrev]);
|
||||
|
|
@ -139,21 +139,33 @@ impl InputStory {
|
|||
|
||||
let prefix_input1 = cx.new(|cx| {
|
||||
TextInput::new(window, cx)
|
||||
.prefix(|_, _| div().child(IconName::Search).ml_3())
|
||||
.prefix(|_, _| div().child(Icon::new(IconName::Search).small()).ml_3())
|
||||
.placeholder("Search some thing...")
|
||||
.cleanable()
|
||||
});
|
||||
let suffix_input1 = cx.new(|cx| {
|
||||
TextInput::new(window, cx)
|
||||
.suffix(|_, _| div().child(IconName::Info).mr_3())
|
||||
.suffix(|_, _| {
|
||||
Button::new("info")
|
||||
.ghost()
|
||||
.icon(IconName::Info)
|
||||
.xsmall()
|
||||
.mr_3()
|
||||
})
|
||||
.placeholder("This input only support [a-zA-Z0-9] characters.")
|
||||
.pattern(regex::Regex::new(r"^[a-zA-Z0-9]*$").unwrap())
|
||||
.cleanable()
|
||||
});
|
||||
let both_input1 = cx.new(|cx| {
|
||||
TextInput::new(window, cx)
|
||||
.prefix(|_, _| div().child(IconName::Search).ml_3())
|
||||
.suffix(|_, _| div().child(IconName::Info).mr_3())
|
||||
.prefix(|_, _| div().child(Icon::new(IconName::Search).small()).ml_3())
|
||||
.suffix(|_, _| {
|
||||
Button::new("info")
|
||||
.ghost()
|
||||
.icon(IconName::Info)
|
||||
.xsmall()
|
||||
.mr_3()
|
||||
})
|
||||
.cleanable()
|
||||
.placeholder("This input have prefix and suffix.")
|
||||
});
|
||||
|
|
|
|||
|
|
@ -149,3 +149,9 @@ Modal:
|
|||
zh-CN: 取消
|
||||
zh-HK: 取消
|
||||
it: Annulla
|
||||
List:
|
||||
search_placeholder:
|
||||
en: Search...
|
||||
zh-CN: 搜索...
|
||||
zh-HK: 搜索...
|
||||
it: Ricerca...
|
||||
|
|
|
|||
|
|
@ -355,6 +355,7 @@ impl RenderOnce for Button {
|
|||
|
||||
self.base
|
||||
.id(self.id)
|
||||
.cursor_default()
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ use crate::history::History;
|
|||
use crate::indicator::Indicator;
|
||||
use crate::input::clear_button;
|
||||
use crate::scroll::{Scrollbar, ScrollbarAxis, ScrollbarState};
|
||||
use crate::StyledExt;
|
||||
use crate::{h_flex, StyledExt};
|
||||
use crate::{ActiveTheme, Root};
|
||||
use crate::{IconName, Size};
|
||||
use crate::{Sizable, StyleSized};
|
||||
|
|
@ -1756,6 +1756,13 @@ impl Render for TextInput {
|
|||
|
||||
let prefix = self.prefix.as_ref().map(|build| build(window, cx));
|
||||
let suffix = self.suffix.as_ref().map(|build| build(window, cx));
|
||||
let show_clear_button =
|
||||
self.cleanable && !self.loading && !self.text.is_empty() && self.is_single_line();
|
||||
let bg = if self.disabled {
|
||||
cx.theme().muted
|
||||
} else {
|
||||
cx.theme().background
|
||||
};
|
||||
|
||||
div()
|
||||
.flex()
|
||||
|
|
@ -1815,40 +1822,45 @@ impl Render for TextInput {
|
|||
.when_some(self.height, |this, height| this.h(height))
|
||||
})
|
||||
.when(self.appearance, |this| {
|
||||
this.bg(if self.disabled {
|
||||
cx.theme().muted
|
||||
} else {
|
||||
cx.theme().background
|
||||
})
|
||||
.border_color(cx.theme().input)
|
||||
.border_1()
|
||||
.rounded(cx.theme().radius)
|
||||
.when(cx.theme().shadow, |this| this.shadow_sm())
|
||||
.when(focused, |this| this.focused_border(cx))
|
||||
this.bg(bg)
|
||||
.border_color(cx.theme().input)
|
||||
.border_1()
|
||||
.rounded(cx.theme().radius)
|
||||
.when(cx.theme().shadow, |this| this.shadow_sm())
|
||||
.when(focused, |this| this.focused_border(cx))
|
||||
})
|
||||
.when(prefix.is_none(), |this| this.input_pl(self.size))
|
||||
.when(suffix.is_none(), |this| this.input_pr(self.size))
|
||||
.children(prefix)
|
||||
.gap(gap_x)
|
||||
.input_pr(self.size)
|
||||
.items_center()
|
||||
.gap(gap_x)
|
||||
.children(prefix)
|
||||
.child(
|
||||
div()
|
||||
.id("TextElement")
|
||||
.id("text-element")
|
||||
.flex_1()
|
||||
.when(self.is_multi_line(), |this| this.h_full())
|
||||
.flex_grow()
|
||||
.overflow_x_hidden()
|
||||
.child(TextElement::new(cx.entity().clone())),
|
||||
)
|
||||
.when(self.loading, |this| {
|
||||
this.child(Indicator::new().color(cx.theme().muted_foreground))
|
||||
})
|
||||
.children(self.render_toggle_mask_button(window, cx))
|
||||
.when(
|
||||
self.cleanable && !self.loading && !self.text.is_empty() && self.is_single_line(),
|
||||
|this| this.child(clear_button(cx).on_click(cx.listener(Self::clean))),
|
||||
.child(
|
||||
h_flex()
|
||||
.id("suffix")
|
||||
.absolute()
|
||||
.gap(gap_x)
|
||||
.bg(bg)
|
||||
.items_center()
|
||||
.when(suffix.is_none(), |this| this.pr_1())
|
||||
.right_0()
|
||||
.when(self.loading, |this| {
|
||||
this.child(Indicator::new().color(cx.theme().muted_foreground))
|
||||
})
|
||||
.children(self.render_toggle_mask_button(window, cx))
|
||||
.when(show_clear_button, |this| {
|
||||
this.child(clear_button(cx).on_click(cx.listener(Self::clean)))
|
||||
})
|
||||
.children(suffix),
|
||||
)
|
||||
.children(suffix)
|
||||
.when(self.is_multi_line(), |this| {
|
||||
let entity_id = cx.entity().entity_id();
|
||||
if self.last_layout.is_some() {
|
||||
|
|
|
|||
|
|
@ -164,8 +164,8 @@ impl Render for NumberInput {
|
|||
// Sync size to input at first.
|
||||
self.sync_size_to_input_if_needed(window, cx);
|
||||
let btn_size = match self.size {
|
||||
Size::XSmall | Size::Small => Size::XSmall,
|
||||
_ => Size::Small,
|
||||
Size::XSmall | Size::Small => Size::Size(px(16.)),
|
||||
_ => Size::XSmall,
|
||||
};
|
||||
|
||||
h_flex()
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use gpui::{
|
|||
Window,
|
||||
};
|
||||
use gpui::{px, App, Context, EventEmitter, MouseDownEvent, ScrollStrategy, Subscription};
|
||||
use rust_i18n::t;
|
||||
use smol::Timer;
|
||||
|
||||
use super::loading::Loading;
|
||||
|
|
@ -173,7 +174,7 @@ where
|
|||
TextInput::new(window, cx)
|
||||
.appearance(false)
|
||||
.prefix(|_, cx| Icon::new(IconName::Search).text_color(cx.theme().muted_foreground))
|
||||
.placeholder("Search...")
|
||||
.placeholder(t!("List.search_placeholder"))
|
||||
.cleanable()
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue