diff --git a/crates/story/src/textarea_story.rs b/crates/story/src/textarea_story.rs index 270ca11e..c9318f5d 100644 --- a/crates/story/src/textarea_story.rs +++ b/crates/story/src/textarea_story.rs @@ -1,14 +1,15 @@ use gpui::{ - px, App, AppContext as _, ClickEvent, Context, Entity, Focusable, InteractiveElement, - IntoElement, ParentElement as _, Render, Styled, Window, + App, AppContext as _, ClickEvent, Context, Entity, Focusable, InteractiveElement, IntoElement, + ParentElement as _, Render, Styled, Window, px, }; use crate::section; use gpui_component::{ + Sizable, button::Button, h_flex, input::{InputState, TextInput}, - v_flex, Sizable, + v_flex, }; pub fn init(_: &mut App) {} @@ -17,6 +18,7 @@ pub struct TextareaStory { textarea: Entity, textarea_auto_grow: Entity, textarea_no_wrap: Entity, + textarea_auto_grow_no_wrap: Entity, } impl super::Story for TextareaStory { @@ -73,13 +75,6 @@ impl TextareaStory { ) }); - let textarea_auto_grow = cx.new(|cx| { - InputState::new(window, cx) - .auto_grow(1, 5) - .placeholder("Enter text here...") - .default_value("Hello 世界,this is GPUI component.") - }); - let textarea_no_wrap = cx.new(|cx| { InputState::new(window, cx) .multi_line() @@ -88,10 +83,26 @@ impl TextareaStory { .default_value("This is a very long line of text to test if the horizontal scrolling function is working properly, and it should not wrap automatically but display a horizontal scrollbar.\nThe second line is also very long text, used to test the horizontal scrolling effect under multiple lines, and you can input more content to test.\nThe third line: Here you can input other long text content that requires horizontal scrolling.\n") }); + let textarea_auto_grow = cx.new(|cx| { + InputState::new(window, cx) + .auto_grow(1, 5) + .placeholder("Enter text here...") + .default_value("Hello 世界, this is a very long line of text to test if the horizontal scrolling function is working properly, and it should not wrap automatically but display a horizontal scrollbar.\nThe second line is also very long text, used to test the horizontal scrolling effect under multiple lines, and you can input more content to test.\nThe third line: Here you can input other long text content that requires horizontal scrolling.\n") + }); + + let textarea_auto_grow_no_wrap = cx.new(|cx| { + InputState::new(window, cx) + .auto_grow(1, 5) + .soft_wrap(false) + .placeholder("Enter text here...") + .default_value("Hello 世界,this is GPUI component.") + }); + Self { textarea, textarea_auto_grow, textarea_no_wrap, + textarea_auto_grow_no_wrap, } } @@ -166,11 +177,20 @@ impl Render for TextareaStory { ), ), ) - .child(section("Textarea Auto Grow").child(TextInput::new(&self.textarea_auto_grow))) .child( section("No Wrap") .max_w_md() .child(TextInput::new(&self.textarea_no_wrap).h(px(200.))), ) + .child( + section("Auto Grow") + .max_w_md() + .child(TextInput::new(&self.textarea_auto_grow)), + ) + .child( + section("Auto Grow with No Wrap") + .max_w_md() + .child(TextInput::new(&self.textarea_auto_grow_no_wrap)), + ) } } diff --git a/crates/ui/src/input/element.rs b/crates/ui/src/input/element.rs index bcd4f41f..8730eebc 100644 --- a/crates/ui/src/input/element.rs +++ b/crates/ui/src/input/element.rs @@ -974,14 +974,14 @@ impl Element for TextElement { last_layout.lines = Rc::new(lines); let total_wrapped_lines = state.text_wrapper.len(); - let empty_bottom_height = if state.mode.is_auto_grow() || state.mode.is_single_line() { - px(0.) - } else { + let empty_bottom_height = if state.mode.is_code_editor() { bounds .size .height .half() .max(BOTTOM_MARGIN_ROWS * line_height) + } else { + px(0.) }; let scroll_size = size( @@ -1283,9 +1283,7 @@ impl Element for TextElement { state.set_input_bounds(input_bounds, cx); state.last_selected_range = Some(selected_range); state.scroll_size = prepaint.scroll_size; - state - .scroll_handle - .set_offset(prepaint.cursor_scroll_offset); + state.update_scroll_offset(Some(prepaint.cursor_scroll_offset), cx); state.deferred_scroll_offset = None; cx.notify(); diff --git a/crates/ui/src/input/state.rs b/crates/ui/src/input/state.rs index 2dcd198b..737a9ac8 100644 --- a/crates/ui/src/input/state.rs +++ b/crates/ui/src/input/state.rs @@ -1456,7 +1456,11 @@ impl InputState { self.diagnostic_popover = None; } - fn update_scroll_offset(&mut self, offset: Option>, cx: &mut Context) { + pub(super) fn update_scroll_offset( + &mut self, + offset: Option>, + cx: &mut Context, + ) { let mut offset = offset.unwrap_or(self.scroll_handle.offset()); let safe_y_range = @@ -1516,7 +1520,11 @@ impl InputState { // Check if row_offset_y is out of the viewport // If row offset is not in the viewport, scroll to make it visible - let edge_height = 3 * line_height; + let edge_height = if self.mode.is_code_editor() { + 3 * line_height + } else { + line_height + }; if row_offset_y - edge_height < -scroll_offset.y { // Scroll up scroll_offset.y = -row_offset_y + edge_height;