Make `border` methods always require an explicit width (#11450)

Marshall Bowers created

This PR makes the `border` methods require an explicit width instead of
defaulting to 1px.

This breaks convention with Tailwind, but it makes GPUI more consistent
with itself. We already have an edge case where the parameterized method
had to be named `border_width`, since `border` was taken up by an alias
for the 1px variant.

### Before

```rs
div()
    .border()
    .border_t()
    .border_r()
    .border_b()
    .border_l()
    .border_width(px(7.))
```

### After

```rs
div()
    .border_1()
    .border_t_1()
    .border_r_1()
    .border_b_1()
    .border_l_1()
    .border(px(7.))
```

Release Notes:

- N/A

Change summary

crates/assistant2/src/assistant2.rs               |  2 +-
crates/collab_ui/src/collab_panel.rs              |  2 +-
crates/copilot/src/sign_in.rs                     |  2 +-
crates/editor/src/element.rs                      |  2 +-
crates/extensions_ui/src/extensions_ui.rs         |  2 +-
crates/feedback/src/feedback_modal.rs             |  4 ++--
crates/gpui/examples/hello_world.rs               |  2 +-
crates/gpui_macros/src/style_helpers.rs           |  8 +-------
crates/recent_projects/src/dev_servers.rs         |  4 ++--
crates/story/src/story.rs                         |  8 ++++----
crates/ui/docs/hello-world.md                     |  2 +-
crates/ui/src/components/avatar/avatar.rs         |  2 +-
crates/ui/src/components/checkbox/checkbox.rs     |  2 +-
crates/ui/src/components/collapsible_container.rs |  4 ++--
crates/ui/src/components/icon.rs                  |  2 +-
crates/ui/src/components/list/list_item.rs        |  4 ++--
crates/ui/src/components/stories/checkbox.rs      |  4 ++--
crates/ui/src/components/tab.rs                   | 14 +++++++-------
crates/ui/src/components/tab_bar.rs               | 10 +++++-----
crates/ui/src/styled_ext.rs                       |  2 +-
crates/ui_text_field/src/ui_text_field.rs         |  2 +-
crates/workspace/src/dock.rs                      |  6 +++---
crates/workspace/src/toolbar.rs                   |  2 +-
crates/workspace/src/workspace.rs                 | 12 ++++++------
24 files changed, 49 insertions(+), 55 deletions(-)

Detailed changes

crates/assistant2/src/assistant2.rs 🔗

@@ -622,7 +622,7 @@ impl AssistantChat {
                 .px_2()
                 .neg_mx_1()
                 .rounded_md()
-                .border()
+                .border_1()
                 .border_color(theme.status().error_border)
                 // .bg(theme.status().error_background)
                 .text_color(theme.status().error)

crates/collab_ui/src/collab_panel.rs 🔗

@@ -2149,7 +2149,7 @@ impl CollabPanel {
             .child(list(self.list_state.clone()).size_full())
             .child(
                 v_flex()
-                    .child(div().mx_2().border_primary(cx).border_t())
+                    .child(div().mx_2().border_primary(cx).border_t_1())
                     .child(
                         v_flex()
                             .p_2()

crates/copilot/src/sign_in.rs 🔗

@@ -60,7 +60,7 @@ impl CopilotCodeVerification {
         h_flex()
             .w_full()
             .p_1()
-            .border()
+            .border_1()
             .border_muted(cx)
             .rounded_md()
             .cursor_pointer()

crates/editor/src/element.rs 🔗

@@ -1817,7 +1817,7 @@ impl EditorElement {
                                     .pr(gpui::px(8.))
                                     .rounded_md()
                                     .shadow_md()
-                                    .border()
+                                    .border_1()
                                     .border_color(cx.theme().colors().border)
                                     .bg(cx.theme().colors().editor_subheader_background)
                                     .justify_between()

crates/extensions_ui/src/extensions_ui.rs 🔗

@@ -852,7 +852,7 @@ impl Render for ExtensionsPage {
                 v_flex()
                     .gap_4()
                     .p_4()
-                    .border_b()
+                    .border_b_1()
                     .border_color(cx.theme().colors().border)
                     .bg(cx.theme().colors().editor_background)
                     .child(

crates/feedback/src/feedback_modal.rs 🔗

@@ -454,7 +454,7 @@ impl Render for FeedbackModal {
                     .flex_1()
                     .bg(cx.theme().colors().editor_background)
                     .p_2()
-                    .border()
+                    .border_1()
                     .rounded_md()
                     .border_color(cx.theme().colors().border)
                     .child(self.feedback_editor.clone()),
@@ -466,7 +466,7 @@ impl Render for FeedbackModal {
                         h_flex()
                             .bg(cx.theme().colors().editor_background)
                             .p_2()
-                            .border()
+                            .border_1()
                             .rounded_md()
                             .border_color(if self.valid_email_address() {
                                 cx.theme().colors().border

crates/gpui/examples/hello_world.rs 🔗

@@ -13,7 +13,7 @@ impl Render for HelloWorld {
             .justify_center()
             .items_center()
             .shadow_lg()
-            .border()
+            .border_1()
             .border_color(rgb(0x0000ff))
             .text_xl()
             .text_color(rgb(0xffffff))

crates/gpui_macros/src/style_helpers.rs 🔗

@@ -86,12 +86,7 @@ fn generate_methods() -> Vec<TokenStream2> {
 
     for (prefix, fields, prefix_doc_string) in border_prefixes() {
         methods.push(generate_custom_value_setter(
-            // The plain method names (e.g., `border`, `border_t`, `border_r`, etc.) are special-cased
-            // versions of the 1px variants. This better matches Tailwind, but breaks our existing
-            // convention of the suffix-less variant of the method being the one that accepts a custom value
-            //
-            // To work around this, we're assigning a `_width` suffix here.
-            &format!("{prefix}_width"),
+            prefix,
             quote! { AbsoluteLength },
             &fields,
             prefix_doc_string,
@@ -553,7 +548,6 @@ fn border_prefixes() -> Vec<(&'static str, Vec<TokenStream2>, &'static str)> {
 
 fn border_suffixes() -> Vec<(&'static str, TokenStream2, &'static str)> {
     vec![
-        ("", quote! { px(1.)}, "1px"),
         ("0", quote! { px(0.)}, "0px"),
         ("1", quote! { px(1.) }, "1px"),
         ("2", quote! { px(2.) }, "2px"),

crates/recent_projects/src/dev_servers.rs 🔗

@@ -551,7 +551,7 @@ impl DevServerProjects {
                 v_flex()
                     .w_full()
                     .bg(cx.theme().colors().title_bar_background) // todo: this should be distinct
-                    .border()
+                    .border_1()
                     .border_color(cx.theme().colors().border_variant)
                     .rounded_md()
                     .my_1()
@@ -754,7 +754,7 @@ impl DevServerProjects {
                 v_flex()
                     .w_full()
                     .bg(cx.theme().colors().title_bar_background) // todo: this should be distinct
-                    .border()
+                    .border_1()
                     .border_color(cx.theme().colors().border_variant)
                     .rounded_md()
                     .my_1()

crates/story/src/story.rs 🔗

@@ -88,7 +88,7 @@ impl RenderOnce for StoryContainer {
                     .justify_between()
                     .p_2()
                     .bg(story_color().background)
-                    .border_b()
+                    .border_b_1()
                     .border_color(story_color().border)
                     .child(Story::title(self.title))
                     .child(
@@ -145,7 +145,7 @@ impl Story {
                         .flex()
                         .justify_between()
                         .p_2()
-                        .border_b()
+                        .border_b_1()
                         .border_color(story_color().border)
                         .child(Story::title_for::<T>())
                         .child(
@@ -202,7 +202,7 @@ impl Story {
         div()
             .p_4()
             .m_4()
-            .border()
+            .border_1()
             .border_color(story_color().border)
     }
 
@@ -307,7 +307,7 @@ impl RenderOnce for StoryItem {
                         div()
                             .rounded_md()
                             .bg(story_color().card_background)
-                            .border()
+                            .border_1()
                             .border_color(story_color().border)
                             .py_1()
                             .px_2()

crates/ui/docs/hello-world.md 🔗

@@ -133,7 +133,7 @@ impl<V: 'static> TodoList<V> {
             .text_color(color.text) // Set text color
             // Border properties
             .rounded_md()           // Add 4px of border radius
-            .border()               // Add a 1px border
+            .border_1()             // Add a 1px border
             .border_color(color.border)
             .child(
                 "Hello, world!"

crates/ui/src/components/avatar/avatar.rs 🔗

@@ -115,7 +115,7 @@ impl RenderOnce for Avatar {
                 div
             })
             .when_some(self.border_color, |this, color| {
-                this.border_width(border_width).border_color(color)
+                this.border(border_width).border_color(color)
             })
             .child(
                 self.image

crates/ui/src/components/checkbox/checkbox.rs 🔗

@@ -95,7 +95,7 @@ impl RenderOnce for Checkbox {
                     .size(crate::styles::custom_spacing(cx, 16.))
                     .rounded_sm()
                     .bg(bg_color)
-                    .border()
+                    .border_1()
                     .border_color(border_color)
                     .when(!self.disabled, |this| {
                         this.group_hover(group_id.clone(), |el| {

crates/ui/src/components/collapsible_container.rs 🔗

@@ -88,7 +88,7 @@ impl RenderOnce for CollapsibleContainer {
             .relative()
             .rounded_md()
             .bg(styles.background_color)
-            .border()
+            .border_1()
             .border_color(styles.border_color)
             .text_color(styles.text_color)
             .overflow_hidden()
@@ -97,7 +97,7 @@ impl RenderOnce for CollapsibleContainer {
                     .overflow_hidden()
                     .w_full()
                     .group("toggleable_container_header")
-                    .border_b()
+                    .border_b_1()
                     .border_color(if self.toggle {
                         styles.border_color
                     } else {

crates/ui/src/components/icon.rs 🔗

@@ -393,7 +393,7 @@ impl RenderOnce for IconWithIndicator {
                         .absolute()
                         .w_2()
                         .h_2()
-                        .border()
+                        .border_1()
                         .border_color(indicator_border_color)
                         .rounded_full()
                         .neg_bottom_0p5()

crates/ui/src/components/list/list_item.rs 🔗

@@ -161,7 +161,7 @@ impl RenderOnce for ListItem {
                 this
                     // TODO: Add focus state
                     // .when(self.state == InteractionState::Focused, |this| {
-                    //     this.border()
+                    //     this.border_1()
                     //         .border_color(cx.theme().colors().border_focused)
                     // })
                     .hover(|style| style.bg(cx.theme().colors().ghost_element_hover))
@@ -186,7 +186,7 @@ impl RenderOnce for ListItem {
                         this
                             // TODO: Add focus state
                             // .when(self.state == InteractionState::Focused, |this| {
-                            //     this.border()
+                            //     this.border_1()
                             //         .border_color(cx.theme().colors().border_focused)
                             // })
                             .hover(|style| style.bg(cx.theme().colors().ghost_element_hover))

crates/ui/src/components/stories/checkbox.rs 🔗

@@ -16,7 +16,7 @@ impl Render for CheckboxStory {
                     .p_2()
                     .gap_2()
                     .rounded_md()
-                    .border()
+                    .border_1()
                     .border_color(cx.theme().colors().border)
                     .child(Checkbox::new("checkbox-enabled", Selection::Unselected))
                     .child(Checkbox::new(
@@ -31,7 +31,7 @@ impl Render for CheckboxStory {
                     .p_2()
                     .gap_2()
                     .rounded_md()
-                    .border()
+                    .border_1()
                     .border_color(cx.theme().colors().border)
                     .child(Checkbox::new("checkbox-disabled", Selection::Unselected).disabled(true))
                     .child(

crates/ui/src/components/tab.rs 🔗

@@ -124,21 +124,21 @@ impl RenderOnce for Tab {
             .map(|this| match self.position {
                 TabPosition::First => {
                     if self.selected {
-                        this.pl_px().border_r().pb_px()
+                        this.pl_px().border_r_1().pb_px()
                     } else {
-                        this.pl_px().pr_px().border_b()
+                        this.pl_px().pr_px().border_b_1()
                     }
                 }
                 TabPosition::Last => {
                     if self.selected {
-                        this.border_l().border_r().pb_px()
+                        this.border_l_1().border_r_1().pb_px()
                     } else {
-                        this.pr_px().pl_px().border_b().border_r()
+                        this.pr_px().pl_px().border_b_1().border_r_1()
                     }
                 }
-                TabPosition::Middle(Ordering::Equal) => this.border_l().border_r().pb_px(),
-                TabPosition::Middle(Ordering::Less) => this.border_l().pr_px().border_b(),
-                TabPosition::Middle(Ordering::Greater) => this.border_r().pl_px().border_b(),
+                TabPosition::Middle(Ordering::Equal) => this.border_l_1().border_r_1().pb_px(),
+                TabPosition::Middle(Ordering::Less) => this.border_l_1().pr_px().border_b_1(),
+                TabPosition::Middle(Ordering::Greater) => this.border_r_1().pl_px().border_b_1(),
             })
             .cursor_pointer()
             .child(

crates/ui/src/components/tab_bar.rs 🔗

@@ -108,8 +108,8 @@ impl RenderOnce for TabBar {
                         .flex_none()
                         .gap(Spacing::Small.rems(cx))
                         .px(Spacing::Medium.rems(cx))
-                        .border_b()
-                        .border_r()
+                        .border_b_1()
+                        .border_r_1()
                         .border_color(cx.theme().colors().border)
                         .children(self.start_children),
                 )
@@ -126,7 +126,7 @@ impl RenderOnce for TabBar {
                             .top_0()
                             .left_0()
                             .size_full()
-                            .border_b()
+                            .border_b_1()
                             .border_color(cx.theme().colors().border),
                     )
                     .child(
@@ -146,8 +146,8 @@ impl RenderOnce for TabBar {
                         .flex_none()
                         .gap(Spacing::Small.rems(cx))
                         .px(Spacing::Medium.rems(cx))
-                        .border_b()
-                        .border_l()
+                        .border_b_1()
+                        .border_l_1()
                         .border_color(cx.theme().colors().border)
                         .children(self.end_children),
                 )

crates/ui/src/styled_ext.rs 🔗

@@ -6,7 +6,7 @@ use crate::ElevationIndex;
 fn elevated<E: Styled>(this: E, cx: &mut WindowContext, index: ElevationIndex) -> E {
     this.bg(cx.theme().colors().elevated_surface_background)
         .rounded(px(8.))
-        .border()
+        .border_1()
         .border_color(cx.theme().colors().border_variant)
         .shadow(index.shadow())
 }

crates/ui_text_field/src/ui_text_field.rs 🔗

@@ -170,7 +170,7 @@ impl Render for TextField {
                                 .bg(style.background_color)
                                 .text_color(style.text_color)
                                 .rounded_lg()
-                                .border()
+                                .border_1()
                                 .border_color(style.border_color)
                                 .min_w_48()
                                 .w_full()

crates/workspace/src/dock.rs 🔗

@@ -623,9 +623,9 @@ impl Render for Dock {
                     Axis::Vertical => this.h(size).w_full().flex_col(),
                 })
                 .map(|this| match self.position() {
-                    DockPosition::Left => this.border_r(),
-                    DockPosition::Right => this.border_l(),
-                    DockPosition::Bottom => this.border_t(),
+                    DockPosition::Left => this.border_r_1(),
+                    DockPosition::Right => this.border_l_1(),
+                    DockPosition::Bottom => this.border_t_1(),
                 })
                 .child(
                     div()

crates/workspace/src/toolbar.rs 🔗

@@ -100,7 +100,7 @@ impl Render for Toolbar {
             .when(has_left_items || has_right_items, |this| {
                 this.gap(Spacing::Large.rems(cx))
             })
-            .border_b()
+            .border_b_1()
             .border_color(cx.theme().colors().border_variant)
             .bg(cx.theme().colors().toolbar_background)
             .child(

crates/workspace/src/workspace.rs 🔗

@@ -4123,8 +4123,8 @@ impl Render for Workspace {
                     .flex()
                     .flex_col()
                     .overflow_hidden()
-                    .border_t()
-                    .border_b()
+                    .border_t_1()
+                    .border_b_1()
                     .border_color(colors.border)
                     .child({
                         let this = cx.view().clone();
@@ -4230,10 +4230,10 @@ impl Render for Workspace {
                             .shadow_lg();
 
                         Some(match self.zoomed_position {
-                            Some(DockPosition::Left) => div.right_2().border_r(),
-                            Some(DockPosition::Right) => div.left_2().border_l(),
-                            Some(DockPosition::Bottom) => div.top_2().border_t(),
-                            None => div.top_2().bottom_2().left_2().right_2().border(),
+                            Some(DockPosition::Left) => div.right_2().border_r_1(),
+                            Some(DockPosition::Right) => div.left_2().border_l_1(),
+                            Some(DockPosition::Bottom) => div.top_2().border_t_1(),
+                            None => div.top_2().bottom_2().left_2().right_2().border_1(),
                         })
                     }))
                     .child(self.modal_layer.clone())