ui: Update Label component (#24653)

Nate Butler created

- Standardize style methods
- Convert label story to a component preview
- update component preview styles  

Release Notes:

- N/A

Change summary

crates/collab_ui/src/channel_view.rs                |   2 
crates/component/src/component.rs                   |  32 +++
crates/component_preview/src/component_preview.rs   |  36 ++-
crates/editor/src/items.rs                          |   6 
crates/git_ui/src/git_panel.rs                      |   6 
crates/image_viewer/src/image_viewer.rs             |   2 
crates/project_panel/src/project_panel.rs           |   2 
crates/repl/src/notebook/notebook_ui.rs             |   2 
crates/storybook/src/story_selector.rs              |   2 
crates/ui/src/components/avatar/avatar.rs           |   1 
crates/ui/src/components/button/button.rs           |   1 
crates/ui/src/components/content_group.rs           |   1 
crates/ui/src/components/icon.rs                    |   1 
crates/ui/src/components/icon/decorated_icon.rs     |   1 
crates/ui/src/components/keybinding_hint.rs         |   1 
crates/ui/src/components/label/highlighted_label.rs |  12 
crates/ui/src/components/label/label.rs             | 130 ++++++++------
crates/ui/src/components/label/label_like.rs        |  41 +++-
crates/ui/src/components/stories.rs                 |   2 
crates/ui/src/components/stories/label.rs           |  38 ----
crates/ui/src/components/tab.rs                     |   1 
crates/ui/src/components/table.rs                   |   1 
crates/ui/src/components/toggle.rs                  |   3 
crates/ui/src/components/tooltip.rs                 |   1 
crates/ui/src/prelude.rs                            |   5 
crates/ui/src/styles/typography.rs                  |   1 
crates/welcome/src/welcome.rs                       |   2 
27 files changed, 182 insertions(+), 151 deletions(-)

Detailed changes

crates/collab_ui/src/channel_view.rs 🔗

@@ -461,7 +461,7 @@ impl Item for ChannelView {
             .child(
                 Label::new(channel_name)
                     .color(params.text_color())
-                    .italic(params.preview),
+                    .when(params.preview, |this| this.italic()),
             )
             .when_some(status, |element, status| {
                 element.child(

crates/component/src/component.rs 🔗

@@ -1,7 +1,7 @@
 use std::ops::{Deref, DerefMut};
 
 use collections::HashMap;
-use gpui::{div, prelude::*, AnyElement, App, IntoElement, RenderOnce, SharedString, Window};
+use gpui::{div, prelude::*, px, AnyElement, App, IntoElement, RenderOnce, SharedString, Window};
 use linkme::distributed_slice;
 use once_cell::sync::Lazy;
 use parking_lot::RwLock;
@@ -201,8 +201,9 @@ impl RenderOnce for ComponentExample {
         };
 
         base.gap_1()
-            .text_xs()
-            .text_color(cx.theme().colors().text_muted)
+            .p_2()
+            .text_sm()
+            .text_color(cx.theme().colors().text)
             .when(self.grow, |this| this.flex_1())
             .child(self.element)
             .child(self.variant_name)
@@ -243,13 +244,34 @@ impl RenderOnce for ComponentExampleGroup {
             .text_sm()
             .text_color(cx.theme().colors().text_muted)
             .when(self.grow, |this| this.w_full().flex_1())
-            .when_some(self.title, |this, title| this.gap_4().child(title))
+            .when_some(self.title, |this, title| {
+                this.gap_4().pb_5().child(
+                    div()
+                        .flex()
+                        .items_center()
+                        .gap_3()
+                        .child(div().h_px().w_4().bg(cx.theme().colors().border_variant))
+                        .child(
+                            div()
+                                .flex_none()
+                                .text_size(px(10.))
+                                .child(title.to_uppercase()),
+                        )
+                        .child(
+                            div()
+                                .h_px()
+                                .w_full()
+                                .flex_1()
+                                .bg(cx.theme().colors().border),
+                        ),
+                )
+            })
             .child(
                 div()
                     .flex()
                     .items_start()
                     .w_full()
-                    .gap_6()
+                    .gap_8()
                     .children(self.examples)
                     .into_any_element(),
             )

crates/component_preview/src/component_preview.rs 🔗

@@ -41,11 +41,21 @@ impl ComponentPreview {
         let components = components().all_sorted();
         let sorted_components = components.clone();
 
-        v_flex().gap_px().p_1().children(
-            sorted_components
-                .into_iter()
-                .map(|component| self.render_sidebar_entry(&component, _cx)),
-        )
+        v_flex()
+            .max_w_48()
+            .gap_px()
+            .p_1()
+            .children(
+                sorted_components
+                    .into_iter()
+                    .map(|component| self.render_sidebar_entry(&component, _cx)),
+            )
+            .child(
+                Label::new("These will be clickable once the layout is moved to a gpui::List.")
+                    .color(Color::Muted)
+                    .size(LabelSize::XSmall)
+                    .italic(),
+            )
     }
 
     fn render_sidebar_entry(
@@ -56,7 +66,8 @@ impl ComponentPreview {
         h_flex()
             .w_40()
             .px_1p5()
-            .py_1()
+            .py_0p5()
+            .text_sm()
             .child(component.name().clone())
     }
 
@@ -71,18 +82,19 @@ impl ComponentPreview {
 
         let description = component.description();
 
-        v_group()
+        v_flex()
+            .border_b_1()
+            .border_color(cx.theme().colors().border)
             .w_full()
-            .gap_4()
-            .p_8()
-            .rounded_md()
+            .gap_3()
+            .py_6()
             .child(
                 v_flex()
                     .gap_1()
                     .child(
                         h_flex()
                             .gap_1()
-                            .text_xl()
+                            .text_2xl()
                             .child(div().child(name))
                             .when_some(scope, |this, scope| {
                                 this.child(div().opacity(0.5).child(format!("({})", scope)))
@@ -110,7 +122,7 @@ impl ComponentPreview {
             .size_full()
             .overflow_y_scroll()
             .p_4()
-            .gap_2()
+            .gap_4()
             .children(
                 components()
                     .all_previews_sorted()

crates/editor/src/items.rs 🔗

@@ -36,7 +36,7 @@ use std::{
 };
 use text::{BufferId, Selection};
 use theme::{Theme, ThemeSettings};
-use ui::{h_flex, prelude::*, IconDecorationKind, Label};
+use ui::{prelude::*, IconDecorationKind};
 use util::{paths::PathExt, ResultExt, TryFutureExt};
 use workspace::item::{Dedup, ItemSettings, SerializableItem, TabContentParams};
 use workspace::{
@@ -679,8 +679,8 @@ impl Item for Editor {
             .child(
                 Label::new(self.title(cx).to_string())
                     .color(label_color)
-                    .italic(params.preview)
-                    .strikethrough(was_deleted),
+                    .when(params.preview, |this| this.italic())
+                    .when(was_deleted, |this| this.strikethrough()),
             )
             .when_some(description, |this, description| {
                 this.child(

crates/git_ui/src/git_panel.rs 🔗

@@ -1657,9 +1657,7 @@ impl GitPanel {
                                 if !parent_str.is_empty() {
                                     this.child(
                                         self.entry_label(format!("{}/", parent_str), path_color)
-                                            .when(status.is_deleted(), |this| {
-                                                this.strikethrough(true)
-                                            }),
+                                            .when(status.is_deleted(), |this| this.strikethrough()),
                                     )
                                 } else {
                                     this
@@ -1667,7 +1665,7 @@ impl GitPanel {
                             })
                             .child(
                                 self.entry_label(display_name.clone(), label_color)
-                                    .when(status.is_deleted(), |this| this.strikethrough(true)),
+                                    .when(status.is_deleted(), |this| this.strikethrough()),
                             ),
                     ),
             )

crates/image_viewer/src/image_viewer.rs 🔗

@@ -131,7 +131,7 @@ impl Item for ImageView {
         Label::new(title)
             .single_line()
             .color(label_color)
-            .italic(params.preview)
+            .when(params.preview, |this| this.italic())
             .into_any_element()
     }
 

crates/repl/src/notebook/notebook_ui.rs 🔗

@@ -738,7 +738,7 @@ impl Item for NotebookEditor {
         Label::new(title)
             .single_line()
             .color(params.text_color())
-            .italic(params.preview)
+            .when(params.preview, |this| this.italic())
             .into_any_element()
     }
 

crates/storybook/src/story_selector.rs 🔗

@@ -25,7 +25,6 @@ pub enum ComponentStory {
     Icon,
     IconButton,
     Keybinding,
-    Label,
     List,
     ListHeader,
     ListItem,
@@ -61,7 +60,6 @@ impl ComponentStory {
             Self::Icon => cx.new(|_| ui::IconStory).into(),
             Self::IconButton => cx.new(|_| ui::IconButtonStory).into(),
             Self::Keybinding => cx.new(|_| ui::KeybindingStory).into(),
-            Self::Label => cx.new(|_| ui::LabelStory).into(),
             Self::List => cx.new(|_| ui::ListStory).into(),
             Self::ListHeader => cx.new(|_| ui::ListHeaderStory).into(),
             Self::ListItem => cx.new(|_| ui::ListItemStory).into(),

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

@@ -97,6 +97,7 @@ impl RenderOnce for Avatar {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for Avatar {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         let example_avatar = "https://avatars.githubusercontent.com/u/1714999?v=4";

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

@@ -456,6 +456,7 @@ impl RenderOnce for Button {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for Button {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         v_flex()

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

@@ -88,6 +88,7 @@ impl RenderOnce for ContentGroup {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for ContentGroup {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         example_group(vec![

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

@@ -490,6 +490,7 @@ impl RenderOnce for IconWithIndicator {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for Icon {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         v_flex()

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

@@ -24,6 +24,7 @@ impl RenderOnce for DecoratedIcon {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for DecoratedIcon {
     fn preview(_window: &mut Window, cx: &App) -> AnyElement {
         let decoration_x = IconDecoration::new(

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

@@ -205,6 +205,7 @@ impl RenderOnce for KeybindingHint {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for KeybindingHint {
     fn preview(window: &mut Window, _cx: &App) -> AnyElement {
         let enter_fallback = gpui::KeyBinding::new("enter", menu::Confirm, None);

crates/ui/src/components/label/highlighted_label.rs 🔗

@@ -46,13 +46,13 @@ impl LabelCommon for HighlightedLabel {
         self
     }
 
-    fn strikethrough(mut self, strikethrough: bool) -> Self {
-        self.base = self.base.strikethrough(strikethrough);
+    fn strikethrough(mut self) -> Self {
+        self.base = self.base.strikethrough();
         self
     }
 
-    fn italic(mut self, italic: bool) -> Self {
-        self.base = self.base.italic(italic);
+    fn italic(mut self) -> Self {
+        self.base = self.base.italic();
         self
     }
 
@@ -61,8 +61,8 @@ impl LabelCommon for HighlightedLabel {
         self
     }
 
-    fn underline(mut self, underline: bool) -> Self {
-        self.base = self.base.underline(underline);
+    fn underline(mut self) -> Self {
+        self.base = self.base.underline();
         self
     }
 

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

@@ -1,8 +1,5 @@
-#![allow(missing_docs)]
-
-use gpui::{AnyElement, App, StyleRefinement, Window};
-
-use crate::{prelude::*, LabelCommon, LabelLike, LabelSize, LineHeightStyle};
+use crate::{prelude::*, LabelLike};
+use gpui::StyleRefinement;
 
 /// A struct representing a label element in the UI.
 ///
@@ -56,6 +53,9 @@ impl Label {
     }
 }
 
+// nate: If we are going to do this, we might as well just
+// impl Styled for Label and not constrain styles
+
 // Style methods.
 impl Label {
     fn style(&mut self) -> &mut StyleRefinement {
@@ -82,6 +82,15 @@ impl LabelCommon for Label {
         self
     }
 
+    /// Sets the weight of the label using a [`FontWeight`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use ui::prelude::*;
+    ///
+    /// let my_label = Label::new("Hello, World!").weight(FontWeight::Bold);
+    /// ```
     fn weight(mut self, weight: gpui::FontWeight) -> Self {
         self.base = self.base.weight(weight);
         self
@@ -124,8 +133,8 @@ impl LabelCommon for Label {
     ///
     /// let my_label = Label::new("Hello, World!").strikethrough(true);
     /// ```
-    fn strikethrough(mut self, strikethrough: bool) -> Self {
-        self.base = self.base.strikethrough(strikethrough);
+    fn strikethrough(mut self) -> Self {
+        self.base = self.base.strikethrough();
         self
     }
 
@@ -138,8 +147,8 @@ impl LabelCommon for Label {
     ///
     /// let my_label = Label::new("Hello, World!").italic(true);
     /// ```
-    fn italic(mut self, italic: bool) -> Self {
-        self.base = self.base.italic(italic);
+    fn italic(mut self) -> Self {
+        self.base = self.base.italic();
         self
     }
 
@@ -157,8 +166,8 @@ impl LabelCommon for Label {
         self
     }
 
-    fn underline(mut self, underline: bool) -> Self {
-        self.base = self.base.underline(underline);
+    fn underline(mut self) -> Self {
+        self.base = self.base.underline();
         self
     }
 
@@ -185,52 +194,57 @@ impl RenderOnce for Label {
     }
 }
 
-impl ComponentPreview for Label {
-    fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
-        v_flex()
-            .gap_6()
-            .children(vec![
-                example_group_with_title(
-                    "Sizes",
-                    vec![
-                        single_example("Default", Label::new("Default Label").into_any_element()),
-                        single_example("Small", Label::new("Small Label").size(LabelSize::Small).into_any_element()),
-                        single_example("Large", Label::new("Large Label").size(LabelSize::Large).into_any_element()),
-                    ],
-                ),
-                example_group_with_title(
-                    "Colors",
-                    vec![
-                        single_example("Default", Label::new("Default Color").into_any_element()),
-                        single_example("Accent", Label::new("Accent Color").color(Color::Accent).into_any_element()),
-                        single_example("Error", Label::new("Error Color").color(Color::Error).into_any_element()),
-                    ],
-                ),
-                example_group_with_title(
-                    "Styles",
-                    vec![
-                        single_example("Default", Label::new("Default Style").into_any_element()),
-                        single_example("Bold", Label::new("Bold Style").weight(gpui::FontWeight::BOLD).into_any_element()),
-                        single_example("Italic", Label::new("Italic Style").italic(true).into_any_element()),
-                        single_example("Strikethrough", Label::new("Strikethrough Style").strikethrough(true).into_any_element()),
-                        single_example("Underline", Label::new("Underline Style").underline(true).into_any_element()),
-                    ],
-                ),
-                example_group_with_title(
-                    "Line Height Styles",
-                    vec![
-                        single_example("Default", Label::new("Default Line Height").into_any_element()),
-                        single_example("UI Label", Label::new("UI Label Line Height").line_height_style(LineHeightStyle::UiLabel).into_any_element()),
-                    ],
-                ),
-                example_group_with_title(
-                    "Special Cases",
-                    vec![
-                        single_example("Single Line", Label::new("Single\nLine\nText").single_line().into_any_element()),
-                        single_example("Text Ellipsis", Label::new("This is a very long text that should be truncated with an ellipsis").text_ellipsis().into_any_element()),
-                    ],
-                ),
-            ])
-            .into_any_element()
+mod label_preview {
+    use crate::prelude::*;
+
+    // View this component preview using `workspace: open component-preview`
+    impl ComponentPreview for Label {
+        fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
+            v_flex()
+                .gap_6()
+                .children(vec![
+                    example_group_with_title(
+                        "Sizes",
+                        vec![
+                            single_example("Default", Label::new("Project Explorer").into_any_element()),
+                            single_example("Small", Label::new("File: main.rs").size(LabelSize::Small).into_any_element()),
+                            single_example("Large", Label::new("Welcome to Zed").size(LabelSize::Large).into_any_element()),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "Colors",
+                        vec![
+                            single_example("Default", Label::new("Status: Ready").into_any_element()),
+                            single_example("Accent", Label::new("New Update Available").color(Color::Accent).into_any_element()),
+                            single_example("Error", Label::new("Build Failed").color(Color::Error).into_any_element()),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "Styles",
+                        vec![
+                            single_example("Default", Label::new("Normal Text").into_any_element()),
+                            single_example("Bold", Label::new("Important Notice").weight(gpui::FontWeight::BOLD).into_any_element()),
+                            single_example("Italic", Label::new("Code Comment").italic().into_any_element()),
+                            single_example("Strikethrough", Label::new("Deprecated Feature").strikethrough().into_any_element()),
+                            single_example("Underline", Label::new("Clickable Link").underline().into_any_element()),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "Line Height Styles",
+                        vec![
+                            single_example("Default", Label::new("Multi-line\nText\nExample").into_any_element()),
+                            single_example("UI Label", Label::new("Compact\nUI\nLabel").line_height_style(LineHeightStyle::UiLabel).into_any_element()),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "Special Cases",
+                        vec![
+                            single_example("Single Line", Label::new("Line 1\nLine 2\nLine 3").single_line().into_any_element()),
+                            single_example("Text Ellipsis", div().max_w_24().child(Label::new("This is a very long file name that should be truncated: very_long_file_name_with_many_words.rs").text_ellipsis()).into_any_element()),
+                        ],
+                    ),
+                ])
+                .into_any_element()
+        }
     }
 }

crates/ui/src/components/label/label_like.rs 🔗

@@ -1,23 +1,29 @@
-#![allow(missing_docs)]
-
-use gpui::{relative, AnyElement, FontWeight, StyleRefinement, Styled, UnderlineStyle};
+use crate::prelude::*;
+use gpui::{FontWeight, StyleRefinement, UnderlineStyle};
 use settings::Settings;
 use smallvec::SmallVec;
 use theme::ThemeSettings;
 
-use crate::prelude::*;
-
+/// Sets the size of a label
 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
 pub enum LabelSize {
+    /// The default size of a label.
     #[default]
     Default,
+    /// The large size of a label.
     Large,
+    /// The small size of a label.
     Small,
+    /// The extra small size of a label.
     XSmall,
 }
 
+/// Sets the line height of a label
 #[derive(Default, PartialEq, Copy, Clone)]
 pub enum LineHeightStyle {
+    /// The default line height style of a label,
+    /// set by either the UI's default line height,
+    /// or the developer's default buffer line height.
     #[default]
     TextLabel,
     /// Sets the line height to 1.
@@ -39,13 +45,13 @@ pub trait LabelCommon {
     fn color(self, color: Color) -> Self;
 
     /// Sets the strikethrough property of the label.
-    fn strikethrough(self, strikethrough: bool) -> Self;
+    fn strikethrough(self) -> Self;
 
     /// Sets the italic property of the label.
-    fn italic(self, italic: bool) -> Self;
+    fn italic(self) -> Self;
 
     /// Sets the underline property of the label
-    fn underline(self, underline: bool) -> Self;
+    fn underline(self) -> Self;
 
     /// Sets the alpha property of the label, overwriting the alpha value of the color.
     fn alpha(self, alpha: f32) -> Self;
@@ -60,6 +66,11 @@ pub trait LabelCommon {
     fn buffer_font(self, cx: &App) -> Self;
 }
 
+/// A label-like element that can be used to create a custom label when
+/// prebuilt labels are not sufficient. Use this sparingly, as it is
+/// unconstrained and may make the UI feel less consistent.
+///
+/// This is also used to build the prebuilt labels.
 #[derive(IntoElement)]
 pub struct LabelLike {
     pub(super) base: Div,
@@ -83,6 +94,8 @@ impl Default for LabelLike {
 }
 
 impl LabelLike {
+    /// Creates a new, fully custom label.
+    /// Prefer using [`Label`] or [`HighlightedLabel`] where possible.
     pub fn new() -> Self {
         Self {
             base: div(),
@@ -133,18 +146,18 @@ impl LabelCommon for LabelLike {
         self
     }
 
-    fn strikethrough(mut self, strikethrough: bool) -> Self {
-        self.strikethrough = strikethrough;
+    fn strikethrough(mut self) -> Self {
+        self.strikethrough = true;
         self
     }
 
-    fn italic(mut self, italic: bool) -> Self {
-        self.italic = italic;
+    fn italic(mut self) -> Self {
+        self.italic = true;
         self
     }
 
-    fn underline(mut self, underline: bool) -> Self {
-        self.underline = underline;
+    fn underline(mut self) -> Self {
+        self.underline = true;
         self
     }
 

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

@@ -8,7 +8,6 @@ mod disclosure;
 mod icon;
 mod icon_button;
 mod keybinding;
-mod label;
 mod list;
 mod list_header;
 mod list_item;
@@ -23,7 +22,6 @@ pub use disclosure::*;
 pub use icon::*;
 pub use icon_button::*;
 pub use keybinding::*;
-pub use label::*;
 pub use list::*;
 pub use list_header::*;
 pub use list_item::*;

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

@@ -1,38 +0,0 @@
-use std::time::Duration;
-
-use crate::{prelude::*, HighlightedLabel, Label};
-use gpui::{pulsating_between, Animation, AnimationExt, Render};
-use story::Story;
-
-pub struct LabelStory;
-
-impl Render for LabelStory {
-    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
-        Story::container()
-            .child(Story::title_for::<Label>())
-            .child(Story::label("Default"))
-            .child(Label::new("Hello, world!"))
-            .child(Story::label("Highlighted"))
-            .child(HighlightedLabel::new(
-                "Hello, world!",
-                vec![0, 1, 2, 7, 8, 12],
-            ))
-            .child(HighlightedLabel::new(
-                "Héllo, world!",
-                vec![0, 1, 3, 8, 9, 13],
-            ))
-            .child(Story::label("Highlighted with `color`"))
-            .child(
-                HighlightedLabel::new("Hello, world!", vec![0, 1, 2, 7, 8, 12]).color(Color::Error),
-            )
-            .child(
-                Label::new("This text is pulsating").with_animation(
-                    "pulsating-label",
-                    Animation::new(Duration::from_secs(2))
-                        .repeat()
-                        .with_easing(pulsating_between(0.4, 0.8)),
-                    |label, delta| label.alpha(delta),
-                ),
-            )
-    }
-}

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

@@ -172,6 +172,7 @@ impl RenderOnce for Tab {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for Tab {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         v_flex()

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

@@ -151,6 +151,7 @@ where
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for Table {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         v_flex()

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

@@ -508,6 +508,7 @@ impl RenderOnce for SwitchWithLabel {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for Checkbox {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         v_flex()
@@ -592,6 +593,7 @@ impl ComponentPreview for Checkbox {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for Switch {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         v_flex()
@@ -654,6 +656,7 @@ impl ComponentPreview for Switch {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for CheckboxWithLabel {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         v_flex()

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

@@ -206,6 +206,7 @@ impl Render for LinkPreview {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for Tooltip {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         example_group(vec![single_example(

crates/ui/src/prelude.rs 🔗

@@ -2,8 +2,9 @@
 
 pub use gpui::prelude::*;
 pub use gpui::{
-    div, px, relative, rems, AbsoluteLength, App, Context, DefiniteLength, Div, Element, ElementId,
-    InteractiveElement, ParentElement, Pixels, Rems, RenderOnce, SharedString, Styled, Window,
+    div, px, relative, rems, AbsoluteLength, AnyElement, App, Context, DefiniteLength, Div,
+    Element, ElementId, InteractiveElement, ParentElement, Pixels, Rems, RenderOnce, SharedString,
+    Styled, Window,
 };
 
 pub use component::{example_group, example_group_with_title, single_example, ComponentPreview};

crates/ui/src/styles/typography.rs 🔗

@@ -233,6 +233,7 @@ impl Headline {
     }
 }
 
+// View this component preview using `workspace: open component-preview`
 impl ComponentPreview for Headline {
     fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
         v_flex()

crates/welcome/src/welcome.rs 🔗

@@ -104,7 +104,7 @@ impl Render for WelcomePage {
                                 h_flex().w_full().justify_center().child(
                                     Label::new("The editor for what's next")
                                         .color(Color::Muted)
-                                        .italic(true),
+                                        .italic(),
                                 ),
                             ),
                     )