number_input: Improve style details (#1606)

| Before | After |
| - | - |
| <img width="401" height="120" alt="SCR-20251114-pmci"
src="https://github.com/user-attachments/assets/75e3936c-1366-4ab1-a70a-164c47826002"
/> <img width="402" height="120" alt="SCR-20251114-pmef"
src="https://github.com/user-attachments/assets/224ca715-4131-4be5-ae4f-d70708463469"
/> | <img width="395" height="120" alt="SCR-20251114-plul"
src="https://github.com/user-attachments/assets/4b68c697-74da-4618-8f1a-fff57273378d"
/> <img width="397" height="118" alt="SCR-20251114-plwi"
src="https://github.com/user-attachments/assets/94d30c02-19e2-4fd7-916e-6e15d100c331"
/> |
This commit is contained in:
Floyd Wang 2025-11-14 18:01:40 +08:00 committed by GitHub
parent 78efbfdd7b
commit 542346f3c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 47 additions and 32 deletions

View file

@ -1,14 +1,15 @@
use gpui::{
div, App, AppContext as _, Context, Entity, Focusable, InteractiveElement, IntoElement,
App, AppContext as _, Context, Entity, Focusable, InteractiveElement, IntoElement,
ParentElement as _, Render, Styled, Subscription, Window,
};
use regex::Regex;
use crate::section;
use gpui_component::{
ActiveTheme, Disableable, IconName, Sizable,
button::{Button, ButtonVariants},
input::{InputEvent, InputState, MaskPattern, NumberInput, NumberInputEvent, StepAction},
v_flex, ActiveTheme, Disableable, IconName, Sizable,
v_flex,
};
pub fn init(_: &mut App) {}
@ -245,11 +246,9 @@ impl Render for NumberInputStory {
)
.child(
section("Without appearance").max_w_md().child(
div()
.w_full()
.bg(cx.theme().secondary)
.rounded_md()
.child(NumberInput::new(&self.number_input4).appearance(false)),
NumberInput::new(&self.number_input4)
.appearance(false)
.bg(cx.theme().secondary),
),
)
}

View file

@ -1,12 +1,11 @@
use gpui::{
actions, prelude::FluentBuilder as _, px, AnyElement, App, Context, Entity, EventEmitter,
FocusHandle, Focusable, InteractiveElement, IntoElement, KeyBinding, ParentElement, RenderOnce,
SharedString, StyleRefinement, Styled, Window,
actions, prelude::FluentBuilder as _, AnyElement, App, Context, Corners, Edges, Entity,
EventEmitter, FocusHandle, Focusable, InteractiveElement, IntoElement, KeyBinding,
ParentElement, RenderOnce, SharedString, StyleRefinement, Styled, Window,
};
use crate::{
button::{Button, ButtonVariants as _},
h_flex, ActiveTheme, Disableable, IconName, Sizable, Size, StyleSized, StyledExt as _,
button::Button, h_flex, ActiveTheme, Disableable, IconName, Sizable, Size, StyledExt as _,
};
use super::{Input, InputState};
@ -75,12 +74,14 @@ impl NumberInput {
fn on_increment(state: &Entity<InputState>, window: &mut Window, cx: &mut App) {
state.update(cx, |state, cx| {
state.focus(window, cx);
state.on_action_increment(&Increment, window, cx);
})
}
fn on_decrement(state: &Entity<InputState>, window: &mut Window, cx: &mut App) {
state.update(cx, |state, cx| {
state.focus(window, cx);
state.on_action_decrement(&Decrement, window, cx);
})
}
@ -142,33 +143,35 @@ impl Styled for NumberInput {
impl RenderOnce for NumberInput {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
let focused = self.state.focus_handle(cx).is_focused(window);
h_flex()
.id(("number-input", self.state.entity_id()))
.key_context(CONTEXT)
.on_action(window.listener_for(&self.state, InputState::on_action_increment))
.on_action(window.listener_for(&self.state, InputState::on_action_decrement))
.flex_1()
.input_size(self.size)
.px(self.size.input_px() / 2.)
.when(self.appearance, |this| {
this.bg(cx.theme().background)
.border_color(cx.theme().input)
.border_1()
.rounded(cx.theme().radius)
.refine_style(&self.style)
})
.rounded(cx.theme().radius)
.refine_style(&self.style)
.when(self.disabled, |this| this.bg(cx.theme().muted))
.when(focused, |this| this.focused_border(cx))
.child(
Button::new("-")
.ghost()
.with_size(self.size.smaller())
.outline()
.with_size(self.size)
.icon(IconName::Minus)
.compact()
.tab_stop(false)
.disabled(self.disabled)
.border_corners(Corners {
top_left: true,
top_right: false,
bottom_right: false,
bottom_left: true,
})
.border_edges(Edges {
top: self.appearance,
right: false,
bottom: self.appearance,
left: self.appearance,
})
.on_click({
let state = self.state.clone();
move |_, window, cx| {
@ -178,21 +181,34 @@ impl RenderOnce for NumberInput {
)
.child(
Input::new(&self.state)
.appearance(false)
.appearance(self.appearance)
.with_size(self.size)
.disabled(self.disabled)
.px(px(2.))
.gap_0()
.rounded_none()
.when_some(self.prefix, |this, prefix| this.prefix(prefix))
.when_some(self.suffix, |this, suffix| this.suffix(suffix)),
)
.child(
Button::new("+")
.ghost()
.with_size(self.size.smaller())
.outline()
.with_size(self.size)
.icon(IconName::Plus)
.compact()
.tab_stop(false)
.disabled(self.disabled)
.border_corners(Corners {
top_left: false,
top_right: true,
bottom_right: true,
bottom_left: false,
})
.border_edges(Edges {
top: self.appearance,
right: self.appearance,
bottom: self.appearance,
left: false,
})
.on_click({
let state = self.state.clone();
move |_, window, cx| {

View file

@ -461,9 +461,9 @@ impl<T: Styled> StyleSized<T> for T {
match size {
Size::Large => self.h_11(),
Size::Medium => self.h_8(),
Size::Small => self.h(px(26.)),
Size::Small => self.h(px(24.)),
Size::XSmall => self.h(px(20.)),
_ => self.h(px(26.)),
_ => self.h(px(24.)),
}
.input_text_size(size)
}