From d6597135556b268b1ae6f911fa697d057465273f Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Wed, 31 Jul 2024 11:49:32 +0800 Subject: [PATCH] Fix Label, Checkbox, Radio to support label text wrap. (#90) image --- Cargo.toml | 10 ++++----- crates/story/src/checkbox_story.rs | 33 +++++++++++++++++++++++++----- crates/ui/src/checkbox.rs | 18 +++++++++++----- crates/ui/src/label.rs | 3 +-- crates/ui/src/radio.rs | 27 +++++++++++++++++------- 5 files changed, 67 insertions(+), 24 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fb6749a1..fb85e4a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,19 +15,19 @@ serde = "1.0.203" serde_json = "1" [workspace.lints.clippy] -dbg_macro = "deny" -todo = "deny" -single_range_in_vec_init = "allow" -style = "allow" almost_complete_range = "allow" arc_with_non_send_sync = "allow" borrowed_box = "allow" +dbg_macro = "deny" let_underscore_future = "allow" map_entry = "allow" +module_inception = "allow" non_canonical_partial_ord_impl = "allow" reversed_empty_ranges = "allow" +single_range_in_vec_init = "allow" +style = { level = "allow", priority = -1 } +todo = "deny" type_complexity = "allow" -module_inception = "allow" [profile.dev] split-debuginfo = "unpacked" diff --git a/crates/story/src/checkbox_story.rs b/crates/story/src/checkbox_story.rs index de2256eb..afcd4705 100644 --- a/crates/story/src/checkbox_story.rs +++ b/crates/story/src/checkbox_story.rs @@ -1,6 +1,6 @@ use gpui::{ - px, rems, IntoElement, ParentElement, Render, Styled, View, ViewContext, VisualContext as _, - WindowContext, + div, px, rems, IntoElement, ParentElement, Render, Styled, View, ViewContext, + VisualContext as _, WindowContext, }; use ui::{ @@ -51,6 +51,7 @@ impl Render for CheckboxStory { .gap_6() .child( section("Label", cx) + .items_start() .child( v_flex() .w_full() @@ -66,6 +67,13 @@ impl Render for CheckboxStory { .text_left() .font_semibold() .line_height(rems(1.8)), + ) + .child( + div().w(px(200.)).child( + Label::new("Label should support text wrap in default, if the text is too long, it should wrap to the next line.") + .text_left() + .line_height(rems(1.8)), + ), ), ) .child( @@ -96,7 +104,7 @@ impl Render for CheckboxStory { section("Checkbox", cx).child( h_flex() .w_full() - .items_center() + .items_start() .gap_6() .child( Checkbox::new("check1") @@ -120,7 +128,13 @@ impl Render for CheckboxStory { .on_click(cx.listener(|v, _, _| { v.check3 = v.check3.inverse(); })), - ), + ) + .child( + div().w(px(300.)).child( + Checkbox::new("longlong-checkbox") + .label("Warp: Label should support text wrap in default, if the text is too long, it should wrap to the next line.") + ), + ) ), ) .child( @@ -154,6 +168,7 @@ impl Render for CheckboxStory { h_flex() .w_full() .gap_4() + .items_start() .child( Radio::new("radio1") .selected(self.select1) @@ -174,7 +189,15 @@ impl Render for CheckboxStory { .label("Disabled Radio") .selected(true) .disabled(true), - ), + ) + .child( + div().w(px(200.)).child( + Radio::new("radio3") + .label("Warp: A long long long text radio label") + .selected(true) + .disabled(true), + ), + ) ), ) } diff --git a/crates/ui/src/checkbox.rs b/crates/ui/src/checkbox.rs index fe849351..3dd0e9b1 100644 --- a/crates/ui/src/checkbox.rs +++ b/crates/ui/src/checkbox.rs @@ -1,6 +1,7 @@ use gpui::{ - prelude::FluentBuilder as _, svg, ElementId, InteractiveElement, IntoElement, ParentElement, - RenderOnce, SharedString, StatefulInteractiveElement as _, Styled as _, WindowContext, + div, prelude::FluentBuilder as _, relative, svg, ElementId, InteractiveElement, IntoElement, + ParentElement, RenderOnce, SharedString, StatefulInteractiveElement as _, Styled as _, + WindowContext, }; use crate::{ @@ -84,9 +85,8 @@ impl RenderOnce for Checkbox { h_flex() .id(self.id) .group(group_id.clone()) - .justify_center() - .items_center() .gap_2() + .items_start() .child( v_flex() .relative() @@ -94,6 +94,7 @@ impl RenderOnce for Checkbox { .border_color(color) .rounded_sm() .size_4() + .flex_shrink_0() .map(|this| match self.checked { Selection::Unselected => this.bg(theme.transparent), _ => this.bg(color), @@ -121,7 +122,14 @@ impl RenderOnce for Checkbox { ) .map(|this| { if let Some(label) = self.label { - this.child(label).text_color(color) + this.child( + div() + .w_full() + .overflow_hidden() + .line_height(relative(1.)) + .child(label), + ) + .text_color(color) } else { this } diff --git a/crates/ui/src/label.rs b/crates/ui/src/label.rs index bed7e373..7868a091 100644 --- a/crates/ui/src/label.rs +++ b/crates/ui/src/label.rs @@ -3,7 +3,7 @@ use gpui::{ Styled, WindowContext, }; -use crate::{theme::ActiveTheme, StyledExt}; +use crate::theme::ActiveTheme; #[derive(Default)] pub enum TextAlign { @@ -88,7 +88,6 @@ impl RenderOnce for Label { div().text_color(cx.theme().foreground).child( self.base - .h_flex() .map(|this| match self.align { TextAlign::Left => this.justify_start(), TextAlign::Center => this.justify_center(), diff --git a/crates/ui/src/radio.rs b/crates/ui/src/radio.rs index dbfcb297..d140d6db 100644 --- a/crates/ui/src/radio.rs +++ b/crates/ui/src/radio.rs @@ -1,6 +1,7 @@ use gpui::{ - div, prelude::FluentBuilder, svg, CursorStyle, ElementId, InteractiveElement, IntoElement, - ParentElement, RenderOnce, SharedString, StatefulInteractiveElement, Styled, WindowContext, + div, prelude::FluentBuilder, relative, svg, CursorStyle, ElementId, InteractiveElement, + IntoElement, ParentElement, RenderOnce, SharedString, StatefulInteractiveElement, Styled, + WindowContext, }; use crate::{ @@ -63,29 +64,41 @@ impl RenderOnce for Radio { .gap_x_2() .cursor(CursorStyle::PointingHand) .text_color(color) + .items_start() .child( div() .relative() - .w_3p5() - .h_3p5() + .size_4() + .flex_shrink_0() .rounded_full() .border_1() .border_color(color) - .mt_neg_0p5() + .when(self.selected, |this| this.bg(color)) .child( svg() .absolute() .top_px() .left_px() - .size_2p5() + .size_3() .text_color(color) + .when(self.selected, |this| { + this.text_color(cx.theme().primary_foreground) + }) .map(|this| match self.selected { true => this.path(IconName::Check.path()), false => this, }), ), ) - .when_some(self.label, |this, label| this.child(label)) + .when_some(self.label, |this, label| { + this.child( + div() + .size_full() + .overflow_hidden() + .line_height(relative(1.)) + .child(label), + ) + }) .when_some( self.on_click.filter(|_| !self.disabled), |this, on_click| {