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

View file

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

View file

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