Fix Label, Checkbox, Radio to support label text wrap. (#90)

<img width="1102" alt="image"
src="https://github.com/user-attachments/assets/1443378d-54e9-43a4-8bb8-0d0f4581169d">
This commit is contained in:
Jason Lee 2024-07-31 11:49:32 +08:00 committed by GitHub
parent c94e9feae2
commit d659713555
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 67 additions and 24 deletions

View file

@ -15,19 +15,19 @@ serde = "1.0.203"
serde_json = "1" serde_json = "1"
[workspace.lints.clippy] [workspace.lints.clippy]
dbg_macro = "deny"
todo = "deny"
single_range_in_vec_init = "allow"
style = "allow"
almost_complete_range = "allow" almost_complete_range = "allow"
arc_with_non_send_sync = "allow" arc_with_non_send_sync = "allow"
borrowed_box = "allow" borrowed_box = "allow"
dbg_macro = "deny"
let_underscore_future = "allow" let_underscore_future = "allow"
map_entry = "allow" map_entry = "allow"
module_inception = "allow"
non_canonical_partial_ord_impl = "allow" non_canonical_partial_ord_impl = "allow"
reversed_empty_ranges = "allow" reversed_empty_ranges = "allow"
single_range_in_vec_init = "allow"
style = { level = "allow", priority = -1 }
todo = "deny"
type_complexity = "allow" type_complexity = "allow"
module_inception = "allow"
[profile.dev] [profile.dev]
split-debuginfo = "unpacked" split-debuginfo = "unpacked"

View file

@ -1,6 +1,6 @@
use gpui::{ use gpui::{
px, rems, IntoElement, ParentElement, Render, Styled, View, ViewContext, VisualContext as _, div, px, rems, IntoElement, ParentElement, Render, Styled, View, ViewContext,
WindowContext, VisualContext as _, WindowContext,
}; };
use ui::{ use ui::{
@ -51,6 +51,7 @@ impl Render for CheckboxStory {
.gap_6() .gap_6()
.child( .child(
section("Label", cx) section("Label", cx)
.items_start()
.child( .child(
v_flex() v_flex()
.w_full() .w_full()
@ -66,6 +67,13 @@ impl Render for CheckboxStory {
.text_left() .text_left()
.font_semibold() .font_semibold()
.line_height(rems(1.8)), .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( .child(
@ -96,7 +104,7 @@ impl Render for CheckboxStory {
section("Checkbox", cx).child( section("Checkbox", cx).child(
h_flex() h_flex()
.w_full() .w_full()
.items_center() .items_start()
.gap_6() .gap_6()
.child( .child(
Checkbox::new("check1") Checkbox::new("check1")
@ -120,7 +128,13 @@ impl Render for CheckboxStory {
.on_click(cx.listener(|v, _, _| { .on_click(cx.listener(|v, _, _| {
v.check3 = v.check3.inverse(); 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( .child(
@ -154,6 +168,7 @@ impl Render for CheckboxStory {
h_flex() h_flex()
.w_full() .w_full()
.gap_4() .gap_4()
.items_start()
.child( .child(
Radio::new("radio1") Radio::new("radio1")
.selected(self.select1) .selected(self.select1)
@ -174,7 +189,15 @@ impl Render for CheckboxStory {
.label("Disabled Radio") .label("Disabled Radio")
.selected(true) .selected(true)
.disabled(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),
),
)
), ),
) )
} }

View file

@ -1,6 +1,7 @@
use gpui::{ use gpui::{
prelude::FluentBuilder as _, svg, ElementId, InteractiveElement, IntoElement, ParentElement, div, prelude::FluentBuilder as _, relative, svg, ElementId, InteractiveElement, IntoElement,
RenderOnce, SharedString, StatefulInteractiveElement as _, Styled as _, WindowContext, ParentElement, RenderOnce, SharedString, StatefulInteractiveElement as _, Styled as _,
WindowContext,
}; };
use crate::{ use crate::{
@ -84,9 +85,8 @@ impl RenderOnce for Checkbox {
h_flex() h_flex()
.id(self.id) .id(self.id)
.group(group_id.clone()) .group(group_id.clone())
.justify_center()
.items_center()
.gap_2() .gap_2()
.items_start()
.child( .child(
v_flex() v_flex()
.relative() .relative()
@ -94,6 +94,7 @@ impl RenderOnce for Checkbox {
.border_color(color) .border_color(color)
.rounded_sm() .rounded_sm()
.size_4() .size_4()
.flex_shrink_0()
.map(|this| match self.checked { .map(|this| match self.checked {
Selection::Unselected => this.bg(theme.transparent), Selection::Unselected => this.bg(theme.transparent),
_ => this.bg(color), _ => this.bg(color),
@ -121,7 +122,14 @@ impl RenderOnce for Checkbox {
) )
.map(|this| { .map(|this| {
if let Some(label) = self.label { 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 { } else {
this this
} }

View file

@ -3,7 +3,7 @@ use gpui::{
Styled, WindowContext, Styled, WindowContext,
}; };
use crate::{theme::ActiveTheme, StyledExt}; use crate::theme::ActiveTheme;
#[derive(Default)] #[derive(Default)]
pub enum TextAlign { pub enum TextAlign {
@ -88,7 +88,6 @@ impl RenderOnce for Label {
div().text_color(cx.theme().foreground).child( div().text_color(cx.theme().foreground).child(
self.base self.base
.h_flex()
.map(|this| match self.align { .map(|this| match self.align {
TextAlign::Left => this.justify_start(), TextAlign::Left => this.justify_start(),
TextAlign::Center => this.justify_center(), TextAlign::Center => this.justify_center(),

View file

@ -1,6 +1,7 @@
use gpui::{ use gpui::{
div, prelude::FluentBuilder, svg, CursorStyle, ElementId, InteractiveElement, IntoElement, div, prelude::FluentBuilder, relative, svg, CursorStyle, ElementId, InteractiveElement,
ParentElement, RenderOnce, SharedString, StatefulInteractiveElement, Styled, WindowContext, IntoElement, ParentElement, RenderOnce, SharedString, StatefulInteractiveElement, Styled,
WindowContext,
}; };
use crate::{ use crate::{
@ -63,29 +64,41 @@ impl RenderOnce for Radio {
.gap_x_2() .gap_x_2()
.cursor(CursorStyle::PointingHand) .cursor(CursorStyle::PointingHand)
.text_color(color) .text_color(color)
.items_start()
.child( .child(
div() div()
.relative() .relative()
.w_3p5() .size_4()
.h_3p5() .flex_shrink_0()
.rounded_full() .rounded_full()
.border_1() .border_1()
.border_color(color) .border_color(color)
.mt_neg_0p5() .when(self.selected, |this| this.bg(color))
.child( .child(
svg() svg()
.absolute() .absolute()
.top_px() .top_px()
.left_px() .left_px()
.size_2p5() .size_3()
.text_color(color) .text_color(color)
.when(self.selected, |this| {
this.text_color(cx.theme().primary_foreground)
})
.map(|this| match self.selected { .map(|this| match self.selected {
true => this.path(IconName::Check.path()), true => this.path(IconName::Check.path()),
false => this, 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( .when_some(
self.on_click.filter(|_| !self.disabled), self.on_click.filter(|_| !self.disabled),
|this, on_click| { |this, on_click| {